tomwer 1.2.9__py3-none-any.whl → 1.3.0a0__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 (253) hide show
  1. orangecontrib/tomwer/tutorials/icat_publication.ows +58 -0
  2. orangecontrib/tomwer/widgets/__init__.py +1 -0
  3. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
  4. orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
  5. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
  6. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +11 -5
  7. orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
  8. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +31 -18
  9. orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +14 -7
  10. orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
  11. orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
  12. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
  13. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +4 -4
  14. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
  15. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
  16. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +2 -0
  17. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
  18. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
  19. orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
  20. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
  21. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
  22. orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
  23. orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
  24. orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
  25. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
  26. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
  27. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
  28. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
  29. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
  30. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
  31. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +9 -8
  32. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +3 -3
  33. orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +179 -169
  34. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
  35. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
  36. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +7 -13
  37. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +7 -17
  38. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +3 -4
  39. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
  40. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
  41. orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
  42. tomwer/__main__.py +11 -58
  43. tomwer/app/canvas.py +8 -0
  44. tomwer/app/canvas_launcher/config.py +13 -11
  45. tomwer/app/darkref.py +1 -1
  46. tomwer/app/darkrefpatch.py +1 -1
  47. tomwer/app/imagekeyeditor.py +5 -5
  48. tomwer/app/imagekeyupgrader.py +5 -5
  49. tomwer/app/intensitynormalization.py +2 -2
  50. tomwer/app/radiostack.py +2 -2
  51. tomwer/app/zstitching.py +74 -3
  52. tomwer/core/cluster/cluster.py +26 -0
  53. tomwer/core/log/logger.py +7 -5
  54. tomwer/core/process/conditions/filters.py +1 -1
  55. tomwer/core/process/control/datalistener/datalistener.py +3 -3
  56. tomwer/core/process/control/nxtomoconcatenate.py +13 -13
  57. tomwer/core/process/control/nxtomomill.py +83 -25
  58. tomwer/core/process/control/scantransfer.py +11 -10
  59. tomwer/core/process/control/scanvalidator.py +3 -2
  60. tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
  61. tomwer/core/process/control/test/test_email.py +4 -4
  62. tomwer/core/process/control/test/test_h52nx_process.py +59 -7
  63. tomwer/core/process/control/test/test_volume_link.py +64 -64
  64. tomwer/core/process/control/timer.py +1 -1
  65. tomwer/core/process/control/volumesymlink.py +200 -200
  66. tomwer/core/process/edit/darkflatpatch.py +6 -6
  67. tomwer/core/process/edit/imagekeyeditor.py +17 -18
  68. tomwer/core/process/icat/__init__.py +0 -0
  69. tomwer/core/process/icat/createscreenshots.py +100 -0
  70. tomwer/core/process/icat/gallery.py +377 -0
  71. tomwer/core/process/icat/icatbase.py +36 -0
  72. tomwer/core/process/icat/publish.py +228 -0
  73. tomwer/core/process/icat/screenshots.py +26 -0
  74. tomwer/core/process/output.py +52 -0
  75. tomwer/core/process/reconstruction/axis/axis.py +17 -10
  76. tomwer/core/process/reconstruction/axis/mode.py +4 -0
  77. tomwer/core/process/reconstruction/axis/params.py +9 -4
  78. tomwer/core/process/reconstruction/darkref/darkrefs.py +8 -6
  79. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
  80. tomwer/core/process/reconstruction/darkref/params.py +1 -1
  81. tomwer/core/process/reconstruction/lamino/tofu.py +4 -4
  82. tomwer/core/process/reconstruction/nabu/castvolume.py +1 -1
  83. tomwer/core/process/reconstruction/nabu/helical.py +9 -5
  84. tomwer/core/process/reconstruction/nabu/nabucommon.py +32 -62
  85. tomwer/core/process/reconstruction/nabu/nabuscores.py +387 -61
  86. tomwer/core/process/reconstruction/nabu/nabuslices.py +33 -21
  87. tomwer/core/process/reconstruction/nabu/nabuvolume.py +37 -14
  88. tomwer/core/process/reconstruction/nabu/settings.py +2 -2
  89. tomwer/core/process/reconstruction/nabu/utils.py +129 -24
  90. tomwer/core/process/reconstruction/output.py +108 -0
  91. tomwer/core/process/reconstruction/saaxis/saaxis.py +233 -263
  92. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +140 -86
  93. tomwer/core/process/reconstruction/scores/params.py +4 -1
  94. tomwer/core/process/reconstruction/scores/scores.py +13 -0
  95. tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
  96. tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
  97. tomwer/core/process/reconstruction/test/test_darkref_copy.py +3 -3
  98. tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
  99. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
  100. tomwer/core/process/stitching/nabustitcher.py +2 -2
  101. tomwer/core/process/test/test_axis.py +6 -6
  102. tomwer/core/process/test/test_dark_and_flat.py +10 -7
  103. tomwer/core/process/test/test_data_transfer.py +7 -6
  104. tomwer/core/process/test/test_nabu.py +4 -4
  105. tomwer/core/process/test/test_normalization.py +2 -2
  106. tomwer/core/scan/edfscan.py +4 -1
  107. tomwer/core/scan/hdf5scan.py +19 -500
  108. tomwer/core/scan/nxtomoscan.py +532 -0
  109. tomwer/core/scan/scanbase.py +42 -20
  110. tomwer/core/scan/scanfactory.py +13 -13
  111. tomwer/core/scan/test/test_future_scan.py +2 -2
  112. tomwer/core/scan/test/test_h5.py +12 -10
  113. tomwer/core/scan/test/test_process_registration.py +2 -2
  114. tomwer/core/scan/test/test_scan.py +4 -3
  115. tomwer/core/settings.py +20 -0
  116. tomwer/core/test/test_scanutils.py +8 -7
  117. tomwer/core/test/test_utils.py +33 -26
  118. tomwer/core/utils/__init__.py +0 -466
  119. tomwer/core/utils/deprecation.py +1 -1
  120. tomwer/core/utils/dictutils.py +14 -0
  121. tomwer/core/utils/lbsram.py +35 -0
  122. tomwer/core/utils/nxtomoutils.py +1 -1
  123. tomwer/core/utils/scanutils.py +6 -6
  124. tomwer/core/utils/spec.py +263 -0
  125. tomwer/core/volume/volumefactory.py +2 -2
  126. tomwer/gui/cluster/slurm.py +260 -60
  127. tomwer/gui/cluster/test/test_cluster.py +13 -0
  128. tomwer/gui/cluster/test/test_supervisor.py +2 -2
  129. tomwer/gui/configuration/__init__.py +0 -0
  130. tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
  131. tomwer/gui/configuration/level.py +22 -0
  132. tomwer/gui/control/actions.py +54 -0
  133. tomwer/gui/control/datalist.py +78 -16
  134. tomwer/gui/control/datalistener.py +4 -16
  135. tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
  136. tomwer/gui/control/history.py +2 -2
  137. tomwer/gui/control/observations.py +2 -2
  138. tomwer/gui/control/reducedarkflatselector.py +1 -1
  139. tomwer/gui/control/selectorwidgetbase.py +36 -9
  140. tomwer/gui/control/serie/seriecreator.py +5 -22
  141. tomwer/gui/control/test/test_email.py +1 -1
  142. tomwer/gui/control/test/test_scanvalidator.py +6 -5
  143. tomwer/gui/control/test/test_single_tomo_obj.py +2 -2
  144. tomwer/gui/control/tomoobjdisplaymode.py +8 -0
  145. tomwer/gui/debugtools/datasetgenerator.py +3 -3
  146. tomwer/gui/edit/dkrfpatch.py +16 -22
  147. tomwer/gui/edit/imagekeyeditor.py +8 -11
  148. tomwer/gui/edit/nxtomoeditor.py +111 -44
  149. tomwer/gui/edit/nxtomowarmer.py +4 -4
  150. tomwer/gui/edit/test/test_dkrf_patch.py +7 -7
  151. tomwer/gui/edit/test/test_image_key_editor.py +3 -3
  152. tomwer/gui/edit/test/test_nx_editor.py +40 -16
  153. tomwer/gui/icat/__init__.py +0 -0
  154. tomwer/gui/icat/createscreenshots.py +80 -0
  155. tomwer/gui/icat/gallery.py +214 -0
  156. tomwer/gui/icat/publish.py +187 -0
  157. tomwer/gui/reconstruction/axis/axis.py +171 -57
  158. tomwer/gui/reconstruction/axis/radioaxis.py +80 -95
  159. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
  160. tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
  161. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +3 -6
  162. tomwer/gui/reconstruction/nabu/castvolume.py +1 -1
  163. tomwer/gui/reconstruction/nabu/check.py +9 -9
  164. tomwer/gui/reconstruction/nabu/helical.py +29 -12
  165. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
  166. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +110 -33
  167. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +9 -12
  168. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +219 -29
  169. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +3 -6
  170. tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
  171. tomwer/gui/reconstruction/nabu/slices.py +6 -7
  172. tomwer/gui/reconstruction/nabu/volume.py +22 -10
  173. tomwer/gui/reconstruction/normalization/intensity.py +15 -23
  174. tomwer/gui/reconstruction/saaxis/corrangeselector.py +7 -23
  175. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
  176. tomwer/gui/reconstruction/saaxis/saaxis.py +7 -9
  177. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +2 -1
  178. tomwer/gui/reconstruction/scores/control.py +2 -9
  179. tomwer/gui/reconstruction/scores/scoreplot.py +11 -5
  180. tomwer/gui/reconstruction/test/test_axis.py +23 -12
  181. tomwer/gui/reconstruction/test/test_lamino.py +8 -3
  182. tomwer/gui/reconstruction/test/test_nabu.py +28 -9
  183. tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
  184. tomwer/gui/reconstruction/test/test_sadeltabeta.py +2 -2
  185. tomwer/gui/settings.py +5 -28
  186. tomwer/gui/stackplot.py +2 -5
  187. tomwer/gui/stitching/action.py +49 -0
  188. tomwer/gui/stitching/config/axisparams.py +7 -24
  189. tomwer/gui/stitching/config/output.py +10 -8
  190. tomwer/gui/stitching/config/positionoveraxis.py +22 -23
  191. tomwer/gui/stitching/normalization.py +117 -0
  192. tomwer/gui/stitching/stitchandbackground.py +4 -6
  193. tomwer/gui/stitching/stitching.py +265 -43
  194. tomwer/gui/stitching/stitching_preview.py +62 -5
  195. tomwer/gui/stitching/stitching_raw.py +2 -5
  196. tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
  197. tomwer/gui/utils/buttons.py +112 -29
  198. tomwer/gui/utils/inputwidget.py +33 -25
  199. tomwer/gui/utils/scandescription.py +4 -0
  200. tomwer/gui/utils/step.py +144 -0
  201. tomwer/gui/utils/unitsystem.py +2 -5
  202. tomwer/gui/utils/vignettes.py +176 -15
  203. tomwer/gui/visualization/dataviewer.py +1 -4
  204. tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
  205. tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
  206. tomwer/gui/visualization/scanoverview.py +1 -1
  207. tomwer/gui/visualization/sinogramviewer.py +1 -10
  208. tomwer/gui/visualization/test/test_diffviewer.py +3 -3
  209. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
  210. tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
  211. tomwer/gui/visualization/test/test_stacks.py +3 -3
  212. tomwer/gui/visualization/test/test_volumeviewer.py +2 -2
  213. tomwer/io/utils/raw_and_processed_data.py +84 -0
  214. tomwer/io/utils/tomoobj.py +4 -6
  215. tomwer/resources/gui/icons/ruler.png +0 -0
  216. tomwer/resources/gui/icons/ruler.svg +273 -0
  217. tomwer/resources/gui/icons/short_description.png +0 -0
  218. tomwer/resources/gui/icons/short_description.svg +58 -0
  219. tomwer/resources/gui/icons/url.png +0 -0
  220. tomwer/resources/gui/icons/url.svg +58 -0
  221. tomwer/synctools/stacks/edit/darkflatpatch.py +2 -2
  222. tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
  223. tomwer/synctools/stacks/reconstruction/axis.py +4 -4
  224. tomwer/synctools/stacks/reconstruction/castvolume.py +2 -2
  225. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -10
  226. tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
  227. tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
  228. tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
  229. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
  230. tomwer/synctools/test/test_darkRefs.py +7 -58
  231. tomwer/synctools/test/test_foldertransfer.py +6 -6
  232. tomwer/synctools/utils/scanstages.py +6 -6
  233. tomwer/tests/conftest.py +34 -0
  234. tomwer/tests/datasets.py +13 -0
  235. tomwer/tests/test_scripts.py +92 -39
  236. tomwer/tests/utils.py +5 -0
  237. tomwer/version.py +3 -3
  238. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/METADATA +39 -39
  239. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/RECORD +248 -209
  240. tomwer/resources/gui/icons/esrf_1.svg +0 -307
  241. tomwer/resources/gui/icons/triangle.svg +0 -80
  242. tomwer/synctools/test/test_scanstages.py +0 -162
  243. tomwer/tests/utils/__init__.py +0 -247
  244. tomwer/tests/utils/utilstest.py +0 -220
  245. /tomwer/app/{saaxis.py → multicor.py} +0 -0
  246. /tomwer/app/{sadeltabeta.py → multipag.py} +0 -0
  247. /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
  248. /tomwer-1.2.9-py3.11-nspkg.pth → /tomwer-1.3.0a0-py3.11-nspkg.pth +0 -0
  249. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/LICENSE +0 -0
  250. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/WHEEL +0 -0
  251. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/entry_points.txt +0 -0
  252. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/namespace_packages.txt +0 -0
  253. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+ import os
