amulet-core 1.9.19__py3-none-any.whl → 1.9.20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of amulet-core might be problematic. Click here for more details.
- amulet/__init__.py +27 -27
- amulet/__pyinstaller/__init__.py +2 -2
- amulet/__pyinstaller/hook-amulet.py +4 -4
- amulet/_version.py +21 -21
- amulet/api/__init__.py +2 -2
- amulet/api/abstract_base_entity.py +128 -128
- amulet/api/block.py +630 -630
- amulet/api/block_entity.py +71 -71
- amulet/api/cache.py +107 -107
- amulet/api/chunk/__init__.py +6 -6
- amulet/api/chunk/biomes.py +207 -207
- amulet/api/chunk/block_entity_dict.py +175 -175
- amulet/api/chunk/blocks.py +46 -46
- amulet/api/chunk/chunk.py +389 -389
- amulet/api/chunk/entity_list.py +75 -75
- amulet/api/chunk/status.py +167 -167
- amulet/api/data_types/__init__.py +4 -4
- amulet/api/data_types/generic_types.py +4 -4
- amulet/api/data_types/operation_types.py +16 -16
- amulet/api/data_types/world_types.py +49 -49
- amulet/api/data_types/wrapper_types.py +71 -71
- amulet/api/entity.py +74 -74
- amulet/api/errors.py +119 -119
- amulet/api/history/__init__.py +36 -36
- amulet/api/history/base/__init__.py +3 -3
- amulet/api/history/base/base_history.py +26 -26
- amulet/api/history/base/history_manager.py +63 -63
- amulet/api/history/base/revision_manager.py +73 -73
- amulet/api/history/changeable.py +15 -15
- amulet/api/history/data_types.py +7 -7
- amulet/api/history/history_manager/__init__.py +3 -3
- amulet/api/history/history_manager/container.py +102 -102
- amulet/api/history/history_manager/database.py +279 -279
- amulet/api/history/history_manager/meta.py +93 -93
- amulet/api/history/history_manager/object.py +116 -116
- amulet/api/history/revision_manager/__init__.py +2 -2
- amulet/api/history/revision_manager/disk.py +33 -33
- amulet/api/history/revision_manager/ram.py +12 -12
- amulet/api/item.py +75 -75
- amulet/api/level/__init__.py +4 -4
- amulet/api/level/base_level/__init__.py +1 -1
- amulet/api/level/base_level/base_level.py +1035 -1026
- amulet/api/level/base_level/chunk_manager.py +227 -227
- amulet/api/level/base_level/clone.py +389 -389
- amulet/api/level/base_level/player_manager.py +101 -101
- amulet/api/level/immutable_structure/__init__.py +1 -1
- amulet/api/level/immutable_structure/immutable_structure.py +94 -94
- amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
- amulet/api/level/structure.py +22 -22
- amulet/api/level/world.py +19 -19
- amulet/api/partial_3d_array/__init__.py +2 -2
- amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
- amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
- amulet/api/partial_3d_array/data_types.py +15 -15
- amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
- amulet/api/partial_3d_array/util.py +152 -152
- amulet/api/player.py +65 -65
- amulet/api/registry/__init__.py +2 -2
- amulet/api/registry/base_registry.py +34 -34
- amulet/api/registry/biome_manager.py +153 -153
- amulet/api/registry/block_manager.py +156 -156
- amulet/api/selection/__init__.py +2 -2
- amulet/api/selection/abstract_selection.py +315 -315
- amulet/api/selection/box.py +805 -805
- amulet/api/selection/group.py +488 -488
- amulet/api/structure.py +37 -37
- amulet/api/wrapper/__init__.py +8 -8
- amulet/api/wrapper/chunk/interface.py +441 -441
- amulet/api/wrapper/chunk/translator.py +567 -567
- amulet/api/wrapper/format_wrapper.py +772 -772
- amulet/api/wrapper/structure_format_wrapper.py +116 -116
- amulet/api/wrapper/world_format_wrapper.py +63 -63
- amulet/level/__init__.py +1 -1
- amulet/level/formats/anvil_forge_world.py +40 -40
- amulet/level/formats/anvil_world/__init__.py +3 -3
- amulet/level/formats/anvil_world/_sector_manager.py +291 -384
- amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
- amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
- amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
- amulet/level/formats/anvil_world/dimension.py +177 -177
- amulet/level/formats/anvil_world/format.py +769 -769
- amulet/level/formats/anvil_world/region.py +384 -384
- amulet/level/formats/construction/__init__.py +3 -3
- amulet/level/formats/construction/format_wrapper.py +515 -515
- amulet/level/formats/construction/interface.py +134 -134
- amulet/level/formats/construction/section.py +60 -60
- amulet/level/formats/construction/util.py +165 -165
- amulet/level/formats/leveldb_world/__init__.py +3 -3
- amulet/level/formats/leveldb_world/chunk.py +33 -33
- amulet/level/formats/leveldb_world/dimension.py +385 -419
- amulet/level/formats/leveldb_world/format.py +659 -641
- amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
- amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
- amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
- amulet/level/formats/mcstructure/__init__.py +3 -3
- amulet/level/formats/mcstructure/chunk.py +50 -50
- amulet/level/formats/mcstructure/format_wrapper.py +408 -408
- amulet/level/formats/mcstructure/interface.py +175 -175
- amulet/level/formats/schematic/__init__.py +3 -3
- amulet/level/formats/schematic/chunk.py +55 -55
- amulet/level/formats/schematic/data_types.py +4 -4
- amulet/level/formats/schematic/format_wrapper.py +373 -373
- amulet/level/formats/schematic/interface.py +142 -142
- amulet/level/formats/sponge_schem/__init__.py +4 -4
- amulet/level/formats/sponge_schem/chunk.py +62 -62
- amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
- amulet/level/formats/sponge_schem/interface.py +118 -118
- amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
- amulet/level/formats/sponge_schem/varint/varint.py +87 -87
- amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
- amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
- amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
- amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
- amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
- amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
- amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
- amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
- amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
- amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
- amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
- amulet/level/load.py +59 -59
- amulet/level/loader.py +95 -95
- amulet/level/translators/chunk/bedrock/__init__.py +267 -267
- amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
- amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
- amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
- amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
- amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
- amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
- amulet/libs/leveldb/__init__.py +7 -7
- amulet/operations/__init__.py +5 -5
- amulet/operations/clone.py +18 -18
- amulet/operations/delete_chunk.py +32 -32
- amulet/operations/fill.py +30 -30
- amulet/operations/paste.py +65 -65
- amulet/operations/replace.py +58 -58
- amulet/utils/__init__.py +14 -14
- amulet/utils/format_utils.py +41 -41
- amulet/utils/generator.py +15 -15
- amulet/utils/matrix.py +243 -243
- amulet/utils/numpy_helpers.py +46 -46
- amulet/utils/world_utils.py +349 -349
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
- amulet_core-1.9.20.dist-info/RECORD +208 -0
- amulet_core-1.9.19.dist-info/RECORD +0 -208
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/top_level.txt +0 -0
amulet/api/level/world.py
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from .base_level import BaseLevel
|
|
4
|
-
from amulet.api.wrapper import WorldFormatWrapper
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class World(BaseLevel):
|
|
8
|
-
"""
|
|
9
|
-
Class that handles world editing of any world format via an separate and flexible data format
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def __init__(self, directory: str, world_wrapper: WorldFormatWrapper):
|
|
13
|
-
assert isinstance(world_wrapper, WorldFormatWrapper)
|
|
14
|
-
super().__init__(directory, world_wrapper)
|
|
15
|
-
|
|
16
|
-
@property
|
|
17
|
-
def level_wrapper(self) -> "WorldFormatWrapper":
|
|
18
|
-
"""A class to access data directly from the level."""
|
|
19
|
-
return self._level_wrapper
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .base_level import BaseLevel
|
|
4
|
+
from amulet.api.wrapper import WorldFormatWrapper
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class World(BaseLevel):
|
|
8
|
+
"""
|
|
9
|
+
Class that handles world editing of any world format via an separate and flexible data format
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, directory: str, world_wrapper: WorldFormatWrapper):
|
|
13
|
+
assert isinstance(world_wrapper, WorldFormatWrapper)
|
|
14
|
+
super().__init__(directory, world_wrapper)
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def level_wrapper(self) -> "WorldFormatWrapper":
|
|
18
|
+
"""A class to access data directly from the level."""
|
|
19
|
+
return self._level_wrapper
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .unbounded_partial_3d_array import UnboundedPartial3DArray
|
|
2
|
-
from .bounded_partial_3d_array import BoundedPartial3DArray
|
|
1
|
+
from .unbounded_partial_3d_array import UnboundedPartial3DArray
|
|
2
|
+
from .bounded_partial_3d_array import BoundedPartial3DArray
|
|
@@ -1,263 +1,263 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Optional, Dict, Union, Tuple, Type, TYPE_CHECKING
|
|
3
|
-
import numpy
|
|
4
|
-
|
|
5
|
-
import copy
|
|
6
|
-
|
|
7
|
-
from .util import get_sanitised_sliced_array_size
|
|
8
|
-
from .data_types import DtypeType, UnpackedSlicesType, IntegerType
|
|
9
|
-
|
|
10
|
-
if TYPE_CHECKING:
|
|
11
|
-
from .unbounded_partial_3d_array import UnboundedPartial3DArray
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class BasePartial3DArray(ABC):
|
|
15
|
-
"""Do not use this class directly. Use UnboundedPartial3DArray or BoundedPartial3DArray"""
|
|
16
|
-
|
|
17
|
-
_sections: Dict[int, numpy.ndarray]
|
|
18
|
-
|
|
19
|
-
def __init__(
|
|
20
|
-
self,
|
|
21
|
-
dtype: DtypeType,
|
|
22
|
-
default_value: Union[int, bool],
|
|
23
|
-
section_shape: Tuple[int, int, int],
|
|
24
|
-
start: Tuple[Optional[int], Optional[int], Optional[int]],
|
|
25
|
-
stop: Tuple[Optional[int], Optional[int], Optional[int]],
|
|
26
|
-
step: Tuple[Optional[int], Optional[int], Optional[int]],
|
|
27
|
-
parent_array: Optional["UnboundedPartial3DArray"] = None,
|
|
28
|
-
sections: Optional[Dict[int, numpy.ndarray]] = None,
|
|
29
|
-
):
|
|
30
|
-
self._dtype = dtype
|
|
31
|
-
self._default_value: Union[int, bool] = default_value
|
|
32
|
-
self._section_shape = section_shape
|
|
33
|
-
self._parent_array = parent_array
|
|
34
|
-
|
|
35
|
-
self._size_x = None
|
|
36
|
-
self._size_y = None
|
|
37
|
-
self._size_z = None
|
|
38
|
-
|
|
39
|
-
self._start_x, self._stop_x, self._step_x = start[0], stop[0], step[0]
|
|
40
|
-
self._start_y, self._stop_y = start[1], stop[1]
|
|
41
|
-
assert (self._start_y is None and self._stop_y is None) or (
|
|
42
|
-
isinstance(self._start_y, int) and isinstance(self._stop_y, int)
|
|
43
|
-
), "y start and stop must both be None or ints"
|
|
44
|
-
self._step_y = 1 if step[1] is None else step[1]
|
|
45
|
-
if self.size_y == 0:
|
|
46
|
-
self._stop_y = self._start_y
|
|
47
|
-
self._start_z, self._stop_z, self._step_z = start[2], stop[2], step[2]
|
|
48
|
-
|
|
49
|
-
if parent_array is None:
|
|
50
|
-
# populate from sections
|
|
51
|
-
self._sections = sections or {}
|
|
52
|
-
for key, section in self._sections.items():
|
|
53
|
-
if not isinstance(key, int):
|
|
54
|
-
raise ValueError("All keys must be ints")
|
|
55
|
-
if section.shape != self._section_shape:
|
|
56
|
-
raise ValueError(
|
|
57
|
-
f"The size of all sections must be equal to the section_shape. Expected shape {self._section_shape}, got {section.shape}"
|
|
58
|
-
)
|
|
59
|
-
if section.dtype != self._dtype:
|
|
60
|
-
raise ValueError(
|
|
61
|
-
f"The given dtype does not match the arrays given. Expected {self._default_value}, got {section.dtype}"
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
elif isinstance(parent_array, BasePartial3DArray):
|
|
65
|
-
# populate from the array
|
|
66
|
-
assert (
|
|
67
|
-
parent_array.section_shape == self._section_shape
|
|
68
|
-
), "The parent section shape must match the given section_shape."
|
|
69
|
-
assert (
|
|
70
|
-
parent_array.dtype == self._dtype
|
|
71
|
-
), "The parent dtype must match the given dtype"
|
|
72
|
-
self._sections = parent_array._sections
|
|
73
|
-
|
|
74
|
-
else:
|
|
75
|
-
raise Exception(
|
|
76
|
-
f"{parent_array.__class__.__name__}({parent_array}) is not a valid input type for parent_array"
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
@property
|
|
80
|
-
def start_x(self) -> int:
|
|
81
|
-
"""The minimum x value of the slice within the original array. Read Only"""
|
|
82
|
-
return self._start_x
|
|
83
|
-
|
|
84
|
-
@property
|
|
85
|
-
def start_y(self) -> Optional[int]:
|
|
86
|
-
"""The minimum y value of the slice within the original array. Read Only"""
|
|
87
|
-
return self._start_y
|
|
88
|
-
|
|
89
|
-
@property
|
|
90
|
-
def start_z(self) -> int:
|
|
91
|
-
"""The minimum z value of the slice within the original array. Read Only"""
|
|
92
|
-
return self._start_z
|
|
93
|
-
|
|
94
|
-
@property
|
|
95
|
-
def start(self) -> Tuple[int, int, int]:
|
|
96
|
-
"""The minimum x, y and z of the slice within the original array. Read Only"""
|
|
97
|
-
return self.start_x, self.start_y, self.start_z
|
|
98
|
-
|
|
99
|
-
@property
|
|
100
|
-
def stop_x(self) -> int:
|
|
101
|
-
"""The maximum x value of the slice within the original array. Read Only"""
|
|
102
|
-
return self._stop_x
|
|
103
|
-
|
|
104
|
-
@property
|
|
105
|
-
def stop_y(self) -> Optional[int]:
|
|
106
|
-
"""The maximum y value of the slice within the original array. Read Only"""
|
|
107
|
-
return self._stop_y
|
|
108
|
-
|
|
109
|
-
@property
|
|
110
|
-
def stop_z(self) -> int:
|
|
111
|
-
"""The maximum z value of the slice within the original array. Read Only"""
|
|
112
|
-
return self._stop_z
|
|
113
|
-
|
|
114
|
-
@property
|
|
115
|
-
def stop(self) -> Tuple[int, int, int]:
|
|
116
|
-
"""The maximum x value of the slice within the original array. Read Only"""
|
|
117
|
-
return self.stop_x, self.stop_y, self.stop_z
|
|
118
|
-
|
|
119
|
-
@property
|
|
120
|
-
def step_x(self) -> int:
|
|
121
|
-
"""The step count of the slice in the x axis. Read Only"""
|
|
122
|
-
return self._step_x
|
|
123
|
-
|
|
124
|
-
@property
|
|
125
|
-
def step_y(self) -> int:
|
|
126
|
-
"""The step count of the slice in the y axis. Read Only"""
|
|
127
|
-
return self._step_y
|
|
128
|
-
|
|
129
|
-
@property
|
|
130
|
-
def step_z(self) -> int:
|
|
131
|
-
"""The step count of the slice in the z axis. Read Only"""
|
|
132
|
-
return self._step_z
|
|
133
|
-
|
|
134
|
-
@property
|
|
135
|
-
def step(self) -> Tuple[int, int, int]:
|
|
136
|
-
"""The step count of the slice in the x, y and z axis. Read Only"""
|
|
137
|
-
return self.step_x, self.step_y, self.step_z
|
|
138
|
-
|
|
139
|
-
@property
|
|
140
|
-
def slice_x(self) -> slice:
|
|
141
|
-
"""The slice in the x axis into the original array. Read Only"""
|
|
142
|
-
return slice(self.start_x, self.stop_x, self.step_x)
|
|
143
|
-
|
|
144
|
-
@property
|
|
145
|
-
def slice_y(self) -> slice:
|
|
146
|
-
"""The slice in the y axis into the original array. Read Only"""
|
|
147
|
-
return slice(self.start_y, self.stop_y, self.step_y)
|
|
148
|
-
|
|
149
|
-
@property
|
|
150
|
-
def slice_z(self) -> slice:
|
|
151
|
-
"""The slice in the z axis into the original array. Read Only"""
|
|
152
|
-
return slice(self.start_z, self.stop_z, self.step_z)
|
|
153
|
-
|
|
154
|
-
@property
|
|
155
|
-
def slices_tuple(self) -> UnpackedSlicesType:
|
|
156
|
-
"""The slices data in the x, y and z axis into the original array. Read Only"""
|
|
157
|
-
return (
|
|
158
|
-
(self.start_x, self.stop_x, self.step_x),
|
|
159
|
-
(self.start_y, self.stop_y, self.step_y),
|
|
160
|
-
(self.start_z, self.stop_z, self.step_z),
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
@property
|
|
164
|
-
def size_x(self) -> int:
|
|
165
|
-
"""The size of the array in the x axis. Read Only"""
|
|
166
|
-
if self._size_x is None:
|
|
167
|
-
self._size_x = get_sanitised_sliced_array_size(
|
|
168
|
-
self.start_x, self.stop_x, self.step_x
|
|
169
|
-
)
|
|
170
|
-
return self._size_x
|
|
171
|
-
|
|
172
|
-
@property
|
|
173
|
-
def size_y(self) -> Union[int, float]:
|
|
174
|
-
"""The size of the array in the y axis. Read Only"""
|
|
175
|
-
if self._size_y is None:
|
|
176
|
-
self._size_y = get_sanitised_sliced_array_size(
|
|
177
|
-
self.start_y, self.stop_y, self.step_y
|
|
178
|
-
)
|
|
179
|
-
return self._size_y
|
|
180
|
-
|
|
181
|
-
@property
|
|
182
|
-
def size_z(self) -> int:
|
|
183
|
-
"""The size of the array in the z axis. Read Only"""
|
|
184
|
-
if self._size_z is None:
|
|
185
|
-
self._size_z = get_sanitised_sliced_array_size(
|
|
186
|
-
self.start_z, self.stop_z, self.step_z
|
|
187
|
-
)
|
|
188
|
-
return self._size_z
|
|
189
|
-
|
|
190
|
-
@property
|
|
191
|
-
def shape(self) -> Tuple[int, Union[int, float], int]:
|
|
192
|
-
"""The size of the array in the x, y and z axis. Read Only"""
|
|
193
|
-
return self.size_x, self.size_y, self.size_z
|
|
194
|
-
|
|
195
|
-
@property
|
|
196
|
-
def dtype(self) -> Type[numpy.dtype]:
|
|
197
|
-
"""The numpy dtype for the arrays. Read Only."""
|
|
198
|
-
return self._dtype
|
|
199
|
-
|
|
200
|
-
@property
|
|
201
|
-
def default_value(self) -> Union[int, bool]:
|
|
202
|
-
"""The default value to populate undefined sections with. Read Only"""
|
|
203
|
-
return self._default_value
|
|
204
|
-
|
|
205
|
-
@property
|
|
206
|
-
def section_shape(self) -> Tuple[int, int, int]:
|
|
207
|
-
"""The x, y and z size of a section in the original array."""
|
|
208
|
-
return self._section_shape
|
|
209
|
-
|
|
210
|
-
def _section_index(self, y: IntegerType) -> Tuple[IntegerType, IntegerType]:
|
|
211
|
-
"""
|
|
212
|
-
Get the section index and location within the section of an absolute y coordinate.
|
|
213
|
-
|
|
214
|
-
:param y: The absolute y coordinate.
|
|
215
|
-
:return: The section index this coordinate is found in.
|
|
216
|
-
"""
|
|
217
|
-
return y // self.section_shape[1], y % self.section_shape[1]
|
|
218
|
-
|
|
219
|
-
@abstractmethod
|
|
220
|
-
def __array__(self, dtype=None):
|
|
221
|
-
raise NotImplementedError
|
|
222
|
-
|
|
223
|
-
def __contains__(self, item: int):
|
|
224
|
-
"""
|
|
225
|
-
Is a section array defined.
|
|
226
|
-
|
|
227
|
-
>>> 5 in partial_array
|
|
228
|
-
True
|
|
229
|
-
|
|
230
|
-
:param item: The section index to test.
|
|
231
|
-
:return: ``True`` if there is an array present for this section. ``False`` otherwise
|
|
232
|
-
"""
|
|
233
|
-
return item in self._sections
|
|
234
|
-
|
|
235
|
-
def __iter__(self):
|
|
236
|
-
raise Exception(
|
|
237
|
-
"Please use sections method if this is what you are trying to achieve"
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
@abstractmethod
|
|
241
|
-
def __getitem__(self, item):
|
|
242
|
-
raise NotImplementedError
|
|
243
|
-
|
|
244
|
-
@abstractmethod
|
|
245
|
-
def __setitem__(self, key, value):
|
|
246
|
-
raise NotImplementedError
|
|
247
|
-
|
|
248
|
-
def copy(self):
|
|
249
|
-
return copy.copy(self)
|
|
250
|
-
|
|
251
|
-
def __copy__(self):
|
|
252
|
-
cls = self.__class__
|
|
253
|
-
result = cls.__new__(cls)
|
|
254
|
-
result.__dict__.update(self.__dict__)
|
|
255
|
-
return result
|
|
256
|
-
|
|
257
|
-
def __deepcopy__(self, memodict=None):
|
|
258
|
-
cls = self.__class__
|
|
259
|
-
result = cls.__new__(cls)
|
|
260
|
-
memodict[id(self)] = result
|
|
261
|
-
for k, v in self.__dict__.items():
|
|
262
|
-
setattr(result, k, copy.deepcopy(v, memodict))
|
|
263
|
-
return result
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Optional, Dict, Union, Tuple, Type, TYPE_CHECKING
|
|
3
|
+
import numpy
|
|
4
|
+
|
|
5
|
+
import copy
|
|
6
|
+
|
|
7
|
+
from .util import get_sanitised_sliced_array_size
|
|
8
|
+
from .data_types import DtypeType, UnpackedSlicesType, IntegerType
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .unbounded_partial_3d_array import UnboundedPartial3DArray
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BasePartial3DArray(ABC):
|
|
15
|
+
"""Do not use this class directly. Use UnboundedPartial3DArray or BoundedPartial3DArray"""
|
|
16
|
+
|
|
17
|
+
_sections: Dict[int, numpy.ndarray]
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
dtype: DtypeType,
|
|
22
|
+
default_value: Union[int, bool],
|
|
23
|
+
section_shape: Tuple[int, int, int],
|
|
24
|
+
start: Tuple[Optional[int], Optional[int], Optional[int]],
|
|
25
|
+
stop: Tuple[Optional[int], Optional[int], Optional[int]],
|
|
26
|
+
step: Tuple[Optional[int], Optional[int], Optional[int]],
|
|
27
|
+
parent_array: Optional["UnboundedPartial3DArray"] = None,
|
|
28
|
+
sections: Optional[Dict[int, numpy.ndarray]] = None,
|
|
29
|
+
):
|
|
30
|
+
self._dtype = dtype
|
|
31
|
+
self._default_value: Union[int, bool] = default_value
|
|
32
|
+
self._section_shape = section_shape
|
|
33
|
+
self._parent_array = parent_array
|
|
34
|
+
|
|
35
|
+
self._size_x = None
|
|
36
|
+
self._size_y = None
|
|
37
|
+
self._size_z = None
|
|
38
|
+
|
|
39
|
+
self._start_x, self._stop_x, self._step_x = start[0], stop[0], step[0]
|
|
40
|
+
self._start_y, self._stop_y = start[1], stop[1]
|
|
41
|
+
assert (self._start_y is None and self._stop_y is None) or (
|
|
42
|
+
isinstance(self._start_y, int) and isinstance(self._stop_y, int)
|
|
43
|
+
), "y start and stop must both be None or ints"
|
|
44
|
+
self._step_y = 1 if step[1] is None else step[1]
|
|
45
|
+
if self.size_y == 0:
|
|
46
|
+
self._stop_y = self._start_y
|
|
47
|
+
self._start_z, self._stop_z, self._step_z = start[2], stop[2], step[2]
|
|
48
|
+
|
|
49
|
+
if parent_array is None:
|
|
50
|
+
# populate from sections
|
|
51
|
+
self._sections = sections or {}
|
|
52
|
+
for key, section in self._sections.items():
|
|
53
|
+
if not isinstance(key, int):
|
|
54
|
+
raise ValueError("All keys must be ints")
|
|
55
|
+
if section.shape != self._section_shape:
|
|
56
|
+
raise ValueError(
|
|
57
|
+
f"The size of all sections must be equal to the section_shape. Expected shape {self._section_shape}, got {section.shape}"
|
|
58
|
+
)
|
|
59
|
+
if section.dtype != self._dtype:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
f"The given dtype does not match the arrays given. Expected {self._default_value}, got {section.dtype}"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
elif isinstance(parent_array, BasePartial3DArray):
|
|
65
|
+
# populate from the array
|
|
66
|
+
assert (
|
|
67
|
+
parent_array.section_shape == self._section_shape
|
|
68
|
+
), "The parent section shape must match the given section_shape."
|
|
69
|
+
assert (
|
|
70
|
+
parent_array.dtype == self._dtype
|
|
71
|
+
), "The parent dtype must match the given dtype"
|
|
72
|
+
self._sections = parent_array._sections
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
raise Exception(
|
|
76
|
+
f"{parent_array.__class__.__name__}({parent_array}) is not a valid input type for parent_array"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def start_x(self) -> int:
|
|
81
|
+
"""The minimum x value of the slice within the original array. Read Only"""
|
|
82
|
+
return self._start_x
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def start_y(self) -> Optional[int]:
|
|
86
|
+
"""The minimum y value of the slice within the original array. Read Only"""
|
|
87
|
+
return self._start_y
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def start_z(self) -> int:
|
|
91
|
+
"""The minimum z value of the slice within the original array. Read Only"""
|
|
92
|
+
return self._start_z
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def start(self) -> Tuple[int, int, int]:
|
|
96
|
+
"""The minimum x, y and z of the slice within the original array. Read Only"""
|
|
97
|
+
return self.start_x, self.start_y, self.start_z
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def stop_x(self) -> int:
|
|
101
|
+
"""The maximum x value of the slice within the original array. Read Only"""
|
|
102
|
+
return self._stop_x
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def stop_y(self) -> Optional[int]:
|
|
106
|
+
"""The maximum y value of the slice within the original array. Read Only"""
|
|
107
|
+
return self._stop_y
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def stop_z(self) -> int:
|
|
111
|
+
"""The maximum z value of the slice within the original array. Read Only"""
|
|
112
|
+
return self._stop_z
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def stop(self) -> Tuple[int, int, int]:
|
|
116
|
+
"""The maximum x value of the slice within the original array. Read Only"""
|
|
117
|
+
return self.stop_x, self.stop_y, self.stop_z
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def step_x(self) -> int:
|
|
121
|
+
"""The step count of the slice in the x axis. Read Only"""
|
|
122
|
+
return self._step_x
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def step_y(self) -> int:
|
|
126
|
+
"""The step count of the slice in the y axis. Read Only"""
|
|
127
|
+
return self._step_y
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def step_z(self) -> int:
|
|
131
|
+
"""The step count of the slice in the z axis. Read Only"""
|
|
132
|
+
return self._step_z
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def step(self) -> Tuple[int, int, int]:
|
|
136
|
+
"""The step count of the slice in the x, y and z axis. Read Only"""
|
|
137
|
+
return self.step_x, self.step_y, self.step_z
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def slice_x(self) -> slice:
|
|
141
|
+
"""The slice in the x axis into the original array. Read Only"""
|
|
142
|
+
return slice(self.start_x, self.stop_x, self.step_x)
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def slice_y(self) -> slice:
|
|
146
|
+
"""The slice in the y axis into the original array. Read Only"""
|
|
147
|
+
return slice(self.start_y, self.stop_y, self.step_y)
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def slice_z(self) -> slice:
|
|
151
|
+
"""The slice in the z axis into the original array. Read Only"""
|
|
152
|
+
return slice(self.start_z, self.stop_z, self.step_z)
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def slices_tuple(self) -> UnpackedSlicesType:
|
|
156
|
+
"""The slices data in the x, y and z axis into the original array. Read Only"""
|
|
157
|
+
return (
|
|
158
|
+
(self.start_x, self.stop_x, self.step_x),
|
|
159
|
+
(self.start_y, self.stop_y, self.step_y),
|
|
160
|
+
(self.start_z, self.stop_z, self.step_z),
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def size_x(self) -> int:
|
|
165
|
+
"""The size of the array in the x axis. Read Only"""
|
|
166
|
+
if self._size_x is None:
|
|
167
|
+
self._size_x = get_sanitised_sliced_array_size(
|
|
168
|
+
self.start_x, self.stop_x, self.step_x
|
|
169
|
+
)
|
|
170
|
+
return self._size_x
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def size_y(self) -> Union[int, float]:
|
|
174
|
+
"""The size of the array in the y axis. Read Only"""
|
|
175
|
+
if self._size_y is None:
|
|
176
|
+
self._size_y = get_sanitised_sliced_array_size(
|
|
177
|
+
self.start_y, self.stop_y, self.step_y
|
|
178
|
+
)
|
|
179
|
+
return self._size_y
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def size_z(self) -> int:
|
|
183
|
+
"""The size of the array in the z axis. Read Only"""
|
|
184
|
+
if self._size_z is None:
|
|
185
|
+
self._size_z = get_sanitised_sliced_array_size(
|
|
186
|
+
self.start_z, self.stop_z, self.step_z
|
|
187
|
+
)
|
|
188
|
+
return self._size_z
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def shape(self) -> Tuple[int, Union[int, float], int]:
|
|
192
|
+
"""The size of the array in the x, y and z axis. Read Only"""
|
|
193
|
+
return self.size_x, self.size_y, self.size_z
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def dtype(self) -> Type[numpy.dtype]:
|
|
197
|
+
"""The numpy dtype for the arrays. Read Only."""
|
|
198
|
+
return self._dtype
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def default_value(self) -> Union[int, bool]:
|
|
202
|
+
"""The default value to populate undefined sections with. Read Only"""
|
|
203
|
+
return self._default_value
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def section_shape(self) -> Tuple[int, int, int]:
|
|
207
|
+
"""The x, y and z size of a section in the original array."""
|
|
208
|
+
return self._section_shape
|
|
209
|
+
|
|
210
|
+
def _section_index(self, y: IntegerType) -> Tuple[IntegerType, IntegerType]:
|
|
211
|
+
"""
|
|
212
|
+
Get the section index and location within the section of an absolute y coordinate.
|
|
213
|
+
|
|
214
|
+
:param y: The absolute y coordinate.
|
|
215
|
+
:return: The section index this coordinate is found in.
|
|
216
|
+
"""
|
|
217
|
+
return y // self.section_shape[1], y % self.section_shape[1]
|
|
218
|
+
|
|
219
|
+
@abstractmethod
|
|
220
|
+
def __array__(self, dtype=None):
|
|
221
|
+
raise NotImplementedError
|
|
222
|
+
|
|
223
|
+
def __contains__(self, item: int):
|
|
224
|
+
"""
|
|
225
|
+
Is a section array defined.
|
|
226
|
+
|
|
227
|
+
>>> 5 in partial_array
|
|
228
|
+
True
|
|
229
|
+
|
|
230
|
+
:param item: The section index to test.
|
|
231
|
+
:return: ``True`` if there is an array present for this section. ``False`` otherwise
|
|
232
|
+
"""
|
|
233
|
+
return item in self._sections
|
|
234
|
+
|
|
235
|
+
def __iter__(self):
|
|
236
|
+
raise Exception(
|
|
237
|
+
"Please use sections method if this is what you are trying to achieve"
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
@abstractmethod
|
|
241
|
+
def __getitem__(self, item):
|
|
242
|
+
raise NotImplementedError
|
|
243
|
+
|
|
244
|
+
@abstractmethod
|
|
245
|
+
def __setitem__(self, key, value):
|
|
246
|
+
raise NotImplementedError
|
|
247
|
+
|
|
248
|
+
def copy(self):
|
|
249
|
+
return copy.copy(self)
|
|
250
|
+
|
|
251
|
+
def __copy__(self):
|
|
252
|
+
cls = self.__class__
|
|
253
|
+
result = cls.__new__(cls)
|
|
254
|
+
result.__dict__.update(self.__dict__)
|
|
255
|
+
return result
|
|
256
|
+
|
|
257
|
+
def __deepcopy__(self, memodict=None):
|
|
258
|
+
cls = self.__class__
|
|
259
|
+
result = cls.__new__(cls)
|
|
260
|
+
memodict[id(self)] = result
|
|
261
|
+
for k, v in self.__dict__.items():
|
|
262
|
+
setattr(result, k, copy.deepcopy(v, memodict))
|
|
263
|
+
return result
|