tomwer 1.3.0.dev2__py3-none-any.whl → 1.3.0rc10__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 (156) hide show
  1. orangecontrib/tomwer/widgets/__init__.py +11 -12
  2. orangecontrib/tomwer/widgets/control/DataListenerOW.py +6 -6
  3. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +6 -6
  4. orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +3 -3
  5. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +10 -8
  6. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +6 -6
  7. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +1 -1
  8. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -98
  9. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -129
  10. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +13 -12
  11. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +11 -9
  12. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +11 -9
  13. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +12 -15
  14. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +9 -9
  15. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  16. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -1
  17. tomwer/__main__.py +0 -10
  18. tomwer/app/canvas_launcher/config.py +3 -3
  19. tomwer/app/canvas_launcher/environ.py +1 -0
  20. tomwer/app/intensitynormalization.py +12 -11
  21. tomwer/app/nabuapp.py +0 -11
  22. tomwer/app/zstitching.py +11 -1
  23. tomwer/core/process/control/datalistener/datalistener.py +15 -10
  24. tomwer/core/process/control/nxtomomill.py +1 -1
  25. tomwer/core/process/control/scantransfer.py +8 -32
  26. tomwer/core/process/edit/darkflatpatch.py +8 -9
  27. tomwer/core/process/edit/imagekeyeditor.py +20 -22
  28. tomwer/core/process/icat/screenshots.py +1 -0
  29. tomwer/core/process/reconstruction/axis/axis.py +263 -59
  30. tomwer/core/process/reconstruction/axis/mode.py +161 -50
  31. tomwer/core/process/reconstruction/axis/params.py +23 -20
  32. tomwer/core/process/reconstruction/darkref/darkrefs.py +12 -13
  33. tomwer/core/process/reconstruction/nabu/castvolume.py +3 -3
  34. tomwer/core/process/reconstruction/nabu/nabucommon.py +43 -19
  35. tomwer/core/process/reconstruction/nabu/nabuscores.py +34 -7
  36. tomwer/core/process/reconstruction/nabu/nabuslices.py +81 -26
  37. tomwer/core/process/reconstruction/nabu/nabuvolume.py +31 -26
  38. tomwer/core/process/reconstruction/nabu/plane.py +9 -0
  39. tomwer/core/process/reconstruction/nabu/utils.py +32 -9
  40. tomwer/core/process/reconstruction/saaxis/saaxis.py +4 -1
  41. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +9 -1
  42. tomwer/core/process/reconstruction/scores/params.py +3 -3
  43. tomwer/core/process/reconstruction/test/test_darkref_copy.py +4 -4
  44. tomwer/core/process/stitching/nabustitcher.py +11 -10
  45. tomwer/core/process/task.py +33 -27
  46. tomwer/core/process/test/test_axis.py +7 -6
  47. tomwer/core/process/test/test_data_transfer.py +3 -3
  48. tomwer/core/process/test/test_nabu.py +10 -2
  49. tomwer/core/process/test/test_normalization.py +2 -2
  50. tomwer/core/scan/blissscan.py +3 -3
  51. tomwer/core/scan/edfscan.py +9 -9
  52. tomwer/core/scan/nxtomoscan.py +11 -11
  53. tomwer/core/scan/scanbase.py +31 -24
  54. tomwer/core/scan/test/test_future_scan.py +1 -1
  55. tomwer/core/scan/test/test_h5.py +4 -4
  56. tomwer/core/scan/test/test_process_registration.py +2 -2
  57. tomwer/core/scan/test/test_scan.py +1 -75
  58. tomwer/core/settings.py +3 -3
  59. tomwer/core/test/test_utils.py +2 -2
  60. tomwer/core/volume/edfvolume.py +6 -6
  61. tomwer/core/volume/hdf5volume.py +6 -6
  62. tomwer/core/volume/jp2kvolume.py +6 -6
  63. tomwer/core/volume/rawvolume.py +6 -6
  64. tomwer/core/volume/tiffvolume.py +12 -12
  65. tomwer/gui/cluster/slurm.py +14 -9
  66. tomwer/gui/cluster/supervisor.py +12 -0
  67. tomwer/gui/cluster/test/test_cluster.py +1 -2
  68. tomwer/gui/cluster/test/test_supervisor.py +1 -1
  69. tomwer/gui/control/datalist.py +5 -0
  70. tomwer/gui/control/datawatcher/controlwidget.py +2 -4
  71. tomwer/gui/control/reducedarkflatselector.py +8 -8
  72. tomwer/gui/control/test/test_single_tomo_obj.py +1 -1
  73. tomwer/gui/edit/dkrfpatch.py +4 -4
  74. tomwer/gui/edit/nxtomowarmer.py +2 -2
  75. tomwer/gui/edit/test/test_dkrf_patch.py +6 -6
  76. tomwer/gui/imagefromfile.py +2 -2
  77. tomwer/gui/qfolderdialog.py +5 -0
  78. tomwer/gui/reconstruction/axis/CompareImages.py +94 -168
  79. tomwer/gui/reconstruction/axis/radioaxis.py +58 -182
  80. tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -1
  81. tomwer/gui/reconstruction/nabu/castvolume.py +8 -1
  82. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +54 -21
  83. tomwer/gui/reconstruction/normalization/intensity.py +3 -25
  84. tomwer/gui/reconstruction/saaxis/corrangeselector.py +1 -1
  85. tomwer/gui/reconstruction/saaxis/saaxis.py +1 -11
  86. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +0 -10
  87. tomwer/gui/reconstruction/scores/scoreplot.py +1 -6
  88. tomwer/gui/reconstruction/test/test_axis.py +18 -4
  89. tomwer/gui/reconstruction/test/test_nabu.py +3 -0
  90. tomwer/gui/stitching/stitching.py +2 -2
  91. tomwer/gui/stitching/stitching_preview.py +7 -53
  92. tomwer/gui/stitching/stitching_raw.py +3 -3
  93. tomwer/gui/utils/inputwidget.py +12 -2
  94. tomwer/gui/utils/lineselector/lineselector.py +1 -1
  95. tomwer/gui/visualization/dataviewer.py +47 -17
  96. tomwer/gui/visualization/sinogramviewer.py +19 -26
  97. tomwer/gui/visualization/test/test_volumeviewer.py +64 -66
  98. tomwer/gui/visualization/volumeviewer.py +105 -105
  99. tomwer/io/utils/h5pyutils.py +7 -3
  100. tomwer/io/utils/utils.py +3 -3
  101. tomwer/resources/gui/icons/parameters.svg +1 -1
  102. tomwer/resources/gui/illustrations/no_rot.svg +1 -1
  103. tomwer/synctools/stacks/edit/darkflatpatch.py +17 -12
  104. tomwer/tests/test_scripts.py +0 -3
  105. tomwer/third_part/WaitingOverlay.py +110 -0
  106. tomwer/third_part/__init__.py +0 -0
  107. tomwer/version.py +2 -2
  108. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/METADATA +32 -31
  109. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/RECORD +115 -153
  110. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/WHEEL +1 -1
  111. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +0 -197
  112. orangecontrib/tomwer/widgets/reconstruction/icons/XY_lamino.svg +0 -168
  113. orangecontrib/tomwer/widgets/reconstruction/icons/XZ_lamino.svg +0 -275
  114. orangecontrib/tomwer/widgets/reconstruction/icons/YZ_lamino.svg +0 -182
  115. tomwer/app/lamino.py +0 -143
  116. tomwer/core/process/reconstruction/lamino/__init__.py +0 -1
  117. tomwer/core/process/reconstruction/lamino/tofu.py +0 -1000
  118. tomwer/core/process/test/test_lamino.py +0 -76
  119. tomwer/core/test/test_lamino.py +0 -92
  120. tomwer/gui/reconstruction/lamino/__init__.py +0 -31
  121. tomwer/gui/reconstruction/lamino/tofu/TofuOptionLoader.py +0 -107
  122. tomwer/gui/reconstruction/lamino/tofu/__init__.py +0 -1
  123. tomwer/gui/reconstruction/lamino/tofu/misc.py +0 -148
  124. tomwer/gui/reconstruction/lamino/tofu/projections.py +0 -896
  125. tomwer/gui/reconstruction/lamino/tofu/settings.py +0 -75
  126. tomwer/gui/reconstruction/lamino/tofu/tofu.py +0 -432
  127. tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +0 -567
  128. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +0 -757
  129. tomwer/gui/reconstruction/test/test_lamino.py +0 -194
  130. tomwer/resources/gui/icons/lamino_parameters.svg +0 -70
  131. tomwer/resources/gui/illustrations/lamino_angle.png +0 -0
  132. tomwer/resources/gui/illustrations/lamino_angle.svg +0 -509
  133. tomwer/resources/gui/illustrations/lamino_beta_angle.png +0 -0
  134. tomwer/resources/gui/illustrations/lamino_beta_angle.svg +0 -97
  135. tomwer/resources/gui/illustrations/lamino_theta_angle.png +0 -0
  136. tomwer/resources/gui/illustrations/lamino_theta_angle.svg +0 -368
  137. tomwer/resources/gui/illustrations/manual_slice.png +0 -0
  138. tomwer/resources/gui/illustrations/manual_slice.svg +0 -221
  139. tomwer/resources/gui/illustrations/psi_angle.png +0 -0
  140. tomwer/resources/gui/illustrations/psi_angle.svg +0 -479
  141. tomwer/resources/gui/illustrations/rotation_center.png +0 -0
  142. tomwer/resources/gui/illustrations/rotation_center.svg +0 -276
  143. tomwer/resources/gui/illustrations/slice_stack.png +0 -0
  144. tomwer/resources/gui/illustrations/slice_stack.svg +0 -266
  145. tomwer/resources/gui/illustrations/xy_slice.png +0 -0
  146. tomwer/resources/gui/illustrations/xy_slice.svg +0 -269
  147. tomwer/resources/gui/illustrations/xz_slice.png +0 -0
  148. tomwer/resources/gui/illustrations/xz_slice.svg +0 -270
  149. tomwer/resources/gui/illustrations/yz_slice.png +0 -0
  150. tomwer/resources/gui/illustrations/yz_slice.svg +0 -270
  151. tomwer/synctools/stacks/reconstruction/lamino.py +0 -233
  152. /tomwer-1.3.0.dev2-py3.11-nspkg.pth → /tomwer-1.3.0rc10-py3.11-nspkg.pth +0 -0
  153. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/LICENSE +0 -0
  154. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/entry_points.txt +0 -0
  155. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/namespace_packages.txt +0 -0
  156. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/top_level.txt +0 -0