3
+ from silx.utils.enum import Enum as _Enum
4
+
5
+
6
+ class ProcessDataOutputDirMode(_Enum):
7
+ IN_SCAN_FOLDER = "same folder as scan"
8
+ PROCESSED_DATA_FOLDER = "PROCESSED_DATA folder"
9
+ RAW_DATA_FOLDER = "RAW_DATA folder"
10
+ OTHER = "other"
11
+
12
+ @classmethod
13
+ def from_value(cls, value):
14
+ # ensure backward compatibility
15
+ if value == "near input":
16
+ return cls.IN_SCAN_FOLDER
17
+ elif value == "processed data dir":
18
+ return cls.PROCESSED_DATA_FOLDER
19
+ elif value == "raw data dir":
20
+ return cls.RAW_DATA_FOLDER
21
+ return super().from_value(value)
22
+
23
+
24
+ class NabuOutputFileFormat(_Enum):
25
+ TIFF = "tiff"
26
+ HDF5 = "hdf5"
27
+ JP2K = "jp2"
28
+ EDF = "edf"
29
+ RAW = "vol"
30
+
31
+ @classmethod
32
+ def from_value(cls, value):
33
+ if isinstance(value, str):
34
+ value = value.lstrip(".")
35
+ return super().from_value(value)
36
+
37
+
38
+ def get_file_format(file_str):
39
+ extension = os.path.splitext(file_str.lower())[-1]
40
+ extension = extension.lstrip(".")
41
+ if extension in ("tiff", "tif"):
42
+ return NabuOutputFileFormat.TIFF
43
+ elif extension in ("hdf5", "hdf", "h5"):
44
+ return NabuOutputFileFormat.HDF5
45
+ elif extension in ("jp2", "jp2k", "jpg2k"):
46
+ return NabuOutputFileFormat.JP2K
47
+ elif extension in ("edf",):
48
+ return NabuOutputFileFormat.EDF
49
+ elif extension in ("vol", "raw"):
50
+ return NabuOutputFileFormat.RAW
51
+ else:
52
+ raise ValueError(f"Unrecognized file extension {extension} from {file_str}")
@@ -43,12 +43,12 @@ from nabu.pipeline.estimators import SinoCORFinder
43
43
  from nabu.resources.nxflatfield import update_dataset_info_flats_darks
