tomwer 1.4.0rc0__py3-none-any.whl → 1.4.0rc2__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 (52) hide show
  1. orangecontrib/tomwer/tutorials/test_cor.ows +3 -3
  2. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +6 -14
  3. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +4 -2
  4. tomwer/app/axis.py +0 -3
  5. tomwer/app/multipag.py +11 -3
  6. tomwer/core/process/reconstruction/axis/axis.py +27 -736
  7. tomwer/core/process/reconstruction/axis/mode.py +86 -24
  8. tomwer/core/process/reconstruction/axis/params.py +127 -138
  9. tomwer/core/process/reconstruction/axis/side.py +8 -0
  10. tomwer/core/process/reconstruction/nabu/nabuscores.py +17 -20
  11. tomwer/core/process/reconstruction/nabu/nabuslices.py +5 -1
  12. tomwer/core/process/reconstruction/saaxis/saaxis.py +4 -4
  13. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +4 -4
  14. tomwer/core/process/reconstruction/tests/test_axis.py +1 -1
  15. tomwer/core/process/reconstruction/tests/test_utils.py +4 -4
  16. tomwer/core/process/reconstruction/utils/cor.py +8 -4
  17. tomwer/core/process/tests/test_nabu.py +1 -3
  18. tomwer/core/scan/nxtomoscan.py +2 -0
  19. tomwer/core/scan/scanbase.py +4 -4
  20. tomwer/core/scan/tests/test_process_registration.py +0 -18
  21. tomwer/gui/fonts.py +5 -0
  22. tomwer/gui/reconstruction/axis/AxisMainWindow.py +20 -9
  23. tomwer/gui/reconstruction/axis/AxisOptionsWidget.py +239 -79
  24. tomwer/gui/reconstruction/axis/AxisSettingsWidget.py +38 -17
  25. tomwer/gui/reconstruction/axis/AxisWidget.py +16 -8
  26. tomwer/gui/reconstruction/axis/CalculationWidget.py +40 -200
  27. tomwer/gui/reconstruction/axis/ControlWidget.py +10 -2
  28. tomwer/gui/reconstruction/axis/EstimatedCORWidget.py +394 -0
  29. tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py +118 -0
  30. tomwer/gui/reconstruction/axis/InputWidget.py +11 -155
  31. tomwer/gui/reconstruction/saaxis/corrangeselector.py +19 -10
  32. tomwer/gui/reconstruction/scores/scoreplot.py +5 -2
  33. tomwer/gui/reconstruction/tests/test_nabu.py +8 -0
  34. tomwer/gui/stitching/z_stitching/fineestimation.py +1 -1
  35. tomwer/gui/tests/test_axis_gui.py +31 -15
  36. tomwer/synctools/stacks/reconstruction/axis.py +5 -23
  37. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +1 -1
  38. tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
  39. tomwer/synctools/stacks/reconstruction/normalization.py +1 -1
  40. tomwer/synctools/stacks/reconstruction/saaxis.py +1 -1
  41. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +1 -1
  42. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py +0 -16
  43. tomwer/tests/test_ewoks/test_single_node_execution.py +1 -1
  44. tomwer/tests/test_ewoks/test_workflows.py +1 -1
  45. tomwer/version.py +1 -1
  46. {tomwer-1.4.0rc0.dist-info → tomwer-1.4.0rc2.dist-info}/METADATA +2 -2
  47. {tomwer-1.4.0rc0.dist-info → tomwer-1.4.0rc2.dist-info}/RECORD +51 -48
  48. tomwer/core/process/tests/test_axis.py +0 -231
  49. {tomwer-1.4.0rc0.dist-info → tomwer-1.4.0rc2.dist-info}/LICENSE +0 -0
  50. {tomwer-1.4.0rc0.dist-info → tomwer-1.4.0rc2.dist-info}/WHEEL +0 -0
  51. {tomwer-1.4.0rc0.dist-info → tomwer-1.4.0rc2.dist-info}/entry_points.txt +0 -0
  52. {tomwer-1.4.0rc0.dist-info → tomwer-1.4.0rc2.dist-info}/top_level.txt +0 -0
@@ -152,6 +152,7 @@ class AxisSettingsWidget(qt.QWidget):
152
152
  with block_signals(self._axisParams):
153
153
  self._axisParams.mode = mode
154
154
  self._mainWidget._calculationWidget.setMode(mode)
