tomwer 1.2.0a1__py3-none-any.whl → 1.2.0a3__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 (219) hide show
  1. orangecontrib/tomwer/tutorials/append_raw_darks_and_flats_frames_to_NXtomos.ows +44 -0
  2. orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows +55 -0
  3. orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth2.ows +48 -0
  4. orangecontrib/tomwer/tutorials/default_cor_search.ows +40 -0
  5. orangecontrib/tomwer/tutorials/hello_world_python_script.ows +50 -0
  6. orangecontrib/tomwer/tutorials/simple_slice_reconstruction_on_slurm.ows +50 -0
  7. orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +8 -8
  8. orangecontrib/tomwer/widgets/__init__.py +1 -1
  9. orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +0 -1
  10. orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +8 -6
  11. orangecontrib/tomwer/widgets/control/AdvancementOW.py +0 -1
  12. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +1 -6
  13. orangecontrib/tomwer/widgets/control/DataListOW.py +0 -1
  14. orangecontrib/tomwer/widgets/control/DataListenerOW.py +4 -4
  15. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +0 -1
  16. orangecontrib/tomwer/widgets/control/DataTransfertOW.py +7 -7
  17. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +0 -1
  18. orangecontrib/tomwer/widgets/control/DataWatcherOW.py +0 -3
  19. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +3 -2
  20. orangecontrib/tomwer/widgets/control/EmailOW.py +82 -0
  21. orangecontrib/tomwer/widgets/control/FilterOW.py +3 -3
  22. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +1 -1
  23. orangecontrib/tomwer/widgets/control/NotifierOW.py +0 -1
  24. orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py +93 -0
  25. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +29 -5
  26. orangecontrib/tomwer/widgets/control/TimerOW.py +1 -2
  27. orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +0 -1
  28. orangecontrib/tomwer/widgets/control/VolumeSelector.py +0 -1
  29. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +4 -10
  30. orangecontrib/tomwer/widgets/control/icons/email.png +0 -0
  31. orangecontrib/tomwer/widgets/control/icons/email.svg +58 -0
  32. orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png +0 -0
  33. orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg +199 -0
  34. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +0 -1
  35. orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py +0 -1
  36. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +1 -2
  37. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +1 -2
  38. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +0 -1
  39. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +0 -1
  40. orangecontrib/tomwer/widgets/other/PythonScriptOW.py +29 -1
  41. orangecontrib/tomwer/widgets/other/TomoObjsHub.py +28 -0
  42. orangecontrib/tomwer/widgets/other/icons/hub.png +0 -0
  43. orangecontrib/tomwer/widgets/other/icons/hub.svg +113 -0
  44. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +18 -12
  45. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +0 -2
  46. orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +21 -6
  47. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +29 -7
  48. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +18 -5
  49. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +40 -13
  50. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +37 -10
  51. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +2 -3
  52. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +5 -4
  53. orangecontrib/tomwer/widgets/stitching/StitcherOW.py +0 -1
  54. orangecontrib/tomwer/widgets/stitching/ZStitchingConfigOW.py +0 -1
  55. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +10 -4
  56. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  57. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +0 -1
  58. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +0 -1
  59. orangecontrib/tomwer/widgets/visualization/RadioStackOW.py +7 -5
  60. orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +1 -1
  61. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -3
  62. orangecontrib/tomwer/widgets/visualization/SliceStackOW.py +7 -5
  63. orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +4 -4
  64. tomwer/__main__.py +139 -5
  65. tomwer/app/axis.py +16 -5
  66. tomwer/app/canvas_launcher/config.py +1 -1
  67. tomwer/app/canvas_launcher/mainwindow.py +164 -6
  68. tomwer/app/darkref.py +10 -181
  69. tomwer/app/darkrefpatch.py +10 -131
  70. tomwer/app/diffframe.py +11 -0
  71. tomwer/app/imagekeyeditor.py +12 -19
  72. tomwer/app/intensitynormalization.py +1 -0
  73. tomwer/app/lamino.py +7 -2
  74. tomwer/app/patchrawdarkflat.py +131 -0
  75. tomwer/app/radiostack.py +10 -0
  76. tomwer/app/reducedarkflat.py +205 -0
  77. tomwer/app/saaxis.py +27 -8
  78. tomwer/app/sadeltabeta.py +29 -8
  79. tomwer/app/samplemoved.py +11 -0
  80. tomwer/app/scanviewer.py +12 -0
  81. tomwer/app/sinogramviewer.py +11 -0
  82. tomwer/app/slicestack.py +11 -0
  83. tomwer/app/zstitching.py +12 -0
  84. tomwer/core/futureobject.py +4 -2
  85. tomwer/core/process/conditions/filters.py +26 -4
  86. tomwer/core/process/control/datadiscovery.py +4 -0
  87. tomwer/core/process/control/datawatcher/datawatcher.py +5 -1
  88. tomwer/core/process/control/email.py +148 -0
  89. tomwer/core/process/control/nxtomoconcatenate.py +9 -2
  90. tomwer/core/process/control/nxtomomill.py +58 -16
  91. tomwer/core/process/control/scanselector.py +4 -0
  92. tomwer/core/process/control/scantransfer.py +52 -23
  93. tomwer/core/process/control/test/test_concatenate_nxtomos.py +1 -0
  94. tomwer/core/process/control/test/test_email.py +52 -0
  95. tomwer/core/process/control/test/test_h52nx_process.py +106 -0
  96. tomwer/core/process/control/test/test_volume_link.py +5 -4
  97. tomwer/core/process/control/timer.py +27 -6
  98. tomwer/core/process/control/tomoobjserie.py +4 -0
  99. tomwer/core/process/control/volumeselector.py +4 -0
  100. tomwer/core/process/control/volumesymlink.py +47 -8
  101. tomwer/core/process/edit/darkflatpatch.py +49 -8
  102. tomwer/core/process/edit/imagekeyeditor.py +63 -13
  103. tomwer/core/process/reconstruction/axis/__init__.py +1 -1
  104. tomwer/core/process/reconstruction/axis/axis.py +61 -41
  105. tomwer/core/process/reconstruction/axis/params.py +4 -6
  106. tomwer/core/process/reconstruction/darkref/darkrefs.py +53 -16
  107. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +12 -2
  108. tomwer/core/process/reconstruction/lamino/__init__.py +1 -1
  109. tomwer/core/process/reconstruction/lamino/tofu.py +22 -2
  110. tomwer/core/process/reconstruction/nabu/nabucommon.py +93 -14
  111. tomwer/core/process/reconstruction/nabu/nabuscores.py +70 -33
  112. tomwer/core/process/reconstruction/nabu/nabuslices.py +219 -41
  113. tomwer/core/process/reconstruction/nabu/nabuvolume.py +240 -108
  114. tomwer/core/process/reconstruction/nabu/utils.py +10 -36
  115. tomwer/core/process/reconstruction/normalization/normalization.py +10 -3
  116. tomwer/core/process/reconstruction/saaxis/__init__.py +1 -0
  117. tomwer/core/process/reconstruction/saaxis/saaxis.py +564 -376
  118. tomwer/core/process/reconstruction/sadeltabeta/__init__.py +1 -0
  119. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +481 -268
  120. tomwer/core/process/reconstruction/scores/params.py +21 -8
  121. tomwer/core/process/reconstruction/test/test_darkref_copy.py +2 -0
  122. tomwer/core/process/reconstruction/test/test_saaxis.py +21 -8
  123. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +8 -5
  124. tomwer/core/process/script/python.py +7 -2
  125. tomwer/core/process/stitching/nabustitcher.py +10 -3
  126. tomwer/core/process/task.py +2 -9
  127. tomwer/core/process/test/test_axis.py +25 -15
  128. tomwer/core/process/test/test_conditions.py +6 -6
  129. tomwer/core/process/test/test_dark_and_flat.py +20 -15
  130. tomwer/core/process/test/test_data_transfer.py +8 -8
  131. tomwer/core/process/test/test_data_watcher.py +1 -1
  132. tomwer/core/process/test/test_lamino.py +6 -6
  133. tomwer/core/process/test/test_nabu.py +13 -8
  134. tomwer/core/process/test/test_normalization.py +1 -0
  135. tomwer/core/process/test/test_timer.py +6 -6
  136. tomwer/core/process/visualization/dataviewer.py +4 -0
  137. tomwer/core/process/visualization/diffviewer.py +4 -0
  138. tomwer/core/process/visualization/imagestackviewer.py +4 -0
  139. tomwer/core/process/visualization/radiostack.py +4 -0
  140. tomwer/core/process/visualization/samplemoved.py +4 -0
  141. tomwer/core/process/visualization/sinogramviewer.py +4 -0
  142. tomwer/core/process/visualization/slicestack.py +4 -0
  143. tomwer/core/process/visualization/volumeviewer.py +4 -0
  144. tomwer/core/scan/hdf5scan.py +4 -4
  145. tomwer/core/scan/scanbase.py +5 -1
  146. tomwer/core/scan/test/test_process_registration.py +9 -9
  147. tomwer/core/settings.py +59 -1
  148. tomwer/core/test/test_lamino.py +2 -1
  149. tomwer/core/utils/__init__.py +16 -0
  150. tomwer/core/utils/locker.py +0 -1
  151. tomwer/core/utils/resource.py +6 -11
  152. tomwer/core/utils/scanutils.py +2 -0
  153. tomwer/gui/cluster/slurm.py +91 -7
  154. tomwer/gui/cluster/supervisor.py +16 -11
  155. tomwer/gui/cluster/test/test_cluster.py +16 -1
  156. tomwer/gui/conditions/filter.py +3 -3
  157. tomwer/gui/control/datalist.py +24 -11
  158. tomwer/gui/control/email.py +183 -0
  159. tomwer/gui/control/reducedarkflatselector.py +545 -0
  160. tomwer/gui/control/singletomoobj.py +23 -1
  161. tomwer/gui/control/test/test_email.py +35 -0
  162. tomwer/gui/control/test/test_reducedarkflat_selector.py +280 -0
  163. tomwer/gui/reconstruction/axis/CompareImages.py +1 -1
  164. tomwer/gui/reconstruction/axis/axis.py +10 -6
  165. tomwer/gui/reconstruction/axis/radioaxis.py +14 -6
  166. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +2 -0
  167. tomwer/gui/reconstruction/darkref/darkrefwidget.py +4 -4
  168. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +3 -1
  169. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +34 -33
  170. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +1 -1
  171. tomwer/gui/reconstruction/normalization/intensity.py +5 -5
  172. tomwer/gui/reconstruction/saaxis/corrangeselector.py +1 -0
  173. tomwer/gui/reconstruction/saaxis/saaxis.py +6 -6
  174. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +6 -6
  175. tomwer/gui/reconstruction/scores/scoreplot.py +6 -4
  176. tomwer/gui/samplemoved/__init__.py +2 -2
  177. tomwer/gui/stackplot.py +18 -7
  178. tomwer/gui/stacks.py +2 -2
  179. tomwer/gui/stitching/stitchandbackground.py +2 -2
  180. tomwer/gui/stitching/stitching.py +1 -1
  181. tomwer/gui/stitching/stitching_raw.py +1 -1
  182. tomwer/gui/utils/__init__.py +1 -85
  183. tomwer/gui/utils/illustrations.py +1 -1
  184. tomwer/gui/utils/inputwidget.py +41 -36
  185. tomwer/gui/utils/slider.py +2 -2
  186. tomwer/gui/utils/utils.py +93 -0
  187. tomwer/gui/visualization/dataviewer.py +8 -5
  188. tomwer/gui/visualization/diffviewer/diffviewer.py +4 -4
  189. tomwer/gui/visualization/reconstructionparameters.py +26 -6
  190. tomwer/gui/visualization/sinogramviewer.py +7 -1
  191. tomwer/gui/visualization/test/test_reconstruction_parameters.py +2 -4
  192. tomwer/gui/visualization/volumeviewer.py +2 -0
  193. tomwer/resources/__init__.py +55 -43
  194. tomwer/resources/gui/icons/compose.png +0 -0
  195. tomwer/resources/gui/icons/compose.svg +75 -0
  196. tomwer/synctools/datatransfert.py +3 -1
  197. tomwer/synctools/stacks/edit/darkflatpatch.py +39 -34
  198. tomwer/synctools/stacks/edit/imagekeyeditor.py +8 -27
  199. tomwer/synctools/stacks/processingstack.py +45 -9
  200. tomwer/synctools/stacks/reconstruction/axis.py +6 -5
  201. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +1 -0
  202. tomwer/synctools/stacks/reconstruction/lamino.py +3 -3
  203. tomwer/synctools/stacks/reconstruction/nabu.py +49 -140
  204. tomwer/synctools/stacks/reconstruction/normalization.py +1 -0
  205. tomwer/synctools/stacks/reconstruction/saaxis.py +19 -33
  206. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +16 -32
  207. tomwer/synctools/test/test_darkRefs.py +19 -10
  208. tomwer/synctools/test/test_foldertransfer.py +7 -7
  209. tomwer/third_party/nabu/preproc/phase.py +6 -8
  210. tomwer/third_party/nabu/utils.py +2 -3
  211. tomwer/version.py +1 -1
  212. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/METADATA +15 -54
  213. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/RECORD +219 -192
  214. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/WHEEL +1 -1
  215. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/entry_points.txt +3 -3
  216. /tomwer-1.2.0a1-py3.9-nspkg.pth → /tomwer-1.2.0a3-py3.11-nspkg.pth +0 -0
  217. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/LICENSE +0 -0
  218. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/namespace_packages.txt +0 -0
  219. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/top_level.txt +0 -0