44
44
  from processview.core.manager import DatasetState, ProcessManager
45
45
  from processview.core.superviseprocess import SuperviseProcess
46
- from silx.utils.deprecation import deprecated_warning
46
+ from tomwer.core.utils.deprecation import deprecated_warning
47
47
 
48
48
  import tomwer.version
49
49
  from tomwer.core.process.reconstruction.utils.cor import absolute_pos_to_relative
50
50
  from tomwer.core.process.task import Task
51
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
51
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
52
52
  from tomwer.core.scan.scanbase import TomwerScanBase
53
53
  from tomwer.core.scan.scanfactory import ScanFactory
54
54
  from tomwer.core.utils import image, logconfig
@@ -108,7 +108,7 @@ def adapt_tomwer_scan_to_nabu(scan: TomwerScanBase):
108
108
  updating infos regarding flat and dark if needed
109
109
  """
110
110
  dataset_infos = scan.to_nabu_dataset_analyser()
111
- if isinstance(scan, HDF5TomoScan):
111
+ if isinstance(scan, NXtomoScan):
112
112
  try:
113
113
  update_dataset_info_flats_darks(
114
114
  dataset_infos,
@@ -183,12 +183,15 @@ def compute_cor_nabu_growing_window_sinogram(
183
183
 
184
184
  :return:
185
185
  """
