nxtomomill 2.1.0.dev2__tar.gz → 2.1.0.dev4__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 (187) hide show
  1. {nxtomomill-2.1.0.dev2/nxtomomill.egg-info → nxtomomill-2.1.0.dev4}/PKG-INFO +3 -2
  2. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/dxfile2nx.py +15 -1
  3. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/h52nx.py +19 -12
  4. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/patch_nx.py +4 -1
  5. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/split_nxfile.py +18 -2
  6. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/z_concatenate_scans.py +3 -1
  7. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/dxfile/dxfileconverter.py +39 -12
  8. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/dxfile/tests/test_dxfile.py +56 -11
  9. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/edf/edfconverter.py +9 -1
  10. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fscan/fscanconverter.py +1 -3
  11. nxtomomill-2.1.0.dev4/nxtomomill/converter/hdf5/acquisition/_bliss_activeconfig.py +34 -0
  12. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/baseacquisition.py +29 -12
  13. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/multitomo.py +86 -9
  14. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/standardacquisition.py +201 -53
  15. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition.py +37 -0
  16. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_legacy.py +1 -0
  17. nxtomomill-2.1.0.dev4/nxtomomill/converter/hdf5/acquisition/tests/test_multitomo_zseries.py +109 -0
  18. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_multitomoacquisition.py +9 -0
  19. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/bliss_scan_type.py +4 -2
  20. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/zseriesacquisition.py +10 -3
  21. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisitionConstructor.py +12 -4
  22. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/hdf5converter.py +10 -6
  23. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/post_processing/dark_flat_copy.py +4 -0
  24. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/tests/test_frame_flip.py +7 -5
  25. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/tests/test_hdf5converter.py +35 -12
  26. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/confighandler.py +3 -0
  27. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/tests/test_confighandler.py +3 -0
  28. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/dx2nx.py +23 -2
  29. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/detector_section.py +5 -2
  30. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/edf2nx.py +1 -0
  31. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/general_section.py +14 -0
  32. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/h52nx.py +2 -0
  33. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/datasets.py +4 -5
  34. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/flat_reducer.py +19 -4
  35. nxtomomill-2.1.0.dev4/nxtomomill/utils/h5pyutils.py +219 -0
  36. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/hdf5.py +47 -21
  37. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/nexus.py +14 -4
  38. nxtomomill-2.1.0.dev4/nxtomomill/utils/tests/test_h5pyutils.py +209 -0
  39. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/tests/test_utils.py +15 -0
  40. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/utils.py +18 -8
  41. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/version.py +1 -1
  42. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4/nxtomomill.egg-info}/PKG-INFO +3 -2
  43. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill.egg-info/SOURCES.txt +3 -10
  44. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill.egg-info/requires.txt +2 -1
  45. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill.egg-info/top_level.txt +1 -0
  46. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/pyproject.toml +2 -1
  47. nxtomomill-2.1.0.dev2/nxtomomill/nexus/__init__.py +0 -8
  48. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxdetector.py +0 -10
  49. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxinstrument.py +0 -10
  50. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxmonitor.py +0 -10
  51. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxobject.py +0 -10
  52. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxsample.py +0 -10
  53. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxsource.py +0 -10
  54. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxtomo.py +0 -10
  55. nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxtransformations.py +0 -10
  56. nxtomomill-2.1.0.dev2/nxtomomill/nexus/utils.py +0 -10
  57. nxtomomill-2.1.0.dev2/nxtomomill/utils/h5pyutils.py +0 -58
  58. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/LICENSE +0 -0
  59. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/README.md +0 -0
  60. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/doc/conf.py +0 -0
  61. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/__init__.py +0 -0
  62. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/__main__.py +0 -0
  63. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/__init__.py +0 -0
  64. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/blissfluo2nx.py +0 -0
  65. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/blissfluoconfig.py +0 -0
  66. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/edf2nx.py +0 -0
  67. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/edf2nx_check.py +0 -0
  68. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/edfconfig.py +0 -0
  69. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/fluo2nx.py +0 -0
  70. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/fluoconfig.py +0 -0
  71. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/fscan2nx.py +0 -0
  72. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/h5config.py +0 -0
  73. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/nxcopy.py +0 -0
  74. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_bliss_fluo2nx_app.py +0 -0
  75. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_dxfile2nx_app.py +0 -0
  76. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_edf2nx_app.py +0 -0
  77. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_edf_config_app.py +0 -0
  78. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_fluo2nx_app.py +0 -0
  79. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_h52nx_app.py +0 -0
  80. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_h5_config_app.py +0 -0
  81. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_nx_copy.py +0 -0
  82. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_patch_nx_app.py +0 -0
  83. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/tests/test_split_nxfile_app.py +0 -0
  84. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/app/zstages2nxs.py +0 -0
  85. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/__init__.py +0 -0
  86. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/baseconverter.py +0 -0
  87. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/dxfile/__init__.py +0 -0
  88. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/edf/__init__.py +0 -0
  89. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/edf/checks.py +0 -0
  90. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/edf/tests/test_checks.py +0 -0
  91. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/edf/tests/test_edf2nx.py +0 -0
  92. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/edf/tests/test_edf2nx_check.py +0 -0
  93. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/__init__.py +0 -0
  94. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/blissfluoscan.py +0 -0
  95. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/fluoconverter.py +0 -0
  96. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/fluoscan.py +0 -0
  97. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/tests/__init__.py +0 -0
  98. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/tests/test_fluoscan2D.py +0 -0
  99. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fluo/tests/test_fluoscan3D.py +0 -0
  100. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/fscan/__init__.py +0 -0
  101. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/__init__.py +0 -0
  102. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/__init__.py +0 -0
  103. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/backandforth.py +0 -0
  104. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/blisstomoconfig.py +0 -0
  105. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/pcotomoacquisition.py +0 -0
  106. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/bliss_tomo_datasets.py +0 -0
  107. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition_utils.py +0 -0
  108. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_back_and_forth.py +0 -0
  109. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_bliss_tomo_config.py +0 -0
  110. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/tests/test_holotomo.py +0 -0
  111. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/__init__.py +0 -0
  112. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/_context.py +0 -0
  113. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/_keys.py +0 -0
  114. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/_scan_type_finder.py +0 -0
  115. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/detector.py +0 -0
  116. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/machine_current.py +0 -0
  117. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/series.py +0 -0
  118. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/acquisition/utils/timestamps.py +0 -0
  119. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/post_processing/__init__.py +0 -0
  120. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/tests/test_h52nx_utils.py +0 -0
  121. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/hdf5/utils.py +0 -0
  122. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/converter/version.py +0 -0
  123. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/__init__.py +0 -0
  124. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/__init__.py +0 -0
  125. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/configbase.py +0 -0
  126. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/dxconfig.py +0 -0
  127. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/edfconfig.py +0 -0
  128. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/fluoconfig.py +0 -0
  129. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/hdf5config.py +0 -0
  130. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/config/tests/__init__.py +0 -0
  131. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/tests/test_frame_group.py +0 -0
  132. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/io/tests/utils.py +0 -0
  133. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/__init__.py +0 -0
  134. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/ConfigBase.py +0 -0
  135. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/FrmFlatToNestedBase.py +0 -0
  136. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/NestedModelBase.py +0 -0
  137. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/__init__.py +0 -0
  138. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/general_section.py +0 -0
  139. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/instrument_section.py +0 -0
  140. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/base/source_section.py +0 -0
  141. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/blissfluo2nx/__init__.py +0 -0
  142. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/blissfluo2nx/blissfluo2nx.py +0 -0
  143. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/blissfluo2nx/general_section.py +0 -0
  144. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/__init__.py +0 -0
  145. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/dark_and_flat_section.py +0 -0
  146. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/general_section.py +0 -0
  147. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/keys_section.py +0 -0
  148. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/sample_section.py +0 -0
  149. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/edf2nx/unit_section.py +0 -0
  150. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/fluo2nx/__init__.py +0 -0
  151. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/fluo2nx/fluo2nx.py +0 -0
  152. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/fluo2nx/general_section.py +0 -0
  153. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/FrameGroup.py +0 -0
  154. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/__init__.py +0 -0
  155. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/_acquisitionstep.py +0 -0
  156. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/_context.py +0 -0
  157. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/entries_and_title_section.py +0 -0
  158. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/extra_params_section.py +0 -0
  159. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/frame_type_section.py +0 -0
  160. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/keys_section.py +0 -0
  161. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/h52nx/multitomo_section.py +0 -0
  162. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/tests/test_context.py +0 -0
  163. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/tests/test_edf2nx_model.py +0 -0
  164. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/tests/test_fluo2nx_model.py +0 -0
  165. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/tests/test_h52nx_model.py +0 -0
  166. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/tests/test_io_utils.py +0 -0
  167. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/models/utils.py +0 -0
  168. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/settings.py +0 -0
  169. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/test.py +0 -0
  170. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/__init__.py +0 -0
  171. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/resources/__init__.py +0 -0
  172. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/resources/edf2nx_config_files/__init__.py +0 -0
  173. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/resources/fluo2nx_config_files/__init__.py +0 -0
  174. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/resources/h52nx_config_files/__init__.py +0 -0
  175. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/test_version.py +0 -0
  176. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/utils/__init__.py +0 -0
  177. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/utils/bliss.py +0 -0
  178. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/tests/utils/dxfile.py +0 -0
  179. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/__init__.py +0 -0
  180. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/_os.py +0 -0
  181. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/io.py +0 -0
  182. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/pintutils.py +0 -0
  183. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/tests/test_flat_reducer.py +0 -0
  184. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill/utils/tests/test_nexus_utils.py +0 -0
  185. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill.egg-info/dependency_links.txt +0 -0
  186. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/nxtomomill.egg-info/entry_points.txt +0 -0
  187. {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nxtomomill
3
- Version: 2.1.0.dev2
3
+ Version: 2.1.0.dev4
4
4
  Summary: applications and library to convert raw format to NXtomo format
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:
@@ -55,13 +55,14 @@ License-File: LICENSE
55
55
  Requires-Dist: numpy
56
56
  Requires-Dist: h5py>=3.0
57
57
  Requires-Dist: silx>=2.0
58
- Requires-Dist: nxtomo>=3.0.0dev0
58
+ Requires-Dist: nxtomo>=3.1.0dev1
59
59
  Requires-Dist: pint
60
60
  Requires-Dist: packaging
61
61
  Requires-Dist: tomoscan[full]>=2.2.0a4
62
62
  Requires-Dist: tqdm
63
63
  Requires-Dist: pydantic
64
64
  Requires-Dist: eval_type_backport; python_version < "3.10"
65
+ Requires-Dist: platformdirs
65
66
  Provides-Extra: test
66
67
  Requires-Dist: pytest; extra == "test"
67
68
  Requires-Dist: python-gitlab; extra == "test"
@@ -103,9 +103,16 @@ def main(argv):
103
103
  "--fov",
104
104
  "--field-of-view",
105
105
  default=None,
106
- help="field of view. Can be Full or Half",
106
+ help="DEPRECATED: field of view as string. Use --half-acquisition instead.",
107
107
  dest="field_of_view",
108
108
  )