@@ -45,7 +45,7 @@ from tomwer.core.scan.scanbase import TomwerScanBase
45
45
  from tomwer.core.utils.spec import getParametersFromParOrInfo
46
46
 
47
47
  from .anglemode import CorAngleMode
48
- from .mode import AxisMode
48
+ from .mode import AxisMode, AXIS_MODE_METADATAS
49
49
  from .projectiontype import ProjectionType
50
50
 
51
51
  from nabu.preproc.phase import PaganinPhaseRetrieval
@@ -160,9 +160,9 @@ class AxisResource(object):
160
160
  else:
161
161
  self.__norme_data = scan.data_flat_field_correction(data=self.data)
162
162
  if log_ is True:
163
- self.__norme_data[
164
- numpy.isnan(self.__norme_data)
165
- ] = self.__norme_data.max()
163
+ self.__norme_data[numpy.isnan(self.__norme_data)] = (
164
+ self.__norme_data.max()
165
+ )
166
166
  if self.__norme_data.max() < 0:
167
167
  _logger.error("max data value < 0 unable to compute log")
168
168
  else:
@@ -173,9 +173,9 @@ class AxisResource(object):
173
173
  except Exception as e:
174
174
  _logger.error("Fail to apply log on radio" + e)
175
175
  else:
176
- self.__norme_data[
177
- numpy.isnan(self.__norme_data)
178
- ] = self.__norme_data.min()
176
+ self.__norme_data[numpy.isnan(self.__norme_data)] = (
177
+ self.__norme_data.min()
178
+ )
179
179
 
