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
@@ -87,8 +87,6 @@ class CastNabuVolumeOW(WidgetLongProcessing, SuperviseOW):
87
87
 
88
88
  want_main_area = True
89
89
  resizing_enabled = True
90
- compress_signal = False
91
- allows_cycle = True
92
90
 
93
91
  _ewoks_default_inputs = Setting({"data": None, "cast_volume_params": {}})
94
92
 
@@ -70,7 +70,6 @@ class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing):
70
70
 
71
71
  want_main_area = True
72
72
  resizing_enabled = True
73
- compress_signal = False
74
73
 
75
74
  _ewoks_default_inputs = Setting({"data": None, "dark_ref_params": None})
76
75
 
@@ -82,14 +81,23 @@ class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing):
82
81
  )
83
82
 
84
83
  class Inputs:
85
- data = Input(name="data", type=TomwerScanBase, doc="one scan to be process")
84
+ data = Input(
85
+ name="data",
86
+ type=TomwerScanBase,
87
+ doc="one scan to be process",
88
+ multiple=True,
89
+ )
86
90
  reduced_darks = Input(
87
- name="reduced dark(s)", type=dict, doc="dict containing reduced dark(s)"
91
+ name="reduced dark(s)",
92
+ type=dict,
93
+ doc="dict containing reduced dark(s)",
94
+ multiple=False,
88
95
  )
89
96
  reduced_flats = Input(
90
97
  name="reduced flat(s)",
91
98
  type=dict,
92
99
  doc="dict of containing reduced flat(s)",
100
+ multiple=False,
93
101
  )
94
102
 
95
103
  class Outputs:
@@ -175,7 +183,7 @@ class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing):
175
183
  return super().__new__(cls, *args, **kwargs)
176
184
 
177
185
  @Inputs.data
178
- def process(self, scanID):
186
+ def process(self, scanID, *args, **kwargs):
179
187
  if scanID is None:
180
188
  return
181
189
  assert isinstance(scanID, TomwerScanBase)
@@ -185,6 +193,7 @@ class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing):
185
193
  configuration = self.widget.recons_params.to_dict()
186
194
  configuration["process_only_copy"] = False # we never only do copy from the gui
187
195
  configuration["process_only_dkrf"] = not self.widget.isCopyActive()
196
+ configuration["mode_auto"] = self.widget.isOnModeAuto()
188
197
 
189
198
  self._processing_stack.add(copy.copy(scanID), configuration=configuration)
190
199
 
@@ -192,12 +201,14 @@ class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing):
192
201
  def received_reduced_darks(self, reduced_darks: dict):
193
202
  # we consider if the darks are provided then the user want to use those and don't copy them manually
194
203
  self.setModeAuto(False)
204
+ reduced_darks.pop("reduce_frames_name", None)
195
205
  self.setReducedDarks(reduced_darks)
196
206
 
197
207
  @Inputs.reduced_flats
198
208
  def received_reduced_flats(self, reduced_flats: dict):
199
209
  # we consider if the darks are provided then the user want to use those and don't copy them manually
200
210
  self.setModeAuto(False)
211
+ reduced_flats.pop("reduce_frames_name", None)
201
212
  self.setReducedFlats(reduced_flats)
202
213
 
203
214
  @docstring(SuperviseOW)
@@ -235,16 +246,20 @@ class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing):
235
246
  self.sigScanReady.emit(scan)
236
247
  if scan.reduced_darks not in (None, {}):
237
248
  # we want to send those in relative position to have something generic. This is a convention for now
249
+ reduced_darks = scan.reduced_darks
250
+ reduced_darks.pop("reduce_frames_name", None)
238
251
  self.Outputs.reduced_darks.send(
239
252
  tomoscan.esrf.scan.utils.from_absolute_reduced_frames_to_relative(
240
- reduced_frames=scan.reduced_darks, scan=scan
253
+ reduced_frames=reduced_darks, scan=scan
241
254
  )
242
255
  )
