tomwer 1.2.8__py3-none-any.whl → 1.3.0a0__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/icat_publication.ows +58 -0
- orangecontrib/tomwer/widgets/__init__.py +1 -0
- orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
- orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +11 -5
- orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +31 -18
- orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +14 -7
- orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +2 -0
- orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
- orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
- orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
- orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
- orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
- orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
- orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
- orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +9 -8
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +3 -3
- orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +179 -169
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +7 -13
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +7 -17
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +3 -4
- orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
- orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
- tomwer/__main__.py +11 -58
- tomwer/app/canvas.py +8 -0
- tomwer/app/canvas_launcher/config.py +13 -11
- tomwer/app/darkref.py +1 -1
- tomwer/app/darkrefpatch.py +1 -1
- tomwer/app/imagekeyeditor.py +5 -5
- tomwer/app/imagekeyupgrader.py +5 -5
- tomwer/app/intensitynormalization.py +2 -2
- tomwer/app/radiostack.py +2 -2
- tomwer/app/zstitching.py +74 -3
- tomwer/core/cluster/cluster.py +26 -0
- tomwer/core/log/logger.py +7 -5
- tomwer/core/process/conditions/filters.py +1 -1
- tomwer/core/process/control/datalistener/datalistener.py +3 -3
- tomwer/core/process/control/nxtomoconcatenate.py +13 -13
- tomwer/core/process/control/nxtomomill.py +83 -25
- tomwer/core/process/control/scantransfer.py +11 -10
- tomwer/core/process/control/scanvalidator.py +3 -2
- tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
- tomwer/core/process/control/test/test_email.py +4 -4
- tomwer/core/process/control/test/test_h52nx_process.py +59 -7
- tomwer/core/process/control/test/test_volume_link.py +64 -64
- tomwer/core/process/control/timer.py +1 -1
- tomwer/core/process/control/volumesymlink.py +200 -200
- tomwer/core/process/edit/darkflatpatch.py +6 -6
- tomwer/core/process/edit/imagekeyeditor.py +17 -18
- tomwer/core/process/icat/__init__.py +0 -0
- tomwer/core/process/icat/createscreenshots.py +100 -0
- tomwer/core/process/icat/gallery.py +377 -0
- tomwer/core/process/icat/icatbase.py +36 -0
- tomwer/core/process/icat/publish.py +228 -0
- tomwer/core/process/icat/screenshots.py +26 -0
- tomwer/core/process/output.py +52 -0
- tomwer/core/process/reconstruction/axis/axis.py +17 -10
- tomwer/core/process/reconstruction/axis/mode.py +4 -0
- tomwer/core/process/reconstruction/axis/params.py +9 -4
- tomwer/core/process/reconstruction/darkref/darkrefs.py +8 -6
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
- tomwer/core/process/reconstruction/darkref/params.py +1 -1
- tomwer/core/process/reconstruction/lamino/tofu.py +4 -4
- tomwer/core/process/reconstruction/nabu/castvolume.py +1 -1
- tomwer/core/process/reconstruction/nabu/helical.py +9 -5
- tomwer/core/process/reconstruction/nabu/nabucommon.py +32 -62
- tomwer/core/process/reconstruction/nabu/nabuscores.py +387 -61
- tomwer/core/process/reconstruction/nabu/nabuslices.py +33 -21
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +37 -14
- tomwer/core/process/reconstruction/nabu/settings.py +2 -2
- tomwer/core/process/reconstruction/nabu/utils.py +129 -24
- tomwer/core/process/reconstruction/output.py +108 -0
- tomwer/core/process/reconstruction/saaxis/saaxis.py +233 -263
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +140 -86
- tomwer/core/process/reconstruction/scores/params.py +4 -1
- tomwer/core/process/reconstruction/scores/scores.py +13 -0
- tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
- tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
- tomwer/core/process/reconstruction/test/test_darkref_copy.py +3 -3
- tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
- tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
- tomwer/core/process/stitching/nabustitcher.py +2 -2
- tomwer/core/process/test/test_axis.py +6 -6
- tomwer/core/process/test/test_dark_and_flat.py +10 -7
- tomwer/core/process/test/test_data_transfer.py +7 -6
- tomwer/core/process/test/test_nabu.py +4 -4
- tomwer/core/process/test/test_normalization.py +2 -2
- tomwer/core/scan/edfscan.py +4 -1
- tomwer/core/scan/hdf5scan.py +19 -500
- tomwer/core/scan/nxtomoscan.py +532 -0
- tomwer/core/scan/scanbase.py +42 -20
- tomwer/core/scan/scanfactory.py +13 -13
- tomwer/core/scan/test/test_future_scan.py +2 -2
- tomwer/core/scan/test/test_h5.py +12 -10
- tomwer/core/scan/test/test_process_registration.py +2 -2
- tomwer/core/scan/test/test_scan.py +4 -3
- tomwer/core/settings.py +20 -0
- tomwer/core/test/test_scanutils.py +8 -7
- tomwer/core/test/test_utils.py +33 -26
- tomwer/core/utils/__init__.py +0 -466
- tomwer/core/utils/deprecation.py +1 -1
- tomwer/core/utils/dictutils.py +14 -0
- tomwer/core/utils/lbsram.py +35 -0
- tomwer/core/utils/nxtomoutils.py +1 -1
- tomwer/core/utils/scanutils.py +6 -6
- tomwer/core/utils/spec.py +263 -0
- tomwer/core/volume/volumefactory.py +2 -2
- tomwer/gui/cluster/slurm.py +260 -60
- tomwer/gui/cluster/test/test_cluster.py +13 -0
- tomwer/gui/cluster/test/test_supervisor.py +2 -2
- tomwer/gui/configuration/__init__.py +0 -0
- tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
- tomwer/gui/configuration/level.py +22 -0
- tomwer/gui/control/actions.py +54 -0
- tomwer/gui/control/datalist.py +78 -16
- tomwer/gui/control/datalistener.py +4 -16
- tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
- tomwer/gui/control/history.py +2 -2
- tomwer/gui/control/observations.py +2 -2
- tomwer/gui/control/reducedarkflatselector.py +1 -1
- tomwer/gui/control/selectorwidgetbase.py +36 -9
- tomwer/gui/control/serie/seriecreator.py +5 -22
- tomwer/gui/control/test/test_email.py +1 -1
- tomwer/gui/control/test/test_scanvalidator.py +6 -5
- tomwer/gui/control/test/test_single_tomo_obj.py +2 -2
- tomwer/gui/control/tomoobjdisplaymode.py +8 -0
- tomwer/gui/debugtools/datasetgenerator.py +3 -3
- tomwer/gui/edit/dkrfpatch.py +16 -22
- tomwer/gui/edit/imagekeyeditor.py +8 -11
- tomwer/gui/edit/nxtomoeditor.py +111 -44
- tomwer/gui/edit/nxtomowarmer.py +4 -4
- tomwer/gui/edit/test/test_dkrf_patch.py +7 -7
- tomwer/gui/edit/test/test_image_key_editor.py +3 -3
- tomwer/gui/edit/test/test_nx_editor.py +40 -16
- tomwer/gui/icat/__init__.py +0 -0
- tomwer/gui/icat/createscreenshots.py +80 -0
- tomwer/gui/icat/gallery.py +214 -0
- tomwer/gui/icat/publish.py +187 -0
- tomwer/gui/reconstruction/axis/axis.py +171 -57
- tomwer/gui/reconstruction/axis/radioaxis.py +80 -95
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
- tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
- tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +3 -6
- tomwer/gui/reconstruction/nabu/castvolume.py +1 -1
- tomwer/gui/reconstruction/nabu/check.py +9 -9
- tomwer/gui/reconstruction/nabu/helical.py +29 -12
- tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
- tomwer/gui/reconstruction/nabu/nabuconfig/output.py +110 -33
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +9 -12
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +219 -29
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +3 -6
- tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
- tomwer/gui/reconstruction/nabu/slices.py +6 -7
- tomwer/gui/reconstruction/nabu/volume.py +22 -10
- tomwer/gui/reconstruction/normalization/intensity.py +15 -23
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +7 -23
- tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
- tomwer/gui/reconstruction/saaxis/saaxis.py +7 -9
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +2 -1
- tomwer/gui/reconstruction/scores/control.py +2 -9
- tomwer/gui/reconstruction/scores/scoreplot.py +11 -5
- tomwer/gui/reconstruction/test/test_axis.py +23 -12
- tomwer/gui/reconstruction/test/test_lamino.py +8 -3
- tomwer/gui/reconstruction/test/test_nabu.py +28 -9
- tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
- tomwer/gui/reconstruction/test/test_sadeltabeta.py +2 -2
- tomwer/gui/settings.py +5 -28
- tomwer/gui/stackplot.py +2 -5
- tomwer/gui/stitching/action.py +49 -0
- tomwer/gui/stitching/config/axisparams.py +7 -24
- tomwer/gui/stitching/config/output.py +10 -8
- tomwer/gui/stitching/config/positionoveraxis.py +22 -23
- tomwer/gui/stitching/normalization.py +117 -0
- tomwer/gui/stitching/stitchandbackground.py +4 -6
- tomwer/gui/stitching/stitching.py +265 -43
- tomwer/gui/stitching/stitching_preview.py +62 -5
- tomwer/gui/stitching/stitching_raw.py +2 -5
- tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
- tomwer/gui/utils/buttons.py +112 -29
- tomwer/gui/utils/inputwidget.py +33 -25
- tomwer/gui/utils/scandescription.py +4 -0
- tomwer/gui/utils/step.py +144 -0
- tomwer/gui/utils/unitsystem.py +2 -5
- tomwer/gui/utils/vignettes.py +176 -15
- tomwer/gui/visualization/dataviewer.py +1 -18
- tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
- tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
- tomwer/gui/visualization/scanoverview.py +1 -1
- tomwer/gui/visualization/sinogramviewer.py +1 -10
- tomwer/gui/visualization/test/test_diffviewer.py +3 -3
- tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
- tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
- tomwer/gui/visualization/test/test_stacks.py +3 -3
- tomwer/gui/visualization/test/test_volumeviewer.py +2 -2
- tomwer/io/utils/raw_and_processed_data.py +84 -0
- tomwer/io/utils/tomoobj.py +4 -6
- tomwer/resources/gui/icons/ruler.png +0 -0
- tomwer/resources/gui/icons/ruler.svg +273 -0
- tomwer/resources/gui/icons/short_description.png +0 -0
- tomwer/resources/gui/icons/short_description.svg +58 -0
- tomwer/resources/gui/icons/url.png +0 -0
- tomwer/resources/gui/icons/url.svg +58 -0
- tomwer/synctools/stacks/edit/darkflatpatch.py +2 -2
- tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
- tomwer/synctools/stacks/reconstruction/axis.py +4 -4
- tomwer/synctools/stacks/reconstruction/castvolume.py +2 -2
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -10
- tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
- tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
- tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
- tomwer/synctools/test/test_darkRefs.py +7 -58
- tomwer/synctools/test/test_foldertransfer.py +6 -6
- tomwer/synctools/utils/scanstages.py +6 -6
- tomwer/tests/conftest.py +34 -0
- tomwer/tests/datasets.py +13 -0
- tomwer/tests/test_scripts.py +92 -39
- tomwer/tests/utils.py +5 -0
- tomwer/version.py +3 -3
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/METADATA +39 -44
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/RECORD +248 -209
- tomwer/resources/gui/icons/esrf_1.svg +0 -307
- tomwer/resources/gui/icons/triangle.svg +0 -80
- tomwer/synctools/test/test_scanstages.py +0 -162
- tomwer/tests/utils/__init__.py +0 -247
- tomwer/tests/utils/utilstest.py +0 -220
- /tomwer/app/{saaxis.py → multicor.py} +0 -0
- /tomwer/app/{sadeltabeta.py → multipag.py} +0 -0
- /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
- /tomwer-1.2.8-py3.11-nspkg.pth → /tomwer-1.3.0a0-py3.11-nspkg.pth +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/LICENSE +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/WHEEL +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/entry_points.txt +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,6 @@ from typing import Union
|
|
10
10
|
from nabu.stitching import config as _nabu_stitching_config
|
11
11
|
from nabu.stitching.config import StitchingType
|
12
12
|
from nabu.stitching.overlap import OverlapStitchingStrategy
|
13
|
-
from nabu.stitching.utils import ScoreMethod as _NabuScoreMethod
|
14
13
|
from nabu.stitching.utils import ShiftAlgorithm as _NabuShiftAlgorithm
|
15
14
|
from silx.gui import qt
|
16
15
|
from tomoscan.serie import Serie
|
@@ -39,44 +38,8 @@ class Axis_N_Params(qt.QGroupBox):
|
|
39
38
|
)
|
40
39
|
self.layout().addRow("image registration method", self._imageRegMethodCB)
|
41
40
|
|
42
|
-
# window size
|
43
|
-
self._windowSize = qt.QSpinBox(self)
|
44
|
-
self._windowSizeLabel = qt.QLabel(
|
45
|
-
_nabu_stitching_config.KEY_WINDOW_SIZE.replace("_", " "), self
|
46
|
-
)
|
47
|
-
self.layout().addRow(self._windowSizeLabel, self._windowSize)
|
48
|
-
self._windowSize.setToolTip("research window width to find shifts")
|
49
|
-
|
50
|
-
# score method
|
51
|
-
self._scoreCB = qt.QComboBox(self)
|
52
|
-
for score_method in _NabuScoreMethod.values():
|
53
|
-
self._scoreCB.addItem(score_method)
|
54
|
-
self._scoreCBLabel = qt.QLabel(
|
55
|
-
_nabu_stitching_config.KEY_SCORE_METHOD.replace("_", " "), self
|
56
|
-
)
|
57
|
-
self.layout().addRow(self._scoreCBLabel, self._scoreCB)
|
58
|
-
self._windowSize.setToolTip(
|
59
|
-
"method to use in order to compute score and determine the best shift"
|
60
|
-
)
|
61
|
-
|
62
|
-
# connect signal / slot
|
63
|
-
self._imageRegMethodCB.currentTextChanged.connect(self._updatePossibleOpts)
|
64
|
-
|
65
41
|
# set up
|
66
42
|
self._imageRegMethodCB.setCurrentText(_NabuShiftAlgorithm.NONE.value)
|
67
|
-
self._updatePossibleOpts()
|
68
|
-
|
69
|
-
def getWindowSize(self):
|
70
|
-
return self._windowSize.value()
|
71
|
-
|
72
|
-
def setWindowSize(self, window_size):
|
73
|
-
return self._windowSize.setValue(int(window_size))
|
74
|
-
|
75
|
-
def getScoreMethod(self):
|
76
|
-
return _NabuScoreMethod.from_value(self._scoreCB.currentText())
|
77
|
-
|
78
|
-
def setScoreMethod(self, method):
|
79
|
-
self._scoreCB.setCurrentText(_NabuScoreMethod.from_value(method).value)
|
80
43
|
|
81
44
|
def getCurrentMethod(self):
|
82
45
|
return _NabuShiftAlgorithm.from_value(self._imageRegMethodCB.currentText())
|
@@ -89,13 +52,6 @@ class Axis_N_Params(qt.QGroupBox):
|
|
89
52
|
def getOptsLine(self) -> str:
|
90
53
|
current_method = self.getCurrentMethod()
|
91
54
|
line_ = f"{_nabu_stitching_config.KEY_IMG_REG_METHOD}={current_method.value}"
|
92
|
-
if current_method is _NabuShiftAlgorithm.SHIFT_GRID:
|
93
|
-
line_ = ",".join(
|
94
|
-
(
|
95
|
-
line_,
|
96
|
-
f"{_nabu_stitching_config.KEY_WINDOW_SIZE}={self.getWindowSize()},{_nabu_stitching_config.KEY_SCORE_METHOD}={self.getScoreMethod().value}",
|
97
|
-
)
|
98
|
-
)
|
99
55
|
return line_
|
100
56
|
|
101
57
|
def setOptsLine(self, opt_line: str) -> None:
|
@@ -113,13 +69,6 @@ class Axis_N_Params(qt.QGroupBox):
|
|
113
69
|
except Exception as e:
|
114
70
|
_logger.error(e)
|
115
71
|
|
116
|
-
score_method = opts.get(_nabu_stitching_config.KEY_SCORE_METHOD, None)
|
117
|
-
if score_method is not None:
|
118
|
-
try:
|
119
|
-
self.setScoreMethod(score_method)
|
120
|
-
except Exception as e:
|
121
|
-
_logger.error(e)
|
122
|
-
|
123
72
|
img_reg_exp_method = opts.get(_nabu_stitching_config.KEY_IMG_REG_METHOD, None)
|
124
73
|
if img_reg_exp_method is not None:
|
125
74
|
try:
|
@@ -127,15 +76,6 @@ class Axis_N_Params(qt.QGroupBox):
|
|
127
76
|
except Exception as e:
|
128
77
|
_logger.error(e)
|
129
78
|
|
130
|
-
def _updatePossibleOpts(self, *args, **kwargs):
|
131
|
-
current_method = self.getCurrentMethod()
|
132
|
-
self._windowSizeLabel.setVisible(
|
133
|
-
current_method is _NabuShiftAlgorithm.SHIFT_GRID
|
134
|
-
)
|
135
|
-
self._windowSize.setVisible(current_method is _NabuShiftAlgorithm.SHIFT_GRID)
|
136
|
-
self._scoreCBLabel.setVisible(current_method is _NabuShiftAlgorithm.SHIFT_GRID)
|
137
|
-
self._scoreCB.setVisible(current_method is _NabuShiftAlgorithm.SHIFT_GRID)
|
138
|
-
|
139
79
|
|
140
80
|
class AutoRefineWidget(qt.QWidget):
|
141
81
|
"""
|
tomwer/gui/utils/buttons.py
CHANGED
@@ -1,39 +1,20 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# /*##########################################################################
|
3
|
-
# Copyright (C) 2017 European Synchrotron Radiation Facility
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
22
|
-
#
|
23
|
-
#############################################################################*/
|
24
|
-
|
25
1
|
"""
|
26
2
|
Button of general usage.
|
27
3
|
"""
|
28
4
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
5
|
+
import numpy
|
6
|
+
import logging
|
7
|
+
from typing import Optional, Union
|
34
8
|
from silx.gui import qt
|
9
|
+
from silx.gui.plot.tools.roi import RegionOfInterestManager
|
10
|
+
from silx.gui.plot.items.roi import LineROI
|
11
|
+
from silx.gui.plot.PlotToolButtons import PlotToolButton
|
35
12
|
|
36
13
|
from tomwer.gui import icons
|
14
|
+
from pyunitsystem.metricsystem import MetricSystem
|
15
|
+
|
16
|
+
|
17
|
+
_logger = logging.getLogger(__file__)
|
37
18
|
|
38
19
|
|
39
20
|
class PadlockButton(qt.QPushButton):
|
@@ -100,3 +81,105 @@ class TabBrowsersButtons(qt.QWidget):
|
|
100
81
|
|
101
82
|
def _nextReleased(self, *args, **kwargs):
|
102
83
|
self.sigNextReleased.emit()
|
84
|
+
|
85
|
+
|
86
|
+
class TapeMeasureToolButton(PlotToolButton):
|
87
|
+
"""Button to active measurement between two point of the plot"""
|
88
|
+
|
89
|
+
class TapeMeasureROI(LineROI):
|
90
|
+
def __init__(self, parent=None, pixel_size_m=None):
|
91
|
+
super().__init__(parent)
|
92
|
+
self._pixel_size_m = None
|
93
|
+
self.setPixelSize(pixel_size_m)
|
94
|
+
|
95
|
+
def setEndPoints(self, startPoint, endPoint):
|
96
|
+
distance_px = numpy.linalg.norm(endPoint - startPoint)
|
97
|
+
super().setEndPoints(startPoint=startPoint, endPoint=endPoint)
|
98
|
+
if self._pixel_size_m is None:
|
99
|
+
self._updateText(f"{distance_px :.1f}px")
|
100
|
+
else:
|
101
|
+
distance_m = distance_px * self._pixel_size_m
|
102
|
+
value, unit = MetricSystem.cast_metric_to_best_unit(distance_m)
|
103
|
+
self._updateText(f"{distance_px :.1f}px ({value:.2f}{unit})")
|
104
|
+
|
105
|
+
def setPixelSize(self, pixel_size_m: Optional[Union[tuple, float]]):
|
106
|
+
if isinstance(pixel_size_m, (tuple, list)):
|
107
|
+
assert (
|
108
|
+
len(pixel_size_m) == 2
|
109
|
+
), "expects at most two pixel size values (x and y values)"
|
110
|
+
if not numpy.isclose(pixel_size_m[0], pixel_size_m[1]):
|
111
|
+
value, unit = MetricSystem.cast_metric_to_best_unit(pixel_size_m[0])
|
112
|
+
_logger.warning(
|
113
|
+
f"TapeMeasure is only handling square pixels for now. Will consider the pixel is {value:.2f}{unit}x{value:.2f}{unit}"
|
114
|
+
)
|
115
|
+
pixel_size_m = pixel_size_m[0]
|
116
|
+
self._pixel_size_m = pixel_size_m
|
117
|
+
|
118
|
+
def __init__(self, parent=None, plot=None, pixel_size_mm=None):
|
119
|
+
super().__init__(parent=parent, plot=plot)
|
120
|
+
self._roiManager = None
|
121
|
+
self._lastRoiCreated = None
|
122
|
+
self._pixel_sixel_m = pixel_size_mm
|
123
|
+
self.setIcon(icons.getQIcon("ruler"))
|
124
|
+
self.setToolTip("measure distance between two pixels")
|
125
|
+
self.toggled.connect(self._callback)
|
126
|
+
self._connectPlot(plot)
|
127
|
+
|
128
|
+
def setPlot(self, plot):
|
129
|
+
return super().setPlot(plot)
|
130
|
+
|
131
|
+
def setPixelSize(self, pixel_size_m: Optional[Union[tuple, float]]):
|
132
|
+
self._pixel_sixel_m = pixel_size_m
|
133
|
+
|
134
|
+
def _callback(self, toggled):
|
135
|
+
if not self._roiManager:
|
136
|
+
return
|
137
|
+
if self._lastRoiCreated is not None:
|
138
|
+
self._lastRoiCreated.setVisible(self.isChecked())
|
139
|
+
if self.isChecked():
|
140
|
+
self._roiManager.start(
|
141
|
+
self.TapeMeasureROI,
|
142
|
+
self,
|
143
|
+
)
|
144
|
+
self.__interactiveModeStarted(self._roiManager)
|
145
|
+
else:
|
146
|
+
source = self._roiManager.getInteractionSource()
|
147
|
+
if source is self:
|
148
|
+
self._roiManager.stop()
|
149
|
+
|
150
|
+
def __interactiveModeStarted(self, roiManager):
|
151
|
+
roiManager.sigInteractiveModeFinished.connect(self.__interactiveModeFinished)
|
152
|
+
|
153
|
+
def __interactiveModeFinished(self):
|
154
|
+
roiManager = self._roiManager
|
155
|
+
if roiManager is not None:
|
156
|
+
roiManager.sigInteractiveModeFinished.disconnect(
|
157
|
+
self.__interactiveModeFinished
|
158
|
+
)
|
159
|
+
self.setChecked(False)
|
160
|
+
|
161
|
+
def _connectPlot(self, plot):
|
162
|
+
"""
|
163
|
+
Called when the plot is connected to the widget
|
164
|
+
:param plot: :class:`.PlotWidget` instance
|
165
|
+
"""
|
166
|
+
if plot is None:
|
167
|
+
return
|
168
|
+
self._roiManager = RegionOfInterestManager(plot)
|
169
|
+
self._roiManager.setColor("yellow") # Set the color of ROI
|
170
|
+
self._roiManager.sigRoiAdded.connect(self._registerCurrentROI)
|
171
|
+
|
172
|
+
def _disconnectPlot(self, plot):
|
173
|
+
if plot and self._lastRoiCreated is not None:
|
174
|
+
self._roiManager.removeRoi(self._lastRoiCreated)
|
175
|
+
self._lastRoiCreated = None
|
176
|
+
return super()._disconnectPlot(plot)
|
177
|
+
|
178
|
+
def _registerCurrentROI(self, currentRoi):
|
179
|
+
if self._lastRoiCreated is None:
|
180
|
+
self._lastRoiCreated = currentRoi
|
181
|
+
self._lastRoiCreated.setPixelSize(self._pixel_sixel_m)
|
182
|
+
elif currentRoi != self._lastRoiCreated and self._roiManager is not None:
|
183
|
+
self._roiManager.removeRoi(self._lastRoiCreated)
|
184
|
+
self._lastRoiCreated = currentRoi
|
185
|
+
self._lastRoiCreated.setPixelSize(self._pixel_sixel_m)
|
tomwer/gui/utils/inputwidget.py
CHANGED
@@ -28,7 +28,7 @@ __date__ = "16/08/2018"
|
|
28
28
|
|
29
29
|
import logging
|
30
30
|
import os
|
31
|
-
from typing import Optional
|
31
|
+
from typing import Optional, Union
|
32
32
|
|
33
33
|
import numpy
|
34
34
|
from nxtomomill.io.config import TomoEDFConfig as EDFConfig
|
@@ -41,7 +41,7 @@ from tomwer.gui import icons
|
|
41
41
|
from tomwer.gui.qlefilesystem import QLFileSystem
|
42
42
|
from tomwer.io.utils import get_default_directory
|
43
43
|
from tomwer.core.volume.volumefactory import VolumeFactory
|
44
|
-
from tomwer.core.process.
|
44
|
+
from tomwer.core.process.output import ProcessDataOutputDirMode
|
45
45
|
|
46
46
|
from tomwer.core.volume import (
|
47
47
|
EDFVolume,
|
@@ -271,42 +271,49 @@ class NXTomomillOutputDirSelector(qt.QWidget):
|
|
271
271
|
self.__buttonGroup.setExclusive(True)
|
272
272
|
|
273
273
|
tooltip = """Define the output directory of the nexus (.nx) file. Options are:
|
274
|
-
\n -
|
274
|
+
\n - same folder as scan: create the NXtomos at the same level as the bliss input file or spec folder
|
275
|
+
\n - 'RAW_DATA' folder: create NXtomos on the default 'RAW_DATA' folder (bliss default folder, nearby the 'raw' folder).
|
275
276
|
\n - 'PROCESSED_DATA' folder: create NXtomos on the default 'PROCESSED_DATA' folder (bliss default folder, nearby the 'raw' folder).
|
276
277
|
\n - user defined folder: users can provide their own folders using keywords for string formatting such as 'scan_dir_name', 'scan_basename' or 'scan_parent_dir_basename'
|
277
278
|
"""
|
278
279
|
|
279
280
|
# output dir is the folder containing the .nx file
|
280
|
-
self.
|
281
|
-
self.
|
282
|
-
self.layout().addWidget(self.
|
283
|
-
self.__buttonGroup.addButton(self.
|
281
|
+
self._inScanFolder = qt.QRadioButton("same folder as scan", self)
|
282
|
+
self._inScanFolder.setToolTip(tooltip)
|
283
|
+
self.layout().addWidget(self._inScanFolder, 0, 0, 1, 1)
|
284
|
+
self.__buttonGroup.addButton(self._inScanFolder)
|
284
285
|
# output dir is the default 'reduced'folder
|
285
286
|
self._processedDataFolderRB = qt.QRadioButton("'PROCESSED_DATA' folder", self)
|
286
287
|
self._processedDataFolderRB.setToolTip(tooltip)
|
287
288
|
self.layout().addWidget(self._processedDataFolderRB, 1, 0, 1, 1)
|
288
289
|
self.__buttonGroup.addButton(self._processedDataFolderRB)
|
290
|
+
# output dir is the default 'reduced'folder
|
291
|
+
self._rawDataFolderRB = qt.QRadioButton("'RAW_DATA' folder", self)
|
292
|
+
self._rawDataFolderRB.setToolTip(tooltip)
|
293
|
+
self.layout().addWidget(self._rawDataFolderRB, 2, 0, 1, 1)
|
294
|
+
self.__buttonGroup.addButton(self._rawDataFolderRB)
|
289
295
|
# manual
|
290
296
|
self._manualRB = qt.QRadioButton("custom output directory", self)
|
291
297
|
self._manualRB.setToolTip(tooltip)
|
292
|
-
self.layout().addWidget(self._manualRB,
|
298
|
+
self.layout().addWidget(self._manualRB, 3, 0, 1, 1)
|
293
299
|
self._outputFolderQLE = QLFileSystem("", self)
|
294
|
-
self.layout().addWidget(self._outputFolderQLE,
|
300
|
+
self.layout().addWidget(self._outputFolderQLE, 3, 1, 1, 1)
|
295
301
|
self._selectButton = qt.QPushButton("", self)
|
296
302
|
style = qt.QApplication.style()
|
297
303
|
icon_opendir = style.standardIcon(qt.QStyle.SP_DirOpenIcon)
|
298
304
|
self._selectButton.setIcon(icon_opendir)
|
299
305
|
self._selectButton.setToolTip("select output directory")
|
300
|
-
self.layout().addWidget(self._selectButton,
|
306
|
+
self.layout().addWidget(self._selectButton, 3, 2, 1, 1)
|
301
307
|
self.__buttonGroup.addButton(self._manualRB)
|
302
308
|
|
303
309
|
# connect signal / slot
|
304
310
|
self._selectButton.released.connect(self._selectOutpuFolder)
|
305
311
|
self.__buttonGroup.buttonReleased.connect(self._updateVisiblity)
|
306
|
-
self.
|
307
|
-
self._processedDataFolderRB.toggled.connect(self.
|
308
|
-
self.
|
309
|
-
self.
|
312
|
+
self._inScanFolder.toggled.connect(self.sigChanged)
|
313
|
+
self._processedDataFolderRB.toggled.connect(self.sigChanged)
|
314
|
+
self._rawDataFolderRB.toggled.connect(self.sigChanged)
|
315
|
+
self._manualRB.toggled.connect(self.sigChanged)
|
316
|
+
self._outputFolderQLE.editingFinished.connect(self.sigChanged)
|
310
317
|
|
311
318
|
# set up
|
312
319
|
self._processedDataFolderRB.setChecked(True)
|
@@ -316,9 +323,6 @@ class NXTomomillOutputDirSelector(qt.QWidget):
|
|
316
323
|
self._selectButton.setVisible(self._manualRB.isChecked())
|
317
324
|
self._outputFolderQLE.setVisible(self._manualRB.isChecked())
|
318
325
|
|
319
|
-
def _outputDirChanged(self):
|
320
|
-
self.sigChanged.emit()
|
321
|
-
|
322
326
|
def _selectOutpuFolder(self): # pragma: no cover
|
323
327
|
defaultDirectory = self._outputFolderQLE.text()
|
324
328
|
if os.path.isdir(defaultDirectory):
|
@@ -334,13 +338,15 @@ class NXTomomillOutputDirSelector(qt.QWidget):
|
|
334
338
|
self._outputFolderQLE.setText(dialog.selectedFiles()[0])
|
335
339
|
self.sigChanged.emit()
|
336
340
|
|
337
|
-
def getOutputFolder(self) -> str:
|
341
|
+
def getOutputFolder(self) -> Union[str, ProcessDataOutputDirMode]:
|
338
342
|
if self._manualRB.isChecked():
|
339
343
|
return self._outputFolderQLE.text()
|
340
344
|
elif self._processedDataFolderRB.isChecked():
|
341
|
-
return
|
342
|
-
elif self.
|
343
|
-
return
|
345
|
+
return ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER
|
346
|
+
elif self._inScanFolder.isChecked():
|
347
|
+
return ProcessDataOutputDirMode.IN_SCAN_FOLDER
|
348
|
+
elif self._rawDataFolderRB.isChecked():
|
349
|
+
return ProcessDataOutputDirMode.RAW_DATA_FOLDER
|
344
350
|
else:
|
345
351
|
raise RuntimeError("Use case - h52nx output dir - not handled")
|
346
352
|
|
@@ -348,15 +354,17 @@ class NXTomomillOutputDirSelector(qt.QWidget):
|
|
348
354
|
old = self.blockSignals(True)
|
349
355
|
self._manualRB.setChecked(output_folder is not None)
|
350
356
|
try:
|
351
|
-
default_output =
|
357
|
+
default_output = ProcessDataOutputDirMode.from_value(output_folder)
|
352
358
|
except ValueError:
|
353
359
|
self._outputFolderQLE.setText(output_folder)
|
354
360
|
self._manualRB.setChecked(True)
|
355
361
|
else:
|
356
|
-
if default_output is
|
362
|
+
if default_output is ProcessDataOutputDirMode.IN_SCAN_FOLDER:
|
357
363
|
self._processedDataFolderRB.setChecked(True)
|
358
|
-
elif default_output is
|
359
|
-
self.
|
364
|
+
elif default_output is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER:
|
365
|
+
self._inScanFolder.setChecked(True)
|
366
|
+
elif default_output is ProcessDataOutputDirMode.RAW_DATA_FOLDER:
|
367
|
+
self._rawDataFolderRB.setChecked(True)
|
360
368
|
else:
|
361
369
|
raise ValueError(f"default output not handled ({default_output})")
|
362
370
|
finally:
|
@@ -64,6 +64,10 @@ class ScanNameLabelAndShape(qt.QWidget):
|
|
64
64
|
def setScan(self, scan: Optional[TomwerScanBase]):
|
65
65
|
if scan is None or scan.path is None:
|
66
66
|
self.clear()
|
67
|
+
elif not isinstance(scan, TomwerScanBase):
|
68
|
+
raise TypeError(
|
69
|
+
f"Scan is expected to be an instance of {TomwerScanBase}. Get {type(scan)} instead"
|
70
|
+
)
|
67
71
|
else:
|
68
72
|
assert isinstance(scan, TomwerScanBase)
|
69
73
|
self._scanNameLabel.setText(scan.get_identifier().short_description())
|
tomwer/gui/utils/step.py
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
import functools
|
2
|
+
from silx.gui import qt
|
3
|
+
from typing import Optional, Union
|
4
|
+
from tomwer.gui.utils.qt_utils import block_signals
|
5
|
+
|
6
|
+
|
7
|
+
class StepSizeSelectorWidget(qt.QGroupBox):
|
8
|
+
"""
|
9
|
+
Widget to define some steps size (as float). Used by the Axis and the AxisOrdered widgets
|
10
|
+
|
11
|
+
:param str title: title to provide to the group box
|
12
|
+
:param str label: text for the label set at the left of the QLineEdit
|
13
|
+
:param fine_value: (optional) value to provide for 'fine' step
|
14
|
+
:param medium_value: (optional) value to provide for 'medium' step
|
15
|
+
:param rough_value: (optional) value to provide for 'rough' step
|
16
|
+
:param dtype: type of the step. Can be int or float
|
17
|
+
"""
|
18
|
+
|
19
|
+
valueChanged = qt.Signal()
|
20
|
+
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
parent=None,
|
24
|
+
title="",
|
25
|
+
label: str = "step size",
|
26
|
+
fine_value: [float, int, None] = 0.1,
|
27
|
+
medium_value: [float, int, None] = 0.5,
|
28
|
+
rough_value: [float, int, None] = 1.0,
|
29
|
+
unit: Optional[str] = "px",
|
30
|
+
dtype: Union[int, float] = float,
|
31
|
+
):
|
32
|
+
assert fine_value is None or isinstance(
|
33
|
+
fine_value, dtype
|
34
|
+
), f"fine_value is expected to be None or a {dtype}. Get {type(fine_value)}"
|
35
|
+
assert medium_value is None or isinstance(
|
36
|
+
medium_value, dtype
|
37
|
+
), f"medium_value is expected to be None or a {dtype}. Get {type(medium_value)}"
|
38
|
+
assert rough_value is None or isinstance(
|
39
|
+
rough_value, dtype
|
40
|
+
), f"rough_value is expected to be None or a {dtype}. Get {type(rough_value)}"
|
41
|
+
super().__init__(title, parent)
|
42
|
+
self._dtype = dtype
|
43
|
+
if unit is None:
|
44
|
+
unit = ""
|
45
|
+
else:
|
46
|
+
unit = f" {unit}"
|
47
|
+
self.setLayout(qt.QGridLayout())
|
48
|
+
self.layout().setSpacing(2)
|
49
|
+
|
50
|
+
# label
|
51
|
+
self.layout().addWidget(qt.QLabel(label), 0, 0, 3, 1)
|
52
|
+
|
53
|
+
# QLE manual step size
|
54
|
+
default_value = medium_value or fine_value or rough_value
|
55
|
+
self._manualLE = qt.QLineEdit(str(default_value), parent=self)
|
56
|
+
if dtype is float:
|
57
|
+
validator = qt.QDoubleValidator(parent=self._manualLE, decimals=2)
|
58
|
+
validator.setBottom(0.0)
|
59
|
+
elif dtype is int:
|
60
|
+
validator = qt.QIntValidator(parent=self._manualLE)
|
61
|
+
validator.setBottom(0)
|
62
|
+
else:
|
63
|
+
raise ValueError("dtype is expected to be int or float")
|
64
|
+
self._manualLE.setValidator(validator)
|
65
|
+
self.layout().addWidget(self._manualLE, 0, 1, 3, 1)
|
66
|
+
|
67
|
+
# buttons
|
68
|
+
buttons_font = self.font()
|
69
|
+
buttons_font.setPixelSize(10)
|
70
|
+
self._expectedValues = {}
|
71
|
+
# for each button associate the expected value
|
72
|
+
|
73
|
+
# fine
|
74
|
+
if fine_value is not None:
|
75
|
+
self._fineButton = qt.QPushButton(f"fine ({fine_value}{unit})", parent=self)
|
76
|
+
self._fineButton.setCheckable(True)
|
77
|
+
self._fineButton.setFont(buttons_font)
|
78
|
+
self.layout().addWidget(self._fineButton, 0, 2, 1, 1)
|
79
|
+
self._fineButton.released.connect(
|
80
|
+
functools.partial(self.setStepSize, fine_value)
|
81
|
+
)
|
82
|
+
self._expectedValues[self._fineButton] = fine_value
|
83
|
+
else:
|
84
|
+
self._fineButton = None
|
85
|
+
|
86
|
+
# medium
|
87
|
+
if medium_value is not None:
|
88
|
+
self._mediumButton = qt.QPushButton(
|
89
|
+
f"medium ({medium_value}{unit})", parent=self
|
90
|
+
)
|
91
|
+
self._mediumButton.setCheckable(True)
|
92
|
+
self._mediumButton.setFont(buttons_font)
|
93
|
+
self.layout().addWidget(self._mediumButton, 1, 2, 1, 1)
|
94
|
+
self._mediumButton.released.connect(
|
95
|
+
functools.partial(self.setStepSize, medium_value)
|
96
|
+
)
|
97
|
+
self._expectedValues[self._mediumButton] = medium_value
|
98
|
+
else:
|
99
|
+
self._mediumButton = None
|
100
|
+
|
101
|
+
# rough
|
102
|
+
if rough_value is not None:
|
103
|
+
self._roughButton = qt.QPushButton(
|
104
|
+
f"rough ({rough_value}{unit})", parent=self
|
105
|
+
)
|
106
|
+
self._roughButton.setCheckable(True)
|
107
|
+
self._roughButton.setFont(buttons_font)
|
108
|
+
self.layout().addWidget(self._roughButton, 2, 2, 1, 1)
|
109
|
+
self._roughButton.released.connect(
|
110
|
+
functools.partial(self.setStepSize, rough_value)
|
111
|
+
)
|
112
|
+
self._expectedValues[self._roughButton] = rough_value
|
113
|
+
else:
|
114
|
+
self._roughButton = None
|
115
|
+
|
116
|
+
# connect signal / slot
|
117
|
+
self._manualLE.textChanged.connect(self._updateButtonChecked)
|
118
|
+
self._manualLE.textChanged.connect(self.valueChanged)
|
119
|
+
# set up
|
120
|
+
self._updateButtonChecked(self._manualLE.text())
|
121
|
+
|
122
|
+
def _updateButtonChecked(self, text):
|
123
|
+
if text == "":
|
124
|
+
return
|
125
|
+
current_value = self._dtype(text)
|
126
|
+
for button, activation_value in self._expectedValues.items():
|
127
|
+
with block_signals(button):
|
128
|
+
button.setChecked(activation_value == current_value)
|
129
|
+
|
130
|
+
def getStepSize(self) -> Union[float, int]:
|
131
|
+
"""
|
132
|
+
|
133
|
+
:return: displacement shift defined
|
134
|
+
:rtype: float
|
135
|
+
"""
|
136
|
+
return self._dtype(self._manualLE.text())
|
137
|
+
|
138
|
+
def setStepSize(self, value: Union[float, int]):
|
139
|
+
"""
|
140
|
+
|
141
|
+
:param float value: shift step
|
142
|
+
"""
|
143
|
+
assert isinstance(value, self._dtype)
|
144
|
+
self._manualLE.setText(str(value))
|
tomwer/gui/utils/unitsystem.py
CHANGED
@@ -35,7 +35,7 @@ __date__ = "21/09/2018"
|
|
35
35
|
import logging
|
36
36
|
|
37
37
|
from silx.gui import qt
|
38
|
-
from
|
38
|
+
from pyunitsystem import metricsystem
|
39
39
|
|
40
40
|
from tomwer.core.utils.char import MU_CHAR
|
41
41
|
|
@@ -64,10 +64,7 @@ class PixelEntry(qt.QWidget):
|
|
64
64
|
self.layout().addWidget(self._qlePixelSize)
|
65
65
|
|
66
66
|
# connect signal / slot
|
67
|
-
self._qlePixelSize.editingFinished.connect(self.
|
68
|
-
|
69
|
-
def _callbackEditingFinished(self):
|
70
|
-
self.valueChanged.emit()
|
67
|
+
self._qlePixelSize.editingFinished.connect(self.valueChanged)
|
71
68
|
|
72
69
|
def getValue(self):
|
73
70
|
if self._qlePixelSize.text() in ("unknown", ""):
|