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.
Files changed (54) hide show
  1. ewoksid02/__init__.py +0 -0
  2. ewoksid02/ocl/__init__.py +0 -0
  3. ewoksid02/resources/__init__.py +8 -0
  4. ewoksid02/resources/saxs_loop.json +96 -0
  5. ewoksid02/resources/template_saxs.yaml +37 -0
  6. ewoksid02/scripts/__init__.py +0 -0
  7. ewoksid02/scripts/__main__.py +70 -0
  8. ewoksid02/scripts/parsers.py +224 -0
  9. ewoksid02/scripts/saxs/__init__.py +0 -0
  10. ewoksid02/scripts/saxs/main.py +255 -0
  11. ewoksid02/scripts/saxs/slurm_python_post_script.py +3 -0
  12. ewoksid02/scripts/saxs/slurm_python_pre_script.py +5 -0
  13. ewoksid02/scripts/utils.py +21 -0
  14. ewoksid02/scripts/xpcs/__init__.py +0 -0
  15. ewoksid02/scripts/xpcs/__main__.py +3 -0
  16. ewoksid02/tasks/__init__.py +7 -0
  17. ewoksid02/tasks/averagetask.py +179 -0
  18. ewoksid02/tasks/azimuthaltask.py +272 -0
  19. ewoksid02/tasks/cavingtask.py +170 -0
  20. ewoksid02/tasks/dahuprocessingtask.py +71 -0
  21. ewoksid02/tasks/end.py +35 -0
  22. ewoksid02/tasks/id02processingtask.py +2582 -0
  23. ewoksid02/tasks/looptask.py +672 -0
  24. ewoksid02/tasks/metadatatask.py +879 -0
  25. ewoksid02/tasks/normalizationtask.py +204 -0
  26. ewoksid02/tasks/scalerstask.py +46 -0
  27. ewoksid02/tasks/secondaryscatteringtask.py +159 -0
  28. ewoksid02/tasks/sumtask.py +45 -0
  29. ewoksid02/tests/__init__.py +3 -0
  30. ewoksid02/tests/conftest.py +639 -0
  31. ewoksid02/tests/debug.py +64 -0
  32. ewoksid02/tests/test_2scat_node.py +119 -0
  33. ewoksid02/tests/test_ave_node.py +106 -0
  34. ewoksid02/tests/test_azim_node.py +89 -0
  35. ewoksid02/tests/test_cave_node.py +118 -0
  36. ewoksid02/tests/test_norm_node.py +190 -0
  37. ewoksid02/tests/test_saxs.py +69 -0
  38. ewoksid02/tests/test_sumtask.py +10 -0
  39. ewoksid02/tests/utils.py +514 -0
  40. ewoksid02/utils/__init__.py +22 -0
  41. ewoksid02/utils/average.py +158 -0
  42. ewoksid02/utils/blissdata.py +1157 -0
  43. ewoksid02/utils/caving.py +851 -0
  44. ewoksid02/utils/cupyutils.py +42 -0
  45. ewoksid02/utils/io.py +722 -0
  46. ewoksid02/utils/normalization.py +804 -0
  47. ewoksid02/utils/pyfai.py +424 -0
  48. ewoksid02/utils/secondaryscattering.py +597 -0
  49. ewoksid02-0.1.0.dist-info/METADATA +76 -0
  50. ewoksid02-0.1.0.dist-info/RECORD +54 -0
  51. ewoksid02-0.1.0.dist-info/WHEEL +5 -0
  52. ewoksid02-0.1.0.dist-info/entry_points.txt +5 -0
  53. ewoksid02-0.1.0.dist-info/licenses/LICENSE.md +20 -0
  54. ewoksid02-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,424 @@