243
256
  if scan.reduced_flats not in (None, {}):
244
257
  # we want to send those in relative position to have something generic. This is a convention for now
258
+ reduced_flats = scan.reduced_flats
259
+ reduced_flats.pop("reduce_frames_name", None)
245
260
  self.Outputs.reduced_flats.send(
246
261
  tomoscan.esrf.scan.utils.from_absolute_reduced_frames_to_relative(
247
- reduced_frames=scan.reduced_flats, scan=scan
262
+ reduced_frames=reduced_flats, scan=scan
248
263
  )
249
264
  )
250
265
  _logger.info(f"{scan} ended")
@@ -41,7 +41,7 @@ from silx.gui import qt
41
41
  import tomwer.core.process.reconstruction.nabu.nabuslices
42
42
  from tomwer.core.cluster import SlurmClusterConfiguration
43
43
  from tomwer.core.futureobject import FutureTomwerObject
44
- from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSlices
44
+ from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSlicesTask
45
45
  from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock
46
46
  from tomwer.core.volume.volumefactory import VolumeFactory
47
47
  from tomwer.gui.reconstruction.nabu.slices import NabuWindow
@@ -70,12 +70,10 @@ class NabuOW(WidgetLongProcessing, SuperviseOW):
70
70
 
71
71
  want_main_area = True
72
72
  resizing_enabled = True
73
- compress_signal = False
74
- allows_cycle = True
75
73
 
76
74
  _ewoks_default_inputs = Setting({"data": None, "nabu_params": None})
77
75
 
78
- ewokstaskclass = tomwer.core.process.reconstruction.nabu.nabuslices.NabuSlices
76
+ ewokstaskclass = tomwer.core.process.reconstruction.nabu.nabuslices.NabuSlicesTask
79
77
 
80
78
  sigScanReady = qt.Signal(TomwerScanBase)
81
79
  "Signal emitted when a scan is ended"
@@ -91,7 +89,7 @@ class NabuOW(WidgetLongProcessing, SuperviseOW):
91
89
  type=TomwerScanBase,
92
90
  doc="one scan to be process",
93
91
  default=True,
94
- multiple=False,
92
+ multiple=True,
95
93
  )