155
+ self._mainWidget._optionsWidget.setMode(mode)
155
156
  self._updateAxisView()
156
157
  self._axisParams.sigChanged.emit()
157
158
 
@@ -230,15 +231,15 @@ class AxisSettingsWidget(qt.QWidget):
230
231
 
231
232
  # expose API
232
233
 
233
- def updateAutomaticallyEstimatedCor(self):
234
- return self._mainWidget.updateAutomaticallyEstimatedCor()
235
-
236
- def setUpdateAutomaticallyEstimatedCor(self, value):
237
- self._mainWidget.setUpdateAutomaticallyEstimatedCor(value)
238
-
239
234
  def setEstimatedCor(self, value):
240
235
  self._mainWidget.setEstimatedCorValue(value=value)
241
236
 
237
+ def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
238
+ return self._mainWidget.updateXRotationAxisPixelPositionOnNewScan()
239
+
240
+ def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool):
241
+ self._mainWidget.setUpdateXRotationAxisPixelPositionOnNewScan(update=update)
242
+
242
243
  def getEstimatedCor(self):
243
244
  return self._mainWidget.getEstimatedCor()
244
245
 
@@ -266,6 +267,12 @@ class AxisSettingsWidget(qt.QWidget):
266
267
  def setModeLock(self, mode):
267
268
  return self._mainWidget.setModeLock(mode=mode)
268
269
 
270
+ def isYAxisInverted(self) -> bool:
271
+ return self._mainWidget.isYAxisInverted()
272
+
273
+ def setYAxisInverted(self, checked: bool):
274
+ return self._mainWidget.setYAxisInverted(checked=checked)
275
+
269
276
 
270
277
  class ManualAxisSelectionWidget(qt.QWidget):
271
278
  sigResetZoomRequested = qt.Signal()
@@ -492,6 +499,8 @@ class AxisSettingsTabWidget(qt.QTabWidget):
492
499
  sigModeChanged = qt.Signal(str)
493
500
  """Signal emit when mode (algorithm) is changed"""
494
501
 