186
+ has_darks = scan.reduced_darks is not None and len(scan.reduced_darks) > 0
187
+ has_flats = scan.reduced_flats is not None and len(scan.reduced_flats) > 0
188
+
186
189
  corfinder = SinoCORFinder(
187
190
  dataset_info=adapt_tomwer_scan_to_nabu(scan),
188
191
  method="growing-window",
189
192
  slice_idx=scan.axis_params.sinogram_line or "middle",
190
193
  subsampling=scan.axis_params.sinogram_subsampling,
191
- do_flatfield=True,
194
+ do_flatfield=has_darks and has_flats,
192
195
  cor_options=scan.axis_params.get_nabu_cor_options_as_dict(),
193
196
  logger=_logger,
194
197
  )
@@ -213,12 +216,15 @@ def compute_scan_sino_coarse_to_fine(scan):
213
216
  :param scan:
214
217
  :return:
215
218
  """
219
+ has_darks = scan.reduced_darks is not None and len(scan.reduced_darks) > 0
220
+ has_flats = scan.reduced_flats is not None and len(scan.reduced_flats) > 0
221
+
216
222
  corfinder = SinoCORFinder(
217
223
  dataset_info=adapt_tomwer_scan_to_nabu(scan),
218
224
  method=AxisMode.sino_coarse_to_fine.value,
219
225
  slice_idx=scan.axis_params.sinogram_line or "middle",
220
226
  subsampling=scan.axis_params.sinogram_subsampling,
221
- do_flatfield=True,
227
+ do_flatfield=has_darks and has_flats,
222
228
  cor_options=scan.axis_params.get_nabu_cor_options_as_dict(),
223
229
  logger=_logger,
224
230
  )
@@ -252,8 +258,6 @@ def compute_scan_composite_coarse_to_fine(scan: TomwerScanBase):
252
258
  # allow some tolerance for the "side" argument that is there only
253
259
  # in the new one
254
260
 
255
- extra_args = {}
256
-
257
261
  cor_options = scan.axis_params.get_nabu_cor_options_as_dict()
258
262
  for key in "low_pass", "high_pass":
259
263
  if key in cor_options:
@@ -266,7 +270,6 @@ def compute_scan_composite_coarse_to_fine(scan: TomwerScanBase):
266
270
  cor_options=cor_options,
267
271
  logger=_logger,
268
272
  take_log=take_log,
269
- **extra_args,
270
273
  )
271
274
  res = corfinder.find_cor()
272
275
  return _absolute_pos_to_relative_with_warning(
@@ -381,12 +384,15 @@ def compute_cor_nabu_sliding_window_sinogram(
381
384
 
382
385
  :return:
383
386
  """