@@ -37,7 +37,7 @@ from queue import Queue
37
37
  from processview.core.superviseprocess import SuperviseProcess
38
38
  from silx.gui import qt
39
39
 
40
- from tomwer.core.process.reconstruction.lamino.tofu import LaminoReconstruction
40
+ from tomwer.core.process.reconstruction.lamino.tofu import LaminoReconstructionTask
41
41
  from tomwer.core.scan.scanbase import TomwerScanBase
42
42
  from tomwer.core.utils.Singleton import singleton
43
43
 
@@ -92,7 +92,7 @@ class LaminoReconstructionStack(qt.QObject, Queue):
92
92
  reconstruction
93
93
  :param callback: function to call after the reconstruction execution
94
94
  """
95
- assert isinstance(recons_obj, LaminoReconstruction)
95
+ assert isinstance(recons_obj, LaminoReconstructionTask)
96
96
  Queue.put(
97
97
  self,
98
98
  (
@@ -199,7 +199,7 @@ class _LaminoReconsThread(qt.QThread, SuperviseProcess):
199
199
  def init(
200
200
  self, recons_obj, recons_params, additional_opts, remove_existing, scan_id
201
201
  ):
202
- assert isinstance(recons_obj, LaminoReconstruction)
202
+ assert isinstance(recons_obj, LaminoReconstructionTask)
203
203
  self.recons_obj = recons_obj
204
204
  self.recons_params = recons_params
205
205
  self.additional_opts = additional_opts
@@ -24,22 +24,21 @@
24
24
 
25
25
  __authors__ = ["H.Payno"]
26
26
  __license__ = "MIT"
27
- __date__ = "28/08/2020"
27
+ __date__ = "17/07/2023"
28
28
 
29
29
 
30
- import gc
31
30
  import logging
32
31
 
33
32
  from processview.core.manager import DatasetState, ProcessManager
34
33
  from processview.core.superviseprocess import SuperviseProcess
35
34
  from silx.gui import qt
35
+ from silx.gui.utils import blockSignals
36
36
 
37
- from tomwer.core.process.reconstruction.nabu import nabuslices, nabuvolume
38
- from tomwer.core.scan.edfscan import EDFTomoScan
39
37
  from tomwer.core.scan.scanbase import TomwerScanBase
40
38
  from tomwer.core.settings import get_lbsram_path, isOnLbsram
41
39
  from tomwer.core.utils import isLowOnMemory
42
- from tomwer.io.utils import format_stderr_stdout
40
+ from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSlicesTask
41
+ from tomwer.core.process.reconstruction.nabu.nabuvolume import NabuVolumeTask
43
42
 
44
43
  from ..processingstack import FIFO, ProcessingThread
45
44
 
@@ -93,6 +92,15 @@ class NabuSliceProcessStack(FIFO, qt.QObject):
93
92
  def setDryRun(self, dry_run):
94
93
  self._dry_run = dry_run
95
94
 
95
+ def cancel(self):
96
+ if self._computationThread.isRunning():
97
+ with blockSignals(self._computationThread):
98
+ self._computationThread.cancel()
99
+ # stop stack
100
+ super().stop()
101
+ # emit next
102
+ self.sigComputationEnded.emit(None, None)
103
+
96
104
 
97
105
  class NabuVolumeProcessStack(NabuSliceProcessStack):
98
106
  """Implementation of the `.AxisProcess` but having a stack for treating
