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
@@ -27,53 +27,29 @@ __authors__ = ["H. Payno"]
|
|
27
27
|
__license__ = "MIT"
|
28
28
|
__date__ = "11/03/2020"
|
29
29
|
|
30
|
+
import os
|
31
|
+
import logging
|
32
|
+
from copy import copy
|
30
33
|
from silx.gui import qt
|
31
|
-
from orangewidget import
|
34
|
+
from orangewidget import gui
|
32
35
|
from tomwer.gui.control.datalist import BlissHDF5DataListMainWindow
|
36
|
+
from orangecontrib.tomwer.orange.managedprocess import TomwerWithStackStack
|
33
37
|
from tomwer.core.scan.hdf5scan import HDF5TomoScan, HDF5TomoScanIdentifier
|
34
|
-
from tomwer.web.client import OWClient
|
35
38
|
from tomwer.core.process.control.nxtomomill import H5ToNxProcess
|
36
|
-
|
37
|
-
from orangewidget.settings import Setting
|
38
|
-
from orangewidget.widget import Output, Input
|
39
|
-
from tomwer.core.scan.scanbase import TomwerScanBase
|
39
|
+
from orangecontrib.tomwer.widgets.control.NXTomomillMixIn import NXTomomillMixIn
|
40
40
|
from tomwer.core.scan.blissscan import BlissScan
|
41
|
-
from nxtomomill import converter as nxtomomill_converter
|
42
41
|
from nxtomomill.io.config import TomoHDF5Config as HDF5Config
|
43
|
-
from tomwer.gui.control.nxtomomill import
|
44
|
-
import
|
45
|
-
import logging
|
42
|
+
from tomwer.gui.control.nxtomomill import OverwriteMessage
|
43
|
+
from tomwer.gui.control.nxtomomill import NXTomomillInput
|
46
44
|
|
47
45
|
logger = logging.getLogger(__name__)
|
48
46
|
|
49
47
|
|
50
|
-
class
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
_static_input = Setting(dict())
|
57
|
-
|
58
|
-
def _saveNXTomoCfgFile(self, cfg_file):
|
59
|
-
"""save the nxtomofile to the setttings"""
|
60
|
-
self._nxtomo_cfg_file = cfg_file
|
61
|
-
self._static_input["nxtomomill_cfg_file"] = cfg_file
|
62
|
-
|
63
|
-
def _updateSettings(self):
|
64
|
-
self._scans = []
|
65
|
-
for scan in self.widget.datalist._myitems:
|
66
|
-
# kept for backward compatibility since 0.11. To be removed on the future version.
|
67
|
-
if "@" in scan:
|
68
|
-
entry, file_path = scan.split("@")
|
69
|
-
hdf5_tomo_scan = HDF5TomoScan(entry=entry, scan=file_path)
|
70
|
-
self.add(hdf5_tomo_scan)
|
71
|
-
else:
|
72
|
-
self._scans.append(scan)
|
73
|
-
self._static_input["output_dir"] = self.widget.getOutputFolder()
|
74
|
-
|
75
|
-
|
76
|
-
class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
48
|
+
class NXTomomillOW(
|
49
|
+
TomwerWithStackStack,
|
50
|
+
NXTomomillMixIn,
|
51
|
+
ewokstaskclass=H5ToNxProcess,
|
52
|
+
):
|
77
53
|
"""
|
78
54
|
Widget to allow user to pick some bliss files and that will convert them
|
79
55
|
to HDF5scan.
|
@@ -104,21 +80,17 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
104
80
|
resizing_enabled = True
|
105
81
|
compress_signal = False
|
106
82
|
|
107
|
-
|
83
|
+
CONFIG_CLS = HDF5Config
|
108
84
|
|
109
|
-
|
110
|
-
data = Input(name="bliss data", type=BlissScan, doc="bliss scan to be process")
|
111
|
-
|
112
|
-
class Outputs:
|
113
|
-
data = Output(name="data", type=TomwerScanBase, doc="one scan to be process")
|
85
|
+
LOGGER = logger
|
114
86
|
|
115
87
|
def __init__(self, parent=None):
|
116
|
-
|
117
|
-
|
118
|
-
|
88
|
+
TomwerWithStackStack.__init__(self, parent=parent)
|
89
|
+
NXTomomillMixIn.__init__(self)
|
90
|
+
_layout = gui.vBox(self.mainArea, self.name).layout()
|
91
|
+
|
119
92
|
self.widget = BlissHDF5DataListMainWindow(parent=self)
|
120
|
-
|
121
|
-
layout.addWidget(self.widget)
|
93
|
+
_layout.addWidget(self.widget)
|
122
94
|
self.__request_input = True
|
123
95
|
# do we ask the user for input if missing
|
124
96
|
self._inputGUI = None
|
@@ -127,7 +99,6 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
127
99
|
"""Cache to know if we have to ask user permission for overwriting"""
|
128
100
|
|
129
101
|
# expose API
|
130
|
-
self.add = self.widget.add
|
131
102
|
self.n_scan = self.widget.n_scan
|
132
103
|
# alias used for the 'simple workflow' for now
|
133
104
|
self.start = self._sendAll
|
@@ -137,9 +108,30 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
137
108
|
self.widget._sendSelectedButton.clicked.connect(self._sendSelected)
|
138
109
|
self.widget.sigNXTomoCFGFileChanged.connect(self._saveNXTomoCfgFile)
|
139
110
|
self.widget.sigUpdated.connect(self._updateSettings)
|
111
|
+
|
112
|
+
# set default configuration is no existing configuration file defined in the settings
|
113
|
+
self.update_default_inputs(
|
114
|
+
h5_to_nx_configuration=HDF5Config().to_dict(),
|
115
|
+
)
|
116
|
+
self.task_output_changed_callbacks.add(self._notify_state)
|
117
|
+
|
140
118
|
# handle settings
|
141
119
|
self._loadSettings()
|
142
120
|
|
121
|
+
def _updateSettings(self):
|
122
|
+
self._scans = []
|
123
|
+
for scan in self.widget.datalist._myitems:
|
124
|
+
# kept for backward compatibility since 0.11. To be removed on the future version.
|
125
|
+
if "@" in scan:
|
126
|
+
entry, file_path = scan.split("@")
|
127
|
+
hdf5_tomo_scan = HDF5TomoScan(entry=entry, scan=file_path)
|
128
|
+
self.add(hdf5_tomo_scan)
|
129
|
+
else:
|
130
|
+
self._scans.append(scan)
|
131
|
+
self._ewoks_default_inputs[ # pylint: disable=E1137
|
132
|
+
"output_dir"
|
133
|
+
] = self.widget.getOutputFolder()
|
134
|
+
|
143
135
|
@property
|
144
136
|
def request_input(self):
|
145
137
|
return self.__request_input
|
@@ -148,42 +140,57 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
148
140
|
def request_input(self, request):
|
149
141
|
self.__request_input = request
|
150
142
|
|
151
|
-
def
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
self._canOverwriteOutputs = False
|
156
|
-
for bliss_url in self.widget.datalist.selectedItems():
|
157
|
-
identifier = HDF5TomoScanIdentifier.from_str(bliss_url.text())
|
158
|
-
self._inputGUI.setBlissScan(
|
159
|
-
entry=identifier.data_path, file_path=identifier.file_path
|
160
|
-
)
|
161
|
-
self._process(bliss_url.text())
|
143
|
+
def get_task_inputs(self):
|
144
|
+
return {
|
145
|
+
"h5_to_nx_configuration": self.__configuration_cache.to_dict(),
|
146
|
+
}
|
162
147
|
|
163
|
-
def
|
164
|
-
"""
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
148
|
+
def handleNewSignals(self) -> None:
|
149
|
+
"""Invoked by the workflow signal propagation manager after all
|
150
|
+
signals handlers have been called.
|
151
|
+
"""
|
152
|
+
# for now we want to avoid propagation any processing.
|
153
|
+
# task will be executed only when the user validates the dialog
|
154
|
+
h5_scan = super().get_task_inputs().get("hdf5_scan", None)
|
155
|
+
if h5_scan is not None:
|
156
|
+
if not isinstance(h5_scan, H5ToNxProcess):
|
157
|
+
raise TypeError(
|
158
|
+
"hdf5_scan is expected to be an instance of HDF5TomoScan"
|
159
|
+
)
|
160
|
+
self.add(h5_scan.path)
|
174
161
|
|
175
|
-
def
|
162
|
+
def _convertAndSend(self, bliss_url):
|
176
163
|
"""
|
177
164
|
|
178
165
|
:param str bliss_url: string at entry@file format
|
179
166
|
"""
|
180
167
|
logger.processStarted("Start translate {} to NXTomo".format(str(bliss_url)))
|
168
|
+
self.__configuration_cache = HDF5Config.from_dict(
|
169
|
+
copy(self.get_default_input_values()["h5_to_nx_configuration"])
|
170
|
+
)
|
171
|
+
|
181
172
|
identifier = HDF5TomoScanIdentifier.from_str(bliss_url)
|
182
173
|
bliss_scan = BlissScan(
|
183
174
|
master_file=identifier.file_path,
|
184
175
|
entry=identifier.data_path,
|
185
176
|
proposal_file=None,
|
186
177
|
)
|
178
|
+
|
179
|
+
output_file_path = H5ToNxProcess.deduce_output_file_path(
|
180
|
+
bliss_scan.master_file,
|
181
|
+
entry=bliss_scan.entry,
|
182
|
+
outputdir=self.widget.getOutputFolder(),
|
183
|
+
scan=bliss_scan,
|
184
|
+
)
|
185
|
+
|
186
|
+
self.__configuration_cache.input_file = bliss_scan.master_file
|
187
|
+
self.__configuration_cache.output_file = output_file_path
|
188
|
+
self.__configuration_cache.entries = (bliss_scan.entry,)
|
189
|
+
self.__configuration_cache.single_file = False
|
190
|
+
self.__configuration_cache.overwrite = True
|
191
|
+
self.__configuration_cache.request_input = self.request_input
|
192
|
+
self.__configuration_cache.file_extension = ".nx"
|
193
|
+
|
187
194
|
self._processBlissScan(bliss_scan)
|
188
195
|
|
189
196
|
def _userAgreeForOverwrite(self, file_path):
|
@@ -199,10 +206,6 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
199
206
|
else:
|
200
207
|
return False
|
201
208
|
|
202
|
-
@Inputs.data
|
203
|
-
def treatBlissScan(self, bliss_scan):
|
204
|
-
self._processBlissScan(bliss_scan)
|
205
|
-
|
206
209
|
def _processBlissScan(self, bliss_scan):
|
207
210
|
if bliss_scan is None:
|
208
211
|
return
|
@@ -210,16 +213,14 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
210
213
|
bliss_scan.master_file,
|
211
214
|
entry=bliss_scan.entry,
|
212
215
|
outputdir=self.widget.getOutputFolder(),
|
216
|
+
scan=bliss_scan,
|
213
217
|
)
|
214
218
|
# check user has rights to write on the folder
|
215
219
|
dirname = os.path.dirname(output_file_path)
|
216
|
-
if not os.access(dirname, os.W_OK):
|
220
|
+
if os.path.exists(dirname) and not os.access(dirname, os.W_OK):
|
217
221
|
msg = qt.QMessageBox(self)
|
218
222
|
msg.setIcon(qt.QMessageBox.Warning)
|
219
|
-
text = (
|
220
|
-
"You don't have write rights on {}. Unable to generate "
|
221
|
-
"the nexus file associated to {}".format(dirname, str(bliss_scan))
|
222
|
-
)
|
223
|
+
text = f"You don't have write rights on '{dirname}'. Unable to generate the nexus file associated to {str(bliss_scan)}"
|
223
224
|
msg.setWindowTitle("No rights to write")
|
224
225
|
msg.setText(text)
|
225
226
|
msg.show()
|
@@ -229,43 +230,11 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
229
230
|
if not self._userAgreeForOverwrite(output_file_path):
|
230
231
|
return
|
231
232
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
# provided ? Or check if the entry receive fit
|
238
|
-
# one provided (a root entry for now)
|
239
|
-
# force some parameters
|
240
|
-
configuration.input_file = bliss_scan.master_file
|
241
|
-
configuration.output_file = output_file_path
|
242
|
-
configuration.entries = (bliss_scan.entry,)
|
243
|
-
configuration.single_file = False
|
244
|
-
configuration.overwrite = True
|
245
|
-
configuration.request_input = self.request_input
|
246
|
-
configuration.file_extension = ".nx"
|
247
|
-
if hasattr(configuration, "bam_single_file"):
|
248
|
-
configuration.bam_single_file = True
|
249
|
-
try:
|
250
|
-
convs = nxtomomill_converter.from_h5_to_nx(
|
251
|
-
configuration=configuration,
|
252
|
-
input_callback=self._inputGUI,
|
253
|
-
progress=None,
|
254
|
-
)
|
255
|
-
except Exception as e:
|
256
|
-
logger.processFailed(
|
257
|
-
"Fail to convert from bliss file: %s to NXTomo."
|
258
|
-
"Conversion error is: %s" % (bliss_scan, e)
|
259
|
-
)
|
260
|
-
else:
|
261
|
-
# in the case of zserie we can have several scan for one entry
|
262
|
-
for conv in convs:
|
263
|
-
conv_file, conv_entry = conv
|
264
|
-
scan_converted = HDF5TomoScan(scan=conv_file, entry=conv_entry)
|
265
|
-
logger.processSucceed(
|
266
|
-
"{} has been translated to {}" "".format(bliss_scan, scan_converted)
|
267
|
-
)
|
268
|
-
self.Outputs.data.send(scan_converted)
|
233
|
+
# keep 'h5_to_nx_configuration' up to date according to input folder and output_file updates
|
234
|
+
self.update_default_inputs(
|
235
|
+
h5_to_nx_configuration=self.__configuration_cache.to_dict()
|
236
|
+
)
|
237
|
+
self._execute_ewoks_task(propagate=True)
|
269
238
|
|
270
239
|
def _loadSettings(self):
|
271
240
|
for scan in self._scans:
|
@@ -276,13 +245,15 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
276
245
|
logger.error("Fail to add {}. Error is {}".format(scan, e))
|
277
246
|
else:
|
278
247
|
logger.warning("{} is an invalid link to a file".format(scan))
|
279
|
-
if "nxtomomill_cfg_file" in self.
|
280
|
-
nxtomo_cfg_file = self.
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
if "output_dir" in self.
|
285
|
-
self.widget.setOutputFolder(
|
248
|
+
if "nxtomomill_cfg_file" in self._ewoks_default_inputs: # pylint: disable=E1135
|
249
|
+
nxtomo_cfg_file = self._ewoks_default_inputs[ # pylint: disable=E1136
|
250
|
+
"nxtomomill_cfg_file"
|
251
|
+
]
|
252
|
+
self.widget.setCFGFilePath(nxtomo_cfg_file)
|
253
|
+
if "output_dir" in self._ewoks_default_inputs: # pylint: disable=E1135
|
254
|
+
self.widget.setOutputFolder(
|
255
|
+
self._ewoks_default_inputs["output_dir"] # pylint: disable=E1136
|
256
|
+
)
|
286
257
|
|
287
258
|
def getHDF5Config(self):
|
288
259
|
configuration_file = self.widget.getCFGFilePath()
|
@@ -301,6 +272,42 @@ class NXTomomillOW(widget.OWBaseWidget, _NXTomoMixIn, OWClient, openclass=True):
|
|
301
272
|
return configuration
|
302
273
|
|
303
274
|
def _saveNXTomoCfgFile(self, cfg_file):
|
304
|
-
super()._saveNXTomoCfgFile(cfg_file)
|
305
|
-
|
306
|
-
|
275
|
+
super()._saveNXTomoCfgFile(cfg_file, keyword="h5_to_nx_configuration")
|
276
|
+
|
277
|
+
def _sendSelected(self):
|
278
|
+
"""Send a signal for selected scans found to the next widget"""
|
279
|
+
self._inputGUI = NXTomomillInput()
|
280
|
+
# reset the GUI for input (reset all the cache for answers)
|
281
|
+
self._canOverwriteOutputs = False
|
282
|
+
for bliss_url in self.widget.datalist.selectedItems():
|
283
|
+
identifier = HDF5TomoScanIdentifier.from_str(bliss_url.text())
|
284
|
+
self._inputGUI.setBlissScan(
|
285
|
+
entry=identifier.data_path, file_path=identifier.file_path
|
286
|
+
)
|
287
|
+
self._convertAndSend(bliss_url.text())
|
288
|
+
|
289
|
+
def _sendAll(self):
|
290
|
+
"""Send a signal for each scan found to the next widget"""
|
291
|
+
self._inputGUI = NXTomomillInput()
|
292
|
+
# reset the GUI for input (reset all the cache for answers)
|
293
|
+
self._canOverwriteOutputs = False
|
294
|
+
for bliss_url in self.widget.datalist.selectedItems():
|
295
|
+
identifier = HDF5TomoScanIdentifier.from_str(bliss_url.text())
|
296
|
+
self._inputGUI.setBlissScan(
|
297
|
+
entry=identifier.data_path, file_path=identifier.file_path
|
298
|
+
)
|
299
|
+
self._convertAndSend(bliss_url.text())
|
300
|
+
|
301
|
+
def _notify_state(self):
|
302
|
+
try:
|
303
|
+
task_executor = self.sender()
|
304
|
+
task_suceeded = task_executor.succeeded
|
305
|
+
config = task_executor.current_task.inputs.h5_to_nx_configuration
|
306
|
+
config = HDF5Config.from_dict(config)
|
307
|
+
scan = task_executor.current_task.outputs.data
|
308
|
+
if task_suceeded:
|
309
|
+
self.notify_succeed(scan=scan)
|
310
|
+
else:
|
311
|
+
self.notify_failed(scan=scan)
|
312
|
+
except Exception as e:
|
313
|
+
logger.error(f"failed to handle task finished callback. Raiseon is {e}")
|
@@ -32,6 +32,7 @@ from silx.gui import qt
|
|
32
32
|
from orangewidget import widget
|
33
33
|
from orangewidget.widget import Input, Output
|
34
34
|
from tomwer.core.tomwer_object import TomwerObject
|
35
|
+
from orangewidget import settings
|
35
36
|
|
36
37
|
|
37
38
|
class NotifierWidgetOW(widget.OWBaseWidget):
|
@@ -50,6 +51,8 @@ class NotifierWidgetOW(widget.OWBaseWidget):
|
|
50
51
|
resizing_enabled = False
|
51
52
|
compress_signal = False
|
52
53
|
|
54
|
+
_muted = settings.Setting(False)
|
55
|
+
|
53
56
|
class Inputs:
|
54
57
|
tomo_obj = Input(name="tomo_obj", type=TomwerObject, multiple=True)
|
55
58
|
|
@@ -60,19 +63,44 @@ class NotifierWidgetOW(widget.OWBaseWidget):
|
|
60
63
|
super().__init__(parent)
|
61
64
|
self.pop_up = None
|
62
65
|
layout = gui.vBox(self.mainArea, self.name).layout()
|
63
|
-
self.
|
64
|
-
self.
|
65
|
-
|
66
|
+
self._soundButton = qt.QPushButton(parent=self)
|
67
|
+
self._soundButton.setMinimumSize(150, 100)
|
68
|
+
self._soundButton.setCheckable(True)
|
69
|
+
layout.addWidget(self._soundButton)
|
70
|
+
self._updateButtonIcon()
|
71
|
+
|
72
|
+
# connect signal / slot
|
73
|
+
self._soundButton.toggled.connect(self._switchMute)
|
74
|
+
|
75
|
+
def _switchMute(self):
|
76
|
+
self._muted = not self._muted
|
77
|
+
|
78
|
+
self._updateButtonIcon()
|
66
79
|
|
67
80
|
@Inputs.tomo_obj
|
68
81
|
def process(self, tomo_obj, *args, **kwargs):
|
69
82
|
self.notify(tomo_obj)
|
70
83
|
self.Outputs.tomo_obj.send(tomo_obj)
|
71
84
|
|
85
|
+
def _updateButtonIcon(self):
|
86
|
+
style = qt.QApplication.style()
|
87
|
+
if self._muted:
|
88
|
+
icon = style.standardIcon(qt.QStyle.SP_MediaVolumeMuted)
|
89
|
+
else:
|
90
|
+
icon = style.standardIcon(qt.QStyle.SP_MediaVolume)
|
91
|
+
self._soundButton.setIcon(icon)
|
92
|
+
|
72
93
|
def notify(self, tomo_obj):
|
73
94
|
if self.pop_up is not None:
|
74
95
|
self.pop_up.close()
|
75
96
|
|
97
|
+
if not self._muted:
|
98
|
+
# emit sound when requested
|
99
|
+
try:
|
100
|
+
qt.QApplication.beep()
|
101
|
+
except Exception:
|
102
|
+
pass
|
103
|
+
|
76
104
|
self.pop_up = NotificationMessage()
|
77
105
|
text = f"Object {tomo_obj} received."
|
78
106
|
self.pop_up.setText(text)
|
@@ -86,14 +114,10 @@ class NotificationMessage(qt.QMessageBox):
|
|
86
114
|
super().__init__()
|
87
115
|
self.setModal(False)
|
88
116
|
self.setIcon(qt.QMessageBox.Information)
|
89
|
-
# types = qt.QDialogButtonBox.Ok
|
90
|
-
# self.setStandardButtons(types)
|
91
117
|
self.addButton(
|
92
118
|
f"Ok - will close automatically after {self.EXPOSITION_TIME / 1000}s",
|
93
119
|
qt.QMessageBox.YesRole,
|
94
120
|
)
|
95
|
-
# print("self.standardButtons()", self.standardButtons())
|
96
|
-
# self.standardButtons()[0].setText(f"Ok - will close automatically after {self.EXPOSITION_TIME / 1000}s")
|
97
121
|
|
98
122
|
def show(self):
|
99
123
|
super().show()
|
@@ -27,13 +27,12 @@ __authors__ = ["C. Nemoz", "H. Payno"]
|
|
27
27
|
__license__ = "MIT"
|
28
28
|
__date__ = "25/08/2022"
|
29
29
|
|
30
|
-
from orangewidget import
|
30
|
+
from orangewidget import gui
|
31
31
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
32
32
|
from tomwer.core.scan.scanfactory import ScanFactory
|
33
33
|
from tomwer.core.tomwer_object import TomwerObject
|
34
34
|
from tomwer.core.volume.volumefactory import VolumeFactory
|
35
35
|
from tomwer.gui.control.singletomoobj import SingleTomoObj
|
36
|
-
from tomwer.web.client import OWClient
|
37
36
|
from orangewidget.settings import Setting
|
38
37
|
from orangewidget.widget import Output, Input, OWBaseWidget
|
39
38
|
import tomoscan.esrf.scan.utils
|
@@ -43,7 +42,7 @@ import logging
|
|
43
42
|
_logger = logging.getLogger(__name__)
|
44
43
|
|
45
44
|
|
46
|
-
class SingleTomoObjOW(OWBaseWidget,
|
45
|
+
class SingleTomoObjOW(OWBaseWidget, openclass=True):
|
47
46
|
name = "single tomo obj"
|
48
47
|
id = "orange.widgets.tomwer.control.SingleScanOW.SingleScanOW"
|
49
48
|
description = "Definition of a single dataset"
|
@@ -79,8 +78,7 @@ class SingleTomoObjOW(OWBaseWidget, OWClient, openclass=True):
|
|
79
78
|
)
|
80
79
|
|
81
80
|
def __init__(self, parent=None):
|
82
|
-
|
83
|
-
OWClient.__init__(self)
|
81
|
+
super().__init__(parent)
|
84
82
|
self._latest_received_scan = None
|
85
83
|
# small work around to keep in scan processing cache and avoid recomputing it if not necessary
|
86
84
|
self.widget = SingleTomoObj(parent=self)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# /*##########################################################################
|
3
|
+
#
|
4
|
+
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
#
|
24
|
+
# ###########################################################################*/
|
25
|
+
|
26
|
+
__authors__ = [
|
27
|
+
"H. Payno",
|
28
|
+
]
|
29
|
+
__license__ = "MIT"
|
30
|
+
__date__ = "12/07/2022"
|
31
|
+
|
32
|
+
from orangewidget import gui
|
33
|
+
from orangewidget.widget import Output, Input, OWBaseWidget
|
34
|
+
from tomoscan.serie import Serie
|
35
|
+
from tomwer.core.tomwer_object import TomwerObject
|
36
|
+
import tomwer.core.process.control.tomoobjserie
|
37
|
+
from tomwer.gui.control.serie.seriecreator import SerieWidgetDialog
|
38
|
+
import logging
|
39
|
+
|
40
|
+
logger = logging.getLogger(__name__)
|
41
|
+
|
42
|
+
|
43
|
+
class TomoObjSerieOW(OWBaseWidget, openclass=True):
|
44
|
+
name = "serie of objects"
|
45
|
+
id = "orange.widgets.tomwer.tomoobjserieow"
|
46
|
+
description = "Allow user define a serie of object that will be defined as a Serie (grouped together and can be used within a purpose like stiching)"
|
47
|
+
icon = "icons/tomoobjserie.svg"
|
48
|
+
priority = 55
|
49
|
+
keywords = ["tomography", "selection", "tomwer", "serie", "group"]
|
50
|
+
|
51
|
+
ewokstaskclass = tomwer.core.process.control.tomoobjserie._TomoobjseriePlaceHolder
|
52
|
+
|
53
|
+
want_main_area = True
|
54
|
+
want_control_area = False
|
55
|
+
resizing_enabled = True
|
56
|
+
compress_signal = False
|
57
|
+
|
58
|
+
class Inputs:
|
59
|
+
tomo_obj = Input(name="tomo obj", type=TomwerObject, multiple=True)
|
60
|
+
|
61
|
+
class Outputs:
|
62
|
+
serie = Output(name="serie", type=Serie)
|
63
|
+
|
64
|
+
def __init__(self, parent=None):
|
65
|
+
""" """
|
66
|
+
super().__init__(parent)
|
67
|
+
layout = gui.vBox(self.mainArea, self.name).layout()
|
68
|
+
|
69
|
+
self._widget = SerieWidgetDialog(self)
|
70
|
+
layout.addWidget(self._widget)
|
71
|
+
|
72
|
+
# connect signal / slot
|
73
|
+
self._widget.sigSerieSelected.connect(self._send_serie)
|
74
|
+
|
75
|
+
@Inputs.tomo_obj
|
76
|
+
def addTomoObj(self, tomo_obj, *args, **kwargs):
|
77
|
+
if tomo_obj is not None:
|
78
|
+
self._widget.add(tomo_obj)
|
79
|
+
|
80
|
+
def _send_serie(self, serie: Serie):
|
81
|
+
if not isinstance(serie, Serie):
|
82
|
+
raise TypeError(
|
83
|
+
f"serie is expected to be an instance of {Serie}. Not {type(serie)}"
|
84
|
+
)
|
85
|
+
self.Outputs.serie.send(serie)
|
@@ -29,10 +29,10 @@ __authors__ = [
|
|
29
29
|
__license__ = "MIT"
|
30
30
|
__date__ = "12/07/2022"
|
31
31
|
|
32
|
+
from silx.gui import qt
|
32
33
|
from orangewidget import gui
|
33
34
|
from orangewidget.widget import Output, Input, OWBaseWidget
|
34
35
|
from tomwer.core.volume.volumebase import TomwerVolumeBase
|
35
|
-
from tomwer.web.client import OWClient
|
36
36
|
from tomwer.core.scan.hdf5scan import HDF5TomoScan
|
37
37
|
from tomwer.gui.control.volumeselectorwidget import VolumeSelectorWidget
|
38
38
|
from orangewidget.settings import Setting
|
@@ -42,7 +42,7 @@ import logging
|
|
42
42
|
logger = logging.getLogger(__name__)
|
43
43
|
|
44
44
|
|
45
|
-
class VolumeSelectorOW(OWBaseWidget,
|
45
|
+
class VolumeSelectorOW(OWBaseWidget, openclass=True):
|
46
46
|
name = "volume selector"
|
47
47
|
id = "orange.widgets.tomwer.volumeselector"
|
48
48
|
description = (
|
@@ -72,8 +72,7 @@ class VolumeSelectorOW(OWBaseWidget, OWClient, openclass=True):
|
|
72
72
|
|
73
73
|
def __init__(self, parent=None):
|
74
74
|
""" """
|
75
|
-
|
76
|
-
OWClient.__init__(self)
|
75
|
+
super().__init__(parent)
|
77
76
|
|
78
77
|
self.widget = VolumeSelectorWidget(parent=self)
|
79
78
|
self._loadSettings()
|
@@ -128,3 +127,12 @@ class VolumeSelectorOW(OWBaseWidget, OWClient, openclass=True):
|
|
128
127
|
self._scanIDs = []
|
129
128
|
for scan in self.widget.dataList._myitems:
|
130
129
|
self._scanIDs.append(scan)
|
130
|
+
|
131
|
+
def keyPressEvent(self, event):
|
132
|
+
"""
|
133
|
+
To shortcut orange and make sure the `delete` key will be interpreted we need to overwrite this function
|
134
|
+
"""
|
135
|
+
if event.key() == qt.Qt.Key_Delete:
|
136
|
+
self.widget._callbackRemoveSelectedDatasets()
|
137
|
+
else:
|
138
|
+
super().keyPressEvent(event)
|
@@ -32,7 +32,6 @@ from silx.gui import qt
|
|
32
32
|
from orangewidget import gui
|
33
33
|
|
34
34
|
import tomwer.core.process.control.volumesymlink
|
35
|
-
from tomwer.web.client import OWClient
|
36
35
|
from orangewidget.settings import Setting
|
37
36
|
from orangewidget.widget import Output, Input
|
38
37
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
@@ -47,7 +46,7 @@ import logging
|
|
47
46
|
_logger = logging.getLogger(__name__)
|
48
47
|
|
49
48
|
|
50
|
-
class VolumeSymLinkOW(SuperviseOW
|
49
|
+
class VolumeSymLinkOW(SuperviseOW):
|
51
50
|
"""
|
52
51
|
link volume reconstructed at proposal file if possible else under
|
53
52
|
the given folder
|
@@ -86,8 +85,7 @@ class VolumeSymLinkOW(SuperviseOW, OWClient):
|
|
86
85
|
data = Output(name="data", type=TomwerScanBase, doc="one scan to be process")
|
87
86
|
|
88
87
|
def __init__(self, parent=None):
|
89
|
-
|
90
|
-
OWClient.__init__(self)
|
88
|
+
super().__init__(parent)
|
91
89
|
self._mainWidget = _OutputDir(parent=self)
|
92
90
|
layout = gui.vBox(self.mainArea, self.name).layout()
|
93
91
|
layout.addWidget(self._mainWidget)
|
@@ -96,7 +94,13 @@ class VolumeSymLinkOW(SuperviseOW, OWClient):
|
|
96
94
|
def process(self, scan):
|
97
95
|
if scan is None:
|
98
96
|
return
|
99
|
-
symlink_process = VolumeSymbolicLinkProcess(
|
97
|
+
symlink_process = VolumeSymbolicLinkProcess(
|
98
|
+
inputs={
|
99
|
+
"data": scan,
|
100
|
+
"output_type": self._mainWidget.getOutputType(),
|
101
|
+
"output_folder": self._mainWidget.getOutputFolder(),
|
102
|
+
}
|
103
|
+
)
|
100
104
|
symlink_process.set_configuration(
|
101
105
|
{
|
102
106
|
"output_type": self._mainWidget.getOutputType(),
|
@@ -109,7 +113,7 @@ class VolumeSymLinkOW(SuperviseOW, OWClient):
|
|
109
113
|
state=DatasetState.ON_GOING,
|
110
114
|
)
|
111
115
|
try:
|
112
|
-
|
116
|
+
symlink_process.run()
|
113
117
|
except Exception:
|
114
118
|
mess = "Failed to create symbolic link for {}".format(str(scan))
|
115
119
|
_logger.processFailed(mess)
|
@@ -158,7 +162,7 @@ class _OutputDir(qt.QGroupBox):
|
|
158
162
|
def _activeStaticOpt(self, *args, **kwargs):
|
159
163
|
self._staticOpt.setChecked(True)
|
160
164
|
|
161
|
-
def _selectFolder(self):
|
165
|
+
def _selectFolder(self): # pragma: no cover
|
162
166
|
dialog = qt.QFileDialog(self)
|
163
167
|
dialog.setWindowTitle("Select destination folder for symbolic link")
|
164
168
|
dialog.setModal(1)
|