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,246 @@
1
+ # coding: utf-8
2
+ # /*##########################################################################
3
+ #
4
+ # Copyright (c) 2015-2016 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
+ """Full tomwer test suite.
26
+
27
+ """
28
+
29
+ __authors__ = ["H.Payno"]
30
+ __license__ = "MIT"
31
+ __date__ = "19/01/2017"
32
+
33
+ import logging
34
+ import os
35
+ import shutil
36
+
37
+ from silx.gui import qt
38
+
39
+ from tomwer.core.scan.edfscan import EDFTomoScan
40
+ from tomwer.tests.datasets import TomwerCIDatasets
41
+
42
+ logger = logging.getLogger(__name__)
43
+
44
+
45
+ class Simulation(qt.QThread):
46
+ """Simulation is a simple class able to simulate an acquisition by copying
47
+ files on a targetted directory.
48
+
49
+ :param str: targetdir the folder where the acquisition is stored
50
+ :param str: manipulationId the id of the simulation we want to simulate
51
+ :param str: finalState when launched, the state to reach before stopping
52
+
53
+ :warning: the targetted directory won't be removed or cleaned during class
54
+ destruction. This is to be managed by callers.
55
+ """
56
+
57
+ advancement = {
58
+ "not started": -1,
59
+ "starting-s0": 0,
60
+ "starting-s1": 1,
61
+ "acquisitionRunning": 2,
62
+ "acquisitionDone": 3,
63
+ "reconstructionLaunched": 4,
64
+ }
65
+ sigAdvancementChanged = qt.Signal(int)
66
+
67
+ __definedDataset = ["test01", "test10"]
68
+
69
+ def __init__(self, targetdir, manipulationId, finalState=4):
70
+ assert type(manipulationId) is str
71
+ assert type(targetdir) is str
72
+ assert manipulationId in self.__definedDataset
73
+ super(Simulation, self).__init__()
74
+
75
+ self.targetdir = targetdir
76
+ self.outputFolder = os.path.sep.join((targetdir, manipulationId))
77
+ self.finalState = finalState
78
+ self.currentState = "not started"
79
+ self._createFinalXML = False
80
+ (
81
+ self.originalFolder,
82
+ self.nbSlices,
83
+ self.manipulationId,
84
+ ) = self.__getOriginalDataSet(manipulationId)
85
+ self.stopFileCreationForRunningState = int(self.nbSlices / 2)
86
+ self.srcPattern = None
87
+ self.destPattern = None
88
+
89
+ def __getOriginalDataSet(self, dataSetID):
90
+ """Return paths to the requested scan"""
91
+ assert dataSetID in self.__definedDataset
92
+ dataDir = TomwerCIDatasets.get_dataset(os.path.join("edf_datasets", dataSetID))
93
+
94
+ assert os.path.isdir(dataDir)
95
+ assert os.path.isfile(os.path.join(dataDir, dataSetID + ".info"))
96
+ slices = EDFTomoScan(dataDir).projections
97
+ nbSlices = len(slices)
98
+ manipulationID = dataSetID
99
+
100
+ return dataDir, nbSlices, manipulationID
101
+
102
+ def advanceTo(self, state):
103
+ """Reset the new advancement targetted
104
+
105
+ :param str state: the new state to reach when run will be executed
106
+ """
107
+ assert state in Simulation.advancement
108
+ assert type(state) is str
109
+ self.finalState = Simulation.advancement[state]
110
+
111
+ def setSrcDestPatterns(self, srcPattern, destPattern):
112
+ """
113
+ If setted, will set the .info and .xml files into a different folder
114
+ """
115
+ self.srcPattern = srcPattern
116
+ self.destPattern = destPattern
117
+ if srcPattern is not None or destPattern is not None:
118
+ assert os.path.isdir(srcPattern)
119
+ assert os.path.isdir(destPattern)
120
+ targettedFolder = self.outputFolder.replace(
121
+ self.srcPattern, self.destPattern, 1
122
+ )
123
+ if not os.path.isdir(targettedFolder):
124
+ os.makedirs(targettedFolder)
125
+
126
+ def __shouldExecStep(self, step):
127
+ """Return True if the thread should exec this step to advance taking
128
+ into consideration is current state and his final state
129
+ """
130
+ return self.finalState >= self.advancement[step] and (
131
+ Simulation.advancement[self.currentState] + 1 == self.advancement[step]
132
+ )
133
+
134
+ def run(self):
135
+ """Main function, run the acquisition through all states until
136
+ finalState is reached
137
+ """
138
+ if self.__shouldExecStep("starting-s0") is True:
139
+ logger.info("starting-s0")
140
+ self._startAcquisition()
141
+ self.currentState = "starting-s0"
142
+ self.signalCurrentState()
143
+
144
+ if self.__shouldExecStep("starting-s1") is True:
145
+ self.copyInitialFiles()
146
+ logger.info("starting-s1")
147
+ self.currentState = "starting-s1"
148
+ self.signalCurrentState()
149
+
150
+ if self.__shouldExecStep("acquisitionRunning") is True:
151
+ self._copyScans((0, self.stopFileCreationForRunningState))
152
+ logger.info("acquisitionRunning")
153
+ self.currentState = "acquisitionRunning"
154
+ self.signalCurrentState()
155
+
156
+ if self.__shouldExecStep("acquisitionDone") is True:
157
+ self._copyScans((self.stopFileCreationForRunningState, self.nbSlices))
158
+ if self._createFinalXML is True:
159
+ inputXMLFile = os.path.join(
160
+ self.originalFolder, self.manipulationId + ".xml"
161
+ )
162
+ assert os.path.isfile(inputXMLFile)
163
+ ouputXMLFile = os.path.join(
164
+ self.outputFolder, self.manipulationId + ".xml"
165
+ )
166
+ shutil.copyfile(inputXMLFile, ouputXMLFile)
167
+
168
+ logger.info("acquisitionDone")
169
+ self.currentState = "acquisitionDone"
170
+ self.signalCurrentState()
171
+
172
+ def signalCurrentState(self):
173
+ """Signal the actual state of the simulation"""
174
+ self.sigAdvancementChanged.emit(self.currentState)
175
+
176
+ def _startAcquisition(self):
177
+ """create needed data dir"""
178
+ for newFolder in (self.targetdir, self.outputFolder):
179
+ if not os.path.exists(self.outputFolder):
180
+ os.makedirs(self.outputFolder)
181
+
182
+ def _copyScans(self, _slicesRange):
183
+ """copy the .edf file from the original directory to the outputFolder
184
+
185
+ :_slicesRange tuple: the _range of slices data we want to copy
186
+ """
187
+ logger.info("copying files from %s to %s" % (_slicesRange[0], _slicesRange[1]))
188
+ for iSlice in list(range(_slicesRange[0], _slicesRange[1])):
189
+ filename = "".join((self.manipulationId, format(iSlice, "04d"), ".edf"))
190
+ srcFile = os.path.join(self.originalFolder, filename)
191
+ outputFile = os.path.join(self.outputFolder, filename)
192
+ assert os.path.isfile(srcFile)
193
+ assert os.path.isdir(self.outputFolder)
194
+ shutil.copyfile(srcFile, outputFile)
195
+
196
+ def copyInitialFiles(self):
197
+ """copy the .info file"""
198
+ assert os.path.isdir(self.originalFolder)
199
+ logger.info(
200
+ "copying initial files (.info, .xml...) from %s to %s"
201
+ % (self.originalFolder, self.manipulationId)
202
+ )
203
+ for extension in (".info", ".db", ".cfg"):
204
+ filename = "".join((self.manipulationId, extension))
205
+ srcFile = os.path.join(self.originalFolder, filename)
206
+
207
+ targettedFolder = self.outputFolder
208
+ if self.srcPattern is not None or self.destPattern is not None:
209
+ targettedFolder = self.outputFolder.replace(
210
+ self.srcPattern, self.destPattern, 1
211
+ )
212
+ assert os.path.isfile(srcFile)
213
+ assert os.path.isdir(targettedFolder)
214
+ assert os.path.isdir(self.originalFolder)
215
+ shutil.copy2(srcFile, targettedFolder)
216
+
217
+ def createFinalXML(self, val):
218
+ """If activated, once all the file will be copied, this will create
219
+ an .xml file into the output directory
220
+ """
221
+ self._createFinalXML = val
222
+
223
+ def createParFile(self):
224
+ pass
225
+
226
+ def createReconstructedFile(self):
227
+ pass
228
+
229
+ def createOARJob(self):
230
+ pass
231
+
232
+ def createDark(self):
233
+ pass
234
+
235
+ def createJPG(self):
236
+ pass
237
+
238
+ def createVolfloat(self):
239
+ pass
240
+
241
+ def createVolraw(self):
242
+ pass
243
+
244
+ def __createFileTo(self, filePath):
245
+ assert type(filePath) is str
246
+ open(filePath, "a").close()
@@ -0,0 +1,87 @@
1
+ # coding: utf-8
2
+ # /*##########################################################################
3
+ #
4
+ # Copyright (c) 2017-2019 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
+ __authors__ = ["H. Payno"]
26
+ __license__ = "MIT"
27
+ __date__ = "10/12/2021"
28
+
29
+
30
+ import asyncio
31
+ import os
32
+ import shutil
33
+ import tempfile
34
+
35
+ import pytest
36
+ from silx.gui import qt
37
+ from silx.gui.utils.testutils import TestCaseQt
38
+
39
+ from orangecontrib.tomwer.widgets.cluster.FutureSupervisorOW import FutureSupervisorOW
40
+ from tomwer.core.futureobject import FutureTomwerObject
41
+ from tomwer.core.utils.scanutils import MockNXtomo
42
+ from tomwer.tests.utils import skip_gui_test
43
+
44
+
45
+ @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
46
+ class TestFutureSupervisorOW(TestCaseQt):
47
+ """Test that the axis widget work correctly"""
48
+
49
+ def setUp(self):
50
+ super().setUp()
51
+ self._window = FutureSupervisorOW()
52
+ self.tempdir = tempfile.mkdtemp()
53
+
54
+ # set up scans
55
+ self._scans = []
56
+ self._future_tomo_objs = []
57
+ for i in range(5):
58
+ # create scan
59
+ scan = MockNXtomo(
60
+ scan_path=os.path.join(self.tempdir, f"scan_test{i}"),
61
+ n_proj=10,
62
+ n_ini_proj=10,
63
+ create_ini_dark=False,
64
+ create_ini_flat=False,
65
+ dim=10,
66
+ ).scan
67
+ self._scans.append(scan)
68
+
69
+ # create future
70
+ future = asyncio.Future()
71
+ if i == 1:
72
+ future.set_result(None)
73
+ self._future_tomo_objs.append(
74
+ FutureTomwerObject(
75
+ tomo_obj=scan,
76
+ futures=(future,),
77
+ )
78
+ )
79
+
80
+ def tearDown(self):
81
+ self._window.setAttribute(qt.Qt.WA_DeleteOnClose)
82
+ self._window.close()
83
+ self._window = None
84
+ shutil.rmtree(self.tempdir)
85
+ self._scans.clear()
86
+ self._future_tomo_objs.clear()
87
+ super().tearDown()
@@ -0,0 +1,67 @@
1
+ # coding: utf-8
2
+ # /*##########################################################################
3
+ #
4
+ # Copyright (c) 2017-2019 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
+ __authors__ = ["H. Payno"]
26
+ __license__ = "MIT"
27
+ __date__ = "10/12/2021"
28
+
29
+
30
+ import gc
31
+ import pickle
32
+
33
+ import pytest
34
+ from orangecanvas.scheme.readwrite import literal_dumps
35
+ from silx.gui import qt
36
+ from silx.gui.utils.testutils import TestCaseQt
37
+
38
+ from orangecontrib.tomwer.widgets.cluster.SlurmClusterOW import SlurmClusterOW
39
+ from tomwer.core.cluster.cluster import SlurmClusterConfiguration
40
+ from tomwer.tests.utils import skip_gui_test
41
+
42
+
43
+ @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
44
+ class TestSlurmClusterOW(TestCaseQt):
45
+ """Test that the axis widget work correctly"""
46
+
47
+ def setUp(self):
48
+ super().setUp()
49
+ self._window = SlurmClusterOW()
50
+
51
+ def tearDown(self):
52
+ self._window.setAttribute(qt.Qt.WA_DeleteOnClose)
53
+ self._window.close()
54
+ self._window = None
55
+ gc.collect()
56
+
57
+ def test(self):
58
+ self._window.show()
59
+ self.qWaitForWindowExposed(self._window)
60
+ configuration = self._window.getConfiguration()
61
+ assert isinstance(configuration, SlurmClusterConfiguration)
62
+
63
+ def test_serializing(self):
64
+ pickle.dumps(self._window.getConfiguration().to_dict())
65
+
66
+ def test_literal_dumps(self):
67
+ literal_dumps(self._window.getConfiguration().to_dict())
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+ # /*##########################################################################
3
+ #
4
+ # Copyright (c) 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__ = "17/06/2021"
29
+
30
+
31
+ import gc
32
+
33
+ from silx.gui import qt
34
+ from silx.gui.utils.testutils import TestCaseQt
35
+
36
+ from orangecontrib.tomwer.widgets.control.AdvancementOW import AdvancementOW
37
+
38
+
39
+ class TestAdvancementOw(TestCaseQt):
40
+ def setUp(self):
41
+ super().setUp()
42
+ self.widget = AdvancementOW()
43
+
44
+ def tearDown(self):
45
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
46
+ self.widget.close()
47
+ self.widget = None
48
+ gc.collect()
49
+
50
+ def test(self):
51
+ self.widget.show()
@@ -0,0 +1,55 @@
1
+ import gc
2
+ import os
3
+ import shutil
4
+ import tempfile
5
+
6
+ from silx.gui import qt
7
+ from silx.gui.utils.testutils import TestCaseQt
8
+
9
+ from orangecontrib.tomwer.widgets.control.DataValidatorOW import DataValidatorOW
10
+ from tomwer.core.utils.scanutils import MockNXtomo
11
+
12
+
13
+ class TestDataValidatorOW(TestCaseQt):
14
+ """
15
+ simple test on the DataValidatorOW widget
16
+ """
17
+
18
+ def setUp(self):
19
+ super().setUp()
20
+ self.window = DataValidatorOW()
21
+ self.folder = tempfile.mkdtemp()
22
+ self.scan_1 = MockNXtomo(
23
+ scan_path=os.path.join(self.folder, "scan_1"),
24
+ n_proj=20,
25
+ n_ini_proj=20,
26
+ dim=10,
27
+ ).scan
28
+ self.scan_2 = MockNXtomo(
29
+ scan_path=os.path.join(self.folder, "scan_2"),
30
+ n_proj=20,
31
+ n_ini_proj=20,
32
+ dim=10,
33
+ ).scan
34
+
35
+ def tearDown(self):
36
+ self.window.setAttribute(qt.Qt.WA_DeleteOnClose)
37
+ self.window.close()
38
+ self.window = None
39
+ shutil.rmtree(self.folder)
40
+ gc.collect()
41
+
42
+ def test(self):
43
+ def wait_processing():
44
+ while self.qapp.hasPendingEvents():
45
+ self.qapp.processEvents()
46
+
47
+ assert self.window.getNScanToValidate() == 0
48
+ self.window.addScan(self.scan_1)
49
+ wait_processing()
50
+ self.window.addScan(self.scan_2)
51
+ wait_processing()
52
+ assert self.window.getNScanToValidate() == 2
53
+ self.window._widget.validateCurrentScan()
54
+ wait_processing()
55
+ assert self.window.getNScanToValidate() == 1
@@ -0,0 +1,131 @@
1
+ __authors__ = ["H. Payno"]
2
+ __license__ = "MIT"
3
+ __date__ = "27/03/2023"
4
+
5
+
6
+ import gc
7
+ import os
8
+ import pickle
9
+ import tempfile
10
+
11
+ from orangecanvas.scheme.readwrite import literal_dumps
12
+ from silx.gui import qt
13
+ from silx.gui.utils.testutils import SignalListener, TestCaseQt
14
+
15
+ from orangecontrib.tomwer.widgets.control.DataDiscoveryOW import DataDiscoveryOW
16
+ from tomwer.core.scan.scantype import ScanType
17
+ from tomwer.core.utils.scanutils import MockBlissAcquisition
18
+ from tomoscan.esrf.scan.mock import MockNXtomo, MockEDF
19
+
20
+
21
+ class TestDataDiscovery(TestCaseQt):
22
+ WAIT_TIME = 5000 # thread processing wait time in ms
23
+
24
+ def setUp(self):
25
+ super().setUp()
26
+ self.widget = DataDiscoveryOW()
27
+ self.widget.setConfiguration(self.default_settings)
28
+ self.signal_listener = SignalListener()
29
+ self.widget.getProcessingThread().sigDataFound.connect(self.signal_listener)
30
+
31
+ def tearDown(self):
32
+ self.widget.getProcessingThread().sigDataFound.disconnect(self.signal_listener)
33
+ self.signal_listener = None
34
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
35
+ self.widget.close()
36
+ self.widget = None
37
+ gc.collect()
38
+
39
+ @property
40
+ def default_settings(self):
41
+ return {
42
+ "start_folder": "/my/folder",
43
+ "file_filter": "*.h5",
44
+ "scan_type_searched": ScanType.NX_TOMO,
45
+ }
46
+
47
+ def testSerialization(self):
48
+ """make sure pickling works for the settings"""
49
+ pickle.dumps(self.widget.getConfiguration())
50
+
51
+ def testLiteralDumps(self):
52
+ """make sure literal dumps (from orangecanvas) works for the settings"""
53
+ literal_dumps(self.widget.getConfiguration())
54
+
55
+ def testProcessingNXtomo(self):
56
+ """Test the widget can find NXtomos"""
57
+ n_scan = 3
58
+ with tempfile.TemporaryDirectory() as root_dir:
59
+ for i_scan in range(n_scan):
60
+ MockNXtomo(
61
+ scan_path=os.path.join(root_dir, f"sub_folder_{i_scan}", "scan"),
62
+ n_proj=10,
63
+ n_ini_proj=10,
64
+ dim=10,
65
+ )
66
+ self.widget.setFolderObserved(root_dir)
67
+ self.widget.start_discovery(wait=self.WAIT_TIME)
68
+ while self.qapp.hasPendingEvents():
69
+ self.qapp.processEvents()
70
+
71
+ assert self.signal_listener.callCount() == n_scan
72
+
73
+ def testProcessingBlissRawScan(self):
74
+ """Test the widget can find bliss raw scans"""
75
+ with tempfile.TemporaryDirectory() as root_dir:
76
+ n_scan = 2
77
+ for i_scan in range(n_scan):
78
+ MockBlissAcquisition(
79
+ n_sample=1,
80
+ n_sequence=1,
81
+ n_scan_per_sequence=1,
82
+ n_darks=1,
83
+ n_flats=1,
84
+ with_nx=True,
85
+ output_dir=os.path.join(root_dir, f"sub_folder_{i_scan}", "scan"),
86
+ )
87
+
88
+ self.widget.setFilePattern("*.edf")
89
+ self.widget.setSearchScanType(ScanType.BLISS)
90
+ self.widget.setFolderObserved(root_dir)
91
+ self.widget.start_discovery(wait=self.WAIT_TIME)
92
+ while self.qapp.hasPendingEvents():
93
+ self.qapp.processEvents()
94
+
95
+ assert (
96
+ self.signal_listener.callCount() == 0
97
+ ) # because of the filtering on files
98
+ self.widget.setFilePattern(None)
99
+ self.widget.start_discovery(wait=self.WAIT_TIME)
100
+ while self.qapp.hasPendingEvents():
101
+ self.qapp.processEvents()
102
+
103
+ assert self.signal_listener.callCount() == n_scan
104
+
105
+ def testProcessingSpecScan(self):
106
+ """Test the widget can find bliss raw scans"""
107
+ with tempfile.TemporaryDirectory() as root_dir:
108
+ n_scan = 4
109
+ for i_scan in range(n_scan):
110
+ MockEDF(
111
+ n_radio=4,
112
+ n_ini_radio=4,
113
+ scan_path=os.path.join(root_dir, f"sub_folder_{i_scan}", "scan"),
114
+ )
115
+
116
+ self.widget.setSearchScanType(ScanType.BLISS)
117
+ self.widget.setFilePattern(None)
118
+ self.widget.setFolderObserved(root_dir)
119
+ self.widget.start_discovery(wait=self.WAIT_TIME)
120
+ while self.qapp.hasPendingEvents():
121
+ self.qapp.processEvents()
122
+
123
+ assert (
124
+ self.signal_listener.callCount() == 0
125
+ ) # because of the scan type searched
126
+ self.widget.setSearchScanType(ScanType.SPEC)
127
+ self.widget.setFilePattern(None)
128
+ self.widget.start_discovery(wait=self.WAIT_TIME)
129
+ while self.qapp.hasPendingEvents():
130
+ self.qapp.processEvents()
131
+ assert self.signal_listener.callCount() == n_scan