tomwer 1.3.6__py3-none-any.whl → 1.3.7__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.
Files changed (107) hide show
  1. orangecontrib/tomwer/test/TestAcquisition.py +246 -0
  2. orangecontrib/tomwer/widgets/cluster/test/test_future_supervisorow.py +87 -0
  3. orangecontrib/tomwer/widgets/cluster/test/test_slurm_clusterow.py +67 -0
  4. orangecontrib/tomwer/widgets/control/test/test_advancement.py +51 -0
  5. orangecontrib/tomwer/widgets/control/test/test_data_validator.py +55 -0
  6. orangecontrib/tomwer/widgets/control/test/test_datadiscovery.py +131 -0
  7. orangecontrib/tomwer/widgets/control/test/test_datalist.py +70 -0
  8. orangecontrib/tomwer/widgets/control/test/test_datalistener.py +137 -0
  9. orangecontrib/tomwer/widgets/control/test/test_dataselector.py +95 -0
  10. orangecontrib/tomwer/widgets/control/test/test_datawatcher.py +436 -0
  11. orangecontrib/tomwer/widgets/control/test/test_emailow.py +29 -0
  12. orangecontrib/tomwer/widgets/control/test/test_notifier.py +51 -0
  13. orangecontrib/tomwer/widgets/control/test/test_nxtomo_concatenate_ow.py +64 -0
  14. orangecontrib/tomwer/widgets/control/test/test_nxtomomill.py +160 -0
  15. orangecontrib/tomwer/widgets/control/test/test_reduce_dark_flat_selector.py +40 -0
  16. orangecontrib/tomwer/widgets/control/test/test_singletomoobj.py +40 -0
  17. orangecontrib/tomwer/widgets/control/test/test_timerow.py +51 -0
  18. orangecontrib/tomwer/widgets/control/test/test_tomoobj_serie.py +96 -0
  19. orangecontrib/tomwer/widgets/control/test/test_volume_selector.py +69 -0
  20. orangecontrib/tomwer/widgets/control/test/test_volumesymlink.py +51 -0
  21. orangecontrib/tomwer/widgets/debugtools/test/test_dataset_generator.py +57 -0
  22. orangecontrib/tomwer/widgets/debugtools/test/test_object_inspector.py +62 -0
  23. orangecontrib/tomwer/widgets/other/test/test_pythonscript.py +31 -0
  24. orangecontrib/tomwer/widgets/reconstruction/test/test_axis.py +224 -0
  25. orangecontrib/tomwer/widgets/reconstruction/test/test_cast_volumeow.py +85 -0
  26. orangecontrib/tomwer/widgets/reconstruction/test/test_dark_refs_widget.py +136 -0
  27. orangecontrib/tomwer/widgets/reconstruction/test/test_delta_beta_selector.py +15 -0
  28. orangecontrib/tomwer/widgets/reconstruction/test/test_i_norm.py +226 -0
  29. orangecontrib/tomwer/widgets/reconstruction/test/test_nabu_helical_prepare_weights_double.py +20 -0
  30. orangecontrib/tomwer/widgets/reconstruction/test/test_nabu_volume.py +100 -0
  31. orangecontrib/tomwer/widgets/reconstruction/test/test_nabu_widget.py +107 -0
  32. orangecontrib/tomwer/widgets/reconstruction/test/test_sa_delta_beta.py +194 -0
  33. orangecontrib/tomwer/widgets/reconstruction/test/test_saaxis.py +220 -0
  34. orangecontrib/tomwer/widgets/stitching/test/test_zstitching.py +308 -0
  35. orangecontrib/tomwer/widgets/test/test_conditions.py +111 -0
  36. orangecontrib/tomwer/widgets/test/test_darkref.py +251 -0
  37. orangecontrib/tomwer/widgets/test/test_foldertransfert.py +131 -0
  38. orangecontrib/tomwer/widgets/visualization/test/test_dataviewerow.py +83 -0
  39. orangecontrib/tomwer/widgets/visualization/test/test_diffviewerow.py +65 -0
  40. orangecontrib/tomwer/widgets/visualization/test/test_live_sliceow.py +63 -0
  41. orangecontrib/tomwer/widgets/visualization/test/test_nxtomo_metadata_viewer.py +29 -0
  42. orangecontrib/tomwer/widgets/visualization/test/test_radio_stackow.py +56 -0
  43. orangecontrib/tomwer/widgets/visualization/test/test_sample_movedow.py +72 -0
  44. orangecontrib/tomwer/widgets/visualization/test/test_sinogram_viewerow.py +56 -0
  45. orangecontrib/tomwer/widgets/visualization/test/test_slice_stackow.py +57 -0
  46. orangecontrib/tomwer/widgets/visualization/test/test_volume_viewerow.py +57 -0
  47. tomwer/core/log/test/test_processlog.py +41 -0
  48. tomwer/core/process/edit/test/test_darkflatpatch.py +269 -0
  49. tomwer/core/process/edit/test/test_imagekey_editor.py +125 -0
  50. tomwer/core/process/icat/test/test_create_screenshots.py +98 -0
  51. tomwer/core/process/icat/test/test_gallery.py +170 -0
  52. tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +143 -0
  53. tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py +203 -0
  54. tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py +222 -0
  55. tomwer/core/process/script/test/test_script.py +68 -0
  56. tomwer/core/process/stitching/test/test_metadataholder.py +17 -0
  57. tomwer/core/process/visualization/test/test_data_viewer.py +39 -0
  58. tomwer/core/process/visualization/test/test_diff_viewer.py +39 -0
  59. tomwer/core/process/visualization/test/test_image_stack_viewer.py +41 -0
  60. tomwer/core/process/visualization/test/test_radio_stack.py +39 -0
  61. tomwer/core/process/visualization/test/test_sample_moved.py +41 -0
  62. tomwer/core/process/visualization/test/test_sinogram_viewer.py +39 -0
  63. tomwer/core/process/visualization/test/test_slice_stack.py +39 -0
  64. tomwer/core/process/visualization/test/test_volume_viewer.py +39 -0
  65. tomwer/core/utils/test/test_image.py +30 -0
  66. tomwer/core/utils/test/test_nxtomo.py +66 -0
  67. tomwer/core/utils/test/test_scan_utils.py +46 -0
  68. tomwer/core/utils/test/test_time.py +6 -0
  69. tomwer/core/volume/test/test_volumes.py +21 -0
  70. tomwer/gui/control/serie/test/test_creator.py +451 -0
  71. tomwer/gui/control/serie/test/test_nxtomo_concatenate.py +21 -0
  72. tomwer/gui/icat/test/test_create_screenshots_gui.py +23 -0
  73. tomwer/gui/icat/test/test_gallery_gui.py +37 -0
  74. tomwer/gui/reconstruction/nabu/test/test_check.py +92 -0
  75. tomwer/gui/reconstruction/nabu/test/test_ctf.py +46 -0
  76. tomwer/gui/reconstruction/nabu/test/test_helical.py +21 -0
  77. tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py +81 -0
  78. tomwer/gui/reconstruction/normalization/test/test_intensity.py +119 -0
  79. tomwer/gui/stitching/config/tests/test_axisparams.py +25 -0
  80. tomwer/gui/stitching/tests/test_axis_ordered_list.py +21 -0
  81. tomwer/gui/stitching/tests/test_normalization.py +27 -0
  82. tomwer/gui/stitching/tests/test_preview.py +85 -0
  83. tomwer/gui/stitching/tests/test_stitching_raw.py +110 -0
  84. tomwer/gui/stitching/tests/test_z_stitching.py +67 -0
  85. tomwer/gui/stitching/tests/utils.py +79 -0
  86. tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py +35 -0
  87. tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +215 -0
  88. tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +51 -0
  89. tomwer/gui/utils/test/test_completer.py +67 -0
  90. tomwer/gui/utils/test/test_line_selector.py +21 -0
  91. tomwer/gui/utils/test/test_splashscreen.py +8 -0
  92. tomwer/gui/utils/test/test_vignettes.py +68 -0
  93. tomwer/io/utils/test/test_raw_and_processed_data.py +10 -0
  94. tomwer/io/utils/test/test_utils.py +92 -0
  95. tomwer/synctools/stacks/reconstruction/castvolume.py +20 -5
  96. tomwer/tests/test_ewoks/test_conversion.py +104 -0
  97. tomwer/tests/test_ewoks/test_single_node_execution.py +112 -0
  98. tomwer/tests/test_ewoks/test_workflows.py +160 -0
  99. tomwer/version.py +1 -1
  100. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/METADATA +1 -1
  101. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/RECORD +107 -10
  102. /tomwer-1.3.6-py3.11-nspkg.pth → /tomwer-1.3.7-py3.11-nspkg.pth +0 -0
  103. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/LICENSE +0 -0
  104. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/WHEEL +0 -0
  105. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/entry_points.txt +0 -0
  106. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/namespace_packages.txt +0 -0
  107. {tomwer-1.3.6.dist-info → tomwer-1.3.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,224 @@
1
+ import gc
2
+ import pickle
3
+ import shutil
4
+ import tempfile
5
+ import time
6
+ import os
7
+
8
+ import pytest
9
+ from orangecanvas.scheme.readwrite import literal_dumps
10
+ from silx.gui import qt
11
+ from silx.gui.utils.testutils import TestCaseQt
12
+
13
+ from orangecontrib.tomwer.widgets.reconstruction.AxisOW import AxisOW
14
+ from tomwer.core.utils.lbsram import mock_low_memory
15
+ from tomwer.core.process.reconstruction.axis.mode import AxisMode
16
+ from tomwer.core.settings import mock_lsbram
17
+ from tomwer.core.utils.scanutils import MockNXtomo, MockEDF
18
+ from tomwer.tests.utils import skip_gui_test
19
+
20
+
21
+ @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
22
+ class TestOWAxis(TestCaseQt):
23
+ """Test that the axis widget work correctly"""
24
+
25
+ def setUp(self):
26
+ self._window = AxisOW()
27
+ self.recons_params = self._window.recons_params
28
+ self.tempdir = tempfile.mkdtemp()
29
+ self.scan = MockNXtomo(
30
+ scan_path=os.path.join(self.tempdir, "nx_tomo.nx"),
31
+ n_proj=10,
32
+ n_ini_proj=10,
33
+ scan_range=180,
34
+ dim=20,
35
+ energy=12.3,
36
+ ).scan
37
+
38
+ self._window.getAxis().mode = AxisMode.centered
39
+ self._window.show()
40
+ self.qWaitForWindowExposed(self._window)
41
+
42
+ def tearDown(self):
43
+ shutil.rmtree(self.tempdir)
44
+ self._window.setAttribute(qt.Qt.WA_DeleteOnClose)
45
+ self._window.close()
46
+ gc.collect()
47
+
48
+ def testAxisLock(self):
49
+ """Test behavior when locking the axis position. Could not be included
50
+ in the tomwer/gui because the lock action is only available for the OW
51
+ """
52
+ assert self._window.getAxis().mode in (AxisMode.centered, AxisMode.global_)
53
+ radio_axis = self._window._widget._axisWidget._radioAxis
54
+ main_widget = self._window._widget._axisWidget
55
+ self.assertFalse(main_widget._controlWidget._lockBut.isLocked())
56
+ self.assertTrue(radio_axis._controlWidget._mainWidget.isEnabled())
57
+ self.mouseClick(main_widget._controlWidget._lockBut, qt.Qt.LeftButton)
58
+ self.qapp.processEvents()
59
+ self.assertTrue(main_widget._controlWidget._lockBut.isLocked())
60
+ # when the lock button is activated we should automatically switch to
61
+ # the manual mode
62
+ self.assertTrue(self._window.getAxis().mode is AxisMode.manual)
63
+ self.assertFalse(radio_axis._controlWidget._mainWidget.isEnabled())
64
+
65
+ def test_serializing(self):
66
+ pickle.dumps(self._window.recons_params.to_dict())
67
+
68
+ def test_literal_dumps(self):
69
+ literal_dumps(self._window.recons_params.to_dict())
70
+
71
+
72
+ class TestWindowAxisComputation(TestCaseQt):
73
+ @staticmethod
74
+ def _long_computation(scan):
75
+ time.sleep(5)
76
+ return -1
77
+
78
+ """Test that the axis widget work correctly"""
79
+
80
+ def setUp(self):
81
+ TestCaseQt.setUp(self)
82
+ self.tempdir = tempfile.mkdtemp()
83
+ self._mainWindow = AxisOW()
84
+ self.recons_params = self._mainWindow.recons_params
85
+ self._window = self._mainWindow._widget
86
+ self.scan = MockNXtomo(
87
+ scan_path=os.path.join(self.tempdir, "nx_tomo.nx"),
88
+ n_proj=10,
89
+ n_ini_proj=10,
90
+ scan_range=180,
91
+ dim=20,
92
+ energy=12.3,
93
+ ).scan
94
+ self._mainWindow.show()
95
+ self.qWaitForWindowExposed(self._mainWindow)
96
+ self._mainWindow.setMode("manual")
97
+
98
+ def tearDown(self):
99
+ shutil.rmtree(self.tempdir)
100
+ self._mainWindow.setAttribute(qt.Qt.WA_DeleteOnClose)
101
+ self._mainWindow.close()
102
+ self._mainWindow = None
103
+ self._window = None
104
+ gc.collect()
105
+
106
+ def testFailedComputation(self):
107
+ """Test gui if the axis position fails"""
108
+ self.qapp.processEvents()
109
+ self.recons_params.set_position_frm_par_file("not existing", force=True)
110
+ radio_axis = self._window._axisWidget._radioAxis
111
+ radio_axis.setMode("read")
112
+ self.assertEqual(radio_axis.getMode(), AxisMode.read)
113
+ self._mainWindow.process(self.scan)
114
+ self.assertEqual(radio_axis.getMode(), AxisMode.read)
115
+ self.assertEqual(self.recons_params.value_ref_tomwer, None)
116
+ self.assertEqual(self.recons_params.mode, AxisMode.read)
117
+
118
+ def testComputationSucceed(self):
119
+ """Test gui if the axis position is correctly computed"""
120
+ self.recons_params.mode = AxisMode.manual
121
+ radio_axis = self._window._axisWidget._radioAxis
122
+ self.assertEqual(radio_axis.getMode(), AxisMode.manual)
123
+ radio_axis.setXShift(2.345)
124
+ self._mainWindow.process(self.scan)
125
+ self.qapp.processEvents()
126
+ self.assertEqual(radio_axis.getMode(), AxisMode.manual)
127
+ self.assertEqual(self.recons_params.value_ref_tomwer, 2.345)
128
+ position_info_widget = self._window._axisWidget._controlWidget._positionInfo
129
+ self.assertEqual(position_info_widget._relativePositionQLE.text(), "2.345")
130
+
131
+
132
+ global _computation_res
133
+ _computation_res = 0
134
+
135
+
136
+ @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
137
+ class TestAxisStack(TestCaseQt):
138
+ """Test axis computation of a stack of scan"""
139
+
140
+ @staticmethod
141
+ def _test_computation(scan):
142
+ global _computation_res
143
+ _computation_res += 1
144
+ return _computation_res
145
+
146
+ def setUp(self):
147
+ # not working due to OW
148
+ TestCaseQt.setUp(self)
149
+ self._scan1 = MockEDF.mockScan(scanID=tempfile.mkdtemp())
150
+ self._scan2 = MockEDF.mockScan(scanID=tempfile.mkdtemp())
151
+ self._scan3 = MockEDF.mockScan(scanID=tempfile.mkdtemp())
152
+ self._mainWindow = AxisOW()
153
+ self.recons_params = self._mainWindow._axis_params
154
+ self._mainWindow._skip_exec(True)
155
+
156
+ global _computation_res
157
+ _computation_res = 0
158
+
159
+ self._mainWindow.patch_calc_method(
160
+ AxisMode.centered, TestAxisStack._test_computation
161
+ )
162
+ self.recons_params.mode = AxisMode.centered
163
+
164
+ self._mainWindow.show()
165
+ self.qWaitForWindowExposed(self._mainWindow)
166
+
167
+ def tearDown(self):
168
+ mock_low_memory(False)
169
+ mock_lsbram(False)
170
+ self._mainWindow.setAttribute(qt.Qt.WA_DeleteOnClose)
171
+ self._mainWindow.close()
172
+ self._mainWindow = None
173
+ self._recons_params = None
174
+ self.qapp.processEvents()
175
+ for scan in (self._scan1, self._scan2, self._scan3):
176
+ shutil.rmtree(scan.path)
177
+ gc.collect()
178
+
179
+ def testLowMemory(self):
180
+ """Make sure the axis computation will be skip if we are in low memory"""
181
+ mock_low_memory(True)
182
+ mock_lsbram(True)
183
+ for scan in (self._scan1, self._scan2, self._scan3):
184
+ self.qapp.processEvents()
185
+ self._mainWindow.new_data_in(scan)
186
+
187
+ self.assertEqual(self._scan1.axis_params, None)
188
+ self.assertEqual(self._scan2.axis_params, None)
189
+ self.assertEqual(self._scan3.axis_params, None)
190
+
191
+ def testUnlockStack(self):
192
+ """Check that all axis position will be computed properly if we set a
193
+ stack of scan"""
194
+ self._mainWindow.recons_params.set_relative_value(1.0)
195
+ for scan in (self._scan1, self._scan2, self._scan3):
196
+ self._mainWindow.process(scan)
197
+
198
+ for i in range(5):
199
+ self.qapp.processEvents()
200
+ time.sleep(0.2)
201
+ self.qapp.processEvents()
202
+
203
+ self.assertNotEqual(self._scan1.axis_params, None)
204
+ self.assertNotEqual(self._scan2.axis_params, None)
205
+ self.assertNotEqual(self._scan3.axis_params, None)
206
+
207
+ def testLockStack(self):
208
+ """Check that axis position will be simply copy if we are in a lock
209
+ stack"""
210
+ self.recons_params.mode = AxisMode.manual
211
+ position_value = 0.36
212
+ self.recons_params.set_relative_value(position_value)
213
+
214
+ for scan in (self._scan1, self._scan2, self._scan3):
215
+ self._mainWindow.process(scan)
216
+
217
+ for i in range(5):
218
+ self.qapp.processEvents()
219
+ time.sleep(0.2)
220
+ self.qapp.processEvents()
221
+
222
+ self.assertEqual(self._scan1.axis_params.value_ref_tomwer, position_value)
223
+ self.assertEqual(self._scan2.axis_params.value_ref_tomwer, position_value)
224
+ self.assertEqual(self._scan3.axis_params.value_ref_tomwer, position_value)
@@ -0,0 +1,85 @@
1
+ # coding: utf-8
2
+ # /*##########################################################################
3
+ #
4
+ # Copyright (c) 2017-2021 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__ = ["H. Payno"]
27
+ __license__ = "MIT"
28
+ __date__ = "16/12/2021"
29
+
30
+
31
+ import gc
32
+ import os
33
+ import pickle
34
+ import tempfile
35
+ import time
36
+
37
+ import numpy
38
+ from orangecanvas.scheme.readwrite import literal_dumps
39
+ from silx.gui import qt
40
+ from silx.gui.utils.testutils import TestCaseQt
41
+
42
+ from orangecontrib.tomwer.widgets.reconstruction.CastNabuVolumeOW import (
43
+ CastNabuVolumeOW,
44
+ )
45
+ from tomwer.core.volume.rawvolume import RawVolume
46
+
47
+
48
+ class TestCastVolumeOW(TestCaseQt):
49
+ def setUp(self):
50
+ super().setUp()
51
+ self._window = CastNabuVolumeOW()
52
+
53
+ def tearDown(self):
54
+ self._window.setAttribute(qt.Qt.WA_DeleteOnClose)
55
+ self._window.close()
56
+ self._window = None
57
+ gc.collect()
58
+
59
+ def test(self):
60
+ self._window.show()
61
+ self.qWaitForWindowExposed(self._window)
62
+
63
+ def test_serializing(self):
64
+ pickle.dumps(self._window.getConfiguration())
65
+
66
+ def test_literal_dumps(self):
67
+ literal_dumps(self._window.getConfiguration())
68
+
69
+ def test_cast_volume(self):
70
+ with tempfile.TemporaryDirectory() as tmp_dir:
71
+ input_dir = os.path.join(tmp_dir, "input")
72
+ os.makedirs(input_dir)
73
+
74
+ volume = RawVolume(
75
+ file_path=os.path.join(input_dir, "vol_file.vol"),
76
+ data=numpy.linspace(0, 10, 100 * 100 * 3, dtype=numpy.float32).reshape(
77
+ 3, 100, 100
78
+ ),
79
+ )
80
+ volume.save()
81
+
82
+ self._window.process_volume(volume)
83
+ while self._window._processingStack.is_computing():
84
+ time.sleep(0.1)
85
+ self.qapp.processEvents()
@@ -0,0 +1,136 @@
1
+ import gc
2
+ import logging
3
+ import os
4
+ import pickle
5
+ import tempfile
6
+
7
+ import numpy
8
+ from orangecanvas.scheme.readwrite import literal_dumps
9
+ from silx.gui import qt
10
+ from silx.gui.utils.testutils import TestCaseQt
11
+
12
+ from orangecontrib.tomwer.widgets.reconstruction.DarkRefAndCopyOW import (
13
+ DarkRefAndCopyOW,
14
+ )
15
+ from tomwer.core.utils.scanutils import MockNXtomo
16
+
17
+ logging.disable(logging.INFO)
18
+
19
+
20
+ class TestDarkRefWidget(TestCaseQt):
21
+ """class testing the DarkRefWidget"""
22
+
23
+ def setUp(self):
24
+ self._tmp_path = tempfile.mkdtemp()
25
+ scan_folder_with_raw = os.path.join(self._tmp_path, "test_dir_1")
26
+ scan_folder_without_raw = os.path.join(self._tmp_path, "test_dir_2")
27
+ for my_dir in (scan_folder_with_raw, scan_folder_without_raw):
28
+ os.makedirs(my_dir)
29
+
30
+ self._scan_with_raw = MockNXtomo(
31
+ scan_path=scan_folder_with_raw,
32
+ create_ini_dark=True,
33
+ create_ini_flat=True,
34
+ create_final_flat=False,
35
+ n_proj=10,
36
+ n_ini_proj=10,
37
+ dim=12,
38
+ ).scan
39
+ self._scan_without_raw = MockNXtomo(
40
+ scan_path=scan_folder_without_raw,
41
+ create_ini_dark=False,
42
+ create_ini_flat=False,
43
+ create_final_flat=False,
44
+ n_proj=10,
45
+ n_ini_proj=10,
46
+ dim=12,
47
+ ).scan
48
+
49
+ self.widget = DarkRefAndCopyOW()
50
+ return super().setUp()
51
+
52
+ def tearDown(self):
53
+ # shutil.rmtree(self._tmp_path)
54
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
55
+ self.widget.close()
56
+ gc.collect()
57
+
58
+ def test_serializing(self):
59
+ self.widget._updateSettingsVals()
60
+ pickle.dumps(self.widget._ewoks_default_inputs)
61
+
62
+ def test_literal_dumps(self):
63
+ self.widget._updateSettingsVals()
64
+ literal_dumps(self.widget._ewoks_default_inputs)
65
+
66
+ def test_copy(self):
67
+ self.widget.setCopyActive(True)
68
+ while self.qapp.hasPendingEvents():
69
+ self.qapp.processEvents()
70
+ assert len(os.listdir(self.widget._processing_stack._save_dir)) == 0
71
+
72
+ self.widget.process(self._scan_with_raw)
73
+ self.widget._processing_stack.wait_computation_finished()
74
+ while self.qapp.hasPendingEvents():
75
+ self.qapp.processEvents()
76
+ assert self._scan_with_raw.load_reduced_darks() not in (None, {})
77
+ assert self._scan_with_raw.load_reduced_flats() not in (None, {})
78
+ assert len(os.listdir(self.widget._processing_stack._save_dir)) == 1
79
+ assert len(os.listdir(self.widget._processing_stack._save_dir)) == 1
80
+
81
+ self.widget.setCopyActive(False)
82
+ while self.qapp.hasPendingEvents():
83
+ self.qapp.processEvents()
84
+ self.widget.process(self._scan_without_raw)
85
+ self.widget._processing_stack.wait_computation_finished()
86
+ while self.qapp.hasPendingEvents():
87
+ self.qapp.processEvents()
88
+ assert self._scan_without_raw.load_reduced_darks() in (None, {})
89
+ assert self._scan_without_raw.load_reduced_flats() in (None, {})
90
+
91
+ self.widget.setCopyActive(True)
92
+ while self.qapp.hasPendingEvents():
93
+ self.qapp.processEvents()
94
+ self.widget.process(self._scan_without_raw)
95
+ self.widget._processing_stack.wait_computation_finished()
96
+ while self.qapp.hasPendingEvents():
97
+ self.qapp.processEvents()
98
+ assert self._scan_without_raw.load_reduced_darks() not in (None, {})
99
+ assert self._scan_without_raw.load_reduced_flats() not in (None, {})
100
+
101
+ def test_set_darks_and_flats(self):
102
+ """
103
+ Test settings darks and flats.
104
+ """
105
+ self.widget.setCopyActive(True)
106
+
107
+ assert len(os.listdir(self.widget._processing_stack._save_dir)) == 0
108
+ self.widget.setReducedFlats(
109
+ {
110
+ "0.0r": numpy.linspace(12, 12 + 12 * 12, 12 * 12).reshape(12, 12),
111
+ "1.0r": numpy.linspace(24, 24 + 12 * 12, 12 * 12).reshape(12, 12),
112
+ }
113
+ )
114
+ self.widget.setReducedDarks(
115
+ {
116
+ "0.0r": numpy.linspace(0, 12 * 12, 12 * 12).reshape(12, 12),
117
+ }
118
+ )
119
+ self.widget.process(self._scan_without_raw)
120
+ self.widget._processing_stack.wait_computation_finished()
121
+ while self.qapp.hasPendingEvents():
122
+ self.qapp.processEvents()
123
+
124
+ loaded_reduced_darks = self._scan_without_raw.load_reduced_darks()
125
+ assert tuple(loaded_reduced_darks.keys()) == (0,)
126
+ numpy.testing.assert_allclose(
127
+ loaded_reduced_darks[0],
128
+ numpy.linspace(0, 12 * 12, 12 * 12).reshape(12, 12),
129
+ )
130
+
131
+ loaded_reduced_flats = self._scan_without_raw.load_reduced_flats()
132
+ assert tuple(loaded_reduced_flats.keys()) == (0, 9)
133
+ numpy.testing.assert_allclose(
134
+ loaded_reduced_flats[9],
135
+ numpy.linspace(24, 24 + 12 * 12, 12 * 12).reshape(12, 12),
136
+ )
@@ -0,0 +1,15 @@
1
+ import numpy
2
+
3
+ from orangecontrib.tomwer.widgets.reconstruction.NabuVolumeOW import (
4
+ _DeltaBetaSelectorDialog,
5
+ )
6
+ from tomwer.tests.conftest import qtapp # noqa F401
7
+
8
+
9
+ def test_DeltaBetaSelector(
10
+ qtapp, # noqa F811
11
+ ):
12
+ """simple test of the _DeltaBetaSelectorDialog"""
13
+ dialog = _DeltaBetaSelectorDialog(values=(12, 45))
14
+ dialog.show()
15
+ assert numpy.isscalar(dialog.getSelectedValue())
@@ -0,0 +1,226 @@
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__ = ["H. Payno"]
27
+ __license__ = "MIT"
28
+ __date__ = "09/06/2021"
29
+
30
+ import gc
31
+ import logging
32
+ import os
33
+ import pickle
34
+ import shutil
35
+ import tempfile
36
+
37
+ from orangecanvas.scheme.readwrite import literal_dumps
38
+ from processview.core.manager import DatasetState, ProcessManager
39
+ from silx.gui import qt
40
+ from silx.gui.utils.testutils import TestCaseQt
41
+ from silx.io.utils import h5py_read_dataset
42
+
43
+ from orangecontrib.tomwer.widgets.reconstruction.SinoNormOW import (
44
+ SinoNormOW as _NormIOW,
45
+ )
46
+ from tomwer.core import settings
47
+ from tomwer.core.utils.lbsram import mock_low_memory
48
+ from tomwer.core.process.reconstruction.normalization import SinoNormalizationTask
49
+ from tomwer.core.utils.scanutils import MockNXtomo
50
+ from tomwer.io.utils.h5pyutils import EntryReader
51
+
52
+ logger = logging.getLogger(__name__)
53
+
54
+
55
+ class NormIOW(_NormIOW):
56
+ def __init__(self, parent=None):
57
+ self._scans_finished = []
58
+ super().__init__(parent)
59
+
60
+ def processing_finished(self, scan):
61
+ self._scans_finished.append(scan)
62
+
63
+ def wait_processing(self, wait_time):
64
+ self._window._processing_stack._computationThread.wait(wait_time)
65
+
66
+ @property
67
+ def scans_finished(self):
68
+ return self._scans_finished
69
+
70
+ def compute(self):
71
+ self._window._processCurrentScan()
72
+
73
+ def setROI(self, start_x, end_x, start_y, end_y):
74
+ self._window.setROI(start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y)
75
+
76
+ def close(self):
77
+ self._scans_finished = {}
78
+ super().close()
79
+
80
+
81
+ class TestProcessing(TestCaseQt):
82
+ DIM = 100
83
+
84
+ def setUp(self):
85
+ super().setUp()
86
+ self._source_dir = tempfile.mkdtemp()
87
+
88
+ def create_scan(folder_name):
89
+ _dir = os.path.join(self._source_dir, folder_name)
90
+ return MockNXtomo(
91
+ scan_path=_dir,
92
+ n_ini_proj=20,
93
+ n_proj=20,
94
+ n_alignement_proj=2,
95
+ create_final_flat=False,
96
+ create_ini_dark=True,
97
+ create_ini_flat=True,
98
+ n_refs=1,
99
+ dim=self.DIM,
100
+ ).scan
101
+
102
+ # create scans
103
+ self.scan_1 = create_scan("scan_1")
104
+ self.scan_2 = create_scan("scan_2")
105
+ self.scan_3 = create_scan("scan_3")
106
+ self._process_manager = ProcessManager()
107
+
108
+ self.widget = NormIOW()
109
+ self.widget.show()
110
+
111
+ def tearDown(self):
112
+ mock_low_memory(False)
113
+ settings.mock_lsbram(False)
114
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
115
+ self.widget.close()
116
+ self.widget = None
117
+ self.qapp.processEvents()
118
+ shutil.rmtree(self._source_dir)
119
+ gc.collect()
120
+
121
+ def test_serializing(self):
122
+ pickle.dumps(self.widget.getConfiguration())
123
+
124
+ def test_literal_dumps(self):
125
+ self.widget._updateSettings()
126
+ literal_dumps(self.widget._ewoks_default_inputs)
127
+
128
+ def testUnlocked(self):
129
+ """Test result when used with some interaction"""
130
+ self.widget.setLocked(False)
131
+
132
+ def process_scalar_manually():
133
+ self.widget.setCurrentMethod("division")
134
+ self.widget.setCurrentSource("manual ROI")
135
+
136
+ self.qapp.processEvents()
137
+ self.widget.setROI(start_x=0, end_x=10, start_y=0, end_y=10)
138
+ self.qapp.processEvents()
139
+ self.widget.compute()
140
+ self.widget.wait_processing(5000)
141
+ self.qapp.processEvents()
142
+
143
+ self.widget.process(self.scan_1)
144
+ process_scalar_manually()
145
+ self.assertEqual(
146
+ self._process_manager.get_dataset_state(
147
+ dataset_id=self.scan_1.get_identifier(),
148
+ process=self.widget,
149
+ ),
150
+ DatasetState.WAIT_USER_VALIDATION,
151
+ )
152
+
153
+ self.widget.process(self.scan_2)
154
+ process_scalar_manually()
155
+ self.assertEqual(len(self.widget.scans_finished), 0)
156
+ self.assertEqual(
157
+ self._process_manager.get_dataset_state(
158
+ dataset_id=self.scan_1.get_identifier(),
159
+ process=self.widget,
160
+ ),
161
+ DatasetState.SKIPPED,
162
+ )
163
+ self.assertEqual(
164
+ self._process_manager.get_dataset_state(
165
+ dataset_id=self.scan_2.get_identifier(),
166
+ process=self.widget,
167
+ ),
168
+ DatasetState.WAIT_USER_VALIDATION,
169
+ )
170
+
171
+ self.widget.process(self.scan_3)
172
+ process_scalar_manually()
173
+ self.widget.validateCurrentScan()
174
+ self.assertEqual(
175
+ self._process_manager.get_dataset_state(
176
+ dataset_id=self.scan_3.get_identifier(),
177
+ process=self.widget,
178
+ ),
179
+ DatasetState.SUCCEED,
180
+ )
181
+
182
+ def testTestLbsram(self):
183
+ """Test scan are all validated if 'low memory on lbsram' scenario is
184
+ activated"""
185
+ mock_low_memory(True)
186
+ settings.mock_lsbram(True)
187
+ for scan in (self.scan_1, self.scan_2, self.scan_3):
188
+ self.widget.process(scan)
189
+ self.widget.wait_processing(5000)
190
+ self.qapp.processEvents()
191
+
192
+ for scan in (self.scan_1, self.scan_2, self.scan_3):
193
+ with self.subTest(scan=str(scan)):
194
+ self.assertEqual(
195
+ self._process_manager.get_dataset_state(
196
+ dataset_id=scan.get_identifier(),
197
+ process=self.widget,
198
+ ),
199
+ DatasetState.SKIPPED,
200
+ )
201
+
202
+ def testLocked(self):
203
+ """Test scan are all validated if the widget is lock"""
204
+ self.widget.setLocked(True)
205
+ for scan in (self.scan_1, self.scan_2, self.scan_3):
206
+ self.widget.process(scan)
207
+ self.widget.wait_processing(5000)
208
+ self.qapp.processEvents()
209
+
210
+ for scan in (self.scan_1, self.scan_2, self.scan_3):
211
+ # test status is SUCCEED
212
+ with self.subTest(scan=str(scan)):
213
+ self.assertEqual(
214
+ self._process_manager.get_dataset_state(
215
+ dataset_id=scan.get_identifier(),
216
+ process=self.widget,
217
+ ),
218
+ DatasetState.SUCCEED,
219
+ )
220
+ # test process file has been updated
221
+ with EntryReader(scan.process_file_url) as entry:
222
+ self.assertTrue("tomwer_process_0" in entry)
223
+ self.assertEqual(
224
+ h5py_read_dataset(entry["tomwer_process_0"]["program"]),
225
+ SinoNormalizationTask.program_name(),
226
+ )