ewoksid02 0.0.1a0__tar.gz → 0.1.0__tar.gz

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 (72) hide show
  1. {ewoksid02-0.0.1a0/src/ewoksid02.egg-info → ewoksid02-0.1.0}/PKG-INFO +3 -3
  2. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/pyproject.toml +6 -3
  3. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/resources/saxs_loop.json +16 -0
  4. ewoksid02-0.1.0/src/ewoksid02/resources/template_saxs.yaml +37 -0
  5. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/saxs/main.py +9 -10
  6. ewoksid02-0.1.0/src/ewoksid02/tasks/__init__.py +7 -0
  7. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/averagetask.py +46 -45
  8. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/azimuthaltask.py +65 -81
  9. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/cavingtask.py +33 -85
  10. ewoksid02-0.1.0/src/ewoksid02/tasks/dahuprocessingtask.py +71 -0
  11. ewoksid02-0.1.0/src/ewoksid02/tasks/end.py +35 -0
  12. ewoksid02-0.1.0/src/ewoksid02/tasks/id02processingtask.py +2582 -0
  13. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/looptask.py +205 -87
  14. ewoksid02-0.1.0/src/ewoksid02/tasks/metadatatask.py +879 -0
  15. ewoksid02-0.1.0/src/ewoksid02/tasks/normalizationtask.py +204 -0
  16. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/scalerstask.py +6 -5
  17. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/secondaryscatteringtask.py +32 -51
  18. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tests/conftest.py +127 -71
  19. ewoksid02-0.1.0/src/ewoksid02/tests/debug.py +64 -0
  20. ewoksid02-0.1.0/src/ewoksid02/tests/test_2scat_node.py +119 -0
  21. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tests/test_ave_node.py +25 -30
  22. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tests/test_azim_node.py +25 -30
  23. ewoksid02-0.1.0/src/ewoksid02/tests/test_cave_node.py +118 -0
  24. ewoksid02-0.1.0/src/ewoksid02/tests/test_norm_node.py +190 -0
  25. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tests/test_saxs.py +22 -6
  26. ewoksid02-0.1.0/src/ewoksid02/tests/utils.py +514 -0
  27. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/utils/average.py +1 -1
  28. ewoksid02-0.1.0/src/ewoksid02/utils/blissdata.py +1157 -0
  29. ewoksid02-0.1.0/src/ewoksid02/utils/caving.py +851 -0
  30. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/utils/cupyutils.py +9 -4
  31. ewoksid02-0.1.0/src/ewoksid02/utils/io.py +722 -0
  32. ewoksid02-0.1.0/src/ewoksid02/utils/normalization.py +804 -0
  33. ewoksid02-0.1.0/src/ewoksid02/utils/pyfai.py +424 -0
  34. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/utils/secondaryscattering.py +151 -110
  35. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0/src/ewoksid02.egg-info}/PKG-INFO +3 -3
  36. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02.egg-info/SOURCES.txt +5 -1
  37. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02.egg-info/requires.txt +1 -1
  38. ewoksid02-0.0.1a0/src/ewoksid02/resources/template_saxs.yaml +0 -38
  39. ewoksid02-0.0.1a0/src/ewoksid02/tasks/__init__.py +0 -1
  40. ewoksid02-0.0.1a0/src/ewoksid02/tasks/id02processingtask.py +0 -1765
  41. ewoksid02-0.0.1a0/src/ewoksid02/tasks/normalizationtask.py +0 -255
  42. ewoksid02-0.0.1a0/src/ewoksid02/tests/test_2scat_node.py +0 -135
  43. ewoksid02-0.0.1a0/src/ewoksid02/tests/test_caving_node.py +0 -129
  44. ewoksid02-0.0.1a0/src/ewoksid02/tests/test_norm_node.py +0 -146
  45. ewoksid02-0.0.1a0/src/ewoksid02/tests/utils.py +0 -304
  46. ewoksid02-0.0.1a0/src/ewoksid02/utils/blissdata.py +0 -1542
  47. ewoksid02-0.0.1a0/src/ewoksid02/utils/caving.py +0 -563
  48. ewoksid02-0.0.1a0/src/ewoksid02/utils/io.py +0 -333
  49. ewoksid02-0.0.1a0/src/ewoksid02/utils/normalization.py +0 -582
  50. ewoksid02-0.0.1a0/src/ewoksid02/utils/pyfai.py +0 -467
  51. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/LICENSE.md +0 -0
  52. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/README.md +0 -0
  53. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/setup.cfg +0 -0
  54. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/__init__.py +0 -0
  55. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/ocl/__init__.py +0 -0
  56. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/resources/__init__.py +0 -0
  57. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/__init__.py +0 -0
  58. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/__main__.py +0 -0
  59. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/parsers.py +0 -0
  60. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/saxs/__init__.py +0 -0
  61. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/saxs/slurm_python_post_script.py +0 -0
  62. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/saxs/slurm_python_pre_script.py +0 -0
  63. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/utils.py +0 -0
  64. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/xpcs/__init__.py +0 -0
  65. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/scripts/xpcs/__main__.py +0 -0
  66. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tasks/sumtask.py +0 -0
  67. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tests/__init__.py +0 -0
  68. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/tests/test_sumtask.py +0 -0
  69. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02/utils/__init__.py +0 -0
  70. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02.egg-info/dependency_links.txt +0 -0
  71. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02.egg-info/entry_points.txt +0 -0
  72. {ewoksid02-0.0.1a0 → ewoksid02-0.1.0}/src/ewoksid02.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ewoksid02
