tomoscan 2.3.0.dev0__tar.gz → 2.3.0.dev1__tar.gz

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 (136) hide show
  1. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/PKG-INFO +1 -1
  2. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/framereducer/hdf5framereducer.py +5 -0
  3. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/framereducer/tests/test_hdf5framereducer.py +31 -2
  4. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/ReduceFrameSaver.py +3 -1
  5. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/reducedframesinfos.py +50 -0
  6. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/version.py +1 -1
  7. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan.egg-info/PKG-INFO +1 -1
  8. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan.egg-info/SOURCES.txt +0 -3
  9. tomoscan-2.3.0.dev0/tomoscan/esrf/volume/helpers/single_frame_saver.py +0 -73
  10. tomoscan-2.3.0.dev0/tomoscan/esrf/volume/helpers/test/test_single_frame_saver.py +0 -67
  11. tomoscan-2.3.0.dev0/tomoscan/tests/__init__.py +0 -0
  12. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/LICENSE +0 -0
  13. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/README.md +0 -0
  14. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/doc/conf.py +0 -0
  15. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/pyproject.toml +0 -0
  16. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/setup.cfg +0 -0
  17. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/snippets/test_sinogram.py +0 -0
  18. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/_CoordinateSystem.py +0 -0
  19. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/__init__.py +0 -0
  20. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/__init__.py +0 -0
  21. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/edfscan.py +0 -0
  22. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/hdf5scan.py +0 -0
  23. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/__init__.py +0 -0
  24. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/edfidentifier.py +0 -0
  25. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/folderidentifier.py +0 -0
  26. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/hdf5Identifier.py +0 -0
  27. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/jp2kidentifier.py +0 -0
  28. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/rawidentifier.py +0 -0
  29. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/tests/test_edfidentifier.py +0 -0
  30. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/tests/test_hdf5identifier.py +0 -0
  31. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/tests/test_rawidentifier.py +0 -0
  32. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/tiffidentifier.py +0 -0
  33. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/identifier/url_utils.py +0 -0
  34. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/mock.py +0 -0
  35. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/__init__.py +0 -0
  36. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/edfscan.py +0 -0
  37. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/framereducer/__init__.py +0 -0
  38. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/framereducer/edfframereducer.py +0 -0
  39. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/framereducer/tests/test_edfframereducer.py +0 -0
  40. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/fscan.py +0 -0
  41. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/fscan_scantypes.py +0 -0
  42. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/h5utils.py +0 -0
  43. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/hdf5scan.py +0 -0
  44. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/mock.py +0 -0
  45. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/nxtomoscan.py +0 -0
  46. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/tests/test_edfscan.py +0 -0
  47. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/tests/test_fscan.py +0 -0
  48. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/tests/test_mock.py +0 -0
  49. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/tests/test_nxtomoscan.py +0 -0
  50. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/tests/test_nxtomoscan_mcstas.py +0 -0
  51. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/tests/test_utils.py +0 -0
  52. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/scan/utils.py +0 -0
  53. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/utils.py +0 -0
  54. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/__init__.py +0 -0
  55. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/edfvolume.py +0 -0
  56. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/hdf5volume.py +0 -0
  57. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/jp2kvolume.py +0 -0
  58. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/mock.py +0 -0
  59. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/rawvolume.py +0 -0
  60. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/singleframebase.py +0 -0
  61. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_edfvolume.py +0 -0
  62. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_hdf5volume.py +0 -0
  63. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_jp2kvolume.py +0 -0
  64. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_raw_volume.py +0 -0
  65. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_single_frame_volume.py +0 -0
  66. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_tiffvolume.py +0 -0
  67. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tests/test_volume_esrf_utils.py +0 -0
  68. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/tiffvolume.py +0 -0
  69. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/esrf/volume/utils.py +0 -0
  70. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/factory.py +0 -0
  71. {tomoscan-2.3.0.dev0/tomoscan/esrf/volume/helpers → tomoscan-2.3.0.dev1/tomoscan/framereducer}/__init__.py +0 -0
  72. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/framereducerbase.py +0 -0
  73. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/method.py +0 -0
  74. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/target.py +0 -0
  75. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/tests/test_ReduceFrameSaver.py +0 -0
  76. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducer/tests/test_framereducerbase.py +0 -0
  77. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/framereducerbase.py +0 -0
  78. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/identifier.py +0 -0
  79. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/io.py +0 -0
  80. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/__init__.py +0 -0
  81. {tomoscan-2.3.0.dev0/tomoscan/framereducer → tomoscan-2.3.0.dev1/tomoscan/nexus/paths}/__init__.py +0 -0
  82. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxdetector.py +0 -0
  83. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxinstrument.py +0 -0
  84. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxmonitor.py +0 -0
  85. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxsample.py +0 -0
  86. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxsource.py +0 -0
  87. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxtomo.py +0 -0
  88. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/nexus/paths/nxtransformations.py +0 -0
  89. {tomoscan-2.3.0.dev0/tomoscan/nexus/paths → tomoscan-2.3.0.dev1/tomoscan/nexus/utils}/__init__.py +0 -0
  90. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/__init__.py +0 -0
  91. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/calculationmode.py +0 -0
  92. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/datasetscope.py +0 -0
  93. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/method.py +0 -0
  94. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/methodmode.py +0 -0
  95. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/normalization.py +0 -0
  96. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/normalization/tests/test_normalization.py +0 -0
  97. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/progress.py +0 -0
  98. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/scanbase.py +0 -0
  99. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/scanfactory.py +0 -0
  100. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/serie.py +0 -0
  101. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/series.py +0 -0
  102. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/source.py +0 -0
  103. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/test.py +0 -0
  104. {tomoscan-2.3.0.dev0/tomoscan/nexus/utils → tomoscan-2.3.0.dev1/tomoscan/tests}/__init__.py +0 -0
  105. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/conftest.py +0 -0
  106. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/datasets.py +0 -0
  107. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_drac_utils.py +0 -0
  108. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_factory.py +0 -0
  109. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_hdf5_utils.py +0 -0
  110. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_io.py +0 -0
  111. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_progress.py +0 -0
  112. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_scanbase.py +0 -0
  113. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_serie.py +0 -0
  114. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_tomoobject.py +0 -0
  115. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_utils.py +0 -0
  116. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_validator.py +0 -0
  117. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_version.py +0 -0
  118. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_volume_base.py +0 -0
  119. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/test_volume_utils.py +0 -0
  120. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tests/utils.py +0 -0
  121. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/tomoobject.py +0 -0
  122. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/__init__.py +0 -0
  123. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/decorator.py +0 -0
  124. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/drac/__init__.py +0 -0
  125. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/drac/mapper.py +0 -0
  126. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/drac/recons_vol_mapping.py +0 -0
  127. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/geometry.py +0 -0
  128. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/hdf5.py +0 -0
  129. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/io.py +0 -0
  130. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/utils/volume.py +0 -0
  131. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/validator.py +0 -0
  132. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan/volumebase.py +0 -0
  133. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan.egg-info/dependency_links.txt +0 -0
  134. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan.egg-info/entry_points.txt +0 -0
  135. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan.egg-info/requires.txt +0 -0
  136. {tomoscan-2.3.0.dev0 → tomoscan-2.3.0.dev1}/tomoscan.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tomoscan
3
- Version: 2.3.0.dev0
3
+ Version: 2.3.0.dev1
4
4
  Summary: Utility to access tomography data at ESRF
5
5
  Author-email: Henri Payno <henri.payno@esrf.fr>, Pierre Paleo <pierre.paleo@esrf.fr>, Pierre-Olivier Autran <pierre-olivier.autran@esrf.fr>, Jérôme Lesaint <jerome.lesaint@esrf.fr>, Alessandro Mirone <mirone@esrf.fr>
6
6
  License: MIT
@@ -154,6 +154,11 @@ class HDF5FrameReducer(FrameReducerBase):
154
154
  res = {}
155
155
  # res: key is serie index (first serie frame index), value is the numpy.array of the reduced frame
156
156
  infos = ReducedFramesInfos()
157
+ from tomoscan.esrf.scan.nxtomoscan import NXtomoScan # avoid cyclic import
158
+
159
+ if isinstance(self.scan, NXtomoScan):
160
+ infos.lr_flip = self.scan.detector_is_lr_flip
161
+ infos.ud_flip = self.scan.detector_is_ud_flip
157
162
 
158
163
  for series_ in raw_series:
159
164
  series_index = min(series_)
@@ -4,10 +4,17 @@ from __future__ import annotations
4
4
 
5
5
  import h5py
6
6
  import numpy
7
+ import pytest
7
8
 
8
9
  from nxtomo.application.nxtomo import ImageKey
9
10
  from tomoscan.esrf.scan.mock import MockNXtomo as _MockNXtomo
10
11
  from tomoscan.scanbase import ReducedFramesInfos
12
+ from tomoscan.esrf.scan.nxtomoscan import NXtomoScan
13
+ from nxtomo.utils.transformation import (
14
+ DetXFlipTransformation,
15
+ DetYFlipTransformation,
16
+ )
17
+ from nxtomo.nxobject.nxtransformations import NXtransformations
11
18
 
12
19
 
13
20
  class MockNXtomo(_MockNXtomo):
@@ -86,7 +93,10 @@ class MockNXtomo(_MockNXtomo):
86
93
  )
87
94
 
88
95
 
89
- def test_reduce_hdf5(tmp_path):
96
+ @pytest.mark.parametrize(
97
+ "lr_flip, ud_flip", ((False, False), (True, False), (False, True))
98
+ )
99
+ def test_reduce_hdf5(tmp_path, lr_flip, ud_flip):
90
100
  """insure calculation of dark and flats are valid for a default use case"""
91
101
  dim = 20
92
102
  folder_1 = tmp_path / "test1"
@@ -158,6 +168,8 @@ def test_reduce_hdf5(tmp_path):
158
168
  machine_current=machine_current,
159
169
  ).scan
160
170
 
171
+ patch_detector_flip(scan=scan, lr_flip=lr_flip, ud_flip=ud_flip)
172
+
161
173
  assert scan.machine_current is not None
162
174
  assert scan.exposure_time is not None
163
175
 
@@ -276,7 +288,11 @@ def test_reduce_hdf5(tmp_path):
276
288
  numpy.testing.assert_almost_equal(
277
289
  flats_infos.count_time[1], numpy.mean(flats_s2_count_time)
278
290
  )
279
- # no test on first and last but this is the same as for darks
291
+ # note: no test are done on the first and last but this is the same as for darks
292
+
293
+ # test detector flips
294
+ assert flats_infos.lr_flip == lr_flip
295
+ assert flats_infos.ud_flip == ud_flip
280
296
 
281
297
 
282
298
  def test_reduce_hdf5_fails(tmp_path):
@@ -291,3 +307,16 @@ def test_reduce_hdf5_fails(tmp_path):
291
307
  ).scan
292
308
  assert scan.compute_reduced_flats(reduced_method="first", return_info=False) == {}
293
309
  assert scan.compute_reduced_darks(reduced_method="last", return_info=False) == {}
310
+
311
+
312
+ def patch_detector_flip(scan: NXtomoScan, lr_flip: bool, ud_flip: bool):
313
+ "function that patches an NXtomo' detector flips"
314
+
315
+ mc_stas_transformation = NXtransformations()
316
+ mc_stas_transformation.add_transformation(DetYFlipTransformation(flip=lr_flip))
317
+ mc_stas_transformation.add_transformation(DetXFlipTransformation(flip=ud_flip))
318
+ mc_stas_transformation.save(
319
+ file_path=scan.master_file,
320
+ data_path="/entry/instrument/detector/transformations",
321
+ overwrite=True,
322
+ )
@@ -199,7 +199,9 @@ class ReduceFrameSaver:
199
199
  metadata_values,
200
200
  ) in self.frames_metadata.to_dict().items():
201
201
  # warning: for now we only handle list (of count_time and machine_current)
202
- if len(metadata_values) == 0:
202
+ if (not numpy.isscalar(metadata_values)) and len(
203
+ metadata_values
204
+ ) == 0:
203
205
  continue
204
206
  else:
205
207
  # save metadata
@@ -13,9 +13,17 @@ class ReducedFramesInfos:
13
13
 
14
14
  COUNT_TIME_KEY = "count_time"
15
15
 
16
+ LR_FLIP = "lr_flip"
17
+ """Save the information if the original raw frame was left-right flipped. Warning: tomoscan will only propagate this information but won't flip reduced frames saved"""
18
+
19
+ UD_FLIP = "ud_flip"
20
+ """Save the information if the original raw frame was up-down flipped. Warning: tomoscan will only propagate this information but won't flip reduced frames saved"""
21
+
16
22
  def __init__(self) -> None:
17
23
  self._count_time = []
18
24
  self._machine_current = []
25
+ self._lr_flip = None
26
+ self._ud_flip = None
19
27
 
20
28
  def __eq__(self, __o: object) -> bool:
21
29
  if isinstance(__o, dict):
@@ -32,6 +40,8 @@ class ReducedFramesInfos:
32
40
  def clear(self):
33
41
  self._count_time.clear()
34
42
  self._machine_current.clear()
43
+ self._lr_flip = None
44
+ self._ud_flip = None
35
45
 
36
46
  @property
37
47
  def count_time(self) -> list:
@@ -79,17 +89,53 @@ class ReducedFramesInfos:
79
89
  else:
80
90
  self._machine_current = list(machine_current)
81
91
 
92
+ @property
93
+ def lr_flip(self) -> bool | None:
94
+ return self._lr_flip
95
+
96
+ @lr_flip.setter
97
+ def lr_flip(self, flip: bool | None):
98
+ if not isinstance(flip, (bool, type(None))):
99
+ raise TypeError(
100
+ f"flip is expected to be None or a bool. got {type(flip)}, {flip}, {flip.dtype}"
101
+ )
102
+ self._lr_flip = flip
103
+
104
+ @property
105
+ def ud_flip(self) -> bool | None:
106
+ return self._ud_flip
107
+
108
+ @ud_flip.setter
109
+ def ud_flip(self, flip: bool | None):
110
+ if not isinstance(flip, (bool, type(None))):
111
+ raise TypeError(
112
+ f"flip is expected to be None or a bool. got {type(flip)}, {flip}, {flip.dtype}"
113
+ )
114
+ self._ud_flip = flip
115
+
82
116
  def to_dict(self) -> dict:
83
117
  res = {}
84
118
  if len(self.machine_current) > 0:
85
119
  res[self.MACHINE_ELECT_CURRENT_KEY] = self.machine_current
86
120
  if len(self.count_time) > 0:
87
121
  res[self.COUNT_TIME_KEY] = self.count_time
122
+ if self.lr_flip is not None:
123
+ res[self.LR_FLIP] = self.lr_flip
124
+ if self.ud_flip is not None:
125
+ res[self.UD_FLIP] = self.ud_flip
88
126
  return res
89
127
 
90
128
  def load_from_dict(self, my_dict: dict):
91
129
  self.machine_current = my_dict.get(self.MACHINE_ELECT_CURRENT_KEY, None)
92
130
  self.count_time = my_dict.get(self.COUNT_TIME_KEY, None)
131
+
132
+ def cast_numpy_bool(value):
133
+ if isinstance(value, numpy.ndarray):
134
+ return bool(value)
135
+ return value
136
+
137
+ self.lr_flip = cast_numpy_bool(my_dict.get(self.LR_FLIP, None))
138
+ self.ud_flip = cast_numpy_bool(my_dict.get(self.UD_FLIP, None))
93
139
  return self
94
140
 
95
141
  @staticmethod
@@ -98,6 +144,8 @@ class ReducedFramesInfos:
98
144
  raise TypeError
99
145
  my_dict.pop(ReducedFramesInfos.MACHINE_ELECT_CURRENT_KEY, None)
100
146
  my_dict.pop(ReducedFramesInfos.COUNT_TIME_KEY, None)
147
+ my_dict.pop(ReducedFramesInfos.LR_FLIP, None)
148
+ my_dict.pop(ReducedFramesInfos.UD_FLIP, None)
101
149
  return my_dict
102
150
 
103
151
  @staticmethod
@@ -119,5 +167,7 @@ class ReducedFramesInfos:
119
167
  [
120
168
  f"machine_current {self.machine_current}",
121
169
  f"count_time {self.count_time}",
170
+ f"lr_flip {self.lr_flip}",
171
+ f"ud_flip {self.ud_flip}",
122
172
  ]
123
173
  )
@@ -56,7 +56,7 @@ MAJOR = 2
56
56
  MINOR = 3
57
57
  MICRO = 0
58
58
  RELEV = "dev" # <16
59
- SERIAL = 0
59
+ SERIAL = 1
60
60
 
61
61
  date = __date__
62
62
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tomoscan
3
- Version: 2.3.0.dev0
3
+ Version: 2.3.0.dev1
4
4
  Summary: Utility to access tomography data at ESRF
5
5
  Author-email: Henri Payno <henri.payno@esrf.fr>, Pierre Paleo <pierre.paleo@esrf.fr>, Pierre-Olivier Autran <pierre-olivier.autran@esrf.fr>, Jérôme Lesaint <jerome.lesaint@esrf.fr>, Alessandro Mirone <mirone@esrf.fr>
6
6
  License: MIT
@@ -71,9 +71,6 @@ tomoscan/esrf/volume/rawvolume.py
71
71
  tomoscan/esrf/volume/singleframebase.py
72
72
  tomoscan/esrf/volume/tiffvolume.py
73
73
  tomoscan/esrf/volume/utils.py
74
- tomoscan/esrf/volume/helpers/__init__.py
75
- tomoscan/esrf/volume/helpers/single_frame_saver.py
76
- tomoscan/esrf/volume/helpers/test/test_single_frame_saver.py
77
74
  tomoscan/esrf/volume/tests/test_edfvolume.py
78
75
  tomoscan/esrf/volume/tests/test_hdf5volume.py
79
76
  tomoscan/esrf/volume/tests/test_jp2kvolume.py
@@ -1,73 +0,0 @@
1
- """module with helper ot save single frame"""
2
-
3
- from __future__ import annotations
4
-
5
- from tomoscan.esrf.volume.singleframebase import VolumeSingleFrameBase
6
-
7
-
8
- class SingleFrameSaverHelper:
9
- """
10
- Allow to save to a single file per frame structure along any axis. The volume is expected to be 3D.
11
-
12
- .. note:: This is not part of the VolumeSingleFrameBase API because we want to make it clear that way of saving is very particular
13
- and might comes with some botlnecks
14
- """
15
-
16
- def __init__(
17
- self,
18
- volume: VolumeSingleFrameBase,
19
- data_shape: tuple,
20
- dtype,
21
- cache_size: int | None = None,
22
- ) -> None:
23
- """
24
- :param volume: volume to save data for
25
- :param shape: final data shape
26
- :param dtype: data type (as a numpy data type)
27
- :param cache_size: cache of the size (in bytes). Once this size is reached then the data will be dump to disk...
28
- """
29
- if not isinstance(volume, VolumeSingleFrameBase):
30
- raise TypeError(
31
- f"volume is expected to be an instance of VolumeSingleFrameBase. Get {type(volume)}"
32
- )
33
- if not isinstance(data_shape, tuple):
34
- raise TypeError(
35
- f"shape is expected to be an instance of tuple. Get {type(data_shape)}"
36
- )
37
-
38
- self._volume = volume
39
- self._shape = data_shape
40
- self._dtype = dtype
41
- self._frame_index_to_file = None
42
- self._initialized = False
43
-
44
- def init_saver(self):
45
- self._frame_index_to_file = {}
46
- for i, frame_dumper in enumerate(
47
- self._volume.data_file_saver_generator(
48
- n_frames=self._shape[0],
49
- data_url=self._volume.data_url,
50
- overwrite=self._volume.overwrite,
51
- ),
52
- ):
53
- self._frame_index_to_file[i] = frame_dumper
54
- self._initialized = True
55
-
56
- for i in range(len(self._frame_index_to_file) - 1):
57
- assert self._frame_index_to_file[i] != self._frame_index_to_file[i + 1]
58
-
59
- def __setitem__(self, index, value):
60
- if not self._initialized:
61
- raise RuntimeError(
62
- "the helper should be initialized first. Freezing the shape. Please call 'init_saver' before dumping any data to it"
63
- )
64
- if isinstance(index, slice):
65
- # in case we are saving the full frame there is no need for any cache mecanism
66
- self._frame_index_to_file[index.start, index.stop, index.step][:] = value
67
- elif isinstance(index, (int, tuple)):
68
- # in case we are saving the full frame there is no need for any cache mecanism
69
- self._frame_index_to_file[index][:] = value
70
- else:
71
- raise NotImplementedError(
72
- f"index is expected to be an instance of int or a tuple of int. Got {type(index)}"
73
- )
@@ -1,67 +0,0 @@
1
- import os
2
- import pytest
3
- import numpy
4
- from tomoscan.esrf.volume.helpers.single_frame_saver import SingleFrameSaverHelper
5
- from tomoscan.esrf.volume.edfvolume import EDFVolume
6
- from tomoscan.esrf.volume.jp2kvolume import JP2KVolume, has_glymur, has_minimal_openjpeg
7
- from tomoscan.esrf.volume.tiffvolume import TIFFVolume, has_tifffile
8
- from tomoscan.esrf.volume.mock import create_volume
9
-
10
-
11
- volume_constructors = [
12
- EDFVolume,
13
- ]
14
- if has_tifffile:
15
- volume_constructors.append(TIFFVolume)
16
- if has_glymur and has_minimal_openjpeg:
17
- volume_constructors.append(JP2KVolume)
18
-
19
-
20
- @pytest.mark.parametrize("cache_size", (None, 16, 256, 4096, 65536, numpy.inf))
21
- @pytest.mark.parametrize("dtype", (numpy.uint8, numpy.uint16, numpy.float128))
22
- @pytest.mark.parametrize("axis", (0, 1, 2))
23
- @pytest.mark.parametrize("volume_constructor", volume_constructors)
24
- def test_SingleFrameSaverHelper(tmp_path, axis, dtype, volume_constructor, cache_size):
25
- """Test SingleFrameSaverHelper along all the axis and with all kind of 'single frame' volume"""
26
-
27
- data = create_volume(frame_dims=(100, 100), z_size=100)
28
- # rescale data. Because for example jp2k is rescaling it by default
29
- if dtype is numpy.float128:
30
- max_val = numpy.finfo(dtype).max
31
- else:
32
- max_val = numpy.iinfo(dtype).max
33
- data = data / data.max() * max_val
34
- data = data.astype(dtype)
35
-
36
- output_folder = os.path.join(tmp_path, volume_constructor.DEFAULT_DATA_EXTENSION)
37
- volume = volume_constructor(
38
- folder=output_folder,
39
- )
40
-
41
- data_saver_helper = SingleFrameSaverHelper(
42
- volume=volume,
43
- data_shape=(100, 100, 100),
44
- dtype=dtype,
45
- cache_size=cache_size,
46
- )
47
- data_saver_helper.init_saver()
48
-
49
- for i in range(100):
50
- if axis == 0:
51
- data_saver_helper[i] = data[i]
52
- elif axis == 1:
53
- data_saver_helper[:, i] = data[:, i]
54
- elif axis == 2:
55
- data_saver_helper[:, :, i] = data[:, :, i]
56
-
57
- # note: saving is done directly on the file. So this will not affect the volume.data
58
- # except if loaded and stored
59
- volume_data = volume.load_data(store=False)
60
-
61
- assert data.shape == volume_data.shape
62
- assert data.dtype == volume_data.dtype
63
-
64
- numpy.testing.assert_array_equal(
65
- data,
66
- volume_data,
67
- )
File without changes
File without changes
File without changes
File without changes
File without changes