|
35 | 35 | ArrayOfIntOrBool = npt.NDArray[np.intp] | npt.NDArray[np.bool_] |
36 | 36 | BasicSelector = int | slice | EllipsisType |
37 | 37 | Selector = BasicSelector | ArrayOfIntOrBool |
38 | | - |
39 | 38 | BasicSelection = BasicSelector | tuple[BasicSelector, ...] # also used for BlockIndex |
40 | 39 | CoordinateSelection = IntSequence | tuple[IntSequence, ...] |
41 | 40 | MaskSelection = npt.NDArray[np.bool_] |
@@ -75,6 +74,15 @@ def err_too_many_indices(selection: Any, shape: ChunkCoords) -> None: |
75 | 74 | raise IndexError(f"too many indices for array; expected {len(shape)}, got {len(selection)}") |
76 | 75 |
|
77 | 76 |
|
| 77 | +def _zarr_array_to_int_or_bool_array(arr: Array) -> npt.NDArray[np.intp] | npt.NDArray[np.bool_]: |
| 78 | + if arr.dtype.kind in ("i", "b"): |
| 79 | + return np.asarray(arr) |
| 80 | + else: |
| 81 | + raise IndexError( |
| 82 | + f"Invalid array dtype: {arr.dtype}. Arrays used as indices must be of integer or boolean type" |
| 83 | + ) |
| 84 | + |
| 85 | + |
78 | 86 | @runtime_checkable |
79 | 87 | class Indexer(Protocol): |
80 | 88 | shape: ChunkCoords |
@@ -842,7 +850,14 @@ def __iter__(self) -> Iterator[ChunkProjection]: |
842 | 850 | class OIndex: |
843 | 851 | array: Array |
844 | 852 |
|
845 | | - def __getitem__(self, selection: OrthogonalSelection) -> NDArrayLike: |
| 853 | + # TODO: develop Array generic and move zarr.Array[np.intp] | zarr.Array[np.bool_] to ArrayOfIntOrBool |
| 854 | + def __getitem__(self, selection: OrthogonalSelection | Array) -> NDArrayLike: |
| 855 | + from zarr.core.array import Array |
| 856 | + |
| 857 | + # if input is a Zarr array, we materialize it now. |
| 858 | + if isinstance(selection, Array): |
| 859 | + selection = _zarr_array_to_int_or_bool_array(selection) |
| 860 | + |
846 | 861 | fields, new_selection = pop_fields(selection) |
847 | 862 | new_selection = ensure_tuple(new_selection) |
848 | 863 | new_selection = replace_lists(new_selection) |
@@ -1130,7 +1145,13 @@ def __init__(self, selection: MaskSelection, shape: ChunkCoords, chunk_grid: Chu |
1130 | 1145 | class VIndex: |
1131 | 1146 | array: Array |
1132 | 1147 |
|
1133 | | - def __getitem__(self, selection: CoordinateSelection | MaskSelection) -> NDArrayLike: |
| 1148 | + # TODO: develop Array generic and move zarr.Array[np.intp] | zarr.Array[np.bool_] to ArrayOfIntOrBool |
| 1149 | + def __getitem__(self, selection: CoordinateSelection | MaskSelection | Array) -> NDArrayLike: |
| 1150 | + from zarr.core.array import Array |
| 1151 | + |
| 1152 | + # if input is a Zarr array, we materialize it now. |
| 1153 | + if isinstance(selection, Array): |
| 1154 | + selection = _zarr_array_to_int_or_bool_array(selection) |
1134 | 1155 | fields, new_selection = pop_fields(selection) |
1135 | 1156 | new_selection = ensure_tuple(new_selection) |
1136 | 1157 | new_selection = replace_lists(new_selection) |
|
0 commit comments