502
+ sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal()
503
+
495
504
  def __init__(
496
505
  self,
497
506
  recons_params: QAxisRP | None,
@@ -517,12 +526,9 @@ class AxisSettingsTabWidget(qt.QTabWidget):
517
526
  spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
518
527
  widget.layout().addWidget(spacer)
519
528
 
520
- self._optionsSA = qt.QScrollArea(parent=self)
521
- self._optionsSA.setWidget(self._optionsWidget)
522
529
  self.addTab(self._calculationWidget, "calculation")
523
- self.addTab(self._optionsSA, "options")
530
+ self.addTab(self._optionsWidget, "options")
524
531
  # simplify set up. Hide options
525
- self._optionsSA.hide()
526
532
  self.addTab(self._inputWidget, "input")
527
533
 
528
534
  # set up
@@ -532,11 +538,11 @@ class AxisSettingsTabWidget(qt.QTabWidget):
532
538
  # connect signal / slot
533
539
  self._calculationWidget.sigLockModeChanged.connect(self.sigLockModeChanged)
534
540
  self.sigModeChanged.connect(self._updatePossibleInput)
541
+ self.sigModeChanged.connect(self._updatePossibleOptions)
535
542
  self._inputWidget._sigUrlChanged.connect(self._urlChanged)
536
543
  self._calculationWidget.sigModeChanged.connect(self.sigModeChanged)
537
- # not very nice but very convenient to have the setting near at the same level
538
- self._calculationWidget._qleNearPosQLE.textChanged.connect(
539
- self._inputWidget._changed
544
+ self._calculationWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect(
545
+ self.sigUpdateXRotAxisPixelPosOnNewScan
540
546
  )
541
547
 
542
548
  def _urlChanged(self):
@@ -544,6 +550,7 @@ class AxisSettingsTabWidget(qt.QTabWidget):
544
550
 
545
551
  def setScan(self, scan):
546
552
  if scan is not None:
553
+ self._calculationWidget.setScan(scan)
547
554
  self._inputWidget.setScan(scan)
548
555
 
549
556
  def setAxisParams(self, axis):
@@ -562,6 +569,10 @@ class AxisSettingsTabWidget(qt.QTabWidget):
562
569
  self._inputWidget.setEnabled(True)
563
570
  self._inputWidget.setValidInputs(valid_inputs)
564
571
 
572
+ def _updatePossibleOptions(self):
573
+ mode = self.getMode()
574
+ self._optionsWidget.setMode(mode)
575
+
565
576
  # expose API
566
577
  def isModeLock(self) -> bool:
567
578
  return self._calculationWidget.isModeLock()
@@ -575,15 +586,25 @@ class AxisSettingsTabWidget(qt.QTabWidget):
575
586
  def getEstimatedCor(self):
576
587
  return self._calculationWidget.getEstimatedCor()
577
588
 
589
+ def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
590
+ return self._calculationWidget.updateXRotationAxisPixelPositionOnNewScan()
591
+
592
+ def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool):
593
+ self._calculationWidget.setUpdateXRotationAxisPixelPositionOnNewScan(
594
+ update=update
595
+ )
596
+
578
597
  def getMode(self):
579
598
  """Return algorithm to use for axis calculation"""
580
599
  return self._calculationWidget.getMode()
581
600
 
582
- def updateAutomaticallyEstimatedCor(self):
583
- return self._calculationWidget.updateAutomaticallyEstimatedCor()
601
+ def isYAxisInverted(self) -> bool:
602
+ return self._calculationWidget._estimatedCorWidget.isYAxisInverted()
584
603
 
585
- def setUpdateAutomaticallyEstimatedCor(self, value):
586
- self._calculationWidget.setUpdateAutomaticallyEstimatedCor(value)
604
+ def setYAxisInverted(self, checked: bool):
605
+ return self._calculationWidget._estimatedCorWidget.setYAxisInverted(
606
+ checked=checked
607
+ )
587
608
 
588
609
 
589
610
  class _ShiftControl(qt.QWidget):
@@ -131,18 +131,15 @@ class AxisWidget(qt.QMainWindow):
131
131
  if mode is axis_mode.AxisMode.manual:
132
132
  self._setModeLockFrmSettings(False)
133
133
 
134
- def updateAutomaticallyEstimatedCor(self):
135
- return self._settingsWidget.updateAutomaticallyEstimatedCor()
136
-
137
- def setUpdateAutomaticallyEstimatedCor(self, value):
138
- self._settingsWidget.setUpdateAutomaticallyEstimatedCor(value)
139
-
140
134
  def setEstimatedCor(self, value):
141
135
  self._settingsWidget.setEstimatedCor(value=value)
142
136
 
143
137
  def getEstimatedCor(self):
144
138
  return self._settingsWidget.getEstimatedCor()
145
139
 
140
+ def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
141
+ return self._settingsWidget.updateXRotationAxisPixelPositionOnNewScan()
142
+
146
143
  def _setModeLockFrmSettings(self, lock: bool):
147
144
  # only lock the push button
148
145
  with block_signals(self):
@@ -233,9 +230,12 @@ class AxisWidget(qt.QMainWindow):
233
230
 
234
231
  if self._scan is not None:
235
232
  self._scan.axis_params.sigAxisUrlChanged.disconnect(self._updatePlot)
233
+ update_x_rotation_axis_pixel_position = (
234
+ self._settingsWidget._mainWidget.updateXRotationAxisPixelPositionOnNewScan()
235
+ )
236
236
  if (
237
- scan.x_rotation_axis_pixel_position is not None
238
- and self.updateAutomaticallyEstimatedCor()
237
+ update_x_rotation_axis_pixel_position
238
+ and scan.x_rotation_axis_pixel_position is not None
239
239
  ):
240
240
  self.setEstimatedCor(scan.x_rotation_axis_pixel_position)
241
241
 
@@ -495,6 +495,8 @@ class AxisWidget(qt.QMainWindow):
495
495
  if self._imgA is not None and self._imgB is not None:
496
496
  self.setImages(imgA=self._imgA, imgB=self._imgB, flipB=self._flipB)
497
497
 
498
+ # expose API
499
+
498
500
  def getXShift(self):
499
501
  return self._settingsWidget.getXShift()
500
502
 
@@ -524,3 +526,9 @@ class AxisWidget(qt.QMainWindow):
524
526
 
525
527
  def setModeLock(self, mode):
526
528
  return self._settingsWidget.setModeLock(mode=mode)
529
+
530
+ def isYAxisInverted(self) -> bool:
531
+ return self._settingsWidget.isYAxisInverted()
532
+
533
+ def setYAxisInverted(self, checked: bool):
534
+ return self._settingsWidget.setYAxisInverted(checked=checked)
@@ -4,11 +4,13 @@ import logging
4
4
 
5
5
  from silx.gui import qt
6
6
 
7
+ from tomwer.core.scan.scanbase import TomwerScanBase
7
8
  from tomwer.core.process.reconstruction.axis import mode as axis_mode
8
9
  from tomwer.gui.utils.buttons import PadlockButton
9
10
  from tomwer.gui.utils.qt_utils import block_signals
10
11
  from tomwer.synctools.axis import QAxisRP
11
12
  from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel
13
+ from tomwer.gui.reconstruction.axis.EstimatedCORWidget import EstimatedCORWidget
12
14
 
13
15
  _logger = logging.getLogger(__name__)
14
16
 
@@ -24,6 +26,8 @@ class CalculationWidget(qt.QWidget):
24
26
 
25
27
  sigLockModeChanged = qt.Signal(bool)
26
28
  """signal emitted when the mode has been lock or unlock"""
29
+ sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal()
30
+ sigYAxisInvertedChanged = qt.Signal(bool)
27
31
 
28
32
  def __init__(self, parent, axis_params):
29
33
  assert isinstance(axis_params, QAxisRP)
@@ -31,6 +35,7 @@ class CalculationWidget(qt.QWidget):
31
35
  self._axis_params = None
32
36
  self.setLayout(qt.QVBoxLayout())
33
37
 
38
+ # algorithm
34
39
  self._modeWidget = qt.QWidget(parent=self)
35
40
  self._modeWidget.setLayout(qt.QHBoxLayout())
36
41
  self.layout().addWidget(self._modeWidget)
@@ -53,9 +58,9 @@ class CalculationWidget(qt.QWidget):
53
58
  axis_mode.AxisMode.growing_window_sinogram,
54
59
  axis_mode.AxisMode.sino_coarse_to_fine,
55
60
  axis_mode.AxisMode.sliding_window_sinogram,
56
- axis_mode.AxisMode.sino_fourier_angles,
61
+ axis_mode.AxisMode.fourier_angles,
57
62
  ),
