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
@@ -31,7 +31,7 @@ __date__ = "15/09/2017"
|
|
31
31
|
import logging
|
32
32
|
from silx.gui import qt
|
33
33
|
from silx.gui.plot import PlotWidget
|
34
|
-
from typing import Union
|
34
|
+
from typing import Union, Optional
|
35
35
|
from collections.abc import Iterable
|
36
36
|
from collections import OrderedDict
|
37
37
|
import numpy
|
@@ -50,7 +50,6 @@ class QSliceSelectorDialog(qt.QDialog):
|
|
50
50
|
|
51
51
|
def __init__(self, parent, n_required_slice=None):
|
52
52
|
qt.QDialog.__init__(self, parent=parent)
|
53
|
-
self.__selection = None
|
54
53
|
self.setLayout(qt.QVBoxLayout())
|
55
54
|
self.setWindowTitle("select slices on radio")
|
56
55
|
|
@@ -87,14 +86,11 @@ class QSliceSelectorDialog(qt.QDialog):
|
|
87
86
|
selection = selection.replace(")", "")
|
88
87
|
selection = selection.replace(" ", "")
|
89
88
|
selection = selection.replace(",", ";")
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
pass
|
96
|
-
else:
|
97
|
-
self.__selection = selection
|
89
|
+
try:
|
90
|
+
selection = [int(item) for item in selection.split(";")]
|
91
|
+
except Exception as e:
|
92
|
+
logger.error(f"Fail to set selection. Error is {e}")
|
93
|
+
self.mainWidget.setSelection(selection)
|
98
94
|
|
99
95
|
def getSelection(self) -> tuple:
|
100
96
|
"""
|
@@ -102,7 +98,7 @@ class QSliceSelectorDialog(qt.QDialog):
|
|
102
98
|
:return: the selection of slices to use
|
103
99
|
:rtype: tuple
|
104
100
|
"""
|
105
|
-
return self.
|
101
|
+
return self.mainWidget.getSelection()
|
106
102
|
|
107
103
|
def exec_(self):
|
108
104
|
if not self.mainWidget._has_data:
|
@@ -111,13 +107,9 @@ class QSliceSelectorDialog(qt.QDialog):
|
|
111
107
|
qt.QMessageBox.warning(self, "Selection tool not available", mess)
|
112
108
|
self.reject()
|
113
109
|
else:
|
114
|
-
|
115
|
-
res = qt.QDialog.exec_(self)
|
116
|
-
if res == qt.QDialog.Accepted:
|
117
|
-
self.setSelection(self.mainWidget.getSelection())
|
118
|
-
return res
|
110
|
+
return qt.QDialog.exec_(self)
|
119
111
|
|
120
|
-
def nRequiredSlice(self) ->
|
112
|
+
def nRequiredSlice(self) -> Optional[int]:
|
121
113
|
return self.mainWidget.nRequiredSlice()
|
122
114
|
|
123
115
|
|
@@ -139,7 +131,7 @@ class QLineSelector(qt.QWidget):
|
|
139
131
|
# connect signal / slot
|
140
132
|
self._plot.sigPlotSignal.connect(self._plotDrawEvent)
|
141
133
|
|
142
|
-
def nRequiredSlice(self) ->
|
134
|
+
def nRequiredSlice(self) -> Optional[int]:
|
143
135
|
return self._n_required_slice
|
144
136
|
|
145
137
|
def setData(self, data: numpy.ndarray):
|
@@ -160,7 +152,7 @@ class QLineSelector(qt.QWidget):
|
|
160
152
|
:rtype: tuple
|
161
153
|
"""
|
162
154
|
res = []
|
163
|
-
for
|
155
|
+
for _, marker in self.__selection.items():
|
164
156
|
res.append(int(marker.getPoints()[0][1]))
|
165
157
|
return tuple(sorted(res))
|
166
158
|
|
@@ -200,8 +192,8 @@ class QLineSelector(qt.QWidget):
|
|
200
192
|
logger.warning("requested slice out of the data, ignored")
|
201
193
|
return
|
202
194
|
|
203
|
-
while self.nSelected() >= self.nRequiredSlice():
|
204
|
-
|
195
|
+
# while self.nSelected() >= self.nRequiredSlice():
|
196
|
+
# self.removeSlice(row=int(list(self.__selection.items())[0][0]))
|
205
197
|
|
206
198
|
inf = 10000
|
207
199
|
legend = self._getLegend(row_n=row_n)
|
@@ -29,8 +29,6 @@ __date__ = "04/02/2020"
|
|
29
29
|
|
30
30
|
from typing import Optional
|
31
31
|
from silx.gui import qt
|
32
|
-
import os
|
33
|
-
|
34
32
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
35
33
|
|
36
34
|
|
@@ -66,8 +64,8 @@ class ScanNameLabelAndShape(qt.QWidget):
|
|
66
64
|
self.clear()
|
67
65
|
else:
|
68
66
|
assert isinstance(scan, TomwerScanBase)
|
69
|
-
self._scanNameLabel.setText(
|
70
|
-
self._scanNameLabel.setToolTip(scan.
|
67
|
+
self._scanNameLabel.setText(scan.get_identifier().short_description())
|
68
|
+
self._scanNameLabel.setToolTip(scan.get_identifier().to_str())
|
71
69
|
|
72
70
|
shape_x = scan.dim_1 if scan.dim_1 is not None else "?"
|
73
71
|
shape_y = scan.dim_2 if scan.dim_2 is not None else "?"
|
tomwer/gui/utils/slider.py
CHANGED
@@ -29,8 +29,8 @@ __license__ = "MIT"
|
|
29
29
|
__date__ = "17/02/2021"
|
30
30
|
|
31
31
|
|
32
|
-
from silx.gui import qt
|
33
32
|
import numpy
|
33
|
+
from silx.gui import qt
|
34
34
|
|
35
35
|
|
36
36
|
class LogSlider(qt.QWidget):
|
@@ -92,104 +92,3 @@ class LogSlider(qt.QWidget):
|
|
92
92
|
|
93
93
|
def setValue(self, value):
|
94
94
|
self._valueQBSB.setValue(value)
|
95
|
-
|
96
|
-
|
97
|
-
class _TickBar(qt.QWidget):
|
98
|
-
_FONT_SIZE = 6
|
99
|
-
|
100
|
-
def __init__(self, parent=None):
|
101
|
-
qt.QWidget.__init__(self, parent)
|
102
|
-
self._min = 1
|
103
|
-
self._max = 100
|
104
|
-
self._ticks = {}
|
105
|
-
|
106
|
-
def setRange(self, min_, max_):
|
107
|
-
self._min = min_
|
108
|
-
self._max = max_
|
109
|
-
tick_names = self._ticks.values()
|
110
|
-
for tick_name in tick_names:
|
111
|
-
tick_value = self._ticks[tick_name]
|
112
|
-
self._ticks[tick_name] = min(max(self._min, tick_value), self._max)
|
113
|
-
|
114
|
-
def addTick(self, name, value):
|
115
|
-
value = min(max(self._valueQBSB.minimum(), value), self._valueQBSB.maximum())
|
116
|
-
self._ticks[name] = value
|
117
|
-
|
118
|
-
def paintEvent(self, event):
|
119
|
-
painter = qt.QPainter(self)
|
120
|
-
font = painter.font()
|
121
|
-
font.setPixelSize(_TickBar._FONT_SIZE)
|
122
|
-
painter.setFont(font)
|
123
|
-
|
124
|
-
# paint ticks
|
125
|
-
for tick_name, tick_value in self._ticks.items():
|
126
|
-
self._paintTick(tick_value, painter, majorTick=True)
|
127
|
-
|
128
|
-
def _getRelativePosition(self, val):
|
129
|
-
"""Return the relative position of val according to min and max value"""
|
130
|
-
if self._normalizer is None:
|
131
|
-
return 0.0
|
132
|
-
normMin, normMax, normVal = self._normalizer.apply(
|
133
|
-
[self._vmin, self._vmax, val], self._vmin, self._vmax
|
134
|
-
)
|
135
|
-
|
136
|
-
if normMin == normMax:
|
137
|
-
return 0.0
|
138
|
-
else:
|
139
|
-
return 1.0 - (normVal - normMin) / (normMax - normMin)
|
140
|
-
|
141
|
-
def _paintTick(self, val, painter, majorTick=True):
|
142
|
-
"""
|
143
|
-
|
144
|
-
:param bool majorTick: if False will never draw text and will set a line
|
145
|
-
with a smaller width
|
146
|
-
"""
|
147
|
-
fm = qt.QFontMetrics(painter.font())
|
148
|
-
viewportHeight = self.rect().height() - self.margin * 2 - 1
|
149
|
-
relativePos = self._getRelativePosition(val)
|
150
|
-
height = int(viewportHeight * relativePos + self.margin)
|
151
|
-
lineWidth = _TickBar._LINE_WIDTH
|
152
|
-
if majorTick is False:
|
153
|
-
lineWidth /= 2
|
154
|
-
|
155
|
-
painter.drawLine(
|
156
|
-
qt.QLine(int(self.width() - lineWidth), height, self.width(), height)
|
157
|
-
)
|
158
|
-
|
159
|
-
if self.displayValues and majorTick is True:
|
160
|
-
painter.drawText(
|
161
|
-
qt.QPoint(0, int(height + fm.height() / 2)), self.form.format(val)
|
162
|
-
)
|
163
|
-
|
164
|
-
|
165
|
-
class LogSliderWithTick(LogSlider):
|
166
|
-
def __init__(self, parent=None):
|
167
|
-
super().__init__(parent=parent)
|
168
|
-
# register ticks to be displayed with name as key and value as value
|
169
|
-
# Double spin box
|
170
|
-
self._ticksBar = _TickBar(self)
|
171
|
-
self.layout().addWidget(self._ticksBar, 1, 0, 1, 1)
|
172
|
-
|
173
|
-
def addTick(self, name, value):
|
174
|
-
self._ticksBar.addTick(name, value)
|
175
|
-
|
176
|
-
def setRange(self, min_: float, max_: float) -> None:
|
177
|
-
super().setRange(min_=min_, max_=max_)
|
178
|
-
if hasattr(self, "_ticksBar"):
|
179
|
-
self._ticksBar.setRange(min_=min_, max_=max_)
|
180
|
-
|
181
|
-
def clearTicks(self):
|
182
|
-
self._ticks.clear()
|
183
|
-
|
184
|
-
|
185
|
-
if __name__ == "__main__":
|
186
|
-
app = qt.QApplication([])
|
187
|
-
slider = LogSliderWithTick()
|
188
|
-
slider.setFixedWidth(250)
|
189
|
-
# slider.addTick("toto", 1)
|
190
|
-
# slider.addTick("tata", 10)
|
191
|
-
# slider.addTick("titi", 100)
|
192
|
-
slider.setRange(0.01, 1000)
|
193
|
-
slider.setValue(10)
|
194
|
-
slider.show()
|
195
|
-
app.exec_()
|
tomwer/gui/utils/unitsystem.py
CHANGED
@@ -34,6 +34,7 @@ __date__ = "21/09/2018"
|
|
34
34
|
|
35
35
|
from silx.gui import qt
|
36
36
|
from tomoscan.unitsystem import metricsystem
|
37
|
+
from tomwer.core.utils.char import MU_CHAR
|
37
38
|
import logging
|
38
39
|
|
39
40
|
_logger = logging.getLogger(__name__)
|
@@ -48,8 +49,20 @@ class MetricEntry(qt.QWidget):
|
|
48
49
|
:param str: base_unit. Default way to present a value when setted
|
49
50
|
"""
|
50
51
|
|
52
|
+
class DoubleValidator(qt.QDoubleValidator):
|
53
|
+
def __init__(self, *args, **kwargs):
|
54
|
+
super().__init__(*args, **kwargs)
|
55
|
+
self.setNotation(qt.QDoubleValidator.ScientificNotation)
|
56
|
+
|
57
|
+
def validate(self, a0: str, a1: int):
|
58
|
+
if a0 == "unknown":
|
59
|
+
return (qt.QDoubleValidator.Acceptable, a0, a1)
|
60
|
+
else:
|
61
|
+
return super().validate(a0, a1)
|
62
|
+
|
51
63
|
_CONVERSION = {
|
52
64
|
"nm": metricsystem.nanometer.value,
|
65
|
+
f"{MU_CHAR}m": metricsystem.micrometer.value,
|
53
66
|
"mm": metricsystem.millimeter.value,
|
54
67
|
"cm": metricsystem.centimeter.value,
|
55
68
|
"m": metricsystem.meter.value,
|
@@ -58,24 +71,29 @@ class MetricEntry(qt.QWidget):
|
|
58
71
|
def __init__(self, name, default_unit="m", parent=None):
|
59
72
|
qt.QWidget.__init__(self, parent)
|
60
73
|
assert type(default_unit) is str
|
61
|
-
assert default_unit in ("nm", "mm", "cm", "m")
|
74
|
+
assert default_unit in ("nm", "mm", "cm", "m", f"{MU_CHAR}m")
|
62
75
|
self._base_unit = default_unit
|
63
76
|
|
64
77
|
self.setLayout(qt.QHBoxLayout())
|
65
78
|
self._label = qt.QLabel(name, parent=self)
|
66
79
|
self.layout().addWidget(self._label)
|
67
80
|
self._qlePixelSize = qt.QLineEdit("0.0", parent=self)
|
68
|
-
self._qlePixelSize.setValidator(
|
81
|
+
self._qlePixelSize.setValidator(self.DoubleValidator(self._qlePixelSize))
|
69
82
|
self.layout().addWidget(self._qlePixelSize)
|
70
83
|
|
71
84
|
self._qcbUnit = qt.QComboBox(parent=self)
|
72
85
|
self._qcbUnit.addItem("nm")
|
86
|
+
self._qcbUnit.addItem(f"{MU_CHAR}m")
|
73
87
|
self._qcbUnit.addItem("mm")
|
74
88
|
self._qcbUnit.addItem("cm")
|
75
89
|
self._qcbUnit.addItem("m")
|
76
90
|
self.layout().addWidget(self._qcbUnit)
|
77
91
|
self._resetBaseUnit()
|
78
92
|
|
93
|
+
def setReadOnly(self, a0: bool):
|
94
|
+
self._qlePixelSize.setReadOnly(a0)
|
95
|
+
self._qcbUnit.setEnabled(not a0)
|
96
|
+
|
79
97
|
def getCurrentUnit(self):
|
80
98
|
assert self._qcbUnit.currentText() in self._CONVERSION
|
81
99
|
return self._CONVERSION[self._qcbUnit.currentText()]
|
@@ -86,14 +104,22 @@ class MetricEntry(qt.QWidget):
|
|
86
104
|
:param float value: pixel size in international metric system (meter)
|
87
105
|
"""
|
88
106
|
_value = value
|
89
|
-
if
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
107
|
+
if _value in (None, "unknown"):
|
108
|
+
txt = "unknown"
|
109
|
+
elif isinstance(_value, str):
|
110
|
+
if "..." in _value:
|
111
|
+
txt = _value
|
112
|
+
else:
|
113
|
+
try:
|
114
|
+
_value = float(_value)
|
115
|
+
except Exception as error:
|
116
|
+
raise ValueError("Given string does not represent a float", error)
|
117
|
+
else:
|
118
|
+
assert isinstance(_value, float)
|
119
|
+
txt = str(_value)
|
120
|
+
else:
|
121
|
+
txt = str(_value)
|
122
|
+
self._qlePixelSize.setText(txt)
|
97
123
|
self._resetBaseUnit()
|
98
124
|
|
99
125
|
def _resetBaseUnit(self):
|
@@ -110,7 +136,18 @@ class MetricEntry(qt.QWidget):
|
|
110
136
|
:return: the value in meter
|
111
137
|
:rtype: float
|
112
138
|
"""
|
113
|
-
|
139
|
+
if self._qlePixelSize.text() in ("unknown", ""):
|
140
|
+
return None
|
141
|
+
else:
|
142
|
+
return float(self._qlePixelSize.text()) * self.getCurrentUnit()
|
143
|
+
|
144
|
+
def setValidator(self, validator):
|
145
|
+
self._qlePixelSize.setValidator(validator)
|
146
|
+
|
147
|
+
def setUnit(self, unit):
|
148
|
+
unit = str(metricsystem.MetricSystem.from_value(unit))
|
149
|
+
idx = self._qcbUnit.findText(unit)
|
150
|
+
self._qcbUnit.setCurrentIndex(idx)
|
114
151
|
|
115
152
|
|
116
153
|
class CentimeterEntry(MetricEntry):
|
@@ -45,14 +45,14 @@ from tomwer.core.volume.volumefactory import VolumeFactory
|
|
45
45
|
|
46
46
|
try:
|
47
47
|
from PIL import Image
|
48
|
-
except ImportError:
|
49
|
-
has_PIL = False
|
48
|
+
except ImportError: # pragma: no cover
|
49
|
+
has_PIL = False # pragma: no cover
|
50
50
|
else:
|
51
51
|
has_PIL = True
|
52
52
|
try:
|
53
|
-
import cv2
|
54
|
-
except ImportError:
|
55
|
-
has_cv2 = False
|
53
|
+
import cv2 # pragma: no cover
|
54
|
+
except ImportError: # pragma: no cover
|
55
|
+
has_cv2 = False # pragma: no cover
|
56
56
|
else:
|
57
57
|
has_cv2 = True
|
58
58
|
import numpy
|
@@ -97,8 +97,10 @@ class DataViewer(qt.QMainWindow):
|
|
97
97
|
self._controls = DisplayControl(parent=self)
|
98
98
|
self._controlsDW = qt.QDockWidget(self)
|
99
99
|
self._controlsDW.setWidget(self._controls)
|
100
|
-
self._controlsDW.
|
100
|
+
self._controlsDW.setWindowTitle("infos")
|
101
101
|
self.addDockWidget(qt.Qt.TopDockWidgetArea, self._controlsDW)
|
102
|
+
self._controlsDW.setTitleBarWidget(qt.QWidget(self))
|
103
|
+
self._controlsDW.setFloating(False)
|
102
104
|
|
103
105
|
# connect signal / slot
|
104
106
|
self._controls.sigDisplayModeChanged.connect(self._updateDisplay)
|
@@ -220,6 +222,12 @@ class DataViewer(qt.QMainWindow):
|
|
220
222
|
elif self.getDisplayMode() is _DisplayMode.FLATS:
|
221
223
|
self._viewer.setNormalizationFct(None)
|
222
224
|
slices = self._scan().flats
|
225
|
+
elif self.getDisplayMode() is _DisplayMode.REDUCED_DARKS:
|
226
|
+
self._viewer.setNormalizationFct(None)
|
227
|
+
slices = self._scan().load_reduced_darks(return_as_url=True)
|
228
|
+
elif self.getDisplayMode() is _DisplayMode.REDUCED_FLATS:
|
229
|
+
self._viewer.setNormalizationFct(None)
|
230
|
+
slices = self._scan().load_reduced_flats(return_as_url=True)
|
223
231
|
else:
|
224
232
|
raise ValueError("DisplayMode should be RADIOS or SLICES")
|
225
233
|
|
@@ -250,8 +258,10 @@ class DataViewer(qt.QMainWindow):
|
|
250
258
|
class _DisplayMode(_Enum):
|
251
259
|
RADIOS = "projections-radios"
|
252
260
|
SLICES = "slices"
|
253
|
-
DARKS = "darks"
|
254
|
-
FLATS = "flats"
|
261
|
+
DARKS = "raw darks"
|
262
|
+
FLATS = "raw flats"
|
263
|
+
REDUCED_DARKS = "reduced darks"
|
264
|
+
REDUCED_FLATS = "reduced flats"
|
255
265
|
|
256
266
|
|
257
267
|
class _RadioMode(_Enum):
|
@@ -372,9 +382,12 @@ class DisplayControl(qt.QWidget):
|
|
372
382
|
config = mode, self.getRadioOption()
|
373
383
|
elif mode is _DisplayMode.SLICES:
|
374
384
|
config = mode, self.getSliceOption()
|
375
|
-
elif mode
|
376
|
-
|
377
|
-
|
385
|
+
elif mode in (
|
386
|
+
_DisplayMode.DARKS,
|
387
|
+
_DisplayMode.FLATS,
|
388
|
+
_DisplayMode.REDUCED_DARKS,
|
389
|
+
_DisplayMode.REDUCED_FLATS,
|
390
|
+
):
|
378
391
|
config = mode, None
|
379
392
|
else:
|
380
393
|
raise ValueError("mode should be RADIOS or SLICES")
|
@@ -544,12 +557,6 @@ class _TomwerUrlLoader(UrlLoader):
|
|
544
557
|
Thread use to load DataUrl
|
545
558
|
"""
|
546
559
|
|
547
|
-
def __init__(self, parent, url):
|
548
|
-
super(UrlLoader, self).__init__(parent=parent)
|
549
|
-
assert isinstance(url, DataUrl)
|
550
|
-
self.url = url
|
551
|
-
self.data = None
|
552
|
-
|
553
560
|
def run(self):
|
554
561
|
if self.url.file_path().endswith(".vol"):
|
555
562
|
self.data = self._load_vol()
|
@@ -358,6 +358,7 @@ class DiffFrameViewer(qt.QMainWindow):
|
|
358
358
|
self._framesSelector.setContentsMargins(0, 0, 0, 0)
|
359
359
|
self._framesSelector.layout().setContentsMargins(0, 0, 0, 0)
|
360
360
|
self._framesSelectorDW = qt.QDockWidget(parent=self)
|
361
|
+
self._framesSelectorDW.setWindowTitle("inputs")
|
361
362
|
self._framesSelectorDW.setWidget(self._framesSelector)
|
362
363
|
self._framesSelectorDW.setFeatures(qt.QDockWidget.DockWidgetMovable)
|
363
364
|
self.addDockWidget(qt.Qt.TopDockWidgetArea, self._framesSelectorDW)
|
@@ -369,6 +370,7 @@ class DiffFrameViewer(qt.QMainWindow):
|
|
369
370
|
self._shiftDW = qt.QDockWidget(parent=self)
|
370
371
|
self._shiftDW.setWidget(self._shiftsWidget)
|
371
372
|
self._shiftDW.setFeatures(qt.QDockWidget.DockWidgetMovable)
|
373
|
+
self._shiftDW.setWindowTitle("shifts")
|
372
374
|
self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._shiftDW)
|
373
375
|
|
374
376
|
# define central widget
|
@@ -387,13 +389,6 @@ class DiffFrameViewer(qt.QMainWindow):
|
|
387
389
|
toolbar.setFloatable(False)
|
388
390
|
self.addToolBar(qt.Qt.TopToolBarArea, toolbar)
|
389
391
|
|
390
|
-
# add filtering
|
391
|
-
style = qt.QApplication.instance().style()
|
392
|
-
icon = style.standardIcon(qt.QStyle.SP_DialogResetButton)
|
393
|
-
self._clearAction = qt.QAction(icon, "Clear", toolbar)
|
394
|
-
toolbar.addAction(self._clearAction)
|
395
|
-
self._clearAction.triggered.connect(self.clear)
|
396
|
-
|
397
392
|
# set up
|
398
393
|
self._mainWidget.setAutoResetZoom(False)
|
399
394
|
self._shiftsWidget.setFocus(qt.Qt.OtherFocusReason)
|
@@ -492,10 +487,6 @@ class DiffFrameViewer(qt.QMainWindow):
|
|
492
487
|
)
|
493
488
|
self._mainWidget.setImage2(shifted_image)
|
494
489
|
|
495
|
-
def clear(self):
|
496
|
-
self._framesSelector.clear()
|
497
|
-
self._mainWidget.getPlot().clear()
|
498
|
-
|
499
490
|
def _frameShiftsChanged(self):
|
500
491
|
self._resetLeftFrame()
|
501
492
|
self._resetRightFrame()
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from silx.gui import qt
|
2
|
+
from tomwer.gui.edit.nxtomoeditor import NXtomoEditor as _NXtomoEditor
|
3
|
+
|
4
|
+
|
5
|
+
class NXtomoMetadataViewer(_NXtomoEditor):
|
6
|
+
"""
|
7
|
+
class to display metadata of a NXtomo.
|
8
|
+
inherit from the `NXtomoEditor` and make sure not edition is possible
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self, parent=None):
|
12
|
+
super().__init__(parent)
|
13
|
+
for widget in self.getEditableWidgets():
|
14
|
+
if isinstance(widget, (qt.QComboBox, qt.QCheckBox)):
|
15
|
+
widget.setEnabled(False)
|
16
|
+
else:
|
17
|
+
widget.setReadOnly(True)
|
18
|
+
|
19
|
+
def overwriteNXtomo(self):
|
20
|
+
"""overwrite data on disk"""
|
21
|
+
raise NotImplementedError("viewer not editor")
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import os
|
2
|
+
import pytest
|
3
|
+
import numpy
|
4
|
+
from tomoscan.esrf.scan.hdf5scan import ImageKey
|
5
|
+
from tomwer.core.scan.hdf5scan import HDF5TomoScan
|
6
|
+
from tomwer.gui.visualization.nxtomometadata import NXtomoMetadataViewer
|
7
|
+
from nxtomomill.nexus.nxtomo import NXtomo
|
8
|
+
from tomwer.tests.conftest import qtapp # noqa F401
|
9
|
+
from silx.gui import qt
|
10
|
+
|
11
|
+
|
12
|
+
def test_nx_editor(
|
13
|
+
tmp_path,
|
14
|
+
qtapp, # noqa F811
|
15
|
+
):
|
16
|
+
# 1.0 create nx tomo with raw data
|
17
|
+
nx_tomo = NXtomo()
|
18
|
+
nx_tomo.instrument.detector.x_pixel_size = 2.6e-6
|
19
|
+
nx_tomo.instrument.detector.y_pixel_size = 2.5e-6
|
20
|
+
nx_tomo.instrument.detector.field_of_view = "Half"
|
21
|
+
nx_tomo.instrument.detector.distance = 59.0
|
22
|
+
nx_tomo.instrument.detector.x_flipped = True
|
23
|
+
nx_tomo.instrument.detector.y_flipped = False
|
24
|
+
nx_tomo.energy = 12.8
|
25
|
+
nx_tomo.sample.x_translation = numpy.arange(12)
|
26
|
+
nx_tomo.sample.z_translation = numpy.arange(2, 14)
|
27
|
+
nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12
|
28
|
+
nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10))
|
29
|
+
nx_tomo.sample.rotation_angle = numpy.linspace(0, 180, num=12)
|
30
|
+
|
31
|
+
file_path = os.path.join(tmp_path, "nxtomo.nx")
|
32
|
+
entry = "entry0000"
|
33
|
+
nx_tomo.save(
|
34
|
+
file_path=file_path,
|
35
|
+
data_path=entry,
|
36
|
+
)
|
37
|
+
|
38
|
+
scan = HDF5TomoScan(file_path, entry)
|
39
|
+
|
40
|
+
# 2.0 create the widget and do the edition
|
41
|
+
widget = NXtomoMetadataViewer()
|
42
|
+
widget.setScan(scan=scan)
|
43
|
+
widget.show()
|
44
|
+
|
45
|
+
# 3.0 check data have been corrcetly loaded
|
46
|
+
def check_metric(expected_value, current_value):
|
47
|
+
if expected_value is None:
|
48
|
+
return current_value is None
|
49
|
+
return expected_value == current_value
|
50
|
+
|
51
|
+
assert check_metric(2.6e-6, widget._xPixelSizeMetricEntry.getValue())
|
52
|
+
assert widget._xPixelSizeMetricEntry._qcbUnit.currentText() == "m"
|
53
|
+
assert check_metric(2.5e-6, widget._yPixelSizeMetricEntry.getValue())
|
54
|
+
assert widget._yPixelSizeMetricEntry._qcbUnit.currentText() == "m"
|
55
|
+
|
56
|
+
assert check_metric(59, widget._distanceMetricEntry.getValue())
|
57
|
+
assert widget._distanceMetricEntry._qcbUnit.currentText() == "m"
|
58
|
+
|
59
|
+
assert "Half" == widget._fieldOfViewCB.currentText()
|
60
|
+
assert widget._xFlippedCB.isChecked()
|
61
|
+
assert not widget._yFlippedCB.isChecked()
|
62
|
+
|
63
|
+
assert "12.8" == widget._energyQLE.text()
|
64
|
+
|
65
|
+
# make sure saving raises an error (viewer inherit from the editor)
|
66
|
+
with pytest.raises(NotImplementedError):
|
67
|
+
widget.overwriteNXtomo()
|
68
|
+
|
69
|
+
# end
|
70
|
+
widget.setAttribute(qt.Qt.WA_DeleteOnClose)
|
71
|
+
widget.close()
|
72
|
+
widget = None
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from .volumeoverview import VolumeOverviewWidget
|
2
|
+
from .scanoverview import ScanOverviewWidget
|
3
|
+
from silx.gui import qt
|
4
|
+
from tomwer.core.tomwer_object import TomwerObject
|
5
|
+
from tomwer.core.volume.volumebase import TomwerVolumeBase
|
6
|
+
from tomwer.core.scan.scanbase import TomwerScanBase
|
7
|
+
from typing import Optional
|
8
|
+
|
9
|
+
|
10
|
+
class TomoObjOverview(qt.QWidget):
|
11
|
+
"""
|
12
|
+
Dummy widget to show ScanOverviewWidget if the object is a scan or VolumeOverviewWidget if the object is a Volume
|
13
|
+
"""
|
14
|
+
|
15
|
+
def __init__(self, parent=None) -> None:
|
16
|
+
super().__init__(parent)
|
17
|
+
self.setLayout(qt.QVBoxLayout())
|
18
|
+
self._scanOverview = ScanOverviewWidget(self)
|
19
|
+
self.layout().addWidget(self._scanOverview)
|
20
|
+
|
21
|
+
self._volumeOverview = VolumeOverviewWidget(self)
|
22
|
+
self.layout().addWidget(self._volumeOverview)
|
23
|
+
|
24
|
+
self._scanOverview.setVisible(False)
|
25
|
+
self._volumeOverview.setVisible(False)
|
26
|
+
|
27
|
+
def setTomoObj(self, tomo_obj: Optional[TomwerObject]):
|
28
|
+
"""
|
29
|
+
update sub widgets according to the type of tomo_obj
|
30
|
+
"""
|
31
|
+
if tomo_obj is not None and not isinstance(tomo_obj, TomwerObject):
|
32
|
+
raise TypeError(
|
33
|
+
f"tomo_obj is expected to be an instance of {TomwerObject} and not {type(tomo_obj)}"
|
34
|
+
)
|
35
|
+
# handle visibility
|
36
|
+
self._volumeOverview.setVisible(isinstance(tomo_obj, TomwerVolumeBase))
|
37
|
+
self._scanOverview.setVisible(isinstance(tomo_obj, TomwerScanBase))
|
38
|
+
|
39
|
+
if isinstance(tomo_obj, TomwerVolumeBase):
|
40
|
+
self._scanOverview.setScan(None)
|
41
|
+
self._volumeOverview.setVolume(tomo_obj)
|
42
|
+
elif isinstance(tomo_obj, TomwerScanBase):
|
43
|
+
self._scanOverview.setScan(tomo_obj)
|
44
|
+
self._volumeOverview.setVolume(None)
|
45
|
+
elif tomo_obj is None:
|
46
|
+
self._volumeOverview.setVolume(None)
|
47
|
+
self._scanOverview.setScan(None)
|
48
|
+
else:
|
49
|
+
raise RuntimeError(f"TomwerObject of type {type(tomo_obj)} is not handled")
|