ngio 0.5.0b6__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.
- ngio/__init__.py +69 -0
- ngio/common/__init__.py +28 -0
- ngio/common/_dimensions.py +335 -0
- ngio/common/_masking_roi.py +153 -0
- ngio/common/_pyramid.py +408 -0
- ngio/common/_roi.py +315 -0
- ngio/common/_synt_images_utils.py +101 -0
- ngio/common/_zoom.py +188 -0
- ngio/experimental/__init__.py +5 -0
- ngio/experimental/iterators/__init__.py +15 -0
- ngio/experimental/iterators/_abstract_iterator.py +390 -0
- ngio/experimental/iterators/_feature.py +189 -0
- ngio/experimental/iterators/_image_processing.py +130 -0
- ngio/experimental/iterators/_mappers.py +48 -0
- ngio/experimental/iterators/_rois_utils.py +126 -0
- ngio/experimental/iterators/_segmentation.py +235 -0
- ngio/hcs/__init__.py +19 -0
- ngio/hcs/_plate.py +1354 -0
- ngio/images/__init__.py +44 -0
- ngio/images/_abstract_image.py +967 -0
- ngio/images/_create_synt_container.py +132 -0
- ngio/images/_create_utils.py +423 -0
- ngio/images/_image.py +926 -0
- ngio/images/_label.py +411 -0
- ngio/images/_masked_image.py +531 -0
- ngio/images/_ome_zarr_container.py +1237 -0
- ngio/images/_table_ops.py +471 -0
- ngio/io_pipes/__init__.py +75 -0
- ngio/io_pipes/_io_pipes.py +361 -0
- ngio/io_pipes/_io_pipes_masked.py +488 -0
- ngio/io_pipes/_io_pipes_roi.py +146 -0
- ngio/io_pipes/_io_pipes_types.py +56 -0
- ngio/io_pipes/_match_shape.py +377 -0
- ngio/io_pipes/_ops_axes.py +344 -0
- ngio/io_pipes/_ops_slices.py +411 -0
- ngio/io_pipes/_ops_slices_utils.py +199 -0
- ngio/io_pipes/_ops_transforms.py +104 -0
- ngio/io_pipes/_zoom_transform.py +180 -0
- ngio/ome_zarr_meta/__init__.py +65 -0
- ngio/ome_zarr_meta/_meta_handlers.py +536 -0
- ngio/ome_zarr_meta/ngio_specs/__init__.py +77 -0
- ngio/ome_zarr_meta/ngio_specs/_axes.py +515 -0
- ngio/ome_zarr_meta/ngio_specs/_channels.py +462 -0
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +89 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +539 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +438 -0
- ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +122 -0
- ngio/ome_zarr_meta/v04/__init__.py +27 -0
- ngio/ome_zarr_meta/v04/_custom_models.py +18 -0
- ngio/ome_zarr_meta/v04/_v04_spec.py +473 -0
- ngio/ome_zarr_meta/v05/__init__.py +27 -0
- ngio/ome_zarr_meta/v05/_custom_models.py +18 -0
- ngio/ome_zarr_meta/v05/_v05_spec.py +511 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
- ngio/resources/__init__.py +55 -0
- ngio/resources/resource_model.py +36 -0
- ngio/tables/__init__.py +43 -0
- ngio/tables/_abstract_table.py +270 -0
- ngio/tables/_tables_container.py +449 -0
- ngio/tables/backends/__init__.py +57 -0
- ngio/tables/backends/_abstract_backend.py +240 -0
- ngio/tables/backends/_anndata.py +139 -0
- ngio/tables/backends/_anndata_utils.py +90 -0
- ngio/tables/backends/_csv.py +19 -0
- ngio/tables/backends/_json.py +92 -0
- ngio/tables/backends/_parquet.py +19 -0
- ngio/tables/backends/_py_arrow_backends.py +222 -0
- ngio/tables/backends/_table_backends.py +226 -0
- ngio/tables/backends/_utils.py +608 -0
- ngio/tables/v1/__init__.py +23 -0
- ngio/tables/v1/_condition_table.py +71 -0
- ngio/tables/v1/_feature_table.py +125 -0
- ngio/tables/v1/_generic_table.py +49 -0
- ngio/tables/v1/_roi_table.py +575 -0
- ngio/transforms/__init__.py +5 -0
- ngio/transforms/_zoom.py +19 -0
- ngio/utils/__init__.py +45 -0
- ngio/utils/_cache.py +48 -0
- ngio/utils/_datasets.py +165 -0
- ngio/utils/_errors.py +37 -0
- ngio/utils/_fractal_fsspec_store.py +42 -0
- ngio/utils/_zarr_utils.py +534 -0
- ngio-0.5.0b6.dist-info/METADATA +148 -0
- ngio-0.5.0b6.dist-info/RECORD +88 -0
- ngio-0.5.0b6.dist-info/WHEEL +4 -0
- ngio-0.5.0b6.dist-info/licenses/LICENSE +28 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
import dask.array as da
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from ngio.utils import NgioValueError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Action(str, Enum):
|
|
12
|
+
NONE = "none"
|
|
13
|
+
PAD = "pad"
|
|
14
|
+
TRIM = "trim"
|
|
15
|
+
RESCALING = "rescaling"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _compute_pad_widths(
|
|
19
|
+
array_shape: tuple[int, ...],
|
|
20
|
+
actions: list[Action],
|
|
21
|
+
target_shape: tuple[int, ...],
|
|
22
|
+
) -> tuple[tuple[int, int], ...]:
|
|
23
|
+
pad_def = []
|
|
24
|
+
for act, s, ts in zip(actions, array_shape, target_shape, strict=True):
|
|
25
|
+
if act == Action.PAD:
|
|
26
|
+
total_pad = ts - s
|
|
27
|
+
before = total_pad // 2
|
|
28
|
+
after = total_pad - before
|
|
29
|
+
pad_def.append((before, after))
|
|
30
|
+
else:
|
|
31
|
+
pad_def.append((0, 0))
|
|
32
|
+
warnings.warn(
|
|
33
|
+
f"Images have a different shape ({array_shape} vs {target_shape}). "
|
|
34
|
+
f"Resolving by padding: {pad_def}",
|
|
35
|
+
stacklevel=2,
|
|
36
|
+
)
|
|
37
|
+
return tuple(pad_def)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _numpy_pad(
|
|
41
|
+
array: np.ndarray,
|
|
42
|
+
actions: list[Action],
|
|
43
|
+
target_shape: tuple[int, ...],
|
|
44
|
+
pad_mode: str = "constant",
|
|
45
|
+
constant_values: int | float = 0,
|
|
46
|
+
) -> np.ndarray:
|
|
47
|
+
if all(act != Action.PAD for act in actions):
|
|
48
|
+
return array
|
|
49
|
+
pad_widths = _compute_pad_widths(array.shape, actions, target_shape)
|
|
50
|
+
return np.pad(array, pad_widths, mode=pad_mode, constant_values=constant_values) # type: ignore
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _dask_pad(
|
|
54
|
+
array: da.Array,
|
|
55
|
+
actions: list[Action],
|
|
56
|
+
target_shape: tuple[int, ...],
|
|
57
|
+
pad_mode: str = "constant",
|
|
58
|
+
constant_values: int | float = 0,
|
|
59
|
+
) -> da.Array:
|
|
60
|
+
if all(act != Action.PAD for act in actions):
|
|
61
|
+
return array
|
|
62
|
+
shape = tuple(int(s) for s in array.shape)
|
|
63
|
+
pad_widths = _compute_pad_widths(shape, actions, target_shape)
|
|
64
|
+
return da.pad(array, pad_widths, mode=pad_mode, constant_values=constant_values)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _compute_trim_slices(
|
|
68
|
+
array_shape: tuple[int, ...],
|
|
69
|
+
actions: list[Action],
|
|
70
|
+
target_shape: tuple[int, ...],
|
|
71
|
+
) -> tuple[slice, ...]:
|
|
72
|
+
slices = []
|
|
73
|
+
for act, s, ts in zip(actions, array_shape, target_shape, strict=True):
|
|
74
|
+
if act == Action.TRIM:
|
|
75
|
+
slices.append(slice(0, ts))
|
|
76
|
+
else:
|
|
77
|
+
slices.append(slice(0, s))
|
|
78
|
+
|
|
79
|
+
warnings.warn(
|
|
80
|
+
f"Images have a different shape ({array_shape} vs {target_shape}). "
|
|
81
|
+
f"Resolving by trimming: {slices}",
|
|
82
|
+
stacklevel=2,
|
|
83
|
+
)
|
|
84
|
+
return tuple(slices)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _numpy_trim(
|
|
88
|
+
array: np.ndarray, actions: list[Action], target_shape: tuple[int, ...]
|
|
89
|
+
) -> np.ndarray:
|
|
90
|
+
if all(act != Action.TRIM for act in actions):
|
|
91
|
+
return array
|
|
92
|
+
slices = _compute_trim_slices(array.shape, actions, target_shape)
|
|
93
|
+
return array[tuple(slices)]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _dask_trim(
|
|
97
|
+
array: da.Array, actions: list[Action], target_shape: tuple[int, ...]
|
|
98
|
+
) -> da.Array:
|
|
99
|
+
if all(act != Action.TRIM for act in actions):
|
|
100
|
+
return array
|
|
101
|
+
shape = tuple(int(s) for s in array.shape)
|
|
102
|
+
slices = _compute_trim_slices(shape, actions, target_shape)
|
|
103
|
+
return array[tuple(slices)]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _compute_rescaling_shape(
|
|
107
|
+
array_shape: tuple[int, ...],
|
|
108
|
+
actions: list[Action],
|
|
109
|
+
target_shape: tuple[int, ...],
|
|
110
|
+
) -> tuple[int, ...]:
|
|
111
|
+
rescaling_shape = []
|
|
112
|
+
factor = []
|
|
113
|
+
for act, s, ts in zip(actions, array_shape, target_shape, strict=True):
|
|
114
|
+
if act == Action.RESCALING:
|
|
115
|
+
rescaling_shape.append(ts)
|
|
116
|
+
factor.append(ts / s)
|
|
117
|
+
else:
|
|
118
|
+
rescaling_shape.append(s)
|
|
119
|
+
factor.append(1.0)
|
|
120
|
+
|
|
121
|
+
warnings.warn(
|
|
122
|
+
f"Images have a different shape ({array_shape} vs {target_shape}). "
|
|
123
|
+
f"Resolving by scaling with factors {factor}.",
|
|
124
|
+
stacklevel=2,
|
|
125
|
+
)
|
|
126
|
+
return tuple(rescaling_shape)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _numpy_rescaling(
|
|
130
|
+
array: np.ndarray, actions: list[Action], target_shape: tuple[int, ...]
|
|
131
|
+
) -> np.ndarray:
|
|
132
|
+
if all(act != Action.RESCALING for act in actions):
|
|
133
|
+
return array
|
|
134
|
+
from ngio.common._zoom import numpy_zoom
|
|
135
|
+
|
|
136
|
+
rescaling_shape = _compute_rescaling_shape(array.shape, actions, target_shape)
|
|
137
|
+
return numpy_zoom(source_array=array, target_shape=rescaling_shape, order="nearest")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _dask_rescaling(
|
|
141
|
+
array: da.Array, actions: list[Action], target_shape: tuple[int, ...]
|
|
142
|
+
) -> da.Array:
|
|
143
|
+
if all(act != Action.RESCALING for act in actions):
|
|
144
|
+
return array
|
|
145
|
+
from ngio.common._zoom import dask_zoom
|
|
146
|
+
|
|
147
|
+
shape = tuple(int(s) for s in array.shape)
|
|
148
|
+
rescaling_shape = _compute_rescaling_shape(shape, actions, target_shape)
|
|
149
|
+
return dask_zoom(source_array=array, target_shape=rescaling_shape, order="nearest")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _check_axes(array_shape, reference_shape, array_axes, reference_axes):
|
|
153
|
+
if len(array_shape) != len(array_axes):
|
|
154
|
+
raise NgioValueError(
|
|
155
|
+
f"Array shape {array_shape} and reference axes {array_axes} "
|
|
156
|
+
"must have the same number of dimensions."
|
|
157
|
+
)
|
|
158
|
+
if len(reference_shape) != len(reference_axes):
|
|
159
|
+
raise NgioValueError(
|
|
160
|
+
f"Reference shape {reference_shape} and reference axes {reference_axes} "
|
|
161
|
+
"must have the same number of dimensions."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# Check if the array axes are a subset of the target axes
|
|
165
|
+
diff = set(array_axes) - set(reference_axes)
|
|
166
|
+
if diff:
|
|
167
|
+
raise NgioValueError(
|
|
168
|
+
f"Array axes {array_axes} are not a subset "
|
|
169
|
+
f"of reference axes {reference_axes}"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Array must be smaller or equal in number of dimensions
|
|
173
|
+
if len(array_axes) > len(reference_axes):
|
|
174
|
+
raise NgioValueError(
|
|
175
|
+
f"Array has more dimensions ({len(array_axes)}) "
|
|
176
|
+
f"than reference ({len(reference_axes)}). "
|
|
177
|
+
"Cannot match shapes if the array has more dimensions."
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _compute_reshape_and_actions(
|
|
182
|
+
array_shape: tuple[int, ...],
|
|
183
|
+
reference_shape: tuple[int, ...],
|
|
184
|
+
array_axes: list[str],
|
|
185
|
+
reference_axes: list[str],
|
|
186
|
+
tolerance: int = 1,
|
|
187
|
+
allow_rescaling: bool = True,
|
|
188
|
+
) -> tuple[tuple[int, ...], list[Action]]:
|
|
189
|
+
# Reshape array to match reference shape
|
|
190
|
+
# And determine actions to be taken
|
|
191
|
+
# to match the shapes
|
|
192
|
+
reshape_tuple = []
|
|
193
|
+
actions = []
|
|
194
|
+
errors = []
|
|
195
|
+
left_pointer = 0
|
|
196
|
+
for ref_ax, ref_shape in zip(reference_axes, reference_shape, strict=True):
|
|
197
|
+
if ref_ax not in array_axes:
|
|
198
|
+
reshape_tuple.append(1)
|
|
199
|
+
actions.append(Action.NONE)
|
|
200
|
+
elif ref_ax == array_axes[left_pointer]:
|
|
201
|
+
s2 = array_shape[left_pointer]
|
|
202
|
+
reshape_tuple.append(s2)
|
|
203
|
+
left_pointer += 1
|
|
204
|
+
|
|
205
|
+
if s2 == ref_shape or s2 == 1:
|
|
206
|
+
actions.append(Action.NONE)
|
|
207
|
+
elif s2 < ref_shape:
|
|
208
|
+
if (ref_shape - s2) <= tolerance:
|
|
209
|
+
actions.append(Action.PAD)
|
|
210
|
+
elif allow_rescaling:
|
|
211
|
+
actions.append(Action.RESCALING)
|
|
212
|
+
else:
|
|
213
|
+
errors.append(
|
|
214
|
+
f"Cannot pad axis={ref_ax}:{s2}->{ref_shape} "
|
|
215
|
+
"because shape difference is outside tolerance "
|
|
216
|
+
f"{tolerance}."
|
|
217
|
+
)
|
|
218
|
+
elif s2 > ref_shape:
|
|
219
|
+
if (s2 - ref_shape) <= tolerance:
|
|
220
|
+
actions.append(Action.TRIM)
|
|
221
|
+
elif allow_rescaling:
|
|
222
|
+
actions.append(Action.RESCALING)
|
|
223
|
+
else:
|
|
224
|
+
errors.append(
|
|
225
|
+
f"Cannot trim axis={ref_ax}:{s2}->{ref_shape} "
|
|
226
|
+
"because shape difference is outside tolerance "
|
|
227
|
+
f"{tolerance}."
|
|
228
|
+
)
|
|
229
|
+
else:
|
|
230
|
+
raise RuntimeError("Unreachable code reached.")
|
|
231
|
+
else:
|
|
232
|
+
raise NgioValueError(
|
|
233
|
+
f"Axes order mismatch {array_axes} -> {reference_axes}. "
|
|
234
|
+
"Cannot match shapes if the order is different."
|
|
235
|
+
)
|
|
236
|
+
if errors:
|
|
237
|
+
raise NgioValueError(
|
|
238
|
+
"Array shape cannot be matched to reference shape:\n\n".join(errors)
|
|
239
|
+
)
|
|
240
|
+
return tuple(reshape_tuple), actions
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def numpy_match_shape(
|
|
244
|
+
array: np.ndarray,
|
|
245
|
+
reference_shape: tuple[int, ...],
|
|
246
|
+
array_axes: Sequence[str],
|
|
247
|
+
reference_axes: Sequence[str],
|
|
248
|
+
tolerance: int = 1,
|
|
249
|
+
pad_mode: str = "constant",
|
|
250
|
+
pad_values: int | float = 0,
|
|
251
|
+
allow_rescaling: bool = True,
|
|
252
|
+
):
|
|
253
|
+
"""Match the shape of a numpy array to a reference shape.
|
|
254
|
+
|
|
255
|
+
This function will reshape, pad, trim and broadcast the input array
|
|
256
|
+
to match the reference shape. If the shapes cannot be matched within
|
|
257
|
+
the specified tolerance, an error is raised.
|
|
258
|
+
|
|
259
|
+
The reference axes must be a superset of the array axes, and the order
|
|
260
|
+
of the axes must be the same.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
array (np.ndarray): The input array to be reshaped.
|
|
264
|
+
reference_shape (tuple[int, ...]): The target shape to match.
|
|
265
|
+
array_axes (Sequence[str]): The axes names of the input array.
|
|
266
|
+
reference_axes (Sequence[str]): The axes names of the reference shape.
|
|
267
|
+
tolerance (int): The maximum number of pixels by which dimensions
|
|
268
|
+
can differ when matching shapes.
|
|
269
|
+
allow_broadcast (bool): If True, allow broadcasting new dimensions to
|
|
270
|
+
match the reference shape. If False, single-dimension axes will
|
|
271
|
+
be left as is.
|
|
272
|
+
pad_mode (str): The mode to use for padding. See numpy.pad for options.
|
|
273
|
+
pad_values (int | float): The constant value to use for padding if
|
|
274
|
+
pad_mode is 'constant'.
|
|
275
|
+
allow_rescaling (bool): If True, when the array differs more than the
|
|
276
|
+
tolerance, it will be rescalingd to the reference shape. If False,
|
|
277
|
+
an error will be raised.
|
|
278
|
+
"""
|
|
279
|
+
_check_axes(
|
|
280
|
+
array_shape=array.shape,
|
|
281
|
+
reference_shape=reference_shape,
|
|
282
|
+
array_axes=array_axes,
|
|
283
|
+
reference_axes=reference_axes,
|
|
284
|
+
)
|
|
285
|
+
if array.shape == reference_shape:
|
|
286
|
+
# Shapes already match
|
|
287
|
+
return array
|
|
288
|
+
|
|
289
|
+
array_axes = list(array_axes)
|
|
290
|
+
reference_axes = list(reference_axes)
|
|
291
|
+
|
|
292
|
+
reshape_tuple, actions = _compute_reshape_and_actions(
|
|
293
|
+
array_shape=array.shape,
|
|
294
|
+
reference_shape=reference_shape,
|
|
295
|
+
array_axes=array_axes,
|
|
296
|
+
reference_axes=reference_axes,
|
|
297
|
+
tolerance=tolerance,
|
|
298
|
+
allow_rescaling=allow_rescaling,
|
|
299
|
+
)
|
|
300
|
+
array = array.reshape(reshape_tuple)
|
|
301
|
+
array = _numpy_rescaling(array=array, actions=actions, target_shape=reference_shape)
|
|
302
|
+
array = _numpy_pad(
|
|
303
|
+
array=array,
|
|
304
|
+
actions=actions,
|
|
305
|
+
target_shape=reference_shape,
|
|
306
|
+
pad_mode=pad_mode,
|
|
307
|
+
constant_values=pad_values,
|
|
308
|
+
)
|
|
309
|
+
array = _numpy_trim(array=array, actions=actions, target_shape=reference_shape)
|
|
310
|
+
return array
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def dask_match_shape(
|
|
314
|
+
array: da.Array,
|
|
315
|
+
reference_shape: tuple[int, ...],
|
|
316
|
+
array_axes: Sequence[str],
|
|
317
|
+
reference_axes: Sequence[str],
|
|
318
|
+
tolerance: int = 1,
|
|
319
|
+
pad_mode: str = "constant",
|
|
320
|
+
pad_values: int | float = 0,
|
|
321
|
+
allow_rescaling: bool = True,
|
|
322
|
+
) -> da.Array:
|
|
323
|
+
"""Match the shape of a dask array to a reference shape.
|
|
324
|
+
|
|
325
|
+
This function will reshape, pad, trim and broadcast the input array
|
|
326
|
+
to match the reference shape. If the shapes cannot be matched within
|
|
327
|
+
the specified tolerance, an error is raised.
|
|
328
|
+
|
|
329
|
+
The reference axes must be a superset of the array axes, and the order
|
|
330
|
+
of the axes must be the same.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
array (da.Array): The input array to be reshaped.
|
|
334
|
+
reference_shape (tuple[int, ...]): The target shape to match.
|
|
335
|
+
array_axes (Sequence[str]): The axes names of the input array.
|
|
336
|
+
reference_axes (Sequence[str]): The axes names of the reference shape.
|
|
337
|
+
tolerance (int): The maximum number of pixels by which dimensions
|
|
338
|
+
can differ when matching shapes.
|
|
339
|
+
pad_mode (str): The mode to use for padding. See numpy.pad for options.
|
|
340
|
+
pad_values (int | float): The constant value to use for padding if
|
|
341
|
+
pad_mode is 'constant'.
|
|
342
|
+
allow_rescaling (bool): If True, when the array differs more than the
|
|
343
|
+
tolerance, it will be rescalingd to the reference shape. If False,
|
|
344
|
+
an error will be raised.
|
|
345
|
+
"""
|
|
346
|
+
array_shape = tuple(int(s) for s in array.shape)
|
|
347
|
+
_check_axes(
|
|
348
|
+
array_shape=array_shape,
|
|
349
|
+
reference_shape=reference_shape,
|
|
350
|
+
array_axes=array_axes,
|
|
351
|
+
reference_axes=reference_axes,
|
|
352
|
+
)
|
|
353
|
+
if array_shape == reference_shape:
|
|
354
|
+
# Shapes already match
|
|
355
|
+
return array
|
|
356
|
+
array_axes = list(array_axes)
|
|
357
|
+
reference_axes = list(reference_axes)
|
|
358
|
+
|
|
359
|
+
reshape_tuple, actions = _compute_reshape_and_actions(
|
|
360
|
+
array_shape=tuple(int(s) for s in array.shape),
|
|
361
|
+
reference_shape=reference_shape,
|
|
362
|
+
array_axes=array_axes,
|
|
363
|
+
reference_axes=reference_axes,
|
|
364
|
+
tolerance=tolerance,
|
|
365
|
+
allow_rescaling=allow_rescaling,
|
|
366
|
+
)
|
|
367
|
+
array = da.reshape(array, reshape_tuple)
|
|
368
|
+
array = _dask_rescaling(array=array, actions=actions, target_shape=reference_shape)
|
|
369
|
+
array = _dask_pad(
|
|
370
|
+
array=array,
|
|
371
|
+
actions=actions,
|
|
372
|
+
target_shape=reference_shape,
|
|
373
|
+
pad_mode=pad_mode,
|
|
374
|
+
constant_values=pad_values,
|
|
375
|
+
)
|
|
376
|
+
array = _dask_trim(array=array, actions=actions, target_shape=reference_shape)
|
|
377
|
+
return array
|