58
- # composite corase to fine
63
+ # composite coarse to fine
59
64
  (
60
65
  axis_mode.AxisMode.composite_coarse_to_fine,
61
66
  axis_mode.AxisMode.near,
@@ -91,181 +96,52 @@ class CalculationWidget(qt.QWidget):
91
96
  )
92
97
  self._modeWidget.layout().addWidget(self._lockMethodPB)
93
98
 
94
- self._optsWidget = qt.QWidget(self)
95
- self._optsWidget.setLayout(qt.QVBoxLayout())
96
- self.layout().addWidget(self._optsWidget)
97
-
98
- # padding option
99
- self._padding_widget = qt.QGroupBox("padding mode")
100
- self._padding_widget.setCheckable(True)
101
- self._optsWidget.layout().addWidget(self._padding_widget)
102
- self._padding_widget.setLayout(qt.QHBoxLayout())
103
-
104
- self._qbPaddingMode = QComboBoxIgnoreWheel(self._padding_widget)
105
- for _mode in (
106
- "constant",
107
- "edge",
108
- "linear_ramp",
109
- "maximum",
110
- "mean",
111
- "median",
112
- "minimum",
113
- "reflect",
114
- "symmetric",
115
- "wrap",
116
- ):
117
- self._qbPaddingMode.addItem(_mode)
118
- def_index = self._qbPaddingMode.findText("edge")
119
- self._qbPaddingMode.setCurrentIndex(def_index)
120
- self._padding_widget.layout().addWidget(self._qbPaddingMode)
121
-
122
- # side option
123
- self._sideWidget = qt.QWidget(self)
124
- self._sideWidget.setLayout(qt.QHBoxLayout())
125
- self._optsWidget.layout().addWidget(self._sideWidget)
126
- self._sideWidget.layout().addWidget(qt.QLabel("side:", self))
127
- self._sideCB = QComboBoxIgnoreWheel(self._optsWidget)
128
- self._sideWidget.layout().addWidget(self._sideCB)
129
- self._sideCB.setToolTip(
130
- "Define a side for the sliding and growing" "window algorithms"
131
- )
132
-
133
- # near mode options
134
- self._nearOptsWidget = qt.QWidget(parent=self)
135
- self._nearOptsWidget.setLayout(qt.QVBoxLayout())
136
- self._optsWidget.layout().addWidget(self._nearOptsWidget)
137
-
138
- # near value lock button
139
- self._nearValueCB = qt.QCheckBox(
140
- "Update automatically if `x_rotation_axis_pixel_position` found"
141
- )
142
- self._nearValueCB.setToolTip(
143
- "If the acquisition contains an "
144
- "estimation of the COR value then "
145
- "will set it automatically as estimated "
146
- "value."
147
- )
148
- self._nearOptsWidget.layout().addWidget(self._nearValueCB)
149
-
150
- # LineEdit position value
151
- self._qleValueW = qt.QWidget(self._nearOptsWidget)
152
- self._qleValueW.setLayout(qt.QFormLayout())
153
- self._nearOptsWidget.layout().addWidget(self._qleValueW)
154
-
155
- self._qleNearPosQLE = qt.QLineEdit("0", self._nearOptsWidget)
156
- validator = qt.QDoubleValidator(self._qleNearPosQLE)
157
- self._qleNearPosQLE.setValidator(validator)
158
- self._qleValueW.layout().addRow(
159
- "estimated value (in relative):", self._qleNearPosQLE
160
- )
161
-
162
- # cor_options
163
- self._corOptsWidget = qt.QWidget(self)
164
- self._corOptsWidget.setLayout(qt.QHBoxLayout())
165
- self._corOpts = qt.QLineEdit(self)
166
- self._corOpts.setToolTip(
167
- "Options for methods finding automatically the rotation axis position. 'side', 'near_pos' and 'near_width' are already provided by dedicated interface. The parameters are separated by commas and passed as 'name=value'. Mind the semicolon separator (;)."
168
- )
169
- self._corOpts.setPlaceholderText("low_pass=1; high_pass=20")
170
- self._corOptsWidget.layout().addWidget(qt.QLabel("cor advanced options"))
171
- self._corOptsWidget.layout().addWidget(self._corOpts)
172
- self._optsWidget.layout().addWidget(self._corOptsWidget)
99
+ # estimated cor
100
+ self._estimatedCorWidget = EstimatedCORWidget(self, axis_params=axis_params)
101
+ self.layout().addWidget(self._estimatedCorWidget)
173
102
 
174
103
  # connect signal / slot
175
104
  self._qcbPosition.currentIndexChanged.connect(self._modeChanged)
176
- self._qleNearPosQLE.editingFinished.connect(self._nearValueChanged)
177
- self._sideCB.currentTextChanged.connect(self._sideChanged)
178
105
  self._lockMethodPB.sigLockChanged.connect(self.lockMode)
179
- self._qbPaddingMode.currentIndexChanged.connect(self._paddingModeChanged)
180
- self._padding_widget.toggled.connect(self._paddingModeChanged)
181
- self._corOpts.editingFinished.connect(self._corOptsChanged)
106
+ self._estimatedCorWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect(
107
+ self.sigUpdateXRotAxisPixelPosOnNewScan
108
+ )
109
+ self._estimatedCorWidget.sigYAxisInvertedChanged.connect(
110
+ self.sigYAxisInvertedChanged
111
+ )
182
112
 
183
113
  # set up interface
184
- self._sideWidget.setVisible(False)
114
+ self._estimatedCorWidget._updateVisibleSides(mode=self.getMode())
185
115
  self.setAxisParams(axis_params)
186
- self._nearValueCB.setChecked(True)
187
- self._nearOptsWidget.setHidden(True)
188
116
 
189
117
  def getMethodLockPB(self) -> qt.QPushButton:
190
118
  return self._lockMethodPB
191
119
 
192
120
  def setEstimatedCorValue(self, value):
193
- if value is not None:
194
- self._qleNearPosQLE.setText(str(value))
195
- # note: keep self._axis_params up to date.
196
- if self._axis_params:
197
- self._axis_params.estimated_cor = value
121
+ self._estimatedCorWidget.setEstimatedCor(value=value)
122
+ # note: force to update the side values.
123
+ self._estimatedCorWidget._updateVisibleSides(mode=self.getMode())
198
124
 
199
125
  def getEstimatedCor(self):
200
- try:
201
- return float(self._qleNearPosQLE.text())
202
- except ValueError:
203
- return 0
204
-
205
- def updateAutomaticallyEstimatedCor(self):
206
- return self._nearValueCB.isChecked()
126
+ return self._estimatedCorWidget.getEstimatedCor()
207
127
 
208
- def setUpdateAutomaticallyEstimatedCor(self, checked):
209
- self._nearValueCB.setChecked(checked)
128
+ def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
129
+ return self._estimatedCorWidget.updateXRotationAxisPixelPositionOnNewScan()
210
130
 
211
- def setSide(self, side):
212
- if side is not None:
213
- idx = self._sideCB.findText(side)
214
- if idx >= 0:
215
- self._sideCB.setCurrentIndex(idx)
216
-
217
- def getSide(self):
218
- return self._sideCB.currentText()
131
+ def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool):
132
+ self._estimatedCorWidget.setUpdateXRotationAxisPixelPositionOnNewScan(
133
+ update=update
134
+ )
219
135
 
220
136
  def _modeChanged(self, *args, **kwargs):
221
137
  mode = self.getMode()
222
138
  with block_signals(self._qcbPosition):
223
139
  with block_signals(self._axis_params):
224
- self._corOptsWidget.setVisible(
225
- mode
226
- not in (
227
- axis_mode.AxisMode.manual,
228
- axis_mode.AxisMode.read,
229
- )
230
- )
231
-
232
- self._padding_widget.setVisible(
233
- axis_mode.AXIS_MODE_METADATAS[mode].allows_padding
234
- )
235
- if axis_mode.AXIS_MODE_METADATAS[mode].is_lockable:
236
- self._lockMethodPB.setVisible(True)
237
- else:
238
- self._lockMethodPB.setVisible(False)
239
- self.lockMode(False)
240
-
241
- sides_visible = len(axis_mode.AXIS_MODE_METADATAS[mode].valid_sides) > 0
242
- self._sideWidget.setVisible(sides_visible)
243
- if sides_visible is True:
244
- self._updateSideVisible(mode)
245
- self._nearOptsWidget.setVisible(self.getSide() == "near")
140
+ self._estimatedCorWidget._updateVisibleSides(mode)
246
141
  self._axis_params.mode = mode.value
247
142
  self._axis_params.changed()
248
143
  self.sigModeChanged.emit(mode.value)
249
144
 
250
- def _updateSideVisible(self, mode: axis_mode.AxisMode):
251
- mode = axis_mode.AxisMode.from_value(mode)
252
- if len(axis_mode.AXIS_MODE_METADATAS[mode].valid_sides) == 0:
253
- return
254
- else:
255
- current_value = self._axis_params.side
256
- with block_signals(self._sideCB):
257
- self._sideCB.clear()
258
- values = axis_mode.AXIS_MODE_METADATAS[mode].valid_sides
259
- for value in values:
260
- self._sideCB.addItem(value)
261
- idx = self._sideCB.findText(current_value)
262
- if idx == -1:
263
- # if side doesn't exists, propose right as default when possible
264
- idx = self._sideCB.findText("right")
265
- if idx >= 0:
266
- self._sideCB.setCurrentIndex(idx)
267
- self._axis_params.side = self.getSide()
268
-
269
145
  def isModeLock(self):
270
146
  return self._lockMethodPB.isLocked()
271
147
 
@@ -303,7 +179,7 @@ class CalculationWidget(qt.QWidget):
303
179
  """Return algorithm to use for axis calculation"""
304
180
  return axis_mode.AxisMode.from_value(self._qcbPosition.currentText())
305
181
 
306
- def setMode(self, mode):
182
+ def setMode(self, mode: axis_mode.AxisMode):
307
183
  with block_signals(self._qcbPosition):
308
184
  index = self._qcbPosition.findText(mode.value)
309
185
  if index >= 0:
@@ -311,43 +187,13 @@ class CalculationWidget(qt.QWidget):
311
187
  else:
312
188
  raise ValueError("Unable to find mode", mode)
313
189
  self._lockMethodPB.setVisible(mode not in (axis_mode.AxisMode.manual,))
314
-
315
- def _nearValueChanged(self, *args, **kwargs):
316
- self._axis_params.estimated_cor = self.getEstimatedCor()
317
-
318
- def _paddingModeChanged(self, *args, **kwargs):
319
- self._axis_params.padding_mode = self.getPaddingMode()
320
-
321
- def _corOptsChanged(self, *args, **kwargs):
322
- self._axis_params.extra_cor_options = self.getCorOptions()
323
-
324
- def _sideChanged(self, *args, **kwargs):
325
- side = self.getSide()
326
- if side not in ("", None):
327
- self._axis_params.side = side
328
- self._nearOptsWidget.setVisible(side == "near")
329
-
330
- def getCorOptions(self):
331
- return self._corOpts.text()
332
-
333
- def setCorOptions(self, opts: str | None):
334
- with block_signals(self._axis_params):
335
- self._corOpts.clear()
336
- if opts:
337
- self._corOpts.setText(opts)
338
- self._corOptsChanged()
339
-
340
- def getPaddingMode(self):
341
- if self._padding_widget.isChecked():
342
- return self._qbPaddingMode.currentText()
343
- else:
344
- return None
345
-
346
- def setPaddingMode(self, mode):
347
- index = self._qbPaddingMode.findText(mode)
348
- if index >= 0:
349
- self._qbPaddingMode.setCurrentIndex(index)
350
- self._paddingModeChanged()
190
+ mode_metadata = axis_mode.AXIS_MODE_METADATAS[mode]
191
+ estimated_cor_widget_visible = (
192
+ mode_metadata.allows_estimated_cor_as_numerical_value
193
+ or len(mode_metadata.valid_sides) > 0
194
+ )
195
+ self._estimatedCorWidget.setVisible(estimated_cor_widget_visible)
196
+ self._estimatedCorWidget._updateVisibleSides(mode=mode)
351
197
 
352
198
  def setAxisParams(self, axis):
353
199
  with block_signals(self):
@@ -359,16 +205,10 @@ class CalculationWidget(qt.QWidget):
359
205
  self._axis_params.mode = axis_mode.AxisMode.growing_window_radios
360
206
  self._axis_params.sigChanged.connect(self._axis_params_changed)
361
207
  self._axis_params_changed()
362
- self._sideChanged()
363
208
 
364
209
  def _axis_params_changed(self, *args, **kwargs):
365
210
  self.setMode(self._axis_params.mode)
366
- self.setEstimatedCorValue(self._axis_params.estimated_cor)
367
- self.setSide(self._axis_params.side)
368
- sides_visible = (
369
- len(axis_mode.AXIS_MODE_METADATAS[self._axis_params.mode].valid_sides) > 0
370
- )
371
- self._sideWidget.setVisible(sides_visible)
372
- self._updateSideVisible(mode=self._axis_params.mode)
373
- self.setPaddingMode(self._axis_params.padding_mode)
374
- self.setCorOptions(self._axis_params.extra_cor_options)
211
+
212
+ def setScan(self, scan: TomwerScanBase | None):
213
+ self._estimatedCorWidget.setPixelSize(pixel_size_m=scan.x_pixel_size)
214
+ self._estimatedCorWidget.setImageWidth(image_width=scan.dim_1)
@@ -5,6 +5,10 @@ import numpy
5
5
 
6
6
  from silx.gui import qt
7
7
 
8
+ from tomwer.core.process.reconstruction.utils.cor import (
9
+ absolute_pos_to_relative,
10
+ relative_pos_to_absolute,
11
+ )
8
12
  from tomwer.gui.utils.buttons import PadlockButton
9
13
  from tomwer.gui.settings import EDITING_BACKGROUND_COLOR
10
14
  from tomwer.synctools.axis import QAxisRP
@@ -263,7 +267,9 @@ class _PositionInfoWidget(qt.QWidget):
263
267
  except Exception:
264
268
  return
265
269
  else:
266
- abs_value = float(rel_value) + (width - 1) / 2.0
270
+ abs_value = relative_pos_to_absolute(
271
+ relative_pos=float(rel_value), det_width=width
272
+ )
267
273
  self._absolutePositionQLE.setText(str(abs_value))
268
274
 
269
275
  def _updateRelativePosition(self, width):
@@ -273,5 +279,7 @@ class _PositionInfoWidget(qt.QWidget):
273
279
  except Exception:
274
280
  return
275
281
  else:
276
- rel_value = float(abs_value) - (width - 1) / 2.0
282
+ rel_value = absolute_pos_to_relative(
283
+ absolute_pos=float(abs_value), det_width=width
284
+ )
277
285
  self._relativePositionQLE.setText(str(rel_value))