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.
Files changed (124) 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/control/datalistener/datalistener.py +11 -11
  49. tomwer/core/process/edit/test/test_darkflatpatch.py +269 -0
  50. tomwer/core/process/edit/test/test_imagekey_editor.py +125 -0
  51. tomwer/core/process/icat/test/test_create_screenshots.py +98 -0
  52. tomwer/core/process/icat/test/test_gallery.py +170 -0
  53. tomwer/core/process/reconstruction/axis/axis.py +3 -3
  54. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +3 -2
  55. tomwer/core/process/reconstruction/nabu/nabucommon.py +3 -4
  56. tomwer/core/process/reconstruction/nabu/nabuslices.py +4 -4
  57. tomwer/core/process/reconstruction/nabu/nabuvolume.py +2 -5
  58. tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +143 -0
  59. tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py +203 -0
  60. tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py +222 -0
  61. tomwer/core/process/script/test/test_script.py +68 -0
  62. tomwer/core/process/stitching/test/test_metadataholder.py +17 -0
  63. tomwer/core/process/task.py +3 -2
  64. tomwer/core/process/test/test_data_transfer.py +4 -3
  65. tomwer/core/process/visualization/test/test_data_viewer.py +39 -0
  66. tomwer/core/process/visualization/test/test_diff_viewer.py +39 -0
  67. tomwer/core/process/visualization/test/test_image_stack_viewer.py +41 -0
  68. tomwer/core/process/visualization/test/test_radio_stack.py +39 -0
  69. tomwer/core/process/visualization/test/test_sample_moved.py +41 -0
  70. tomwer/core/process/visualization/test/test_sinogram_viewer.py +39 -0
  71. tomwer/core/process/visualization/test/test_slice_stack.py +39 -0
  72. tomwer/core/process/visualization/test/test_volume_viewer.py +39 -0
  73. tomwer/core/scan/blissscan.py +3 -3
  74. tomwer/core/scan/nxtomoscan.py +2 -2
  75. tomwer/core/scan/scanbase.py +5 -6
  76. tomwer/core/utils/test/test_image.py +30 -0
  77. tomwer/core/utils/test/test_nxtomo.py +66 -0
  78. tomwer/core/utils/test/test_scan_utils.py +46 -0
  79. tomwer/core/utils/test/test_time.py +6 -0
  80. tomwer/core/volume/test/test_volumes.py +21 -0
  81. tomwer/gui/control/reducedarkflatselector.py +2 -2
  82. tomwer/gui/control/serie/test/test_creator.py +451 -0
  83. tomwer/gui/control/serie/test/test_nxtomo_concatenate.py +21 -0
  84. tomwer/gui/edit/dkrfpatch.py +4 -4
  85. tomwer/gui/edit/nxtomowarmer.py +3 -2
  86. tomwer/gui/icat/test/test_create_screenshots_gui.py +23 -0
  87. tomwer/gui/icat/test/test_gallery_gui.py +37 -0
  88. tomwer/gui/imagefromfile.py +2 -2
  89. tomwer/gui/reconstruction/nabu/test/test_check.py +92 -0
  90. tomwer/gui/reconstruction/nabu/test/test_ctf.py +46 -0
  91. tomwer/gui/reconstruction/nabu/test/test_helical.py +21 -0
  92. tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py +81 -0
  93. tomwer/gui/reconstruction/normalization/test/test_intensity.py +119 -0
  94. tomwer/gui/stitching/config/tests/test_axisparams.py +25 -0
  95. tomwer/gui/stitching/tests/test_axis_ordered_list.py +21 -0
  96. tomwer/gui/stitching/tests/test_normalization.py +27 -0
  97. tomwer/gui/stitching/tests/test_preview.py +85 -0
  98. tomwer/gui/stitching/tests/test_stitching_raw.py +110 -0
  99. tomwer/gui/stitching/tests/test_z_stitching.py +67 -0
  100. tomwer/gui/stitching/tests/utils.py +79 -0
  101. tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py +35 -0
  102. tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +215 -0
  103. tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +51 -0
  104. tomwer/gui/utils/test/test_completer.py +67 -0
  105. tomwer/gui/utils/test/test_line_selector.py +21 -0
  106. tomwer/gui/utils/test/test_splashscreen.py +8 -0
  107. tomwer/gui/utils/test/test_vignettes.py +68 -0
  108. tomwer/io/utils/h5pyutils.py +3 -7
  109. tomwer/io/utils/test/test_raw_and_processed_data.py +10 -0
  110. tomwer/io/utils/test/test_utils.py +92 -0
  111. tomwer/io/utils/utils.py +3 -3
  112. tomwer/synctools/stacks/reconstruction/castvolume.py +20 -5
  113. tomwer/tests/test_ewoks/test_conversion.py +104 -0
  114. tomwer/tests/test_ewoks/test_single_node_execution.py +112 -0
  115. tomwer/tests/test_ewoks/test_workflows.py +160 -0
  116. tomwer/version.py +1 -1
  117. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/METADATA +1 -1
  118. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/RECORD +124 -27
  119. /tomwer-1.3.5-py3.11-nspkg.pth → /tomwer-1.3.7-py3.11-nspkg.pth +0 -0
  120. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/LICENSE +0 -0
  121. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/WHEEL +0 -0
  122. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/entry_points.txt +0 -0
  123. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/namespace_packages.txt +0 -0
  124. {tomwer-1.3.5.dist-info → tomwer-1.3.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,92 @@
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__ = "02/12/2021"
29
+
30
+
31
+ import os
32
+
33
+ import pytest
34
+ from nxtomo.nxobject.nxdetector import ImageKey
35
+
36
+ from tomwer.core.scan.edfscan import EDFTomoScan
37
+ from tomwer.core.utils.scanutils import MockEDF, MockNXtomo
38
+ from tomwer.gui.reconstruction.nabu import check
39
+
40
+
41
+ def test_check_dark_series(tmpdir):
42
+ """test check.check_dark_series function"""
43
+ full_edf_path = os.path.join(tmpdir, "my", "aquisition", "folder")
44
+ MockEDF.fastMockAcquisition(full_edf_path)
45
+ edf_scan = EDFTomoScan(full_edf_path)
46
+ with pytest.raises(TypeError):
47
+ assert check.check_dark_series(edf_scan)
48
+
49
+ full_hdf5_scan = os.path.join(tmpdir, "hdf5_scan")
50
+ scan = MockNXtomo(
51
+ scan_path=full_hdf5_scan,
52
+ n_proj=20,
53
+ n_ini_proj=20,
54
+ dim=10,
55
+ ).scan
56
+ scan._image_keys = (
57
+ [ImageKey.DARK_FIELD] * 2
58
+ + [ImageKey.PROJECTION] * 4
59
+ + [ImageKey.DARK_FIELD] * 2
60
+ )
61
+ assert check.check_dark_series(scan, logger=None, user_input=False) is False
62
+ scan._image_keys = [ImageKey.DARK_FIELD] * 2 + [ImageKey.PROJECTION] * 4
63
+ assert check.check_dark_series(scan, logger=None, user_input=False) is True
64
+ scan._image_keys = [ImageKey.PROJECTION] * 4
65
+ assert check.check_dark_series(scan, logger=None, user_input=False) is False
66
+
67
+
68
+ def test_check_flat_series(tmpdir):
69
+ """test check.check_flat_series function"""
70
+ full_edf_path = os.path.join(tmpdir, "my", "aquisition", "folder")
71
+ MockEDF.fastMockAcquisition(full_edf_path)
72
+ edf_scan = EDFTomoScan(full_edf_path)
73
+ with pytest.raises(TypeError):
74
+ assert check.check_flat_series(edf_scan)
75
+
76
+ full_hdf5_scan = os.path.join(tmpdir, "hdf5_scan")
77
+ scan = MockNXtomo(
78
+ scan_path=full_hdf5_scan,
79
+ n_proj=20,
80
+ n_ini_proj=20,
81
+ dim=10,
82
+ ).scan
83
+ scan._image_keys = (
84
+ [ImageKey.FLAT_FIELD] * 2
85
+ + [ImageKey.PROJECTION] * 4
86
+ + [ImageKey.FLAT_FIELD] * 2
87
+ )
88
+ assert check.check_flat_series(scan, logger=None, user_input=False) is True
89
+ scan._image_keys = [ImageKey.FLAT_FIELD] * 2 + [ImageKey.PROJECTION] * 4
90
+ assert check.check_flat_series(scan, logger=None, user_input=False) is True
91
+ scan._image_keys = [ImageKey.PROJECTION] * 4
92
+ assert check.check_flat_series(scan, logger=None, user_input=False) is False
@@ -0,0 +1,46 @@
1
+ import pytest
2
+ from silx.gui import qt
3
+ from silx.gui.utils.testutils import TestCaseQt
4
+
5
+ from tomwer.gui.reconstruction.nabu.nabuconfig.ctf import CTFConfig
6
+ from tomwer.tests.utils import skip_gui_test
7
+
8
+
9
+ @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
10
+ class TestFutureSupervisorOW(TestCaseQt):
11
+ def setUp(self):
12
+ super().setUp()
13
+ self._widget = CTFConfig()
14
+
15
+ def tearDown(self):
16
+ self._widget.setAttribute(qt.Qt.WA_DeleteOnClose)
17
+ self._widget.close()
18
+ self._widget = None
19
+ return super().tearDown()
20
+
21
+ def test_configuration(self):
22
+ """
23
+ test configuration setter and getter
24
+ """
25
+ self._widget.show()
26
+ config = self._widget.getConfiguration()
27
+ assert isinstance(config, dict)
28
+
29
+ assert config == {
30
+ "ctf_geometry": " z1_v=None; z1_h=None; detec_pixel_size=None; magnification=True",
31
+ "ctf_advanced_params": " length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True",
32
+ "ctf_translations_file": "",
33
+ "beam_shape": "parallel",
34
+ }
35
+
36
+ config["beam_shape"] = "cone"
37
+ config["ctf_translations_file"] = "my_file.txt"
38
+ config["ctf_geometry"] = (
39
+ " z1_v=10.2; z1_h=3.6; detec_pixel_size=1e-05; magnification=False"
40
+ )
41
+ config["ctf_advanced_params"] = (
42
+ " length_scale=2e-05; lim1=1e-08; lim2=0.1; normalize_by_mean=False"
43
+ )
44
+
45
+ self._widget.setConfiguration(config)
46
+ assert self._widget.getConfiguration() == config
@@ -0,0 +1,21 @@
1
+ from tomwer.tests.conftest import qtapp # noqa F401
2
+ from tomwer.gui.reconstruction.nabu.helical import HelicalPrepareWeightsDouble
3
+
4
+
5
+ def test_DeltaBetaSelector(
6
+ qtapp, # noqa F811
7
+ ):
8
+ """simple test of the _DeltaBetaSelectorDialog"""
9
+ widget = HelicalPrepareWeightsDouble()
10
+ assert widget.getConfiguration() == {
11
+ "processes_file": "{scan_parent_dir_basename}/{scan_dir_name}/map_and_doubleff.hdf5",
12
+ "transition_width_vertical": 50.0,
13
+ "transition_width_horizontal": 50.0,
14
+ }
15
+ config = {
16
+ "processes_file": "test.hdf5",
17
+ "transition_width_vertical": 12.5,
18
+ "transition_width_horizontal": 11.5,
19
+ }
20
+ widget.setConfiguration(config=config)
21
+ assert widget.getConfiguration() == config
@@ -0,0 +1,81 @@
1
+ from tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import (
2
+ SinoRingsOptions,
3
+ TiltCorrection,
4
+ RingCorrectionMethod,
5
+ )
6
+ from tomwer.tests.conftest import qtapp # noqa F401
7
+
8
+
9
+ def test_tilt_correction_widget(qtapp): # noqa F811
10
+ """
11
+ Test of TiltCorrection
12
+ """
13
+ widget = TiltCorrection(text="")
14
+ assert not widget._tiltManualRB.isChecked()
15
+ assert widget._autoManualRB.isChecked()
16
+ assert widget.getTiltCorrection() == ("1d-correlation", "")
17
+ widget.setTiltCorrection(0.0)
18
+ assert widget.getTiltCorrection() == (0.0, "")
19
+ assert widget._tiltManualRB.isChecked()
20
+ assert not widget._autoManualRB.isChecked()
21
+ widget.setTiltCorrection("fft-polar", auto_tilt_options="low_pass=10")
22
+ assert widget.getTiltCorrection() == ("fft-polar", "low_pass=10")
23
+ assert not widget._tiltManualRB.isChecked()
24
+ assert widget._autoManualRB.isChecked()
25
+
26
+
27
+ def test_sino_rings_options(qtapp): # noqa F811
28
+ """
29
+ Test of SinoRingsOptions
30
+ """
31
+ widget = SinoRingsOptions()
32
+ # test munch options
33
+ assert widget.getOptions() == {
34
+ "sigma": 1.0,
35
+ "levels": 10,
36
+ "padding": False,
37
+ }
38
+
39
+ widget.setOptions(
40
+ {
41
+ "sigma": 3.25,
42
+ "levels": 564,
43
+ "padding": True,
44
+ }
45
+ )
46
+ assert widget.getOptions() == {
47
+ "sigma": 3.25,
48
+ "levels": 564,
49
+ "padding": True,
50
+ }
51
+ # test mean division
52
+ widget.setMethod(method=RingCorrectionMethod.MEAN_DIVISION)
53
+ assert widget.getOptions() == {
54
+ "filter_cutoff": (0, 30),
55
+ }
56
+
57
+ # test VO deringer
58
+ widget.setMethod(method=RingCorrectionMethod.VO.value)
59
+ assert widget.getOptions() == {
60
+ "dim": 1,
61
+ "la_size": 51,
62
+ "sm_size": 21,
63
+ "snr": 3.0,
64
+ }
65
+ new_vo_options = {
66
+ "dim": 2,
67
+ "la_size": 42,
68
+ "sm_size": 22,
69
+ "snr": 6.3,
70
+ }
71
+ widget.setOptions(new_vo_options)
72
+ assert widget.getOptions() == new_vo_options
73
+
74
+ # test mean division
75
+ new_mean_division_options = {
76
+ "filter_cutoff": (10, 23),
77
+ }
78
+
79
+ widget.setMethod(method=RingCorrectionMethod.MEAN_DIVISION)
80
+ widget.setOptions(new_mean_division_options)
81
+ assert widget.getOptions() == new_mean_division_options
@@ -0,0 +1,119 @@
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
+
27
+ __authors__ = [
28
+ "H. Payno",
29
+ ]
30
+ __license__ = "MIT"
31
+ __date__ = "23/06/2021"
32
+
33
+
34
+ import os
35
+ import shutil
36
+ import tempfile
37
+
38
+ from silx.gui import qt
39
+ from silx.gui.utils.testutils import TestCaseQt
40
+
41
+ from tomwer.core.process.reconstruction.normalization.params import (
42
+ Method as NormalizationMethod,
43
+ )
44
+ from tomwer.core.process.reconstruction.normalization.params import (
45
+ _ValueSource as NormalizationSource,
46
+ )
47
+ from tomwer.core.utils.scanutils import MockNXtomo
48
+ from tomwer.gui.reconstruction.normalization.intensity import SinoNormWindow
49
+
50
+
51
+ class TestNormIntensityWindow(TestCaseQt):
52
+ def setUp(self):
53
+ super(TestNormIntensityWindow, self).setUp()
54
+ self._widget = SinoNormWindow(parent=None)
55
+ self._tmp_dir = tempfile.mkdtemp()
56
+ scan_path = os.path.join(self._tmp_dir, "my_scan_2")
57
+ self.scan = MockNXtomo(
58
+ scan_path=scan_path,
59
+ n_ini_proj=10,
60
+ n_proj=10,
61
+ n_alignement_proj=2,
62
+ create_final_flat=False,
63
+ create_ini_dark=True,
64
+ create_ini_flat=True,
65
+ n_refs=1,
66
+ ).scan
67
+
68
+ def tearDown(self):
69
+ self._widget.setAttribute(qt.Qt.WA_DeleteOnClose)
70
+ self._widget.close()
71
+ self.qapp.processEvents()
72
+ self._widget = None
73
+ shutil.rmtree(self._tmp_dir)
74
+ super(TestNormIntensityWindow, self).tearDown()
75
+
76
+ def test(self):
77
+ self._widget.setScan(self.scan)
78
+ self._widget.show()
79
+ self.qWaitForWindowExposed(self._widget)
80
+ self._widget.setCurrentMethod(NormalizationMethod.NONE)
81
+ self.qapp.processEvents()
82
+ assert self._widget.getConfiguration() == {"source": "none", "method": "none"}
83
+
84
+ self._widget.setCurrentMethod(NormalizationMethod.CHEBYSHEV)
85
+ self.qapp.processEvents()
86
+ assert self._widget.getConfiguration() == {
87
+ "method": "chebyshev",
88
+ "source": "none",
89
+ }
90
+
91
+ self._widget.setCurrentMethod(NormalizationMethod.SUBTRACTION)
92
+ self.qapp.processEvents()
93
+ self._widget.setCurrentSource(NormalizationSource.MANUAL_ROI)
94
+ self.qapp.processEvents()
95
+ output_configuration = self._widget.getConfiguration()
96
+ assert output_configuration["method"] == "subtraction"
97
+ assert output_configuration["source"] == "manual ROI"
98
+ assert "start_x" in output_configuration
99
+ assert "end_x" in output_configuration
100
+ assert "start_y" in output_configuration
101
+ assert "end_y" in output_configuration
102
+ assert "calc_fct" in output_configuration
103
+ self._widget.setCurrentMethod(NormalizationMethod.DIVISION)
104
+ self.qapp.processEvents()
105
+ self._widget.setCurrentSource(NormalizationSource.DATASET)
106
+ self.qapp.processEvents()
107
+ output_configuration = self._widget.getConfiguration()
108
+ assert output_configuration["method"] == "division"
109
+ assert output_configuration["source"] == "from dataset"
110
+ assert "dataset_url" in output_configuration
111
+
112
+ self._widget.setCurrentMethod(NormalizationMethod.DIVISION)
113
+ self.qapp.processEvents()
114
+ self._widget.setCurrentSource(NormalizationSource.MANUAL_SCALAR)
115
+ self.qapp.processEvents()
116
+ output_configuration = self._widget.getConfiguration()
117
+ assert output_configuration["method"] == "division"
118
+ assert output_configuration["source"] == "scalar"
119
+ assert "value" in output_configuration
@@ -0,0 +1,25 @@
1
+ import pytest
2
+
3
+ from tomwer.gui.stitching.config.axisparams import StitcherAxisParams
4
+ from tomwer.tests.conftest import qtapp # noqa F401
5
+
6
+
7
+ def test_StitcherAxisParams(
8
+ qtapp, # noqa F811
9
+ ):
10
+ """test the StitcherAxisParams widget"""
11
+ with pytest.raises(TypeError):
12
+ widget = StitcherAxisParams(axis="toto")
13
+ widget = StitcherAxisParams(axis=0)
14
+ assert widget.getConfiguration() == {
15
+ "stitching": {
16
+ "axis_0_params": "img_reg_method=nabu-fft;window_size=400",
17
+ }
18
+ }
19
+ new_config = {
20
+ "stitching": {
21
+ "axis_0_params": "img_reg_method=skimage;window_size=50",
22
+ },
23
+ }
24
+ widget.setConfiguration(new_config)
25
+ assert widget.getConfiguration() == new_config
@@ -0,0 +1,21 @@
1
+ from tomwer.tests.conftest import qtapp # noqa F401
2
+ from tomwer.core.volume.hdf5volume import HDF5Volume
3
+ from tomwer.gui.stitching.axisorderedlist import EditableZOrderedTomoObjWidget
4
+
5
+
6
+ def test_axis_ordered_list_widget(
7
+ qtapp, # noqa F811
8
+ ):
9
+ widget = EditableZOrderedTomoObjWidget()
10
+ volumes = tuple(
11
+ HDF5Volume(
12
+ file_path=f"my_volume{i}.hdf5",
13
+ data_path="my_volume",
14
+ )
15
+ for i in range(5)
16
+ )
17
+ [widget.addTomoObj(volume) for volume in volumes]
18
+
19
+ widget.setSelectedTomoObjs([volumes[1], volumes[-1]])
20
+ widget._callbackRemoveSelectedTomoObj()
21
+ assert widget.getTomoObjsZOrdered() == (volumes[0], volumes[2], volumes[3])
@@ -0,0 +1,27 @@
1
+ from tomwer.gui.stitching.normalization import NormalizationBySampleGroupBox
2
+
3
+ from tomwer.tests.conftest import qtapp # noqa F401
4
+
5
+
6
+ def test_FrameNormalizationWidget(
7
+ qtapp, # noqa F811
8
+ ):
9
+ widget = NormalizationBySampleGroupBox()
10
+ assert widget.getConfiguration() == {
11
+ "active": True,
12
+ "side": "left",
13
+ "method": "median",
14
+ "width": 30,
15
+ "margin": 0,
16
+ }
17
+
18
+ new_config = {
19
+ "active": False,
20
+ "side": "left",
21
+ "method": "median",
22
+ "width": 30,
23
+ "margin": 0,
24
+ }
25
+
26
+ widget.setConfiguration(new_config)
27
+ assert widget.getConfiguration() == new_config
@@ -0,0 +1,85 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+
5
+ import numpy
6
+ from nabu.stitching.config import PreProcessedZStitchingConfiguration
7
+ from nabu.stitching.z_stitching import PreProcessZStitcher
8
+ from silx.gui import qt
9
+ from silx.gui.utils.testutils import TestCaseQt
10
+ from silx.image.phantomgenerator import PhantomGenerator
11
+
12
+ from tomwer.gui.stitching.stitching_preview import PreviewStitchingPlot
13
+ from tomwer.gui.stitching.tests.utils import create_scans_z_serie
14
+
15
+
16
+ class TestPreview(TestCaseQt):
17
+ def setUp(self):
18
+ super().setUp()
19
+ self._tmp_path = tempfile.mkdtemp()
20
+ self.axis_0_positions = (90, 0.0, -90.0)
21
+ self.axis_2_positions = (0.0, 0.0, 0.0)
22
+ pixel_size = 1.0
23
+
24
+ self.output_file_path = os.path.join(self._tmp_path, "output", "stitched.nx")
25
+ self._input_dir = os.path.join(self._tmp_path, "input")
26
+
27
+ self._scans = create_scans_z_serie(
28
+ output_dir=self._input_dir,
29
+ z_positions_m=self.axis_0_positions,
30
+ x_positions_m=self.axis_2_positions,
31
+ shifts=((0.0, 0.0), (-90.0, 0.0), (-180.0, 0.0)),
32
+ pixel_size=pixel_size,
33
+ raw_frame_width=280,
34
+ final_frame_width=100,
35
+ )
36
+ self._stitching_config = PreProcessedZStitchingConfiguration(
37
+ output_file_path=self.output_file_path,
38
+ output_data_path="entry_stitched",
39
+ overwrite_results=True,
40
+ slurm_config=None,
41
+ axis_0_pos_mm=numpy.array(self.axis_0_positions) / 1000,
42
+ axis_2_pos_mm=numpy.array(self.axis_2_positions) / 1000,
43
+ axis_0_pos_px=None,
44
+ axis_1_pos_px=None,
45
+ axis_2_pos_px=None,
46
+ input_scans=self._scans,
47
+ pixel_size=pixel_size,
48
+ )
49
+ self.widget = PreviewStitchingPlot()
50
+
51
+ def tearDown(self):
52
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
53
+ self.widget.close()
54
+ self.widget = None
55
+ shutil.rmtree(self._tmp_path)
56
+
57
+ def test(self):
58
+ """
59
+ test the PreviewStitchingPlot
60
+ """
61
+ self.widget.show()
62
+ self.widget._backGroundAction.toggle()
63
+ self.qapp.processEvents()
64
+
65
+ stitcher = PreProcessZStitcher(configuration=self._stitching_config)
66
+ stitched_id = stitcher.stitch(store_composition=True)
67
+ assert stitched_id is not None
68
+ composition = stitcher.frame_composition
69
+ assert composition is not None
70
+
71
+ self.widget.setStitchedTomoObj(
72
+ tomo_obj_id=stitched_id.to_str(), composition=composition
73
+ )
74
+ self.qapp.processEvents()
75
+ assert self.widget.stitched_image is not None
76
+ assert self.widget.composition_background is not None
77
+
78
+ numpy.testing.assert_almost_equal(
79
+ self.widget.stitched_image,
80
+ PhantomGenerator.get2DPhantomSheppLogan(n=280).astype(numpy.float32)
81
+ * 256.0,
82
+ )
83
+
84
+ self.widget._backGroundAction.toggle()
85
+ self.qapp.processEvents()
@@ -0,0 +1,110 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+
5
+ import numpy
6
+
7
+ from silx.gui import qt
8
+ from silx.gui.utils.testutils import TestCaseQt
9
+ from tomwer.core.utils.scanutils import MockNXtomo
10
+ from tomwer.core.volume.hdf5volume import HDF5Volume
11
+ from tomwer.gui.stitching.metadataholder import QStitchingMetadata
12
+ from tomwer.gui.stitching.stitching_raw import RawStitchingPlot, AlphaValuesTableWidget
13
+
14
+
15
+ def _createVolumes(axis_0_positions: tuple, root_dir: str):
16
+ volumes = []
17
+ for i_volume, axis_0_position in enumerate(axis_0_positions):
18
+ data = numpy.random.random(20 * 20).reshape(1, 20, 20)
19
+ volume = HDF5Volume(
20
+ file_path=os.path.join(root_dir, f"volume_{i_volume}.hdf5"),
21
+ data_path=f"entry_{i_volume}",
22
+ data=data,
23
+ )
24
+ volume.stitching_metadata = QStitchingMetadata(tomo_obj=volume)
25
+ volume.stitching_metadata.setPxPos(axis=0, value=axis_0_position)
26
+ volumes.append(volume)
27
+ return volumes
28
+
29
+
30
+ def _createScans(axis_0_positions: tuple, root_dir: str):
31
+ scans = []
32
+ for i_scan, axis_0_position in enumerate(axis_0_positions):
33
+ scan = MockNXtomo(
34
+ scan_path=os.path.join(root_dir, f"scan_{i_scan}"),
35
+ n_proj=20,
36
+ n_ini_proj=20,
37
+ dim=10,
38
+ ).scan
39
+ scan.stitching_metadata = QStitchingMetadata(tomo_obj=scan)
40
+ scan.stitching_metadata.setPxPos(axis=0, value=axis_0_position)
41
+ scans.append(scan)
42
+ return scans
43
+
44
+
45
+ class TestPlotRawStitching(TestCaseQt):
46
+ """Test RawStitchingPlot widget"""
47
+
48
+ def setUp(self):
49
+ super().setUp()
50
+ self._tmp_path = tempfile.mkdtemp()
51
+ self.widget = RawStitchingPlot(alpha_values=True)
52
+
53
+ def tearDown(self):
54
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
55
+ self.widget.close()
56
+ self.widget = None
57
+ shutil.rmtree(self._tmp_path)
58
+
59
+ def testWithVolumes(self):
60
+ axis_0_positions = (0, 12, 50)
61
+ volumes = _createVolumes(
62
+ axis_0_positions=axis_0_positions, root_dir=self._tmp_path
63
+ )
64
+ assert len(volumes) == 3
65
+ self.widget.addTomoObj(volumes[0])
66
+ images = self.widget.getAllImages()
67
+ assert len(images) == 1
68
+
69
+ self.widget.setTomoObjs(volumes)
70
+ images = self.widget.getAllImages()
71
+ assert len(images) == len(volumes)
72
+ # silx is storing origins as x, y
73
+ origins = tuple([image.getOrigin()[1] for image in images])
74
+ assert tuple(sorted(origins)) == axis_0_positions
75
+
76
+ def testWithScans(self):
77
+ axis_0_positions = (0, 10, 20, 34)
78
+ scans = _createScans(axis_0_positions=axis_0_positions, root_dir=self._tmp_path)
79
+ self.widget.setActive(False)
80
+ self.widget.setTomoObjs(scans)
81
+ assert len(self.widget.getAllImages()) == 0
82
+ self.widget.setActive(True)
83
+ self.qapp.processEvents()
84
+ assert len(self.widget.getAllImages()) == len(scans)
85
+
86
+
87
+ class TestAlphaValuesTableWidget(TestCaseQt):
88
+ """test AlphaValuesTableWidget"""
89
+
90
+ def setUp(self):
91
+ super().setUp()
92
+ self._tmp_path = tempfile.mkdtemp()
93
+ self.widget = AlphaValuesTableWidget()
94
+
95
+ def tearDown(self):
96
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
97
+ self.widget.close()
98
+ self.widget = None
99
+ shutil.rmtree(self._tmp_path)
100
+
101
+ def testSettingTomoObj(self):
102
+ self.widget.setTomoObjs(
103
+ _createVolumes(axis_0_positions=(0, 12, 50), root_dir=self._tmp_path),
104
+ )
105
+
106
+ assert len(self.widget._sliders) == 3
107
+ self.widget.setTomoObjs(
108
+ _createScans(axis_0_positions=(89, 78), root_dir=self._tmp_path)
109
+ )
110
+ assert len(self.widget._sliders) == 2