1
+ import logging
2
+ from typing import Optional
3
+ import h5py
4
+ import numexpr
5
+ import numpy
6
+ import os
7
+ from pyFAI import detector_factory
8
+ from pyFAI.method_registry import IntegrationMethod, Method
9
+ from pyFAI.worker import Worker
10
+ from functools import lru_cache
11
+ from ewoksid02.utils.io import (
12
+ get_from_headers,
13
+ get_persistent_array_mask,
14
+ get_persistent_array_dark,
15
+ )
16
+ from ewoksid02.utils.normalization import AzimuthalIntegrator
17
+
18
+ logger = logging.getLogger(__name__)
19
+ logger.setLevel(logging.INFO)
20
+
21
+
22
+ @lru_cache(maxsize=5)
23
+ def _get_persistent_detector_instance(
24
+ data_signal_shape: tuple,
25
+ psize_1: float,
26
+ psize_2: float,
27
+ ) -> Optional[object]:
28
+ """
29
+ Create a detector instance based on the dataset and pixel sizes.
30
+
31
+ Parameters:
32
+ data_signal_shape (tuple): Shape of the 2D data signal frame.
33
+ psize_1 (float): Pixel size in the first dimension.
34
+ psize_2 (float): Pixel size in the second dimension.
35
+
36
+ Returns:
37
+ Optional[object]: A detector instance or None if the dataset is None.
38
+ """
39
+ detector_config = {
40
+ "pixel1": psize_2,
41
+ "pixel2": psize_1,
42
+ }
43
+ detector_instance = detector_factory(name="detector", config=detector_config)
44
+ detector_instance.shape = data_signal_shape
45
+ return detector_instance
46
+
47
+
48
+ def get_persistent_azimuthal_integrator(
49
+ data_signal_shape: tuple,
50
+ headers: dict = None,
51
+ metadata_parameters_group: h5py.Group = None,
52
+ **kwargs,
53
+ ):
54
+ params_headers = {
55
+ "headers": headers,
56
+ "metadata_file_group": metadata_parameters_group,
57
+ }
58
+
59
+ SampleDistance = kwargs.get("SampleDistance")
60
+ if SampleDistance is None:
61
+ SampleDistance = get_from_headers(key="SampleDistance", **params_headers)
62
+ Center_1 = kwargs.get("Center_1")
63
+ if Center_1 is None:
64
+ Center_1 = get_from_headers(key="Center_1", **params_headers)
65
+ Center_2 = kwargs.get("Center_2")
66
+ if Center_2 is None:
67
+ Center_2 = get_from_headers(key="Center_2", **params_headers)
68
+ PSize_1 = kwargs.get("PSize_1")
69
+ if PSize_1 is None:
70
+ PSize_1 = get_from_headers(key="PSize_1", **params_headers)
71
+ PSize_2 = kwargs.get("PSize_2")
72
+ if PSize_2 is None:
73
+ PSize_2 = get_from_headers(key="PSize_2", **params_headers)
74
+ BSize_1 = kwargs.get("BSize_1")
75
+ if BSize_1 is None:
76
+ BSize_1 = get_from_headers(key="BSize_1", **params_headers)
77
+ BSize_2 = kwargs.get("BSize_2")
78
+ if BSize_2 is None:
79
+ BSize_2 = get_from_headers(key="BSize_2", **params_headers)
80
+ wavelength = kwargs.get("WaveLength")
81
+ if wavelength is None:
82
+ wavelength = get_from_headers(key="WaveLength", **params_headers)
83
+ rot1 = kwargs.get("DetectorRotation_2")
84
+ if rot1 is None:
85
+ rot1 = get_from_headers(key="DetectorRotation_2", **params_headers)
86
+ rot2 = kwargs.get("DetectorRotation_1")
87
+ if rot2 is None:
88
+ rot2 = get_from_headers(key="DetectorRotation_1", **params_headers)
89
+ rot3 = kwargs.get("DetectorRotation_3")
90
+ if rot3 is None:
91
+ rot3 = get_from_headers(key="DetectorRotation_3", **params_headers)
92
+
93
+ if BSize_1 != 1 or BSize_2 != 1:
94
+ logger.warning(f"Binning is activated in this detector: ({BSize_1}, {BSize_2})")
95
+
96
+ return _get_persistent_azimuthal_integrator(
97
+ data_signal_shape=data_signal_shape,
98
+ dist=SampleDistance,
99
+ center_1=Center_1,
100
+ center_2=Center_2,
101
+ psize_1=PSize_1,
102
+ psize_2=PSize_2,
103
+ rot1=rot1,
104
+ rot2=rot2,
105
+ rot3=rot3,
106
+ wavelength=wavelength,
107
+ )
108
+
109
+
110
+ @lru_cache(maxsize=5)
111
+ def _get_persistent_azimuthal_integrator(
112
+ data_signal_shape: tuple,
113
+ dist: float,
114
+ wavelength: float,
115
+ psize_1: float,
116
+ psize_2: float,
117
+ center_1: float = None,
118
+ center_2: float = None,
119
+ poni1: float = None,
120
+ poni2: float = None,
121
+ rot1: float = 0.0,
122
+ rot2: float = 0.0,
123
+ rot3: float = 0.0,
124
+ ):
125
+ detector = _get_persistent_detector_instance(
126
+ data_signal_shape=data_signal_shape,
127
+ psize_1=psize_1,
128
+ psize_2=psize_2,
129
+ )
130
+
131
+ if poni1 is None and center_2:
132
+ poni1 = center_2 * psize_2
133
+ if poni2 is None and center_1:
134
+ poni2 = center_1 * psize_1
135
+
136
+ ai_kwargs = {
137
+ "dist": dist,
138
+ "poni1": poni1,
139
+ "poni2": poni2,
140
+ "rot1": rot1,
141
+ "rot2": rot2,
142
+ "rot3": rot3,
143
+ "wavelength": wavelength,
144
+ "detector": detector,
145
+ }
146
+ ai = AzimuthalIntegrator(**ai_kwargs)
147
+ ai.solidAngleArray(absolute=False)
148
+ return ai
149
+
150
+
151
+ def get_gpu_method():
152
+ if (
153
+ IntegrationMethod.select_method(dim=1, split="full", algo="csr", impl="opencl")[
154
+ 0
155
+ ].impl
156
+ == "OpenCL"
157
+ ):
158
+ return Method(dim=2, split="full", algo="csr", impl="opencl", target=(0, 0))
159
+ return Method(dim=2, split="full", algo="csr", impl="cython", target=None)
160
+
161
+
162
+ def guess_npt2_rad(azimuthal_integrator: AzimuthalIntegrator) -> int:
163
+ qmax = azimuthal_integrator.qArray().max()
164
+ dqmin = azimuthal_integrator.deltaQ().min() * 2.0
165
+ return int(qmax / dqmin)
166
+
167
+
168
+ def get_persistent_pyfai_worker(
169
+ azimuthal_integrator: AzimuthalIntegrator,
170
+ filename_mask: str = None,
171
+ integration_options: dict = {},
172
+ npt2_rad: int = None,
173
+ npt2_azim: int = None,
174
+ unit: str = None,
175
+ Dummy: int = None,
176
+ DDummy: float = None,
177
+ method: str = get_gpu_method(),
178
+ binning: tuple = (1, 1),
179
+ **kwargs,
180
+ ):
181
+ if filename_mask and os.path.exists(filename_mask):
182
+ mtime_mask = os.path.getmtime(filename_mask)
183
+ else:
184
+ mtime_mask = None
185
+ filename_mask = None
186
+
187
+ return _get_persistent_pyfai_worker(
188
+ data_signal_shape=azimuthal_integrator.detector.shape,
189
+ dist=azimuthal_integrator.dist,
190
+ wavelength=azimuthal_integrator.wavelength,
191
+ psize_1=azimuthal_integrator.pixel1,
192
+ psize_2=azimuthal_integrator.pixel2,
193
+ poni1=azimuthal_integrator.poni1,
194
+ poni2=azimuthal_integrator.poni2,
195
+ rot1=azimuthal_integrator.rot1,
196
+ rot2=azimuthal_integrator.rot2,
197
+ rot3=azimuthal_integrator.rot3,
198
+ filename_mask=filename_mask,
199
+ mtime_mask=mtime_mask,
200
+ npt2_rad=npt2_rad,
201
+ npt2_azim=npt2_azim,
202
+ unit=unit,
203
+ Dummy=Dummy,
204
+ DDummy=DDummy,
205
+ method=method,
206
+ binning=binning,
207
+ **integration_options,
208
+ )
209
+
210
+
211
+ @lru_cache(maxsize=5)
212
+ def _get_persistent_pyfai_worker(
213
+ data_signal_shape: tuple,
214
+ dist: float,
215
+ wavelength: float,
216
+ psize_1: float,
217
+ psize_2: float,
218
+ center_1: float = None,
219
+ center_2: float = None,
220
+ poni1: float = None,
221
+ poni2: float = None,
222
+ rot1: float = 0.0,
223
+ rot2: float = 0.0,
224
+ rot3: float = 0.0,
225
+ filename_mask: str = None,
226
+ mtime_mask: float = None,
227
+ npt2_rad: int = None,
228
+ npt2_azim: int = None,
229
+ unit: str = None,
230
+ Dummy: int = None,
231
+ DDummy: float = None,
232
+ method: str = get_gpu_method(),
233
+ binning: tuple = (1, 1),
234
+ **integration_options,
235
+ ):
236
+ azimuthal_integrator = _get_persistent_azimuthal_integrator(
237
+ data_signal_shape=data_signal_shape,
238
+ dist=dist,
239
+ center_1=center_1,
240
+ center_2=center_2,
241
+ psize_1=psize_1,
242
+ psize_2=psize_2,
243
+ poni1=poni1,
244
+ poni2=poni2,
245
+ rot1=rot1,
246
+ rot2=rot2,
247
+ rot3=rot3,
248
+ wavelength=wavelength,
249
+ )
250
+
251
+ # integration options
252
+ applied_integration_options = {
253
+ "npt2_rad": int(npt2_rad),
254
+ "npt2_azim": int(npt2_azim),
255
+ "unit": unit,
256
+ "dummy": Dummy,
257
+ "delta_dummy": DDummy,
258
+ "method": (
259
+ (method.split, method.algo, method.impl)
260
+ if isinstance(method, (IntegrationMethod, Method))
261
+ else method
262
+ ),
263
+ }
264
+ applied_integration_options.update(**integration_options)
265
+
266
+ worker = Worker(
267
+ azimuthalIntegrator=azimuthal_integrator,
268
+ shapeIn=azimuthal_integrator.detector.shape,
269
+ shapeOut=(
270
+ applied_integration_options.pop("npt2_azim"),
271
+ applied_integration_options.pop("npt2_rad"),
272
+ ),
273
+ unit=applied_integration_options.pop("unit"),
274
+ dummy=applied_integration_options.pop("dummy"),
275
+ delta_dummy=applied_integration_options.pop("delta_dummy"),
276
+ method=applied_integration_options.pop("method", get_gpu_method()),
277
+ extra_options=applied_integration_options,
278
+ )
279
+ worker.correct_solid_angle = False
280
+ worker.output = "raw"
281
+ worker.error_model = "azimuthal"
282
+ worker.ai._empty = worker.dummy
283
+
284
+ array_mask = get_persistent_array_mask(
285
+ filename_mask=filename_mask,
286
+ data_signal_shape=data_signal_shape,
287
+ binning=binning,
288
+ use_cupy=False,
289
+ )
290
+ if array_mask is not None:
291
+ worker.mask_image = array_mask
292
+ worker.ai.mask = array_mask
293
+ return worker
294
+
295
+
296
+ def process_dataset_azim(
297
+ dataset_signal: numpy.ndarray,
298
+ azimuthal_integrator: AzimuthalIntegrator,
299
+ dataset_variance: numpy.ndarray = None,
300
+ filename_dark: str = None,
301
+ filename_mask: str = None,
302
+ npt2_rad: int = None,
303
+ npt2_azim: int = None,
304
+ unit: str = None,
305
+ Dummy: int = None,
306
+ DDummy: int = None,
307
+ method: str = None,
308
+ datatype: str = "float32",
309
+ **kwargs,
310
+ ):
311
+ dataset_signal_azim = None
312
+ dataset_variance_azim = None
313
+ dataset_sigma_azim = None
314
+ dataset_sumsignal_azim = None
315
+ dataset_sumnorm_azim = None
316
+ dataset_sumvariance_azim = None
317
+
318
+ do_variance_formula = kwargs.get("do_variance_formula")
319
+ variance_formula = kwargs.get("variance_formula")
320
+ if dataset_variance is not None:
321
+ ...
322
+ elif dataset_variance is None and do_variance_formula and variance_formula:
323
+ variance_function = numexpr.NumExpr(
324
+ variance_formula, [("data", datatype), ("dark", datatype)]
325
+ )
326
+ dark = None
327
+ if filename_dark:
328
+ dark = get_persistent_array_dark(
329
+ filename_dark=filename_dark,
330
+ data_signal_shape=dataset_signal[0].shape,
331
+ dummy=Dummy,
332
+ delta_dummy=DDummy,
333
+ **kwargs,
334
+ )
335
+
336
+ dataset_variance = numpy.zeros_like(dataset_signal, dtype=datatype)
337
+ for frame_index, data_signal in enumerate(dataset_signal):
338
+ dataset_variance[frame_index] = variance_function(
339
+ data_signal, 0 if dark is None else dark
340
+ )
341
+
342
+ worker = get_persistent_pyfai_worker(
343
+ azimuthal_integrator=azimuthal_integrator,
344
+ filename_mask=filename_mask,
345
+ npt2_rad=npt2_rad,
346
+ npt2_azim=npt2_azim,
347
+ unit=unit,
348
+ Dummy=Dummy,
349
+ DDummy=DDummy,
350
+ method=method,
351
+ **kwargs,
352
+ )
353
+
354
+ output_dataset_shape = (
355
+ len(dataset_signal),
356
+ worker.nbpt_azim,
357
+ worker.nbpt_rad,
358
+ )
359
+
360
+ dataset_signal_azim = numpy.zeros(output_dataset_shape, dtype=datatype)
361
+ dataset_sumsignal_azim = numpy.zeros(output_dataset_shape, dtype=datatype)
362
+ dataset_sumnorm_azim = numpy.zeros(output_dataset_shape, dtype=datatype)
363
+
364
+ if dataset_variance is not None:
365
+ dataset_variance_azim = numpy.zeros(output_dataset_shape, dtype=datatype)
366
+ dataset_sigma_azim = numpy.zeros(output_dataset_shape, dtype=datatype)
367
+ dataset_sumvariance_azim = numpy.zeros(output_dataset_shape, dtype=datatype)
368
+
369
+ logger.debug(f"PyFAI worker used method: {worker.method}")
370
+ for frame_index, data_signal in enumerate(dataset_signal):
371
+ if dataset_variance is not None:
372
+ data_variance = dataset_variance[frame_index]
373
+ else:
374
+ data_variance = None
375
+
376
+ result2d_azim = worker.process(
377
+ data=data_signal,
378
+ variance=data_variance,
379
+ )
380
+
381
+ dataset_signal_azim[frame_index] = numpy.ascontiguousarray(
382
+ result2d_azim.intensity, dtype=datatype
383
+ ) # (sum_signal / sum_normalization)
384
+ dataset_sumsignal_azim[frame_index] = numpy.ascontiguousarray(
385
+ result2d_azim.sum_signal, dtype=datatype
386
+ )
387
+ dataset_sumnorm_azim[frame_index] = numpy.ascontiguousarray(
388
+ result2d_azim.sum_normalization, dtype=datatype
389
+ )
390
+
391
+ if data_variance is not None:
392
+ sum_var = numpy.ascontiguousarray( # noqa
393
+ result2d_azim.sum_variance, dtype=datatype
394
+ )
395
+ sum_norm = numpy.ascontiguousarray( # noqa
396
+ result2d_azim.sum_normalization, dtype=datatype
397
+ )
398
+ dataset_variance_azim[frame_index] = numexpr.evaluate(
399
+ f"where(sum_norm <= 0.0, {worker.dummy}, sum_var / (sum_norm * sum_norm))"
400
+ )
401
+ dataset_sigma_azim[frame_index] = numpy.ascontiguousarray(
402
+ result2d_azim.sigma, dtype=datatype
403
+ )
404
+ dataset_sumvariance_azim[frame_index] = numpy.ascontiguousarray(
405
+ result2d_azim.sum_variance, dtype=datatype
406
+ )
407
+
408
+ radial_array = result2d_azim.radial
409
+ if radial_array is not None:
410
+ radial_array = radial_array.astype(datatype)
411
+ azimuthal_array = result2d_azim.azimuthal
412
+ if azimuthal_array is not None:
413
+ azimuthal_array = azimuthal_array.astype(datatype)
414
+
415
+ return (
416
+ dataset_signal_azim,
417
+ dataset_variance_azim,
418
+ dataset_sigma_azim,
419
+ dataset_sumsignal_azim,
420
+ dataset_sumnorm_azim,
421
+ dataset_sumvariance_azim,
422
+ radial_array,
423
+ azimuthal_array,
424
+ )