3
- Version: 0.0.1a0
3
+ Version: 0.1.0
4
4
  Summary: Data processing SAXS and XPCS workflows for ID02
5
5
  Author-email: ESRF <edgar.gutierrez-fernandez@esrf.fr>
6
6
  License: # MIT License
@@ -29,7 +29,7 @@ Project-URL: Documentation, https://ewoksid02.readthedocs.io/
29
29
  Project-URL: Repository, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksid02/
30
30
  Project-URL: Issues, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksid02/issues
31
31
  Project-URL: Changelog, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksid02/-/blob/main/CHANGELOG.md
32
- Keywords: ewoks
32
+ Keywords: ewoks,ID02,SAXS,XPCS
33
33
  Classifier: Intended Audience :: Science/Research
34
34
  Classifier: License :: OSI Approved :: MIT License
35
35
  Classifier: Programming Language :: Python :: 3
@@ -37,7 +37,6 @@ Requires-Python: >=3.8
37
37
  Description-Content-Type: text/markdown
38
38
  License-File: LICENSE.md
39
39
  Requires-Dist: ewoks
40
- Requires-Dist: ewokscore
41
40
  Requires-Dist: ewoksjob[blissworker]
42
41
  Requires-Dist: ewoksjob[slurm]
43
42
  Requires-Dist: ewoksppf
@@ -63,6 +62,7 @@ Requires-Dist: sphinx-autodoc-typehints>=1.16; extra == "doc"
63
62
  Requires-Dist: pydata-sphinx-theme; extra == "doc"
64
63
  Requires-Dist: nbsphinx; extra == "doc"
65
64
  Requires-Dist: ipython; extra == "doc"
65
+ Requires-Dist: ewokssphinx; extra == "doc"
66
66
  Provides-Extra: cupy
67
67
  Requires-Dist: cupy; extra == "cupy"
68
68
  Dynamic: license-file
@@ -6,9 +6,12 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "ewoksid02"
9
- version = "0.0.1-alpha"
9
+ version = "0.1.0"
10
10
  keywords = [
11
- 'ewoks'
11
+ 'ewoks',
12
+ 'ID02',
13
+ 'SAXS',
14
+ 'XPCS',
12
15
  ]
13
16
 
14
17
  authors = [{name = "ESRF", email = "edgar.gutierrez-fernandez@esrf.fr"}]