109
+ parser.add_argument(
110
+ "--half-acquisition",
111
+ help="Use half acquisition instead of full acquisition.",
112
+ action="store_true",
113
+ dest="half_acquisition",
114
+ default=None,
115
+ )
109
116
  # as distance is not stored in the dxfile and requested for paganin
110
117
  # we provide some default value
111
118
  parser.add_argument(
@@ -139,6 +146,12 @@ def main(argv):
139
146
  )
140
147
  options = parser.parse_args(argv[1:])
141
148
 
149
+ if options.field_of_view is not None and options.half_acquisition is not None:
150
+ raise ValueError(
151
+ "Cannot use --field-of-view and --half-acquisition together. "
152
+ "Please use --half-acquisition."
153
+ )
154
+
142
155
  distance = options.distance
143
156
  if distance is not None:
144
157
  distance = float(options.distance)
@@ -163,6 +176,7 @@ def main(argv):
163
176
  scan_range=convert_2elmts__tuple_to_float(options.scan_range),
164
177
  pixel_size=_get_pixel_size(options.pixel_size),
165
178
  field_of_view=options.field_of_view,
179
+ half_acquisition=options.half_acquisition,
166
180
  distance=distance,
167
181
  overwrite=options.overwrite,
168
182
  duplicate_data=options.duplicate_data,