180
180
  return self.__norme_data
181
181
 
@@ -885,6 +885,9 @@ class AxisRP:
885
885
  pass
886
886
 
887
887
  def get_simple_str(self):
888
+ """
889
+ special information as a str for mode able to handle both sinogram and radios
890
+ """
888
891
  results = f"{self.mode.value}"
889
892
  if self.mode in (
890
893
  AxisMode.growing_window_radios,
@@ -898,20 +901,20 @@ class AxisRP:
898
901
 
899
902
  def get_nabu_cor_options_as_dict(self) -> str:
900
903
  options = {}
901
- if self.mode in (
902
- AxisMode.sliding_window_sinogram,
903
- AxisMode.sliding_window_radios,
904
- AxisMode.growing_window_sinogram,
905
- AxisMode.growing_window_radios,
906
- ):
907
- options["side"] = self.side
908
- elif self.mode in (AxisMode.composite_coarse_to_fine, AxisMode.near):
909
- near_pos = self.composite_options.get("near_pos", 0.0)
904
+ if self.mode is AxisMode.near:
905
+ self.side = "near"
906
+ request_side = len(AXIS_MODE_METADATAS[self.mode].valid_sides) > 0
907
+ if request_side:
908
+
909
+ if self.side == "near":
910
+ options["side"] = self.composite_options.get(
911
+ "near_pos", self.estimated_cor
912
+ )
913
+ else:
914
+ options["side"] = self.side
915
+
916
+ if self.side == "near":
910
917
  near_width = self.composite_options.get("near_width", 20.0)
911
- if self.mode is AxisMode.near:
912
- self.side = "near"
913
- options["side"] = self.side
914
- options["near_pos"] = near_pos
915
918
  options["near_width"] = near_width
916
919
 
917
920
  # append "extra_cor_options" to already handled cor options
@@ -396,19 +396,18 @@ class DarkRefsTask(
396
396
  if scan.process_file is not None and not (
397
397
  isinstance(scan, NXtomoScan) and not self.__new_hdf5_entry_created
398
398
  ):
399
- with scan.acquire_process_file_lock():
400
- entry = "entry"
401
- if hasattr(scan, "entry"):
402
- entry = scan.entry
403
- self.register_process(
404
- process_file=scan.process_file,
405
- entry=entry,
406
- configuration=self.recons_params.to_dict(),
407
- results=results,
408
- interpretations=interpretations,
409
- process_index=scan.pop_process_index(),
410
- overwrite=True,
411
- )
399
+ entry = "entry"
400
+ if hasattr(scan, "entry"):
401
+ entry = scan.entry
402
+ self.register_process(
403
+ process_file=scan.process_file,
404
+ entry=entry,
405
+ configuration=self.recons_params.to_dict(),
406
+ results=results,
407
+ interpretations=interpretations,
408
+ process_index=scan.pop_process_index(),
409
+ overwrite=True,
410
+ )
412
411
  logger.processSucceed(f"Dark and flat reduction succeeded for {scan}")
413
412
  self.notify_to_state_to_managed(
414
413
  dataset=scan, state=DatasetState.SUCCEED, details=None
@@ -231,9 +231,9 @@ class CastVolumeTask(
231
231
  working_directory, "slurm_scripts", script_name
232
232
  )
233
233
  # for now force job name
234
- self._cluster_config[
235
- "job_name"
236
- ] = f"tomwer-cast-volume {input_volume.get_identifier().to_str()} to {output_volume.get_identifier().to_str()}"
234
+ self._cluster_config["job_name"] = (
235
+ f"tomwer-cast-volume {input_volume.get_identifier().to_str()} to {output_volume.get_identifier().to_str()}"
236
+ )
237
237
  job = SBatchScriptJob(
238
238
  slurm_config=self._cluster_config,
239
239
  script=(get_command(),),
@@ -39,15 +39,17 @@ import uuid
39
39
  from typing import Iterable, Optional, Union
40
40
  import signal
41
41
  import psutil
42
+ import sys
42
43
 
43
44
  import numpy
44
45
  from silx.io.url import DataUrl
45
46
  from sluurp.executor import submit as submit_to_slurm_cluster
46
47
  from sluurp.job import SBatchScriptJob
47
- from tomoscan.io import HDF5File
48
+ from tomoscan.io import HDF5File, get_swmr_mode
48
49
  from tomoscan.normalization import Method as INormMethod
49
50
  from tomoscan.identifier import VolumeIdentifier
50
51
 
52
+ from tomwer.core.process.reconstruction.nabu.plane import NabuPlane
51
53
  from tomwer.core.cluster.cluster import SlurmClusterConfiguration
52
54
  from tomwer.core.process.reconstruction.nabu.target import Target
53
55
  from tomwer.core.process.reconstruction.nabu.utils import (
@@ -66,6 +68,7 @@ from tomwer.core.scan.edfscan import EDFTomoScan
66
68
  from tomwer.core.scan.nxtomoscan import NXtomoScan
67
69
  from tomwer.core.scan.scanbase import TomwerScanBase
68
70
  from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available
71
+ from tomwer.core.volume.volumefactory import VolumeFactory
69
72
 
70
73
  from . import settings, utils
71
74
 
@@ -147,10 +150,27 @@ class ResultsLocalRun(ResultsWithStd):
147
150
  raise TypeError(
148
151
  f"results_urls is expected to be an Iterable not {type(results_identifiers)}"
149
152
  )
150
- for identifier in results_identifiers:
151
- if not isinstance(identifier, VolumeIdentifier):
152
- raise TypeError("identifiers are expected to be VolumeIdentifier")
153
- self.__results_identifiers = results_identifiers
153
+
154
+ # check all identifiers
155
+ def check_identifier(identifier):
156
+ if isinstance(identifier, str):
157
+ vol = VolumeFactory.create_tomo_object_from_identifier(
158
+ identifier=identifier
159
+ )
160
+ return vol.get_identifier()
161
+ elif not isinstance(identifier, VolumeIdentifier):
162
+ raise TypeError(
163
+ f"identifiers are expected to be VolumeIdentifier. Get {type(identifier)} instead."
164
+ )
165
+ else:
166
+ return identifier
167
+
168
+ self.__results_identifiers = tuple(
169
+ [
170
+ check_identifier(identifier=identifier)
171
+ for identifier in results_identifiers
172
+ ]
173
+ )
154
174
 
155
175
  @property
156
176
  def results_identifiers(self) -> tuple:
@@ -207,6 +227,7 @@ class _NabuBaseReconstructor:
207
227
  target: Target,
208
228
  cluster_config: Optional[Union[dict, SlurmClusterConfiguration]],
209
229
  process_name: str,
230
+ axis: NabuPlane = NabuPlane.XY,
210
231
  ) -> None:
211
232
  self._scan = scan
212
233
  self._target = Target.from_value(target)
@@ -214,6 +235,7 @@ class _NabuBaseReconstructor:
214
235
  self._process_name = process_name
215
236
  self._process = None
216
237
  self._cancelled = False
238
+ self._axis = NabuPlane.from_value(axis)
217
239
  # nabu subprocess if run locally
218
240
  if isinstance(cluster_config, SlurmClusterConfiguration):
219
241
  self._cluster_config = cluster_config
@@ -246,6 +268,10 @@ class _NabuBaseReconstructor:
246
268
  def process_name(self):
247
269
  return self._process_name
248
270
 
271
+ @property
272
+ def axis(self) -> NabuPlane:
273
+ return self._axis
274
+
249
275
  def only_create_config_file(self):
250
276
  """Should we run the reconstruction or only create the configuration file"""
251
277
  return False
@@ -263,8 +289,6 @@ class _NabuBaseReconstructor:
263
289
  config_to_dump: dict,
264
290
  config_file: str,
265
291
  file_format: str,
266
- start_z: Optional[int],
267
- end_z: Optional[int],
268
292
  info: Optional[str],
269
293
  process_name: str,
270
294
  ):
@@ -284,8 +308,7 @@ class _NabuBaseReconstructor:
284
308
  conf_file=config_file,
285
309
  file_format=file_format,
286
310
  config_to_dump=config_to_dump,
287
- start_z=start_z,
288
- end_z=end_z,
311
+ axis=config_to_dump["reconstruction"].get("slice_plane", "XY"),
289
312
  )
290
313
  elif self.target is Target.SLURM:
291
314
  _logger.info(
@@ -295,8 +318,6 @@ class _NabuBaseReconstructor:
295
318
  conf_file=config_file,
296
319
  config_to_dump=config_to_dump,
297
320
  cluster_config=self.cluster_config.to_dict(),
298
- start_z=start_z,
299
- end_z=end_z,
300
321
  process_name=process_name,
301
322
  info=info,
302
323
  )
@@ -317,11 +338,10 @@ class _NabuBaseReconstructor:
317
338
 
318
339
  def _run_nabu_locally(
319
340
  self,
341
+ axis: NabuPlane,
320
342
  conf_file: str,
321
343
  file_format: str,
322
344
  config_to_dump: dict,
323
- start_z: int,
324
- end_z: int,
325
345
  ) -> ResultsLocalRun:
326
346
  """
327
347
  run locally nabu for a single configuration file.
@@ -341,7 +361,7 @@ class _NabuBaseReconstructor:
341
361
 
342
362
  command = " ".join(
343
363
  (
344
- "python3",
364
+ sys.executable,
345
365
  "-m",
346
366
  settings.NABU_FULL_FIELD_APP_PATH,
347
367
  conf_file,
@@ -372,6 +392,7 @@ class _NabuBaseReconstructor:
372
392
  slice_index=None,
373
393
  scan=self.scan,
374
394
  file_format=file_format,
395
+ axis=axis,
375
396
  )
376
397
  return ResultsLocalRun(
377
398
  success=not nabu_std_err_has_error(errs),
@@ -386,8 +407,6 @@ class _NabuBaseReconstructor:
386
407
  conf_file: str,
387
408
  config_to_dump: dict,
388
409
  cluster_config: dict,
389
- start_z: int,
390
- end_z: int,
391
410
  process_name: str,
392
411
  info: str,
393
412
  ) -> ResultSlurmRun:
@@ -494,9 +513,14 @@ class _NabuBaseReconstructor:
494
513
  "delta_beta"
495
514
  ][0]
496
515
  db = round(float(config["phase"]["delta_beta"]))
516
+ # retrieve axis used
517
+ axis = config.get("reconstruction", {}).get("slice_plane", "XY")
518
+
497
519
  # handle output
498
520
  if "output" in config:
499
- _file_name = self._get_file_basename_reconstruction(pag=pag, db=db, ctf=ctf)
521
+ _file_name = self._get_file_basename_reconstruction(
522
+ pag=pag, db=db, ctf=ctf, axis=axis
523
+ )
500
524
  config["output"]["file_prefix"] = _file_name
501
525
  location, location_cfg_files = get_output_folder_from_scan(
502
526
  mode=ProcessDataOutputDirMode.from_value(
@@ -558,7 +582,7 @@ class _NabuBaseReconstructor:
558
582
  dataset_url = DataUrl(path=dataset_url)
559
583
  if os.path.exists(dataset_url.file_path()):
560
584
  with HDF5File(
561
- dataset_url.file_path(), mode="r", swmr="True"
585
+ dataset_url.file_path(), mode="r", swmr=get_swmr_mode()
562
586
  ) as h5f:
563
587
  if dataset_url.data_path() not in h5f:
564
588
  dataset_url = None
@@ -594,7 +618,7 @@ class _NabuBaseReconstructor:
594
618
  raise NotImplementedError(f"source type {source.value} is not handled")
595
619
  return config, nabu_cfg_folder
596
620
 
597
- def _get_file_basename_reconstruction(self, pag, db, ctf):
621
+ def _get_file_basename_reconstruction(self, pag, db, ctf, axis):
598
622
  """return created file base name"""
599
623
  raise NotImplementedError("Base class")
600
624
 
@@ -16,6 +16,7 @@ else:
16
16
  has_nabu = True
17
17
  import logging
18
18
  import os
19
+ import sys
19
20
  from copy import deepcopy
20
21
  import subprocess
21
22
  from typing import Iterable, Optional, Union
@@ -44,6 +45,7 @@ from tomwer.core.scan.scanbase import TomwerScanBase
44
45
  from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available
45
46
  from tomwer.utils import docstring
46
47
  from tomwer.core.process.reconstruction.nabu.utils import nabu_std_err_has_error
48
+ from tomwer.core.process.reconstruction.nabu.plane import NabuPlane
47
49
 
48
50
  from ..nabu import settings as nabu_settings
49
51
  from . import utils, settings
@@ -59,6 +61,7 @@ def run_nabu_one_slice_several_config(
59
61
  dry_run: bool,
60
62
  slice_index: Union[int, str],
61
63
  file_format: str,
64
+ axis: NabuPlane,
62
65
  advancement: Optional[Progress] = None,
63
66
  process_id: Optional[int] = None,
64
67
  instanciate_classes_only: bool = False,
@@ -108,6 +111,7 @@ def run_nabu_one_slice_several_config(
108
111
  cluster_config=cluster_config,
109
112
  process_name=process_name,
110
113
  output_file_prefix_pattern=output_file_prefix_pattern,
114
+ axis=axis,
111
115
  )
112
116
  if instanciate_classes_only:
113
117
  return (reconstructor,)
@@ -180,6 +184,8 @@ def run_nabu_multicor(
180
184
  # half acquisition it will be refused
181
185
  nabu_config["reconstruction"]["rotation_axis_position"] = numpy.mean(cors)
182
186
 
187
+ axis = nabu_config["reconstruction"].get("slice_plane", "XY")
188
+
183
189
  reconstructor = _ReconstructorMultiCor(
184
190
  scan=scan,
185
191
  nabu_config=nabu_config,
@@ -190,6 +196,7 @@ def run_nabu_multicor(
190
196
  file_format=file_format,
191
197
  cluster_config=cluster_config,
192
198
  process_name=process_name,
199
+ axis=axis,
193
200
  output_file_prefix_pattern=output_file_prefix_pattern,
194
201
  )
195
202
  if instanciate_classes_only:
@@ -227,6 +234,7 @@ class _Reconstructor(_NabuBaseReconstructor):
227
234
  nabu_configs: Iterable,
228
235
  advancement: Optional[Progress],
229
236
  slice_index: Union[int, str],
237
+ axis: Union[str, NabuPlane],
230
238
  target: Target,
231
239
  dry_run: bool,
232
240
  file_format: str,
@@ -235,6 +243,14 @@ class _Reconstructor(_NabuBaseReconstructor):
235
243
  output_file_prefix_pattern=None,
236
244
  ) -> None:
237
245
  """
246
+ :param scan: scan to reconstruct
247
+ :param nabu_configs: all the configuration to run
248
+ :param advancement: Progress object to notify advancement
249
+ :param slice_index: index of the slice to reconstruct.
250
+ :param axis: axis over which we want to do the reconstruction
251
+ :param target: is the reconstruction is to made locally or remotly
252
+ :param file_format: reconstructed volume file format
253
+ :param cluster_config: cluster configuration in the case of a remote execution
238
254
  :param str extra_output_file_pattern: possible extra file name pattern like for cor we want to add 'cor_' as prefix and cor value as suffix.
239
255
  To make the file name unique. For delta/beta it is already forseen to be unique. For now keywords are:
240
256
  * file_name: default file name according to db values and dataset name
@@ -246,12 +262,12 @@ class _Reconstructor(_NabuBaseReconstructor):
246
262
  target=target,
247
263
  cluster_config=cluster_config,
248
264
  process_name=process_name,
265
+ axis=axis,
249
266
  )
250
267
  if not isinstance(slice_index, (int, str)):
251
268
  raise TypeError(
252
269
  f"slice_index should be an int or a string not {type(slice_index)}"
253
270
  )
254
-
255
271
  self.advancement = advancement
256
272
  self.slice_index = slice_index
257
273
  self.nabu_configs = nabu_configs
@@ -286,8 +302,6 @@ class _Reconstructor(_NabuBaseReconstructor):
286
302
  config_to_dump=config_to_dump,
287
303
  config_file=conf_file,
288
304
  file_format=self.file_format,
289
- start_z=None,
290
- end_z=None,
291
305
  info="nabu slice reconstruction",
292
306
  process_name=self.process_name,
293
307
  )
