tomwer 1.0.3__py3-none-any.whl → 1.1.0__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/EBS_tomo_listener.ows +39 -0
- orangecontrib/tomwer/tutorials/cast_volume.ows +34 -0
- orangecontrib/tomwer/tutorials/simple_slice_reconstruction.ows +39 -0
- orangecontrib/tomwer/tutorials/simple_volume_local_reconstruction.ows +49 -0
- orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +59 -0
- orangecontrib/tomwer/tutorials/using_saaxis_to_find_cor.ows +44 -0
- orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +1 -1
- orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +14 -4
- orangecontrib/tomwer/widgets/cluster/__init__.py +1 -1
- orangecontrib/tomwer/widgets/control/DataListOW.py +12 -5
- orangecontrib/tomwer/widgets/control/DataListenerOW.py +18 -9
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +13 -6
- orangecontrib/tomwer/widgets/control/DataTransfertOW.py +3 -5
- orangecontrib/tomwer/widgets/control/DataValidatorOW.py +8 -4
- orangecontrib/tomwer/widgets/control/DataWatcherOW.py +4 -6
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +49 -62
- orangecontrib/tomwer/widgets/control/FilterOW.py +2 -4
- orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +93 -0
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +135 -129
- orangecontrib/tomwer/widgets/control/NotifierOW.py +34 -9
- orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +3 -5
- orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +19 -13
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +12 -4
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +11 -7
- orangecontrib/tomwer/widgets/control/icons/notification.svg +4 -4
- orangecontrib/tomwer/widgets/control/icons/nxtomomill.png +0 -0
- orangecontrib/tomwer/widgets/control/icons/nxtomomill.svg +8 -5
- orangecontrib/tomwer/widgets/control/icons/tomoobjserie.png +0 -0
- orangecontrib/tomwer/widgets/control/icons/tomoobjserie.svg +73 -78
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +16 -4
- orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +100 -0
- orangecontrib/tomwer/widgets/edit/icons/image_key_editor.png +0 -0
- orangecontrib/tomwer/widgets/edit/icons/image_key_upgrader.png +0 -0
- orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.png +0 -0
- orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.svg +123 -0
- orangecontrib/tomwer/widgets/edit/test/test_dark_flat_patch.py +21 -1
- orangecontrib/tomwer/widgets/edit/test/test_image_key_editor.py +1 -1
- orangecontrib/tomwer/widgets/edit/test/test_image_key_upgrader.py +1 -1
- orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +25 -0
- orangecontrib/tomwer/widgets/other/PythonScriptOW.py +19 -11
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +20 -14
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +24 -10
- orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +26 -21
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +29 -12
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +44 -17
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +28 -20
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +24 -18
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +6 -6
- orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +4 -2
- orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.png +0 -0
- orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.svg +11 -8
- orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +10 -4
- orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +69 -0
- orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +2 -4
- orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.png +0 -0
- orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.svg +105 -0
- tomwer/__main__.py +10 -5
- tomwer/app/canvas_launcher/config.py +10 -10
- tomwer/app/canvas_launcher/mainwindow.py +68 -6
- tomwer/app/canvas_launcher/widgetsscheme.py +1 -3
- tomwer/app/darkref.py +16 -12
- tomwer/app/imagekeyeditor.py +2 -2
- tomwer/app/imagekeyupgrader.py +104 -0
- tomwer/app/intensitynormalization.py +0 -1
- tomwer/app/nxtomoeditor.py +103 -0
- tomwer/app/rsync.py +1 -1
- tomwer/core/cluster/cluster.py +1 -1
- tomwer/core/futureobject.py +1 -0
- tomwer/core/process/control/datalistener/datalistener.py +7 -1
- tomwer/core/process/control/datalistener/rpcserver.py +3 -4
- tomwer/core/process/control/datawatcher/datawatcher.py +18 -18
- tomwer/core/process/control/datawatcher/datawatcherobserver.py +5 -8
- tomwer/core/process/control/datawatcher/datawatcherprocess.py +2 -3
- tomwer/core/process/control/datawatcher/edfdwprocess.py +2 -2
- tomwer/core/process/control/nxtomomill.py +33 -58
- tomwer/core/process/control/scanlist.py +2 -1
- tomwer/core/process/control/scanselector.py +7 -0
- tomwer/core/process/control/scantransfer.py +2 -2
- tomwer/core/process/control/scanvalidator.py +6 -5
- tomwer/core/process/control/singletomoobj.py +2 -1
- tomwer/core/process/control/timer.py +2 -1
- tomwer/core/process/control/tomoobjserie.py +8 -2
- tomwer/core/process/control/volumeselector.py +2 -1
- tomwer/core/process/control/volumesymlink.py +2 -1
- tomwer/core/process/edit/darkflatpatch.py +2 -1
- tomwer/core/process/edit/imagekeyeditor.py +4 -3
- tomwer/core/process/reconstruction/axis/axis.py +29 -32
- tomwer/core/process/reconstruction/axis/mode.py +3 -2
- tomwer/core/process/reconstruction/axis/params.py +35 -16
- tomwer/core/process/reconstruction/darkref/darkrefs.py +90 -707
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +44 -16
- tomwer/core/process/reconstruction/darkref/params.py +62 -67
- tomwer/core/process/reconstruction/lamino/tofu.py +1 -2
- tomwer/core/process/reconstruction/nabu/castvolume.py +21 -26
- tomwer/core/process/reconstruction/nabu/nabucommon.py +36 -38
- tomwer/core/process/reconstruction/nabu/nabuscores.py +28 -13
- tomwer/core/process/reconstruction/nabu/nabuslices.py +41 -14
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +21 -12
- tomwer/core/process/reconstruction/nabu/utils.py +32 -3
- tomwer/core/process/reconstruction/normalization/normalization.py +9 -8
- tomwer/core/process/reconstruction/saaxis/saaxis.py +46 -20
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +38 -12
- tomwer/core/process/reconstruction/test/__init__.py +0 -39
- tomwer/core/process/reconstruction/test/test_axis_params.py +25 -3
- tomwer/core/process/reconstruction/test/test_darkref_copy.py +117 -1
- tomwer/core/process/script/python.py +16 -12
- tomwer/core/process/task.py +3 -7
- tomwer/core/process/test/test_axis.py +1 -1
- tomwer/core/process/test/test_dark_and_flat.py +41 -111
- tomwer/core/process/test/test_data_listener.py +0 -29
- tomwer/core/process/test/test_data_transfer.py +10 -14
- tomwer/core/process/test/test_nabu.py +1 -1
- tomwer/core/process/test/test_normalization.py +1 -1
- tomwer/core/process/visualization/liveslice.py +6 -0
- tomwer/core/scan/blissscan.py +37 -2
- tomwer/core/scan/edfscan.py +19 -8
- tomwer/core/scan/hdf5scan.py +10 -4
- tomwer/core/scan/scanbase.py +35 -29
- tomwer/core/scan/scanfactory.py +3 -17
- tomwer/core/scan/test/test_h5.py +1 -1
- tomwer/core/scan/test/test_process_registration.py +0 -11
- tomwer/core/scan/test/test_scan.py +32 -30
- tomwer/core/settings.py +2 -2
- tomwer/core/test/test_utils.py +1 -1
- tomwer/core/tomwer_object.py +19 -0
- tomwer/core/utils/__init__.py +0 -45
- tomwer/core/utils/char.py +2 -0
- tomwer/core/utils/gpu.py +5 -5
- tomwer/core/utils/nxtomoutils.py +2 -2
- tomwer/core/utils/scanutils.py +50 -0
- tomwer/core/utils/volumeutils.py +13 -0
- tomwer/core/volume/edfvolume.py +4 -0
- tomwer/core/volume/hdf5volume.py +4 -0
- tomwer/core/volume/jp2kvolume.py +4 -0
- tomwer/core/volume/rawvolume.py +22 -5
- tomwer/core/volume/tiffvolume.py +4 -0
- tomwer/core/volume/volumebase.py +19 -12
- tomwer/core/volume/volumefactory.py +20 -1
- tomwer/gui/cluster/slurm.py +1 -1
- tomwer/gui/cluster/supervisor.py +0 -2
- tomwer/gui/cluster/test/test_cluster.py +2 -2
- tomwer/gui/control/datalist.py +109 -36
- tomwer/gui/control/datatransfert.py +1 -1
- tomwer/gui/control/datawatcher/configuration.py +0 -2
- tomwer/gui/control/datawatcher/datawatcher.py +23 -13
- tomwer/gui/control/datawatcher/datawatcherobserver.py +1 -1
- tomwer/gui/control/observations.py +0 -3
- tomwer/gui/control/selectorwidgetbase.py +42 -12
- tomwer/gui/control/serie/seriecreator.py +967 -0
- tomwer/{web/__init__.py → gui/control/serie/seriewaiter.py} +5 -7
- tomwer/gui/control/singletomoobj.py +15 -4
- tomwer/gui/control/test/test_datalist.py +1 -1
- tomwer/gui/control/test/test_datalistener.py +1 -1
- tomwer/gui/control/test/test_inputwidget.py +1 -1
- tomwer/gui/control/test/test_process_manager.py +1 -13
- tomwer/gui/control/test/test_scanselector.py +1 -1
- tomwer/gui/control/test/test_scanvalidator.py +1 -1
- tomwer/gui/control/test/test_single_tomo_obj.py +1 -1
- tomwer/gui/control/test/test_volume_dialog.py +19 -7
- tomwer/gui/control/test/test_volumeselector.py +4 -4
- tomwer/gui/debugtools/datasetgenerator.py +1 -9
- tomwer/gui/edit/dkrfpatch.py +2 -3
- tomwer/gui/edit/imagekeyeditor.py +12 -11
- tomwer/gui/edit/nxtomoeditor.py +475 -0
- tomwer/gui/edit/test/test_dkrf_patch.py +2 -14
- tomwer/gui/edit/test/test_image_key_editor.py +2 -2
- tomwer/gui/edit/test/test_nx_editor.py +155 -0
- tomwer/gui/icons.py +0 -1
- tomwer/gui/qfolderdialog.py +11 -0
- tomwer/gui/reconstruction/axis/CompareImages.py +27 -29
- tomwer/gui/reconstruction/axis/axis.py +2 -0
- tomwer/gui/reconstruction/axis/radioaxis.py +70 -14
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +7 -9
- tomwer/gui/reconstruction/darkref/darkrefwidget.py +22 -24
- tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
- tomwer/gui/reconstruction/lamino/tofu/tofu.py +3 -3
- tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +4 -4
- tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +10 -5
- tomwer/gui/reconstruction/nabu/castvolume.py +103 -24
- tomwer/gui/reconstruction/nabu/check.py +1 -1
- tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py +352 -0
- tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +0 -9
- tomwer/gui/reconstruction/nabu/nabuconfig/output.py +1 -1
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +18 -19
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +30 -7
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +26 -15
- tomwer/gui/reconstruction/nabu/slices.py +10 -4
- tomwer/gui/reconstruction/nabu/slurm.py +1 -1
- tomwer/gui/reconstruction/nabu/volume.py +13 -7
- tomwer/gui/reconstruction/normalization/intensity.py +1 -5
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +10 -37
- tomwer/gui/reconstruction/saaxis/saaxis.py +11 -7
- tomwer/gui/reconstruction/saaxis/sliceselector.py +11 -26
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +13 -8
- tomwer/gui/reconstruction/scores/scoreplot.py +67 -62
- tomwer/gui/reconstruction/test/test_axis.py +2 -2
- tomwer/gui/reconstruction/test/test_lamino.py +2 -2
- tomwer/gui/reconstruction/test/test_nabu.py +14 -1
- tomwer/gui/reconstruction/test/test_saaxis.py +8 -17
- tomwer/gui/reconstruction/test/test_sadeltabeta.py +7 -13
- tomwer/gui/stackplot.py +11 -28
- tomwer/gui/test/test_axis_gui.py +4 -4
- tomwer/gui/test/test_qfolder_dialog.py +12 -0
- tomwer/gui/utils/inputwidget.py +42 -22
- tomwer/gui/utils/lineselector/lineselector.py +13 -21
- tomwer/gui/utils/scandescription.py +2 -4
- tomwer/gui/utils/slider.py +1 -102
- tomwer/gui/utils/unitsystem.py +48 -11
- tomwer/gui/visualization/dataviewer.py +24 -17
- tomwer/gui/visualization/diffviewer/diffviewer.py +2 -11
- tomwer/gui/visualization/nxtomometadata.py +21 -0
- tomwer/gui/visualization/scanoverview.py +0 -1
- tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +72 -0
- tomwer/gui/visualization/test/test_stacks.py +1 -1
- tomwer/gui/visualization/tomoobjoverview.py +49 -0
- tomwer/gui/visualization/volumeoverview.py +64 -0
- tomwer/gui/visualization/volumeviewer.py +1 -1
- tomwer/io/utils/utils.py +2 -2
- tomwer/resources/gui/icons/multi-document-save.png +0 -0
- tomwer/resources/gui/icons/multi-document-save.svg +101 -0
- tomwer/resources/gui/illustrations/ctf_z1.png +0 -0
- tomwer/resources/gui/illustrations/ctf_z1.svg +471 -0
- tomwer/synctools/axis.py +0 -1
- tomwer/synctools/darkref.py +0 -1
- tomwer/synctools/datalistener.py +5 -1
- tomwer/synctools/imageloaderthread.py +2 -2
- tomwer/synctools/saaxis.py +0 -1
- tomwer/synctools/sadeltabeta.py +0 -1
- tomwer/synctools/stacks/edit/imagekeyeditor.py +1 -1
- tomwer/synctools/stacks/processingstack.py +2 -2
- tomwer/synctools/stacks/reconstruction/castvolume.py +1 -0
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +1 -1
- tomwer/synctools/stacks/reconstruction/lamino.py +1 -3
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +0 -2
- tomwer/synctools/test/test_darkRefs.py +32 -149
- tomwer/synctools/test/test_foldertransfer.py +1 -1
- tomwer/synctools/test/test_scanstages.py +2 -2
- tomwer/tests/conftest.py +51 -0
- tomwer/{test → tests}/test_scripts.py +1 -1
- tomwer/tests/test_utils.py +10 -0
- tomwer/{test → tests}/utils/utilstest.py +0 -11
- tomwer/version.py +3 -3
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/METADATA +14 -16
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/RECORD +255 -235
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/WHEEL +1 -1
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/entry_points.txt +6 -0
- orangecontrib/tomwer/setup.py +0 -45
- orangecontrib/tomwer/widgets/setup.py +0 -49
- tomwer/app/process.py +0 -153
- tomwer/core/process/reconstruction/nabu/slurm.py +0 -36
- tomwer/core/process/reconstruction/utils/nabu_slice_exec.py +0 -10
- tomwer/core/utils/laminoutils.py +0 -80
- tomwer/gui/utils/lineselector/lineselection.py +0 -76
- tomwer/setup.py +0 -52
- tomwer/slurm/executor.py +0 -36
- tomwer/slurm/job.py +0 -349
- tomwer/slurm/utils.py +0 -44
- tomwer/web/client.py +0 -43
- tomwer/web/config.py +0 -36
- tomwer/web/test/test_graylog_connection.py +0 -59
- {tomwer/slurm → orangecontrib/tomwer/tutorials}/__init__.py +0 -0
- /tomwer/{test → gui/control/serie}/__init__.py +0 -0
- /tomwer/{web/test → tests}/__init__.py +0 -0
- /tomwer/{test → tests}/utils/__init__.py +0 -0
- /tomwer-1.0.3-py3.8-nspkg.pth → /tomwer-1.1.0-py3.9-nspkg.pth +0 -0
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/LICENSE +0 -0
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.0.3.dist-info → tomwer-1.1.0.dist-info}/top_level.txt +0 -0
@@ -37,13 +37,14 @@ from tomwer.core.process.reconstruction.nabu.castvolume import (
|
|
37
37
|
from tomwer.core.process.reconstruction.nabu.nabucommon import NabuOutputFileFormat
|
38
38
|
from tomwer.gui.qlefilesystem import QLFileSystem
|
39
39
|
from tomwer.gui.reconstruction.nabu.nabuconfig.output import QNabuFileFormatComboBox
|
40
|
+
from silx.gui.utils import blockSignals
|
40
41
|
import logging
|
42
|
+
from typing import Optional
|
41
43
|
|
42
44
|
_logger = logging.getLogger(__name__)
|
43
45
|
|
44
46
|
|
45
47
|
class CastVolumeWidget(qt.QWidget):
|
46
|
-
|
47
48
|
sigConfigChanged = qt.Signal()
|
48
49
|
"""Signal emit when the configuration changed"""
|
49
50
|
|
@@ -59,28 +60,53 @@ class CastVolumeWidget(qt.QWidget):
|
|
59
60
|
self._outputDataTypeCB = qt.QComboBox(self)
|
60
61
|
for data_type in ("uint8", "uint16", "float32", "float64"):
|
61
62
|
self._outputDataTypeCB.addItem(data_type)
|
62
|
-
self.layout().addWidget(self._outputDataTypeCB, 0,
|
63
|
+
self.layout().addWidget(self._outputDataTypeCB, 0, 1, 1, 3)
|
63
64
|
# output file format
|
64
65
|
self._outputFileformatLabel = qt.QLabel("output file format", self)
|
65
66
|
self.layout().addWidget(self._outputFileformatLabel, 1, 0, 1, 1)
|
66
67
|
self._outputFileformatCB = QNabuFileFormatComboBox(self)
|
67
|
-
self.layout().addWidget(self._outputFileformatCB, 1,
|
68
|
-
|
68
|
+
self.layout().addWidget(self._outputFileformatCB, 1, 1, 1, 3)
|
69
|
+
|
70
|
+
# let the user provide min and max manually
|
71
|
+
self._minMaxLabel = qt.QLabel("min max values")
|
72
|
+
self.layout().addWidget(self._minMaxLabel, 2, 0, 1, 1)
|
73
|
+
self._minMaxAuto = qt.QCheckBox("auto with rescale from percentiles")
|
74
|
+
self._minMaxAuto.setChecked(True)
|
75
|
+
self._minMaxAuto.setToolTip(
|
76
|
+
"If set to auto will try to get min/max pixel values from nabu histogram else will compute it. Otherwise will values provided by the user"
|
77
|
+
)
|
78
|
+
self.layout().addWidget(self._minMaxAuto, 2, 1, 1, 1)
|
79
|
+
|
80
|
+
self._minPixValue = qt.QLineEdit("", self)
|
81
|
+
self._minPixValue.setPlaceholderText("min")
|
82
|
+
self._maxPixValue = qt.QLineEdit("", self)
|
83
|
+
self._maxPixValue.setPlaceholderText("max")
|
84
|
+
validator = qt.QDoubleValidator(self)
|
85
|
+
validator.setNotation(qt.QDoubleValidator.ScientificNotation)
|
86
|
+
self._minPixValue.setValidator(validator)
|
87
|
+
self._maxPixValue.setValidator(validator)
|
88
|
+
self.layout().addWidget(self._minPixValue, 4, 2, 1, 1)
|
89
|
+
self.layout().addWidget(self._maxPixValue, 4, 3, 1, 1)
|
90
|
+
self._minPixValue.setVisible(False)
|
91
|
+
self._maxPixValue.setVisible(False)
|
92
|
+
# or from percentiles
|
69
93
|
self._percentilesLabel = qt.QLabel("rescale percentiles")
|
70
|
-
self.layout().addWidget(self._percentilesLabel,
|
94
|
+
self.layout().addWidget(self._percentilesLabel, 3, 1, 1, 1)
|
71
95
|
self._lowPercentileQSB = qt.QSpinBox(self)
|
72
96
|
self._lowPercentileQSB.setRange(0, 100)
|
73
97
|
self._lowPercentileQSB.setPrefix("min:")
|
98
|
+
self._lowPercentileQSB.setSuffix("%")
|
74
99
|
self._lowPercentileQSB.setValue(RESCALE_MIN_PERCENTILE)
|
75
|
-
self.layout().addWidget(self._lowPercentileQSB,
|
100
|
+
self.layout().addWidget(self._lowPercentileQSB, 3, 2, 1, 1)
|
76
101
|
self._highPercentileQSB = qt.QSpinBox(self)
|
77
102
|
self._highPercentileQSB.setRange(0, 100)
|
78
103
|
self._highPercentileQSB.setPrefix("max:")
|
104
|
+
self._highPercentileQSB.setSuffix("%")
|
79
105
|
self._highPercentileQSB.setValue(RESCALE_MAX_PERCENTILE)
|
80
|
-
self.layout().addWidget(self._highPercentileQSB,
|
106
|
+
self.layout().addWidget(self._highPercentileQSB, 3, 3, 1, 1)
|
81
107
|
# save dir
|
82
108
|
self._saveDirLabel = qt.QLabel("output directory", self)
|
83
|
-
self.layout().addWidget(self._saveDirLabel,
|
109
|
+
self.layout().addWidget(self._saveDirLabel, 5, 0, 1, 1)
|
84
110
|
self._useDefaultSaveDirQCB = qt.QCheckBox("default", self)
|
85
111
|
self._useDefaultSaveDirQCB.setToolTip(
|
86
112
|
f"Default directory is: {DEFAULT_OUTPUT_DIR}"
|
@@ -89,7 +115,7 @@ class CastVolumeWidget(qt.QWidget):
|
|
89
115
|
qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum
|
90
116
|
)
|
91
117
|
self._useDefaultSaveDirQCB.setChecked(True)
|
92
|
-
self.layout().addWidget(self._useDefaultSaveDirQCB,
|
118
|
+
self.layout().addWidget(self._useDefaultSaveDirQCB, 5, 1, 1, 1)
|
93
119
|
self._saveDirQLE = QLFileSystem(text=DEFAULT_OUTPUT_DIR, parent=self)
|
94
120
|
# force text because this is not a valid path
|
95
121
|
self._saveDirQLE.setText(DEFAULT_OUTPUT_DIR)
|
@@ -100,11 +126,11 @@ class CastVolumeWidget(qt.QWidget):
|
|
100
126
|
"""
|
101
127
|
)
|
102
128
|
self._saveDirQLE.setVisible(False)
|
103
|
-
self.layout().addWidget(self._saveDirQLE,
|
129
|
+
self.layout().addWidget(self._saveDirQLE, 5, 2, 1, 2)
|
104
130
|
# overwrite
|
105
131
|
self._overwriteCB = qt.QCheckBox("overwrite", self)
|
106
132
|
self._overwriteCB.setChecked(True)
|
107
|
-
self.layout().addWidget(self._overwriteCB,
|
133
|
+
self.layout().addWidget(self._overwriteCB, 6, 0, 1, 1)
|
108
134
|
# spacer
|
109
135
|
self._spacer = qt.QWidget(self)
|
110
136
|
self._spacer.setSizePolicy(
|
@@ -119,6 +145,8 @@ class CastVolumeWidget(qt.QWidget):
|
|
119
145
|
self._useDefaultSaveDirQCB.toggled.connect(self._configChanged)
|
120
146
|
self._overwriteCB.toggled.connect(self._configChanged)
|
121
147
|
self._useDefaultSaveDirQCB.toggled.connect(self._updateOutputDirVis)
|
148
|
+
self._minMaxAuto.toggled.connect(self._configChanged)
|
149
|
+
self._minMaxAuto.toggled.connect(self._updatePixMinMaxVis)
|
122
150
|
|
123
151
|
def getOutputDataType(self) -> str:
|
124
152
|
return self._outputDataTypeCB.currentText()
|
@@ -155,21 +183,59 @@ class CastVolumeWidget(qt.QWidget):
|
|
155
183
|
def setOverwrite(self, remove) -> None:
|
156
184
|
self._overwriteCB.setChecked(remove)
|
157
185
|
|
186
|
+
def getDataMin(self) -> Optional[float]:
|
187
|
+
if (
|
188
|
+
self._minMaxAuto.isChecked()
|
189
|
+
or self._minPixValue.text().replace(" ", "") == ""
|
190
|
+
):
|
191
|
+
return None
|
192
|
+
else:
|
193
|
+
return float(self._minPixValue.text())
|
194
|
+
|
195
|
+
def setDataMin(self, value: Optional[float]) -> None:
|
196
|
+
with blockSignals(self._minMaxAuto):
|
197
|
+
self._minMaxAuto.setChecked(value is None)
|
198
|
+
if value is not None:
|
199
|
+
with blockSignals(self._minPixValue):
|
200
|
+
self._minPixValue.setText(str(value))
|
201
|
+
|
202
|
+
def getDataMax(self) -> Optional[float]:
|
203
|
+
if (
|
204
|
+
self._minMaxAuto.isChecked()
|
205
|
+
or self._maxPixValue.text().replace(" ", "") == ""
|
206
|
+
):
|
207
|
+
return None
|
208
|
+
else:
|
209
|
+
return float(self._maxPixValue.text())
|
210
|
+
|
211
|
+
def setDataMax(self, value: Optional[float]) -> None:
|
212
|
+
with blockSignals(self._minMaxAuto):
|
213
|
+
self._minMaxAuto.setChecked(value is None)
|
214
|
+
if value is not None:
|
215
|
+
with blockSignals(self._maxPixValue):
|
216
|
+
self._maxPixValue.setText(str(value))
|
217
|
+
|
158
218
|
def getConfiguration(self) -> dict:
|
219
|
+
rescale_min_percentile, rescale_max_percentile = self.getRescalePercentiles()
|
159
220
|
return {
|
160
221
|
"output_data_type": self.getOutputDataType(),
|
161
222
|
"output_type": self.getOutputFileFormat().value,
|
162
223
|
"output_dir": self.getOutputDir(),
|
163
224
|
"overwrite": self.getOverwrite(),
|
164
|
-
"
|
225
|
+
"rescale_min_percentile": rescale_min_percentile,
|
226
|
+
"rescale_max_percentile": rescale_max_percentile,
|
227
|
+
"data_min": self.getDataMin(),
|
228
|
+
"data_max": self.getDataMax(),
|
165
229
|
}
|
166
230
|
|
167
231
|
def getRescalePercentiles(self) -> tuple:
|
168
232
|
return self._lowPercentileQSB.value(), self._highPercentileQSB.value()
|
169
233
|
|
170
234
|
def setRescalePercentiles(self, low, high) -> tuple:
|
171
|
-
|
172
|
-
|
235
|
+
if low is not None:
|
236
|
+
self._lowPercentileQSB.setValue(low)
|
237
|
+
if high is not None:
|
238
|
+
self._highPercentileQSB.setValue(high)
|
173
239
|
|
174
240
|
def setConfiguration(self, config: dict) -> None:
|
175
241
|
output_data_type = config.get("output_data_type", None)
|
@@ -184,19 +250,32 @@ class CastVolumeWidget(qt.QWidget):
|
|
184
250
|
overwrite = config.get("overwrite", None)
|
185
251
|
if overwrite is not None:
|
186
252
|
self.setOverwrite(overwrite)
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
253
|
+
if "rescale_percentiles" in config:
|
254
|
+
rescale_min_percentile, rescale_max_percentile = config[
|
255
|
+
"rescale_percentiles"
|
256
|
+
]
|
257
|
+
_logger.warning(
|
258
|
+
"'rescale_percentiles' is deprecated. Please use 'rescale_min_percentile' and 'rescale_max_percentile' instead"
|
259
|
+
)
|
260
|
+
else:
|
261
|
+
rescale_min_percentile = config.get("rescale_min_percentile", None)
|
262
|
+
rescale_max_percentile = config.get("rescale_max_percentile", None)
|
263
|
+
|
264
|
+
self.setRescalePercentiles(rescale_min_percentile, rescale_max_percentile)
|
265
|
+
if "data_min" in config:
|
266
|
+
self.setDataMin(config["data_min"])
|
267
|
+
if "data_max" in config:
|
268
|
+
self.setDataMax(config["data_max"])
|
197
269
|
|
198
270
|
def _configChanged(self, *args, **kwargs):
|
199
271
|
self.sigConfigChanged.emit()
|
200
272
|
|
201
273
|
def _updateOutputDirVis(self, *args, **kwargs):
|
202
274
|
self._saveDirQLE.setVisible(not self._useDefaultSaveDirQCB.isChecked())
|
275
|
+
|
276
|
+
def _updatePixMinMaxVis(self, *args, **kwargs):
|
277
|
+
self._minPixValue.setVisible(not self._minMaxAuto.isChecked())
|
278
|
+
self._maxPixValue.setVisible(not self._minMaxAuto.isChecked())
|
279
|
+
self._percentilesLabel.setVisible(self._minMaxAuto.isChecked())
|
280
|
+
self._lowPercentileQSB.setVisible(self._minMaxAuto.isChecked())
|
281
|
+
self._highPercentileQSB.setVisible(self._minMaxAuto.isChecked())
|
@@ -30,7 +30,7 @@ __date__ = "02/12/2021"
|
|
30
30
|
|
31
31
|
from tomwer.core.scan.hdf5scan import HDF5TomoScan
|
32
32
|
from tomwer.core.utils.nxtomoutils import get_n_series
|
33
|
-
from tomoscan.esrf.hdf5scan import ImageKey
|
33
|
+
from tomoscan.esrf.scan.hdf5scan import ImageKey
|
34
34
|
from silx.gui import qt
|
35
35
|
|
36
36
|
|
@@ -0,0 +1,352 @@
|
|
1
|
+
from silx.gui import qt
|
2
|
+
from typing import Optional, Union
|
3
|
+
from tomwer.core.process.reconstruction.nabu.utils import _NabuStages
|
4
|
+
from tomwer.gui.reconstruction.nabu.nabuconfig import base
|
5
|
+
from tomwer.gui.utils.illustrations import _IllustrationWidget
|
6
|
+
from silx.gui.utils import blockSignals
|
7
|
+
from silx.utils.enum import Enum as _Enum
|
8
|
+
from .reconstruction import AnglesFileWidget as Filewidget
|
9
|
+
|
10
|
+
|
11
|
+
def nabu_param_ligne_to_dict(str_ligne: str) -> dict:
|
12
|
+
ddict = {}
|
13
|
+
if "=" in str_ligne:
|
14
|
+
for elmt in str_ligne.split(";"):
|
15
|
+
kwv = elmt.lstrip(" ").rstrip(" ")
|
16
|
+
key, value = kwv.split("=")
|
17
|
+
ddict[key] = value
|
18
|
+
return ddict
|
19
|
+
|
20
|
+
|
21
|
+
class _DoubleScientific(qt.QLineEdit):
|
22
|
+
"""
|
23
|
+
A simple QLineEdit with a Doublevalidator with Scientific Notation
|
24
|
+
"""
|
25
|
+
|
26
|
+
def __init__(self, parent=None, *args, **kwargs):
|
27
|
+
super().__init__(parent, *args, **kwargs)
|
28
|
+
validator = qt.QDoubleValidator(parent=self)
|
29
|
+
validator.setNotation(qt.QDoubleValidator.ScientificNotation)
|
30
|
+
self.setValidator(validator)
|
31
|
+
|
32
|
+
def value(self) -> float:
|
33
|
+
if self.text() == "":
|
34
|
+
return 0.0
|
35
|
+
else:
|
36
|
+
return float(self.text())
|
37
|
+
|
38
|
+
def setValue(self, value):
|
39
|
+
self.setText(str(value))
|
40
|
+
|
41
|
+
|
42
|
+
class OptionalDouble(qt.QWidget):
|
43
|
+
"""
|
44
|
+
A spin box with a Check box to handle 'None' case of the nabu CTF options
|
45
|
+
"""
|
46
|
+
|
47
|
+
sigChanged = qt.Signal()
|
48
|
+
"""emit when the combobox of the double spin box value changed"""
|
49
|
+
|
50
|
+
def __init__(self, parent) -> None:
|
51
|
+
super().__init__(parent)
|
52
|
+
self.setLayout(qt.QHBoxLayout())
|
53
|
+
self._cb = qt.QCheckBox("", self)
|
54
|
+
self.layout().addWidget(self._cb)
|
55
|
+
self._dsb = _DoubleScientific(self)
|
56
|
+
self.layout().addWidget(self._dsb)
|
57
|
+
|
58
|
+
# connect signal ? slot
|
59
|
+
self._cb.toggled.connect(self._updateVisibility)
|
60
|
+
self._cb.toggled.connect(self._changed)
|
61
|
+
self._dsb.textChanged.connect(self._changed)
|
62
|
+
|
63
|
+
# set up
|
64
|
+
self._updateVisibility()
|
65
|
+
|
66
|
+
def _changed(self, *args, **kwargs):
|
67
|
+
self.sigChanged.emit()
|
68
|
+
|
69
|
+
def value(self) -> Optional[float]:
|
70
|
+
if self._cb.isChecked():
|
71
|
+
return self._dsb.value()
|
72
|
+
else:
|
73
|
+
return None
|
74
|
+
|
75
|
+
def setValue(self, value: Optional[float]):
|
76
|
+
if value in (None, "None"):
|
77
|
+
self._cb.setChecked(False)
|
78
|
+
else:
|
79
|
+
self._cb.setChecked(True)
|
80
|
+
self._dsb.setValue(float(value))
|
81
|
+
|
82
|
+
def setText(self, text: str):
|
83
|
+
self._cb.setText(text)
|
84
|
+
|
85
|
+
def _updateVisibility(self, *args, **kwargs):
|
86
|
+
self._dsb.setVisible(self._cb.isChecked())
|
87
|
+
|
88
|
+
|
89
|
+
class _BeamShape(_Enum):
|
90
|
+
PARALLEL = "parallel"
|
91
|
+
CONE = "cone"
|
92
|
+
|
93
|
+
|
94
|
+
class ConeBeamOpts(qt.QGroupBox):
|
95
|
+
"""Specific settings for cone beam geometry"""
|
96
|
+
|
97
|
+
sigConfChanged = qt.Signal()
|
98
|
+
"""emit when ctf parameters changed"""
|
99
|
+
|
100
|
+
def __init__(self, parent=None, title="cone settings"):
|
101
|
+
super().__init__(parent, title=title)
|
102
|
+
self.setLayout(qt.QGridLayout())
|
103
|
+
# z1_v
|
104
|
+
self._z1_v = _DoubleScientific(self)
|
105
|
+
self._z1_v.setPlaceholderText("z1_v in meter")
|
106
|
+
self.layout().addWidget(qt.QLabel("z1_v", self), 0, 0, 1, 1)
|
107
|
+
self.layout().addWidget(self._z1_v, 0, 1, 1, 1)
|
108
|
+
# z1_h
|
109
|
+
self._z1_h = _DoubleScientific(self)
|
110
|
+
self._z1_h.setPlaceholderText("z1_h in meter")
|
111
|
+
self.layout().addWidget(qt.QLabel("z1_h", self), 1, 0, 1, 1)
|
112
|
+
self.layout().addWidget(self._z1_h, 1, 1, 1, 1)
|
113
|
+
|
114
|
+
# illustration to define z1, z2
|
115
|
+
self._ctfIllustration = _IllustrationWidget(parent=self, img="ctf_z1")
|
116
|
+
self._ctfIllustration.setMinimumSize(qt.QSize(200, 90))
|
117
|
+
self._ctfIllustration.setSizePolicy(
|
118
|
+
qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding
|
119
|
+
)
|
120
|
+
|
121
|
+
self._ctfIllustration.setContentsMargins(0, 0, 0, 0)
|
122
|
+
self._ctfIllustration.layout().setSpacing(0)
|
123
|
+
self.layout().addWidget(self._ctfIllustration, 0, 2, 2, 2)
|
124
|
+
|
125
|
+
# connect signal / slot
|
126
|
+
self._z1_v.textChanged.connect(self._confChanged)
|
127
|
+
self._z1_h.textChanged.connect(self._confChanged)
|
128
|
+
|
129
|
+
def _confChanged(self, *args, **kwargs):
|
130
|
+
self.sigConfChanged.emit()
|
131
|
+
|
132
|
+
def getGeometry(self) -> dict:
|
133
|
+
return {
|
134
|
+
"z1_v": self._z1_v.value(),
|
135
|
+
"z1_h": self._z1_h.value(),
|
136
|
+
}
|
137
|
+
|
138
|
+
def setGeometry(self, config: dict) -> None:
|
139
|
+
with blockSignals(self):
|
140
|
+
if "z1_v" in config:
|
141
|
+
self._z1_v.setValue(float(config["z1_v"]))
|
142
|
+
if "z1_h" in config:
|
143
|
+
self._z1_h.setValue(float(config["z1_h"]))
|
144
|
+
|
145
|
+
|
146
|
+
class CTFGeometry(qt.QGroupBox):
|
147
|
+
"""
|
148
|
+
widget for the ctf_geometry parameter of nabu
|
149
|
+
"""
|
150
|
+
|
151
|
+
sigConfChanged = qt.Signal()
|
152
|
+
"""emit when ctf parameters changed"""
|
153
|
+
|
154
|
+
def __init__(self, parent=None, title="ctf-geometry") -> None:
|
155
|
+
super().__init__(parent, title=title)
|
156
|
+
self.setLayout(qt.QFormLayout())
|
157
|
+
self._beamShapeCB = qt.QComboBox(self)
|
158
|
+
for shape in _BeamShape.values():
|
159
|
+
self._beamShapeCB.addItem(shape)
|
160
|
+
self.layout().addRow("shape", self._beamShapeCB)
|
161
|
+
|
162
|
+
# cone beam settings
|
163
|
+
self._coneBeamSettings = ConeBeamOpts(self)
|
164
|
+
self.layout().addRow(self._coneBeamSettings)
|
165
|
+
|
166
|
+
# detector pixel size
|
167
|
+
self._detectorPixelSize = OptionalDouble(self)
|
168
|
+
self._detectorPixelSize.setText("overwrite")
|
169
|
+
self._detectorPixelSize._dsb.setPlaceholderText("pixel size in meter")
|
170
|
+
self.layout().addRow("detector pixel size", self._detectorPixelSize)
|
171
|
+
# magnification
|
172
|
+
self._magnification = qt.QCheckBox("magnification", self)
|
173
|
+
self.layout().addRow(self._magnification)
|
174
|
+
|
175
|
+
# set up
|
176
|
+
self._magnification.setChecked(True)
|
177
|
+
self._updateView()
|
178
|
+
|
179
|
+
# connect signal / slot
|
180
|
+
self._coneBeamSettings.sigConfChanged.connect(self._confChanged)
|
181
|
+
self._detectorPixelSize.sigChanged.connect(self._confChanged)
|
182
|
+
self._magnification.toggled.connect(self._confChanged)
|
183
|
+
self._beamShapeCB.currentIndexChanged.connect(self._updateView)
|
184
|
+
self._beamShapeCB.currentIndexChanged.connect(self._confChanged)
|
185
|
+
|
186
|
+
def getBeamShape(self):
|
187
|
+
return _BeamShape.from_value(self._beamShapeCB.currentText())
|
188
|
+
|
189
|
+
def setBeamShape(self, shape: Union[str, _BeamShape]):
|
190
|
+
shape = _BeamShape.from_value(shape)
|
191
|
+
self._beamShapeCB.setCurrentText(shape.value)
|
192
|
+
|
193
|
+
def _updateView(self, *args, **kwargs):
|
194
|
+
self._coneBeamSettings.setVisible(self.getBeamShape() == _BeamShape.CONE)
|
195
|
+
|
196
|
+
def _confChanged(self, *args, **kwargs):
|
197
|
+
self.sigConfChanged.emit()
|
198
|
+
|
199
|
+
def getConfiguration(self) -> dict:
|
200
|
+
magnification = "True" if self._magnification.isChecked() else "False"
|
201
|
+
beam_shape = self.getBeamShape()
|
202
|
+
if beam_shape is _BeamShape.PARALLEL:
|
203
|
+
z1_v = None
|
204
|
+
z1_h = None
|
205
|
+
elif beam_shape is _BeamShape.CONE:
|
206
|
+
cone_params = self._coneBeamSettings.getGeometry()
|
207
|
+
z1_v = cone_params["z1_v"]
|
208
|
+
z1_h = cone_params["z1_h"]
|
209
|
+
else:
|
210
|
+
raise NotImplementedError(f"Geometry {beam_shape.value} is not handled")
|
211
|
+
|
212
|
+
geometry = f" z1_v={z1_v}; z1_h={z1_h}; detec_pixel_size={self._detectorPixelSize.value()}; magnification={magnification}"
|
213
|
+
|
214
|
+
return {"ctf_geometry": geometry, "beam_shape": beam_shape.value}
|
215
|
+
|
216
|
+
def setConfiguration(self, ddict: dict) -> None:
|
217
|
+
params = nabu_param_ligne_to_dict(ddict.get("ctf_geometry", ""))
|
218
|
+
with blockSignals(self):
|
219
|
+
for key, value in params.items():
|
220
|
+
if key == "detec_pixel_size":
|
221
|
+
self._detectorPixelSize.setValue(value)
|
222
|
+
elif key == "magnification":
|
223
|
+
self._magnification.setChecked(value.lower() == "true")
|
224
|
+
|
225
|
+
beam_shape = ddict.get("beam_shape", None)
|
226
|
+
if beam_shape is not None:
|
227
|
+
if _BeamShape.from_value(beam_shape) is _BeamShape.CONE:
|
228
|
+
self._coneBeamSettings.setGeometry(params)
|
229
|
+
self.setBeamShape(beam_shape)
|
230
|
+
|
231
|
+
|
232
|
+
class CTFAdvancedParams(qt.QGroupBox):
|
233
|
+
"""
|
234
|
+
widget for the ctf_advanced_params parameter of nabu
|
235
|
+
"""
|
236
|
+
|
237
|
+
sigConfChanged = qt.Signal()
|
238
|
+
"""emit when ctf parameters changed"""
|
239
|
+
|
240
|
+
def __init__(self, parent=None, title="ctf-advanced-params") -> None:
|
241
|
+
super().__init__(parent, title=title)
|
242
|
+
self.setLayout(qt.QFormLayout())
|
243
|
+
# length_scale
|
244
|
+
self._length_scale = _DoubleScientific(self)
|
245
|
+
self.layout().addRow("length_scale", self._length_scale)
|
246
|
+
# lim1
|
247
|
+
self._lim1 = _DoubleScientific(self)
|
248
|
+
self._lim1Label = qt.QLabel("lim1")
|
249
|
+
self.layout().addRow(self._lim1Label, self._lim1)
|
250
|
+
# lim2
|
251
|
+
self._lim2 = _DoubleScientific(self)
|
252
|
+
self._lim2Label = qt.QLabel("lim2")
|
253
|
+
self.layout().addRow(self._lim2Label, self._lim2)
|
254
|
+
for w in (self._lim1, self._lim1Label, self._lim2, self._lim2Label):
|
255
|
+
w.setToolTip(
|
256
|
+
"parameter of the low-pass filter. Used in equation: 'lim = lim1 * r + lim2 * (1 - r)' where r is some low-pass filter (image dimensionality)"
|
257
|
+
)
|
258
|
+
|
259
|
+
# normalize_by_mean
|
260
|
+
self._normalize_by_mean = qt.QCheckBox("normalize by mean", self)
|
261
|
+
self.layout().addRow(self._normalize_by_mean)
|
262
|
+
|
263
|
+
# set up
|
264
|
+
self._length_scale.setText("1e-5")
|
265
|
+
self._lim1.setText("1e-5")
|
266
|
+
self._lim2.setText("0.2")
|
267
|
+
self._normalize_by_mean.setChecked(True)
|
268
|
+
|
269
|
+
# connect sginal / slot
|
270
|
+
self._length_scale.textChanged.connect(self._confChanged)
|
271
|
+
self._lim1.textChanged.connect(self._confChanged)
|
272
|
+
self._lim2.textChanged.connect(self._confChanged)
|
273
|
+
self._normalize_by_mean.toggled.connect(self._confChanged)
|
274
|
+
|
275
|
+
def getLengthScale(self) -> str:
|
276
|
+
if self._length_scale.text() == "":
|
277
|
+
return "0.0"
|
278
|
+
else:
|
279
|
+
return self._length_scale.text()
|
280
|
+
|
281
|
+
def _confChanged(self, *args, **kwargs):
|
282
|
+
self.sigConfChanged.emit()
|
283
|
+
|
284
|
+
def getConfiguration(self) -> dict:
|
285
|
+
normalize_by_mean = "True" if self._normalize_by_mean.isChecked() else "False"
|
286
|
+
ctf_advanced_params = f" length_scale={self._length_scale.value()}; lim1={self._lim1.value()}; lim2={self._lim2.value()}; normalize_by_mean={normalize_by_mean}"
|
287
|
+
return {
|
288
|
+
"ctf_advanced_params": ctf_advanced_params,
|
289
|
+
}
|
290
|
+
|
291
|
+
def setConfiguration(self, ddict: dict) -> None:
|
292
|
+
params = nabu_param_ligne_to_dict(ddict.get("ctf_advanced_params", {}))
|
293
|
+
with blockSignals(self):
|
294
|
+
for key, value in params.items():
|
295
|
+
if key == "length_scale":
|
296
|
+
self._length_scale.setText(value)
|
297
|
+
elif key == "lim1":
|
298
|
+
self._lim1.setText(value)
|
299
|
+
elif key == "lim2":
|
300
|
+
self._lim2.setText(value)
|
301
|
+
elif key == "normalize_by_mean":
|
302
|
+
self._normalize_by_mean.setChecked(value.lower() == "true")
|
303
|
+
|
304
|
+
|
305
|
+
class CTFConfig(qt.QGroupBox, base._NabuStageConfigBase):
|
306
|
+
"""
|
307
|
+
Widget dedicated for the CTF parameters
|
308
|
+
"""
|
309
|
+
|
310
|
+
sigConfChanged = qt.Signal(str)
|
311
|
+
"""emit when ctf parameters changed"""
|
312
|
+
|
313
|
+
def __init__(self, parent=None, title="ctf parameters"):
|
314
|
+
qt.QGroupBox.__init__(self, parent, title=title, stage=_NabuStages.PHASE)
|
315
|
+
base._NabuStageConfigBase.__init__(self, stage=_NabuStages.PHASE)
|
316
|
+
|
317
|
+
self.setLayout(qt.QFormLayout())
|
318
|
+
|
319
|
+
# geometry
|
320
|
+
self._geometryWidget = CTFGeometry(parent=self, title="geometry")
|
321
|
+
self.layout().addRow(self._geometryWidget)
|
322
|
+
self.registerWidget(self._geometryWidget, "optional")
|
323
|
+
# translation file
|
324
|
+
self._translationFile = Filewidget(self)
|
325
|
+
self.layout().addRow("translation file", self._translationFile)
|
326
|
+
self.registerWidget(self._translationFile, "optional")
|
327
|
+
# advanced parameters
|
328
|
+
self._advancedParamsWidget = CTFAdvancedParams(
|
329
|
+
parent=self, title="advanced parameters"
|
330
|
+
)
|
331
|
+
self.layout().addRow(self._advancedParamsWidget)
|
332
|
+
self.registerWidget(self._advancedParamsWidget, "advanced")
|
333
|
+
|
334
|
+
# connect signal / slot
|
335
|
+
self._geometryWidget.sigConfChanged.connect(self._confChanged)
|
336
|
+
self._advancedParamsWidget.sigConfChanged.connect(self._confChanged)
|
337
|
+
self._translationFile._qle.textEdited.connect(self._confChanged)
|
338
|
+
|
339
|
+
def _confChanged(self, *args, **kwargs):
|
340
|
+
self.sigConfChanged.emit("phase")
|
341
|
+
|
342
|
+
def getConfiguration(self) -> dict:
|
343
|
+
ddict = self._geometryWidget.getConfiguration()
|
344
|
+
ddict.update(self._advancedParamsWidget.getConfiguration())
|
345
|
+
ddict["ctf_translations_file"] = self._translationFile.getFile()
|
346
|
+
return ddict
|
347
|
+
|
348
|
+
def setConfiguration(self, ddict):
|
349
|
+
self._geometryWidget.setConfiguration(ddict=ddict)
|
350
|
+
self._advancedParamsWidget.setConfiguration(ddict=ddict)
|
351
|
+
if "ctf_translations_file" in ddict:
|
352
|
+
self._translationFile.setFile(ddict["ctf_translations_file"])
|
@@ -293,12 +293,3 @@ class NabuConfigurationTab(qt.QTabWidget):
|
|
293
293
|
self._reconstructionWidget.setConfiguration(config["reconstruction"])
|
294
294
|
if "tomwer_slices" in config:
|
295
295
|
self._reconstructionWidget.setSlices(config["tomwer_slices"])
|
296
|
-
|
297
|
-
|
298
|
-
if __name__ == "__main__":
|
299
|
-
app = qt.QApplication([])
|
300
|
-
widget = NabuConfiguration(None, None)
|
301
|
-
widget.show()
|
302
|
-
print(widget.getConfiguration())
|
303
|
-
print(widget.getSlices())
|
304
|
-
app.exec_()
|
@@ -119,7 +119,7 @@ class NabuOutputLocationWidget(qt.QWidget):
|
|
119
119
|
self._outputDirQLE.setVisible(not hide)
|
120
120
|
self._selectOutputPB.setVisible(not hide)
|
121
121
|
|
122
|
-
def _selectOutput(self):
|
122
|
+
def _selectOutput(self): # pragma: no cover
|
123
123
|
defaultDirectory = self._outputDirQLE.text()
|
124
124
|
if os.path.isdir(defaultDirectory):
|
125
125
|
defaultDirectory = get_default_directory()
|