@@ -117,6 +125,11 @@ class _SliceProcessingThread(ProcessingThread, SuperviseProcess):
117
125
  self._future_tomo_obj = None
118
126
  self._configuration = None
119
127
  self._dry_run = False
128
+ self._current_processing = None
129
+ # processing currently runned. As we want to be able to cancel processing we need to keep a pointer on the
130
+ # 'activate' nabu processing to stop process if requested
131
+ self._task = None
132
+ # ewoks task for reconstruction
120
133
 
121
134
  @property
122
135
  def future_tomo_obj(self):
@@ -128,8 +141,11 @@ class _SliceProcessingThread(ProcessingThread, SuperviseProcess):
128
141
  def init(self, data, configuration):
129
142
  self._scan = data
130
143
  self._configuration = configuration
144
+ self._task = None
131
145
 
132
146
  def run(self):
147
+ # note: now rnu does a processing close to the 'run_slices_reconstruction' except that we keep a trace on the
148
+ # current nabu subprocess runned. The goal is to be able to cancel / stop processing when asked
133
149
  self.sigComputationStarted.emit()
134
150
  mess = f"Start nabu slice(s) reconstruction of {self._scan}"
135
151
  _logger.processStarted(mess)
@@ -140,76 +156,22 @@ class _SliceProcessingThread(ProcessingThread, SuperviseProcess):
140
156
  details=mess,
