tomwer 1.3.0.dev2__py3-none-any.whl → 1.3.0rc10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. orangecontrib/tomwer/widgets/__init__.py +11 -12
  2. orangecontrib/tomwer/widgets/control/DataListenerOW.py +6 -6
  3. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +6 -6
  4. orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +3 -3
  5. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +10 -8
  6. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +6 -6
  7. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +1 -1
  8. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -98
  9. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -129
  10. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +13 -12
  11. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +11 -9
  12. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +11 -9
  13. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +12 -15
  14. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +9 -9
  15. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  16. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -1
  17. tomwer/__main__.py +0 -10
  18. tomwer/app/canvas_launcher/config.py +3 -3
  19. tomwer/app/canvas_launcher/environ.py +1 -0
  20. tomwer/app/intensitynormalization.py +12 -11
  21. tomwer/app/nabuapp.py +0 -11
  22. tomwer/app/zstitching.py +11 -1
  23. tomwer/core/process/control/datalistener/datalistener.py +15 -10
  24. tomwer/core/process/control/nxtomomill.py +1 -1
  25. tomwer/core/process/control/scantransfer.py +8 -32
  26. tomwer/core/process/edit/darkflatpatch.py +8 -9
  27. tomwer/core/process/edit/imagekeyeditor.py +20 -22
  28. tomwer/core/process/icat/screenshots.py +1 -0
  29. tomwer/core/process/reconstruction/axis/axis.py +263 -59
  30. tomwer/core/process/reconstruction/axis/mode.py +161 -50
  31. tomwer/core/process/reconstruction/axis/params.py +23 -20
  32. tomwer/core/process/reconstruction/darkref/darkrefs.py +12 -13
  33. tomwer/core/process/reconstruction/nabu/castvolume.py +3 -3
  34. tomwer/core/process/reconstruction/nabu/nabucommon.py +43 -19
  35. tomwer/core/process/reconstruction/nabu/nabuscores.py +34 -7
  36. tomwer/core/process/reconstruction/nabu/nabuslices.py +81 -26
  37. tomwer/core/process/reconstruction/nabu/nabuvolume.py +31 -26
  38. tomwer/core/process/reconstruction/nabu/plane.py +9 -0
  39. tomwer/core/process/reconstruction/nabu/utils.py +32 -9
  40. tomwer/core/process/reconstruction/saaxis/saaxis.py +4 -1
  41. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +9 -1
  42. tomwer/core/process/reconstruction/scores/params.py +3 -3
  43. tomwer/core/process/reconstruction/test/test_darkref_copy.py +4 -4
  44. tomwer/core/process/stitching/nabustitcher.py +11 -10
  45. tomwer/core/process/task.py +33 -27
  46. tomwer/core/process/test/test_axis.py +7 -6
  47. tomwer/core/process/test/test_data_transfer.py +3 -3
  48. tomwer/core/process/test/test_nabu.py +10 -2
  49. tomwer/core/process/test/test_normalization.py +2 -2
  50. tomwer/core/scan/blissscan.py +3 -3
  51. tomwer/core/scan/edfscan.py +9 -9
  52. tomwer/core/scan/nxtomoscan.py +11 -11
  53. tomwer/core/scan/scanbase.py +31 -24
  54. tomwer/core/scan/test/test_future_scan.py +1 -1
  55. tomwer/core/scan/test/test_h5.py +4 -4
  56. tomwer/core/scan/test/test_process_registration.py +2 -2
  57. tomwer/core/scan/test/test_scan.py +1 -75
  58. tomwer/core/settings.py +3 -3
  59. tomwer/core/test/test_utils.py +2 -2
  60. tomwer/core/volume/edfvolume.py +6 -6
  61. tomwer/core/volume/hdf5volume.py +6 -6
  62. tomwer/core/volume/jp2kvolume.py +6 -6
  63. tomwer/core/volume/rawvolume.py +6 -6
  64. tomwer/core/volume/tiffvolume.py +12 -12
  65. tomwer/gui/cluster/slurm.py +14 -9
  66. tomwer/gui/cluster/supervisor.py +12 -0
  67. tomwer/gui/cluster/test/test_cluster.py +1 -2
  68. tomwer/gui/cluster/test/test_supervisor.py +1 -1
  69. tomwer/gui/control/datalist.py +5 -0
  70. tomwer/gui/control/datawatcher/controlwidget.py +2 -4
  71. tomwer/gui/control/reducedarkflatselector.py +8 -8
  72. tomwer/gui/control/test/test_single_tomo_obj.py +1 -1
  73. tomwer/gui/edit/dkrfpatch.py +4 -4
  74. tomwer/gui/edit/nxtomowarmer.py +2 -2
  75. tomwer/gui/edit/test/test_dkrf_patch.py +6 -6
  76. tomwer/gui/imagefromfile.py +2 -2
  77. tomwer/gui/qfolderdialog.py +5 -0
  78. tomwer/gui/reconstruction/axis/CompareImages.py +94 -168
  79. tomwer/gui/reconstruction/axis/radioaxis.py +58 -182
  80. tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -1
  81. tomwer/gui/reconstruction/nabu/castvolume.py +8 -1
  82. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +54 -21
  83. tomwer/gui/reconstruction/normalization/intensity.py +3 -25
  84. tomwer/gui/reconstruction/saaxis/corrangeselector.py +1 -1
  85. tomwer/gui/reconstruction/saaxis/saaxis.py +1 -11
  86. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +0 -10
  87. tomwer/gui/reconstruction/scores/scoreplot.py +1 -6
  88. tomwer/gui/reconstruction/test/test_axis.py +18 -4
  89. tomwer/gui/reconstruction/test/test_nabu.py +3 -0
  90. tomwer/gui/stitching/stitching.py +2 -2
  91. tomwer/gui/stitching/stitching_preview.py +7 -53
  92. tomwer/gui/stitching/stitching_raw.py +3 -3
  93. tomwer/gui/utils/inputwidget.py +12 -2
  94. tomwer/gui/utils/lineselector/lineselector.py +1 -1
  95. tomwer/gui/visualization/dataviewer.py +47 -17
  96. tomwer/gui/visualization/sinogramviewer.py +19 -26
  97. tomwer/gui/visualization/test/test_volumeviewer.py +64 -66
  98. tomwer/gui/visualization/volumeviewer.py +105 -105
  99. tomwer/io/utils/h5pyutils.py +7 -3
  100. tomwer/io/utils/utils.py +3 -3
  101. tomwer/resources/gui/icons/parameters.svg +1 -1
  102. tomwer/resources/gui/illustrations/no_rot.svg +1 -1
  103. tomwer/synctools/stacks/edit/darkflatpatch.py +17 -12
  104. tomwer/tests/test_scripts.py +0 -3
  105. tomwer/third_part/WaitingOverlay.py +110 -0
  106. tomwer/third_part/__init__.py +0 -0
  107. tomwer/version.py +2 -2
  108. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/METADATA +32 -31
  109. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/RECORD +115 -153
  110. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/WHEEL +1 -1
  111. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +0 -197
  112. orangecontrib/tomwer/widgets/reconstruction/icons/XY_lamino.svg +0 -168
  113. orangecontrib/tomwer/widgets/reconstruction/icons/XZ_lamino.svg +0 -275
  114. orangecontrib/tomwer/widgets/reconstruction/icons/YZ_lamino.svg +0 -182
  115. tomwer/app/lamino.py +0 -143
  116. tomwer/core/process/reconstruction/lamino/__init__.py +0 -1
  117. tomwer/core/process/reconstruction/lamino/tofu.py +0 -1000
  118. tomwer/core/process/test/test_lamino.py +0 -76
  119. tomwer/core/test/test_lamino.py +0 -92
  120. tomwer/gui/reconstruction/lamino/__init__.py +0 -31
  121. tomwer/gui/reconstruction/lamino/tofu/TofuOptionLoader.py +0 -107
  122. tomwer/gui/reconstruction/lamino/tofu/__init__.py +0 -1
  123. tomwer/gui/reconstruction/lamino/tofu/misc.py +0 -148
  124. tomwer/gui/reconstruction/lamino/tofu/projections.py +0 -896
  125. tomwer/gui/reconstruction/lamino/tofu/settings.py +0 -75
  126. tomwer/gui/reconstruction/lamino/tofu/tofu.py +0 -432
  127. tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +0 -567
  128. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +0 -757
  129. tomwer/gui/reconstruction/test/test_lamino.py +0 -194
  130. tomwer/resources/gui/icons/lamino_parameters.svg +0 -70
  131. tomwer/resources/gui/illustrations/lamino_angle.png +0 -0
  132. tomwer/resources/gui/illustrations/lamino_angle.svg +0 -509
  133. tomwer/resources/gui/illustrations/lamino_beta_angle.png +0 -0
  134. tomwer/resources/gui/illustrations/lamino_beta_angle.svg +0 -97
  135. tomwer/resources/gui/illustrations/lamino_theta_angle.png +0 -0
  136. tomwer/resources/gui/illustrations/lamino_theta_angle.svg +0 -368
  137. tomwer/resources/gui/illustrations/manual_slice.png +0 -0
  138. tomwer/resources/gui/illustrations/manual_slice.svg +0 -221
  139. tomwer/resources/gui/illustrations/psi_angle.png +0 -0
  140. tomwer/resources/gui/illustrations/psi_angle.svg +0 -479
  141. tomwer/resources/gui/illustrations/rotation_center.png +0 -0
  142. tomwer/resources/gui/illustrations/rotation_center.svg +0 -276
  143. tomwer/resources/gui/illustrations/slice_stack.png +0 -0
  144. tomwer/resources/gui/illustrations/slice_stack.svg +0 -266
  145. tomwer/resources/gui/illustrations/xy_slice.png +0 -0
  146. tomwer/resources/gui/illustrations/xy_slice.svg +0 -269
  147. tomwer/resources/gui/illustrations/xz_slice.png +0 -0
  148. tomwer/resources/gui/illustrations/xz_slice.svg +0 -270
  149. tomwer/resources/gui/illustrations/yz_slice.png +0 -0
  150. tomwer/resources/gui/illustrations/yz_slice.svg +0 -270
  151. tomwer/synctools/stacks/reconstruction/lamino.py +0 -233
  152. /tomwer-1.3.0.dev2-py3.11-nspkg.pth → /tomwer-1.3.0rc10-py3.11-nspkg.pth +0 -0
  153. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/LICENSE +0 -0
  154. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/entry_points.txt +0 -0
  155. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/namespace_packages.txt +0 -0
  156. {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/top_level.txt +0 -0
@@ -33,75 +33,30 @@ import weakref
33
33
  import numpy
34
34
  from silx.gui import icons as silx_icons
35
35
  from silx.gui import qt
36
- from silx.gui.plot import CompareImages as _CompareImages
36
+ from silx.gui.plot.CompareImages import (
37
+ CompareImages as _CompareImages,
38
+ VisualizationMode,
39
+ )
40
+
41
+ try:
42
+ # silx 2
43
+ from silx.gui.plot.tools.compare.toolbar import VisualizationModeToolButton
44
+ except ImportError as e:
45
+ raise e
46
+ # silx 1
47
+ from silx.gui.plot.CompareImages import VisualizationModeToolButton
37
48
  from silx.gui.plot import tools
38
49
 
39
- from tomwer.gui import icons as tomwer_icons
40
50
 
41
51
  _logger = logging.getLogger(__name__)
42
52
 
43
53
 
44
- class CompareImagesToolBar(qt.QToolBar):
45
- """ToolBar containing specific tools to custom the configuration of a
46
- :class:`CompareImages` widget
47
-
48
- Use :meth:`setCompareWidget` to connect this toolbar to a specific
49
- :class:`CompareImages` widget.
50
-
51
- :param Union[qt.QWidget,None] parent: Parent of this widget.
52
- """
53
-
54
- def __init__(self, parent=None):
55
- qt.QToolBar.__init__(self, parent)
56
-
57
- self.__compareWidget = None
58
-
59
- menu = qt.QMenu(self)
60
- self.__visualizationAction = qt.QAction(self)
61
- self.__visualizationAction.setMenu(menu)
62
- self.__visualizationAction.setCheckable(False)
63
- self.addAction(self.__visualizationAction)
64
- self.__visualizationGroup = qt.QActionGroup(self)
65
- self.__visualizationGroup.setExclusive(True)
66
- self.__visualizationGroup.triggered.connect(self.__visualizationModeChanged)
67
-
68
- icon = silx_icons.getQIcon("compare-mode-a")
69
- action = qt.QAction(icon, "Display frame 1", self)
70
- action.setIconVisibleInMenu(True)
71
- action.setCheckable(True)
72
- action.setShortcut(qt.QKeySequence(qt.Qt.Key_A))
73
- action.setProperty("mode", CompareImages.VisualizationMode.ONLY_A)
74
- menu.addAction(action)
75
- self.__visualizationGroup.addAction(action)
76
-
77
- icon = silx_icons.getQIcon("compare-mode-b")
78
- action = qt.QAction(icon, "Display frame 2", self)
79
- action.setIconVisibleInMenu(True)
80
- action.setCheckable(True)
81
- action.setShortcut(qt.QKeySequence(qt.Qt.Key_B))
82
- action.setProperty("mode", CompareImages.VisualizationMode.ONLY_B)
83
- menu.addAction(action)
84
- self.__visualizationGroup.addAction(action)
85
-
86
- icon = silx_icons.getQIcon("compare-mode-rbneg-channel")
87
- action = qt.QAction(icon, "Subtract in color mode", self)
88
- action.setIconVisibleInMenu(True)
89
- action.setCheckable(True)
90
- action.setShortcut(qt.QKeySequence(qt.Qt.Key_C))
91
- action.setProperty(
92
- "mode", _CompareImages.VisualizationMode.COMPOSITE_RED_BLUE_GRAY_NEG
93
- )
94
- menu.addAction(action)
95
- self.__visualizationGroup.addAction(action)
54
+ class CompareImages(_CompareImages):
55
+ sigCropImagesChanged = qt.Signal()
56
+ """Emit when cropping of the compared images has changed"""
96
57
 
97
- icon = tomwer_icons.getQIcon("compare_mode_a_minus_b")
98
- action = qt.QAction(icon, "Subtract in BW mode", self)
99
- action.setIconVisibleInMenu(True)
100
- action.setCheckable(True)
101
- action.setShortcut(qt.QKeySequence(qt.Qt.Key_S))
102
- action.setProperty("mode", _CompareImages.VisualizationMode.COMPOSITE_A_MINUS_B)
103
- menu.addAction(action)
104
- self.__visualizationGroup.addAction(action)
58
+ def __init__(self, parent=None, backend=None):
59
+ super().__init__(parent, backend)
105
60
 
106
61
  # create crop images action
107
62
  icon = silx_icons.getQIcon("crop")
@@ -110,126 +65,39 @@ class CompareImagesToolBar(qt.QToolBar):
110
65
  action.setChecked(True)
111
66
  action.triggered.connect(self.__cropComparedImagesChanged)
112
67
  self.__cropComparedImages = action
113
- self.addAction(action)
114
-
115
- def setCompareWidget(self, widget):
116
- """
117
- Connect this tool bar to a specific :class:`CompareImages` widget.
118
-
119
- :param Union[None,CompareImages] widget: The widget to connect with.
120
- """
121
- compareWidget = self.getCompareWidget()
122
- if compareWidget is not None:
123
- compareWidget.sigConfigurationChanged.disconnect(
124
- self.__updateSelectedActions
125
- )
126
- compareWidget = widget
127
- if compareWidget is None:
128
- self.__compareWidget = None
129
- else:
130
- self.__compareWidget = weakref.ref(compareWidget)
131
- if compareWidget is not None:
132
- widget.sigConfigurationChanged.connect(self.__updateSelectedActions)
133
- self.__updateSelectedActions()
134
-
135
- def getCompareWidget(self):
136
- """Returns the connected widget.
137
-
138
- :rtype: CompareImages
139
- """
140
- if self.__compareWidget is None:
141
- return None
142
- else:
143
- return self.__compareWidget()
144
-
145
- def __updateSelectedActions(self):
146
- """
147
- Update the state of this tool bar according to the state of the
148
- connected :class:`CompareImages` widget.
149
- """
150
- widget = self.getCompareWidget()
151
- if widget is None:
152
- return
153
-
154
- mode = widget.getVisualizationMode()
155
- action = None
156
- for a in self.__visualizationGroup.actions():
157
- actionMode = a.property("mode")
158
- if mode == actionMode:
159
- action = a
160
- break
161
- old = self.__visualizationGroup.blockSignals(True)
162
- if action is not None:
163
- # Check this action
164
- action.setChecked(True)
165
- else:
166
- action = self.__visualizationGroup.checkedAction()
167
- if action is not None:
168
- # Uncheck this action
169
- action.setChecked(False)
170
- self.__updateVisualizationMenu()
171
- self.__visualizationGroup.blockSignals(old)
172
-
173
- def __visualizationModeChanged(self, selectedAction):
174
- """Called when user requesting changes of the visualization mode."""
175
- self.__updateVisualizationMenu()
176
- widget = self.getCompareWidget()
177
- if widget is not None:
178
- mode = selectedAction.property("mode")
179
- widget.setVisualizationMode(mode)
68
+ self._compareToolBar.addAction(action)
69
+
70
+ # define visible compare mode
71
+ self._compareToolBar._visualizationToolButton.setVisibleModes(
72
+ [
73
+ VisualizationMode.ONLY_A,
74
+ VisualizationMode.ONLY_B,
75
+ VisualizationMode.COMPOSITE_RED_BLUE_GRAY_NEG,
76
+ VisualizationMode.COMPOSITE_A_MINUS_B,
77
+ ]
78
+ )
180
79
 
181
80
  def __cropComparedImagesChanged(self):
182
- widget = self.getCompareWidget()
183
- if widget is not None:
184
- cropCompositeImage = self.__cropComparedImages.isChecked()
185
- widget.setCropComparedImages(cropCompositeImage)
186
-
187
- def __updateVisualizationMenu(self):
188
- """Update the state of the action containing visualization menu."""
189
- selectedAction = self.__visualizationGroup.checkedAction()
190
- if selectedAction is not None:
191
- self.__visualizationAction.setText(selectedAction.text())
192
- self.__visualizationAction.setIcon(selectedAction.icon())
193
- self.__visualizationAction.setToolTip(selectedAction.toolTip())
194
- else:
195
- self.__visualizationAction.setText("")
196
- self.__visualizationAction.setIcon(qt.QIcon())
197
- self.__visualizationAction.setToolTip("")
198
-
199
-
200
- class CompareImages(_CompareImages.CompareImages):
201
- sigCropImagesChanged = qt.Signal()
202
- """Emit when cropping of the compared images has changed"""
203
-
204
- def __init__(self, parent=None, backend=None):
205
- super().__init__(parent, backend=backend)
206
- self.__cropComparedImages = True
81
+ cropCompositeImage = self.__cropComparedImages.isChecked()
82
+ self.setCropComparedImages(cropCompositeImage)
207
83
 
208
84
  def cropComparedImages(self) -> bool:
209
- return self.__cropComparedImages
85
+ return self.__cropComparedImages.isChecked()
210
86
 
211
87
  def setCropComparedImages(self, crop):
212
- self.__cropComparedImages = crop
88
+ self.__cropComparedImages.setChecked(crop)
213
89
  self.sigCropImagesChanged.emit()
214
90
 
215
91
  def _createToolBars(self, plot):
216
92
  """Create tool bars displayed by the widget"""
217
- self._interactiveModeToolBar = tools.InteractiveModeToolBar(
218
- parent=self, plot=plot
219
- )
220
- self._imageToolBar = tools.ImageToolBar(parent=self, plot=plot)
221
-
93
+ toolBar = tools.InteractiveModeToolBar(parent=self, plot=plot)
94
+ self._interactiveModeToolBar = toolBar
95
+ toolBar = tools.ImageToolBar(parent=self, plot=plot)
96
+ self._imageToolBar = toolBar
222
97
  toolBar = CompareImagesToolBar(self)
223
98
  toolBar.setCompareWidget(self)
224
99
  self._compareToolBar = toolBar
225
100
 
226
- def _createStatusBar(self, plot):
227
- self._statusBar = CompareImagesStatusBar(self)
228
- self._statusBar.setCompareWidget(self)
229
-
230
- def getCompareToolBar(self):
231
- return self._compareToolBar
232
-
233
101
 
234
102
  class CompareImagesStatusBar(qt.QStatusBar):
235
103
  """StatusBar containing specific information contained in a
@@ -407,3 +275,61 @@ class CompareImagesStatusBar(qt.QStatusBar):
407
275
  text2 = self._formatData(data2)
408
276
  self._label1.setText("Frame 1: %s" % text1)
409
277
  self._label2.setText("Frame 2: %s" % text2)
278
+
279
+
280
+ class CompareImagesToolBar(qt.QToolBar):
281
+ def __init__(self, parent=None):
282
+ qt.QToolBar.__init__(self, parent)
283
+
284
+ self.__compareWidget = None
285
+
286
+ self._visualizationToolButton = VisualizationModeToolButton(self)
287
+ self._visualizationToolButton.setPopupMode(qt.QToolButton.InstantPopup)
288
+ self._visualizationToolButton.sigSelected.connect(self.__visualizationChanged)
289
+ self.addWidget(self._visualizationToolButton)
290
+
291
+ def __visualizationChanged(self, mode: VisualizationMode):
292
+ widget = self.getCompareWidget()
293
+ if widget is not None:
294
+ widget.setVisualizationMode(mode)
295
+
296
+ def setCompareWidget(self, widget):
297
+ """
298
+ Connect this tool bar to a specific :class:`CompareImages` widget.
299
+
300
+ :param Union[None,CompareImages] widget: The widget to connect with.
301
+ """
302
+ compareWidget = self.getCompareWidget()
303
+ if compareWidget is not None:
304
+ compareWidget.sigConfigurationChanged.disconnect(
305
+ self.__updateSelectedActions
306
+ )
307
+ compareWidget = widget
308
+ self.setEnabled(compareWidget is not None)
309
+ if compareWidget is None:
310
+ self.__compareWidget = None
311
+ else:
312
+ self.__compareWidget = weakref.ref(compareWidget)
313
+ if compareWidget is not None:
314
+ widget.sigConfigurationChanged.connect(self.__updateSelectedActions)
315
+ self.__updateSelectedActions()
316
+
317
+ def getCompareWidget(self):
318
+ """Returns the connected widget.
319
+
320
+ :rtype: CompareImages
321
+ """
322
+ if self.__compareWidget is None:
323
+ return None
324
+ else:
325
+ return self.__compareWidget()
326
+
327
+ def __updateSelectedActions(self):
328
+ """
329
+ Update the state of this tool bar according to the state of the
330
+ connected :class:`CompareImages` widget.
331
+ """
332
+ widget = self.getCompareWidget()
333
+ if widget is None:
334
+ return
335
+ self._visualizationToolButton.setSelected(widget.getVisualizationMode())
@@ -1,35 +1,3 @@
1
- # coding: utf-8
2
- # /*##########################################################################
3
- #
4
- # Copyright (c) 2016-2017 European Synchrotron Radiation Facility
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files (the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
- #
24
- # ###########################################################################*/
25
- """
26
- contains gui relative to axis calculation using radios
27
- """
28
-
29
- __authors__ = ["C. Nemoz", "H. Payno"]
30
- __license__ = "MIT"
31
- __date__ = "25/02/2019"
32
-
33
1
  import enum
34
2
  import logging
35
3
  import os
@@ -490,16 +458,10 @@ class RadioAxisWindow(qt.QMainWindow):
490
458
 
491
459
  with block_signals(self):
492
460
  try:
493
- try:
494
- self._plot.setData(
495
- image1=self._shiftedImgA,
496
- image2=self._shiftedImgB,
497
- updateColormap=False,
498
- )
499
- except TypeError:
500
- self._plot.setData(
501
- image1=self._shiftedImgA, image2=self._shiftedImgB
502
- )
461
+ self._plot.setData(
462
+ image1=self._shiftedImgA,
463
+ image2=self._shiftedImgB,
464
+ )
503
465
  except ValueError:
504
466
  _logger.warning(
505
467
  "Unable to set images. Maybe there is some "
@@ -1501,17 +1463,12 @@ class AxisTabWidget(qt.QTabWidget):
1501
1463
  def _updatePossibleInput(self):
1502
1464
  """Update Input tab according to the current mode"""
1503
1465
  current_mode = self.getMode()
1504
- if current_mode not in axis_mode._VALID_INPUTS:
1505
- raise ValueError(
1506
- f"valid input should have been defined for the mode {current_mode.value}"
1507
- )
1466
+ valid_inputs = axis_mode.AXIS_MODE_METADATAS[current_mode].valid_inputs
1467
+ if valid_inputs is None:
1468
+ self._inputWidget.setEnabled(False)
1508
1469
  else:
1509
- valid_inputs = axis_mode._VALID_INPUTS[current_mode]
1510
- if valid_inputs is None:
1511
- self._inputWidget.setEnabled(False)
1512
- else:
1513
- self._inputWidget.setEnabled(True)
1514
- self._inputWidget.setValidInputs(valid_inputs)
1470
+ self._inputWidget.setEnabled(True)
1471
+ self._inputWidget.setValidInputs(valid_inputs)
1515
1472
 
1516
1473
 
1517
1474
  class _CalculationWidget(qt.QWidget):
@@ -1537,46 +1494,46 @@ class _CalculationWidget(qt.QWidget):
1537
1494
  self._modeWidget.layout().addWidget(self.__rotAxisSelLabel)
1538
1495
  self._qcbPosition = qt.QComboBox(self)
1539
1496
 
1540
- algorithm_tooltips = (
1497
+ algorithm_groups = (
1498
+ # radio group
1541
1499
  (
1542
1500
  axis_mode.AxisMode.centered,
1543
- "Dedicated to fullfield. Previously named 'accurate'",
1544
- ),
1545
- (
1546
1501
  axis_mode.AxisMode.global_,
1547
- "Algorithm which can work for both half acquisition and standard ('full field') acquisition",
1548
- ),
1549
- (axis_mode.AxisMode.growing_window_radios, "A auto-Cor method"),
1550
- (
1502
+ axis_mode.AxisMode.growing_window_radios,
1551
1503
  axis_mode.AxisMode.sliding_window_radios,
1552
- "A method for estimating semi-automatically the CoR position. You have to provide a hint on where the CoR is (left, center, right).",
1504
+ axis_mode.AxisMode.octave_accurate_radios,
1553
1505
  ),
1554
- ("separator", None),
1555
- (axis_mode.AxisMode.growing_window_sinogram, "A auto-Cor method"),
1506
+ # sino group
1556
1507
  (
1508
+ axis_mode.AxisMode.growing_window_sinogram,
1557
1509
  axis_mode.AxisMode.sino_coarse_to_fine,
1558
- "Estimate CoR from sinogram. Only works for 360 degrees scans.",
1510
+ axis_mode.AxisMode.sliding_window_sinogram,
1511
+ axis_mode.AxisMode.sino_fourier_angles,
1559
1512
  ),
1513
+ # composite corase to fine
1560
1514
  (
1561
- axis_mode.AxisMode.sliding_window_sinogram,
1562
- "A method for estimating semi-automatically the CoR position. You have to provide a hint on where the CoR is (left, center, right).",
1515
+ axis_mode.AxisMode.composite_coarse_to_fine,
1516
+ axis_mode.AxisMode.near,
1563
1517
  ),
1564
- ("separator", None),
1565
- (axis_mode.AxisMode.composite_coarse_to_fine, "A auto-Cor method"),
1566
- (axis_mode.AxisMode.near, "Alias to composite_coarse_to_fine"),
1567
- ("separator", None),
1568
- (axis_mode.AxisMode.manual, "Enter or find manually the COR value"),
1569
- ("separator", None),
1570
- (axis_mode.AxisMode.read, "Read COR value from a file"),
1518
+ # manual
1519
+ (axis_mode.AxisMode.manual,),
1520
+ # read
1521
+ (axis_mode.AxisMode.read,),
1571
1522
  )
1572
-
1573
- for i_elmt, (method, tooltip) in enumerate(algorithm_tooltips):
1574
- if method == "separator":
1575
- self._qcbPosition.insertSeparator(i_elmt)
1576
- else:
1577
- self._qcbPosition.addItem(method.value)
1578
- idx = self._qcbPosition.findText(method.value)
1579
- self._qcbPosition.setItemData(idx, tooltip, qt.Qt.ToolTipRole)
1523
+ current_pos = 0
1524
+ for i_grp, algorithm_group in enumerate(algorithm_groups):
1525
+ if i_grp != 0:
1526
+ self._qcbPosition.insertSeparator(current_pos)
1527
+ current_pos += 1
1528
+ for cor_algorithm in algorithm_group:
1529
+ self._qcbPosition.addItem(cor_algorithm.value)
1530
+ idx = self._qcbPosition.findText(cor_algorithm.value)
1531
+ self._qcbPosition.setItemData(
1532
+ idx,
1533
+ axis_mode.AXIS_MODE_METADATAS[cor_algorithm].tooltip,
1534
+ qt.Qt.ToolTipRole,
1535
+ )
1536
+ current_pos += 1
1580
1537
 
1581
1538
  self._modeWidget.layout().addWidget(self._qcbPosition)
1582
1539
 
@@ -1716,14 +1673,6 @@ class _CalculationWidget(qt.QWidget):
1716
1673
  mode = self.getMode()
1717
1674
  with block_signals(self._qcbPosition):
1718
1675
  with block_signals(self._axis_params):
1719
- side = self.getSide()
1720
- self._nearOptsWidget.setVisible(
1721
- (
1722
- mode is axis_mode.AxisMode.composite_coarse_to_fine
1723
- and side == "near"
1724
- )
1725
- or (mode is axis_mode.AxisMode.near)
1726
- )
1727
1676
  self._corOptsWidget.setVisible(
1728
1677
  mode
1729
1678
  not in (
@@ -1733,82 +1682,38 @@ class _CalculationWidget(qt.QWidget):
1733
1682
  )
1734
1683
 
1735
1684
  self._padding_widget.setVisible(
1736
- mode
1737
- in (
1738
- axis_mode.AxisMode.centered,
1739
- axis_mode.AxisMode.global_,
1740
- axis_mode.AxisMode.growing_window_sinogram,
1741
- axis_mode.AxisMode.growing_window_radios,
1742
- axis_mode.AxisMode.sliding_window_sinogram,
1743
- axis_mode.AxisMode.sliding_window_radios,
1744
- axis_mode.AxisMode.sino_coarse_to_fine,
1745
- axis_mode.AxisMode.composite_coarse_to_fine,
1746
- axis_mode.AxisMode.near,
1747
- )
1685
+ axis_mode.AXIS_MODE_METADATAS[mode].allows_padding
1748
1686
  )
1749
- if mode in (
1750
- axis_mode.AxisMode.centered,
1751
- axis_mode.AxisMode.global_,
1752
- axis_mode.AxisMode.growing_window_sinogram,
1753
- axis_mode.AxisMode.growing_window_radios,
1754
- axis_mode.AxisMode.sliding_window_sinogram,
1755
- axis_mode.AxisMode.sliding_window_radios,
1756
- axis_mode.AxisMode.sino_coarse_to_fine,
1757
- axis_mode.AxisMode.composite_coarse_to_fine,
1758
- axis_mode.AxisMode.near,
1759
- ):
1687
+ if axis_mode.AXIS_MODE_METADATAS[mode].is_lockable:
1760
1688
  self._lockMethodPB.setVisible(True)
1761
1689
  else:
1762
1690
  self._lockMethodPB.setVisible(False)
1763
1691
  self.lockMode(False)
1764
1692
 
1765
- side_visible = mode in (
1766
- axis_mode.AxisMode.growing_window_sinogram,
1767
- axis_mode.AxisMode.growing_window_radios,
1768
- axis_mode.AxisMode.sliding_window_sinogram,
1769
- axis_mode.AxisMode.sliding_window_radios,
1770
- axis_mode.AxisMode.composite_coarse_to_fine,
1771
- axis_mode.AxisMode.near,
1772
- )
1773
- self._sideWidget.setVisible(side_visible)
1774
- if side_visible is True:
1693
+ sides_visible = len(axis_mode.AXIS_MODE_METADATAS[mode].valid_sides) > 0
1694
+ self._sideWidget.setVisible(sides_visible)
1695
+ if sides_visible is True:
1775
1696
  self._updateSideVisible(mode)
1776
-
1697
+ self._nearOptsWidget.setVisible(self.getSide() == "near")
1777
1698
  self._axis_params.mode = mode.value
1778
1699
  self._axis_params.changed()
1779
1700
  self.sigModeChanged.emit(mode.value)
1780
1701
 
1781
1702
  def _updateSideVisible(self, mode: axis_mode.AxisMode):
1782
- if mode not in (
1783
- axis_mode.AxisMode.growing_window_sinogram,
1784
- axis_mode.AxisMode.growing_window_radios,
1785
- axis_mode.AxisMode.sliding_window_sinogram,
1786
- axis_mode.AxisMode.sliding_window_radios,
1787
- axis_mode.AxisMode.composite_coarse_to_fine,
1788
- axis_mode.AxisMode.near,
1789
- ):
1703
+ mode = axis_mode.AxisMode.from_value(mode)
1704
+ if len(axis_mode.AXIS_MODE_METADATAS[mode].valid_sides) == 0:
1790
1705
  return
1791
1706
  else:
1792
1707
  current_value = self._axis_params.side
1793
1708
  with block_signals(self._sideCB):
1794
1709
  self._sideCB.clear()
1795
- values = ["left", "right", "center"]
1796
- if mode in (
1797
- axis_mode.AxisMode.growing_window_radios,
1798
- axis_mode.AxisMode.growing_window_sinogram,
1799
- ):
1800
- values.append("all")
1801
-
1802
- if mode is axis_mode.AxisMode.composite_coarse_to_fine:
1803
- values.append("near")
1804
- elif mode is axis_mode.AxisMode.near:
1805
- values = [
1806
- "near",
1807
- ]
1808
-
1710
+ values = axis_mode.AXIS_MODE_METADATAS[mode].valid_sides
1809
1711
  for value in values:
1810
1712
  self._sideCB.addItem(value)
1811
1713
  idx = self._sideCB.findText(current_value)
1714
+ if idx == -1:
1715
+ # if side doesn't exists, propose right as default when possible
1716
+ idx = self._sideCB.findText("right")
1812
1717
  if idx >= 0:
1813
1718
  self._sideCB.setCurrentIndex(idx)
1814
1719
  self._axis_params.side = self.getSide()
@@ -1823,30 +1728,12 @@ class _CalculationWidget(qt.QWidget):
1823
1728
  """
1824
1729
  if mode is not None:
1825
1730
  mode = axis_mode.AxisMode.from_value(mode)
1826
- if mode is None and self.getMode() not in (
1827
- axis_mode.AxisMode.centered,
1828
- axis_mode.AxisMode.global_,
1829
- axis_mode.AxisMode.growing_window_sinogram,
1830
- axis_mode.AxisMode.growing_window_radios,
1831
- axis_mode.AxisMode.sliding_window_sinogram,
1832
- axis_mode.AxisMode.sliding_window_radios,
1833
- axis_mode.AxisMode.sino_coarse_to_fine,
1834
- axis_mode.AxisMode.composite_coarse_to_fine,
1835
- axis_mode.AxisMode.near,
1836
- ):
1731
+ if mode is None and axis_mode.AXIS_MODE_METADATAS[self.getMode()].is_lockable():
1837
1732
  raise ValueError(
1838
1733
  "Unable to lock the current mode is not an automatic algorithm"
1839
1734
  )
1840
- elif mode != self.getMode() and mode not in (
1841
- axis_mode.AxisMode.centered,
1842
- axis_mode.AxisMode.global_,
1843
- axis_mode.AxisMode.growing_window_sinogram,
1844
- axis_mode.AxisMode.growing_window_radios,
1845
- axis_mode.AxisMode.sliding_window_sinogram,
1846
- axis_mode.AxisMode.sliding_window_radios,
1847
- axis_mode.AxisMode.sino_coarse_to_fine,
1848
- axis_mode.AxisMode.composite_coarse_to_fine,
1849
- axis_mode.AxisMode.near,
1735
+ elif (
1736
+ mode != self.getMode() and axis_mode.AXIS_MODE_METADATAS[mode].is_lockable()
1850
1737
  ):
1851
1738
  raise ValueError("Unable to lock %s this is not a lockable mode")
1852
1739
 
@@ -1900,11 +1787,7 @@ class _CalculationWidget(qt.QWidget):
1900
1787
  side = self.getSide()
1901
1788
  if side not in ("", None):
1902
1789
  self._axis_params.side = side
1903
- mode = self.getMode()
1904
- self._nearOptsWidget.setVisible(
1905
- (mode is axis_mode.AxisMode.composite_coarse_to_fine and side == "near")
1906
- or mode is axis_mode.AxisMode.near
1907
- )
1790
+ self._nearOptsWidget.setVisible(side == "near")
1908
1791
 
1909
1792
  def getCorOptions(self):
1910
1793
  return self._corOpts.text()
@@ -1947,17 +1830,10 @@ class _CalculationWidget(qt.QWidget):
1947
1830
  self.setMode(self._axis_params.mode)
1948
1831
  self.setEstimatedCorValue(self._axis_params.estimated_cor)
1949
1832
  self.setSide(self._axis_params.side)
1950
- if self._axis_params.mode in (
1951
- axis_mode.AxisMode.growing_window_sinogram,
1952
- axis_mode.AxisMode.growing_window_radios,
1953
- axis_mode.AxisMode.sliding_window_sinogram,
1954
- axis_mode.AxisMode.sliding_window_radios,
1955
- axis_mode.AxisMode.composite_coarse_to_fine,
1956
- axis_mode.AxisMode.near,
1957
- ):
1958
- self._sideWidget.setVisible(True)
1959
- else:
1960
- self._sideWidget.setVisible(False)
1833
+ sides_visible = (
1834
+ len(axis_mode.AXIS_MODE_METADATAS[self._axis_params.mode].valid_sides) > 0
1835
+ )
1836
+ self._sideWidget.setVisible(sides_visible)
1961
1837
  self._updateSideVisible(mode=self._axis_params.mode)
1962
1838
  self.setPaddingMode(self._axis_params.padding_mode)
1963
1839
  self.setCorOptions(self._axis_params.extra_cor_options)
@@ -198,7 +198,8 @@ class _TabGeneral(qt.QWidget):
198
198
  self._grpOptions = qt.QGroupBox("options", parent=self)
199
199
  self._grpOptions.setLayout(qt.QVBoxLayout())
200
200
  self._rmOptionCB = qt.QCheckBox(
201
- parent=self._grpOptions, text="remove raw files when done"
201
+ parent=self._grpOptions,
202
+ text="remove raw EDF files when done (for spec only)",
202
203
  )
203
204
  self.sigRmToggled = self._rmOptionCB.toggled
204
205
  self._skipOptionCB = qt.QCheckBox(
@@ -51,6 +51,12 @@ class CastVolumeWidget(qt.QWidget):
51
51
  sigConfigChanged = qt.Signal()
52
52
  """Signal emit when the configuration changed"""
53
53
 
54
+ DEFAULT_OUTPUT_DATA_TYPE = "uint16"
55
+
56
+ AVAILABLE_OUTPUT_DATA_TYPE = ("uint8", "uint16", "float32", "float64")
57
+
58
+ assert DEFAULT_OUTPUT_DATA_TYPE in AVAILABLE_OUTPUT_DATA_TYPE
59
+
54
60
  def __init__(self, parent) -> None:
55
61
  super().__init__(parent=parent)
56
62
 
@@ -61,7 +67,7 @@ class CastVolumeWidget(qt.QWidget):
61
67
  self._castToLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
62
68
  self.layout().addWidget(self._castToLabel, 0, 0, 1, 1)
63
69
  self._outputDataTypeCB = qt.QComboBox(self)
64
- for data_type in ("uint8", "uint16", "float32", "float64"):
70
+ for data_type in self.AVAILABLE_OUTPUT_DATA_TYPE:
65
71
  self._outputDataTypeCB.addItem(data_type)
66
72
  self.layout().addWidget(self._outputDataTypeCB, 0, 1, 1, 3)
67
73
  # output file format
@@ -158,6 +164,7 @@ class CastVolumeWidget(qt.QWidget):
158
164
  self.layout().addWidget(self._spacer, 99, 0, 1, 3)
159
165
 
160
166
  # set up
167
+ self._outputDataTypeCB.setCurrentText(self.DEFAULT_OUTPUT_DATA_TYPE)
161
168
  self._updateCRatiosVis()
162
169
 
163
170
  # connect signal / slot