96
94
  cluster_in = Input(
97
95
  name="cluster_config",
@@ -185,7 +183,7 @@ class NabuOW(WidgetLongProcessing, SuperviseOW):
185
183
  return super().__new__(cls, *args, **kwargs)
186
184
 
187
185
  @Inputs.data
188
- def process(self, scan: TomwerScanBase):
186
+ def process(self, scan, *args, **kwargs):
189
187
  assert isinstance(scan, (TomwerScanBase, type(None)))
190
188
  if scan is None:
191
189
  return
@@ -206,7 +204,7 @@ class NabuOW(WidgetLongProcessing, SuperviseOW):
206
204
 
207
205
  if scan.axis_params is None or scan.axis_params.relative_cor_value is None:
208
206
  # try to retrieve last computed cor value from nabu process
209
- r_cor = NabuSlices.retrieve_last_relative_cor(scan)
207
+ r_cor = NabuSlicesTask.retrieve_last_relative_cor(scan)
210
208
  if scan.axis_params is None:
211
209
  from tomwer.synctools.axis import QAxisRP
212
210
 
@@ -229,6 +227,21 @@ class NabuOW(WidgetLongProcessing, SuperviseOW):
229
227
  else:
230
228
  self.process(scan)
231
229
 
230
+ def cancel(self, scan):
231
+ if scan is None:
232
+ return
233
+ if scan in self._processingStack:
234
+ self._processingStack.remove(scan)
235
+ if (
236
+ self._processingStack._data_currently_computed.get_identifier().to_str()
237
+ == scan.get_identifier().to_str()
238
+ ):
239
+ # stop current processing
240
+ self._processingStack.cancel()
241
+ # if possible process next
242
+ if self._processingStack.can_process_next():
243
+ self._processingStack._process_next()
244
+
232
245
  @Inputs.cluster_in
233
246
  def setCluster(self, slurm_cluster: Optional[SlurmClusterConfiguration]):
234
247
  assert isinstance(
@@ -283,3 +296,12 @@ class NabuOW(WidgetLongProcessing, SuperviseOW):
283
296
  # ignore slurm cluster. Defined by the upper widget
284
297
  config.pop("cluster_config", None)
285
298
  self._nabuWidget.setConfiguration(config=config)
299
+
300
+ def keyPressEvent(self, event):
301
+ """The event has to be filtered since we have some children
302
+ that can be edited using the 'enter' key as defining the cor manually
303
+ (see #481)). As we are in a dialog this automatically trigger
304
+ 'accepted'. See https://forum.qt.io/topic/5080/preventing-enter-key-from-triggering-ok-in-qbuttonbox-in-particular-qlineedit-qbuttonbox/5
305
+ """
306
+ if event.key() not in (qt.Qt.Key_Enter, qt.Qt.Key_Return):
307
+ super().keyPressEvent(event)
@@ -46,7 +46,7 @@ from tomwer.core import settings
46
46
  from tomwer.core.cluster import SlurmClusterConfiguration
47
47
  from tomwer.core.futureobject import FutureTomwerObject
48
48
  from tomwer.core.process.reconstruction.nabu import utils as nabu_utils
49
- from tomwer.core.process.reconstruction.nabu.nabuvolume import NabuVolume
49
+ from tomwer.core.process.reconstruction.nabu.nabuvolume import NabuVolumeTask
50
50
  from tomwer.core.scan.scanbase import TomwerScanBase
51
51
  from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR
52
52
  from tomwer.core.utils.scanutils import format_output_location
@@ -78,12 +78,10 @@ class NabuVolumeOW(WidgetLongProcessing, SuperviseOW):
78
78
  priority = 15
79
79
  keywords = ["tomography", "nabu", "reconstruction", "volume"]
80
80
 
81
- ewokstaskclass = tomwer.core.process.reconstruction.nabu.nabuvolume.NabuVolume
81
+ ewokstaskclass = tomwer.core.process.reconstruction.nabu.nabuvolume.NabuVolumeTask
82
82
 
83
83
  want_main_area = True
84
84
  resizing_enabled = True
85
- compress_signal = False
86
- allows_cycle = True
87
85
 
88
86
  _ewoks_default_inputs = Setting(
89
87
  {"data": None, "nabu_volume_params": None, "nabu_params": None}
@@ -261,7 +259,7 @@ class NabuVolumeOW(WidgetLongProcessing, SuperviseOW):
261
259
  or dataset.axis_params.relative_cor_value is None
262
260
  ):
263
261
  # try to retrieve last computed cor value from nabu process
264
- r_cor = NabuVolume.retrieve_last_relative_cor(dataset)
262
+ r_cor = NabuVolumeTask.retrieve_last_relative_cor(dataset)
265
263
  if dataset.axis_params is None:
266
264
  from tomwer.synctools.axis import QAxisRP
267
265
 
@@ -275,6 +273,21 @@ class NabuVolumeOW(WidgetLongProcessing, SuperviseOW):
275
273
 
276
274
  self.process(dataset)
277
275
 
276
+ def cancel(self, scan):
277
+ if scan is None:
278
+ return
279
+ if scan in self._processingStack:
280
+ self._processingStack.remove(scan)
281
+ if (
282
+ self._processingStack._data_currently_computed.get_identifier().to_str()
283
+ == scan.get_identifier().to_str()
284
+ ):
285
+ # stop current processing
286
+ self._processingStack.cancel()
287
+ # if possible process next
288
+ if self._processingStack.can_process_next():
289
+ self._processingStack._process_next()
290
+
278
291
  @Inputs.cluster_in
279
292
  def setCluster(self, cluster):
280
293
  self._slurmCluster = cluster
@@ -35,6 +35,7 @@ from typing import Union
35
35
  from orangewidget import gui
36
36
  from orangewidget.settings import Setting
37
37
  from orangewidget.widget import Input, Output
38
+
38
39
  from processview.core import helpers as pv_helpers
39
40
  from processview.core.manager import DatasetState, ProcessManager
40
41
  from silx.gui import qt
@@ -45,8 +46,8 @@ from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler
45
46
  from tomwer.core import settings, utils
46
47
  from tomwer.core.cluster import SlurmClusterConfiguration
47
48
  from tomwer.core.futureobject import FutureTomwerObject
48
- from tomwer.core.process.reconstruction.axis import AxisProcess
49
- from tomwer.core.process.reconstruction.saaxis.saaxis import SAAxisProcess
49
+ from tomwer.core.process.reconstruction.axis import AxisTask
50
+ from tomwer.core.process.reconstruction.saaxis.saaxis import SAAxisTask
50
51
  from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock
51
52
  from tomwer.gui.reconstruction.saaxis.saaxis import SAAxisWindow as _SAAxisWindow
52
53
  from tomwer.synctools.axis import QAxisRP
@@ -103,11 +104,12 @@ class SAAxisWindow(_SAAxisWindow):
103
104
 
104
105
  text = f"start automatic cor for {scan} with {axis_params_info}"
105
106
  _logger.inform(text)
106
- cor_estimation_process = AxisProcess(
107
+ cor_estimation_process = AxisTask(
107
108
  inputs={
108
109
  "axis_params": self.getQAxisRP(),
109
110
  "data": scan,
110
111
  "wait": True,
112
+ "serialize_output_data": False,
111
113
  },
112
114
  process_id=-1,
113
115
  )
@@ -166,14 +168,25 @@ class SAAxisWindow(_SAAxisWindow):
166
168
  details = pm.get_dataset_details(
167
169
  dataset_id=scan.get_identifier(), process=self._processing_stack
168
170
  )
169
- ProcessManager().notify_dataset_state(
170
- dataset=scan,
171
- process=self._processing_stack,
172
- details=details,
173
- state=DatasetState.WAIT_USER_VALIDATION,
171
+ current_state = pm.get_dataset_state(
172
+ dataset_id=scan.get_identifier(), process=self._processing_stack
174
173
  )
175
- self.sigResultsToBeShow.emit()
174
+ if current_state not in (
175
+ DatasetState.CANCELLED,
176
+ DatasetState.FAILED,
177
+ DatasetState.SKIPPED,
178
+ ):
179
+ ProcessManager().notify_dataset_state(
180
+ dataset=scan,
181
+ process=self._processing_stack,
182
+ details=details,
183
+ state=DatasetState.WAIT_USER_VALIDATION,
184
+ )
185
+ self.sigResultsToBeShow.emit()
176
186
  if validate:
187
+ _logger.processSucceed(
188
+ f"saaxis processing succeeded with {scan.axis_params.relative_cor_value} as cor value"
189
+ )
177
190
  self.validateScan(scan)
178
191
 
179
192
  def wait_processing(self, wait_time):
@@ -216,7 +229,7 @@ class SAAxisWindow(_SAAxisWindow):
216
229
  pv_helpers.notify_succeed(
217
230
  process=self._processing_stack, dataset=scan, details=infos
218
231
  )
219
- SAAxisProcess.process_to_tomwer_processes(
232
+ SAAxisTask.process_to_tomwer_processes(
220
233
  scan=scan,
221
234
  )
222
235
  self.Outputs.data.send(scan)
@@ -275,12 +288,10 @@ class SAAxisOW(SuperviseOW, WidgetLongProcessing):
275
288
  "saaxis",
276
289
  ]
277
290
 
278
- ewokstaskclass = tomwer.core.process.reconstruction.saaxis.saaxis.SAAxisProcess
291
+ ewokstaskclass = tomwer.core.process.reconstruction.saaxis.saaxis.SAAxisTask
279
292
 
280
293
  want_main_area = True
281
294
  resizing_enabled = True
282
- allows_cycle = True
283
- compress_signal = False
284
295
 
285
296
  settingsHandler = CallbackSettingsHandler()
286
297
 
@@ -426,6 +437,7 @@ class SAAxisOW(SuperviseOW, WidgetLongProcessing):
426
437
  if current_scan_state in (
427
438
  DatasetState.PENDING,
428
439
  DatasetState.WAIT_USER_VALIDATION,
440
+ DatasetState.CANCELLED,
429
441
  ):
430
442
  details = "Was pending and has been replaced by another scan."
431
443
  self.notify_skip(scan=scan, details=details)
@@ -436,6 +448,21 @@ class SAAxisOW(SuperviseOW, WidgetLongProcessing):
436
448
  self.lockAutofocus(False)
437
449
  self.process(dataset)
438
450
 
451
+ def cancel(self, scan):
452
+ if scan is None:
453
+ return
454
+ if scan in self._widget._processing_stack:
455
+ self._widget._processing_stack.remove(scan)
456
+ if (
457
+ self._widget._processing_stack._data_currently_computed.get_identifier().to_str()
458
+ == scan.get_identifier().to_str()
459
+ ):
460
+ # stop current processing
461
+ self._widget._processing_stack.cancel()
462
+ # if possible process next
463
+ if self._widget._processing_stack.can_process_next():
464
+ self._widget._processing_stack._process_next()
465
+
439
466
  def validateCurrentScan(self):
440
467
  self._widget.validateCurrentScan()
441
468
 
@@ -44,7 +44,7 @@ from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler
44
44
  from tomwer.core import settings, utils
45
45
  from tomwer.core.cluster import SlurmClusterConfiguration
46
46
  from tomwer.core.futureobject import FutureTomwerObject
47
- from tomwer.core.process.reconstruction.sadeltabeta import SADeltaBetaProcess
47
+ from tomwer.core.process.reconstruction.sadeltabeta import SADeltaBetaTask
48
48
  from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock
49
49
  from tomwer.gui.reconstruction.sadeltabeta import (
50
50
  SADeltaBetaWindow as _SADeltaBetaWindow,
@@ -61,6 +61,7 @@ _logger = logging.getLogger(__name__)
61
61
  class SADeltaBetaWindow(_SADeltaBetaWindow):
62
62
  def __init__(self, Outputs, parent=None, process_id=None):
63
63
  _SADeltaBetaWindow.__init__(self, parent=parent)
64
+
64
65
  self.Outputs = Outputs
65
66
  self._sa_delta_beta_params = QSADeltaBetaParams()
66
67
  self._processing_stack = SADeltaBetaProcessStack(
@@ -108,12 +109,25 @@ class SADeltaBetaWindow(_SADeltaBetaWindow):
108
109
  )
109
110
  if scan.sa_delta_beta_params.autofocus is not None:
110
111
  self.setCurrentDeltaBetaValue(scan.sa_delta_beta_params.autofocus)
111
- ProcessManager().notify_dataset_state(
112
- dataset=scan,
113
- process=self._processing_stack,
114
- details="processing done. Wait for user validation",
115
- state=DatasetState.WAIT_USER_VALIDATION,
112
+
113
+ pm = ProcessManager()
114
+ details = pm.get_dataset_details(
115
+ dataset_id=scan.get_identifier(), process=self._processing_stack
116
116
  )
117
+ current_state = ProcessManager().get_dataset_state(
118
+ dataset_id=scan.get_identifier(), process=self._processing_stack
119
+ )
120
+ if current_state not in (
121
+ DatasetState.CANCELLED,
122
+ DatasetState.FAILED,
123
+ DatasetState.SKIPPED,
124
+ ):
125
+ ProcessManager().notify_dataset_state(
126
+ dataset=scan,
127
+ process=self._processing_stack,
128
+ details=details,
129
+ state=DatasetState.WAIT_USER_VALIDATION,
130
+ )
117
131
  if validate:
118
132
  self.validateScan(scan)
119
133
 
@@ -148,7 +162,7 @@ class SADeltaBetaWindow(_SADeltaBetaWindow):
148
162
  pv_helpers.notify_succeed(
149
163
  process=self._processing_stack, dataset=scan, details=infos
150
164
  )
151
- SADeltaBetaProcess.process_to_tomwer_processes(
165
+ SADeltaBetaTask.process_to_tomwer_processes(
152
166
  scan=scan,
153
167
  )
154
168
  self.Outputs.data.send(scan)
@@ -213,13 +227,11 @@ class SADeltaBetaOW(SuperviseOW, WidgetLongProcessing):
213
227
  ]
214
228
 
215
229
  ewokstaskclass = (
216
- tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta.SADeltaBetaProcess
230
+ tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta.SADeltaBetaTask
217
231
  )
218
232
 
219
233
  want_main_area = True
220
234
  resizing_enabled = True
221
- allows_cycle = True
222
- compress_signal = False
223
235
 
224
236
  settingsHandler = CallbackSettingsHandler()
225
237
 
@@ -391,3 +403,18 @@ class SADeltaBetaOW(SuperviseOW, WidgetLongProcessing):
391
403
 
392
404
  def getConfiguration(self):
393
405
  return self._widget.getConfiguration()
406
+
407
+ def cancel(self, scan):
408
+ if scan is None:
409
+ return
410
+ if scan in self._widget._processing_stack:
411
+ self._widget._processing_stack.remove(scan)
412
+ if (
413
+ self._widget._processing_stack._data_currently_computed.get_identifier().to_str()
414
+ == scan.get_identifier().to_str()
415
+ ):
416
+ # stop current processing
417
+ self._widget._processing_stack.cancel()
418
+ # if possible process next
419
+ if self._widget._processing_stack.can_process_next():
420
+ self._widget._processing_stack._process_next()
@@ -41,6 +41,7 @@ from silx.gui import qt
41
41
  from tomoscan.normalization import Method as NormMethod
42
42
 
43
43
  from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing
44
+
44
45
  from tomwer.core import settings, utils
45
46
  from tomwer.core.process.reconstruction.normalization import SinoNormalizationTask
46
47
  from tomwer.core.process.reconstruction.normalization.params import _ValueSource
@@ -67,7 +68,7 @@ class SinoNormWindow(_SinoNormWindow):
67
68
 
68
69
  def __init__(self, parent, process_id=None):
69
70
  assert isinstance(parent, SinoNormOW)
70
- super().__init__(parent)
71
+ _SinoNormWindow.__init__(self, parent)
71
72
  self._parentValidate = self.parent()._validate
72
73
  self._processing_stack = INormalizationProcessStack(process_id=process_id)
73
74
  # connect signal / slot
@@ -129,8 +130,6 @@ class SinoNormOW(WidgetLongProcessing, SuperviseOW):
129
130
 
130
131
  want_main_area = True
131
132
  resizing_enabled = True
132
- compress_signal = False
133
- allows_cycle = True
134
133
 
135
134
  _ewoks_default_inputs = Setting(dict())
136
135
 
@@ -39,7 +39,7 @@ from silx.gui import qt
39
39
 
40
40
  import tomwer.core.process.reconstruction.lamino.tofu
41
41
  from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler
42
- from tomwer.core.process.reconstruction.lamino import LaminoReconstruction
42
+ from tomwer.core.process.reconstruction.lamino import LaminoReconstructionTask
43
43
  from tomwer.core.scan.scanbase import TomwerScanBase
44
44
  from tomwer.gui.reconstruction.lamino.tofu import TofuWindow
45
45
  from tomwer.synctools.stacks.reconstruction.lamino import LaminoReconstructionStack
@@ -68,11 +68,12 @@ class TofuOW(WidgetLongProcessing, SuperviseOW):
68
68
 
69
69
  want_main_area = True
70
70
  resizing_enabled = True
71
- compress_signal = False
72
71
 
73
72
  settingsHandler = CallbackSettingsHandler()
74
73
 
75
- ewokstaskclass = tomwer.core.process.reconstruction.lamino.tofu.LaminoReconstruction
74
+ ewokstaskclass = (
75
+ tomwer.core.process.reconstruction.lamino.tofu.LaminoReconstructionTask
76
+ )
76
77
 
77
78
  _reconsParams = settings.Setting(dict())
78
79
  """Parameters directly editabled from the TOFU interface"""
@@ -146,7 +147,7 @@ class TofuOW(WidgetLongProcessing, SuperviseOW):
146
147
 
147
148
  callback = functools.partial(self.Outputs.data.send, scan_)
148
149
  self._reconsStack.add(
149
- recons_obj=LaminoReconstruction(),
150
+ recons_obj=LaminoReconstructionTask(),
150
151
  scan_id=scan_,
151
152
  recons_params=recons_param,
152
153
  additional_opts=add_options,
@@ -40,7 +40,6 @@ class StitcherOW(
40
40
 
41
41
  want_main_area = True
42
42
  resizing_enabled = True
43
- compress_signal = False
44
43
  want_control_area = False
45
44
 
46
45
  _ewoks_default_inputs = Setting(
@@ -40,7 +40,6 @@ class ZStitchingConfigOW(OWBaseWidget):
40
40
 
41
41
  want_main_area = True
42
42
  resizing_enabled = True
43
- compress_signal = False
44
43
  want_control_area = False
45
44
 
46
45
  _ewoks_default_inputs = Setting({})
@@ -60,17 +60,22 @@ class DataViewerOW(widget.OWBaseWidget, openclass=True):
60
60
  want_main_area = True
61
61
  want_control_area = False
62
62
  resizing_enabled = True
63
- compress_signal = False
64
63
 
65
64
  ewokstaskclass = tomwer.core.process.visualization.dataviewer._DataViewerPlaceHolder
66
65
 
67
66
  _viewer_config = settings.Setting(dict())
68
67
 
69
68
  class Inputs:
70
- data = Input(name="data", type=TomwerScanBase)
69
+ data = Input(
70
+ name="data",
71
+ type=TomwerScanBase,
72
+ multiple=True,
73
+ )
71
74
 
72
75
  def __init__(self, parent=None):
73
76
  super().__init__(parent)
77
+ self._imagejThreads = []
78
+ # threads used to open frames with image j
74
79
  self._layout = gui.vBox(self.mainArea, self.name).layout()
75
80
  self.viewer = DataViewer(parent=self)
76
81
  self.viewer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
@@ -97,7 +102,7 @@ class DataViewerOW(widget.OWBaseWidget, openclass=True):
97
102
  _logger.warning("No active image defined")
98
103
  else:
99
104
  try:
100
- utils.open_url_with_image_j(current_url)
105
+ self._imagejThreads.append(utils.open_url_with_image_j(current_url))
101
106
  except OSError as e:
102
107
  msg = qt.QMessageBox(self)
103
108
  msg.setIcon(qt.QMessageBox.Warning)
@@ -106,7 +111,7 @@ class DataViewerOW(widget.OWBaseWidget, openclass=True):
106
111
  msg.exec_()
107
112
 
108
113
  @Inputs.data
109
- def addScan(self, scan):
114
+ def addScan(self, scan, *args, **kwargs):
110
115
  if scan is None:
111
116
  return
112
117
  self.viewer.setScan(scan)
@@ -136,6 +141,7 @@ class DataViewerOW(widget.OWBaseWidget, openclass=True):
136
141
  self.viewer.blockSignals(old_state)
137
142
 
138
143
  def close(self):
144
+ [thread.quit() for thread in self._imagejThreads]
139
145
  self.viewer.close()
140
146
  self.viewer = None
141
147
  super().close()
@@ -31,6 +31,7 @@ import logging
31
31
 
32
32
  from orangewidget import gui, widget
33
33
  from orangewidget.widget import Input
34
+
34
35
  from silx.gui import qt
35
36
 
36
37
  import tomwer.core.process.visualization.diffviewer
@@ -56,7 +57,6 @@ class DiffViewerOW(widget.OWBaseWidget, openclass=True):
56
57
  want_main_area = True
57
58
  want_control_area = False
58
59
  resizing_enabled = True
59
- compress_signal = False
60
60
 
61
61
  ewokstaskclass = tomwer.core.process.visualization.diffviewer._DiffViewerPlaceHolder
62
62
 
@@ -67,7 +67,6 @@ if has_liveslice is True:
67
67
 
68
68
  want_main_area = True
69
69
  resizing_enabled = True
70
- compress_signal = False
71
70
 
72
71
  class Inputs:
73
72
  data = Input(name="data", type=TomwerScanBase)
@@ -40,7 +40,6 @@ class NXtomoMetadataViewerOW(widget.OWBaseWidget, openclass=True):
40
40
 
41
41
  want_main_area = True
42
42
  resizing_enabled = True
43
- compress_signal = False
44
43
 
45
44
  def __init__(self, parent=None, *args, **kwargs):
46
45
  super().__init__(parent=parent, *args, **kwargs)
@@ -31,6 +31,7 @@ import logging
31
31
 
32
32
  from orangewidget import gui, widget
33
33
  from orangewidget.widget import Input
34
+
34
35
  from silx.gui import qt
35
36
 
36
37
  import tomwer.core.process.visualization.radiostack
@@ -60,15 +61,16 @@ class RadioStackOW(widget.OWBaseWidget, openclass=True):
60
61
 
61
62
  ewokstaskclass = tomwer.core.process.visualization.radiostack._RadioStackPlaceHolder
62
63
 
63
- allows_cycle = True
64
- compress_signal = False
65
-
66
64
  want_main_area = True
67
65
  want_control_area = False
68
66
  resizing_enabled = True
69
67
 
70
68
  class Inputs:
71
- data = Input(name="data", type=TomwerScanBase)
69
+ data = Input(
70
+ name="data",
71
+ type=TomwerScanBase,
72
+ multiple=True,
73
+ )
72
74
 
73
75
  def __init__(self, parent=None):
74
76
  widget.OWBaseWidget.__init__(self, parent)
@@ -77,7 +79,7 @@ class RadioStackOW(widget.OWBaseWidget, openclass=True):
77
79
  self._box.layout().addWidget(self._viewer)
78
80
 
79
81
  @Inputs.data
80
- def addLeafScan(self, scanID):
82
+ def addLeafScan(self, scanID, *args, **kwargs):
81
83
  if scanID is None:
82
84
  return
83
85
  self._viewer.addLeafScan(scanID)
@@ -32,6 +32,7 @@ import os
32
32
 
33
33
  from orangewidget import gui, widget
34
34
  from orangewidget.widget import Input
35
+
35
36
  from silx.gui import qt
36
37
 
37
38
  import tomwer.core.process.visualization.samplemoved
@@ -67,7 +68,6 @@ class SampleMovedOW(widget.OWBaseWidget, openclass=True):
67
68
  want_main_area = True
68
69
  want_control_area = False
69
70
  resizing_enabled = True
70
- compress_signal = False
71
71
 
72
72
  class Inputs:
73
73
  data = Input(name="data", type=TomwerScanBase)
@@ -62,9 +62,6 @@ class SinogramViewerOW(WidgetLongProcessing, widget.OWBaseWidget, openclass=True
62
62
  tomwer.core.process.visualization.sinogramviewer._SinogramViewerPlaceHolder
63
63
  )
64
64
 
65
- allows_cycle = True
66
- compress_signal = False
67
-
68
65
  want_main_area = True
69
66
  want_control_area = False
70
67
  resizing_enabled = True