tomwer 1.0.4__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 +4 -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 -128
- orangecontrib/tomwer/widgets/control/NotifierOW.py +31 -7
- orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +3 -5
- orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +85 -0
- 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 +138 -0
- 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 -10
- 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 -18
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +24 -17
- 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/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 -3
- 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 +9 -18
- 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 -0
- 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 -1
- 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 +12 -1
- 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 +14 -4
- 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 +4 -0
- 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/test/test_cluster.py +2 -2
- tomwer/gui/control/datalist.py +109 -34
- tomwer/gui/control/datatransfert.py +1 -1
- 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 -11
- 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 -3
- 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 -8
- tomwer/gui/edit/dkrfpatch.py +2 -2
- tomwer/gui/edit/imagekeyeditor.py +12 -9
- 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/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 +67 -11
- 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 -4
- tomwer/gui/reconstruction/nabu/castvolume.py +80 -11
- 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 -13
- tomwer/gui/reconstruction/nabu/slices.py +10 -2
- tomwer/gui/reconstruction/nabu/slurm.py +1 -1
- tomwer/gui/reconstruction/nabu/volume.py +13 -7
- tomwer/gui/reconstruction/normalization/intensity.py +1 -1
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +10 -34
- tomwer/gui/reconstruction/saaxis/saaxis.py +11 -6
- tomwer/gui/reconstruction/saaxis/sliceselector.py +11 -26
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +13 -8
- tomwer/gui/reconstruction/scores/scoreplot.py +67 -61
- 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 -21
- 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/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/datalistener.py +5 -1
- tomwer/synctools/imageloaderthread.py +2 -2
- 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/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/__init__.py +0 -0
- 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.4.dist-info → tomwer-1.1.0.dist-info}/METADATA +14 -16
- {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/RECORD +245 -217
- {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/WHEEL +1 -1
- {tomwer-1.0.4.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/web/client.py +0 -43
- tomwer/web/config.py +0 -36
- tomwer/web/test/test_graylog_connection.py +0 -59
- {tomwer/test → orangecontrib/tomwer/tutorials}/__init__.py +0 -0
- /tomwer/{web/test → gui/control/serie}/__init__.py +0 -0
- /tomwer/{test → tests}/utils/__init__.py +0 -0
- /tomwer-1.0.4-py3.8-nspkg.pth → /tomwer-1.1.0-py3.9-nspkg.pth +0 -0
- {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/LICENSE +0 -0
- {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/top_level.txt +0 -0
@@ -37,7 +37,9 @@ 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
|
|
@@ -58,28 +60,53 @@ class CastVolumeWidget(qt.QWidget):
|
|
58
60
|
self._outputDataTypeCB = qt.QComboBox(self)
|
59
61
|
for data_type in ("uint8", "uint16", "float32", "float64"):
|
60
62
|
self._outputDataTypeCB.addItem(data_type)
|
61
|
-
self.layout().addWidget(self._outputDataTypeCB, 0,
|
63
|
+
self.layout().addWidget(self._outputDataTypeCB, 0, 1, 1, 3)
|
62
64
|
# output file format
|
63
65
|
self._outputFileformatLabel = qt.QLabel("output file format", self)
|
64
66
|
self.layout().addWidget(self._outputFileformatLabel, 1, 0, 1, 1)
|
65
67
|
self._outputFileformatCB = QNabuFileFormatComboBox(self)
|
66
|
-
self.layout().addWidget(self._outputFileformatCB, 1,
|
67
|
-
|
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
|
68
93
|
self._percentilesLabel = qt.QLabel("rescale percentiles")
|
69
|
-
self.layout().addWidget(self._percentilesLabel,
|
94
|
+
self.layout().addWidget(self._percentilesLabel, 3, 1, 1, 1)
|
70
95
|
self._lowPercentileQSB = qt.QSpinBox(self)
|
71
96
|
self._lowPercentileQSB.setRange(0, 100)
|
72
97
|
self._lowPercentileQSB.setPrefix("min:")
|
98
|
+
self._lowPercentileQSB.setSuffix("%")
|
73
99
|
self._lowPercentileQSB.setValue(RESCALE_MIN_PERCENTILE)
|
74
|
-
self.layout().addWidget(self._lowPercentileQSB,
|
100
|
+
self.layout().addWidget(self._lowPercentileQSB, 3, 2, 1, 1)
|
75
101
|
self._highPercentileQSB = qt.QSpinBox(self)
|
76
102
|
self._highPercentileQSB.setRange(0, 100)
|
77
103
|
self._highPercentileQSB.setPrefix("max:")
|
104
|
+
self._highPercentileQSB.setSuffix("%")
|
78
105
|
self._highPercentileQSB.setValue(RESCALE_MAX_PERCENTILE)
|
79
|
-
self.layout().addWidget(self._highPercentileQSB,
|
106
|
+
self.layout().addWidget(self._highPercentileQSB, 3, 3, 1, 1)
|
80
107
|
# save dir
|
81
108
|
self._saveDirLabel = qt.QLabel("output directory", self)
|
82
|
-
self.layout().addWidget(self._saveDirLabel,
|
109
|
+
self.layout().addWidget(self._saveDirLabel, 5, 0, 1, 1)
|
83
110
|
self._useDefaultSaveDirQCB = qt.QCheckBox("default", self)
|
84
111
|
self._useDefaultSaveDirQCB.setToolTip(
|
85
112
|
f"Default directory is: {DEFAULT_OUTPUT_DIR}"
|
@@ -88,7 +115,7 @@ class CastVolumeWidget(qt.QWidget):
|
|
88
115
|
qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum
|
89
116
|
)
|
90
117
|
self._useDefaultSaveDirQCB.setChecked(True)
|
91
|
-
self.layout().addWidget(self._useDefaultSaveDirQCB,
|
118
|
+
self.layout().addWidget(self._useDefaultSaveDirQCB, 5, 1, 1, 1)
|
92
119
|
self._saveDirQLE = QLFileSystem(text=DEFAULT_OUTPUT_DIR, parent=self)
|
93
120
|
# force text because this is not a valid path
|
94
121
|
self._saveDirQLE.setText(DEFAULT_OUTPUT_DIR)
|
@@ -99,11 +126,11 @@ class CastVolumeWidget(qt.QWidget):
|
|
99
126
|
"""
|
100
127
|
)
|
101
128
|
self._saveDirQLE.setVisible(False)
|
102
|
-
self.layout().addWidget(self._saveDirQLE,
|
129
|
+
self.layout().addWidget(self._saveDirQLE, 5, 2, 1, 2)
|
103
130
|
# overwrite
|
104
131
|
self._overwriteCB = qt.QCheckBox("overwrite", self)
|
105
132
|
self._overwriteCB.setChecked(True)
|
106
|
-
self.layout().addWidget(self._overwriteCB,
|
133
|
+
self.layout().addWidget(self._overwriteCB, 6, 0, 1, 1)
|
107
134
|
# spacer
|
108
135
|
self._spacer = qt.QWidget(self)
|
109
136
|
self._spacer.setSizePolicy(
|
@@ -118,6 +145,8 @@ class CastVolumeWidget(qt.QWidget):
|
|
118
145
|
self._useDefaultSaveDirQCB.toggled.connect(self._configChanged)
|
119
146
|
self._overwriteCB.toggled.connect(self._configChanged)
|
120
147
|
self._useDefaultSaveDirQCB.toggled.connect(self._updateOutputDirVis)
|
148
|
+
self._minMaxAuto.toggled.connect(self._configChanged)
|
149
|
+
self._minMaxAuto.toggled.connect(self._updatePixMinMaxVis)
|
121
150
|
|
122
151
|
def getOutputDataType(self) -> str:
|
123
152
|
return self._outputDataTypeCB.currentText()
|
@@ -154,6 +183,38 @@ class CastVolumeWidget(qt.QWidget):
|
|
154
183
|
def setOverwrite(self, remove) -> None:
|
155
184
|
self._overwriteCB.setChecked(remove)
|
156
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
|
+
|
157
218
|
def getConfiguration(self) -> dict:
|
158
219
|
rescale_min_percentile, rescale_max_percentile = self.getRescalePercentiles()
|
159
220
|
return {
|
@@ -163,6 +224,8 @@ class CastVolumeWidget(qt.QWidget):
|
|
163
224
|
"overwrite": self.getOverwrite(),
|
164
225
|
"rescale_min_percentile": rescale_min_percentile,
|
165
226
|
"rescale_max_percentile": rescale_max_percentile,
|
227
|
+
"data_min": self.getDataMin(),
|
228
|
+
"data_max": self.getDataMax(),
|
166
229
|
}
|
167
230
|
|
168
231
|
def getRescalePercentiles(self) -> tuple:
|
@@ -187,7 +250,6 @@ class CastVolumeWidget(qt.QWidget):
|
|
187
250
|
overwrite = config.get("overwrite", None)
|
188
251
|
if overwrite is not None:
|
189
252
|
self.setOverwrite(overwrite)
|
190
|
-
|
191
253
|
if "rescale_percentiles" in config:
|
192
254
|
rescale_min_percentile, rescale_max_percentile = config[
|
193
255
|
"rescale_percentiles"
|
@@ -210,3 +272,10 @@ class CastVolumeWidget(qt.QWidget):
|
|
210
272
|
|
211
273
|
def _updateOutputDirVis(self, *args, **kwargs):
|
212
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()
|
@@ -33,6 +33,7 @@ from tomwer.utils import docstring
|
|
33
33
|
from silx.gui import qt
|
34
34
|
from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel as QComboBox
|
35
35
|
from tomwer.gui.reconstruction.nabu.nabuconfig import base
|
36
|
+
from tomwer.gui.reconstruction.nabu.nabuconfig.ctf import CTFConfig
|
36
37
|
from tomwer.gui.utils.inputwidget import SelectionLineEdit
|
37
38
|
from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR
|
38
39
|
from tomwer.core.process.reconstruction.nabu.utils import _NabuStages, _NabuPhaseMethod
|
@@ -75,11 +76,15 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
75
76
|
self._methodCB = QComboBox(parent=self, scrollArea=scrollArea)
|
76
77
|
for method in _NabuPhaseMethod:
|
77
78
|
self._methodCB.addItem(method.value)
|
79
|
+
idx_ctf = self._methodCB.findText(_NabuPhaseMethod.CTF.value)
|
80
|
+
self._methodCB.setItemData(
|
81
|
+
idx_ctf, "Contrast Transfert Function", qt.Qt.ToolTipRole
|
82
|
+
)
|
78
83
|
self.layout().addWidget(self._methodCB, 1, 1, 1, 3)
|
79
84
|
self.registerWidget(self._methodLabel, "required")
|
80
85
|
self.registerWidget(self._methodCB, "required")
|
81
86
|
|
82
|
-
# paganin options
|
87
|
+
# paganin & ctf options
|
83
88
|
self._paganinOpts = NabuPaganinConfig(parent=self, scrollArea=scrollArea)
|
84
89
|
self.layout().addWidget(self._paganinOpts, 2, 0, 3, 3)
|
85
90
|
|
@@ -87,6 +92,11 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
87
92
|
self._unsharpOpts = NabuUnsharpConfig(parent=self)
|
88
93
|
self.layout().addWidget(self._unsharpOpts, 6, 0, 3, 3)
|
89
94
|
|
95
|
+
# ctf options
|
96
|
+
self._ctfOpts = CTFConfig(parent=self)
|
97
|
+
self.layout().addWidget(self._ctfOpts, 9, 0, 3, 4)
|
98
|
+
self.registerWidget(self._ctfOpts, "advanced")
|
99
|
+
|
90
100
|
# spacer for style
|
91
101
|
spacer = qt.QWidget(self)
|
92
102
|
spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
|
@@ -101,12 +111,15 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
101
111
|
self._methodCB.currentIndexChanged.connect(self._methodChanged)
|
102
112
|
self._paganinOpts.sigConfChanged.connect(self._signalConfChanged)
|
103
113
|
self._unsharpOpts.sigConfChanged.connect(self._signalConfChanged)
|
114
|
+
self._ctfOpts.sigConfChanged.connect(self._signalConfChanged)
|
104
115
|
|
105
116
|
# set up
|
106
117
|
self._paganinOpts.setEnabled(self.getMethod() is not _NabuPhaseMethod.NONE)
|
118
|
+
self._ctfOpts.setEnabled(self.getMethod() is _NabuPhaseMethod.CTF)
|
107
119
|
|
108
120
|
def _methodChanged(self, *args, **kwargs):
|
109
121
|
self._paganinOpts.setEnabled(self.getMethod() is not _NabuPhaseMethod.NONE)
|
122
|
+
self._ctfOpts.setEnabled(self.getMethod() is _NabuPhaseMethod.CTF)
|
110
123
|
self._signalConfChanged("method")
|
111
124
|
|
112
125
|
def _signalConfChanged(self, param):
|
@@ -129,13 +142,15 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
129
142
|
else:
|
130
143
|
_logger.warning("unable to find method {method}")
|
131
144
|
self._unsharpOpts.setConfiguration(config)
|
145
|
+
self._ctfOpts.setConfiguration(config)
|
132
146
|
|
133
147
|
@docstring(base._NabuStageConfigBase)
|
134
148
|
def getConfiguration(self) -> dict:
|
135
149
|
configuration = {"method": self.getMethod().value}
|
136
|
-
if self.getMethod()
|
150
|
+
if self.getMethod() in (_NabuPhaseMethod.PAGANIN, _NabuPhaseMethod.CTF):
|
137
151
|
configuration.update(self._paganinOpts.getConfiguration())
|
138
152
|
configuration.update(self._unsharpOpts.getConfiguration())
|
153
|
+
configuration.update(self._ctfOpts.getConfiguration())
|
139
154
|
return configuration
|
140
155
|
|
141
156
|
def setConfigurationLevel(self, level):
|
@@ -169,22 +184,6 @@ class NabuPaganinConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
169
184
|
self.registerWidget(self._db_label, "required")
|
170
185
|
self.registerWidget(self._deltaBetaQLE, "required")
|
171
186
|
|
172
|
-
# paganin lmicron
|
173
|
-
# we skip this paramter, only used for compatibility
|
174
|
-
|
175
|
-
# paganin margin
|
176
|
-
# note: hide for now margin as it is not connected at nabu side
|
177
|
-
# self.layout().addWidget(qt.QLabel("margin"), 1, 0, 1, 1)
|
178
|
-
# self._margeQSB = qt.QSpinBox(self)
|
179
|
-
# self._margeQSB.setMinimum(0)
|
180
|
-
# self._margeQSB.setMaximum(9999)
|
181
|
-
# self._margeQSB.setToolTip(
|
182
|
-
# "Marge (in pixels) in the Paganin filtering "
|
183
|
-
# "to avoid local tomography artefacts"
|
184
|
-
# )
|
185
|
-
# self.layout().addWidget(self._margeQSB, 1, 1, 1, 1)
|
186
|
-
# self.registerWidget(self._margeQSB, "optional")
|
187
|
-
|
188
187
|
# paganin padding_type
|
189
188
|
self._paddingLabel = qt.QLabel("padding", self)
|
190
189
|
self.layout().addWidget(self._paddingLabel, 2, 0, 1, 1)
|
@@ -192,7 +191,7 @@ class NabuPaganinConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
192
191
|
self._paddingTypeCB.setToolTip(
|
193
192
|
"Padding type for the filtering step " "in Paganin/CTR."
|
194
193
|
)
|
195
|
-
for padding_type in (PaddingMode.ZEROS, PaddingMode.
|
194
|
+
for padding_type in (PaddingMode.ZEROS, PaddingMode.EDGE):
|
196
195
|
self._paddingTypeCB.addItem(padding_type.value)
|
197
196
|
self.layout().addWidget(self._paddingTypeCB, 2, 1, 1, 3)
|
198
197
|
self.registerWidget(self._paddingLabel, "advanced")
|