387
+ has_darks = scan.reduced_darks is not None and len(scan.reduced_darks) > 0
388
+ has_flats = scan.reduced_flats is not None and len(scan.reduced_flats) > 0
389
+
384
390
  corfinder = SinoCORFinder(
385
391
  dataset_info=adapt_tomwer_scan_to_nabu(scan),
386
392
  method="sliding-window",
387
393
  slice_idx=scan.axis_params.sinogram_line or "middle",
388
394
  subsampling=scan.axis_params.sinogram_subsampling,
389
- do_flatfield=True,
395
+ do_flatfield=has_darks and has_flats,
390
396
  cor_options=scan.axis_params.get_nabu_cor_options_as_dict(),
391
397
  logger=_logger,
392
398
  )
@@ -597,6 +603,7 @@ class AxisTask(
597
603
  AxisMode.growing_window_radios: compute_scan_cor_nabu_growing_window,
598
604
  AxisMode.sino_coarse_to_fine: compute_scan_sino_coarse_to_fine,
599
605
  AxisMode.composite_coarse_to_fine: compute_scan_composite_coarse_to_fine,
606
+ AxisMode.near: compute_scan_composite_coarse_to_fine,
600
607
  }
601
608
 
602
609
  def __init__(
@@ -722,7 +729,7 @@ class AxisTask(
722
729
  assert isinstance(scan, TomwerScanBase)
723
730
  if scan.process_file is not None:
724
731
  entry = "entry"
725
- if isinstance(scan, HDF5TomoScan):
732
+ if isinstance(scan, NXtomoScan):
726
733
  entry = scan.entry
727
734
  with scan.acquire_process_file_lock():
728
735
  self.register_process(
@@ -56,6 +56,8 @@ class AxisMode(_Enum):
56
56
  sino_coarse_to_fine = "sino-coarse-to-fine"
57
57
  composite_coarse_to_fine = "composite-coarse-to-fine"
58
58
  read = "read"
59
+ # alias to composite_coarse_to_fine with near mode
60
+ near = "near"
59
61
 
60
62
  @classmethod
61
63
  def from_value(cls, value):
@@ -87,9 +89,11 @@ _VALID_INPUTS = {
87
89
  _InputType.COMPOSITE,
88
90
  ), # in fact it is more an n radio constrain
89
91
  AxisMode.read: None,
92
+ AxisMode.near: (_InputType.COMPOSITE,), # in fact it is more an n radio constrain
90
93
  }
91
94
 
92
95
  _AXIS_MODE_CONSTRAIN = {
93
96
  AxisMode.sino_coarse_to_fine: (_Constrain.FULL_TURN,),
94
97
  AxisMode.composite_coarse_to_fine: (_Constrain.FULL_TURN,),
98
+ AxisMode.near: (_Constrain.FULL_TURN,),
95
99
  }
@@ -42,7 +42,7 @@ from tomoscan.esrf.scan.utils import get_data
42
42
 
43
43
  from tomwer.core.process.task import Task
44
44
  from tomwer.core.scan.scanbase import TomwerScanBase
45
- from tomwer.core.utils import getParametersFromParOrInfo
45
+ from tomwer.core.utils.spec import getParametersFromParOrInfo
46
46
 
47
47
  from .anglemode import CorAngleMode
48
48
  from .mode import AxisMode
@@ -905,9 +905,11 @@ class AxisRP:
905
905
  AxisMode.growing_window_radios,
906
906
  ):
907
907
  options["side"] = self.side
908
- elif self.mode in (AxisMode.composite_coarse_to_fine,):
908
+ elif self.mode in (AxisMode.composite_coarse_to_fine, AxisMode.near):
909
909
  near_pos = self.composite_options.get("near_pos", 0.0)
910
910
  near_width = self.composite_options.get("near_width", 20.0)
911
+ if self.mode is AxisMode.near:
912
+ self.side = "near"
911
913
  options["side"] = self.side
912
914
  options["near_pos"] = near_pos
913
915
  options["near_width"] = near_width
@@ -917,8 +919,11 @@ class AxisRP:
917
919
 
918
920
  if extra_cor_options != "":
919
921
  for opt in self.extra_cor_options.replace(" ", "").split(";"):
920
- key, value = opt.split("=")
921
- options[key] = value
922
+ if len(opt.split("=")) == 2:
923
+ key, value = opt.split("=")
924
+ options[key] = value
925
+ else:
926
+ _logger.info(f"ignore option {opt}. Invalid synthax")
922
927
  return options
923
928
 
924
929
  @deprecated(replacement="get_nabu_cor_options_as_str", since_version="1.1")
@@ -37,14 +37,16 @@ from queue import Queue
37
37
 
38
38
  from processview.core.manager import DatasetState, ProcessManager
39
39
  from processview.core.superviseprocess import SuperviseProcess
40
- from silx.utils.deprecation import deprecated_warning
40
+ from tomwer.core.utils.deprecation import deprecated_warning
41
41
 
42
- from tomoscan.framereducerbase import REDUCER_TARGET, ReduceMethod
42
+ from tomoscan.framereducer.target import REDUCER_TARGET
43
+ from tomoscan.framereducer.method import ReduceMethod
43
44
 
44
45
  import tomwer.version
45
- from tomwer.core import settings, utils
46
+ from tomwer.core import settings
47
+ from tomwer.core.utils.lbsram import is_low_on_memory
46
48
  from tomwer.core.process.task import Task
47
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
49
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
48
50
  from tomwer.core.scan.scanbase import TomwerScanBase
49
51
  from tomwer.core.scan.scanfactory import ScanFactory
50
52
  from tomwer.core.utils.scanutils import data_identifier_to_scan
@@ -302,7 +304,7 @@ class DarkRefsTask(
302
304
  logger.processStarted(f"start dark and ref for {scan}")
303
305
  if (
304
306
  settings.isOnLbsram(scan)
305
- and utils.isLowOnMemory(settings.get_lbsram_path()) is True
307
+ and is_low_on_memory(settings.get_lbsram_path()) is True
306
308
  ):
307
309
  mess = (
308
310
  "low memory, do compute dark and flat field mean/median "
@@ -392,7 +394,7 @@ class DarkRefsTask(
392
394
  if len(results) > 0:
393
395
  # if some processing to be registered
394
396
  if scan.process_file is not None and not (
395
- isinstance(scan, HDF5TomoScan) and not self.__new_hdf5_entry_created
397
+ isinstance(scan, NXtomoScan) and not self.__new_hdf5_entry_created
396
398
  ):
397
399
  with scan.acquire_process_file_lock():
398
400
  entry = "entry"
@@ -44,7 +44,7 @@ from tomoscan.esrf.scan.utils import (
44
44
  copy_h5_dict_flats_to,
45
45
  cwd_context,
46
46
  )
47
- from tomoscan.framereducerbase import REDUCER_TARGET
47
+ from tomoscan.framereducer.target import REDUCER_TARGET
48
48
  from tomoscan.io import HDF5File
49
49
 
50
50
  from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask
@@ -31,7 +31,7 @@ __date__ = "07/03/2019"
31
31
  import enum
32
32
 
33
33
  from silx.utils.enum import Enum as _Enum
34
- from tomoscan.framereducerbase import ReduceMethod
34
+ from tomoscan.framereducer.method import ReduceMethod
35
35
 
36
36
  from tomwer.core.process.reconstruction.darkref.settings import (
37
37
  DARKHST_PREFIX,
@@ -44,12 +44,12 @@ from tomwer.core.process.reconstruction.darkref.settings import (
44
44
  REFHST_PREFIX,
45
45
  )
46
46
  from tomwer.core.process.task import Task
47
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
47
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
48
48
  from tomwer.core.scan.scanbase import TomwerScanBase
49
49
  from tomwer.core.scan.scanfactory import ScanFactory
50
- from tomwer.core.utils import getDim1Dim2
50
+ from tomwer.core.utils.spec import getDim1Dim2
51
51
  from tomwer.core.utils.char import PSI_CHAR
52
- from silx.utils.deprecation import deprecated_warning
52
+ from tomwer.core.utils.deprecation import deprecated_warning
53
53
 
54
54
  logger = logging.getLogger(__name__)
55
55
 
@@ -871,7 +871,7 @@ class LaminoReconstructionTask(
871
871
  )
872
872
  if not self.dry_run:
873
873
  entry = "entry"
874
- if isinstance(scan, HDF5TomoScan):
874
+ if isinstance(scan, NXtomoScan):
875
875
  entry = scan.entry
876
876
  with scan.acquire_process_file_lock():
877
877
  self.register_process(
@@ -47,7 +47,7 @@ from tomoscan.volumebase import VolumeBase
47
47
  from tomwer.core.cluster.cluster import SlurmClusterConfiguration
48
48
  from tomwer.core.futureobject import FutureTomwerObject
49
49
  from tomwer.core.process.reconstruction.nabu import settings
50
- from tomwer.core.process.reconstruction.nabu.nabucommon import NabuOutputFileFormat
50
+ from tomwer.core.process.reconstruction.output import NabuOutputFileFormat
51
51
  from tomwer.core.process.task import Task
52
52
  from tomwer.core.utils.slurm import get_slurm_script_name
53
53
  from tomwer.core.utils.volumeutils import volume_identifier_to_volume
@@ -6,7 +6,7 @@ from nabu.io.reader import load_images_from_dataurl_dict
6
6
  from nabu.app.prepare_weights_double import create_heli_maps
7
7
 
8
8
  from tomwer.core.process.task import TaskWithProgress
9
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
9
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
10
10
  from tomwer.core.utils.scanutils import format_output_location
11
11
 
12
12
 
@@ -17,8 +17,10 @@ class NabuHelicalPrepareWeightsDouble(
17
17
  TaskWithProgress,
18
18
  input_names=(
19
19
  "data",
20
- "transition_width",
20
+ "transition_width_vertical",
21
+ "transition_width_horizontal",
21
22
  "processes_file",
23
+ "rotation_axis_position",
22
24
  ),
23
25
  optional_input_names=("progress",),
24
26
  output_names=("data",),
@@ -26,8 +28,8 @@ class NabuHelicalPrepareWeightsDouble(
26
28
  def run(self):
27
29
  # TODO: handle future /cluster config ???
28
30
  scan = self.inputs.data
29
- if not isinstance(scan, HDF5TomoScan):
30
- raise TypeError(f"data is expected to be an instance of {HDF5TomoScan}")
31
+ if not isinstance(scan, NXtomoScan):
32
+ raise TypeError(f"data is expected to be an instance of {NXtomoScan}")
31
33
  dataset_info = HDF5DatasetAnalyzer(
32
34
  scan.master_file,
33
35
  extra_options={"h5_entry": scan.entry},
@@ -48,7 +50,9 @@ class NabuHelicalPrepareWeightsDouble(
48
50
  profile=mappe,
49
51
  process_file_name=scan.helical.processes_files,
50
52
  entry_name=scan.entry,
51
- transition_width=self.inputs.transition_width,
53
+ transition_width_vertical=self.inputs.transition_width_vertical,
54
+ transition_width_horizontal=self.inputs.transition_width_horizontal,
55
+ rotation_axis_position=self.inputs.rotation_axis_position,
52
56
  )
53
57
 
54
58
  self.outputs.data = scan
@@ -42,11 +42,11 @@ import psutil
42
42
 
43
43
  import numpy
44
44
  from silx.io.url import DataUrl
45
- from silx.utils.enum import Enum as _Enum
46
45
  from sluurp.executor import submit as submit_to_slurm_cluster
47
46
  from sluurp.job import SBatchScriptJob
48
47
  from tomoscan.io import HDF5File
49
48
  from tomoscan.normalization import Method as INormMethod
49
+ from tomoscan.identifier import VolumeIdentifier
50
50
 
51
51
  from tomwer.core.cluster.cluster import SlurmClusterConfiguration
52
52
  from tomwer.core.process.reconstruction.nabu.target import Target
@@ -54,13 +54,17 @@ from tomwer.core.process.reconstruction.nabu.utils import (
54
54
  _NabuPhaseMethod,
55
55
  nabu_std_err_has_error,
56
56
  )
57
+ from tomwer.core.process.reconstruction.output import (
58
+ ProcessDataOutputDirMode,
59
+ get_output_folder_from_scan,
60
+ NabuOutputFileFormat,
61
+ )
57
62
  from tomwer.core.process.reconstruction.normalization.params import (
58
63
  _ValueSource as INormSource,
59
64
  )
60
65
  from tomwer.core.scan.edfscan import EDFTomoScan
61
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
66
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
62
67
  from tomwer.core.scan.scanbase import TomwerScanBase
63
- from tomwer.core.utils.scanutils import format_output_location
64
68
  from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available
65
69
 
66
70
  from . import settings, utils
@@ -85,37 +89,6 @@ else:
85
89
  has_nabu = True
86
90
 
87
91
 
88
- class NabuOutputFileFormat(_Enum):
89
- TIFF = "tiff"
90
- HDF5 = "hdf5"
91
- JP2K = "jp2"
92
- EDF = "edf"
93
- RAW = "vol"
94
-
95
- @classmethod
96
- def from_value(cls, value):
97
- if isinstance(value, str):
98
- value = value.lstrip(".")
99
- return super().from_value(value)
100
-
101
-
102
- def get_file_format(file_str):
103
- extension = os.path.splitext(file_str.lower())[-1]
104
- extension = extension.lstrip(".")
105
- if extension in ("tiff", "tif"):
106
- return NabuOutputFileFormat.TIFF
107
- elif extension in ("hdf5", "hdf", "h5"):
108
- return NabuOutputFileFormat.HDF5
109
- elif extension in ("jp2", "jp2k", "jpg2k"):
110
- return NabuOutputFileFormat.JP2K
111
- elif extension in ("edf",):
112
- return NabuOutputFileFormat.EDF
113
- elif extension in ("vol", "raw"):
114
- return NabuOutputFileFormat.RAW
115
- else:
116
- raise ValueError(f"Unrecognized file extension {extension} from {file_str}")
117
-
118
-
119
92
  class ResultsRun:
120
93
  """
121
94
  Base class of results for nabu
@@ -165,24 +138,27 @@ class ResultsLocalRun(ResultsWithStd):
165
138
 
166
139
  def __init__(
167
140
  self,
168
- results_urls: tuple,
141
+ results_identifiers: tuple,
169
142
  *args,
170
143
  **kwargs,
171
144
  ) -> None:
172
145
  super().__init__(*args, **kwargs)
173
- if not isinstance(results_urls, Iterable):
146
+ if not isinstance(results_identifiers, Iterable):
174
147
  raise TypeError(
175
- f"results_urls is expected to be an Iterable not {type(results_urls)}"
148
+ f"results_urls is expected to be an Iterable not {type(results_identifiers)}"
176
149
  )
177
- self.__results_urls = results_urls
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
178
154
 
179
155
  @property
180
- def results_urls(self) -> tuple:
181
- return self.__results_urls
156
+ def results_identifiers(self) -> tuple:
157
+ return self.__results_identifiers
182
158
 
183
159
  def __str__(self) -> str:
184
160
  res = super().__str__()
185
- res += f"\n - result urls: {self.results_urls}"
161
+ res += f"\n - result urls: {self.results_identifiers}"
186
162
  return res
187
163
 
188
164
 
@@ -396,13 +372,10 @@ class _NabuBaseReconstructor:
396
372
  slice_index=None,
397
373
  scan=self.scan,
398
374
  file_format=file_format,
399
- start_z=start_z,
400
- end_z=end_z,
401
- expects_single_slice=self.EXPECTS_SINGLE_SLICE,
402
375
  )
403
376
  return ResultsLocalRun(
404
377
  success=not nabu_std_err_has_error(errs),
405
- results_urls=recons_urls,
378
+ results_identifiers=recons_urls,
406
379
  std_out=outs,
407
380
  std_err=errs,
408
381
  config=config_to_dump, # config_slices,
@@ -525,22 +498,19 @@ class _NabuBaseReconstructor:
525
498
  if "output" in config:
526
499
  _file_name = self._get_file_basename_reconstruction(pag=pag, db=db, ctf=ctf)
527
500
  config["output"]["file_prefix"] = _file_name
528
- location = config["output"].get("location", None)
529
- if location not in ("", None):
530
- location = format_output_location(location, scan=self.scan)
531
- location_cfg_files = location
532
- else:
533
- # otherwise default location will be the data root level
534
- location = self.scan.path
535
- location_cfg_files = location
536
- # TODO: if is a single file - append prefix
537
- if config["output"].get("file_format") in (
538
- NabuOutputFileFormat.EDF.value,
539
- NabuOutputFileFormat.TIFF.value,
540
- NabuOutputFileFormat.JP2K.value,
541
- ): # if user specify the location
542
- location = "/".join([location, _file_name])
543
-
501
+ location, location_cfg_files = get_output_folder_from_scan(
502
+ mode=ProcessDataOutputDirMode.from_value(
503
+ config["output"].get(
504
+ "output_dir_mode", ProcessDataOutputDirMode.OTHER
505
+ )
506
+ ),
507
+ nabu_location=config["output"].get("location", None),
508
+ scan=self.scan,
509
+ file_basename=_file_name,
510
+ file_format=config["output"].get(
511
+ "file_format", NabuOutputFileFormat.HDF5
512
+ ),
513
+ )
544
514
  # add reconstruction path to the list. scan `reconstruction_paths` register all the existing path where
545
515
  # reconstruction are saved in order to be able to browse them all
546
516
  self.scan.add_reconstruction_path(location)
@@ -661,7 +631,7 @@ def dump_normalization_array_for_nabu(
661
631
  f"array is expected to be a numpy array or a scalar and not {type(array)}"
662
632
  )
663
633
  # save the value to a dedicated path in "nabu_tomwer_serving_hatch"
664
- if isinstance(scan, HDF5TomoScan):
634
+ if isinstance(scan, NXtomoScan):
665
635
  entry_path = scan.entry
666
636
  elif isinstance(scan, EDFTomoScan):
667
637
  entry_path = "entry"