@@ -23,7 +26,6 @@ classifiers = [
23
26
  requires-python = ">=3.8"
24
27
  dependencies = [
25
28
  "ewoks",
26
- "ewokscore",
27
29
  "ewoksjob[blissworker]",
28
30
  "ewoksjob[slurm]",
29
31
  "ewoksppf",
@@ -61,6 +63,7 @@ doc = [
61
63
  'pydata-sphinx-theme',
62
64
  'nbsphinx',
63
65
  'ipython',
66
+ 'ewokssphinx',
64
67
  ]
65
68
  cupy = [
66
69
  'cupy',
@@ -37,6 +37,11 @@
37
37
  "task_type": "class",
38
38
  "task_identifier": "ewoksid02.tasks.scalerstask.ScalersTask",
39
39
  "id": "scalers"
40
+ },
41
+ {
42
+ "task_type": "class",
43
+ "task_identifier": "ewoksid02.tasks.end.EndTask",
44
+ "id": "end"
40
45
  }
41
46
  ],
42
47
  "links": [
@@ -51,6 +56,17 @@
51
56
  }
52
57
  ]
53
58
  },
59
+ {
60
+ "map_all_data": true,
61
+ "source": "norm",
62
+ "target": "end",
63
+ "conditions": [
64
+ {
65
+ "source_output": "continue_pipeline",
66
+ "value": false
67
+ }
68
+ ]
69
+ },
54
70
  {
55
71
  "map_all_data": true,
56
72
  "source": "2scat",
@@ -0,0 +1,37 @@
1
+ ###########################
2
+ ## ewoksid02 template SAXS.yaml
3
+ ###########################
4
+
5
+ bliss_filenames: # List of RAW_DATA files (proposal / sample / dataset files)
6
+ - /data/visitor/xxx/id02/xxx/RAW_DATA/xxx/.../file1.h5
7
+ #- /data/visitor/xxx/id02/xxx/RAW_DATA/xxx/.../file2.h5
8
+
9
+ detectors: # List of 2D detectors to integrate (Options: eiger2, waxs, eiger500k)
10
+ - eiger2
11
+ # - waxs
12
+
13
+ scans: # List of scan numbers (if empty, takes all)
14
+ - 1
15
+ # - 2
16
+ # - !slice 1:10 # Slice option: it will iterate between scans 1 and 10 (included)
17
+
18
+ tag: # Additional suffix to the output files (overwritting is forbidden)
19
+ output_root: # Root folder to save the output files (if empty, replace RAW_DATA -> PROCESSED_DATA)
20
+
21
+ # Processing parameters
22
+ to_process: "norm 2scat cave azim ave" # Include in this string which processing steps you want to perform (norm, 2scat, cave, azim, ave)
23
+ to_save: "norm 2scat cave azim ave" # Include in this string which processing results you want to save (norm, 2scat, cave, azim, ave)
24
+
25
+ # Correction parameters
26
+ filename_flatfield: # Path to the file with the flat field array (if empty, it will be taken from headers)
27
+ filename_darkcurrent: # Path to the file with the dark current array (if empty, it will be taken from headers)
28
+ filename_maskgaps: # Path to the file with the detector mask array (if empty, it will be taken from headers)
29
+ filename_maskbeamstop: # Path to the file with an additional detector mask, like beamstop (if empty, it will be taken from headers)
30
+ filename_window_wagon: # Path to the file with the WAXS pattern from the wagon window
31
+ WindowRoiSize: 120 # Size of the window used to convolute the WAXS pattern from the wagon window
32
+
33
+ # Submit parameters
34
+ submit: True # If False, it will save the instructions without submitting the job
35
+ slurm_job_parameters: # Some SLURM parameters to be tweak if the job fails
36
+ time_limit: 01:00:00
37
+ memory_per_cpu: 50GB
@@ -21,6 +21,7 @@ from ...utils.blissdata import LIMA_URL_TEMPLATE_ID02, get_lima_url_template_arg
21
21
  from ..utils import SLURM_JOB_PARAMETERS_SAXS
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
+ WORKER_MODULE = "scattering"
24
25
 
25
26
 
26
27
  def get_saxs_inputs(
@@ -33,17 +34,12 @@ def get_saxs_inputs(
33
34
  # Add all nodes inputs
34
35
  ###########
35
36
  inputs_dict_all_nodes = {
36
- "filename_data": kwargs.get("dataset_filename"),
37
37
  "detector_name": kwargs.get("detector_name"),
38
+ "filename_data": kwargs.get("dataset_filename"),
38
39
  "scan_nb": kwargs.get("scan_nb"),
39
- "filename_metadata": kwargs.get("filename_scalers"),
40
40
  "filename_lima": kwargs.get("filename_scan"),
41
- "dummy": kwargs.get("dummy", -10),
42
- "delta_dummy": kwargs.get("delta_dummy", 0.1),
43
- # "subtitle": kwargs.get("tag", ""),
44
41
  "log_level": kwargs.get("log_level", "info"),
45
42
  "datatype": kwargs.get("datatype"),
46
- "use_cupy": kwargs.get("use_cupy"),
47
43
  "save_variance": kwargs.get("save_variance"),
48
44
  "max_slice_size": kwargs.get("max_slice_size"),
49
45
  "lima_url_template": LIMA_URL_TEMPLATE_ID02,
@@ -69,6 +65,8 @@ def get_saxs_inputs(
69
65
  "filename_dark": kwargs.get("filename_darkcurrent"),
70
66
  "filename_flat": kwargs.get("filename_flatfield"),
71
67
  "algorithm": kwargs.get("algorithm_norm", "cython"),
68
+ "Dummy": kwargs.get("Dummy"),
69
+ "DDummy": kwargs.get("DDummy"),
72
70
  }
73
71
  inputs += validate_inputs_ewoks(
74
72
  inputs=inputs_dict_norm,
@@ -81,8 +79,8 @@ def get_saxs_inputs(
81
79
  #############
82
80
  inputs_dict_2scat = {
83
81
  "filename_window_wagon": kwargs.get("filename_window_wagon"),
84
- "window_roi_size": kwargs.get("window_roi_size"),
85
- "filename_mask_to_cave": kwargs.get("filename_maskgaps"),
82
+ "WindowRoiSize": kwargs.get("WindowRoiSize"),
83
+ "filename_mask_static": kwargs.get("filename_maskgaps"),
86
84
  "filename_mask_reference": kwargs.get("filename_maskbeamstop"),
87
85
  "algorithm": kwargs.get("algorithm_2scat", "numpy"),
88
86
  }
@@ -96,7 +94,7 @@ def get_saxs_inputs(
96
94
  # Add caving inputs
97
95
  #############
98
96
  inputs_dict_cave = {
99
- "filename_mask_to_cave": kwargs.get("filename_maskbeamstop"),
97
+ "filename_mask_static": kwargs.get("filename_maskbeamstop"),
100
98
  "flip_caving": kwargs.get("flip_caving"),
101
99
  "algorithm": kwargs.get("algorithm_cave", "numpy"),
102
100
  }
@@ -141,7 +139,7 @@ def get_saxs_inputs(
141
139
  nodes = ["norm", "2scat", "cave", "azim", "ave", "scalers"]
142
140
 
143
141
  inputs += [
144
- {"name": "do_processing", "id": node, "value": node in to_process}
142
+ {"name": "do_process", "id": node, "value": node in to_process}
145
143
  for node in nodes
146
144
  ]
147
145
  inputs += [
@@ -247,6 +245,7 @@ def main(args):
247
245
  "engine": "ppf",
248
246
  "pool_type": "thread",
249
247
  },
248
+ worker_module=WORKER_MODULE,
250
249
  )
251
250
 
252
251
  print(
@@ -0,0 +1,7 @@
1
+ ###
2
+ from .id02processingtask import ID02ProcessingTask # noqa
3
+ from .normalizationtask import NormalizationTask # noqa
4
+ from .secondaryscatteringtask import SecondaryScatteringTask # noqa
5
+ from .cavingtask import CavingBeamstopTask, CavingGapsTask, CavingTask # noqa
6
+ from .azimuthaltask import AzimuthalTask # noqa
7
+ from .averagetask import AverageTask # noqa
@@ -3,7 +3,7 @@ from contextlib import ExitStack
3
3
  from pyFAI.units import to_unit
4
4
  from silx.io.h5py_utils import open_item as open_item_silx
5
5
 
6
- from ewoksid02.tasks.id02processingtask import ENTRY_NAME, ID02ProcessingTask
6
+ from ewoksid02.tasks.id02processingtask import ID02ProcessingTask
7
7
  from ewoksid02.utils.average import calculate_average, get_array_limit
8
8
 
9
9
 
@@ -46,27 +46,10 @@ class AverageTask(
46
46
 
47
47
  def run(self):
48
48
  super().run(processing_type="ave")
49
- self.update_dataset_ave()
50
49
 
51
- def get_processing_inputs(self, stack: ExitStack = None) -> dict:
52
- if stack:
53
- return self._get_processing_inputs(stack=stack)
54
-
55
- with ExitStack() as stack:
56
- return self._get_processing_inputs(
57
- stack=stack,
58
- )
59
-
60
- def _get_processing_inputs(self, stack: ExitStack) -> dict:
50
+ def get_processing_inputs(self) -> dict:
61
51
  azimuth_range = self.get_input_value("azimuth_range", None)
62
52
  array_ranges = None
63
- metadata_parameters_group = None
64
- if self.filename_metadata_headers_input and self.filename_metadata_mcs_input:
65
- metadata_parameters_group = self._open_metadata_h5pygroup(
66
- stack,
67
- self.filename_metadata_headers_input,
68
- self.path_to_metadata_headers_input,
69
- )
70
53
 
71
54
  if azimuth_range is None:
72
55
  self.log_info("There is no azimuth_range. Full average will be done.")
@@ -86,7 +69,8 @@ class AverageTask(
86
69
 
87
70
  params_ave = {
88
71
  "array_ranges": array_ranges,
89
- "Dummy": self.get_parameter("Dummy", metadata_parameters_group),
72
+ "Dummy": self.get_parameter("Dummy"),
73
+ "azimuth_range": azimuth_range,
90
74
  }
91
75
 
92
76
  return params_ave
@@ -102,11 +86,11 @@ class AverageTask(
102
86
  )
103
87
  stack.enter_context(self.bench_process)
104
88
 
105
- processing_params = self.get_processing_inputs(
106
- stack=stack,
107
- )
89
+ processing_params = self.get_processing_inputs()
108
90
  self.processing_params = processing_params
109
91
 
92
+ self.log_info("Performing 1D integration...")
93
+
110
94
  (
111
95
  dataset_average_intensity,
112
96
  dataset_average_signal_norm,
@@ -129,36 +113,30 @@ class AverageTask(
129
113
  self.outputs.dataset_sigma = dataset_average_sigma
130
114
  self.outputs.radial_array = self.get_input_value("radial_array", None)
131
115
 
132
- self.log_benchmark(self.bench_process)
116
+ self._log_benchmark(self.bench_process)
133
117
 
134
- def update_dataset_ave(self):
135
- if not self.processing_filename or not self.do_save:
118
+ def save(self) -> None:
119
+ do_save = super().save()
120
+ if not do_save:
136
121
  return
137
122
 
138
- with ExitStack() as stack:
139
- file = stack.enter_context(
140
- open_item_silx(filename=self.processing_filename, name="/", mode="a")
141
- )
142
- nexus_data_grp = file[self.path_to_nxdata_output]
143
- metadata_parameters_group = None
144
- if (
145
- self.filename_metadata_headers_input
146
- and self.filename_metadata_mcs_input
147
- ):
148
- metadata_parameters_group = self._open_metadata_h5pygroup(
149
- stack,
150
- self.filename_metadata_headers_input,
151
- self.path_to_metadata_headers_input,
152
- )
153
-
154
- self.update_dataset(
123
+ filename_output, h5path_nxdata = self.links["destination"]["nxdata"].split("::")
124
+ params = {
125
+ "filename": filename_output,
126
+ "name": h5path_nxdata,
127
+ "retry_timeout": 0.1,
128
+ "mode": "a",
129
+ }
130
+ with open_item_silx(**params) as nexus_data_grp:
131
+ self._update_dataset(
155
132
  added_dataset=self.outputs.dataset_average_signal_norm,
156
133
  h5_group=nexus_data_grp,
157
134
  h5_dataset_name="data_signal_norm",
135
+ index_read=self.index_range_last,
158
136
  )
159
137
 
160
138
  # Add nexus data information (only once)
161
- unit = self.get_parameter("unit", metadata_parameters_group)
139
+ unit = self.get_parameter("unit")
162
140
  radial_unit = to_unit(unit)
163
141
 
164
142
  if radial_unit is not None and radial_unit.short_name not in nexus_data_grp:
@@ -175,4 +153,27 @@ class AverageTask(
175
153
 
176
154
  def processing_info(self) -> list:
177
155
  azimuth_range = self.get_input_value("azimuth_range", [0, 360])
178
- return [{"h5path": ENTRY_NAME, "name": "ave_limits", "value": azimuth_range}]
156
+ return [{"h5path": "entry_0000", "name": "ave_limits", "value": azimuth_range}]
157
+
158
+ def _save_in_gallery(self) -> str:
159
+ if self.loop_nb != 1:
160
+ return
161
+
162
+ dataset_signal = self.outputs.dataset_signal
163
+ if dataset_signal is None or dataset_signal.size == 0:
164
+ return
165
+
166
+ import matplotlib.pyplot as plt
167
+
168
+ unit = self.get_parameter("unit")
169
+ radial_unit = to_unit(unit)
170
+
171
+ signal = dataset_signal.mean(axis=0)
172
+ q = self.outputs.radial_array
173
+ fig, ax = plt.subplots(figsize=(15, 10))
174
+ ax.plot(q, signal)
175
+ ax.set_xlabel(f"{radial_unit.short_name} ({radial_unit.unit_symbol})")
176
+ ax.set_ylabel("Intensity (arb. units)")
177
+ ax.set_title(f"scan {self.scan_nb} - average")
178
+ filename_png = self._get_filename_gallery()
179
+ fig.savefig(filename_png)
@@ -8,7 +8,9 @@ from ewoksid02.tasks.id02processingtask import ID02ProcessingTask
8
8
  from ewoksid02.utils.pyfai import (
9
9
  get_gpu_method,
10
10
  get_persistent_azimuthal_integrator,
11
+ _get_persistent_pyfai_worker,
11
12
  process_dataset_azim,
13
+ guess_npt2_rad,
12
14
  )
13
15
 
14
16
  DEFAULT_NPT_RAD = 1600
@@ -88,83 +90,69 @@ class AzimuthalTask(
88
90
 
89
91
  def run(self):
90
92
  super().run(processing_type="azim")
91
- self.update_dataset_azim()
92
93
 
93
- def get_processing_inputs(self, stack: ExitStack = None) -> dict:
94
- if stack:
95
- return self._get_processing_inputs(stack=stack)
96
-
97
- with ExitStack() as stack:
98
- return self._get_processing_inputs(
99
- stack=stack,
100
- )
94
+ def get_processing_inputs(
95
+ self,
96
+ ) -> dict:
97
+ params_azimuthalintegrator = {
98
+ "Center_1": self.get_parameter("Center_1"),
99
+ "Center_2": self.get_parameter("Center_2"),
100
+ "PSize_1": self.get_parameter("PSize_1"),
101
+ "PSize_2": self.get_parameter("PSize_2"),
102
+ "SampleDistance": self.get_parameter("SampleDistance"),
103
+ "WaveLength": self.get_parameter("WaveLength"),
104
+ "BSize_1": self.get_parameter("BSize_1"),
105
+ "BSize_2": self.get_parameter("BSize_2"),
106
+ "DetectorRotation_1": self.get_parameter("DetectorRotation_1"),
107
+ "DetectorRotation_2": self.get_parameter("DetectorRotation_2"),
108
+ "DetectorRotation_3": self.get_parameter("DetectorRotation_3"),
109
+ }
101
110
 
102
- def _get_processing_inputs(self, stack: ExitStack) -> dict:
103
- metadata_parameters_group = None
104
- if self.filename_metadata_headers_input and self.filename_metadata_mcs_input:
105
- metadata_parameters_group = self._open_metadata_h5pygroup(
106
- stack,
107
- self.filename_metadata_headers_input,
108
- self.path_to_metadata_headers_input,
109
- )
110
111
  azimuthal_integrator = get_persistent_azimuthal_integrator(
111
- dataset=self.dataset_signal,
112
- Center_1=self.get_parameter("Center_1", metadata_parameters_group),
113
- Center_2=self.get_parameter("Center_2", metadata_parameters_group),
114
- PSize_1=self.get_parameter("PSize_1", metadata_parameters_group),
115
- PSize_2=self.get_parameter("PSize_2", metadata_parameters_group),
116
- SampleDistance=self.get_parameter(
117
- "SampleDistance", metadata_parameters_group
118
- ),
119
- WaveLength=self.get_parameter("WaveLength", metadata_parameters_group),
120
- BSize_1=self.get_parameter("BSize_1", metadata_parameters_group),
121
- BSize_2=self.get_parameter("BSize_2", metadata_parameters_group),
122
- DetectorRotation_1=self.get_parameter(
123
- "DetectorRotation_1", metadata_parameters_group
124
- ),
125
- DetectorRotation_2=self.get_parameter(
126
- "DetectorRotation_2", metadata_parameters_group
127
- ),
128
- DetectorRotation_3=self.get_parameter(
129
- "DetectorRotation_3", metadata_parameters_group
130
- ),
112
+ data_signal_shape=self.dataset_signal[0].shape,
113
+ **params_azimuthalintegrator,
131
114
  )
132
115
 
133
116
  processing_params = {
134
117
  "filename_mask": self.get_input_value(
135
118
  "filename_mask",
136
- self.get_mask_beamstop_filename(
137
- metadata_file_group=metadata_parameters_group
138
- ),
119
+ self.get_mask_beamstop_filename(),
139
120
  ),
140
121
  "filename_dark": self.get_input_value(
141
122
  "filename_dark",
142
- self.get_dark_filename(metadata_file_group=metadata_parameters_group),
123
+ self.get_dark_filename(),
143
124
  ),
144
- "Dummy": self.get_parameter("Dummy", metadata_parameters_group),
145
- "DDummy": self.get_parameter("DDummy", metadata_parameters_group),
146
- "npt2_rad": self.get_parameter("npt2_rad", metadata_parameters_group),
147
- "npt2_azim": self.get_parameter("npt2_azim", metadata_parameters_group),
148
- "unit": self.get_parameter("unit", metadata_parameters_group),
125
+ "Dummy": self.get_parameter("Dummy"),
126
+ "DDummy": self.get_parameter("DDummy"),
127
+ "npt2_rad": self.get_parameter("npt2_rad"),
128
+ "npt2_azim": self.get_parameter("npt2_azim"),
129
+ "unit": self.get_parameter("unit", defaut="q_nm^-1"),
149
130
  "method": self.get_input_value("method", get_gpu_method()),
150
131
  "integration_options": self.get_input_value("integration_options", {}),
151
132
  "do_variance_formula": self.get_input_value("do_variance_formula", False),
152
- "variance_formula": self.get_parameter(
153
- "variance_formula", metadata_parameters_group
154
- ),
133
+ "variance_formula": self.get_parameter("variance_formula"),
155
134
  "datatype": self.get_input_value("datatype", "float32"),
156
135
  "binning": (
157
- self.get_parameter("BSize_1", metadata_parameters_group),
158
- self.get_parameter("BSize_2", metadata_parameters_group),
136
+ self.get_parameter(
137
+ "BSize_1",
138
+ ),
139
+ self.get_parameter(
140
+ "BSize_2",
141
+ ),
159
142
  ),
160
143
  "save_variance": self.get_input_value("save_variance", False),
161
144
  "save_sum": self.get_input_value("save_sum", False),
162
145
  "azimuthal_integrator": azimuthal_integrator,
146
+ **params_azimuthalintegrator,
163
147
  }
164
148
  if not processing_params.get("npt2_rad"):
165
- processing_params["npt2_rad"] = DEFAULT_NPT_RAD
149
+ processing_params["npt2_rad"] = guess_npt2_rad(
150
+ azimuthal_integrator=azimuthal_integrator
151
+ )
166
152
  if not processing_params.get("npt2_azim"):
167
153
  processing_params["npt2_azim"] = DEFAULT_NPT_AZIM
154
+ if not processing_params.get("method"):
155
+ processing_params["method"] = get_gpu_method()
168
156
  return processing_params
169
157
 
170
158
  def process(self) -> None:
@@ -178,9 +166,7 @@ class AzimuthalTask(
178
166
  )
179
167
  stack.enter_context(self.bench_process)
180
168
 
181
- processing_params = self.get_processing_inputs(
182
- stack=stack,
183
- )
169
+ processing_params = self.get_processing_inputs()
184
170
  self.processing_params = processing_params
185
171
 
186
172
  if self.dataset_variance is not None:
@@ -194,6 +180,8 @@ class AzimuthalTask(
194
180
  else:
195
181
  dataset_variance = None
196
182
 
183
+ self.log_info("Performing 2D integration...")
184
+
197
185
  (
198
186
  dataset_signal_azim,
199
187
  dataset_variance_azim,
@@ -218,50 +206,43 @@ class AzimuthalTask(
218
206
  self.outputs.radial_array = array_radial
219
207
  self.outputs.azimuth_array = array_azim
220
208
 
221
- self.log_benchmark(self.bench_process)
209
+ self._log_benchmark(self.bench_process)
222
210
 
223
- def update_dataset_azim(
224
- self,
225
- ):
226
- if not self.processing_filename or not self.do_save:
211
+ def save(self) -> None:
212
+ do_save = super().save()
213
+ if not do_save:
227
214
  return
228
215
 
229
- with ExitStack() as stack:
230
- file = stack.enter_context(
231
- open_item_silx(filename=self.processing_filename, name="/", mode="a")
232
- )
233
- nexus_data_grp = file[self.path_to_nxdata_output]
234
-
235
- metadata_parameters_group = None
236
- if (
237
- self.filename_metadata_headers_input
238
- and self.filename_metadata_mcs_input
239
- ):
240
- metadata_parameters_group = self._open_metadata_h5pygroup(
241
- stack,
242
- self.filename_metadata_headers_input,
243
- self.path_to_metadata_headers_input,
244
- )
245
-
246
- self.update_dataset(
216
+ filename_output, h5path_nxdata = self.links["destination"]["nxdata"].split("::")
217
+ params = {
218
+ "filename": filename_output,
219
+ "name": h5path_nxdata,
220
+ "retry_timeout": 0.1,
221
+ "mode": "a",
222
+ }
223
+ with open_item_silx(**params) as nexus_data_grp:
224
+ self._update_dataset(
247
225
  added_dataset=self.outputs.dataset_sum_signal,
248
226
  h5_group=nexus_data_grp,
249
227
  h5_dataset_name="sum_signal",
228
+ index_read=self.index_range_last,
250
229
  )
251
230
 
252
- self.update_dataset(
231
+ self._update_dataset(
253
232
  added_dataset=self.outputs.dataset_sum_normalization,
254
233
  h5_group=nexus_data_grp,
255
234
  h5_dataset_name="sum_normalization",
235
+ index_read=self.index_range_last,
256
236
  )
257
237
 
258
- self.update_dataset(
238
+ self._update_dataset(
259
239
  added_dataset=self.outputs.dataset_sum_variance,
260
240
  h5_group=nexus_data_grp,
261
241
  h5_dataset_name="sum_variance",
242
+ index_read=self.index_range_last,
262
243
  )
263
244
 
264
- unit = self.get_parameter("unit", metadata_parameters_group)
245
+ unit = self.get_parameter("unit")
265
246
  radial_unit = to_unit(unit)
266
247
 
267
248
  # Update radial and azimuthal arrays only once
@@ -286,3 +267,6 @@ class AzimuthalTask(
286
267
  chi_dset.attrs["unit"] = "deg"
287
268
 
288
269
  nexus_data_grp.attrs["axes"] = [".", "chi", radial_unit.short_name]
270
+
271
+ def _get_last_worker(self):
272
+ return _get_persistent_pyfai_worker(**self.get_processing_inputs())