141
157
  )
142
158
 
143
- # # loop is required for distributed since version 2021
144
- try:
145
- (
146
- succeed,
147
- stdouts,
148
- stderrs,
149
- configs,
150
- self._future_tomo_obj,
151
- ) = nabuslices.run_slices_reconstruction(
152
- config=self._configuration,
153
- scan=self._scan,
154
- dry_run=self._dry_run,
155
- process_id=self.process_id,
156
- )
157
- except Exception as e:
158
- _logger.processFailed(
159
- f"Fail to compute slices for {str(self._scan)}. Reason is {e}."
160
- )
161
- ProcessManager().notify_dataset_state(
162
- dataset=self._scan,
163
- process=self,
164
- state=DatasetState.FAILED,
165
- details=mess,
166
- )
167
- self._future_tomo_obj = None
168
- else:
169
- index = self._scan.pop_process_index()
170
- if isinstance(self._scan, EDFTomoScan):
171
- entry = None
172
- else:
173
- entry = (
174
- self._scan.entry
175
- ) # hotfix / FIXME: otherwise can fail to open the file to
176
- # register the process. Might be fix since using HDF5File
177
- gc.collect()
178
- try:
179
- nabuslices.NabuSlices._register_process(
180
- process_file=self._scan.process_file,
181
- entry=entry,
182
- configuration=self._configuration,
183
- results={},
184
- process=nabuslices.NabuSlices,
185
- process_index=index,
186
- overwrite=True,
187
- )
188
- except Exception as e:
189
- _logger.warning(f"Fail to register NabuSlices process. Reason is {e}")
190
-
191
- # TODO: check output files with the tomoscan validator ?
192
- if not succeed:
193
- mess = f"Slices computation for {self._scan} failed."
194
- state = DatasetState.FAILED
195
- _logger.processFailed(mess)
196
- else:
197
- state = DatasetState.SUCCEED
198
- mess = f"Slices computed for {self._scan}."
199
- _logger.processSucceed(mess)
200
- elmts = [
201
- format_stderr_stdout(stderr=stderr, stdout=stdout)
202
- for stderr, stdout, config in zip(stderrs, stdouts, configs)
203
- ]
204
- elmts.insert(0, mess)
205
- details = "\n".join(elmts)
159
+ self._task = NabuSlicesTask(
160
+ process_id=self.process_id,
161
+ inputs={
162
+ "data": self._scan,
163
+ "nabu_params": self._configuration,
164
+ "dry_run": self._dry_run,
165
+ "serialize_output_data": False,
166
+ },
167
+ )
168
+ self._task.run()
169
+ self._future_tomo_obj = self._task.outputs.future_tomo_obj
206
170
 
