tomwer 1.3.5__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.
- orangecontrib/tomwer/test/TestAcquisition.py +246 -0
- orangecontrib/tomwer/widgets/cluster/test/test_future_supervisorow.py +87 -0
- orangecontrib/tomwer/widgets/cluster/test/test_slurm_clusterow.py +67 -0
- orangecontrib/tomwer/widgets/control/test/test_advancement.py +51 -0
- orangecontrib/tomwer/widgets/control/test/test_data_validator.py +55 -0
- orangecontrib/tomwer/widgets/control/test/test_datadiscovery.py +131 -0
- orangecontrib/tomwer/widgets/control/test/test_datalist.py +70 -0
- orangecontrib/tomwer/widgets/control/test/test_datalistener.py +137 -0
- orangecontrib/tomwer/widgets/control/test/test_dataselector.py +95 -0
- orangecontrib/tomwer/widgets/control/test/test_datawatcher.py +436 -0
- orangecontrib/tomwer/widgets/control/test/test_emailow.py +29 -0
- orangecontrib/tomwer/widgets/control/test/test_notifier.py +51 -0
- orangecontrib/tomwer/widgets/control/test/test_nxtomo_concatenate_ow.py +64 -0
- orangecontrib/tomwer/widgets/control/test/test_nxtomomill.py +160 -0
- orangecontrib/tomwer/widgets/control/test/test_reduce_dark_flat_selector.py +40 -0
- orangecontrib/tomwer/widgets/control/test/test_singletomoobj.py +40 -0
- orangecontrib/tomwer/widgets/control/test/test_timerow.py +51 -0
- orangecontrib/tomwer/widgets/control/test/test_tomoobj_serie.py +96 -0
- orangecontrib/tomwer/widgets/control/test/test_volume_selector.py +69 -0
- orangecontrib/tomwer/widgets/control/test/test_volumesymlink.py +51 -0
- orangecontrib/tomwer/widgets/debugtools/test/test_dataset_generator.py +57 -0
- orangecontrib/tomwer/widgets/debugtools/test/test_object_inspector.py +62 -0
- orangecontrib/tomwer/widgets/other/test/test_pythonscript.py +31 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_axis.py +224 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_cast_volumeow.py +85 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_dark_refs_widget.py +136 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_delta_beta_selector.py +15 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_i_norm.py +226 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_nabu_helical_prepare_weights_double.py +20 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_nabu_volume.py +100 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_nabu_widget.py +107 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_sa_delta_beta.py +194 -0
- orangecontrib/tomwer/widgets/reconstruction/test/test_saaxis.py +220 -0
- orangecontrib/tomwer/widgets/stitching/test/test_zstitching.py +308 -0
- orangecontrib/tomwer/widgets/test/test_conditions.py +111 -0
- orangecontrib/tomwer/widgets/test/test_darkref.py +251 -0
- orangecontrib/tomwer/widgets/test/test_foldertransfert.py +131 -0
- orangecontrib/tomwer/widgets/visualization/test/test_dataviewerow.py +83 -0
- orangecontrib/tomwer/widgets/visualization/test/test_diffviewerow.py +65 -0
- orangecontrib/tomwer/widgets/visualization/test/test_live_sliceow.py +63 -0
- orangecontrib/tomwer/widgets/visualization/test/test_nxtomo_metadata_viewer.py +29 -0
- orangecontrib/tomwer/widgets/visualization/test/test_radio_stackow.py +56 -0
- orangecontrib/tomwer/widgets/visualization/test/test_sample_movedow.py +72 -0
- orangecontrib/tomwer/widgets/visualization/test/test_sinogram_viewerow.py +56 -0
- orangecontrib/tomwer/widgets/visualization/test/test_slice_stackow.py +57 -0
- orangecontrib/tomwer/widgets/visualization/test/test_volume_viewerow.py +57 -0
- tomwer/core/log/test/test_processlog.py +41 -0
- tomwer/core/process/control/datalistener/datalistener.py +11 -11
- tomwer/core/process/edit/test/test_darkflatpatch.py +269 -0
- tomwer/core/process/edit/test/test_imagekey_editor.py +125 -0
- tomwer/core/process/icat/test/test_create_screenshots.py +98 -0
- tomwer/core/process/icat/test/test_gallery.py +170 -0
- tomwer/core/process/reconstruction/axis/axis.py +3 -3
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +3 -2
- tomwer/core/process/reconstruction/nabu/nabucommon.py +3 -4
- tomwer/core/process/reconstruction/nabu/nabuslices.py +4 -4
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +2 -5
- tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +143 -0
- tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py +203 -0
- tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py +222 -0
- tomwer/core/process/script/test/test_script.py +68 -0
- tomwer/core/process/stitching/test/test_metadataholder.py +17 -0
- tomwer/core/process/task.py +3 -2
- tomwer/core/process/test/test_data_transfer.py +4 -3
- tomwer/core/process/visualization/test/test_data_viewer.py +39 -0
- tomwer/core/process/visualization/test/test_diff_viewer.py +39 -0
- tomwer/core/process/visualization/test/test_image_stack_viewer.py +41 -0
- tomwer/core/process/visualization/test/test_radio_stack.py +39 -0
- tomwer/core/process/visualization/test/test_sample_moved.py +41 -0
- tomwer/core/process/visualization/test/test_sinogram_viewer.py +39 -0
- tomwer/core/process/visualization/test/test_slice_stack.py +39 -0
- tomwer/core/process/visualization/test/test_volume_viewer.py +39 -0
- tomwer/core/scan/blissscan.py +3 -3
- tomwer/core/scan/nxtomoscan.py +2 -2
- tomwer/core/scan/scanbase.py +5 -6
- tomwer/core/utils/test/test_image.py +30 -0
- tomwer/core/utils/test/test_nxtomo.py +66 -0
- tomwer/core/utils/test/test_scan_utils.py +46 -0
- tomwer/core/utils/test/test_time.py +6 -0
- tomwer/core/volume/test/test_volumes.py +21 -0
- tomwer/gui/control/reducedarkflatselector.py +2 -2
- tomwer/gui/control/serie/test/test_creator.py +451 -0
- tomwer/gui/control/serie/test/test_nxtomo_concatenate.py +21 -0
- tomwer/gui/edit/dkrfpatch.py +4 -4
- tomwer/gui/edit/nxtomowarmer.py +3 -2
- tomwer/gui/icat/test/test_create_screenshots_gui.py +23 -0
- tomwer/gui/icat/test/test_gallery_gui.py +37 -0
- tomwer/gui/imagefromfile.py +2 -2
- tomwer/gui/reconstruction/nabu/test/test_check.py +92 -0
- tomwer/gui/reconstruction/nabu/test/test_ctf.py +46 -0
- tomwer/gui/reconstruction/nabu/test/test_helical.py +21 -0
- tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py +81 -0
- tomwer/gui/reconstruction/normalization/test/test_intensity.py +119 -0
- tomwer/gui/stitching/config/tests/test_axisparams.py +25 -0
- tomwer/gui/stitching/tests/test_axis_ordered_list.py +21 -0
- tomwer/gui/stitching/tests/test_normalization.py +27 -0
- tomwer/gui/stitching/tests/test_preview.py +85 -0
- tomwer/gui/stitching/tests/test_stitching_raw.py +110 -0
- tomwer/gui/stitching/tests/test_z_stitching.py +67 -0
- tomwer/gui/stitching/tests/utils.py +79 -0
- tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py +35 -0
- tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +215 -0
- tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +51 -0
- tomwer/gui/utils/test/test_completer.py +67 -0
- tomwer/gui/utils/test/test_line_selector.py +21 -0
- tomwer/gui/utils/test/test_splashscreen.py +8 -0
- tomwer/gui/utils/test/test_vignettes.py +68 -0
- tomwer/io/utils/h5pyutils.py +3 -7
- tomwer/io/utils/test/test_raw_and_processed_data.py +10 -0
- tomwer/io/utils/test/test_utils.py +92 -0
- tomwer/io/utils/utils.py +3 -3
- tomwer/synctools/stacks/reconstruction/castvolume.py +20 -5
- tomwer/tests/test_ewoks/test_conversion.py +104 -0
- tomwer/tests/test_ewoks/test_single_node_execution.py +112 -0
- tomwer/tests/test_ewoks/test_workflows.py +160 -0
- tomwer/version.py +1 -1
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/METADATA +1 -1
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/RECORD +124 -27
- /tomwer-1.3.5-py3.11-nspkg.pth → /tomwer-1.3.7-py3.11-nspkg.pth +0 -0
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/LICENSE +0 -0
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/WHEEL +0 -0
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/entry_points.txt +0 -0
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,41 @@
|
|
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__ = "18/03/2022"
|
29
|
+
|
30
|
+
|
31
|
+
from tomwer.core.log.logger import TomwerLogger
|
32
|
+
|
33
|
+
|
34
|
+
def test_process_log():
|
35
|
+
logger = TomwerLogger("tomtom")
|
36
|
+
logger.processStarted("process started")
|
37
|
+
logger.processEnded("process ended")
|
38
|
+
logger.processSkipped("process skipped")
|
39
|
+
logger.inform("information")
|
40
|
+
logger.processSucceed("process succeed")
|
41
|
+
logger.processFailed("process failed")
|
@@ -37,7 +37,7 @@ import typing
|
|
37
37
|
from ewokscore.task import Task as EwoksTask
|
38
38
|
from nxtomomill import converter as nxtomomill_converter
|
39
39
|
from silx.io.utils import h5py_read_dataset
|
40
|
-
from
|
40
|
+
from silx.io.utils import open as open_hdf5
|
41
41
|
|
42
42
|
import tomwer.version
|
43
43
|
from tomwer.core import settings
|
@@ -229,7 +229,7 @@ class DataListener(BaseProcessInfo):
|
|
229
229
|
"""Return the list of scans dir for this bliss_file / entry"""
|
230
230
|
|
231
231
|
def get_scan_indexes():
|
232
|
-
with
|
232
|
+
with open_hdf5(bliss_file) as h5f:
|
233
233
|
entry_node = h5f[entry]
|
234
234
|
if _SCAN_NUMBER_PATH in entry_node:
|
235
235
|
return h5py_read_dataset(entry_node[_SCAN_NUMBER_PATH])
|
@@ -254,7 +254,7 @@ class DataListener(BaseProcessInfo):
|
|
254
254
|
"""Return the proposal file of the experimentation if registred by the
|
255
255
|
data listener"""
|
256
256
|
if entry is None:
|
257
|
-
with
|
257
|
+
with open_hdf5(process_file) as h5f:
|
258
258
|
entries = BaseProcessInfo._get_process_nodes(
|
259
259
|
root_node=h5f, process=DataListener
|
260
260
|
)
|
@@ -269,7 +269,7 @@ class DataListener(BaseProcessInfo):
|
|
269
269
|
entry = list(entries.keys())[0]
|
270
270
|
_logger.info("take %s as default entry" % entry)
|
271
271
|
|
272
|
-
with
|
272
|
+
with open_hdf5(process_file) as h5f:
|
273
273
|
dl_nodes = BaseProcessInfo._get_process_nodes(
|
274
274
|
root_node=h5f[entry], process=DataListener
|
275
275
|
)
|
@@ -311,7 +311,7 @@ class DataListener(BaseProcessInfo):
|
|
311
311
|
"""Return the proposal file of the experimentation if registred by the
|
312
312
|
data listener"""
|
313
313
|
if entry is None:
|
314
|
-
with
|
314
|
+
with open_hdf5(process_file) as h5f:
|
315
315
|
entries = BaseProcessInfo._get_process_nodes(
|
316
316
|
root_node=h5f, process=DataListener
|
317
317
|
)
|
@@ -326,7 +326,7 @@ class DataListener(BaseProcessInfo):
|
|
326
326
|
entry = list(entries.keys())[0]
|
327
327
|
_logger.info("take %s as default entry" % entry)
|
328
328
|
|
329
|
-
with
|
329
|
+
with open_hdf5(process_file) as h5f:
|
330
330
|
dl_nodes = BaseProcessInfo._get_process_nodes(
|
331
331
|
root_node=h5f[entry], process=DataListener
|
332
332
|
)
|
@@ -360,7 +360,7 @@ class DataListener(BaseProcessInfo):
|
|
360
360
|
"""Return the proposal file of the experimentation if registred by the
|
361
361
|
data listener"""
|
362
362
|
if entry is None:
|
363
|
-
with
|
363
|
+
with open_hdf5(process_file) as h5f:
|
364
364
|
entries = BaseProcessInfo._get_process_nodes(
|
365
365
|
root_node=h5f, process=DataListener
|
366
366
|
)
|
@@ -375,7 +375,7 @@ class DataListener(BaseProcessInfo):
|
|
375
375
|
entry = list(entries.keys())[0]
|
376
376
|
_logger.info("take %s as default entry" % entry)
|
377
377
|
|
378
|
-
with
|
378
|
+
with open_hdf5(process_file) as h5f:
|
379
379
|
dl_nodes = BaseProcessInfo._get_process_nodes(
|
380
380
|
root_node=h5f[entry], process=DataListener
|
381
381
|
)
|
@@ -410,7 +410,7 @@ class DataListener(BaseProcessInfo):
|
|
410
410
|
specific sequence data
|
411
411
|
"""
|
412
412
|
if entry is None:
|
413
|
-
with
|
413
|
+
with open_hdf5(process_file) as h5f:
|
414
414
|
entries = BaseProcessInfo._get_process_nodes(
|
415
415
|
root_node=h5f, process=DataListener
|
416
416
|
)
|
@@ -425,7 +425,7 @@ class DataListener(BaseProcessInfo):
|
|
425
425
|
entry = list(entries.keys())[0]
|
426
426
|
_logger.info("take %s as default entry" % entry)
|
427
427
|
|
428
|
-
with
|
428
|
+
with open_hdf5(process_file) as h5f:
|
429
429
|
dl_nodes = BaseProcessInfo._get_process_nodes(
|
430
430
|
root_node=h5f[entry], process=DataListener
|
431
431
|
)
|
@@ -503,7 +503,7 @@ class DataListener(BaseProcessInfo):
|
|
503
503
|
# write
|
504
504
|
def sequence_is_finished():
|
505
505
|
try:
|
506
|
-
with
|
506
|
+
with open_hdf5(bliss_file) as h5f:
|
507
507
|
end_scan_path = "/".join((entry, "end_time"))
|
508
508
|
return end_scan_path in h5f
|
509
509
|
except Exception:
|
@@ -0,0 +1,269 @@
|
|
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__ = "18/06/2021"
|
29
|
+
|
30
|
+
|
31
|
+
import os
|
32
|
+
import shutil
|
33
|
+
import tempfile
|
34
|
+
import unittest
|
35
|
+
|
36
|
+
import h5py
|
37
|
+
import numpy
|
38
|
+
from silx.io.url import DataUrl
|
39
|
+
from silx.io.utils import h5py_read_dataset
|
40
|
+
from tomoscan.esrf.scan.mock import MockNXtomo
|
41
|
+
|
42
|
+
from tomwer.core.process.edit.darkflatpatch import DarkFlatPatchTask
|
43
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan
|
44
|
+
|
45
|
+
|
46
|
+
class BaseTestAddDarkAndFlats(unittest.TestCase):
|
47
|
+
"""
|
48
|
+
Unit test on nxtomomill.utils.add_dark_flat_nx_file function
|
49
|
+
"""
|
50
|
+
|
51
|
+
def setUp(self) -> None:
|
52
|
+
self.tmpdir = tempfile.mkdtemp()
|
53
|
+
simple_nx_path = os.path.join(self.tmpdir, "simple_case")
|
54
|
+
self.dim = 55
|
55
|
+
self.nproj = 20
|
56
|
+
self._simple_nx = MockNXtomo(
|
57
|
+
scan_path=simple_nx_path,
|
58
|
+
n_proj=self.nproj,
|
59
|
+
n_ini_proj=self.nproj,
|
60
|
+
create_ini_dark=False,
|
61
|
+
create_ini_flat=False,
|
62
|
+
create_final_flat=False,
|
63
|
+
dim=self.dim,
|
64
|
+
).scan
|
65
|
+
with h5py.File(self._simple_nx.master_file, mode="r") as h5s:
|
66
|
+
data_path = "/".join(
|
67
|
+
(self._simple_nx.entry, "instrument", "detector", "data")
|
68
|
+
)
|
69
|
+
self._raw_data = h5py_read_dataset(h5s[data_path])
|
70
|
+
nx_with_vds_path = os.path.join(self.tmpdir, "case_with_vds")
|
71
|
+
self._nx_with_virtual_dataset = MockNXtomo(
|
72
|
+
scan_path=nx_with_vds_path,
|
73
|
+
n_proj=0,
|
74
|
+
n_ini_proj=0,
|
75
|
+
create_ini_dark=False,
|
76
|
+
create_ini_flat=False,
|
77
|
+
create_final_flat=False,
|
78
|
+
dim=self.dim,
|
79
|
+
).scan
|
80
|
+
self._create_vds(
|
81
|
+
source_file=self._simple_nx.master_file,
|
82
|
+
source_data_path=self._simple_nx.entry,
|
83
|
+
target_file=self._nx_with_virtual_dataset.master_file,
|
84
|
+
target_data_path=self._nx_with_virtual_dataset.entry,
|
85
|
+
copy_other_data=True,
|
86
|
+
)
|
87
|
+
self._patch_nxtomo_flags(self._nx_with_virtual_dataset)
|
88
|
+
|
89
|
+
nx_with_vds_path_and_links = os.path.join(
|
90
|
+
self.tmpdir, "case_with_vds_and_links"
|
91
|
+
)
|
92
|
+
self._nx_with_virtual_dataset_with_link = MockNXtomo(
|
93
|
+
scan_path=nx_with_vds_path_and_links,
|
94
|
+
n_proj=0,
|
95
|
+
n_ini_proj=0,
|
96
|
+
create_ini_dark=False,
|
97
|
+
create_ini_flat=False,
|
98
|
+
create_final_flat=False,
|
99
|
+
dim=self.dim,
|
100
|
+
).scan
|
101
|
+
self._create_vds(
|
102
|
+
source_file=self._simple_nx.master_file,
|
103
|
+
source_data_path=self._simple_nx.entry,
|
104
|
+
target_file=self._nx_with_virtual_dataset_with_link.master_file,
|
105
|
+
target_data_path=self._nx_with_virtual_dataset_with_link.entry,
|
106
|
+
copy_other_data=True,
|
107
|
+
)
|
108
|
+
self._patch_nxtomo_flags(self._nx_with_virtual_dataset_with_link)
|
109
|
+
|
110
|
+
# create dark
|
111
|
+
self.start_dark = (
|
112
|
+
numpy.random.random((self.dim * self.dim))
|
113
|
+
.reshape(1, self.dim, self.dim)
|
114
|
+
.astype("f")
|
115
|
+
)
|
116
|
+
self.start_dark_file = os.path.join(self.tmpdir, "dark.hdf5")
|
117
|
+
self.start_dark_entry = "data"
|
118
|
+
self.start_dark_url = self._save_raw(
|
119
|
+
data=self.start_dark,
|
120
|
+
entry=self.start_dark_entry,
|
121
|
+
file_path=self.start_dark_file,
|
122
|
+
)
|
123
|
+
|
124
|
+
self.end_dark = (
|
125
|
+
numpy.random.random((self.dim * self.dim * 2))
|
126
|
+
.reshape(2, self.dim, self.dim)
|
127
|
+
.astype("f")
|
128
|
+
)
|
129
|
+
self.end_dark_file = os.path.join(self.tmpdir, "dark.hdf5")
|
130
|
+
self.end_dark_entry = "data2"
|
131
|
+
self.end_dark_url = self._save_raw(
|
132
|
+
data=self.end_dark, entry=self.end_dark_entry, file_path=self.end_dark_file
|
133
|
+
)
|
134
|
+
|
135
|
+
# create flats
|
136
|
+
self.start_flat = (
|
137
|
+
numpy.random.random((self.dim * self.dim * 3))
|
138
|
+
.reshape(3, self.dim, self.dim)
|
139
|
+
.astype("f")
|
140
|
+
)
|
141
|
+
self.start_flat_file = os.path.join(self.tmpdir, "start_flat.hdf5")
|
142
|
+
self.start_flat_entry = "/root/flat"
|
143
|
+
self.start_flat_url = self._save_raw(
|
144
|
+
data=self.start_flat,
|
145
|
+
entry=self.start_flat_entry,
|
146
|
+
file_path=self.start_flat_file,
|
147
|
+
)
|
148
|
+
|
149
|
+
self.end_flat = (
|
150
|
+
numpy.random.random((self.dim * self.dim))
|
151
|
+
.reshape(1, self.dim, self.dim)
|
152
|
+
.astype("f")
|
153
|
+
)
|
154
|
+
# save the end flat in the simple case file to insure all cases are
|
155
|
+
# consider
|
156
|
+
self.end_flat_file = self._simple_nx.master_file
|
157
|
+
self.end_flat_entry = "flat"
|
158
|
+
self.end_flat_url = self._save_raw(
|
159
|
+
data=self.end_flat, entry=self.end_flat_entry, file_path=self.end_flat_file
|
160
|
+
)
|
161
|
+
|
162
|
+
def _save_raw(self, data, entry, file_path) -> DataUrl:
|
163
|
+
with h5py.File(file_path, mode="a") as h5s:
|
164
|
+
h5s[entry] = data
|
165
|
+
return DataUrl(file_path=file_path, data_path=entry, scheme="silx")
|
166
|
+
|
167
|
+
def _create_vds(
|
168
|
+
self,
|
169
|
+
source_file: str,
|
170
|
+
source_data_path: str,
|
171
|
+
target_file: str,
|
172
|
+
target_data_path: str,
|
173
|
+
copy_other_data: bool,
|
174
|
+
):
|
175
|
+
"""Create virtual dataset and links from source to target
|
176
|
+
|
177
|
+
:param str source_file:
|
178
|
+
:param str source_data_path:
|
179
|
+
:param str target_file:
|
180
|
+
:param str target_data_path:
|
181
|
+
:param bool copy_other_data: we want to create two cases: one copying
|
182
|
+
datasets 'image_key'... and the other
|
183
|
+
one linking them. Might have a difference
|
184
|
+
of behavior when overwriting for example
|
185
|
+
"""
|
186
|
+
assert source_file != target_file, "file should be different"
|
187
|
+
# link data
|
188
|
+
n_frames = 0
|
189
|
+
# for now we only consider the original data
|
190
|
+
with h5py.File(source_file, mode="r") as o_h5s:
|
191
|
+
old_path = os.path.join(source_data_path, "instrument", "detector", "data")
|
192
|
+
n_frames += o_h5s[old_path].shape[0]
|
193
|
+
shape = o_h5s[old_path].shape
|
194
|
+
data_type = o_h5s[old_path].dtype
|
195
|
+
|
196
|
+
layout = h5py.VirtualLayout(shape=shape, dtype=data_type)
|
197
|
+
assert os.path.exists(source_file)
|
198
|
+
with h5py.File(source_file, mode="r") as ppp:
|
199
|
+
assert source_data_path in ppp
|
200
|
+
layout[:] = h5py.VirtualSource(path_or_dataset=o_h5s[old_path])
|
201
|
+
|
202
|
+
det_path = os.path.join(target_data_path, "instrument", "detector")
|
203
|
+
with h5py.File(target_file, mode="a") as h5s:
|
204
|
+
detector_node = h5s.require_group(det_path)
|
205
|
+
detector_node.create_virtual_dataset("data", layout, fillvalue=-5)
|
206
|
+
|
207
|
+
for path in (
|
208
|
+
os.path.join("instrument", "detector", "image_key"),
|
209
|
+
os.path.join("instrument", "detector", "image_key_control"),
|
210
|
+
os.path.join("instrument", "detector", "count_time"),
|
211
|
+
os.path.join("sample", "rotation_angle"),
|
212
|
+
):
|
213
|
+
old_path = os.path.join(source_data_path, path)
|
214
|
+
new_path = os.path.join(target_data_path, path)
|
215
|
+
with h5py.File(target_file, mode="a") as h5s:
|
216
|
+
if copy_other_data:
|
217
|
+
with h5py.File(source_file, mode="r") as o_h5s:
|
218
|
+
if new_path in h5s:
|
219
|
+
del h5s[new_path]
|
220
|
+
h5s[new_path] = h5py_read_dataset(o_h5s[old_path])
|
221
|
+
elif source_file == target_file:
|
222
|
+
h5s[new_path] = h5py.SoftLink(old_path)
|
223
|
+
else:
|
224
|
+
relpath = os.path.relpath(source_file, os.path.dirname(target_file))
|
225
|
+
h5s[new_path] = h5py.ExternalLink(relpath, old_path)
|
226
|
+
|
227
|
+
def _patch_nxtomo_flags(self, scan):
|
228
|
+
"""Insure necessary flags are here"""
|
229
|
+
with h5py.File(scan.master_file, mode="a") as h5s:
|
230
|
+
instrument_path = os.path.join(scan.entry, "instrument")
|
231
|
+
instrument_node = h5s.require_group(instrument_path)
|
232
|
+
if "NX_class" not in instrument_node.attrs:
|
233
|
+
instrument_node.attrs["NX_class"] = "NXinstrument"
|
234
|
+
detector_node = instrument_node.require_group("detector")
|
235
|
+
if "NX_class" not in detector_node.attrs:
|
236
|
+
detector_node.attrs["NX_class"] = "NXdetector"
|
237
|
+
if "data" in instrument_node:
|
238
|
+
if "interpretation" not in instrument_node.attrs:
|
239
|
+
instrument_node["data"].attrs["interpretation"] = "image"
|
240
|
+
|
241
|
+
sample_path = os.path.join(scan.entry, "sample")
|
242
|
+
sample_node = h5s.require_group(sample_path)
|
243
|
+
if "NX_class" not in sample_node:
|
244
|
+
sample_node.attrs["NX_class"] = "NXsample"
|
245
|
+
|
246
|
+
def tearDown(self) -> None:
|
247
|
+
shutil.rmtree(self.tmpdir)
|
248
|
+
|
249
|
+
|
250
|
+
class TestDaarkFlatPatch(BaseTestAddDarkAndFlats):
|
251
|
+
def test(self):
|
252
|
+
scan = NXtomoScan(
|
253
|
+
self._nx_with_virtual_dataset_with_link.master_file,
|
254
|
+
self._nx_with_virtual_dataset_with_link.entry,
|
255
|
+
)
|
256
|
+
process = DarkFlatPatchTask(
|
257
|
+
inputs={
|
258
|
+
"data": scan,
|
259
|
+
"serialize_output_data": False,
|
260
|
+
"configuration": {
|
261
|
+
"darks_start": self.start_dark_url,
|
262
|
+
},
|
263
|
+
},
|
264
|
+
)
|
265
|
+
process.definition()
|
266
|
+
process.program_version()
|
267
|
+
process.program_name()
|
268
|
+
# TODO: properties should be part of inputs
|
269
|
+
process.run()
|
@@ -0,0 +1,125 @@
|
|
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__ = "18/06/2021"
|
29
|
+
|
30
|
+
|
31
|
+
import os
|
32
|
+
import shutil
|
33
|
+
import tempfile
|
34
|
+
import unittest
|
35
|
+
|
36
|
+
import pytest
|
37
|
+
from nxtomo.nxobject.nxdetector import ImageKey
|
38
|
+
|
39
|
+
from tomwer.core.process.edit.imagekeyeditor import (
|
40
|
+
ImageKeyEditorTask,
|
41
|
+
ImageKeyUpgraderTask,
|
42
|
+
)
|
43
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan
|
44
|
+
from tomwer.core.utils.scanutils import MockNXtomo
|
45
|
+
|
46
|
+
|
47
|
+
class TestImageKeyEditor(unittest.TestCase):
|
48
|
+
def setUp(self):
|
49
|
+
self.tempdir = tempfile.mkdtemp()
|
50
|
+
dim = 10
|
51
|
+
mock = MockNXtomo(
|
52
|
+
scan_path=os.path.join(self.tempdir, "scan1"),
|
53
|
+
n_proj=10,
|
54
|
+
n_ini_proj=10,
|
55
|
+
scan_range=180,
|
56
|
+
dim=dim,
|
57
|
+
)
|
58
|
+
self.scan = mock.scan
|
59
|
+
|
60
|
+
def tearDown(self):
|
61
|
+
shutil.rmtree(self.tempdir)
|
62
|
+
|
63
|
+
def test(self):
|
64
|
+
process = ImageKeyEditorTask(
|
65
|
+
inputs={
|
66
|
+
"data": self.scan,
|
67
|
+
"serialize_output_data": False,
|
68
|
+
"configuration": {
|
69
|
+
"modifications": {
|
70
|
+
0: ImageKey.INVALID.value,
|
71
|
+
3: ImageKey.ALIGNMENT.value,
|
72
|
+
},
|
73
|
+
},
|
74
|
+
}
|
75
|
+
)
|
76
|
+
process.definition()
|
77
|
+
process.program_version()
|
78
|
+
process.program_name()
|
79
|
+
process.run()
|
80
|
+
|
81
|
+
|
82
|
+
def test_ImageKeyUpgraderTask(tmp_path):
|
83
|
+
"""
|
84
|
+
test ImageKeyUpgraderTask task
|
85
|
+
"""
|
86
|
+
test_dir = tmp_path / "test_image_key_upgrader"
|
87
|
+
os.makedirs(test_dir)
|
88
|
+
scan = MockNXtomo(
|
89
|
+
scan_path=test_dir,
|
90
|
+
n_proj=20,
|
91
|
+
n_ini_proj=20,
|
92
|
+
create_ini_dark=False,
|
93
|
+
).scan
|
94
|
+
|
95
|
+
operations = {
|
96
|
+
ImageKey.PROJECTION: ImageKey.DARK_FIELD,
|
97
|
+
}
|
98
|
+
|
99
|
+
with pytest.raises(TypeError):
|
100
|
+
ImageKeyUpgraderTask(
|
101
|
+
inputs={
|
102
|
+
"data": None,
|
103
|
+
"operations": operations,
|
104
|
+
},
|
105
|
+
).run()
|
106
|
+
|
107
|
+
with pytest.raises(TypeError):
|
108
|
+
ImageKeyUpgraderTask(
|
109
|
+
inputs={
|
110
|
+
"data": scan,
|
111
|
+
"operations": None,
|
112
|
+
},
|
113
|
+
).run()
|
114
|
+
|
115
|
+
task = ImageKeyUpgraderTask(
|
116
|
+
inputs={
|
117
|
+
"data": scan,
|
118
|
+
"operations": operations,
|
119
|
+
},
|
120
|
+
)
|
121
|
+
task.run()
|
122
|
+
|
123
|
+
scan = NXtomoScan(scan.master_file, scan.entry)
|
124
|
+
assert len(scan.projections) == 0
|
125
|
+
assert len(scan.darks) == 20
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import numpy
|
2
|
+
from tomwer.tests.conftest import nxtomo_scan_180 # noqa F811
|
3
|
+
from tomwer.core.process.icat.createscreenshots import (
|
4
|
+
CreateRawDataScreenshotsTask,
|
5
|
+
select_angles,
|
6
|
+
)
|
7
|
+
|
8
|
+
|
9
|
+
def test_CreateRawDataScreenshotsTask(nxtomo_scan_180): # noqa F811
|
10
|
+
"""
|
11
|
+
test CreateRawDataScreenshotsTask task
|
12
|
+
"""
|
13
|
+
# test nothing requested
|
14
|
+
task = CreateRawDataScreenshotsTask(
|
15
|
+
inputs={
|
16
|
+
"data": nxtomo_scan_180,
|
17
|
+
"raw_projections_required": False,
|
18
|
+
"raw_darks_required": False,
|
19
|
+
"raw_flats_required": False,
|
20
|
+
}
|
21
|
+
)
|
22
|
+
task.run()
|
23
|
+
assert len(task.outputs.screenshots.screenshots) == 0
|
24
|
+
|
25
|
+
# test only dark requested
|
26
|
+
task = CreateRawDataScreenshotsTask(
|
27
|
+
inputs={
|
28
|
+
"data": nxtomo_scan_180,
|
29
|
+
"raw_projections_required": False,
|
30
|
+
"raw_darks_required": False,
|
31
|
+
"raw_flats_required": True,
|
32
|
+
}
|
33
|
+
)
|
34
|
+
task.run()
|
35
|
+
assert len(task.outputs.screenshots.screenshots) == 1
|
36
|
+
|
37
|
+
# test only flat requested
|
38
|
+
task = CreateRawDataScreenshotsTask(
|
39
|
+
inputs={
|
40
|
+
"data": nxtomo_scan_180,
|
41
|
+
"raw_projections_required": False,
|
42
|
+
"raw_darks_required": True,
|
43
|
+
"raw_flats_required": False,
|
44
|
+
}
|
45
|
+
)
|
46
|
+
task.run()
|
47
|
+
assert len(task.outputs.screenshots.screenshots) == 1
|
48
|
+
|
49
|
+
# test only projection requested
|
50
|
+
task = CreateRawDataScreenshotsTask(
|
51
|
+
inputs={
|
52
|
+
"data": nxtomo_scan_180,
|
53
|
+
"raw_projections_required": True,
|
54
|
+
"raw_darks_required": False,
|
55
|
+
"raw_flats_required": False,
|
56
|
+
}
|
57
|
+
)
|
58
|
+
task.run()
|
59
|
+
assert len(task.outputs.screenshots.screenshots) == 2
|
60
|
+
|
61
|
+
# test all requested
|
62
|
+
task = CreateRawDataScreenshotsTask(
|
63
|
+
inputs={
|
64
|
+
"data": nxtomo_scan_180,
|
65
|
+
"raw_projections_required": True,
|
66
|
+
"raw_darks_required": True,
|
67
|
+
"raw_flats_required": True,
|
68
|
+
"raw_projections_each": 10,
|
69
|
+
}
|
70
|
+
)
|
71
|
+
task.run()
|
72
|
+
assert len(task.outputs.screenshots.screenshots) == 12
|
73
|
+
|
74
|
+
|
75
|
+
def test_select_angles():
|
76
|
+
"""test the select_angles function"""
|
77
|
+
numpy.testing.assert_allclose(
|
78
|
+
select_angles(
|
79
|
+
numpy.linspace(start=-20, stop=40, num=201, endpoint=True), each_angle=20
|
80
|
+
),
|
81
|
+
numpy.array([-20, 0.1, 19.9, 40]),
|
82
|
+
)
|
83
|
+
|
84
|
+
assert select_angles((), each_angle=20) == ()
|
85
|
+
assert select_angles((10,), each_angle=10) == (10,)
|
86
|
+
angles = select_angles(
|
87
|
+
numpy.linspace(start=0, stop=10, num=400, endpoint=False), each_angle=1
|
88
|
+
)
|
89
|
+
assert len(angles) == 11
|
90
|
+
assert numpy.isclose(angles[0], 0, atol=0.1)
|
91
|
+
assert numpy.isclose(angles[-1], 10, atol=0.1)
|
92
|
+
|
93
|
+
|
94
|
+
# def test_CreateRawDataScreenshotsWidgetWorkflow():
|
95
|
+
# """
|
96
|
+
# test CreateRawDataScreenshotsTask with a MoveScreenshotsToGalleryTask task to make sure the two work well together
|
97
|
+
# """
|
98
|
+
# raise NotImplementedError
|