ewoksid02 0.1.0__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.
- ewoksid02/__init__.py +0 -0
- ewoksid02/ocl/__init__.py +0 -0
- ewoksid02/resources/__init__.py +8 -0
- ewoksid02/resources/saxs_loop.json +96 -0
- ewoksid02/resources/template_saxs.yaml +37 -0
- ewoksid02/scripts/__init__.py +0 -0
- ewoksid02/scripts/__main__.py +70 -0
- ewoksid02/scripts/parsers.py +224 -0
- ewoksid02/scripts/saxs/__init__.py +0 -0
- ewoksid02/scripts/saxs/main.py +255 -0
- ewoksid02/scripts/saxs/slurm_python_post_script.py +3 -0
- ewoksid02/scripts/saxs/slurm_python_pre_script.py +5 -0
- ewoksid02/scripts/utils.py +21 -0
- ewoksid02/scripts/xpcs/__init__.py +0 -0
- ewoksid02/scripts/xpcs/__main__.py +3 -0
- ewoksid02/tasks/__init__.py +7 -0
- ewoksid02/tasks/averagetask.py +179 -0
- ewoksid02/tasks/azimuthaltask.py +272 -0
- ewoksid02/tasks/cavingtask.py +170 -0
- ewoksid02/tasks/dahuprocessingtask.py +71 -0
- ewoksid02/tasks/end.py +35 -0
- ewoksid02/tasks/id02processingtask.py +2582 -0
- ewoksid02/tasks/looptask.py +672 -0
- ewoksid02/tasks/metadatatask.py +879 -0
- ewoksid02/tasks/normalizationtask.py +204 -0
- ewoksid02/tasks/scalerstask.py +46 -0
- ewoksid02/tasks/secondaryscatteringtask.py +159 -0
- ewoksid02/tasks/sumtask.py +45 -0
- ewoksid02/tests/__init__.py +3 -0
- ewoksid02/tests/conftest.py +639 -0
- ewoksid02/tests/debug.py +64 -0
- ewoksid02/tests/test_2scat_node.py +119 -0
- ewoksid02/tests/test_ave_node.py +106 -0
- ewoksid02/tests/test_azim_node.py +89 -0
- ewoksid02/tests/test_cave_node.py +118 -0
- ewoksid02/tests/test_norm_node.py +190 -0
- ewoksid02/tests/test_saxs.py +69 -0
- ewoksid02/tests/test_sumtask.py +10 -0
- ewoksid02/tests/utils.py +514 -0
- ewoksid02/utils/__init__.py +22 -0
- ewoksid02/utils/average.py +158 -0
- ewoksid02/utils/blissdata.py +1157 -0
- ewoksid02/utils/caving.py +851 -0
- ewoksid02/utils/cupyutils.py +42 -0
- ewoksid02/utils/io.py +722 -0
- ewoksid02/utils/normalization.py +804 -0
- ewoksid02/utils/pyfai.py +424 -0
- ewoksid02/utils/secondaryscattering.py +597 -0
- ewoksid02-0.1.0.dist-info/METADATA +76 -0
- ewoksid02-0.1.0.dist-info/RECORD +54 -0
- ewoksid02-0.1.0.dist-info/WHEEL +5 -0
- ewoksid02-0.1.0.dist-info/entry_points.txt +5 -0
- ewoksid02-0.1.0.dist-info/licenses/LICENSE.md +20 -0
- ewoksid02-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
|
|
3
|
+
from .io import get_persistent_array_mask
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import cupy
|
|
7
|
+
from .cupyutils import log_allocated_gpu_memory
|
|
8
|
+
except ImportError:
|
|
9
|
+
CUPY_AVAILABLE = False
|
|
10
|
+
CUPY_MEM_POOL = None
|
|
11
|
+
cupy = numpy
|
|
12
|
+
else:
|
|
13
|
+
CUPY_AVAILABLE = True
|
|
14
|
+
CUPY_MEM_POOL = cupy.get_default_memory_pool()
|
|
15
|
+
import logging
|
|
16
|
+
|
|
17
|
+
MASK_PIXELS_AVAILABLE = None
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
logger.setLevel(logging.INFO)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_index_shifted(
|
|
24
|
+
data_shape: tuple,
|
|
25
|
+
center_x: int,
|
|
26
|
+
center_y: int,
|
|
27
|
+
):
|
|
28
|
+
"""Calculates the x,y index vectors, shifted to recreate the centro-symmetric pixels
|
|
29
|
+
|
|
30
|
+
Inputs:
|
|
31
|
+
- data_shape (tuple): shape of the data array (2 dimensional)
|
|
32
|
+
- center_x (int): beam center in the first data dimension
|
|
33
|
+
- center_y (int): beam center in the second data dimension
|
|
34
|
+
Outputs:
|
|
35
|
+
Tuple: pair of shifted x,y index vectors
|
|
36
|
+
"""
|
|
37
|
+
y, x = numpy.meshgrid(
|
|
38
|
+
numpy.arange(data_shape[0]),
|
|
39
|
+
numpy.arange(data_shape[1]),
|
|
40
|
+
indexing="ij",
|
|
41
|
+
sparse=True,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
x_ = 2 * int(center_x) - x + 1
|
|
45
|
+
y_ = 2 * int(center_y) - y + 1
|
|
46
|
+
|
|
47
|
+
# Think it's correct
|
|
48
|
+
return x_, y_
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_position_vectors(
|
|
52
|
+
data_shape: tuple,
|
|
53
|
+
use_cupy: bool = False,
|
|
54
|
+
):
|
|
55
|
+
"""Creates the x,y index vector of a 2-dimensional data array
|
|
56
|
+
|
|
57
|
+
Inputs:
|
|
58
|
+
- data_shape (tuple): shape of the data array (2 dimensional)
|
|
59
|
+
- use_cupy (bool): transfer the vectors to the GPU, ready to process using cupy
|
|
60
|
+
Outputs:
|
|
61
|
+
- Tuple: pair of x-y index vector
|
|
62
|
+
"""
|
|
63
|
+
y_vector, x_vector = numpy.meshgrid(
|
|
64
|
+
numpy.arange(data_shape[0]),
|
|
65
|
+
numpy.arange(data_shape[1]),
|
|
66
|
+
indexing="ij",
|
|
67
|
+
sparse=True,
|
|
68
|
+
)
|
|
69
|
+
if use_cupy:
|
|
70
|
+
return cupy.asarray(x_vector), cupy.asarray(y_vector)
|
|
71
|
+
return x_vector, y_vector
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def shift_position_vectors(
|
|
75
|
+
x_vector: numpy.ndarray,
|
|
76
|
+
y_vector: numpy.ndarray,
|
|
77
|
+
center_x: int,
|
|
78
|
+
center_y: int,
|
|
79
|
+
use_cupy: bool = False,
|
|
80
|
+
):
|
|
81
|
+
"""Shift a pair of index vectors, to point to centro-symmetric brothers
|
|
82
|
+
|
|
83
|
+
Inputs:
|
|
84
|
+
- x_vector (numpy.ndarray) : index vector along the first dimension of array
|
|
85
|
+
- y_vector (numpy.ndarray) : index vector along the second dimension of array
|
|
86
|
+
- center_x (int): beam center in the first data dimension
|
|
87
|
+
- center_y (int): beam center in the second data dimension
|
|
88
|
+
- use_cupy (bool): the return result is transfered to the GPU using cupy
|
|
89
|
+
Outputs:
|
|
90
|
+
- Tuple: pair of shifted x,y index vectors
|
|
91
|
+
"""
|
|
92
|
+
center_x = int(center_x)
|
|
93
|
+
center_y = int(center_y)
|
|
94
|
+
x_shifted = 2 * center_x - x_vector + 1
|
|
95
|
+
y_shifted = 2 * center_y - y_vector + 1
|
|
96
|
+
if use_cupy:
|
|
97
|
+
return cupy.asarray(x_shifted), cupy.asarray(y_shifted)
|
|
98
|
+
return x_shifted, y_shifted
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def get_mask_limits(
|
|
102
|
+
data_shape: tuple = None,
|
|
103
|
+
center_x: int = None,
|
|
104
|
+
center_y: int = None,
|
|
105
|
+
x_shifted: numpy.ndarray = None,
|
|
106
|
+
y_shifted: numpy.ndarray = None,
|
|
107
|
+
only_x_dim: bool = False,
|
|
108
|
+
only_y_dim: bool = False,
|
|
109
|
+
use_cupy: bool = False,
|
|
110
|
+
):
|
|
111
|
+
"""
|
|
112
|
+
Mask limits is the primitive mask, it defines the area where the cave can be applied.
|
|
113
|
+
It's the area of the pixels whose centro-symmetric brother falls in the detector surface.
|
|
114
|
+
If the center of the beam matches with the center of the detector, the whole detector area can be caved.
|
|
115
|
+
If the center falls into the edge of the detector, no pixel can be caved.
|
|
116
|
+
|
|
117
|
+
Inputs:
|
|
118
|
+
- data_shape (tuple): shape of the data array (2 dimensional)
|
|
119
|
+
- center_x (int): beam center in the first data dimension
|
|
120
|
+
- center_y (int): beam center in the second data dimension
|
|
121
|
+
- x_shifted (numpy.ndarray) : shifted index vector along the first data dimension
|
|
122
|
+
- y_shifted (numpy.ndarray) : shifted index vector along the second data dimension
|
|
123
|
+
- only_x_dim (bool): if True, returns the mask of the first dimension limits
|
|
124
|
+
- only_y_dim (bool): if True, returns the mask of the second dimension limits
|
|
125
|
+
- use_cupy (bool): the return result is transfered to the GPU using cupy
|
|
126
|
+
Outputs:
|
|
127
|
+
- numpy.ndarray / cupy.ndarray: array to mask the pixels whose centrosymmetric brother falls out of the detector area.
|
|
128
|
+
"""
|
|
129
|
+
if x_shifted is None or y_shifted is None:
|
|
130
|
+
x_vector, y_vector = get_position_vectors(
|
|
131
|
+
data_shape=data_shape,
|
|
132
|
+
use_cupy=use_cupy,
|
|
133
|
+
)
|
|
134
|
+
x_shifted, y_shifted = shift_position_vectors(
|
|
135
|
+
x_vector=x_vector,
|
|
136
|
+
y_vector=y_vector,
|
|
137
|
+
center_x=center_x,
|
|
138
|
+
center_y=center_y,
|
|
139
|
+
use_cupy=use_cupy,
|
|
140
|
+
)
|
|
141
|
+
x_max = x_shifted.shape[-1]
|
|
142
|
+
y_max = y_shifted.shape[0]
|
|
143
|
+
if use_cupy:
|
|
144
|
+
mask_limits_x_cupy = cupy.logical_and(x_shifted > 0, x_shifted < x_max)
|
|
145
|
+
if only_x_dim:
|
|
146
|
+
return mask_limits_x_cupy
|
|
147
|
+
mask_limits_y_cupy = cupy.logical_and(y_shifted > 0, y_shifted < y_max)
|
|
148
|
+
if only_y_dim:
|
|
149
|
+
return mask_limits_y_cupy
|
|
150
|
+
mask_limits_cupy = mask_limits_x_cupy & mask_limits_y_cupy # boolean
|
|
151
|
+
return mask_limits_cupy
|
|
152
|
+
mask_limits_x = numpy.logical_and(x_shifted > 0, x_shifted < x_max)
|
|
153
|
+
if only_x_dim:
|
|
154
|
+
return mask_limits_x
|
|
155
|
+
mask_limits_y = numpy.logical_and(y_shifted > 0, y_shifted < y_max)
|
|
156
|
+
if only_y_dim:
|
|
157
|
+
return mask_limits_y
|
|
158
|
+
mask_limits = mask_limits_x & mask_limits_y # boolean
|
|
159
|
+
return mask_limits
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _mask_caving(
|
|
163
|
+
data_shape: tuple,
|
|
164
|
+
Center_1: int,
|
|
165
|
+
Center_2: int,
|
|
166
|
+
mask_reference: numpy.ndarray = None,
|
|
167
|
+
vertical_symmetry: bool = True,
|
|
168
|
+
horizontal_symmetry: bool = True,
|
|
169
|
+
use_cupy=False,
|
|
170
|
+
) -> numpy.ndarray:
|
|
171
|
+
"""Data-free method, generates the mask with the pixels available. Those pixels whose intensity can be substitued by its centrosymmetric, horz-symmetric or vert-symmetric brother.
|
|
172
|
+
It's determined by the position of the beam center, (the closer to the array center, the more pixels available), and the mask_reference, that determines which pixels will not be caved.
|
|
173
|
+
|
|
174
|
+
Inputs:
|
|
175
|
+
- data_shape (tuple): shape of the data array (2 dimensional)
|
|
176
|
+
- Center_1 (int): beam center in the first data dimension
|
|
177
|
+
- Center_2 (int): beam center in the second data dimension
|
|
178
|
+
- mask_reference (numpy.ndarray): mask with the pixels whose intensity should not be used, that means that their symmetric brother should not be caved
|
|
179
|
+
- vertical_symmetry (bool): the caving performs a vertical flip around the beam center
|
|
180
|
+
- horizontal_symmetry (bool) : the caving performs a horizontal flip around the beam center
|
|
181
|
+
- use_cupy (bool): returns a cupy array
|
|
182
|
+
Outputs:
|
|
183
|
+
- numpy.ndarray, or cupy.ndarray with the available pixels, taken into account the detector limits and the mask reference
|
|
184
|
+
"""
|
|
185
|
+
# Dataset-free method
|
|
186
|
+
# With a reference, this method takes ~20 ms for all operations, < 1ms without reference
|
|
187
|
+
y_vector, x_vector = numpy.meshgrid(
|
|
188
|
+
numpy.arange(data_shape[0]),
|
|
189
|
+
numpy.arange(data_shape[1]),
|
|
190
|
+
indexing="ij",
|
|
191
|
+
sparse=True,
|
|
192
|
+
)
|
|
193
|
+
x_shifted = 2 * int(Center_1) - x_vector + 1
|
|
194
|
+
y_shifted = 2 * int(Center_2) - y_vector + 1
|
|
195
|
+
x_max = x_shifted.shape[-1]
|
|
196
|
+
y_max = y_shifted.shape[0]
|
|
197
|
+
|
|
198
|
+
if vertical_symmetry and horizontal_symmetry:
|
|
199
|
+
# Centrosymmetric caving (standard)
|
|
200
|
+
mask_limits = numpy.logical_and(
|
|
201
|
+
x_shifted > 0, x_shifted < x_max
|
|
202
|
+
) & numpy.logical_and(y_shifted > 0, y_shifted < y_max)
|
|
203
|
+
if mask_reference is None:
|
|
204
|
+
mask_caving = mask_limits
|
|
205
|
+
else:
|
|
206
|
+
mask_caving = mask_limits ^ (
|
|
207
|
+
mask_limits & mask_reference[y_shifted, x_shifted]
|
|
208
|
+
)
|
|
209
|
+
elif horizontal_symmetry:
|
|
210
|
+
# Horizontal flipping around the beam
|
|
211
|
+
mask_limits = numpy.logical_and(x_shifted > 0, x_shifted < x_max)
|
|
212
|
+
if mask_reference is None:
|
|
213
|
+
mask_caving = mask_limits
|
|
214
|
+
else:
|
|
215
|
+
mask_caving = mask_limits ^ (
|
|
216
|
+
mask_limits & mask_reference[y_vector, x_shifted]
|
|
217
|
+
)
|
|
218
|
+
elif vertical_symmetry:
|
|
219
|
+
# Vertical flippinf around the beam
|
|
220
|
+
mask_limits = numpy.logical_and(y_shifted > 0, y_shifted < y_max)
|
|
221
|
+
if mask_reference is None:
|
|
222
|
+
mask_caving = mask_limits
|
|
223
|
+
else:
|
|
224
|
+
mask_caving = mask_limits ^ (
|
|
225
|
+
mask_limits & mask_reference[y_shifted, x_vector]
|
|
226
|
+
)
|
|
227
|
+
else:
|
|
228
|
+
mask_limits = numpy.logical_and(
|
|
229
|
+
x_vector > 0, x_vector < x_max
|
|
230
|
+
) & numpy.logical_and(y_vector > 0, y_vector < y_max)
|
|
231
|
+
if mask_reference is None:
|
|
232
|
+
mask_caving = mask_limits
|
|
233
|
+
else:
|
|
234
|
+
mask_caving = mask_limits ^ (
|
|
235
|
+
mask_limits & mask_reference[y_vector, x_vector]
|
|
236
|
+
)
|
|
237
|
+
if use_cupy:
|
|
238
|
+
return cupy.asarray(mask_caving).astype(bool)
|
|
239
|
+
return mask_caving.astype(bool)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _mask_to_cave(
|
|
243
|
+
data: numpy.ndarray, Dummy: int = None, mask_static: numpy.ndarray = None
|
|
244
|
+
) -> numpy.ndarray:
|
|
245
|
+
"""
|
|
246
|
+
Generates the mask with the pixels that we want to substitute. It's determined by a dummy value and/or by a mask.
|
|
247
|
+
|
|
248
|
+
Inputs:
|
|
249
|
+
- data (numpy.ndarray): data signal, 2 or 3 dimensional
|
|
250
|
+
- Dummy (int): pixels in data with dummy value will be replaced
|
|
251
|
+
- mask_static (numpy.ndarray): pixels that will be replaced
|
|
252
|
+
Outputs:
|
|
253
|
+
- numpy.ndarray: mask whose pixels we want to replace
|
|
254
|
+
"""
|
|
255
|
+
# ~ 1 ms per frame if only Dummy
|
|
256
|
+
# ~ 2 ms per frame if both dummy and mask_static
|
|
257
|
+
# ~0 if only mask_static
|
|
258
|
+
if Dummy and mask_static is not None:
|
|
259
|
+
mask_to_cave = (data == Dummy) + mask_static
|
|
260
|
+
elif Dummy:
|
|
261
|
+
mask_to_cave = data == Dummy
|
|
262
|
+
elif mask_static is not None:
|
|
263
|
+
mask_to_cave = mask_static
|
|
264
|
+
else:
|
|
265
|
+
raise ValueError(
|
|
266
|
+
"Caving has to be determined by a dummy value and/or a static mask"
|
|
267
|
+
)
|
|
268
|
+
return mask_to_cave
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _process_data_caving(
|
|
272
|
+
data: numpy.ndarray,
|
|
273
|
+
pixels_to_cave: numpy.ndarray,
|
|
274
|
+
pixels_to_substitute: numpy.ndarray,
|
|
275
|
+
x_vector: numpy.ndarray,
|
|
276
|
+
y_vector: numpy.ndarray,
|
|
277
|
+
Dummy: int = None,
|
|
278
|
+
mask_dummy_pixels: bool = True,
|
|
279
|
+
use_cupy: bool = False,
|
|
280
|
+
):
|
|
281
|
+
"""Replace the pixels in data according to a mask. The replaced data correspond to a specific index-transformation, determined by input vectors.
|
|
282
|
+
|
|
283
|
+
Inputs:
|
|
284
|
+
- data (numpy.ndarray): data signal, 2 or 3 dimensional
|
|
285
|
+
- mask_to_cave (numpy.ndarray): pixels that will be masked with Dummy or caved (substituted by a symmetric brother)
|
|
286
|
+
|
|
287
|
+
- x_vector (numpy.ndarray): index vector used to shift the data along the first dimension of data array
|
|
288
|
+
- y_vector (numpy.ndarray): index vector used to shift the data along the second dimension of data array
|
|
289
|
+
- Dummy (int): in this method, the dummy value is used to replace the pixels whose replacement falls also into the mask_caving
|
|
290
|
+
- use_cupy (bool): to use cupy, all the inputs must be already in the GPU
|
|
291
|
+
Outputs:
|
|
292
|
+
- numpy.ndarray: data with replaced pixels (caved)
|
|
293
|
+
"""
|
|
294
|
+
# Works for both numpy, cupy, 2 or 3 dimensional, for all cavings
|
|
295
|
+
mask_complete = pixels_to_cave & pixels_to_substitute
|
|
296
|
+
if use_cupy:
|
|
297
|
+
data_caved = cupy.copy(data)
|
|
298
|
+
if mask_dummy_pixels and Dummy:
|
|
299
|
+
cupy.copyto(data_caved, Dummy, where=pixels_to_cave)
|
|
300
|
+
if data.ndim == 3:
|
|
301
|
+
cupy.copyto(
|
|
302
|
+
data_caved, data_caved[:, y_vector, x_vector], where=mask_complete
|
|
303
|
+
)
|
|
304
|
+
elif data.ndim == 2:
|
|
305
|
+
cupy.copyto(data_caved, data_caved[y_vector, x_vector], where=mask_complete)
|
|
306
|
+
else:
|
|
307
|
+
data_caved = numpy.copy(data)
|
|
308
|
+
if mask_dummy_pixels and Dummy:
|
|
309
|
+
numpy.copyto(data_caved, Dummy, where=pixels_to_cave)
|
|
310
|
+
if data.ndim == 3:
|
|
311
|
+
numpy.copyto(
|
|
312
|
+
data_caved, data_caved[:, y_vector, x_vector], where=mask_complete
|
|
313
|
+
)
|
|
314
|
+
elif data.ndim == 2:
|
|
315
|
+
numpy.copyto(
|
|
316
|
+
data_caved, data_caved[y_vector, x_vector], where=mask_complete
|
|
317
|
+
)
|
|
318
|
+
return data_caved
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _process_dataset_caving_numpy(
|
|
322
|
+
dataset: numpy.ndarray,
|
|
323
|
+
Center_1: int,
|
|
324
|
+
Center_2: int,
|
|
325
|
+
Dummy: int = None,
|
|
326
|
+
mask_static: numpy.ndarray = None,
|
|
327
|
+
mask_reference: numpy.ndarray = None,
|
|
328
|
+
flip_caving: bool = False,
|
|
329
|
+
flip_horizontally_preference: bool = True,
|
|
330
|
+
**kwargs,
|
|
331
|
+
) -> numpy.ndarray:
|
|
332
|
+
"""Performs the caving on a 3-dimensional dataset using numpy methods
|
|
333
|
+
|
|
334
|
+
Inputs:
|
|
335
|
+
- dataset (numpy.ndarray): data signal, 3-dimensional
|
|
336
|
+
- Center_1 (int): beam center in the first data dimension
|
|
337
|
+
- Center_2 (int): beam center in the second data dimension
|
|
338
|
+
- Dummy (int): pixels in data with dummy value will be replaced
|
|
339
|
+
- mask_static (numpy.ndarray): pixels that will be replaced
|
|
340
|
+
- mask_reference (numpy.ndarray): mask with the pixels whose intensity should not be used, that means that their symmetric brother should not be caved
|
|
341
|
+
- flip_caving (bool): if True, adds horizontal-symmetric and vertical-symmetric caving (by default, centro-symmetric caving is always performed)
|
|
342
|
+
- flip_horizontally_preference (bool): if flip_caving is activated, horizontal caving is done before vertical caving
|
|
343
|
+
- **kwargs
|
|
344
|
+
Outputs:
|
|
345
|
+
- numpy.ndarray: data with replaced pixels (caved) using numpy methods
|
|
346
|
+
"""
|
|
347
|
+
if dataset.ndim == 2:
|
|
348
|
+
data_shape = dataset.shape
|
|
349
|
+
dataset = dataset[numpy.newaxis, ...]
|
|
350
|
+
elif dataset.ndim == 3:
|
|
351
|
+
data_shape = dataset.shape[1:]
|
|
352
|
+
|
|
353
|
+
y_vector, x_vector = numpy.meshgrid(
|
|
354
|
+
numpy.arange(data_shape[0]),
|
|
355
|
+
numpy.arange(data_shape[1]),
|
|
356
|
+
indexing="ij",
|
|
357
|
+
sparse=True,
|
|
358
|
+
)
|
|
359
|
+
x_shifted = 2 * int(Center_1) - x_vector + 1
|
|
360
|
+
y_shifted = 2 * int(Center_2) - y_vector + 1
|
|
361
|
+
|
|
362
|
+
mask_pixels_available_centrosymmetric = kwargs.get(
|
|
363
|
+
"mask_pixels_available_centrosymmetric"
|
|
364
|
+
)
|
|
365
|
+
mask_pixels_available_horizontal = kwargs.get("mask_pixels_available_horizontal")
|
|
366
|
+
mask_pixels_available_vertical = kwargs.get("mask_pixels_available_vertical")
|
|
367
|
+
if mask_pixels_available_centrosymmetric is None:
|
|
368
|
+
mask_pixels_available_centrosymmetric = _mask_caving(
|
|
369
|
+
data_shape,
|
|
370
|
+
Center_1,
|
|
371
|
+
Center_2,
|
|
372
|
+
mask_reference,
|
|
373
|
+
vertical_symmetry=True,
|
|
374
|
+
horizontal_symmetry=True,
|
|
375
|
+
)
|
|
376
|
+
if flip_caving and mask_pixels_available_horizontal is None:
|
|
377
|
+
mask_pixels_available_horizontal = _mask_caving(
|
|
378
|
+
data_shape,
|
|
379
|
+
Center_1,
|
|
380
|
+
Center_2,
|
|
381
|
+
mask_reference,
|
|
382
|
+
vertical_symmetry=False,
|
|
383
|
+
horizontal_symmetry=True,
|
|
384
|
+
)
|
|
385
|
+
if flip_caving and mask_pixels_available_vertical is None:
|
|
386
|
+
mask_pixels_available_vertical = _mask_caving(
|
|
387
|
+
data_shape,
|
|
388
|
+
Center_1,
|
|
389
|
+
Center_2,
|
|
390
|
+
mask_reference,
|
|
391
|
+
vertical_symmetry=True,
|
|
392
|
+
horizontal_symmetry=False,
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# This is the mask with the pixels that will be, either masked with Dummy or caved
|
|
396
|
+
mask_to_cave = _mask_to_cave(data=dataset, Dummy=Dummy, mask_static=mask_static)
|
|
397
|
+
|
|
398
|
+
data_caved = _process_data_caving(
|
|
399
|
+
data=dataset,
|
|
400
|
+
Dummy=Dummy,
|
|
401
|
+
mask_dummy_pixels=True,
|
|
402
|
+
pixels_to_cave=mask_to_cave,
|
|
403
|
+
pixels_to_substitute=mask_pixels_available_centrosymmetric,
|
|
404
|
+
x_vector=x_shifted,
|
|
405
|
+
y_vector=y_shifted,
|
|
406
|
+
use_cupy=False,
|
|
407
|
+
)
|
|
408
|
+
if flip_caving and Dummy:
|
|
409
|
+
if flip_horizontally_preference:
|
|
410
|
+
# First horizontal caving
|
|
411
|
+
mask_to_cave = data_caved == Dummy
|
|
412
|
+
data_caved = _process_data_caving(
|
|
413
|
+
data=data_caved,
|
|
414
|
+
Dummy=Dummy,
|
|
415
|
+
mask_dummy_pixels=False,
|
|
416
|
+
pixels_to_cave=mask_to_cave,
|
|
417
|
+
pixels_to_substitute=mask_pixels_available_horizontal,
|
|
418
|
+
x_vector=x_shifted,
|
|
419
|
+
y_vector=y_vector,
|
|
420
|
+
use_cupy=False,
|
|
421
|
+
)
|
|
422
|
+
# Second vertical caving
|
|
423
|
+
mask_to_cave = data_caved == Dummy
|
|
424
|
+
data_caved = _process_data_caving(
|
|
425
|
+
data=data_caved,
|
|
426
|
+
Dummy=Dummy,
|
|
427
|
+
mask_dummy_pixels=False,
|
|
428
|
+
pixels_to_cave=mask_to_cave,
|
|
429
|
+
pixels_to_substitute=mask_pixels_available_vertical,
|
|
430
|
+
x_vector=x_vector,
|
|
431
|
+
y_vector=y_shifted,
|
|
432
|
+
use_cupy=False,
|
|
433
|
+
)
|
|
434
|
+
else:
|
|
435
|
+
# First vertical caving
|
|
436
|
+
mask_to_cave = data_caved == Dummy
|
|
437
|
+
data_caved = _process_data_caving(
|
|
438
|
+
data=data_caved,
|
|
439
|
+
Dummy=Dummy,
|
|
440
|
+
mask_dummy_pixels=False,
|
|
441
|
+
pixels_to_cave=mask_to_cave,
|
|
442
|
+
pixels_to_substitute=mask_pixels_available_vertical,
|
|
443
|
+
x_vector=x_vector,
|
|
444
|
+
y_vector=y_shifted,
|
|
445
|
+
use_cupy=False,
|
|
446
|
+
)
|
|
447
|
+
# Second horizontal caving
|
|
448
|
+
mask_to_cave = data_caved == Dummy
|
|
449
|
+
data_caved = _process_data_caving(
|
|
450
|
+
data=data_caved,
|
|
451
|
+
Dummy=Dummy,
|
|
452
|
+
mask_dummy_pixels=False,
|
|
453
|
+
pixels_to_cave=mask_to_cave,
|
|
454
|
+
pixels_to_substitute=mask_pixels_available_horizontal,
|
|
455
|
+
x_vector=x_shifted,
|
|
456
|
+
y_vector=y_vector,
|
|
457
|
+
use_cupy=False,
|
|
458
|
+
)
|
|
459
|
+
return data_caved
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def _process_dataset_caving_cupy(
|
|
463
|
+
dataset: numpy.ndarray,
|
|
464
|
+
Center_1: int,
|
|
465
|
+
Center_2: int,
|
|
466
|
+
Dummy: int = None,
|
|
467
|
+
mask_static: numpy.ndarray = None,
|
|
468
|
+
mask_reference: numpy.ndarray = None,
|
|
469
|
+
flip_caving: bool = False,
|
|
470
|
+
flip_horizontally_preference: bool = True,
|
|
471
|
+
**kwargs,
|
|
472
|
+
) -> numpy.ndarray:
|
|
473
|
+
"""Performs the caving on a 3-dimensional dataset using cupy methods (frame by frame)
|
|
474
|
+
|
|
475
|
+
Inputs:
|
|
476
|
+
- dataset (numpy.ndarray): data signal, 3-dimensional
|
|
477
|
+
- Center_1 (int): beam center in the first data dimension
|
|
478
|
+
- Center_2 (int): beam center in the second data dimension
|
|
479
|
+
- Dummy (int): pixels in data with dummy value will be replaced
|
|
480
|
+
- mask_static (numpy.ndarray): pixels that will be replaced
|
|
481
|
+
- mask_reference (numpy.ndarray): mask with the pixels whose intensity should not be used, that means that their symmetric brother should not be caved
|
|
482
|
+
- flip_caving (bool): if True, adds horizontal-symmetric and vertical-symmetric caving (by default, centro-symmetric caving is always performed)
|
|
483
|
+
- flip_horizontally_preference (bool): if flip_caving is activated, horizontal caving is done before vertical caving
|
|
484
|
+
- **kwargs
|
|
485
|
+
Outputs:
|
|
486
|
+
- numpy.ndarray: data with replaced pixels (caved) using numpy methods
|
|
487
|
+
"""
|
|
488
|
+
log_allocated_gpu_memory()
|
|
489
|
+
if dataset.ndim == 2:
|
|
490
|
+
data_shape = dataset.shape
|
|
491
|
+
dataset = dataset[numpy.newaxis, ...]
|
|
492
|
+
elif dataset.ndim == 3:
|
|
493
|
+
data_shape = dataset.shape[1:]
|
|
494
|
+
|
|
495
|
+
y_vector, x_vector = numpy.meshgrid(
|
|
496
|
+
numpy.arange(data_shape[0]),
|
|
497
|
+
numpy.arange(data_shape[1]),
|
|
498
|
+
indexing="ij",
|
|
499
|
+
sparse=True,
|
|
500
|
+
)
|
|
501
|
+
x_shifted = 2 * int(Center_1) - x_vector + 1
|
|
502
|
+
y_shifted = 2 * int(Center_2) - y_vector + 1
|
|
503
|
+
|
|
504
|
+
x_shifted_cupy = cupy.asarray(x_shifted)
|
|
505
|
+
y_shifted_cupy = cupy.asarray(y_shifted)
|
|
506
|
+
x_vector_cupy = cupy.asarray(x_vector)
|
|
507
|
+
y_vector_cupy = cupy.asarray(y_vector)
|
|
508
|
+
|
|
509
|
+
mask_pixels_available_centrosymmetric = kwargs.get(
|
|
510
|
+
"mask_pixels_available_centrosymmetric"
|
|
511
|
+
)
|
|
512
|
+
mask_pixels_available_horizontal = kwargs.get("mask_pixels_available_horizontal")
|
|
513
|
+
mask_pixels_available_vertical = kwargs.get("mask_pixels_available_vertical")
|
|
514
|
+
if mask_pixels_available_centrosymmetric is None:
|
|
515
|
+
mask_pixels_available_centrosymmetric = _mask_caving(
|
|
516
|
+
data_shape,
|
|
517
|
+
Center_1,
|
|
518
|
+
Center_2,
|
|
519
|
+
mask_reference,
|
|
520
|
+
vertical_symmetry=True,
|
|
521
|
+
horizontal_symmetry=True,
|
|
522
|
+
)
|
|
523
|
+
if flip_caving and mask_pixels_available_horizontal is None:
|
|
524
|
+
mask_pixels_available_horizontal = _mask_caving(
|
|
525
|
+
data_shape,
|
|
526
|
+
Center_1,
|
|
527
|
+
Center_2,
|
|
528
|
+
mask_reference,
|
|
529
|
+
vertical_symmetry=False,
|
|
530
|
+
horizontal_symmetry=True,
|
|
531
|
+
)
|
|
532
|
+
if flip_caving and mask_pixels_available_vertical is None:
|
|
533
|
+
mask_pixels_available_vertical = _mask_caving(
|
|
534
|
+
data_shape,
|
|
535
|
+
Center_1,
|
|
536
|
+
Center_2,
|
|
537
|
+
mask_reference,
|
|
538
|
+
vertical_symmetry=True,
|
|
539
|
+
horizontal_symmetry=False,
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
if mask_static is not None:
|
|
543
|
+
mask_static_cupy = cupy.asarray(mask_static)
|
|
544
|
+
else:
|
|
545
|
+
mask_static_cupy = None
|
|
546
|
+
|
|
547
|
+
mask_pixels_available_centrosymmetric_cupy = cupy.asarray(
|
|
548
|
+
mask_pixels_available_centrosymmetric
|
|
549
|
+
)
|
|
550
|
+
if flip_caving:
|
|
551
|
+
mask_pixels_available_horizontal_cupy = cupy.asarray(
|
|
552
|
+
mask_pixels_available_horizontal
|
|
553
|
+
)
|
|
554
|
+
mask_pixels_available_vertical_cupy = cupy.asarray(
|
|
555
|
+
mask_pixels_available_vertical
|
|
556
|
+
)
|
|
557
|
+
else:
|
|
558
|
+
mask_pixels_available_horizontal_cupy = None
|
|
559
|
+
mask_pixels_available_vertical_cupy = None
|
|
560
|
+
|
|
561
|
+
dataset_caved = numpy.zeros_like(dataset)
|
|
562
|
+
for index_frame, data in enumerate(dataset):
|
|
563
|
+
data_cupy = cupy.asarray(data)
|
|
564
|
+
mask_to_cave = _mask_to_cave(data_cupy, Dummy, mask_static_cupy)
|
|
565
|
+
# mask_complete = mask_to_cave & mask_pixels_available_centrosymmetric_cupy
|
|
566
|
+
data_cupy = _process_data_caving(
|
|
567
|
+
data=data_cupy,
|
|
568
|
+
Dummy=Dummy,
|
|
569
|
+
mask_dummy_pixels=True,
|
|
570
|
+
pixels_to_cave=mask_to_cave,
|
|
571
|
+
pixels_to_substitute=mask_pixels_available_centrosymmetric_cupy,
|
|
572
|
+
x_vector=x_shifted_cupy,
|
|
573
|
+
y_vector=y_shifted_cupy,
|
|
574
|
+
use_cupy=True,
|
|
575
|
+
)
|
|
576
|
+
if flip_caving and Dummy:
|
|
577
|
+
if flip_horizontally_preference:
|
|
578
|
+
# First horizontal caving
|
|
579
|
+
mask_to_cave = data_cupy == Dummy
|
|
580
|
+
data_cupy = _process_data_caving(
|
|
581
|
+
data=data_cupy,
|
|
582
|
+
Dummy=Dummy,
|
|
583
|
+
mask_dummy_pixels=False,
|
|
584
|
+
pixels_to_cave=mask_to_cave,
|
|
585
|
+
pixels_to_substitute=mask_pixels_available_horizontal_cupy,
|
|
586
|
+
x_vector=x_shifted_cupy,
|
|
587
|
+
y_vector=y_vector_cupy,
|
|
588
|
+
use_cupy=True,
|
|
589
|
+
)
|
|
590
|
+
# Second vertical caving
|
|
591
|
+
mask_to_cave = data_cupy == Dummy
|
|
592
|
+
data_cupy = _process_data_caving(
|
|
593
|
+
data=data_cupy,
|
|
594
|
+
Dummy=Dummy,
|
|
595
|
+
mask_dummy_pixels=False,
|
|
596
|
+
pixels_to_cave=mask_to_cave,
|
|
597
|
+
pixels_to_substitute=mask_pixels_available_vertical_cupy,
|
|
598
|
+
x_vector=x_vector_cupy,
|
|
599
|
+
y_vector=y_shifted_cupy,
|
|
600
|
+
use_cupy=True,
|
|
601
|
+
)
|
|
602
|
+
else:
|
|
603
|
+
# First vertical caving
|
|
604
|
+
mask_to_cave = data_cupy == Dummy
|
|
605
|
+
data_cupy = _process_data_caving(
|
|
606
|
+
data=data_cupy,
|
|
607
|
+
Dummy=Dummy,
|
|
608
|
+
mask_dummy_pixels=False,
|
|
609
|
+
pixels_to_cave=mask_to_cave,
|
|
610
|
+
pixels_to_substitute=mask_pixels_available_vertical_cupy,
|
|
611
|
+
x_vector=x_vector_cupy,
|
|
612
|
+
y_vector=y_shifted_cupy,
|
|
613
|
+
use_cupy=True,
|
|
614
|
+
)
|
|
615
|
+
# Second horizontal caving
|
|
616
|
+
mask_to_cave = data_cupy == Dummy
|
|
617
|
+
data_cupy = _process_data_caving(
|
|
618
|
+
data=data_cupy,
|
|
619
|
+
Dummy=Dummy,
|
|
620
|
+
mask_dummy_pixels=False,
|
|
621
|
+
pixels_to_cave=mask_to_cave,
|
|
622
|
+
pixels_to_substitute=mask_pixels_available_horizontal_cupy,
|
|
623
|
+
x_vector=x_shifted_cupy,
|
|
624
|
+
y_vector=y_vector_cupy,
|
|
625
|
+
use_cupy=True,
|
|
626
|
+
)
|
|
627
|
+
dataset_caved[index_frame] = data_cupy.get()
|
|
628
|
+
return dataset_caved
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def _process_data_caving_cupy(
|
|
632
|
+
data_cupy: cupy.ndarray,
|
|
633
|
+
mask_pixels_available_centrosymmetric_cupy: cupy.ndarray,
|
|
634
|
+
x_shifted_cupy: cupy.ndarray,
|
|
635
|
+
y_shifted_cupy: cupy.ndarray,
|
|
636
|
+
Dummy: int = None,
|
|
637
|
+
mask_static_cupy: cupy.ndarray = None,
|
|
638
|
+
flip_caving: bool = False,
|
|
639
|
+
flip_horizontally_preference: bool = True,
|
|
640
|
+
mask_pixels_available_horizontal_cupy: cupy.ndarray = None,
|
|
641
|
+
mask_pixels_available_vertical_cupy: cupy.ndarray = None,
|
|
642
|
+
x_vector_cupy: cupy.ndarray = None,
|
|
643
|
+
y_vector_cupy: cupy.ndarray = None,
|
|
644
|
+
) -> cupy.ndarray:
|
|
645
|
+
"""Performs the caving on a 3-dimensional dataset using cupy methods (frame by frame)
|
|
646
|
+
|
|
647
|
+
Inputs:
|
|
648
|
+
- data_cupy (cupy.ndarray): data signal, 2-dimensional, already on GPU
|
|
649
|
+
- mask_pixels_available_centrosymmetric_cupy (cupy.ndarray): mask with the available pixels to do centrosymmetric caving (already on GPU)
|
|
650
|
+
- x_shifted_cupy (cupy.ndarray): shifted vector of index along the first dimension of data array, already on GPU
|
|
651
|
+
- y_shifted_cupy (cupy.ndarray): shifted vector of index along the second dimension of data array, already on GPU
|
|
652
|
+
- Dummy (int): pixels in data with dummy value will be replaced
|
|
653
|
+
- mask_static_cupy (cupy.ndarray): mask with the pixels that will be replaced, already on GPU
|
|
654
|
+
- flip_caving (bool): if True, adds horizontal-symmetric and vertical-symmetric caving (by default, centro-symmetric caving is always performed)
|
|
655
|
+
- flip_horizontally_preference (bool): if flip_caving is activated, horizontal caving is done before vertical caving
|
|
656
|
+
- mask_pixels_available_horizontal_cupy (cupy.ndarray): mask with the available pixels to do horizontal-symmetric caving (already on GPU)
|
|
657
|
+
- mask_pixels_available_vertical_cupy (cupy.ndarray): mask with the available pixels to do vertical-symmetric caving (already on GPU)
|
|
658
|
+
- x_vector_cupy (cupy.ndarray): vector of index along the first dimension of data array, already on GPU
|
|
659
|
+
- y_vector_cupy (cupy.ndarray): vector of index along the second dimension of data array, already on GPU
|
|
660
|
+
Outputs:
|
|
661
|
+
- cupy.ndarray: data with replaced pixels (caved), still on GPU
|
|
662
|
+
"""
|
|
663
|
+
mask_to_cave = _mask_to_cave(data_cupy, Dummy, mask_static_cupy)
|
|
664
|
+
data_cupy = _process_data_caving(
|
|
665
|
+
data=data_cupy,
|
|
666
|
+
Dummy=Dummy,
|
|
667
|
+
mask_dummy_pixels=True,
|
|
668
|
+
pixels_to_cave=mask_to_cave,
|
|
669
|
+
pixels_to_substitute=mask_pixels_available_centrosymmetric_cupy,
|
|
670
|
+
x_vector=x_shifted_cupy,
|
|
671
|
+
y_vector=y_shifted_cupy,
|
|
672
|
+
use_cupy=True,
|
|
673
|
+
)
|
|
674
|
+
if flip_caving and Dummy:
|
|
675
|
+
if flip_horizontally_preference:
|
|
676
|
+
# First horizontal caving
|
|
677
|
+
mask_to_cave = data_cupy == Dummy
|
|
678
|
+
data_cupy = _process_data_caving(
|
|
679
|
+
data=data_cupy,
|
|
680
|
+
Dummy=Dummy,
|
|
681
|
+
mask_dummy_pixels=False,
|
|
682
|
+
pixels_to_cave=mask_to_cave,
|
|
683
|
+
pixels_to_substitute=mask_pixels_available_horizontal_cupy,
|
|
684
|
+
x_vector=x_shifted_cupy,
|
|
685
|
+
y_vector=y_vector_cupy,
|
|
686
|
+
use_cupy=True,
|
|
687
|
+
)
|
|
688
|
+
# Second vertical caving
|
|
689
|
+
mask_to_cave = data_cupy == Dummy
|
|
690
|
+
data_cupy = _process_data_caving(
|
|
691
|
+
data=data_cupy,
|
|
692
|
+
Dummy=Dummy,
|
|
693
|
+
mask_dummy_pixels=False,
|
|
694
|
+
pixels_to_cave=mask_to_cave,
|
|
695
|
+
pixels_to_substitute=mask_pixels_available_vertical_cupy,
|
|
696
|
+
x_vector=x_vector_cupy,
|
|
697
|
+
y_vector=y_shifted_cupy,
|
|
698
|
+
use_cupy=True,
|
|
699
|
+
)
|
|
700
|
+
else:
|
|
701
|
+
# First vertical caving
|
|
702
|
+
mask_to_cave = data_cupy == Dummy
|
|
703
|
+
data_cupy = _process_data_caving(
|
|
704
|
+
data=data_cupy,
|
|
705
|
+
Dummy=Dummy,
|
|
706
|
+
mask_dummy_pixels=False,
|
|
707
|
+
pixels_to_cave=mask_to_cave,
|
|
708
|
+
pixels_to_substitute=mask_pixels_available_vertical_cupy,
|
|
709
|
+
x_vector=x_vector_cupy,
|
|
710
|
+
y_vector=y_shifted_cupy,
|
|
711
|
+
use_cupy=True,
|
|
712
|
+
)
|
|
713
|
+
# Second horizontal caving
|
|
714
|
+
mask_to_cave = data_cupy == Dummy
|
|
715
|
+
data_cupy = _process_data_caving(
|
|
716
|
+
data=data_cupy,
|
|
717
|
+
Dummy=Dummy,
|
|
718
|
+
mask_dummy_pixels=False,
|
|
719
|
+
pixels_to_cave=mask_to_cave,
|
|
720
|
+
pixels_to_substitute=mask_pixels_available_horizontal_cupy,
|
|
721
|
+
x_vector=x_shifted_cupy,
|
|
722
|
+
y_vector=y_vector_cupy,
|
|
723
|
+
use_cupy=True,
|
|
724
|
+
)
|
|
725
|
+
return data_cupy
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
def process_data_caving(
|
|
729
|
+
data: numpy.ndarray,
|
|
730
|
+
Center_1: int,
|
|
731
|
+
Center_2: int,
|
|
732
|
+
Dummy: int = None,
|
|
733
|
+
filename_mask_static: str = None,
|
|
734
|
+
filename_mask_reference: str = None,
|
|
735
|
+
algorithm: str = "numpy",
|
|
736
|
+
flip_caving: bool = False,
|
|
737
|
+
flip_horizontally_preference: bool = True,
|
|
738
|
+
**kwargs,
|
|
739
|
+
) -> numpy.ndarray:
|
|
740
|
+
"""Performs the caving on a 3-dimensional dataset using numpy methods
|
|
741
|
+
|
|
742
|
+
Inputs:
|
|
743
|
+
- data (numpy.ndarray): data signal, 2 or 3-dimensional
|
|
744
|
+
- Center_1 (int): beam center in the first data dimension
|
|
745
|
+
- Center_2 (int): beam center in the second data dimension
|
|
746
|
+
- Dummy (int): pixels in data with dummy value will be replaced
|
|
747
|
+
- filename_mask_static (str): path to the file with the mask whose pixels we want to replace
|
|
748
|
+
- filename_mask_reference (str): path to the file with the mask whose pixels should not be used, that means that their symmetric brother should not be caved
|
|
749
|
+
- algorithm (str): implementation to perform the caving: numpy or cupy
|
|
750
|
+
- flip_caving (bool): if True, adds horizontal-symmetric and vertical-symmetric caving (by default, centro-symmetric caving is always performed)
|
|
751
|
+
- flip_horizontally_preference (bool): if flip_caving is activated, horizontal caving is done before vertical caving
|
|
752
|
+
- **kwargs
|
|
753
|
+
Outputs:
|
|
754
|
+
- numpy.ndarray: data with replaced pixels (caved) using numpy methods
|
|
755
|
+
"""
|
|
756
|
+
if data.ndim == 2:
|
|
757
|
+
data_signal_shape = data.shape
|
|
758
|
+
data = data[numpy.newaxis, ...]
|
|
759
|
+
elif data.ndim == 3:
|
|
760
|
+
data_signal_shape = data.shape[1:]
|
|
761
|
+
|
|
762
|
+
if algorithm not in ALGORITHMS_AVAILABLE:
|
|
763
|
+
logger.warning(
|
|
764
|
+
f"Algorithm '{algorithm}' is not available. Using '{DEFAULT_ALGORITHM}' instead."
|
|
765
|
+
)
|
|
766
|
+
algorithm = DEFAULT_ALGORITHM
|
|
767
|
+
elif algorithm == "cupy" and not CUPY_AVAILABLE:
|
|
768
|
+
logger.warning(f"CuPy is not available. Using {DEFAULT_ALGORITHM} instead.")
|
|
769
|
+
algorithm = DEFAULT_ALGORITHM
|
|
770
|
+
binning = kwargs.get("binning")
|
|
771
|
+
use_cupy = True if algorithm == "cupy" else False
|
|
772
|
+
|
|
773
|
+
# Load static masks
|
|
774
|
+
mask_static = None
|
|
775
|
+
if filename_mask_static:
|
|
776
|
+
mask_static = get_persistent_array_mask(
|
|
777
|
+
filename_mask=filename_mask_static,
|
|
778
|
+
data_signal_shape=data_signal_shape,
|
|
779
|
+
binning=binning,
|
|
780
|
+
use_cupy=use_cupy,
|
|
781
|
+
)
|
|
782
|
+
if mask_static is not None:
|
|
783
|
+
mask_static = mask_static.astype(bool)
|
|
784
|
+
mask_reference = None
|
|
785
|
+
if filename_mask_reference:
|
|
786
|
+
mask_reference = get_persistent_array_mask(
|
|
787
|
+
filename_mask=filename_mask_reference,
|
|
788
|
+
data_signal_shape=data_signal_shape,
|
|
789
|
+
binning=binning,
|
|
790
|
+
use_cupy=False, # This reference mask won't be cupy
|
|
791
|
+
)
|
|
792
|
+
if mask_reference is not None:
|
|
793
|
+
mask_reference = mask_reference.astype(bool)
|
|
794
|
+
|
|
795
|
+
# This is the mask that contains the only pixels which can be substituted, limited by the detector limits and the reference mask (it's data independent)
|
|
796
|
+
mask_pixels_available_centrosymmetric = _mask_caving(
|
|
797
|
+
data_signal_shape,
|
|
798
|
+
Center_1,
|
|
799
|
+
Center_2,
|
|
800
|
+
mask_reference,
|
|
801
|
+
vertical_symmetry=True,
|
|
802
|
+
horizontal_symmetry=True,
|
|
803
|
+
use_cupy=use_cupy,
|
|
804
|
+
)
|
|
805
|
+
if flip_caving:
|
|
806
|
+
mask_pixels_available_horizontal = _mask_caving(
|
|
807
|
+
data_signal_shape,
|
|
808
|
+
Center_1,
|
|
809
|
+
Center_2,
|
|
810
|
+
mask_reference,
|
|
811
|
+
vertical_symmetry=False,
|
|
812
|
+
horizontal_symmetry=True,
|
|
813
|
+
use_cupy=use_cupy,
|
|
814
|
+
)
|
|
815
|
+
mask_pixels_available_vertical = _mask_caving(
|
|
816
|
+
data_signal_shape,
|
|
817
|
+
Center_1,
|
|
818
|
+
Center_2,
|
|
819
|
+
mask_reference,
|
|
820
|
+
vertical_symmetry=True,
|
|
821
|
+
horizontal_symmetry=False,
|
|
822
|
+
use_cupy=use_cupy,
|
|
823
|
+
)
|
|
824
|
+
else:
|
|
825
|
+
mask_pixels_available_horizontal = None
|
|
826
|
+
mask_pixels_available_vertical = None
|
|
827
|
+
|
|
828
|
+
params_caving = {
|
|
829
|
+
"dataset": data,
|
|
830
|
+
"Center_1": Center_1,
|
|
831
|
+
"Center_2": Center_2,
|
|
832
|
+
"Dummy": Dummy,
|
|
833
|
+
"mask_static": mask_static,
|
|
834
|
+
"mask_reference": mask_reference,
|
|
835
|
+
"flip_caving": flip_caving,
|
|
836
|
+
"flip_horizontally_preference": flip_horizontally_preference,
|
|
837
|
+
"mask_pixels_available_centrosymmetric": mask_pixels_available_centrosymmetric,
|
|
838
|
+
"mask_pixels_available_horizontal": mask_pixels_available_horizontal,
|
|
839
|
+
"mask_pixels_available_vertical": mask_pixels_available_vertical,
|
|
840
|
+
}
|
|
841
|
+
result = ALGORITHMS_AVAILABLE[algorithm]["algorithm"](
|
|
842
|
+
**params_caving,
|
|
843
|
+
)
|
|
844
|
+
return result
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
ALGORITHMS_AVAILABLE = {
|
|
848
|
+
"numpy": {"algorithm": _process_dataset_caving_numpy, "use_cupy": False},
|
|
849
|
+
"cupy": {"algorithm": _process_dataset_caving_cupy, "use_cupy": True},
|
|
850
|
+
}
|
|
851
|
+
DEFAULT_ALGORITHM = "numpy"
|