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
@@ -56,6 +56,8 @@ from tomwer.core.scan.scanfactory import ScanFactory
|
|
56
56
|
from tomwer.core.utils import image
|
57
57
|
from tomwer.gui.utils.buttons import PadlockButton
|
58
58
|
from tomwer.gui.utils.qt_utils import block_signals
|
59
|
+
from tomwer.gui.settings import EDITING_BACKGROUND_COLOR
|
60
|
+
from tomwer.gui.utils.step import StepSizeSelectorWidget
|
59
61
|
from tomwer.synctools.axis import QAxisRP
|
60
62
|
|
61
63
|
from .CompareImages import CompareImages
|
@@ -671,12 +673,12 @@ class _AxisManual(qt.QWidget):
|
|
671
673
|
self._manualSelectionWidget.sigResetZoomRequested.connect(
|
672
674
|
self._requestZoomReset
|
673
675
|
)
|
674
|
-
self._imgOpts.sigSubsamplingChanged.connect(self.
|
675
|
-
self._mainWidget.sigUrlChanged.connect(self.
|
676
|
+
self._imgOpts.sigSubsamplingChanged.connect(self.sigSubsamplingChanged)
|
677
|
+
self._mainWidget.sigUrlChanged.connect(self.sigUrlChanged)
|
676
678
|
|
677
679
|
# expose API
|
678
|
-
self.getShiftStep = self._displacementSelector.
|
679
|
-
self.setShiftStep = self._displacementSelector.
|
680
|
+
self.getShiftStep = self._displacementSelector.getStepSize
|
681
|
+
self.setShiftStep = self._displacementSelector.setStepSize
|
680
682
|
self.sigRoiChanged = self._roiControl.sigRoiChanged
|
681
683
|
self.sigAuto = self._shiftControl.sigAuto
|
682
684
|
self.getROIOrigin = self._roiControl.getROIOrigin
|
@@ -696,12 +698,6 @@ class _AxisManual(qt.QWidget):
|
|
696
698
|
def manual_uses_full_image(self, value):
|
697
699
|
self._roiControl.manual_uses_full_image(value)
|
698
700
|
|
699
|
-
def _urlChanged(self):
|
700
|
-
self.sigUrlChanged.emit()
|
701
|
-
|
702
|
-
def _subsamplingChanged(self):
|
703
|
-
self.sigSubsamplingChanged.emit()
|
704
|
-
|
705
701
|
def _incrementLeftShift(self):
|
706
702
|
self._incrementShift("left")
|
707
703
|
|
@@ -843,7 +839,13 @@ class _AxisManualSelection(qt.QWidget):
|
|
843
839
|
def __init__(self, parent, shift_mode):
|
844
840
|
qt.QWidget.__init__(self, parent)
|
845
841
|
self.setLayout(qt.QVBoxLayout())
|
846
|
-
self._displacementSelector =
|
842
|
+
self._displacementSelector = StepSizeSelectorWidget(
|
843
|
+
parent=self,
|
844
|
+
fine_value=0.1,
|
845
|
+
medium_value=1.0,
|
846
|
+
rough_value=None,
|
847
|
+
dtype=float,
|
848
|
+
)
|
847
849
|
self.layout().addWidget(self._displacementSelector)
|
848
850
|
|
849
851
|
self._shiftControl = _ShiftControl(parent=self, shift_mode=shift_mode)
|
@@ -856,10 +858,7 @@ class _AxisManualSelection(qt.QWidget):
|
|
856
858
|
self.layout().addWidget(self._imgOpts)
|
857
859
|
|
858
860
|
# connect signal / slot
|
859
|
-
self._roiControl.sigResetZoomRequested.connect(self.
|
860
|
-
|
861
|
-
def _requestZoomReset(self):
|
862
|
-
self.sigResetZoomRequested.emit()
|
861
|
+
self._roiControl.sigResetZoomRequested.connect(self.sigResetZoomRequested)
|
863
862
|
|
864
863
|
|
865
864
|
class _ROIControl(qt.QGroupBox):
|
@@ -895,8 +894,8 @@ class _ROIControl(qt.QGroupBox):
|
|
895
894
|
|
896
895
|
# connect signal / Slot
|
897
896
|
self._roiButton.toggled.connect(self._roiDefinition.setEnabled)
|
898
|
-
self._fullImgButton.toggled.connect(self.
|
899
|
-
self._roiButton.toggled.connect(self.
|
897
|
+
self._fullImgButton.toggled.connect(self.sigResetZoomRequested)
|
898
|
+
self._roiButton.toggled.connect(self.sigResetZoomRequested)
|
900
899
|
|
901
900
|
# expose API
|
902
901
|
self.sigRoiChanged = self._roiDefinition.sigRoiChanged
|
@@ -919,9 +918,6 @@ class _ROIControl(qt.QGroupBox):
|
|
919
918
|
else:
|
920
919
|
self._roiButton.setChecked(True)
|
921
920
|
|
922
|
-
def _requestZoomReset(self):
|
923
|
-
self.sigResetZoomRequested.emit()
|
924
|
-
|
925
921
|
|
926
922
|
class _ROIDefinition(qt.QWidget):
|
927
923
|
"""
|
@@ -1165,12 +1161,39 @@ class _ShiftInformation(qt.QWidget):
|
|
1165
1161
|
class _ShiftLineEdit(qt.QLineEdit):
|
1166
1162
|
def __init__(self, *args, **kwargs):
|
1167
1163
|
qt.QLineEdit.__init__(self, *args, **kwargs)
|
1164
|
+
self._defaultBackgroundColor = None
|
1165
|
+
# validator
|
1168
1166
|
validator = qt.QDoubleValidator(parent=self, decimals=2)
|
1169
1167
|
self.setValidator(validator)
|
1168
|
+
self._getDefaultBackgroundColor()
|
1169
|
+
# connect signal / slot
|
1170
|
+
self.textEdited.connect(self._userEditing)
|
1171
|
+
self.editingFinished.connect(self._userEndEditing)
|
1170
1172
|
|
1171
1173
|
def sizeHint(self):
|
1172
1174
|
return qt.QSize(40, 10)
|
1173
1175
|
|
1176
|
+
def _getDefaultBackgroundColor(self):
|
1177
|
+
if self._defaultBackgroundColor is None:
|
1178
|
+
self._defaultBackgroundColor = self.palette().color(
|
1179
|
+
self.backgroundRole()
|
1180
|
+
)
|
1181
|
+
return self._defaultBackgroundColor
|
1182
|
+
|
1183
|
+
def _userEditing(self, *args, **kwargs):
|
1184
|
+
palette = self.palette()
|
1185
|
+
palette.setColor(self.backgroundRole(), EDITING_BACKGROUND_COLOR)
|
1186
|
+
self.setPalette(palette)
|
1187
|
+
|
1188
|
+
def _userEndEditing(self, *args, **kwargs):
|
1189
|
+
print("user end editing")
|
1190
|
+
palette = self.palette()
|
1191
|
+
palette.setColor(
|
1192
|
+
self.backgroundRole(),
|
1193
|
+
self._getDefaultBackgroundColor(),
|
1194
|
+
)
|
1195
|
+
self.setPalette(palette)
|
1196
|
+
|
1174
1197
|
sigShiftChanged = qt.Signal(float, float)
|
1175
1198
|
"""Signal emitted ony when xLE and yLE edition is finished"""
|
1176
1199
|
|
@@ -1213,69 +1236,6 @@ class _ShiftInformation(qt.QWidget):
|
|
1213
1236
|
self.sigShiftChanged.emit(float(self._xLE.text()), float(self._yLE.text()))
|
1214
1237
|
|
1215
1238
|
|
1216
|
-
class _DisplacementSelector(qt.QGroupBox):
|
1217
|
-
"""
|
1218
|
-
Group box to define the displacement step value
|
1219
|
-
"""
|
1220
|
-
|
1221
|
-
def __init__(self, parent):
|
1222
|
-
qt.QGroupBox.__init__(self, "shift step", parent)
|
1223
|
-
self.setLayout(qt.QVBoxLayout())
|
1224
|
-
self._buttonGrp = qt.QButtonGroup(parent=self)
|
1225
|
-
self._buttonGrp.setExclusive(True)
|
1226
|
-
|
1227
|
-
self._rawButton = qt.QRadioButton("Rough (1 pixel)", parent=self)
|
1228
|
-
self.layout().addWidget(self._rawButton)
|
1229
|
-
self._buttonGrp.addButton(self._rawButton)
|
1230
|
-
|
1231
|
-
self._fineButton = qt.QRadioButton("Fine (0.1 pixel)", parent=self)
|
1232
|
-
self.layout().addWidget(self._fineButton)
|
1233
|
-
self._buttonGrp.addButton(self._fineButton)
|
1234
|
-
|
1235
|
-
self._manualWidget = qt.QWidget(parent=self)
|
1236
|
-
self._manualWidget.setLayout(qt.QHBoxLayout())
|
1237
|
-
self._manualWidget.layout().setContentsMargins(0, 0, 0, 0)
|
1238
|
-
self._manualWidget.layout().setSpacing(0)
|
1239
|
-
self._manualButton = qt.QRadioButton("Manual", parent=self._manualWidget)
|
1240
|
-
self._manualWidget.layout().addWidget(self._manualButton)
|
1241
|
-
self._manualLE = qt.QLineEdit("0.5", parent=self._manualWidget)
|
1242
|
-
validator = qt.QDoubleValidator(parent=self._manualLE, decimals=2)
|
1243
|
-
validator.setBottom(0.0)
|
1244
|
-
self._manualLE.setValidator(validator)
|
1245
|
-
self._manualWidget.layout().addWidget(self._manualLE)
|
1246
|
-
|
1247
|
-
self.layout().addWidget(self._manualWidget)
|
1248
|
-
self._manualLE.setEnabled(False)
|
1249
|
-
self._buttonGrp.addButton(self._manualButton)
|
1250
|
-
|
1251
|
-
self._rawButton.setChecked(True)
|
1252
|
-
|
1253
|
-
# signal / slot connection
|
1254
|
-
self._manualButton.toggled.connect(self._manualLE.setEnabled)
|
1255
|
-
|
1256
|
-
def getShiftStep(self):
|
1257
|
-
"""
|
1258
|
-
|
1259
|
-
:return: displacement shift defined
|
1260
|
-
:rtype: float
|
1261
|
-
"""
|
1262
|
-
if self._rawButton.isChecked():
|
1263
|
-
return 1.0
|
1264
|
-
elif self._fineButton.isChecked():
|
1265
|
-
return 0.1
|
1266
|
-
else:
|
1267
|
-
return float(self._manualLE.text())
|
1268
|
-
|
1269
|
-
def setShiftStep(self, value):
|
1270
|
-
"""
|
1271
|
-
|
1272
|
-
:param float value: shift step
|
1273
|
-
"""
|
1274
|
-
assert type(value) is float
|
1275
|
-
self._manualButton.setChecked(True)
|
1276
|
-
self._manualLE.setText(str(value))
|
1277
|
-
|
1278
|
-
|
1279
1239
|
class _AxisOptionsWidget(qt.QWidget):
|
1280
1240
|
"""GUI to tune the axis algorithm"""
|
1281
1241
|
|
@@ -1501,9 +1461,7 @@ class AxisTabWidget(qt.QTabWidget):
|
|
1501
1461
|
self.getEstimatedCor = self._calculationWidget.getEstimatedCor
|
1502
1462
|
|
1503
1463
|
# connect signal / slot
|
1504
|
-
self._calculationWidget.sigLockModeChanged.connect(
|
1505
|
-
self._propagateSigLockModeChanged
|
1506
|
-
)
|
1464
|
+
self._calculationWidget.sigLockModeChanged.connect(self.sigLockModeChanged)
|
1507
1465
|
self.sigModeChanged.connect(self._updatePossibleInput)
|
1508
1466
|
self._inputWidget._sigUrlChanged.connect(self._urlChanged)
|
1509
1467
|
# not very nice but very convenient to have the setting near at the same level
|
@@ -1526,9 +1484,6 @@ class AxisTabWidget(qt.QTabWidget):
|
|
1526
1484
|
def _urlChanged(self):
|
1527
1485
|
self.sigUrlChanged.emit()
|
1528
1486
|
|
1529
|
-
def _propagateSigLockModeChanged(self, lock):
|
1530
|
-
self.sigLockModeChanged.emit(lock)
|
1531
|
-
|
1532
1487
|
def getMode(self):
|
1533
1488
|
"""Return algorithm to use for axis calculation"""
|
1534
1489
|
return self._calculationWidget.getMode()
|
@@ -1608,6 +1563,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1608
1563
|
),
|
1609
1564
|
("separator", None),
|
1610
1565
|
(axis_mode.AxisMode.composite_coarse_to_fine, "A auto-Cor method"),
|
1566
|
+
(axis_mode.AxisMode.near, "Alias to composite_coarse_to_fine"),
|
1611
1567
|
("separator", None),
|
1612
1568
|
(axis_mode.AxisMode.manual, "Enter or find manually the COR value"),
|
1613
1569
|
("separator", None),
|
@@ -1762,8 +1718,11 @@ class _CalculationWidget(qt.QWidget):
|
|
1762
1718
|
with block_signals(self._axis_params):
|
1763
1719
|
side = self.getSide()
|
1764
1720
|
self._nearOptsWidget.setVisible(
|
1765
|
-
|
1766
|
-
|
1721
|
+
(
|
1722
|
+
mode is axis_mode.AxisMode.composite_coarse_to_fine
|
1723
|
+
and side == "near"
|
1724
|
+
)
|
1725
|
+
or (mode is axis_mode.AxisMode.near)
|
1767
1726
|
)
|
1768
1727
|
self._corOptsWidget.setVisible(
|
1769
1728
|
mode
|
@@ -1784,6 +1743,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1784
1743
|
axis_mode.AxisMode.sliding_window_radios,
|
1785
1744
|
axis_mode.AxisMode.sino_coarse_to_fine,
|
1786
1745
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1746
|
+
axis_mode.AxisMode.near,
|
1787
1747
|
)
|
1788
1748
|
)
|
1789
1749
|
if mode in (
|
@@ -1795,6 +1755,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1795
1755
|
axis_mode.AxisMode.sliding_window_radios,
|
1796
1756
|
axis_mode.AxisMode.sino_coarse_to_fine,
|
1797
1757
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1758
|
+
axis_mode.AxisMode.near,
|
1798
1759
|
):
|
1799
1760
|
self._lockMethodPB.setVisible(True)
|
1800
1761
|
else:
|
@@ -1807,6 +1768,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1807
1768
|
axis_mode.AxisMode.sliding_window_sinogram,
|
1808
1769
|
axis_mode.AxisMode.sliding_window_radios,
|
1809
1770
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1771
|
+
axis_mode.AxisMode.near,
|
1810
1772
|
)
|
1811
1773
|
self._sideWidget.setVisible(side_visible)
|
1812
1774
|
if side_visible is True:
|
@@ -1823,6 +1785,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1823
1785
|
axis_mode.AxisMode.sliding_window_sinogram,
|
1824
1786
|
axis_mode.AxisMode.sliding_window_radios,
|
1825
1787
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1788
|
+
axis_mode.AxisMode.near,
|
1826
1789
|
):
|
1827
1790
|
return
|
1828
1791
|
else:
|
@@ -1836,8 +1799,12 @@ class _CalculationWidget(qt.QWidget):
|
|
1836
1799
|
):
|
1837
1800
|
values.append("all")
|
1838
1801
|
|
1839
|
-
if mode
|
1802
|
+
if mode is axis_mode.AxisMode.composite_coarse_to_fine:
|
1840
1803
|
values.append("near")
|
1804
|
+
elif mode is axis_mode.AxisMode.near:
|
1805
|
+
values = [
|
1806
|
+
"near",
|
1807
|
+
]
|
1841
1808
|
|
1842
1809
|
for value in values:
|
1843
1810
|
self._sideCB.addItem(value)
|
@@ -1865,6 +1832,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1865
1832
|
axis_mode.AxisMode.sliding_window_radios,
|
1866
1833
|
axis_mode.AxisMode.sino_coarse_to_fine,
|
1867
1834
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1835
|
+
axis_mode.AxisMode.near,
|
1868
1836
|
):
|
1869
1837
|
raise ValueError(
|
1870
1838
|
"Unable to lock the current mode is not an automatic algorithm"
|
@@ -1878,6 +1846,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1878
1846
|
axis_mode.AxisMode.sliding_window_radios,
|
1879
1847
|
axis_mode.AxisMode.sino_coarse_to_fine,
|
1880
1848
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1849
|
+
axis_mode.AxisMode.near,
|
1881
1850
|
):
|
1882
1851
|
raise ValueError("Unable to lock %s this is not a lockable mode")
|
1883
1852
|
|
@@ -1929,10 +1898,12 @@ class _CalculationWidget(qt.QWidget):
|
|
1929
1898
|
|
1930
1899
|
def _sideChanged(self, *args, **kwargs):
|
1931
1900
|
side = self.getSide()
|
1932
|
-
|
1901
|
+
if side not in ("", None):
|
1902
|
+
self._axis_params.side = side
|
1933
1903
|
mode = self.getMode()
|
1934
1904
|
self._nearOptsWidget.setVisible(
|
1935
|
-
mode
|
1905
|
+
(mode is axis_mode.AxisMode.composite_coarse_to_fine and side == "near")
|
1906
|
+
or mode is axis_mode.AxisMode.near
|
1936
1907
|
)
|
1937
1908
|
|
1938
1909
|
def getCorOptions(self):
|
@@ -1982,6 +1953,7 @@ class _CalculationWidget(qt.QWidget):
|
|
1982
1953
|
axis_mode.AxisMode.sliding_window_sinogram,
|
1983
1954
|
axis_mode.AxisMode.sliding_window_radios,
|
1984
1955
|
axis_mode.AxisMode.composite_coarse_to_fine,
|
1956
|
+
axis_mode.AxisMode.near,
|
1985
1957
|
):
|
1986
1958
|
self._sideWidget.setVisible(True)
|
1987
1959
|
else:
|
@@ -2503,9 +2475,22 @@ class _ManualFramesSelection(qt.QWidget):
|
|
2503
2475
|
_logger.warning("no angles available, unable to get '+180°' frame")
|
2504
2476
|
else:
|
2505
2477
|
angle = float(self._frame1CB.currentText())
|
2506
|
-
|
2478
|
+
# look for the closest 'associated' angle.
|
2479
|
+
# as the angles are not limited to [0-360] we need to check for any value.
|
2480
|
+
# if the angle is on the first part of the acquisition we expect to find it near angle +180
|
2481
|
+
# if it is on the second part (for 360 degree) we expect to find it on the first part (0-180)
|
2482
|
+
closest_pls_180_angle = self._getClosestAssociatedAngle(
|
2507
2483
|
angle + 180.0, self._anglesAvailable
|
2508
2484
|
)
|
2485
|
+
score_add = abs(closest_pls_180_angle - angle)
|
2486
|
+
closest_minus_180_angle = self._getClosestAssociatedAngle(
|
2487
|
+
angle - 180.0, self._anglesAvailable
|
2488
|
+
)
|
2489
|
+
score_sub = abs(closest_minus_180_angle - angle)
|
2490
|
+
if score_add >= score_sub:
|
2491
|
+
closest_180_angle = closest_pls_180_angle
|
2492
|
+
else:
|
2493
|
+
closest_180_angle = closest_minus_180_angle
|
2509
2494
|
item_idx = self._frame2CB.findText(self._angleToStr(closest_180_angle))
|
2510
2495
|
if item_idx < 0:
|
2511
2496
|
_logger.error(f"Unable to find item for angle {closest_180_angle}")
|
@@ -36,7 +36,8 @@ from silx.gui import qt
|
|
36
36
|
from silx.gui.dialog.DataFileDialog import DataFileDialog
|
37
37
|
from silx.io.url import DataUrl
|
38
38
|
|
39
|
-
from tomwer.core import settings
|
39
|
+
from tomwer.core import settings
|
40
|
+
from tomwer.core.utils.lbsram import is_low_on_memory
|
40
41
|
from tomwer.core.process.reconstruction.darkref.darkrefscopy import DarkRefsCopy
|
41
42
|
from tomwer.gui.reconstruction.darkref.darkrefwidget import DarkRefWidget
|
42
43
|
from tomwer.io.utils import get_default_directory
|
@@ -117,7 +118,7 @@ class DarkRefAndCopyWidget(DarkRefWidget):
|
|
117
118
|
# Security: if lbs is full, skip requesting fir user ref
|
118
119
|
if (
|
119
120
|
settings.isOnLbsram(scanID)
|
120
|
-
and
|
121
|
+
and is_low_on_memory(settings.get_lbsram_path()) is True
|
121
122
|
):
|
122
123
|
# if computer is running into low memory on lbsram skip it
|
123
124
|
mess = (
|
@@ -325,9 +325,9 @@ class _AnglesWidget(qt.QWidget):
|
|
325
325
|
self._spacerBot.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
|
326
326
|
self.layout().addWidget(self._spacerBot)
|
327
327
|
|
328
|
-
self._volAngleX.sigEdited.connect(self.
|
329
|
-
self._volAngleY.sigEdited.connect(self.
|
330
|
-
self._volAngleZ.sigEdited.connect(self.
|
328
|
+
self._volAngleX.sigEdited.connect(self.sigAnglesEdited)
|
329
|
+
self._volAngleY.sigEdited.connect(self.sigAnglesEdited)
|
330
|
+
self._volAngleZ.sigEdited.connect(self.sigAnglesEdited)
|
331
331
|
|
332
332
|
# aliases
|
333
333
|
self.setVolumeAngleX = self._volAngleX.setAngle
|
@@ -337,9 +337,6 @@ class _AnglesWidget(qt.QWidget):
|
|
337
337
|
self.getVolumeAngleY = self._volAngleY.getAngle
|
338
338
|
self.getVolumeAngleZ = self._volAngleZ.getAngle
|
339
339
|
|
340
|
-
def _haveBeenEdited(self):
|
341
|
-
self.sigAnglesEdited.emit()
|
342
|
-
|
343
340
|
def set(self, xAngle, yAngle, zAngle):
|
344
341
|
self.blockSignals(True)
|
345
342
|
self.setVolumeAngleX(xAngle)
|
@@ -39,7 +39,7 @@ from tomwer.core.process.reconstruction.nabu.castvolume import (
|
|
39
39
|
RESCALE_MAX_PERCENTILE,
|
40
40
|
RESCALE_MIN_PERCENTILE,
|
41
41
|
)
|
42
|
-
from tomwer.core.process.reconstruction.
|
42
|
+
from tomwer.core.process.reconstruction.output import NabuOutputFileFormat
|
43
43
|
from tomwer.gui.qlefilesystem import QLFileSystem
|
44
44
|
from tomwer.gui.reconstruction.nabu.nabuconfig.output import QNabuFileFormatComboBox
|
45
45
|
from nxtomomill.io.utils import convert_str_to_tuple
|
@@ -29,13 +29,13 @@ __date__ = "02/12/2021"
|
|
29
29
|
|
30
30
|
|
31
31
|
from silx.gui import qt
|
32
|
-
from
|
32
|
+
from nxtomo.nxobject.nxdetector import ImageKey
|
33
33
|
|
34
|
-
from tomwer.core.scan.
|
34
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan
|
35
35
|
from tomwer.core.utils.nxtomoutils import get_n_series
|
36
36
|
|
37
37
|
|
38
|
-
def check_dark_series(scan:
|
38
|
+
def check_dark_series(scan: NXtomoScan, logger=None, user_input: bool = True) -> bool:
|
39
39
|
"""
|
40
40
|
check:
|
41
41
|
- if scan has computed_dark attached. If there is more than one then ask confirmation to the user to process the dataset
|
@@ -43,15 +43,15 @@ def check_dark_series(scan: HDF5TomoScan, logger=None, user_input: bool = True)
|
|
43
43
|
|
44
44
|
ask confirmation for processing is done by a pop up dialog.
|
45
45
|
|
46
|
-
:param
|
46
|
+
:param NXtomoScan scan: scan to check
|
47
47
|
:param bool user_input: if True and if n series of flat is invalid then ask the user to confirm the processing. Else print a warning and refuse processing
|
48
48
|
|
49
49
|
:return: True if processing can be done else False
|
50
50
|
:note: user can 'force' the processing to be done
|
51
51
|
"""
|
52
|
-
if not isinstance(scan,
|
52
|
+
if not isinstance(scan, NXtomoScan):
|
53
53
|
raise TypeError(
|
54
|
-
f"scan is expected to be an instance of {
|
54
|
+
f"scan is expected to be an instance of {NXtomoScan} not a {type(scan)}"
|
55
55
|
)
|
56
56
|
try:
|
57
57
|
image_keys = scan.image_keys
|
@@ -82,13 +82,13 @@ def check_dark_series(scan: HDF5TomoScan, logger=None, user_input: bool = True)
|
|
82
82
|
return True
|
83
83
|
|
84
84
|
|
85
|
-
def check_flat_series(scan:
|
85
|
+
def check_flat_series(scan: NXtomoScan, logger, user_input: bool = True) -> bool:
|
86
86
|
"""
|
87
87
|
Insure the scan contains at least one serie of flat. Otherwise warn the user nabu will not be able to process
|
88
88
|
"""
|
89
|
-
if not isinstance(scan,
|
89
|
+
if not isinstance(scan, NXtomoScan):
|
90
90
|
raise TypeError(
|
91
|
-
f"scan is expected to be an instance of {
|
91
|
+
f"scan is expected to be an instance of {NXtomoScan} not a {type(scan)}"
|
92
92
|
)
|
93
93
|
try:
|
94
94
|
image_keys = scan.image_keys
|
@@ -22,17 +22,28 @@ class HelicalPrepareWeightsDouble(qt.QWidget):
|
|
22
22
|
)
|
23
23
|
self.layout().addWidget(self._outputFilePathQLE, 0, 2, 1, 1)
|
24
24
|
|
25
|
-
#
|
26
|
-
self.
|
27
|
-
self.layout().addWidget(self.
|
28
|
-
self.
|
29
|
-
self.
|
30
|
-
self.
|
31
|
-
self.
|
25
|
+
# transition_width_vertical
|
26
|
+
self._verticalTransitionWidthQDSP = qt.QLabel("transition width", self)
|
27
|
+
self.layout().addWidget(self._verticalTransitionWidthQDSP, 1, 0, 1, 1)
|
28
|
+
self._verticalTransitionWidthQDSP = qt.QDoubleSpinBox(self)
|
29
|
+
self._verticalTransitionWidthQDSP.setRange(0.0, 99999999)
|
30
|
+
self._verticalTransitionWidthQDSP.setValue(50.0)
|
31
|
+
self._verticalTransitionWidthQDSP.setToolTip(
|
32
32
|
"the transition width is used to determine how the weights are apodised near the upper and lower border"
|
33
33
|
)
|
34
34
|
# TODO: improve tooltip of this
|
35
|
-
self.layout().addWidget(self.
|
35
|
+
self.layout().addWidget(self._verticalTransitionWidthQDSP, 1, 1, 1, 2)
|
36
|
+
|
37
|
+
# transition_width_vertical
|
38
|
+
self._horizontalTransitionWidthQDSP = qt.QLabel("transition width", self)
|
39
|
+
self.layout().addWidget(self._horizontalTransitionWidthQDSP, 1, 0, 1, 1)
|
40
|
+
self._horizontalTransitionWidthQDSP = qt.QDoubleSpinBox(self)
|
41
|
+
self._horizontalTransitionWidthQDSP.setRange(0.0, 99999999)
|
42
|
+
self._horizontalTransitionWidthQDSP.setValue(50.0)
|
43
|
+
self._horizontalTransitionWidthQDSP.setToolTip(
|
44
|
+
"the transition width is used to determine how the weights are apodised near the upper and lower border"
|
45
|
+
)
|
46
|
+
self.layout().addWidget(self._horizontalTransitionWidthQDSP, 1, 1, 1, 2)
|
36
47
|
|
37
48
|
spacer = qt.QWidget(parent=self)
|
38
49
|
spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
|
@@ -40,7 +51,8 @@ class HelicalPrepareWeightsDouble(qt.QWidget):
|
|
40
51
|
|
41
52
|
# connect signal / slot
|
42
53
|
self._outputFilePathQLE.editingFinished.connect(self._changed)
|
43
|
-
self.
|
54
|
+
self._verticalTransitionWidthQDSP.valueChanged.connect(self._changed)
|
55
|
+
self._horizontalTransitionWidthQDSP.valueChanged.connect(self._changed)
|
44
56
|
|
45
57
|
def _changed(self, *args, **kwargs):
|
46
58
|
self.sigConfigChanged.emit()
|
@@ -48,7 +60,8 @@ class HelicalPrepareWeightsDouble(qt.QWidget):
|
|
48
60
|
def getConfiguration(self) -> dict:
|
49
61
|
return {
|
50
62
|
"processes_file": self._outputFilePathQLE.text(),
|
51
|
-
"
|
63
|
+
"transition_width_vertical": self._verticalTransitionWidthQDSP.value(),
|
64
|
+
"transition_width_horizontal": self._horizontalTransitionWidthQDSP.value(),
|
52
65
|
}
|
53
66
|
|
54
67
|
def setConfiguration(self, config: dict):
|
@@ -56,6 +69,10 @@ class HelicalPrepareWeightsDouble(qt.QWidget):
|
|
56
69
|
if processes_file is not None:
|
57
70
|
self._outputFilePathQLE.setText(processes_file)
|
58
71
|
|
59
|
-
transition_width = config.get("
|
72
|
+
transition_width = config.get("transition_width_vertical", None)
|
73
|
+
if transition_width is not None:
|
74
|
+
self._verticalTransitionWidthQDSP.setValue(float(transition_width))
|
75
|
+
|
76
|
+
transition_width = config.get("transition_width_horizontal", None)
|
60
77
|
if transition_width is not None:
|
61
|
-
self.
|
78
|
+
self._horizontalTransitionWidthQDSP.setValue(float(transition_width))
|
@@ -30,10 +30,8 @@ __date__ = "11/02/2020"
|
|
30
30
|
|
31
31
|
from typing import Union
|
32
32
|
|
33
|
-
from tomwer.core.process.reconstruction.nabu.utils import
|
34
|
-
|
35
|
-
_NabuStages,
|
36
|
-
)
|
33
|
+
from tomwer.core.process.reconstruction.nabu.utils import _NabuStages
|
34
|
+
from tomwer.gui.configuration.level import ConfigurationLevel
|
37
35
|
|
38
36
|
|
39
37
|
class _FilteringObject:
|