@@ -11,7 +11,6 @@ For a complete tutorial you can have a look at: :ref:`Tomoh52nx`
11
11
 
12
12
  import argparse
13
13
  import logging
14
- import os
15
14
 
16
15
  from tqdm import tqdm
17
16
 
@@ -126,6 +125,11 @@ def main(argv):
126
125
  "parse raw data to find this information.",
127
126
  default=None,
128
127
  )
128
+ parser.add_argument(
129
+ "--half-acquisition",
130
+ help="If the scan is an half-acquisition (CoR at the borders of projections).",
131
+ default=None,
132
+ )
129
133
  parser.add_argument(
130
134
  "--no-input",
131
135
  "--no-input-for-missing-information",
@@ -206,9 +210,10 @@ def main(argv):
206
210
  help="Y pixel size key to read",
207
211
  )
208
212
  parser.add_argument(
209
- "--read-mode",
213
+ "--open_mode_for_reading",
214
+ "--open-mode-for-reading",
210
215
  default="robust",
211
- help="Options when reading bliss file. Valid values are 'locking', 'swmr' and 'safe'. 'robust' is the default h5py read mode.",
216
+ help="Options when reading bliss file. Valid values are 'robust' or 'safe'. 'robust' is the default h5py read mode.",
212
217
  )
213
218
  # scan titles
214
219
  parser.add_argument(
@@ -301,21 +306,23 @@ def main(argv):
301
306
  help="file containing the full configuration to convert from h5 "
302
307
  "bliss to nexus",
303
308
  )
304
-
309
+ parser.add_argument(
310
+ "--use-abs-path-for-vds",
311
+ "--abs-path-for-vds",
312
+ "--use_abs_path_for_vds",
313
+ "--use-abs-path-for-vds",
314
+ default=False,
315
+ action="store_true",
316
+ help="Generated NXtomo file contains relative path by default. "
317
+ "Sometime relative link cannot be solved (GPFS vs NFS). "
318
+ "In this case you might be forced to use absolute path.",
319
+ )
305
320
  options = parser.parse_args(argv[1:])
