tomwer 1.2.0a1__py3-none-any.whl → 1.2.0a3__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/append_raw_darks_and_flats_frames_to_NXtomos.ows +44 -0
- orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows +55 -0
- orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth2.ows +48 -0
- orangecontrib/tomwer/tutorials/default_cor_search.ows +40 -0
- orangecontrib/tomwer/tutorials/hello_world_python_script.ows +50 -0
- orangecontrib/tomwer/tutorials/simple_slice_reconstruction_on_slurm.ows +50 -0
- orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +8 -8
- orangecontrib/tomwer/widgets/__init__.py +1 -1
- orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +0 -1
- orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +8 -6
- orangecontrib/tomwer/widgets/control/AdvancementOW.py +0 -1
- orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +1 -6
- orangecontrib/tomwer/widgets/control/DataListOW.py +0 -1
- orangecontrib/tomwer/widgets/control/DataListenerOW.py +4 -4
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +0 -1
- orangecontrib/tomwer/widgets/control/DataTransfertOW.py +7 -7
- orangecontrib/tomwer/widgets/control/DataValidatorOW.py +0 -1
- orangecontrib/tomwer/widgets/control/DataWatcherOW.py +0 -3
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +3 -2
- orangecontrib/tomwer/widgets/control/EmailOW.py +82 -0
- orangecontrib/tomwer/widgets/control/FilterOW.py +3 -3
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +1 -1
- orangecontrib/tomwer/widgets/control/NotifierOW.py +0 -1
- orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py +93 -0
- orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +29 -5
- orangecontrib/tomwer/widgets/control/TimerOW.py +1 -2
- orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +0 -1
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +0 -1
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +4 -10
- orangecontrib/tomwer/widgets/control/icons/email.png +0 -0
- orangecontrib/tomwer/widgets/control/icons/email.svg +58 -0
- orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png +0 -0
- orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg +199 -0
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +0 -1
- orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py +0 -1
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +1 -2
- orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +1 -2
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +0 -1
- orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +0 -1
- orangecontrib/tomwer/widgets/other/PythonScriptOW.py +29 -1
- orangecontrib/tomwer/widgets/other/TomoObjsHub.py +28 -0
- orangecontrib/tomwer/widgets/other/icons/hub.png +0 -0
- orangecontrib/tomwer/widgets/other/icons/hub.svg +113 -0
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +18 -12
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +0 -2
- orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +21 -6
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +29 -7
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +18 -5
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +40 -13
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +37 -10
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +2 -3
- orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +5 -4
- orangecontrib/tomwer/widgets/stitching/StitcherOW.py +0 -1
- orangecontrib/tomwer/widgets/stitching/ZStitchingConfigOW.py +0 -1
- orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +10 -4
- orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +0 -1
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +0 -1
- orangecontrib/tomwer/widgets/visualization/RadioStackOW.py +7 -5
- orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -3
- orangecontrib/tomwer/widgets/visualization/SliceStackOW.py +7 -5
- orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +4 -4
- tomwer/__main__.py +139 -5
- tomwer/app/axis.py +16 -5
- tomwer/app/canvas_launcher/config.py +1 -1
- tomwer/app/canvas_launcher/mainwindow.py +164 -6
- tomwer/app/darkref.py +10 -181
- tomwer/app/darkrefpatch.py +10 -131
- tomwer/app/diffframe.py +11 -0
- tomwer/app/imagekeyeditor.py +12 -19
- tomwer/app/intensitynormalization.py +1 -0
- tomwer/app/lamino.py +7 -2
- tomwer/app/patchrawdarkflat.py +131 -0
- tomwer/app/radiostack.py +10 -0
- tomwer/app/reducedarkflat.py +205 -0
- tomwer/app/saaxis.py +27 -8
- tomwer/app/sadeltabeta.py +29 -8
- tomwer/app/samplemoved.py +11 -0
- tomwer/app/scanviewer.py +12 -0
- tomwer/app/sinogramviewer.py +11 -0
- tomwer/app/slicestack.py +11 -0
- tomwer/app/zstitching.py +12 -0
- tomwer/core/futureobject.py +4 -2
- tomwer/core/process/conditions/filters.py +26 -4
- tomwer/core/process/control/datadiscovery.py +4 -0
- tomwer/core/process/control/datawatcher/datawatcher.py +5 -1
- tomwer/core/process/control/email.py +148 -0
- tomwer/core/process/control/nxtomoconcatenate.py +9 -2
- tomwer/core/process/control/nxtomomill.py +58 -16
- tomwer/core/process/control/scanselector.py +4 -0
- tomwer/core/process/control/scantransfer.py +52 -23
- tomwer/core/process/control/test/test_concatenate_nxtomos.py +1 -0
- tomwer/core/process/control/test/test_email.py +52 -0
- tomwer/core/process/control/test/test_h52nx_process.py +106 -0
- tomwer/core/process/control/test/test_volume_link.py +5 -4
- tomwer/core/process/control/timer.py +27 -6
- tomwer/core/process/control/tomoobjserie.py +4 -0
- tomwer/core/process/control/volumeselector.py +4 -0
- tomwer/core/process/control/volumesymlink.py +47 -8
- tomwer/core/process/edit/darkflatpatch.py +49 -8
- tomwer/core/process/edit/imagekeyeditor.py +63 -13
- tomwer/core/process/reconstruction/axis/__init__.py +1 -1
- tomwer/core/process/reconstruction/axis/axis.py +61 -41
- tomwer/core/process/reconstruction/axis/params.py +4 -6
- tomwer/core/process/reconstruction/darkref/darkrefs.py +53 -16
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +12 -2
- tomwer/core/process/reconstruction/lamino/__init__.py +1 -1
- tomwer/core/process/reconstruction/lamino/tofu.py +22 -2
- tomwer/core/process/reconstruction/nabu/nabucommon.py +93 -14
- tomwer/core/process/reconstruction/nabu/nabuscores.py +70 -33
- tomwer/core/process/reconstruction/nabu/nabuslices.py +219 -41
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +240 -108
- tomwer/core/process/reconstruction/nabu/utils.py +10 -36
- tomwer/core/process/reconstruction/normalization/normalization.py +10 -3
- tomwer/core/process/reconstruction/saaxis/__init__.py +1 -0
- tomwer/core/process/reconstruction/saaxis/saaxis.py +564 -376
- tomwer/core/process/reconstruction/sadeltabeta/__init__.py +1 -0
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +481 -268
- tomwer/core/process/reconstruction/scores/params.py +21 -8
- tomwer/core/process/reconstruction/test/test_darkref_copy.py +2 -0
- tomwer/core/process/reconstruction/test/test_saaxis.py +21 -8
- tomwer/core/process/reconstruction/test/test_sadeltabeta.py +8 -5
- tomwer/core/process/script/python.py +7 -2
- tomwer/core/process/stitching/nabustitcher.py +10 -3
- tomwer/core/process/task.py +2 -9
- tomwer/core/process/test/test_axis.py +25 -15
- tomwer/core/process/test/test_conditions.py +6 -6
- tomwer/core/process/test/test_dark_and_flat.py +20 -15
- tomwer/core/process/test/test_data_transfer.py +8 -8
- tomwer/core/process/test/test_data_watcher.py +1 -1
- tomwer/core/process/test/test_lamino.py +6 -6
- tomwer/core/process/test/test_nabu.py +13 -8
- tomwer/core/process/test/test_normalization.py +1 -0
- tomwer/core/process/test/test_timer.py +6 -6
- tomwer/core/process/visualization/dataviewer.py +4 -0
- tomwer/core/process/visualization/diffviewer.py +4 -0
- tomwer/core/process/visualization/imagestackviewer.py +4 -0
- tomwer/core/process/visualization/radiostack.py +4 -0
- tomwer/core/process/visualization/samplemoved.py +4 -0
- tomwer/core/process/visualization/sinogramviewer.py +4 -0
- tomwer/core/process/visualization/slicestack.py +4 -0
- tomwer/core/process/visualization/volumeviewer.py +4 -0
- tomwer/core/scan/hdf5scan.py +4 -4
- tomwer/core/scan/scanbase.py +5 -1
- tomwer/core/scan/test/test_process_registration.py +9 -9
- tomwer/core/settings.py +59 -1
- tomwer/core/test/test_lamino.py +2 -1
- tomwer/core/utils/__init__.py +16 -0
- tomwer/core/utils/locker.py +0 -1
- tomwer/core/utils/resource.py +6 -11
- tomwer/core/utils/scanutils.py +2 -0
- tomwer/gui/cluster/slurm.py +91 -7
- tomwer/gui/cluster/supervisor.py +16 -11
- tomwer/gui/cluster/test/test_cluster.py +16 -1
- tomwer/gui/conditions/filter.py +3 -3
- tomwer/gui/control/datalist.py +24 -11
- tomwer/gui/control/email.py +183 -0
- tomwer/gui/control/reducedarkflatselector.py +545 -0
- tomwer/gui/control/singletomoobj.py +23 -1
- tomwer/gui/control/test/test_email.py +35 -0
- tomwer/gui/control/test/test_reducedarkflat_selector.py +280 -0
- tomwer/gui/reconstruction/axis/CompareImages.py +1 -1
- tomwer/gui/reconstruction/axis/axis.py +10 -6
- tomwer/gui/reconstruction/axis/radioaxis.py +14 -6
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +2 -0
- tomwer/gui/reconstruction/darkref/darkrefwidget.py +4 -4
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +3 -1
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +34 -33
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +1 -1
- tomwer/gui/reconstruction/normalization/intensity.py +5 -5
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +1 -0
- tomwer/gui/reconstruction/saaxis/saaxis.py +6 -6
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +6 -6
- tomwer/gui/reconstruction/scores/scoreplot.py +6 -4
- tomwer/gui/samplemoved/__init__.py +2 -2
- tomwer/gui/stackplot.py +18 -7
- tomwer/gui/stacks.py +2 -2
- tomwer/gui/stitching/stitchandbackground.py +2 -2
- tomwer/gui/stitching/stitching.py +1 -1
- tomwer/gui/stitching/stitching_raw.py +1 -1
- tomwer/gui/utils/__init__.py +1 -85
- tomwer/gui/utils/illustrations.py +1 -1
- tomwer/gui/utils/inputwidget.py +41 -36
- tomwer/gui/utils/slider.py +2 -2
- tomwer/gui/utils/utils.py +93 -0
- tomwer/gui/visualization/dataviewer.py +8 -5
- tomwer/gui/visualization/diffviewer/diffviewer.py +4 -4
- tomwer/gui/visualization/reconstructionparameters.py +26 -6
- tomwer/gui/visualization/sinogramviewer.py +7 -1
- tomwer/gui/visualization/test/test_reconstruction_parameters.py +2 -4
- tomwer/gui/visualization/volumeviewer.py +2 -0
- tomwer/resources/__init__.py +55 -43
- tomwer/resources/gui/icons/compose.png +0 -0
- tomwer/resources/gui/icons/compose.svg +75 -0
- tomwer/synctools/datatransfert.py +3 -1
- tomwer/synctools/stacks/edit/darkflatpatch.py +39 -34
- tomwer/synctools/stacks/edit/imagekeyeditor.py +8 -27
- tomwer/synctools/stacks/processingstack.py +45 -9
- tomwer/synctools/stacks/reconstruction/axis.py +6 -5
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +1 -0
- tomwer/synctools/stacks/reconstruction/lamino.py +3 -3
- tomwer/synctools/stacks/reconstruction/nabu.py +49 -140
- tomwer/synctools/stacks/reconstruction/normalization.py +1 -0
- tomwer/synctools/stacks/reconstruction/saaxis.py +19 -33
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +16 -32
- tomwer/synctools/test/test_darkRefs.py +19 -10
- tomwer/synctools/test/test_foldertransfer.py +7 -7
- tomwer/third_party/nabu/preproc/phase.py +6 -8
- tomwer/third_party/nabu/utils.py +2 -3
- tomwer/version.py +1 -1
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/METADATA +15 -54
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/RECORD +219 -192
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/WHEEL +1 -1
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/entry_points.txt +3 -3
- /tomwer-1.2.0a1-py3.9-nspkg.pth → /tomwer-1.2.0a3-py3.11-nspkg.pth +0 -0
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/LICENSE +0 -0
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,280 @@
|
|
1
|
+
import numpy
|
2
|
+
from silx.gui.utils.testutils import SignalListener
|
3
|
+
from tomwer.tests.conftest import qtapp # noqa F401
|
4
|
+
from tomwer.gui.control.reducedarkflatselector import (
|
5
|
+
filter_selected_reduced_frames,
|
6
|
+
filter_unselected_reduced_frames,
|
7
|
+
ReduceDarkFlatSelectorWidget,
|
8
|
+
ReduceDarkFlatSelectorDialog,
|
9
|
+
)
|
10
|
+
|
11
|
+
|
12
|
+
def test_reduce_darkflat_selector(
|
13
|
+
qtapp, # noqa F811
|
14
|
+
):
|
15
|
+
widget = ReduceDarkFlatSelectorWidget()
|
16
|
+
widget.show()
|
17
|
+
|
18
|
+
widget.addReduceFrames(
|
19
|
+
{
|
20
|
+
0: numpy.random.random(100 * 100).reshape(100, 100),
|
21
|
+
1: numpy.random.random(100 * 100).reshape(100, 100),
|
22
|
+
}
|
23
|
+
)
|
24
|
+
|
25
|
+
widget.addReduceFrames(
|
26
|
+
{
|
27
|
+
"reduce_frames_name": "my_dict",
|
28
|
+
-1: numpy.random.random(100 * 100).reshape(100, 100),
|
29
|
+
2: numpy.random.random(100 * 100).reshape(100, 100),
|
30
|
+
}
|
31
|
+
)
|
32
|
+
|
33
|
+
config = widget.getConfiguration()
|
34
|
+
assert len(config) == 2
|
35
|
+
assert config[0]["reduce_frames_name"] == "reduced frames #0"
|
36
|
+
assert config[1]["reduce_frames_name"] == "my_dict"
|
37
|
+
|
38
|
+
widget.setConfiguration(
|
39
|
+
(
|
40
|
+
{
|
41
|
+
"reduce_frames_name": "toto frames",
|
42
|
+
"reduce_frames": (
|
43
|
+
{
|
44
|
+
"index": -1, # -1 will be interpreated as at the end of the acquisition
|
45
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
46
|
+
"selected": True,
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"index": 0,
|
50
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
51
|
+
"selected": True,
|
52
|
+
},
|
53
|
+
),
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"reduce_frames_name": "tata frames",
|
57
|
+
"reduce_frames": (
|
58
|
+
{
|
59
|
+
"index": "0.25r",
|
60
|
+
"data": numpy.random.random(40 * 20).reshape(40, 20),
|
61
|
+
"selected": False,
|
62
|
+
},
|
63
|
+
),
|
64
|
+
},
|
65
|
+
)
|
66
|
+
)
|
67
|
+
|
68
|
+
config = widget.getConfiguration()
|
69
|
+
assert len(config) == 2
|
70
|
+
# check selection has been well take into account
|
71
|
+
assert config[0]["reduce_frames"][0]["selected"]
|
72
|
+
assert config[0]["reduce_frames"][1]["selected"]
|
73
|
+
assert not config[1]["reduce_frames"][0]["selected"]
|
74
|
+
|
75
|
+
selected_frames = widget.getSelectedReduceFrames()
|
76
|
+
assert -1 in selected_frames
|
77
|
+
assert 0 in selected_frames
|
78
|
+
assert 0.25 not in selected_frames
|
79
|
+
|
80
|
+
# test receive twice the same 'reduce_frames_name'
|
81
|
+
widget.clear()
|
82
|
+
assert len(widget.getConfiguration()) == 0
|
83
|
+
for i in range(2):
|
84
|
+
widget.addReduceFrames(
|
85
|
+
{
|
86
|
+
"reduce_frames_name": "my_dict",
|
87
|
+
-1: numpy.random.random(100 * 100).reshape(100, 100),
|
88
|
+
2: numpy.random.random(100 * 100).reshape(100, 100),
|
89
|
+
}
|
90
|
+
)
|
91
|
+
assert len(widget.getConfiguration()) == 1
|
92
|
+
|
93
|
+
|
94
|
+
def test_reduce_darkflat_selector_dialog(
|
95
|
+
qtapp, # noqa F811
|
96
|
+
):
|
97
|
+
dialog = ReduceDarkFlatSelectorDialog()
|
98
|
+
|
99
|
+
flat_sel_signal_listener = SignalListener()
|
100
|
+
dialog.sigSelectActiveAsFlats.connect(flat_sel_signal_listener)
|
101
|
+
|
102
|
+
dark_sel_signal_listener = SignalListener()
|
103
|
+
dialog.sigSelectActiveAsDarks.connect(dark_sel_signal_listener)
|
104
|
+
|
105
|
+
dialog.show()
|
106
|
+
|
107
|
+
dialog.addReduceFrames(
|
108
|
+
{
|
109
|
+
0: numpy.random.random(100 * 100).reshape(100, 100),
|
110
|
+
1: numpy.random.random(100 * 100).reshape(100, 100),
|
111
|
+
},
|
112
|
+
selected=(1,),
|
113
|
+
)
|
114
|
+
|
115
|
+
dialog.addReduceFrames(
|
116
|
+
{
|
117
|
+
"reduce_frames_name": "my_dict",
|
118
|
+
-1: numpy.random.random(100 * 100).reshape(100, 100),
|
119
|
+
2: numpy.random.random(100 * 100).reshape(100, 100),
|
120
|
+
},
|
121
|
+
selected=(-1,),
|
122
|
+
)
|
123
|
+
|
124
|
+
# check dark selection
|
125
|
+
assert dark_sel_signal_listener.callCount() == 0
|
126
|
+
dialog._darkSelected()
|
127
|
+
assert dark_sel_signal_listener.callCount() == 1
|
128
|
+
assert -1 in dark_sel_signal_listener.arguments()[0][0]
|
129
|
+
|
130
|
+
# check flat selection
|
131
|
+
assert flat_sel_signal_listener.callCount() == 0
|
132
|
+
dialog._flatSelected()
|
133
|
+
assert flat_sel_signal_listener.callCount() == 1
|
134
|
+
assert -1 in flat_sel_signal_listener.arguments()[0][0]
|
135
|
+
|
136
|
+
# check remove selected
|
137
|
+
dialog._removeSelected()
|
138
|
+
assert dialog._widget.getSelectedReduceFrames() == {}
|
139
|
+
|
140
|
+
# check clear selection
|
141
|
+
dialog.addReduceFrames(
|
142
|
+
{
|
143
|
+
"reduce_frames_name": "new dict",
|
144
|
+
-1: numpy.random.random(100 * 100).reshape(100, 100),
|
145
|
+
2: numpy.random.random(100 * 100).reshape(100, 100),
|
146
|
+
},
|
147
|
+
selected=(-1, 2),
|
148
|
+
)
|
149
|
+
|
150
|
+
assert len(dialog._widget.getSelectedReduceFrames()) == 2
|
151
|
+
dialog._clearSelection()
|
152
|
+
assert len(dialog._widget.getSelectedReduceFrames()) == 0
|
153
|
+
|
154
|
+
|
155
|
+
def test_reduced_frames_filtering():
|
156
|
+
"""
|
157
|
+
dummy test of the filter_selected_reduced_frames filter_unselected_reduced_frames function
|
158
|
+
"""
|
159
|
+
check_reduce_frames_configuration(
|
160
|
+
filter_selected_reduced_frames(
|
161
|
+
(
|
162
|
+
{
|
163
|
+
"reduce_frames_name": "toto frames",
|
164
|
+
"reduce_frames": (
|
165
|
+
{
|
166
|
+
"index": -1, # -1 will be interpreated as at the end of the acquisition
|
167
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
168
|
+
"selected": True,
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"index": 0,
|
172
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
173
|
+
"selected": True,
|
174
|
+
},
|
175
|
+
),
|
176
|
+
},
|
177
|
+
{
|
178
|
+
"reduce_frames_name": "tata frames",
|
179
|
+
"reduce_frames": (
|
180
|
+
{
|
181
|
+
"index": "0.25r",
|
182
|
+
"data": numpy.random.random(40 * 20).reshape(40, 20),
|
183
|
+
"selected": False,
|
184
|
+
},
|
185
|
+
),
|
186
|
+
},
|
187
|
+
)
|
188
|
+
),
|
189
|
+
(
|
190
|
+
{
|
191
|
+
"reduce_frames_name": "toto frames",
|
192
|
+
"reduce_frames": (
|
193
|
+
{
|
194
|
+
"index": -1, # -1 will be interpreated as at the end of the acquisition
|
195
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
196
|
+
"selected": True,
|
197
|
+
},
|
198
|
+
{
|
199
|
+
"index": 0,
|
200
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
201
|
+
"selected": True,
|
202
|
+
},
|
203
|
+
),
|
204
|
+
},
|
205
|
+
),
|
206
|
+
)
|
207
|
+
|
208
|
+
check_reduce_frames_configuration(
|
209
|
+
filter_unselected_reduced_frames(
|
210
|
+
(
|
211
|
+
{
|
212
|
+
"reduce_frames_name": "toto frames",
|
213
|
+
"reduce_frames": (
|
214
|
+
{
|
215
|
+
"index": -1, # -1 will be interpreated as at the end of the acquisition
|
216
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
217
|
+
"selected": True,
|
218
|
+
},
|
219
|
+
{
|
220
|
+
"index": 0,
|
221
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
222
|
+
"selected": False,
|
223
|
+
},
|
224
|
+
),
|
225
|
+
},
|
226
|
+
{
|
227
|
+
"reduce_frames_name": "tata frames",
|
228
|
+
"reduce_frames": (
|
229
|
+
{
|
230
|
+
"index": "0.25r",
|
231
|
+
"data": numpy.random.random(40 * 20).reshape(40, 20),
|
232
|
+
"selected": False,
|
233
|
+
},
|
234
|
+
),
|
235
|
+
},
|
236
|
+
)
|
237
|
+
),
|
238
|
+
(
|
239
|
+
{
|
240
|
+
"reduce_frames_name": "toto frames",
|
241
|
+
"reduce_frames": (
|
242
|
+
{
|
243
|
+
"index": 0,
|
244
|
+
"data": numpy.random.random(20 * 20).reshape(20, 20),
|
245
|
+
"selected": False,
|
246
|
+
},
|
247
|
+
),
|
248
|
+
},
|
249
|
+
{
|
250
|
+
"reduce_frames_name": "tata frames",
|
251
|
+
"reduce_frames": (
|
252
|
+
{
|
253
|
+
"index": "0.25r",
|
254
|
+
"data": numpy.random.random(40 * 20).reshape(40, 20),
|
255
|
+
"selected": False,
|
256
|
+
},
|
257
|
+
),
|
258
|
+
},
|
259
|
+
),
|
260
|
+
)
|
261
|
+
|
262
|
+
check_reduce_frames_configuration(filter_unselected_reduced_frames(()), ())
|
263
|
+
|
264
|
+
|
265
|
+
def check_reduce_frames_configuration(config_1, config_2):
|
266
|
+
"""
|
267
|
+
simple comparaison of two configurations
|
268
|
+
"""
|
269
|
+
assert len(config_1) == len(config_2)
|
270
|
+
for reduce_frame_group_1, reduce_frame_group_2 in zip(config_1, config_2):
|
271
|
+
assert reduce_frame_group_1.get(
|
272
|
+
"reduce_frames_name", None
|
273
|
+
) == reduce_frame_group_2.get("reduce_frames_name", None)
|
274
|
+
|
275
|
+
for reduce_frame_group_1, reduce_frame_group_2 in zip(
|
276
|
+
reduce_frame_group_1.get("reduce_frames", tuple()),
|
277
|
+
reduce_frame_group_2.get("reduce_frames", tuple()),
|
278
|
+
):
|
279
|
+
assert reduce_frame_group_1["index"] == reduce_frame_group_2["index"]
|
280
|
+
assert reduce_frame_group_1["selected"] == reduce_frame_group_2["selected"]
|
@@ -202,7 +202,7 @@ class CompareImages(_CompareImages.CompareImages):
|
|
202
202
|
"""Emit when cropping of the compared images has changed"""
|
203
203
|
|
204
204
|
def __init__(self, parent=None, backend=None):
|
205
|
-
super().__init__(parent, backend)
|
205
|
+
super().__init__(parent, backend=backend)
|
206
206
|
self.__cropComparedImages = True
|
207
207
|
|
208
208
|
def cropComparedImages(self) -> bool:
|
@@ -101,8 +101,8 @@ class AxisWindow(qt.QMainWindow):
|
|
101
101
|
sigLockModeChanged = qt.Signal()
|
102
102
|
"""Signal emitted when the lock on the method change"""
|
103
103
|
|
104
|
-
def __init__(self, axis_params, parent=None):
|
105
|
-
|
104
|
+
def __init__(self, axis_params, parent=None, backend=None):
|
105
|
+
super().__init__(parent=parent)
|
106
106
|
self._mainWidget = qt.QWidget(self)
|
107
107
|
self._mainWidget.setLayout(qt.QVBoxLayout())
|
108
108
|
self.setCentralWidget(self._mainWidget)
|
@@ -119,7 +119,9 @@ class AxisWindow(qt.QMainWindow):
|
|
119
119
|
self._selectionGB.hide()
|
120
120
|
|
121
121
|
# add widget for radio and sinogram axis
|
122
|
-
self._axisWidget = _AxisWidget(
|
122
|
+
self._axisWidget = _AxisWidget(
|
123
|
+
parent=self, axis_params=axis_params, backend=backend
|
124
|
+
)
|
123
125
|
self._mainWidget.layout().addWidget(self._axisWidget)
|
124
126
|
|
125
127
|
self.setCentralWidget(self._mainWidget)
|
@@ -226,8 +228,8 @@ class _AxisWidget(qt.QMainWindow):
|
|
226
228
|
|
227
229
|
sigSinogramReady = qt.Signal()
|
228
230
|
|
229
|
-
def __init__(self, parent, axis_params):
|
230
|
-
|
231
|
+
def __init__(self, parent, axis_params, backend=None):
|
232
|
+
super().__init__(parent)
|
231
233
|
self._settingsWidget = None
|
232
234
|
self.setDockOptions(qt.QMainWindow.AnimatedDocks)
|
233
235
|
|
@@ -253,7 +255,9 @@ class _AxisWidget(qt.QMainWindow):
|
|
253
255
|
self.addDockWidget(qt.Qt.RightDockWidgetArea, self._controlDockWidget)
|
254
256
|
|
255
257
|
self._axis_params = axis_params
|
256
|
-
self._radioAxis = RadioAxisWindow(
|
258
|
+
self._radioAxis = RadioAxisWindow(
|
259
|
+
parent=self, axis=axis_params, backend=backend
|
260
|
+
)
|
257
261
|
self._plotWidgets = qt.QWidget(self)
|
258
262
|
self._plotWidgets.setLayout(qt.QVBoxLayout())
|
259
263
|
self.setCentralWidget(self._plotWidgets)
|
@@ -80,8 +80,8 @@ class RadioAxisWindow(qt.QMainWindow):
|
|
80
80
|
sigPositionChanged = qt.Signal(tuple)
|
81
81
|
"""signal emitted when the center of rotation center change"""
|
82
82
|
|
83
|
-
def __init__(self, axis, parent=None):
|
84
|
-
|
83
|
+
def __init__(self, axis, parent=None, backend=None):
|
84
|
+
super().__init__(parent)
|
85
85
|
if isinstance(axis, QAxisRP):
|
86
86
|
self.__recons_params = axis
|
87
87
|
else:
|
@@ -106,7 +106,7 @@ class RadioAxisWindow(qt.QMainWindow):
|
|
106
106
|
# cache to know if the y origin has changed since
|
107
107
|
|
108
108
|
self.setWindowFlags(qt.Qt.Widget)
|
109
|
-
self._plot = CompareImages(parent=self)
|
109
|
+
self._plot = CompareImages(parent=self, backend=backend)
|
110
110
|
self._plot.setAutoResetZoom(False)
|
111
111
|
_mode = CompareImages.VisualizationMode.COMPOSITE_A_MINUS_B
|
112
112
|
self._plot.setVisualizationMode(_mode)
|
@@ -2565,10 +2565,18 @@ class _ManualFramesSelection(qt.QWidget):
|
|
2565
2565
|
idx = self._frame1CB.findText(current_angle1)
|
2566
2566
|
if idx >= 0:
|
2567
2567
|
self._frame1CB.setCurrentIndex(idx)
|
2568
|
+
if current_angle1 == current_angle2:
|
2569
|
+
# if the two current angle are close then we consider it is better to look for angleX - angleX + 180 angles
|
2570
|
+
# instead of finding back angles
|
2571
|
+
self._findAssociatedAngle()
|
2572
|
+
else:
|
2573
|
+
idx = self._frame1CB.findText(current_angle1)
|
2574
|
+
if idx >= 0:
|
2575
|
+
self._frame1CB.setCurrentIndex(idx)
|
2568
2576
|
|
2569
|
-
|
2570
|
-
|
2571
|
-
|
2577
|
+
idx = self._frame2CB.findText(current_angle2)
|
2578
|
+
if idx >= 0:
|
2579
|
+
self._frame2CB.setCurrentIndex(idx)
|
2572
2580
|
|
2573
2581
|
def getFramesUrl(self, as_txt=False) -> tuple:
|
2574
2582
|
"""
|
@@ -253,6 +253,7 @@ class RefCopyWidget(qt.QGroupBox):
|
|
253
253
|
_logger.error(f"Fails to define flat url. Error is {e}")
|
254
254
|
return False
|
255
255
|
else:
|
256
|
+
self._statusBar.showMessage(f"darks set from {url.path()}")
|
256
257
|
DarkRefsCopy.save_flats_to_be_copied(self.__save_dir, data=url)
|
257
258
|
return True
|
258
259
|
return False
|
@@ -268,6 +269,7 @@ class RefCopyWidget(qt.QGroupBox):
|
|
268
269
|
_logger.error(f"Fails to define flat url. Error is {e}")
|
269
270
|
return False
|
270
271
|
else:
|
272
|
+
self._statusBar.showMessage(f"darks set from {url.path()}")
|
271
273
|
DarkRefsCopy.save_darks_to_be_copied(self.__save_dir, data=url)
|
272
274
|
return True
|
273
275
|
return False
|
@@ -33,7 +33,7 @@ import logging
|
|
33
33
|
from silx.gui import qt
|
34
34
|
|
35
35
|
from tomwer.core.process.reconstruction.darkref import params as dkrf
|
36
|
-
from tomwer.core.process.reconstruction.darkref.darkrefs import
|
36
|
+
from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask
|
37
37
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
38
38
|
from tomwer.gui.utils.sandboxes import RegularExpressionSandBox
|
39
39
|
from tomwer.synctools.darkref import QDKRFRP
|
@@ -89,7 +89,7 @@ class DarkRefWidget(qt.QWidget):
|
|
89
89
|
return self.mainWidget.recons_params
|
90
90
|
|
91
91
|
|
92
|
-
class QDarkRefs(
|
92
|
+
class QDarkRefs(DarkRefsTask):
|
93
93
|
def _computationStarts(self):
|
94
94
|
pass
|
95
95
|
|
@@ -232,14 +232,14 @@ class _TabExpert(qt.QWidget):
|
|
232
232
|
qt.QLabel("pyhst dark file pattern", parent=self._patternsWidget), 0, 0
|
233
233
|
)
|
234
234
|
self._darkLE = qt.QLineEdit(parent=self._patternsWidget)
|
235
|
-
self._darkLE.setToolTip(
|
235
|
+
self._darkLE.setToolTip(DarkRefsTask.getDarkPatternTooltip())
|
236
236
|
self._darkLE.editingFinished.connect(self._darkPatternEdited)
|
237
237
|
self._patternsWidget.layout().addWidget(self._darkLE, 0, 1)
|
238
238
|
self._patternsWidget.layout().addWidget(
|
239
239
|
qt.QLabel("pyhst flat file pattern", parent=self._patternsWidget), 1, 0
|
240
240
|
)
|
241
241
|
self._refLE = qt.QLineEdit(parent=self._patternsWidget)
|
242
|
-
self._refLE.setToolTip(
|
242
|
+
self._refLE.setToolTip(DarkRefsTask.getRefPatternTooltip())
|
243
243
|
self._refLE.editingFinished.connect(self._refPatternEdited)
|
244
244
|
|
245
245
|
self._patternsWidget.layout().addWidget(self._refLE, 1, 1)
|
@@ -181,7 +181,9 @@ class NabuPaganinConfig(qt.QWidget, base._NabuStageConfigBase):
|
|
181
181
|
label = DELTA_CHAR + " / " + BETA_CHAR
|
182
182
|
self._db_label = qt.QLabel(label, self)
|
183
183
|
self.layout().addWidget(self._db_label, 0, 0, 1, 1)
|
184
|
-
self._deltaBetaQLE = SelectionLineEdit(
|
184
|
+
self._deltaBetaQLE = SelectionLineEdit(
|
185
|
+
"100.0", self, allow_negative_indices=False
|
186
|
+
)
|
185
187
|
self.layout().addWidget(self._deltaBetaQLE, 0, 1, 1, 3)
|
186
188
|
self.registerWidget(self._db_label, "required")
|
187
189
|
self.registerWidget(self._deltaBetaQLE, "required")
|
@@ -372,42 +372,43 @@ class _NabuPreProcessingConfig(_NabuStageConfigBase, qt.QWidget):
|
|
372
372
|
except Exception as e:
|
373
373
|
_logger.error(e)
|
374
374
|
|
375
|
-
def _setConfiguration(self, conf):
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
375
|
+
def _setConfiguration(self, conf: dict):
|
376
|
+
ff = conf.get("flatfield", None)
|
377
|
+
if ff is not None:
|
378
|
+
self._flatFieldCB.setChecked(bool(ff))
|
379
|
+
|
380
|
+
dff = conf.get("double_flatfield_enabled", None)
|
381
|
+
if dff is not None:
|
382
|
+
self._dffCB.setChecked(bool(dff))
|
383
|
+
|
384
|
+
dff_sigma = conf.get("dff_sigma", None)
|
385
|
+
if dff_sigma not in (None, "", "none"):
|
386
|
+
self._dffSigmaQDSB.setValue(float(dff_sigma))
|
387
|
+
|
388
|
+
ccd_filter = conf.get("ccd_filter_enabled", None)
|
389
|
+
if ccd_filter not in (None, "", "none"):
|
390
|
+
self._ccdFilterCB.setChecked(bool(ccd_filter))
|
391
|
+
|
392
|
+
ccd_filter_threshold = conf.get("ccd_filter_threshold", None)
|
393
|
+
if ccd_filter_threshold not in (None, "", "none"):
|
394
|
+
self._ccdThreshold.setValue(float(ccd_filter_threshold))
|
395
|
+
|
396
396
|
normalize_srcurrent = conf.get("normalize_srcurrent", None)
|
397
397
|
if normalize_srcurrent is not None:
|
398
398
|
self.setNormalizeCurrent(bool(normalize_srcurrent))
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
399
|
+
|
400
|
+
take_logarithm = conf.get("take_logarithm", None)
|
401
|
+
if take_logarithm not in (None, "", "none"):
|
402
|
+
self._takeLogarithmCB.setChecked(bool(take_logarithm))
|
403
|
+
|
404
|
+
clip_value = conf.get("log_min_clip", None)
|
405
|
+
if clip_value not in (None, "", "none"):
|
406
|
+
self._clipMinLogValue.setValue(float(clip_value))
|
407
|
+
|
408
|
+
clip_value = conf.get("log_max_clip", None)
|
409
|
+
if clip_value not in (None, "", "none"):
|
410
|
+
self._clipMaxLogValue.setValue(float(clip_value))
|
411
|
+
|
411
412
|
sino_rings_correction = conf.get("sino_rings_correction", None)
|
412
413
|
if sino_rings_correction is not None:
|
413
414
|
if sino_rings_correction == "":
|
@@ -71,7 +71,7 @@ class SliceGroupBox(qt.QGroupBox):
|
|
71
71
|
self.layout().addWidget(self._modeCB)
|
72
72
|
self._modeCB.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus)
|
73
73
|
|
74
|
-
self._sliceQLE = SelectionLineEdit(parent=self)
|
74
|
+
self._sliceQLE = SelectionLineEdit(parent=self, allow_negative_indices=True)
|
75
75
|
self.layout().addWidget(self._sliceQLE)
|
76
76
|
|
77
77
|
spacer = qt.QWidget(parent=self)
|
@@ -58,13 +58,13 @@ class SinoNormWindow(qt.QMainWindow):
|
|
58
58
|
sigConfigurationChanged = qt.Signal()
|
59
59
|
"""signal emit when the configuration change"""
|
60
60
|
|
61
|
-
def __init__(self, parent):
|
61
|
+
def __init__(self, parent, backend=None):
|
62
62
|
qt.QMainWindow.__init__(self, parent)
|
63
63
|
self._scan = None
|
64
64
|
self.setWindowFlags(qt.Qt.Widget)
|
65
65
|
|
66
66
|
# central widget
|
67
|
-
self._centralWidget = _Viewer(self)
|
67
|
+
self._centralWidget = _Viewer(self, backend=backend)
|
68
68
|
self.setCentralWidget(self._centralWidget)
|
69
69
|
|
70
70
|
# control widget (options + ctrl buttons)
|
@@ -198,13 +198,13 @@ class SinoNormWindow(qt.QMainWindow):
|
|
198
198
|
|
199
199
|
|
200
200
|
class _Viewer(qt.QTabWidget):
|
201
|
-
def __init__(self, parent):
|
201
|
+
def __init__(self, parent, backend=None):
|
202
202
|
if not isinstance(parent, SinoNormWindow):
|
203
203
|
raise TypeError("Expect a NormIntensityWindow as parrent")
|
204
204
|
qt.QTabWidget.__init__(self, parent)
|
205
|
-
self._projView = _ProjPlotWithROI(parent=self)
|
205
|
+
self._projView = _ProjPlotWithROI(parent=self, backend=backend)
|
206
206
|
self.addTab(self._projView, "projection view")
|
207
|
-
self._sinoView = SinogramViewer(parent=self)
|
207
|
+
self._sinoView = SinogramViewer(parent=self, backend=backend)
|
208
208
|
self.addTab(self._sinoView, "sinogram view")
|
209
209
|
|
210
210
|
# connect signal / Slot
|
@@ -550,6 +550,7 @@ class _EstimatedCorWidget(qt.QGroupBox):
|
|
550
550
|
self._relLabel.setVisible(manual_opt_visible)
|
551
551
|
self._manualCORRel.setVisible(manual_opt_visible)
|
552
552
|
self._manualCORAbs.setVisible(manual_opt_visible)
|
553
|
+
self._autoCorPB.setVisible(manual_opt_visible)
|
553
554
|
|
554
555
|
def _relativePositionChanged(self, *args, **kwargs):
|
555
556
|
if self._frameWidth is not None:
|
@@ -43,7 +43,7 @@ from silx.gui import qt
|
|
43
43
|
from tomwer.core.process.reconstruction.axis import mode as axis_mode
|
44
44
|
from tomwer.core.process.reconstruction.nabu.utils import _NabuMode
|
45
45
|
from tomwer.core.process.reconstruction.saaxis.params import SAAxisParams
|
46
|
-
from tomwer.core.process.reconstruction.saaxis.saaxis import
|
46
|
+
from tomwer.core.process.reconstruction.saaxis.saaxis import SAAxisTask
|
47
47
|
from tomwer.gui import icons
|
48
48
|
from tomwer.gui.reconstruction.axis.radioaxis import _CalculationWidget
|
49
49
|
from tomwer.gui.reconstruction.nabu.slices import NabuWindow
|
@@ -71,7 +71,7 @@ class ScorePlot(_ScorePlot, constructor=CorSelection):
|
|
71
71
|
scan.saaxis_params.score_method = self.getScoreMethod()
|
72
72
|
img_width = scan.dim_1
|
73
73
|
# update autofocus
|
74
|
-
|
74
|
+
SAAxisTask.autofocus(scan)
|
75
75
|
else:
|
76
76
|
img_width = None
|
77
77
|
self.setVarScores(
|
@@ -145,7 +145,7 @@ class _SAAxisTabWidget(qt.QTabWidget):
|
|
145
145
|
like slice to reconstruct, number of reconstruction, research width,
|
146
146
|
nabu reconstruction parameters..."""
|
147
147
|
|
148
|
-
def __init__(self, parent):
|
148
|
+
def __init__(self, parent, backend=None):
|
149
149
|
qt.QTabWidget.__init__(self, parent)
|
150
150
|
# select slice & cor range
|
151
151
|
|
@@ -159,7 +159,7 @@ class _SAAxisTabWidget(qt.QTabWidget):
|
|
159
159
|
nabu_icon = icons.getQIcon("nabu")
|
160
160
|
self.addTab(self._nabuSettings, nabu_icon, "reconstruction settings")
|
161
161
|
# results
|
162
|
-
self._resultsViewer = ScorePlot(self, variable_name="cor")
|
162
|
+
self._resultsViewer = ScorePlot(self, variable_name="cor", backend=backend)
|
163
163
|
results_icon = icons.getQIcon("results")
|
164
164
|
self.addTab(self._resultsViewer, results_icon, "reconstructed slices")
|
165
165
|
|
@@ -312,7 +312,7 @@ class SAAxisWindow(qt.QMainWindow):
|
|
312
312
|
Widget used to determine half-automatically the center of rotation
|
313
313
|
"""
|
314
314
|
|
315
|
-
def __init__(self, parent=None):
|
315
|
+
def __init__(self, parent=None, backend=None):
|
316
316
|
qt.QMainWindow.__init__(self, parent)
|
317
317
|
self._scan = None
|
318
318
|
self._automaticCorWidget = None
|
@@ -324,7 +324,7 @@ class SAAxisWindow(qt.QMainWindow):
|
|
324
324
|
|
325
325
|
self._scanInfo = ScanNameLabelAndShape(self)
|
326
326
|
self._mainWidget.layout().addWidget(self._scanInfo)
|
327
|
-
self._tabWidget = _SAAxisTabWidget(self)
|
327
|
+
self._tabWidget = _SAAxisTabWidget(self, backend=backend)
|
328
328
|
self._mainWidget.layout().addWidget(self._tabWidget)
|
329
329
|
self.setCentralWidget(self._mainWidget)
|
330
330
|
# next and previous buttons for browsing the tab widget
|