207
- ProcessManager().notify_dataset_state(
208
- dataset=self._scan,
209
- process=self,
210
- state=state,
211
- details=details,
212
- )
171
+ def cancel(self):
172
+ if self._task is not None:
173
+ self._task.cancel()
174
+ self.quit()
213
175
 
214
176
 
215
177
  class _VolumeProcessingThread(_SliceProcessingThread):
@@ -228,69 +190,16 @@ class _VolumeProcessingThread(_SliceProcessingThread):
228
190
  details=mess,
229
191
  )
230
192
 
231
- # loop is required for distributed since version 2021
232
- try:
233
- (
234
- succeed,
235
- stdouts,
236
- stderrs,
237
- configs,
238
- self._future_tomo_obj,
239
- ) = nabuvolume.run_volume_reconstruction(
240
- config=self._configuration,
241
- scan=self._scan,
242
- dry_run=self._dry_run,
243
- process_id=self.process_id,
244
- )
245
- except Exception as e:
246
- self._future_tomo_obj = None
247
- mess = f"Fail to compute volume for {e}. Reason is {e}"
248
- _logger.processFailed(mess)
249
- ProcessManager().notify_dataset_state(
250
- dataset=self._scan,
251
- process=self,
252
- state=DatasetState.FAILED,
253
- details=mess,
254
- )
255
- else:
256
- index = self._scan.pop_process_index()
257
- if isinstance(self._scan, EDFTomoScan):
258
- entry = None
259
- else:
260
- entry = self._scan.entry
261
- gc.collect()
262
- try:
263
- nabuvolume.NabuVolume._register_process(
264
- process_file=self._scan.process_file,
265
- entry=entry,
266
- configuration=self._configuration,
267
- results={},
268
- process=nabuvolume.NabuVolume,
269
- process_index=index,
270
- overwrite=True,
271
- )
272
- except Exception as e:
273
- _logger.warning(f"Fail to register NabuVolume process. Reason is {e}")
274
- elmts = [
275
- format_stderr_stdout(stderr=stderr, stdout=stdout, config=config)
276
- for stderr, stdout, config in zip(stderrs, stdouts, configs)
277
- ]
278
-
279
- if not succeed:
280
- mess = f"Volume computed for {self._scan} failed."
281
- _logger.processFailed(mess)
282
- state = DatasetState.FAILED
283
- else:
284
- mess = f"Volume computed for {self._scan}."
285
- _logger.processSucceed(mess)
286
- state = DatasetState.SUCCEED
287
-
288
- elmts.insert(0, mess)
289
- details = "\n".join(elmts)
290
-
291
- ProcessManager().notify_dataset_state(
292
- dataset=self._scan,
293
- process=self,
294
- state=state,
295
- details=details,
296
- )
193
+ self._task = NabuVolumeTask(
194
+ process_id=self.process_id,
195
+ inputs={
196
+ "data": self._scan,
197
+ "nabu_params": self._scan.nabu_recons_params,
198
+ "nabu_extra_params": self._configuration,
199
+ "process_id": self.process_id,
200
+ "dry_run": self._dry_run,
201
+ "serialize_output_data": False, # avoid spending time on serialization / deserialization
202
+ },
203
+ )
204
+ self._task.run()
205
+ self._future_tomo_obj = self._task.outputs.future_tomo_obj
@@ -115,6 +115,7 @@ class _ProcessingThread(ProcessingThread, SuperviseProcess):
115
115
  inputs={
116
116
  "data": self._scan,
117
117
  "configuration": self._i_norm_params,
118
+ "serialize_output_data": False,
118
119
  },
119
120
  )
120
121
  try:
@@ -34,11 +34,10 @@ from processview.core.manager import DatasetState, ProcessManager
34
34
  from processview.core.superviseprocess import SuperviseProcess
35
35
  from silx.gui import qt
36
36
 
37
- from tomwer.core.process.reconstruction.saaxis import SAAxisProcess
37
+ from tomwer.core.process.reconstruction.saaxis import SAAxisTask
38
38
  from tomwer.core.scan.scanbase import TomwerScanBase
39
39
  from tomwer.core.settings import get_lbsram_path, isOnLbsram
40
40
  from tomwer.core.utils import isLowOnMemory
41
- from tomwer.io.utils import format_stderr_stdout
42
41
  from tomwer.synctools.axis import QAxisRP
43
42
  from tomwer.synctools.saaxis import QSAAxisParams
44
43
 
@@ -110,7 +109,6 @@ class SAAxisProcessStack(FIFO, qt.QObject):
110
109
  )
111
110
 
112
111
  def _end_threaded_computation(self, callback=None):
113
- assert self._data_currently_computed is not None
114
112
  self._computationThread.finished.disconnect()
115
113
  if callback:
116
114
  callback()
@@ -138,8 +136,11 @@ class _ProcessingThread(ProcessingThread, SuperviseProcess):
138
136
  self._patch_process_fct = None
139
137
  """function pointer to know which function to call for the axis
140
138
  calculation"""
141
- self.__patch = {}
142
- """Used to patch some calculation method (for test purpose)"""
139
+ self._current_processing = None
140
+ # processing currently runned. As we want to be able to cancel processing we need to keep a pointer on the
141
+ # 'activate' nabu processing to stop process if requested
142
+ self._task = None
143
+ # ewoks task for reconstruction
143
144
 
144
145
  def set_dry_run(self, dry_run):
145
146
  self._dry_run = dry_run
@@ -147,7 +148,7 @@ class _ProcessingThread(ProcessingThread, SuperviseProcess):
147
148
  def patch_processing(self, process_fct):
148
149
  self._patch_process_fct = process_fct
149
150
 
150
- def init(self, data, saaxis_params):
151
+ def init(self, data, saaxis_params: dict):
151
152
  self._scan = data
152
153
  self._saaxis_params = saaxis_params
153
154
 
@@ -158,39 +159,24 @@ class _ProcessingThread(ProcessingThread, SuperviseProcess):
158
159
  for cor in self._saaxis_params.cors:
159
160
  scores[cor] = self._patch_process_fct(cor)
160
161
  self._scan.saaxis_params.scores = scores
161
- SAAxisProcess.autofocus(scan=self._scan)
162
+ SAAxisTask.autofocus(scan=self._scan)
162
163
  self.center_of_rotation = self._scan.saaxis_params.autofocus
163
164
  else:
164
- saaxis = SAAxisProcess(
165
+ self._task = SAAxisTask(
165
166
  process_id=self.process_id,
166
167
  inputs={
167
168
  "dump_process": False,
168
169
  "data": self._scan,
169
170
  "dry_run": self._dry_run,
171
+ "sa_axis_params": self._saaxis_params.to_dict(),
172
+ "serialize_output_data": False,
170
173
  },
171
174
  )
172
- saaxis.set_configuration(self._saaxis_params)
173
- # loop is required for distributed since version 2021
174
- try:
175
- saaxis.run()
176
- except Exception as e:
177
- _logger.error(str(e))
178
- mess = f"SAaxis computation for {str(self._scan)} failed."
179
- state = DatasetState.FAILED
180
- else:
181
- mess = f"SAaxis computation for {str(self._scan)} succeed."
182
- state = DatasetState.WAIT_USER_VALIDATION
183
- self.center_of_rotation = self._scan.saaxis_params.autofocus
184
-
185
- nabu_logs = []
186
- for std_err, std_out in zip(saaxis.std_errs, saaxis.std_outs):
187
- nabu_logs.append(format_stderr_stdout(stdout=std_out, stderr=std_err))
188
- self._nabu_log = nabu_logs
189
- nabu_logs.insert(0, mess)
190
- details = "\n".join(nabu_logs)
191
- ProcessManager().notify_dataset_state(
192
- dataset=self._scan,
193
- process=self,
194
- state=state,
195
- details=details,
196
- )
175
+
176
+ self._task.run()
177
+ self.center_of_rotation = self._task.outputs.best_cor
178
+
179
+ def cancel(self):
180
+ if self._task is not None:
181
+ self._task.cancel()
182
+ self.quit()
@@ -35,12 +35,11 @@ from processview.core.superviseprocess import SuperviseProcess
35
35
  from silx.gui import qt
36
36
 
37
37
  from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import (
38
- SADeltaBetaProcess,
38
+ SADeltaBetaTask,
39
39
  )
40
40
  from tomwer.core.scan.scanbase import TomwerScanBase
41
41
  from tomwer.core.settings import get_lbsram_path, isOnLbsram
42
42
  from tomwer.core.utils import isLowOnMemory
43
- from tomwer.io.utils import format_stderr_stdout
44
43
  from tomwer.synctools.axis import QAxisRP
45
44
  from tomwer.synctools.sadeltabeta import QSADeltaBetaParams
46
45
 
@@ -134,15 +133,15 @@ class _ProcessingThread(ProcessingThread, SuperviseProcess):
134
133
  ProcessingThread.__init__(self, process_id=process_id)
135
134
  except TypeError:
136
135
  ProcessingThread.__init__(self)
137
- self.center_of_rotation = None
136
+ self.db_value = None
138
137
  self._dry_run = False
139
138
  self._scan = None
140
139
  self._sa_delta_beta_params = None
141
140
  self._patch_process_fct = None
142
141
  """function pointer to know which function to call for the axis
143
142
  calculation"""
144
- self.__patch = {}
145
- """Used to patch some calculation method (for test purpose)"""
143
+ self._task = None
144
+ # ewoks task for reconstruction
146
145
 
147
146
  def set_dry_run(self, dry_run):
148
147
  self._dry_run = dry_run
@@ -161,39 +160,24 @@ class _ProcessingThread(ProcessingThread, SuperviseProcess):
161
160
  for db in self._sa_delta_beta_params.delta_beta_values:
162
161
  scores[db] = self._patch_process_fct(db)
163
162
  self._scan.sa_delta_beta_params.scores = scores
164
- SADeltaBetaProcess.autofocus(scan=self._scan)
163
+ SADeltaBetaTask.autofocus(scan=self._scan)
165
164
  self.db_value = self._scan.sa_delta_beta_params.autofocus
166
165
  else:
167
- sa_delta_beta = SADeltaBetaProcess(
166
+ self._task = SADeltaBetaTask(
168
167
  inputs={
169
168
  "dump_process": False,
170
169
  "data": self._scan,
171
170
  "dry_run": self._dry_run,
172
- "sa_delta_beta_params": self._sa_delta_beta_params,
171
+ "sa_delta_beta_params": self._sa_delta_beta_params.to_dict(),
172
+ "serialize_output_data": False,
173
173
  },
174
174
  process_id=self.process_id,
175
175
  )
176
- # loop is required for distributed since version 2021
177
- try:
178
- sa_delta_beta.run()
179
- except Exception as e:
180
- _logger.error(str(e))
181
- mess = f"SADeltaBeta computation for {self._scan} failed."
182
- state = DatasetState.FAILED
183
- else:
184
- mess = f"SADeltaBeta computation for {self._scan} succeed."
185
- state = DatasetState.WAIT_USER_VALIDATION
186
- self.db_value = self._scan.sa_delta_beta_params.autofocus
187
-
188
- nabu_logs = []
189
- for std_err, std_out in zip(sa_delta_beta.std_errs, sa_delta_beta.std_outs):
190
- nabu_logs.append(format_stderr_stdout(stdout=std_out, stderr=std_err))
191
- self._nabu_log = nabu_logs
192
- nabu_logs.insert(0, mess)
193
- details = "\n".join(nabu_logs)
194
- ProcessManager().notify_dataset_state(
195
- dataset=self._scan,
196
- process=self,
197
- state=state,
198
- details=details,
199
- )
176
+
177
+ self._task.run()
178
+ self.db_value = self._task.outputs.best_db
179
+
180
+ def cancel(self):
181
+ if self._task is not None:
182
+ self._task.cancel()
183
+ self.quit()
@@ -36,7 +36,7 @@ import fabio
36
36
  import numpy
37
37
  from silx.gui.utils.testutils import TestCaseQt
38
38
 
39
- from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefs
39
+ from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask
40
40
  from tomwer.core.process.reconstruction.darkref.params import DKRFRP, ReduceMethod
41
41
  from tomwer.core.scan.scanfactory import ScanFactory
42
42
  from tomwer.core.utils.scanutils import MockEDF
@@ -78,12 +78,13 @@ class TestDarkRefsBehavior(TestCaseQt):
78
78
  self.recons_params.flat_calc_method = ReduceMethod.NONE
79
79
  self.recons_params.dark_calc_method = ReduceMethod.MEDIAN
80
80
 
81
- dar_ref_process = DarkRefs(
81
+ dar_ref_process = DarkRefsTask(
82
82
  inputs={
83
83
  "dark_ref_params": self.recons_params,
84
84
  "force_sync": True,
85
85
  "darkhst_prefix": "darkHST",
86
86
  "data": self.dataset_folder,
87
+ "serialize_output_data": False,
87
88
  }
88
89
  )
89
90
  dar_ref_process.run()
@@ -113,12 +114,13 @@ class TestDarkRefsBehavior(TestCaseQt):
113
114
  self.recons_params.flat_calc_method = ReduceMethod.MEDIAN
114
115
  self.recons_params.dark_calc_method = ReduceMethod.NONE
115
116
 
116
- dar_ref_process = DarkRefs(
117
+ dar_ref_process = DarkRefsTask(
117
118
  inputs={
118
119
  "dark_ref_params": self.recons_params,
119
120
  "force_sync": True,
120
121
  "darkhst_prefix": "darkHST",
121
122
  "data": self.dataset_folder,
123
+ "serialize_output_data": False,
122
124
  }
123
125
  )
124
126
 
@@ -162,10 +164,11 @@ class TestRefCalculationOneSerie(TestCaseQt):
162
164
  )
163
165
 
164
166
  self.recons_params = DKRFRP()
165
- self.darkRef = DarkRefs(
167
+ self.darkRef = DarkRefsTask(
166
168
  inputs={
167
169
  "dark_ref_params": self.recons_params,
168
170
  "data": self.tmp_dir,
171
+ "serialize_output_data": False,
169
172
  }
170
173
  )
171
174
  self.darkRef.setForceSync(True)
@@ -220,11 +223,12 @@ class TestRefCalculationThreeSerie(TestCaseQt):
220
223
  file_desc.write(os.path.join(self.tmp_dir, refFile))
221
224
 
222
225
  self.recons_params = DKRFRP()
223
- self.darkRef = DarkRefs(
226
+ self.darkRef = DarkRefsTask(
224
227
  inputs={
225
228
  "dark_ref_params": self.recons_params,
226
229
  "data": self.tmp_dir,
227
230
  "force_sync": True,
231
+ "serialize_output_data": False,
228
232
  }
229
233
  )
230
234
  self.recons_params.flat_pattern = "ref*.*[0-9]{3,4}_[0-9]{3,4}"
@@ -275,11 +279,12 @@ class TestDarkCalculationOneFrame(TestCaseQt):
275
279
  file_desc.write(os.path.join(self.tmp_dir, "darkend0000.edf"))
276
280
  assert len(os.listdir(self.tmp_dir)) is (1 + n_scan + n_info + n_xml)
277
281
  self.recons_params = DKRFRP()
278
- self.darkRef = DarkRefs(
282
+ self.darkRef = DarkRefsTask(
279
283
  inputs={
280
284
  "dark_ref_params": self.recons_params,
281
285
  "force_sync": True,
282
286
  "data": self.tmp_dir,
287
+ "serialize_output_data": False,
283
288
  }
284
289
  )
285
290
 
@@ -330,11 +335,12 @@ class TestDarkCalculation(TestCaseQt):
330
335
  file_desc.write(os.path.join(self.tmp_dir, "darkend0000.edf"))
331
336
  assert len(os.listdir(self.tmp_dir)) is (1 + n_scan + n_xml + n_info)
332
337
  self.recons_params = DKRFRP()
333
- self.darkRef = DarkRefs(
338
+ self.darkRef = DarkRefsTask(
334
339
  inputs={
335
340
  "data": self.tmp_dir,
336
341
  "dark_ref_params": self.recons_params,
337
342
  "force_sync": True,
343
+ "serialize_output_data": False,
338
344
  }
339
345
  )
340
346
 
@@ -399,10 +405,11 @@ class TestDarkAccumulation(TestCaseQt):
399
405
  def testComputation(self):
400
406
  """Test data bone8_1_ from id16b containing dark.edf of reference
401
407
  and darkend"""
402
- dark_ref_process = DarkRefs(
408
+ dark_ref_process = DarkRefsTask(
403
409
  inputs={
404
410
  "data": os.path.join(self.outputdir, self.dataset),
405
411
  "force_sync": True,
412
+ "serialize_output_data": False,
406
413
  }
407
414
  )
408
415
 
@@ -440,12 +447,13 @@ class TestPCOTomo(TestCaseQt):
440
447
  self.dataset = "pcotomo_2x2scan_refdarkbeg_end_conti"
441
448
  self.copyDataset(self.dataset)
442
449
  self.recons_params.dark_calc_method = ReduceMethod.MEDIAN
443
- dar_ref_process = DarkRefs(
450
+ dar_ref_process = DarkRefsTask(
444
451
  inputs={
445
452
  "dark_ref_params": self.recons_params,
446
453
  "data": self.scan,
447
454
  "darkhst_prefix": "darkHST",
448
455
  "force_sync": True,
456
+ "serialize_output_data": False,
449
457
  }
450
458
  )
451
459
  dar_ref_process.run()
@@ -454,12 +462,13 @@ class TestPCOTomo(TestCaseQt):
454
462
  self.dataset = "pcotomo_2x2scan_refdarkbeg_end_conti"
455
463
  self.copyDataset(self.dataset)
456
464
  self.recons_params.flat_calc_method = ReduceMethod.MEDIAN
457
- dar_ref_process = DarkRefs(
465
+ dar_ref_process = DarkRefsTask(
458
466
  inputs={
459
467
  "dark_ref_params": self.recons_params,
460
468
  "data": self.scan,
461
469
  "darkhst_prefix": "darkHST",
462
470
  "force_sync": True,
471
+ "serialize_output_data": False,
463
472
  }
464
473
  )
465
474
  dar_ref_process.run()
@@ -131,7 +131,7 @@ class TestEDFDataTransfert(TestCaseQt):
131
131
  "dest_dir": self.targettedir,
132
132
  "noRsync": True,
133
133
  "move": True,
134
- "force": False,
134
+ "overwrite": False,
135
135
  }
136
136
  )
137
137
  folder_trans_process.run()
@@ -145,7 +145,7 @@ class TestEDFDataTransfert(TestCaseQt):
145
145
  "dest_dir": self.targettedir,
146
146
  "noRsync": True,
147
147
  "move": True,
148
- "force": False,
148
+ "overwrite": False,
149
149
  }
150
150
  )
151
151
  with self.assertRaises(shutil.Error):
@@ -159,7 +159,7 @@ class TestEDFDataTransfert(TestCaseQt):
159
159
  "dest_dir": self.targettedir,
160
160
  "noRsync": True,
161
161
  "move": True,
162
- "force": True,
162
+ "overwrite": True,
163
163
  }
164
164
  )
165
165
  folder_trans_process.run()
@@ -181,7 +181,7 @@ class TestEDFDataTransfert(TestCaseQt):
181
181
  "dest_dir": self.targettedir,
182
182
  "noRsync": True,
183
183
  "move": False,
184
- "force": False,
184
+ "overwrite": False,
185
185
  }
186
186
  )
187
187
  folder_trans_process.run()
@@ -198,7 +198,7 @@ class TestEDFDataTransfert(TestCaseQt):
198
198
  "dest_dir": self.targettedir,
199
199
  "noRsync": True,
200
200
  "move": False,
201
- "force": False,
201
+ "overwrite": False,
202
202
  }
203
203
  )
204
204
 
@@ -213,7 +213,7 @@ class TestEDFDataTransfert(TestCaseQt):
213
213
  "dest_dir": self.targettedir,
214
214
  "noRsync": True,
215
215
  "move": False,
216
- "force": True,
216
+ "overwrite": True,
217
217
  }
218
218
  )
219
219
  folder_trans_process.run()
@@ -374,7 +374,7 @@ class TestPreTransfert(unittest.TestCase):
374
374
  "dest_dir": self.outputfolder,
375
375
  "data": self.scan,
376
376
  "move": False,
377
- "force": True,
377
+ "overwrite": True,
378
378
  "noRsync": True,
379
379
  }
380
380
  )