306
321
  if options.request_input:
307
322
  callback_det_sel = _ask_for_selecting_detector
308
323
  else:
309
324
  callback_det_sel = None
310
325
 
311
- # define reading mode
312
- read_mode = os.getenv("NXTOMOMILL_HDF5_READ_MODE", "robust")
313
- if options.read_mode not in ("robust", "safe", "swmr"):
314
- raise ValueError(
315
- f"Invalid read mode: {read_mode}. Valid values are 'robust', 'safe' and 'swmr'"
316
- )
317
- os.environ["NXTOMOMILL_HDF5_READ_MODE"] = options.read_mode
318
-
319
326
  try:
320
327
  configuration_handler = TomoHDF5ConfigHandler(options)
321
328
  except Exception:
@@ -253,7 +253,9 @@ def main(argv):
253
253
  "No url provided for dark or flats or frame type to "
254
254
  "modify. Nothing to be done."
255
255
  )
256
- elif not utils.is_nx_tomo_entry(file_path=options.file_path, entry=options.entry):
256
+ elif not utils.is_nx_tomo_entry(
257
+ file_path=options.file_path, entry=options.entry, open_mode_for_reading="safe"
258
+ ):
257
259
  _logger.error(
258
260
  f"{options.entry}@{options.file_path} is not recognized as a valid NXTomo entry."
259
261
  )
@@ -292,4 +294,5 @@ def main(argv):
292
294
  flats_end=flat_end_url,
293
295
  embed_data=True,
294
296
  logger=_logger,
297
+ open_mode_for_reading="robust",
295
298
  )
@@ -47,7 +47,17 @@ def main(argv):
47
47
  help="Make all NXtomo free of any external link. As a result this will duplicate data",
48
48
  nargs="?",
49
49
  )
50
-
50
+ parser.add_argument(
51
+ "--use_abs_path_for_vds",
52
+ "--use-abs-path-for-vds",
53
+ "--abs-path-for-vds",
54
+ "--abs_path_for_vds",
55
+ default=False,
56
+ action="store_true",
57
+ help="Generated NXtomo file contains relative path by default. "
58
+ "Sometime relative link cannot be solved (GPFS vs NFS). "
59
+ "In this case you might be forced to use absolute path.",
60
+ )
51
61
  options = parser.parse_args(argv[1:])
52
62
  output_file_pattern = options.output_file_pattern
53
63
  if "{input_file_name}" in output_file_pattern:
@@ -61,6 +71,7 @@ def main(argv):
61
71
  input_file=options.input_file,
62
72
  output_file_pattern=output_file_pattern,
63
73
  overwrite=options.overwrite,
74
+ force_abs_path=options.use_abs_path_for_vds,
64
75
  )
65
76
 
66
77
 
@@ -69,11 +80,13 @@ def split(
69
80
  output_file_pattern: str,
70
81
  overwrite: bool = False,
71
82
  duplicate_data: bool = False,
83
+ force_abs_path: bool = False,
72
84
  ) -> tuple:
73
85
  """
74
86
  :param input_file: path to the file to be splitted
75
87
  :param output_file_pattern: pattern of the file to create. Must contain either `{entry_name}` or `{index}`
76
88
  :param overwrite: can we overwrite output file if alread exists
89
+ :param force_abs_path: should the generated NXtomo contains absolute path (True) or relative path (False, default)
77
90
 
78
91
  :return: tuple of identifier of all the NXtomo generated
79
92
  """
