tomwer 1.4.0__py3-none-any.whl → 1.4.0rc0__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.
- orangecontrib/tomwer/tutorials/test_cor.ows +3 -3
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +14 -6
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +2 -4
- tomwer/app/axis.py +3 -0
- tomwer/app/multipag.py +3 -11
- tomwer/core/process/reconstruction/axis/axis.py +736 -27
- tomwer/core/process/reconstruction/axis/mode.py +24 -86
- tomwer/core/process/reconstruction/axis/params.py +138 -127
- tomwer/core/process/reconstruction/nabu/nabuscores.py +22 -19
- tomwer/core/process/reconstruction/nabu/nabuslices.py +1 -5
- tomwer/core/process/reconstruction/saaxis/saaxis.py +4 -4
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +4 -4
- tomwer/core/process/reconstruction/tests/test_axis.py +1 -1
- tomwer/core/process/reconstruction/tests/test_utils.py +4 -4
- tomwer/core/process/reconstruction/utils/cor.py +4 -8
- tomwer/core/process/tests/test_axis.py +231 -0
- tomwer/core/process/tests/test_nabu.py +3 -1
- tomwer/core/scan/nxtomoscan.py +0 -2
- tomwer/core/scan/scanbase.py +4 -4
- tomwer/core/scan/tests/test_process_registration.py +18 -0
- tomwer/gui/reconstruction/axis/AxisMainWindow.py +9 -20
- tomwer/gui/reconstruction/axis/AxisOptionsWidget.py +79 -239
- tomwer/gui/reconstruction/axis/AxisSettingsWidget.py +17 -38
- tomwer/gui/reconstruction/axis/AxisWidget.py +8 -16
- tomwer/gui/reconstruction/axis/CalculationWidget.py +200 -44
- tomwer/gui/reconstruction/axis/ControlWidget.py +2 -10
- tomwer/gui/reconstruction/axis/InputWidget.py +155 -11
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +10 -19
- tomwer/gui/reconstruction/scores/scoreplot.py +2 -5
- tomwer/gui/reconstruction/tests/test_nabu.py +0 -8
- tomwer/gui/stitching/config/axisparams.py +0 -2
- tomwer/gui/stitching/z_stitching/fineestimation.py +1 -1
- tomwer/gui/tests/test_axis_gui.py +15 -31
- tomwer/synctools/stacks/reconstruction/axis.py +23 -5
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +1 -1
- tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
- tomwer/synctools/stacks/reconstruction/normalization.py +1 -1
- tomwer/synctools/stacks/reconstruction/saaxis.py +1 -1
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +1 -1
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py +16 -0
- tomwer/tests/test_ewoks/test_single_node_execution.py +1 -1
- tomwer/tests/test_ewoks/test_workflows.py +1 -1
- tomwer/version.py +1 -1
- {tomwer-1.4.0.dist-info → tomwer-1.4.0rc0.dist-info}/METADATA +3 -3
- {tomwer-1.4.0.dist-info → tomwer-1.4.0rc0.dist-info}/RECORD +49 -52
- tomwer/core/process/reconstruction/axis/side.py +0 -8
- tomwer/gui/fonts.py +0 -5
- tomwer/gui/reconstruction/axis/EstimatedCORWidget.py +0 -394
- tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py +0 -118
- {tomwer-1.4.0.dist-info → tomwer-1.4.0rc0.dist-info}/LICENSE +0 -0
- {tomwer-1.4.0.dist-info → tomwer-1.4.0rc0.dist-info}/WHEEL +0 -0
- {tomwer-1.4.0.dist-info → tomwer-1.4.0rc0.dist-info}/entry_points.txt +0 -0
- {tomwer-1.4.0.dist-info → tomwer-1.4.0rc0.dist-info}/top_level.txt +0 -0
@@ -2,17 +2,9 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from silx.gui import qt
|
4
4
|
|
5
|
-
from tomwer.core.process.reconstruction.axis.mode import AxisMode, AXIS_MODE_METADATAS
|
6
5
|
from tomwer.synctools.axis import QAxisRP
|
7
6
|
from tomwer.core.process.reconstruction.axis.params import AxisCalculationInput
|
8
7
|
from tomwer.gui.utils.qt_utils import block_signals
|
9
|
-
from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel, QSpinBoxIgnoreWheel
|
10
|
-
from tomwer.core.process.reconstruction.axis.params import (
|
11
|
-
DEFAULT_CMP_N_SUBSAMPLING_Y,
|
12
|
-
DEFAULT_CMP_OVERSAMPLING,
|
13
|
-
DEFAULT_CMP_TAKE_LOG,
|
14
|
-
DEFAULT_CMP_THETA,
|
15
|
-
)
|
16
8
|
|
17
9
|
|
18
10
|
class AxisOptionsWidget(qt.QWidget):
|
@@ -22,50 +14,12 @@ class AxisOptionsWidget(qt.QWidget):
|
|
22
14
|
Used as a tab of the AxisSettingsTabWidget
|
23
15
|
"""
|
24
16
|
|
25
|
-
sigChanged = qt.Signal()
|
26
|
-
"""Emit when the options changed"""
|
27
|
-
|
28
17
|
def __init__(self, parent, axis_params):
|
29
18
|
qt.QWidget.__init__(self, parent=parent)
|
30
19
|
assert isinstance(axis_params, QAxisRP)
|
31
20
|
self._axis_params = axis_params
|
32
21
|
self.setLayout(qt.QVBoxLayout())
|
33
22
|
|
34
|
-
# cor_options
|
35
|
-
self._corOptsWidget = qt.QWidget(self)
|
36
|
-
self._corOptsWidget.setLayout(qt.QFormLayout())
|
37
|
-
self._corOpts = qt.QLineEdit(self)
|
38
|
-
self._corOpts.setToolTip(
|
39
|
-
"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 (;)."
|
40
|
-
)
|
41
|
-
self._corOpts.setPlaceholderText("low_pass=1; high_pass=20")
|
42
|
-
self._corOptsWidget.layout().addRow("cor advanced options", self._corOpts)
|
43
|
-
self.layout().addWidget(self._corOptsWidget)
|
44
|
-
|
45
|
-
# padding option
|
46
|
-
self._padding_widget = qt.QGroupBox("padding mode")
|
47
|
-
self._padding_widget.setCheckable(True)
|
48
|
-
self.layout().addWidget(self._padding_widget)
|
49
|
-
self._padding_widget.setLayout(qt.QHBoxLayout())
|
50
|
-
|
51
|
-
self._qbPaddingMode = QComboBoxIgnoreWheel(self._padding_widget)
|
52
|
-
for _mode in (
|
53
|
-
"constant",
|
54
|
-
"edge",
|
55
|
-
"linear_ramp",
|
56
|
-
"maximum",
|
57
|
-
"mean",
|
58
|
-
"median",
|
59
|
-
"minimum",
|
60
|
-
"reflect",
|
61
|
-
"symmetric",
|
62
|
-
"wrap",
|
63
|
-
):
|
64
|
-
self._qbPaddingMode.addItem(_mode)
|
65
|
-
def_index = self._qbPaddingMode.findText("edge")
|
66
|
-
self._qbPaddingMode.setCurrentIndex(def_index)
|
67
|
-
self._padding_widget.layout().addWidget(self._qbPaddingMode)
|
68
|
-
|
69
23
|
# define common options
|
70
24
|
self._commonOpts = qt.QWidget(parent=self)
|
71
25
|
self._commonOpts.setLayout(qt.QFormLayout())
|
@@ -76,75 +30,39 @@ class AxisOptionsWidget(qt.QWidget):
|
|
76
30
|
self._qcbDataMode.addItem(data_mode.name(), data_mode)
|
77
31
|
self._qcbDataMode.hide()
|
78
32
|
|
33
|
+
# add scale option
|
34
|
+
self._scaleOpt = qt.QCheckBox(parent=self)
|
35
|
+
self._commonOpts.layout().addRow("scale the two images", self._scaleOpt)
|
79
36
|
self.layout().addWidget(self._commonOpts)
|
80
37
|
|
81
|
-
#
|
82
|
-
self.
|
83
|
-
|
84
|
-
)
|
85
|
-
self.layout().addWidget(self._compositeOptsGroup)
|
38
|
+
# add near options
|
39
|
+
self._nearOpts = _AxisNearOptsWidget(parent=self, axis_params=self._axis_params)
|
40
|
+
self.layout().addWidget(self._nearOpts)
|
86
41
|
|
87
42
|
# set up
|
88
43
|
self.setCalculationInputType(self._axis_params.calculation_input_type)
|
89
|
-
self._compositeOptsGroup.setVisible(
|
90
|
-
self._axis_params.mode in (AxisMode.near, AxisMode.composite_coarse_to_fine)
|
91
|
-
)
|
92
44
|
|
93
45
|
# connect signal / slot
|
94
|
-
self.
|
46
|
+
self._scaleOpt.toggled.connect(self._updateScaleOpt)
|
95
47
|
self._qcbDataMode.currentIndexChanged.connect(self._updateInputType)
|
96
|
-
self._axis_params.sigChanged.connect(self.
|
97
|
-
self._qbPaddingMode.currentIndexChanged.connect(self._paddingModeChanged)
|
98
|
-
self._padding_widget.toggled.connect(self._paddingModeChanged)
|
99
|
-
self._compositeOptsGroup.sigChanged.connect(self.sigChanged)
|
48
|
+
self._axis_params.sigChanged.connect(self._updateMode)
|
100
49
|
|
101
|
-
def
|
50
|
+
def _updateMode(self):
|
102
51
|
with block_signals(self):
|
103
|
-
# update according to AxisCalculationInput
|
104
52
|
index = self._qcbDataMode.findText(
|
105
53
|
self._axis_params.calculation_input_type.name()
|
106
54
|
)
|
107
55
|
if index >= 0:
|
108
56
|
self._qcbDataMode.setCurrentIndex(index)
|
109
|
-
# update advanced cor options visibility (not relevant if mode is manual or read)
|
110
|
-
axis_mode = self._axis_params.mode
|
111
|
-
self._corOptsWidget.setVisible(
|
112
|
-
axis_mode
|
113
|
-
not in (
|
114
|
-
AxisMode.manual,
|
115
|
-
AxisMode.read,
|
116
|
-
)
|
117
|
-
)
|
118
|
-
# update cor options value
|
119
|
-
self.setCorOptions(self._axis_params.extra_cor_options)
|
120
|
-
self.setPaddingMode(self._axis_params.padding_mode)
|
121
|
-
self._padding_widget.setVisible(
|
122
|
-
AXIS_MODE_METADATAS[axis_mode].allows_padding
|
123
|
-
)
|
124
|
-
|
125
|
-
def _updateInputType(self, *arg, **kwargs):
|
126
|
-
self._axis_params.calculation_input_type = self.getCalculationInputType()
|
127
|
-
self.sigChanged.emit()
|
128
|
-
|
129
|
-
def _paddingModeChanged(self, *args, **kwargs):
|
130
|
-
self._axis_params.padding_mode = self.getPaddingMode()
|
131
|
-
self.sigChanged.emit()
|
132
57
|
|
133
|
-
def
|
134
|
-
|
135
|
-
return self._qbPaddingMode.currentText()
|
136
|
-
else:
|
137
|
-
return None
|
58
|
+
def _updateScaleOpt(self, *arg, **kwargs):
|
59
|
+
self._axis_params.scale_img2_to_img1 = self.isImageScaled()
|
138
60
|
|
139
|
-
def
|
140
|
-
|
141
|
-
if index >= 0:
|
142
|
-
self._qbPaddingMode.setCurrentIndex(index)
|
143
|
-
self._paddingModeChanged()
|
61
|
+
def isImageScaled(self):
|
62
|
+
return self._scaleOpt.isChecked()
|
144
63
|
|
145
|
-
def
|
146
|
-
self._axis_params.
|
147
|
-
self.sigChanged.emit()
|
64
|
+
def _updateInputType(self, *arg, **kwargs):
|
65
|
+
self._axis_params.calculation_input_type = self.getCalculationInputType()
|
148
66
|
|
149
67
|
def getCalculationInputType(self, *arg, **kwargs):
|
150
68
|
return AxisCalculationInput.from_value(self._qcbDataMode.currentText())
|
@@ -155,159 +73,81 @@ class AxisOptionsWidget(qt.QWidget):
|
|
155
73
|
self._qcbDataMode.setCurrentIndex(index_dm)
|
156
74
|
|
157
75
|
def setAxisParams(self, axis):
|
76
|
+
self._nearOpts.setAxisParams(axis=axis)
|
158
77
|
self._axis_params = axis
|
159
78
|
with block_signals(self):
|
79
|
+
self._scaleOpt.setChecked(axis.scale_img2_to_img1)
|
160
80
|
index = self._qcbDataMode.findText(axis.calculation_input_type.name())
|
161
81
|
self._qcbDataMode.setCurrentIndex(index)
|
162
|
-
self._compositeOptsGroup.setAxisParams(axis)
|
163
82
|
|
164
|
-
def getCorOptions(self):
|
165
|
-
return self._corOpts.text()
|
166
83
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
84
|
+
class _AxisNearOptsWidget(qt.QWidget):
|
85
|
+
"""GUI dedicated to the near options"""
|
86
|
+
|
87
|
+
def __init__(self, parent, axis_params):
|
88
|
+
qt.QWidget.__init__(self, parent=parent)
|
89
|
+
assert isinstance(axis_params, QAxisRP)
|
90
|
+
self._axis_params = axis_params
|
91
|
+
|
92
|
+
self.setLayout(qt.QFormLayout())
|
93
|
+
|
94
|
+
self._stdMaxOpt = qt.QCheckBox(parent=self)
|
95
|
+
self.layout().addRow("look at max standard deviation", self._stdMaxOpt)
|
173
96
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
)
|
179
|
-
self._compositeOptsGroup.setVisible(composite_opts_visible)
|
97
|
+
self._nearWX = qt.QSpinBox(parent=self)
|
98
|
+
self._nearWX.setMinimum(1)
|
99
|
+
self._nearWX.setValue(5)
|
100
|
+
self.layout().addRow("window size", self._nearWX)
|
180
101
|
|
102
|
+
self._fineStepX = qt.QDoubleSpinBox(parent=self)
|
103
|
+
self._fineStepX.setMinimum(0.05)
|
104
|
+
self._fineStepX.setSingleStep(0.05)
|
105
|
+
self._fineStepX.setMaximum(1.0)
|
106
|
+
self.layout().addRow("fine step x", self._fineStepX)
|
181
107
|
|
182
|
-
|
183
|
-
|
108
|
+
# connect signal / Slot
|
109
|
+
self._stdMaxOpt.toggled.connect(self._lookForStxMaxChanged)
|
110
|
+
self._nearWX.valueChanged.connect(self._windowSizeChanged)
|
111
|
+
self._fineStepX.valueChanged.connect(self._fineStepXChanged)
|
184
112
|
|
185
|
-
|
186
|
-
|
113
|
+
def _lookForStxMaxChanged(self, *args, **kwargs):
|
114
|
+
self._axis_params.look_at_stdmax = self.isLookAtStdMax()
|
187
115
|
|
188
|
-
def
|
189
|
-
|
190
|
-
super().__init__(title, parent)
|
191
|
-
## options for the composite mode
|
192
|
-
self.setLayout(qt.QFormLayout())
|
193
|
-
self.layout().setContentsMargins(0, 0, 0, 0)
|
194
|
-
|
195
|
-
self._thetaSB = QSpinBoxIgnoreWheel(self)
|
196
|
-
self._thetaSB.setRange(0, 360)
|
197
|
-
self._thetaSB.setValue(DEFAULT_CMP_THETA)
|
198
|
-
self._thetaSB.setToolTip("a radio will be picked each theta degrees")
|
199
|
-
self._thetaLabel = qt.QLabel("angle interval (in degree)", self)
|
200
|
-
self._thetaLabel.setToolTip(
|
201
|
-
"algorithm will take one projection each 'angle interval'. Also know as 'theta'"
|
202
|
-
)
|
203
|
-
self.layout().addRow(self._thetaLabel, self._thetaSB)
|
204
|
-
|
205
|
-
self._oversamplingSB = QSpinBoxIgnoreWheel(self)
|
206
|
-
self._oversamplingSB.setRange(1, 999999)
|
207
|
-
self._oversamplingSB.setValue(DEFAULT_CMP_OVERSAMPLING)
|
208
|
-
self._oversamplingSB.setToolTip("sinogram oversampling")
|
209
|
-
self.layout().addRow("oversampling", self._oversamplingSB)
|
210
|
-
|
211
|
-
self._nearWidthSB = QSpinBoxIgnoreWheel(self)
|
212
|
-
self._nearWidthSB.setRange(1, 999999)
|
213
|
-
self._nearWidthSB.setValue(0)
|
214
|
-
self._nearWidthSB.setToolTip("position to be used with near option")
|
215
|
-
self._nearWidthLabel = qt.QLabel("near width", self)
|
216
|
-
self._nearWidthLabel.setToolTip("position to be used with near option")
|
217
|
-
self.layout().addRow(self._nearWidthLabel, self._nearWidthSB)
|
218
|
-
|
219
|
-
self._subsamplingYSB = QSpinBoxIgnoreWheel(self)
|
220
|
-
self._subsamplingYSB.setRange(1, 999999)
|
221
|
-
self._subsamplingYSB.setValue(DEFAULT_CMP_N_SUBSAMPLING_Y)
|
222
|
-
self._subsamplingYSB.setToolTip("sinogram number of subsampling along y")
|
223
|
-
self.layout().addRow("n_subsampling_y", self._subsamplingYSB)
|
224
|
-
|
225
|
-
self._takeLogCB = qt.QCheckBox(self)
|
226
|
-
self._takeLogCB.setToolTip("Take logarithm")
|
227
|
-
self._takeLogCB.setChecked(DEFAULT_CMP_TAKE_LOG)
|
228
|
-
self._takeTheLogLabel = qt.QLabel("linearisation (-log(I/I0))")
|
229
|
-
self._takeTheLogLabel.setToolTip(
|
230
|
-
"take (-log(I/I0)) as input. Also know as 'take_log' option"
|
231
|
-
)
|
232
|
-
self.layout().addRow(self._takeTheLogLabel, self._takeLogCB)
|
116
|
+
def isLookAtStdMax(self) -> bool:
|
117
|
+
"""
|
233
118
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
self.
|
238
|
-
self._nearWidthSB.valueChanged.connect(self._changed)
|
239
|
-
self._takeLogCB.toggled.connect(self._changed)
|
119
|
+
:return: is the option for looking at max standard deviation is
|
120
|
+
activated
|
121
|
+
"""
|
122
|
+
return self._stdMaxOpt.isChecked()
|
240
123
|
|
241
|
-
def
|
242
|
-
|
243
|
-
self.setConfiguration(axis_params.composite_options)
|
244
|
-
self._axis_params = axis_params
|
124
|
+
def _windowSizeChanged(self, *args, **kwargs):
|
125
|
+
self._axis_params.near_wx = self.getWindowSize()
|
245
126
|
|
246
|
-
def
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
self.
|
262
|
-
|
263
|
-
def
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
self._subsamplingYSB.setValue(subsampling)
|
274
|
-
|
275
|
-
def getTakeLog(self) -> bool:
|
276
|
-
return self._takeLogCB.isChecked()
|
277
|
-
|
278
|
-
def setTakeLog(self, log: bool) -> None:
|
279
|
-
self._takeLogCB.setChecked(log)
|
280
|
-
|
281
|
-
def getConfiguration(self) -> dict:
|
282
|
-
|
283
|
-
return {
|
284
|
-
"theta": self.getTheta(),
|
285
|
-
"oversampling": self.getOversampling(),
|
286
|
-
"n_subsampling_y": self.getSubSamplingY(),
|
287
|
-
"take_log": self.getTakeLog(),
|
288
|
-
"near_width": self.getNearWidth(),
|
289
|
-
}
|
290
|
-
|
291
|
-
def setConfiguration(self, opts: dict) -> None:
|
292
|
-
if not isinstance(opts, dict):
|
293
|
-
raise TypeError("opts should be an instance of dict")
|
294
|
-
# theta
|
295
|
-
theta = opts.get("theta", None)
|
296
|
-
if theta is not None:
|
297
|
-
self.setTheta(theta=theta)
|
298
|
-
# oversampling
|
299
|
-
oversampling = opts.get("oversampling", None)
|
300
|
-
if oversampling is not None:
|
301
|
-
self.setOversampling(oversampling)
|
302
|
-
# n subsampling y
|
303
|
-
n_subsampling_y = opts.get("n_subsampling_y", None)
|
304
|
-
if n_subsampling_y is not None:
|
305
|
-
self.setSubSamplingY(n_subsampling_y)
|
306
|
-
# near_width
|
307
|
-
near_width = opts.get("near_width", None)
|
308
|
-
if near_width is not None:
|
309
|
-
self.setNearWidth(near_width)
|
310
|
-
# take log
|
311
|
-
take_log = opts.get("take_log", None)
|
312
|
-
if take_log is not None:
|
313
|
-
self.setTakeLog(take_log)
|
127
|
+
def getWindowSize(self) -> int:
|
128
|
+
"""
|
129
|
+
|
130
|
+
:return: window size for near search
|
131
|
+
"""
|
132
|
+
return self._nearWX.value()
|
133
|
+
|
134
|
+
def _fineStepXChanged(self, *args, **kwargs):
|
135
|
+
self._axis_params.fine_step_x = self.getFineStepX()
|
136
|
+
|
137
|
+
def getFineStepX(self) -> float:
|
138
|
+
"""
|
139
|
+
|
140
|
+
:return: fine step x for near calculation
|
141
|
+
"""
|
142
|
+
return self._fineStepX.value()
|
143
|
+
|
144
|
+
def setAxisParams(self, axis: QAxisRP):
|
145
|
+
"""
|
146
|
+
|
147
|
+
:param axis: axis to edit
|
148
|
+
"""
|
149
|
+
with block_signals(self):
|
150
|
+
self._axis_params = axis
|
151
|
+
self._stdMaxOpt.setChecked(axis.look_at_stdmax)
|
152
|
+
self._nearWX.setValue(axis.near_wx)
|
153
|
+
self._fineStepX.setValue(axis.fine_step_x)
|
@@ -152,7 +152,6 @@ 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)
|
156
155
|
self._updateAxisView()
|
157
156
|
self._axisParams.sigChanged.emit()
|
158
157
|
|
@@ -231,14 +230,14 @@ class AxisSettingsWidget(qt.QWidget):
|
|
231
230
|
|
232
231
|
# expose API
|
233
232
|
|
234
|
-
def
|
235
|
-
self._mainWidget.
|
233
|
+
def updateAutomaticallyEstimatedCor(self):
|
234
|
+
return self._mainWidget.updateAutomaticallyEstimatedCor()
|
236
235
|
|
237
|
-
def
|
238
|
-
|
236
|
+
def setUpdateAutomaticallyEstimatedCor(self, value):
|
237
|
+
self._mainWidget.setUpdateAutomaticallyEstimatedCor(value)
|
239
238
|
|
240
|
-
def
|
241
|
-
self._mainWidget.
|
239
|
+
def setEstimatedCor(self, value):
|
240
|
+
self._mainWidget.setEstimatedCorValue(value=value)
|
242
241
|
|
243
242
|
def getEstimatedCor(self):
|
244
243
|
return self._mainWidget.getEstimatedCor()
|
@@ -267,12 +266,6 @@ class AxisSettingsWidget(qt.QWidget):
|
|
267
266
|
def setModeLock(self, mode):
|
268
267
|
return self._mainWidget.setModeLock(mode=mode)
|
269
268
|
|
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
|
-
|
276
269
|
|
277
270
|
class ManualAxisSelectionWidget(qt.QWidget):
|
278
271
|
sigResetZoomRequested = qt.Signal()
|
@@ -499,8 +492,6 @@ class AxisSettingsTabWidget(qt.QTabWidget):
|
|
499
492
|
sigModeChanged = qt.Signal(str)
|
500
493
|
"""Signal emit when mode (algorithm) is changed"""
|
501
494
|
|
502
|
-
sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal()
|
503
|
-
|
504
495
|
def __init__(
|
505
496
|
self,
|
506
497
|
recons_params: QAxisRP | None,
|
@@ -526,9 +517,12 @@ class AxisSettingsTabWidget(qt.QTabWidget):
|
|
526
517
|
spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
|
527
518
|
widget.layout().addWidget(spacer)
|
528
519
|
|
520
|
+
self._optionsSA = qt.QScrollArea(parent=self)
|
521
|
+
self._optionsSA.setWidget(self._optionsWidget)
|
529
522
|
self.addTab(self._calculationWidget, "calculation")
|
530
|
-
self.addTab(self.
|
523
|
+
self.addTab(self._optionsSA, "options")
|
531
524
|
# simplify set up. Hide options
|
525
|
+
self._optionsSA.hide()
|
532
526
|
self.addTab(self._inputWidget, "input")
|
533
527
|
|
534
528
|
# set up
|
@@ -538,11 +532,11 @@ class AxisSettingsTabWidget(qt.QTabWidget):
|
|
538
532
|
# connect signal / slot
|
539
533
|
self._calculationWidget.sigLockModeChanged.connect(self.sigLockModeChanged)
|
540
534
|
self.sigModeChanged.connect(self._updatePossibleInput)
|
541
|
-
self.sigModeChanged.connect(self._updatePossibleOptions)
|
542
535
|
self._inputWidget._sigUrlChanged.connect(self._urlChanged)
|
543
536
|
self._calculationWidget.sigModeChanged.connect(self.sigModeChanged)
|
544
|
-
|
545
|
-
|
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
|
546
540
|
)
|
547
541
|
|
548
542
|
def _urlChanged(self):
|
@@ -550,7 +544,6 @@ class AxisSettingsTabWidget(qt.QTabWidget):
|
|
550
544
|
|
551
545
|
def setScan(self, scan):
|
552
546
|
if scan is not None:
|
553
|
-
self._calculationWidget.setScan(scan)
|
554
547
|
self._inputWidget.setScan(scan)
|
555
548
|
|
556
549
|
def setAxisParams(self, axis):
|
@@ -569,10 +562,6 @@ class AxisSettingsTabWidget(qt.QTabWidget):
|
|
569
562
|
self._inputWidget.setEnabled(True)
|
570
563
|
self._inputWidget.setValidInputs(valid_inputs)
|
571
564
|
|
572
|
-
def _updatePossibleOptions(self):
|
573
|
-
mode = self.getMode()
|
574
|
-
self._optionsWidget.setMode(mode)
|
575
|
-
|
576
565
|
# expose API
|
577
566
|
def isModeLock(self) -> bool:
|
578
567
|
return self._calculationWidget.isModeLock()
|
@@ -586,25 +575,15 @@ class AxisSettingsTabWidget(qt.QTabWidget):
|
|
586
575
|
def getEstimatedCor(self):
|
587
576
|
return self._calculationWidget.getEstimatedCor()
|
588
577
|
|
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
|
-
|
597
578
|
def getMode(self):
|
598
579
|
"""Return algorithm to use for axis calculation"""
|
599
580
|
return self._calculationWidget.getMode()
|
600
581
|
|
601
|
-
def
|
602
|
-
return self._calculationWidget.
|
582
|
+
def updateAutomaticallyEstimatedCor(self):
|
583
|
+
return self._calculationWidget.updateAutomaticallyEstimatedCor()
|
603
584
|
|
604
|
-
def
|
605
|
-
|
606
|
-
checked=checked
|
607
|
-
)
|
585
|
+
def setUpdateAutomaticallyEstimatedCor(self, value):
|
586
|
+
self._calculationWidget.setUpdateAutomaticallyEstimatedCor(value)
|
608
587
|
|
609
588
|
|
610
589
|
class _ShiftControl(qt.QWidget):
|
@@ -131,15 +131,18 @@ 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
|
+
|
134
140
|
def setEstimatedCor(self, value):
|
135
141
|
self._settingsWidget.setEstimatedCor(value=value)
|
136
142
|
|
137
143
|
def getEstimatedCor(self):
|
138
144
|
return self._settingsWidget.getEstimatedCor()
|
139
145
|
|
140
|
-
def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
|
141
|
-
return self._settingsWidget.updateXRotationAxisPixelPositionOnNewScan()
|
142
|
-
|
143
146
|
def _setModeLockFrmSettings(self, lock: bool):
|
144
147
|
# only lock the push button
|
145
148
|
with block_signals(self):
|
@@ -230,12 +233,9 @@ class AxisWidget(qt.QMainWindow):
|
|
230
233
|
|
231
234
|
if self._scan is not None:
|
232
235
|
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
|
-
|
238
|
-
and
|
237
|
+
scan.x_rotation_axis_pixel_position is not None
|
238
|
+
and self.updateAutomaticallyEstimatedCor()
|
239
239
|
):
|
240
240
|
self.setEstimatedCor(scan.x_rotation_axis_pixel_position)
|
241
241
|
|
@@ -495,8 +495,6 @@ 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
|
-
|
500
498
|
def getXShift(self):
|
501
499
|
return self._settingsWidget.getXShift()
|
502
500
|
|
@@ -526,9 +524,3 @@ class AxisWidget(qt.QMainWindow):
|
|
526
524
|
|
527
525
|
def setModeLock(self, mode):
|
528
526
|
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)
|