@@ -349,6 +363,7 @@ class _Reconstructor(_NabuBaseReconstructor):
349
363
  pag=pag,
350
364
  db=db,
351
365
  ctf=ctf,
366
+ axis=self.axis,
352
367
  )
353
368
  file_prefix = self._format_file_prefix(file_prefix=file_prefix, value=value)
354
369
  _config["output"]["file_prefix"] = file_prefix
@@ -358,8 +373,19 @@ class _Reconstructor(_NabuBaseReconstructor):
358
373
 
359
374
  if "reconstruction" not in _config:
360
375
  _config["reconstruction"] = {}
361
- _config["reconstruction"]["start_z"] = self.slice_index
362
- _config["reconstruction"]["end_z"] = self.slice_index
376
+ if self.axis is NabuPlane.YZ:
377
+ _config["reconstruction"]["start_x"] = self.slice_index
378
+ _config["reconstruction"]["end_x"] = self.slice_index
379
+ elif self.axis is NabuPlane.XZ:
380
+ _config["reconstruction"]["start_y"] = self.slice_index
381
+ _config["reconstruction"]["end_y"] = self.slice_index
382
+ elif self.axis is NabuPlane.XY:
383
+ _config["reconstruction"]["start_z"] = self.slice_index
384
+ _config["reconstruction"]["end_z"] = self.slice_index
385
+ else:
386
+ raise ValueError(
387
+ f"self.axis has an invalid value: {self.axis} when expected to be in {NabuPlane.values()}"
388
+ )
363
389
  return _config, file_prefix
364
390
 
365
391
  def preprocess_config(self, config, value) -> tuple:
@@ -396,6 +422,7 @@ class _ReconstructorMultiCor(_NabuBaseReconstructor):
396
422
  def __init__(
397
423
  self,
398
424
  nabu_config: dict,
425
+ axis: Union[str, NabuPlane],
399
426
  cors: tuple,
400
427
  file_format,
401
428
  slice_index: Union[int, str] = "middle",
@@ -507,7 +534,7 @@ class _ReconstructorMultiCor(_NabuBaseReconstructor):
507
534
  cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref])
508
535
  command = " ".join(
509
536
  (
510
- "python3",
537
+ sys.executable,
511
538
  "-m",
512
539
  settings.NABU_MULTICOR_PATH,
513
540
  conf_file, # input file
@@ -549,7 +576,7 @@ class _ReconstructorMultiCor(_NabuBaseReconstructor):
549
576
  }
550
577
  return ResultsLocalRun(
551
578
  success=not nabu_std_err_has_error(errs),
552
- results_identifiers=recons_vol_identifiers,
579
+ results_identifiers=recons_vol_identifiers.values(),
553
580
  std_out=outs,
554
581
  std_err=errs,
555
582
  config=config_to_dump, # config_slices,