@@ -128,7 +141,10 @@ def split(
128
141
  if dirname and not os.path.exists(dirname):
129
142
  os.makedirs(dirname)
130
143
  nx_tomo.save(
131
- file_path=output_file, data_path=entry, overwrite=overwrite
144
+ file_path=output_file,
145
+ data_path=entry,
146
+ overwrite=overwrite,
147
+ use_abs_path_for_vds=force_abs_path,
132
148
  )
133
149
  result.append(NXtomoScan(output_file, entry))
134
150
 
@@ -209,7 +209,9 @@ def main(argv):
209
209
  if dummy_frame is None:
210
210
  if len(nxt.instrument.detector.data) > 0:
211
211
  # create empty frame to give it to the 'invalid_nxt' NXtomo later
212
- with DatasetReader(nxt.instrument.detector.data[0]) as raw_data:
212
+ with DatasetReader(
213
+ nxt.instrument.detector.data[0], open_mode_for_reading="safe"
214
+ ) as raw_data:
213
215
  data_type = raw_data.dtype
214
216
  # FIXME: avoid keeping some file open. not clear why this is needed
215
217
  raw_data = None
@@ -49,6 +49,7 @@ def from_dx_to_nx(
49
49
  scan_range: tuple = (0.0, 180.0),
50
50
  pixel_size=(None, None),
51
51
  field_of_view: FieldOfView | str | None = None,
52
+ half_acquisition: bool | None = None,
52
53
  distance: float | None = None,
53
54
  overwrite: bool = True,
54
55
  energy: float | None = None,
@@ -84,6 +85,7 @@ def from_dx_to_nx(
84
85
  configuration.scan_range = scan_range
85
86
  configuration.pixel_size = pixel_size
86
87
  configuration.field_of_view = field_of_view
88
+ configuration.half_acquisition = half_acquisition
87
89
  configuration.sample_detector_distance = distance
88
90
  configuration.overwrite = overwrite
89
91
  configuration.energy = energy
@@ -143,7 +145,7 @@ class _DxFileToNxConverter(BaseConverter):
143
145
  output_file = os.path.join(
144
146
  os.path.dirname(input_file),
145
147
  os.path.basename(input_file_basename)
146
- + self._configuration.file_extension,
148
+ + self._configuration.file_extension.value,
147
149
  )
148
150
  else:
149
151
  output_file = os.path.abspath(self.output_file)
@@ -200,6 +202,10 @@ class _DxFileToNxConverter(BaseConverter):
200
202
  def field_of_view(self) -> FieldOfView | None:
201
203
  return self._configuration.field_of_view
202
204
 
205
+ @property
206
+ def half_acquisition(self) -> bool | None:
207
+ return self._configuration.half_acquisition
208
+
203
209
  @property
204
210
  def energy(self) -> float | None:
205
211
  return self._configuration.energy
@@ -281,12 +287,15 @@ class _DxFileToNxConverter(BaseConverter):
281
287
  detector_grp["y_pixel_size"] = y_pixel_size
282
288
  detector_grp["y_pixel_size"].attrs["units"] = "m"
283
289
  # field of view
284
- if self.field_of_view is not None:
290
+ if self.field_of_view is not None or self.half_acquisition is not None:
285
291
  with HDF5File(self.output_file, mode="a") as h5f:
286
292
  root_grp = h5f.require_group(self.output_entry)
287
293
  instrument_grp = root_grp.require_group("instrument")
288
294
  detector_grp = instrument_grp.require_group("detector")
289
- detector_grp["field_of_view"] = self.field_of_view.value
295
+ if self.field_of_view is not None:
296
+ detector_grp["field_of_view"] = self.field_of_view.value
297
+ if self.half_acquisition is not None:
298
+ detector_grp["half_acquisition"] = self.half_acquisition
290
299
  # distance
291
300
  if self._configuration.sample_detector_distance is None:
292
301
  # if value not set by the user let read it
@@ -329,7 +338,9 @@ class _DxFileToNxConverter(BaseConverter):
329
338
  self._copy_count_time()
330
339
 
331
340
  # start time
332
- with EntryReader(self.input_root_url) as input_entry:
341
+ with EntryReader(
342
+ self.input_root_url, open_mode_for_reading="safe"
343
+ ) as input_entry:
333
344
  if "file_creation_datetime" in input_entry:
334
345
  with HDF5File(self.output_file, mode="a") as h5f:
335
346
  root_grp = h5f.require_group(self.output_entry)
@@ -365,7 +376,9 @@ class _DxFileToNxConverter(BaseConverter):
365
376
  f"Failed to get 'count_time' / 'exposure_period'. reason is {e}"
366
377
  )
367
378
 
368
- with EntryReader(self.input_root_url) as input_entry:
379
+ with EntryReader(
380
+ self.input_root_url, open_mode_for_reading="safe"
381
+ ) as input_entry:
369
382
  if "measurement" in input_entry:
370
383
  measurement_grp = input_entry["measurement"]
371
384
  if "detector" in measurement_grp:
@@ -469,7 +482,9 @@ class _DxFileToNxConverter(BaseConverter):
469
482
  n_proj = 0
470
483
  # handle darks
471
484
  try:
472
- with DatasetReader(self._data_darks_url) as dark_dataset:
485
+ with DatasetReader(
486
+ self._data_darks_url, open_mode_for_reading="safe"
487
+ ) as dark_dataset:
473
488
  n_dark = dark_dataset.shape[0]
474
489
  # FIXME: avoid keeping some file open. not clear why this is needed
475
490
  dark_dataset = None
@@ -491,7 +506,9 @@ class _DxFileToNxConverter(BaseConverter):
491
506
 
492
507
  # handle flats
493
508
  try:
494
- with DatasetReader(self._data_flats_url) as flat_dataset:
509
+ with DatasetReader(
510
+ self._data_flats_url, open_mode_for_reading="safe"
511
+ ) as flat_dataset:
495
512
  n_flat = flat_dataset.shape[0]
496
513
  # FIXME: avoid keeping some file open. not clear why this is needed
497
514
  flat_dataset = None
@@ -513,7 +530,9 @@ class _DxFileToNxConverter(BaseConverter):
513
530
 
514
531
  # handle projections
515
532
  try:
516
- with DatasetReader(self._data_proj_url) as proj_dataset:
533
+ with DatasetReader(
534
+ self._data_proj_url, open_mode_for_reading="safe"
535
+ ) as proj_dataset:
517
536
  n_proj = proj_dataset.shape[0]
518
537
  # FIXME: avoid keeping some file open. not clear why this is needed
519
538
  proj_dataset = None
@@ -554,7 +573,9 @@ class _DxFileToNxConverter(BaseConverter):
554
573
  self._path_nxtomo_attrs(root_grp)
555
574
 
556
575
  def _read_sample_detector_distance(self):
557
- with EntryReader(self.input_root_url) as input_entry:
576
+ with EntryReader(
577
+ self.input_root_url, open_mode_for_reading="safe"
578
+ ) as input_entry:
558
579
  path = "/".join(
559
580
  ("measurement", "instrument", "sample", "setup", "detector_distance")
560
581
  )
@@ -568,7 +589,9 @@ class _DxFileToNxConverter(BaseConverter):
568
589
  return distance * unit
569
590
 
570
591
  def _read_energy(self):
571
- with EntryReader(self.input_root_url) as input_entry:
592
+ with EntryReader(
593
+ self.input_root_url, open_mode_for_reading="safe"
594
+ ) as input_entry:
572
595
  path = "/".join(("measurement", "instrument", "source", "energy"))
573
596
  dataset = input_entry[path]
574
597
  energy = float(h5py_read_dataset(dataset))
@@ -580,7 +603,9 @@ class _DxFileToNxConverter(BaseConverter):
580
603
  return energy * unit
581
604
 
582
605
  def _read_x_pixel_size(self):
583
- with EntryReader(self.input_root_url) as input_entry:
606
+ with EntryReader(
607
+ self.input_root_url, open_mode_for_reading="safe"
608
+ ) as input_entry:
584
609
  path = "/".join(
585
610
  ("measurement", "instrument", "detector", "actual_pixel_size_x")
586
611
  )
@@ -594,7 +619,9 @@ class _DxFileToNxConverter(BaseConverter):
594
619
  return pixel_size * unit
595
620
 
596
621
  def _read_y_pixel_size(self):
597
- with EntryReader(self.input_root_url) as input_entry:
622
+ with EntryReader(
623
+ self.input_root_url, open_mode_for_reading="safe"
624
+ ) as input_entry:
598
625
  path = "/".join(
599
626
  ("measurement", "instrument", "detector", "actual_pixel_size_y")
600
627
  )
@@ -1,16 +1,18 @@
1
1
  # coding: utf-8
2
2
 
3
3
  import os
4
+ import h5py
4
5
  import pytest
5
6
  import numpy
6
7
 
7
- from nxtomomill import converter
8
+ from nxtomomill.converter.dxfile.dxfileconverter import from_dx_config_to_nx
9
+ from nxtomomill.models.dx2nx import DX2nxModel
8
10
  from nxtomomill.tests.utils.dxfile import MockDxFile
9
11
 
10
12
  from tomoscan.esrf.scan.nxtomoscan import NXtomoScan
11
13
  from tomoscan.validator import is_valid_for_reconstruction
12
14
 
13
- from silx.io.utils import get_data
15
+ from silx.io.utils import get_data, h5py_read_dataset
14
16
 
15
17
 
16
18
  @pytest.mark.parametrize("duplicate_data", (True, False))
@@ -32,11 +34,13 @@ def test_dx_file_conversion(tmp_path, duplicate_data):
32
34
 
33
35
  output_file = os.path.join(folder, "dxfile.nx")
34
36
 
35
- results = converter.from_dx_to_nx(
37
+ config = DX2nxModel(
36
38
  input_file=dxfile_path,
37
39
  output_file=output_file,
38
40
  duplicate_data=duplicate_data,
39
41
  )
42
+
43
+ results = from_dx_config_to_nx(config)
40
44
  assert len(results) == 1
41
45
  assert os.path.exists(output_file)
42
46
  _, entry = results[0]
@@ -62,17 +66,58 @@ def test_dx_file_conversion(tmp_path, duplicate_data):
62
66
 
63
67
  # if overwrite not requested should fail on reprocessing
64
68
  with pytest.raises(OSError):
65
- converter.from_dx_to_nx(
69
+ from_dx_config_to_nx(
70
+ DX2nxModel(
71
+ input_file=dxfile_path,
72
+ output_file=output_file,
73
+ duplicate_data=duplicate_data,
74
+ overwrite=False,
75
+ )
76
+ )
77
+
78
+ # if overwrite requested should succeed
79
+ from_dx_config_to_nx(
80
+ DX2nxModel(
66
81
  input_file=dxfile_path,
67
82
  output_file=output_file,
68
83
  duplicate_data=duplicate_data,
69
- overwrite=False,
84
+ overwrite=True,
70
85
  )
86
+ )
71
87
 
72
- # if overwrite requested should succeed
73
- converter.from_dx_to_nx(
74
- input_file=dxfile_path,
75
- output_file=output_file,
76
- overwrite=True,
77
- duplicate_data=duplicate_data,
88
+
89
+ def test_dx_file_conversion_half_acquisition(tmp_path):
90
+ folder = tmp_path / "test_dx_file_conversion_half_acquisition"
91
+ folder.mkdir()
92
+ dxfile_path = os.path.join(folder, "dxfile.h5")
93
+
94
+ n_projections = 10
95
+ n_darks = 1
96
+ n_flats = 1
97
+ MockDxFile(
98
+ file_path=dxfile_path,
99
+ n_projection=n_projections,
100
+ n_darks=n_darks,
101
+ n_flats=n_flats,
78
102
  )
103
+
104
+ output_file = os.path.join(folder, "dxfile_half.nx")
105
+
106
+ results = from_dx_config_to_nx(
107
+ DX2nxModel(
108
+ input_file=dxfile_path,
109
+ output_file=output_file,
110
+ half_acquisition=True,
111
+ )
112
+ )
113
+ assert len(results) == 1
114
+ assert os.path.exists(output_file)
115
+
116
+ with h5py.File(output_file, "r") as h5f:
117
+ assert h5py_read_dataset(
118
+ h5f["entry0000/instrument/detector/half_acquisition"]
119
+ ) is numpy.bool(True)
120
+ assert (
121
+ h5py_read_dataset(h5f["entry0000/instrument/detector/field_of_view"])
122
+ == "Half"
123
+ )
@@ -1000,16 +1000,24 @@ def __process(
1000
1000
  output_grp["/entry/instrument"].attrs["NX_class"] = "NXinstrument"
1001
1001
  output_grp["/entry/instrument/detector"].attrs["NX_class"] = "NXdetector"
1002
1002
  output_grp["/entry/instrument/detector/data"].attrs["interpretation"] = "image"
1003
- if configuration.field_of_view is not None:
1003
+ if configuration.half_acquisition is not None:
1004
+ half_acquisition = configuration.half_acquisition
1005
+ field_of_view = "Half" if half_acquisition else "Full"
1006
+ elif configuration.field_of_view is not None:
1004
1007
  field_of_view = configuration.field_of_view
1008
+ half_acquisition = field_of_view is FieldOfView.HALF
1005
1009
  elif abs(scan.scan_range) == 180:
1006
1010
  field_of_view = "Full"
1011
+ half_acquisition = False
1007
1012
  elif abs(scan.scan_range) == 360:
1008
1013
  field_of_view = "Half"
1014
+ half_acquisition = True
1009
1015
 
1010
1016
  if field_of_view is not None:
1011
1017
  field_of_view = FieldOfView(field_of_view)
1012
1018
  output_grp["/entry/instrument/detector/field_of_view"] = field_of_view.value
1019
+ if half_acquisition is not None:
1020
+ output_grp["/entry/instrument/detector/half_acquisition"] = half_acquisition
1013
1021
 
1014
1022
  output_grp["/entry/sample"].attrs["NX_class"] = "NXsample"
1015
1023
  output_grp["/entry/definition"] = "NXtomo"
@@ -125,9 +125,7 @@ def from_fscan_to_nx(
125
125
  )
126
126
  my_nxtomo.sample.rotation_angle = np.concatenate(rotation_angles) * _ureg.degree
127
127
 
128
- my_nxtomo.instrument.detector.field_of_view = (
129
- "Half" if (halftomo and do_360) else "Full"
130
- )
128
+ my_nxtomo.instrument.detector.half_acquisition = halftomo and do_360
131
129
  my_nxtomo.instrument.detector.x_pixel_size = (
132
130
  my_nxtomo.instrument.detector.y_pixel_size
133
131
  ) = (6.5 * 1e-6)
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ import h5py
4
+ from silx.io.utils import h5py_read_dataset
5
+
6
+ __all__ = [
7
+ "BlissActiveConfig",
8
+ ]
9
+
10
+
11
+ class BlissActiveConfig:
12
+ """
13
+ hold the bliss active config. Can retrieve the 'tomo_detector' that contains information about the optic
14
+ """
15
+
16
+ def __init__(self) -> None:
17
+ self._tomo_detector: None | tuple[str, ...] = None
18
+
19
+ @property
20
+ def tomo_detector(self) -> tuple[str, ...] | None:
21
+ return self._tomo_detector
22
+
23
+ @staticmethod
24
+ def from_hdf5_group(group: h5py.Group):
25
+ """
26
+ Create an instance of 'BlissActiveConfig' from a group (containing the bliss active configuration).
27
+ """
28
+ if not isinstance(group, h5py.Group):
29
+ raise TypeError
30
+
31
+ bliss_config = BlissActiveConfig()
32
+ if "tomo_detector" in group:
33
+ bliss_config._tomo_detector = h5py_read_dataset(group["tomo_detector"])
34
+ return bliss_config
@@ -64,12 +64,15 @@ class BaseAcquisition:
64
64
  )
65
65
 
66
66
  _INSTRUMENT_NAME_PATH = (
67
+ "instrument/name",
67
68
  "technique/saving/beamline",
68
69
  "instrument/title",
69
70
  )
70
71
 
71
72
  _FOV_PATH = "technique/scan/field_of_view"
72
73
 
74
+ _HALF_ACQUISITION = "technique/scan/half_acquisition"
75
+
73
76
  _NB_LOOP_PATH = ("technique/scan/nb_loop", "technique/proj/nb_loop")
74
77
 
75
78
  _NB_TOMO_PATH = ("technique/scan/nb_tomo", "technique/proj/nb_tomo")
@@ -98,14 +101,10 @@ class BaseAcquisition:
98
101
 
99
102
  _SOURCE_NAME = ("instrument/machine/name",)
100
103
 
101
- _BEAMLINE_NAME = (
102
- "instrument/name",
103
- "instrument/title",
104
- )
105
-
106
104
  _SOURCE_TYPE = ("instrument/machine/type",)
107
105
 
108
106
  _FRAME_FLIP_PATHS = (
107
+ "instrument/{active_config_tomo_detector}/data_axes", # note: data_axes are stored in the optic and not in the camera name.
109
108
  "technique/detector/{detector_name}/flipping",
110
109
  "technique/detector/flipping",
111
110
  )
@@ -203,7 +202,7 @@ class BaseAcquisition:
203
202
  if self.configuration.single_file or not divide_sub_files:
204
203
  en_output_file = self.configuration.output_file
205
204
  else:
206
- ext = file_extension_ or self.configuration.file_extension
205
+ ext = file_extension_ or self.configuration.file_extension.value
207
206
  file_name = (
208
207
  os.path.splitext(output_file_basename)[0]
209
208
  + "_"
@@ -284,7 +283,10 @@ class BaseAcquisition:
284
283
  and self._copy_frames[url.path()]
285
284
  ):
286
285
  new_url = embed_url(url, output_file=output_file)
287
- n_vs, _, _ = from_data_url_to_virtual_source(new_url)
286
+ n_vs, _, _ = from_data_url_to_virtual_source(
287
+ new_url,
288
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
289
+ )
288
290
  new_vs.append(n_vs)
289
291
  else:
290
292
  new_vs.append(vs)
@@ -294,7 +296,11 @@ class BaseAcquisition:
294
296
  if input_file_path is not None:
295
297
  nx_tomo.bliss_original_files = (abspath(input_file_path),)
296
298
  # save data
297
- nx_tomo.save(file_path=output_file, data_path=data_path)
299
+ nx_tomo.save(
300
+ file_path=output_file,
301
+ data_path=data_path,
302
+ use_abs_path_for_vds=self.configuration.use_abs_path_for_vds,
303
+ )
298
304
  # check rotation angle
299
305
  if nx_tomo.sample.rotation_angle is not None:
300
306
  unique_angles = numpy.unique(
@@ -331,7 +337,10 @@ class BaseAcquisition:
331
337
  raise NotImplementedError("Base class")
332
338
 
333
339
  def read_entry(self):
334
- return EntryReader(self._root_url)
340
+ return EntryReader(
341
+ self._root_url,
342
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
343
+ )
335
344
 
336
345
  def is_different_sequence(self, entry):
337
346
  """
@@ -346,7 +355,9 @@ class BaseAcquisition:
346
355
  return False
347
356
 
348
357
  def read_sample_node(url: DataUrl) -> str | None:
349
- with EntryReader(url=url) as entry:
358
+ with EntryReader(
359
+ url=url, open_mode_for_reading=self.configuration.open_mode_for_reading
360
+ ) as entry:
350
361
  sample_node = self._get_sample_node(entry)
351
362
  if sample_node is None:
352
363
  return None
@@ -536,7 +547,10 @@ class BaseAcquisition:
536
547
  _logger.warning("no root url. Unable to read rotation motor")
537
548
  return None
538
549
  else:
539
- with EntryReader(self._root_url) as entry:
550
+ with EntryReader(
551
+ self._root_url,
552
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
553
+ ) as entry:
540
554
  for motor_path in self._TECHNIQUE_MOTOR_PATHS:
541
555
  if motor_path in entry:
542
556
  try:
@@ -809,7 +823,10 @@ class BaseAcquisition:
809
823
  _logger.warning("no root url. Unable to read detector roi")
810
824
  return None
811
825
  else:
812
- with EntryReader(self._root_url) as entry:
826
+ with EntryReader(
827
+ self._root_url,
828
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
829
+ ) as entry:
813
830
  for roi_path in self._DETECTOR_ROI:
814
831
  if roi_path in entry:
815
832
  try: