nxtomomill 2.1.0.dev1__tar.gz → 2.1.0.dev3__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 (188) hide show
  1. {nxtomomill-2.1.0.dev1/nxtomomill.egg-info → nxtomomill-2.1.0.dev3}/PKG-INFO +3 -2
  2. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/h52nx.py +21 -13
  3. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/patch_nx.py +4 -1
  4. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/split_nxfile.py +18 -2
  5. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/z_concatenate_scans.py +3 -1
  6. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/dxfileconverter.py +28 -10
  7. nxtomomill-2.1.0.dev3/nxtomomill/converter/edf/_Blosc2Jp2kWrapper.py +63 -0
  8. nxtomomill-2.1.0.dev3/nxtomomill/converter/hdf5/acquisition/_bliss_activeconfig.py +34 -0
  9. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/baseacquisition.py +62 -15
  10. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/multitomo.py +86 -9
  11. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/standardacquisition.py +161 -48
  12. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition.py +37 -0
  13. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition_utils.py +2 -1
  14. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_holotomo.py +7 -0
  15. nxtomomill-2.1.0.dev3/nxtomomill/converter/hdf5/acquisition/tests/test_multitomo_zseries.py +109 -0
  16. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_multitomoacquisition.py +9 -0
  17. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/bliss_scan_type.py +4 -2
  18. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/zseriesacquisition.py +10 -3
  19. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisitionConstructor.py +12 -4
  20. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/hdf5converter.py +17 -16
  21. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/post_processing/dark_flat_copy.py +4 -0
  22. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_frame_flip.py +7 -5
  23. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_hdf5converter.py +15 -12
  24. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/confighandler.py +3 -0
  25. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/tests/test_confighandler.py +3 -0
  26. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/general_section.py +43 -1
  27. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/h52nx.py +2 -0
  28. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/datasets.py +4 -5
  29. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/flat_reducer.py +19 -4
  30. nxtomomill-2.1.0.dev3/nxtomomill/utils/h5pyutils.py +219 -0
  31. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/hdf5.py +51 -24
  32. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/nexus.py +14 -4
  33. nxtomomill-2.1.0.dev3/nxtomomill/utils/tests/test_h5pyutils.py +209 -0
  34. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_utils.py +15 -0
  35. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/utils.py +18 -8
  36. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/version.py +1 -1
  37. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3/nxtomomill.egg-info}/PKG-INFO +3 -2
  38. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/SOURCES.txt +4 -10
  39. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/requires.txt +2 -1
  40. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/top_level.txt +1 -0
  41. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/pyproject.toml +2 -1
  42. nxtomomill-2.1.0.dev1/nxtomomill/nexus/__init__.py +0 -8
  43. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxdetector.py +0 -10
  44. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxinstrument.py +0 -10
  45. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxmonitor.py +0 -10
  46. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxobject.py +0 -10
  47. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxsample.py +0 -10
  48. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxsource.py +0 -10
  49. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxtomo.py +0 -10
  50. nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxtransformations.py +0 -10
  51. nxtomomill-2.1.0.dev1/nxtomomill/nexus/utils.py +0 -10
  52. nxtomomill-2.1.0.dev1/nxtomomill/utils/h5pyutils.py +0 -58
  53. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/LICENSE +0 -0
  54. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/README.md +0 -0
  55. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/doc/conf.py +0 -0
  56. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/__init__.py +0 -0
  57. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/__main__.py +0 -0
  58. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/__init__.py +0 -0
  59. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/blissfluo2nx.py +0 -0
  60. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/blissfluoconfig.py +0 -0
  61. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/dxfile2nx.py +0 -0
  62. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edf2nx.py +0 -0
  63. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edf2nx_check.py +0 -0
  64. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edfconfig.py +0 -0
  65. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fluo2nx.py +0 -0
  66. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fluoconfig.py +0 -0
  67. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fscan2nx.py +0 -0
  68. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/h5config.py +0 -0
  69. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/nxcopy.py +0 -0
  70. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_bliss_fluo2nx_app.py +0 -0
  71. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_dxfile2nx_app.py +0 -0
  72. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_edf2nx_app.py +0 -0
  73. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_edf_config_app.py +0 -0
  74. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_fluo2nx_app.py +0 -0
  75. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_h52nx_app.py +0 -0
  76. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_h5_config_app.py +0 -0
  77. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_nx_copy.py +0 -0
  78. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_patch_nx_app.py +0 -0
  79. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_split_nxfile_app.py +0 -0
  80. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/zstages2nxs.py +0 -0
  81. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/__init__.py +0 -0
  82. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/baseconverter.py +0 -0
  83. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/__init__.py +0 -0
  84. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/tests/test_dxfile.py +0 -0
  85. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/__init__.py +0 -0
  86. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/checks.py +0 -0
  87. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/edfconverter.py +0 -0
  88. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_checks.py +0 -0
  89. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_edf2nx.py +0 -0
  90. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_edf2nx_check.py +0 -0
  91. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/__init__.py +0 -0
  92. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/blissfluoscan.py +0 -0
  93. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/fluoconverter.py +0 -0
  94. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/fluoscan.py +0 -0
  95. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/__init__.py +0 -0
  96. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/test_fluoscan2D.py +0 -0
  97. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/test_fluoscan3D.py +0 -0
  98. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fscan/__init__.py +0 -0
  99. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fscan/fscanconverter.py +0 -0
  100. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/__init__.py +0 -0
  101. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/__init__.py +0 -0
  102. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/backandforth.py +0 -0
  103. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/blisstomoconfig.py +0 -0
  104. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/pcotomoacquisition.py +0 -0
  105. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/bliss_tomo_datasets.py +0 -0
  106. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_back_and_forth.py +0 -0
  107. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_bliss_tomo_config.py +0 -0
  108. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_legacy.py +0 -0
  109. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/__init__.py +0 -0
  110. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_context.py +0 -0
  111. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_keys.py +0 -0
  112. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_scan_type_finder.py +0 -0
  113. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/detector.py +0 -0
  114. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/machine_current.py +0 -0
  115. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/series.py +0 -0
  116. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/timestamps.py +0 -0
  117. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/post_processing/__init__.py +0 -0
  118. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_h52nx_utils.py +0 -0
  119. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/utils.py +0 -0
  120. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/version.py +0 -0
  121. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/__init__.py +0 -0
  122. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/__init__.py +0 -0
  123. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/configbase.py +0 -0
  124. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/dxconfig.py +0 -0
  125. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/edfconfig.py +0 -0
  126. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/fluoconfig.py +0 -0
  127. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/hdf5config.py +0 -0
  128. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/tests/__init__.py +0 -0
  129. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/tests/test_frame_group.py +0 -0
  130. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/tests/utils.py +0 -0
  131. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/__init__.py +0 -0
  132. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/ConfigBase.py +0 -0
  133. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/FrmFlatToNestedBase.py +0 -0
  134. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/NestedModelBase.py +0 -0
  135. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/__init__.py +0 -0
  136. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/general_section.py +0 -0
  137. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/instrument_section.py +0 -0
  138. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/source_section.py +0 -0
  139. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/__init__.py +0 -0
  140. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/blissfluo2nx.py +0 -0
  141. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/general_section.py +0 -0
  142. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/dx2nx.py +0 -0
  143. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/__init__.py +0 -0
  144. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/dark_and_flat_section.py +0 -0
  145. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/detector_section.py +0 -0
  146. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/edf2nx.py +0 -0
  147. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/general_section.py +0 -0
  148. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/keys_section.py +0 -0
  149. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/sample_section.py +0 -0
  150. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/unit_section.py +0 -0
  151. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/__init__.py +0 -0
  152. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/fluo2nx.py +0 -0
  153. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/general_section.py +0 -0
  154. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/FrameGroup.py +0 -0
  155. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/__init__.py +0 -0
  156. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/_acquisitionstep.py +0 -0
  157. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/_context.py +0 -0
  158. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/entries_and_title_section.py +0 -0
  159. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/extra_params_section.py +0 -0
  160. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/frame_type_section.py +0 -0
  161. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/keys_section.py +0 -0
  162. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/multitomo_section.py +0 -0
  163. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_context.py +0 -0
  164. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_edf2nx_model.py +0 -0
  165. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_fluo2nx_model.py +0 -0
  166. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_h52nx_model.py +0 -0
  167. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_io_utils.py +0 -0
  168. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/utils.py +0 -0
  169. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/settings.py +0 -0
  170. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/test.py +0 -0
  171. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/__init__.py +0 -0
  172. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/__init__.py +0 -0
  173. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/edf2nx_config_files/__init__.py +0 -0
  174. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/fluo2nx_config_files/__init__.py +0 -0
  175. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/h52nx_config_files/__init__.py +0 -0
  176. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/test_version.py +0 -0
  177. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/__init__.py +0 -0
  178. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/bliss.py +0 -0
  179. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/dxfile.py +0 -0
  180. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/__init__.py +0 -0
  181. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/_os.py +0 -0
  182. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/io.py +0 -0
  183. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/pintutils.py +0 -0
  184. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_flat_reducer.py +0 -0
  185. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_nexus_utils.py +0 -0
  186. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/dependency_links.txt +0 -0
  187. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/entry_points.txt +0 -0
  188. {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nxtomomill
3
- Version: 2.1.0.dev1
3
+ Version: 2.1.0.dev3
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.0dev0
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"
@@ -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
 
@@ -206,9 +205,10 @@ def main(argv):
206
205
  help="Y pixel size key to read",
207
206
  )
208
207
  parser.add_argument(
209
- "--read-mode",
210
- default="locking",
211
- help="Options when reading bliss file. Valid values are 'locking', 'swmr' and 'locking_free'. 'locking' is the default h5py read mode.",
208
+ "--open_mode_for_reading",
209
+ "--open-mode-for-reading",
210
+ default="robust",
211
+ help="Options when reading bliss file. Valid values are 'robust' or 'safe'. 'robust' is the default h5py read mode.",
212
212
  )
213
213
  # scan titles
214
214
  parser.add_argument(
@@ -284,6 +284,12 @@ def main(argv):
284
284
  f"are: {_getPossibleInputParams()}. Should be added at the end of the command line because "
285
285
  "will try to cover all text set after this option.",
286
286
  )
287
+ # output entries
288
+ parser.add_argument(
289
+ "--output-entries",
290
+ default=None,
291
+ help="Provide names of the output entries (HDF5 group path).",
292
+ )
287
293
 
288
294
  # config file
289
295
  parser.add_argument(
@@ -295,21 +301,23 @@ def main(argv):
295
301
  help="file containing the full configuration to convert from h5 "
296
302
  "bliss to nexus",
297
303
  )
298
-
304
+ parser.add_argument(
305
+ "--use-abs-path-for-vds",
306
+ "--abs-path-for-vds",
307
+ "--use_abs_path_for_vds",
308
+ "--use-abs-path-for-vds",
309
+ default=False,
310
+ action="store_true",
311
+ help="Generated NXtomo file contains relative path by default. "
312
+ "Sometime relative link cannot be solved (GPFS vs NFS). "
313
+ "In this case you might be forced to use absolute path.",
314
+ )
299
315
  options = parser.parse_args(argv[1:])
300
316
  if options.request_input:
301
317
  callback_det_sel = _ask_for_selecting_detector
302
318
  else:
303
319
  callback_det_sel = None
304
320
 
305
- # define reading mode
306
- read_mode = os.getenv("NXTOMOMILL_HDF5_READ_MODE", "locking")
307
- if options.read_mode not in ("locking", "locking_free", "swmr"):
308
- raise ValueError(
309
- f"Invalid read mode: {read_mode}. Valid values are 'locking', 'locking_free' and 'swmr'"
310
- )
311
- os.environ["NXTOMOMILL_HDF5_READ_MODE"] = options.read_mode
312
-
313
321
  try:
314
322
  configuration_handler = TomoHDF5ConfigHandler(options)
315
323
  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
@@ -143,7 +143,7 @@ class _DxFileToNxConverter(BaseConverter):
143
143
  output_file = os.path.join(
144
144
  os.path.dirname(input_file),
145
145
  os.path.basename(input_file_basename)
146
- + self._configuration.file_extension,
146
+ + self._configuration.file_extension.value,
147
147
  )
148
148
  else:
149
149
  output_file = os.path.abspath(self.output_file)
@@ -329,7 +329,9 @@ class _DxFileToNxConverter(BaseConverter):
329
329
  self._copy_count_time()
330
330
 
331
331
  # start time
332
- with EntryReader(self.input_root_url) as input_entry:
332
+ with EntryReader(
333
+ self.input_root_url, open_mode_for_reading="safe"
334
+ ) as input_entry:
333
335
  if "file_creation_datetime" in input_entry:
334
336
  with HDF5File(self.output_file, mode="a") as h5f:
335
337
  root_grp = h5f.require_group(self.output_entry)
@@ -365,7 +367,9 @@ class _DxFileToNxConverter(BaseConverter):
365
367
  f"Failed to get 'count_time' / 'exposure_period'. reason is {e}"
366
368
  )
367
369
 
368
- with EntryReader(self.input_root_url) as input_entry:
370
+ with EntryReader(
371
+ self.input_root_url, open_mode_for_reading="safe"
372
+ ) as input_entry:
369
373
  if "measurement" in input_entry:
370
374
  measurement_grp = input_entry["measurement"]
371
375
  if "detector" in measurement_grp:
@@ -469,7 +473,9 @@ class _DxFileToNxConverter(BaseConverter):
469
473
  n_proj = 0
470
474
  # handle darks
471
475
  try:
472
- with DatasetReader(self._data_darks_url) as dark_dataset:
476
+ with DatasetReader(
477
+ self._data_darks_url, open_mode_for_reading="safe"
478
+ ) as dark_dataset:
473
479
  n_dark = dark_dataset.shape[0]
474
480
  # FIXME: avoid keeping some file open. not clear why this is needed
475
481
  dark_dataset = None
@@ -491,7 +497,9 @@ class _DxFileToNxConverter(BaseConverter):
491
497
 
492
498
  # handle flats
493
499
  try:
494
- with DatasetReader(self._data_flats_url) as flat_dataset:
500
+ with DatasetReader(
501
+ self._data_flats_url, open_mode_for_reading="safe"
502
+ ) as flat_dataset:
495
503
  n_flat = flat_dataset.shape[0]
496
504
  # FIXME: avoid keeping some file open. not clear why this is needed
497
505
  flat_dataset = None
@@ -513,7 +521,9 @@ class _DxFileToNxConverter(BaseConverter):
513
521
 
514
522
  # handle projections
515
523
  try:
516
- with DatasetReader(self._data_proj_url) as proj_dataset:
524
+ with DatasetReader(
525
+ self._data_proj_url, open_mode_for_reading="safe"
526
+ ) as proj_dataset:
517
527
  n_proj = proj_dataset.shape[0]
518
528
  # FIXME: avoid keeping some file open. not clear why this is needed
519
529
  proj_dataset = None
@@ -554,7 +564,9 @@ class _DxFileToNxConverter(BaseConverter):
554
564
  self._path_nxtomo_attrs(root_grp)
555
565
 
556
566
  def _read_sample_detector_distance(self):
557
- with EntryReader(self.input_root_url) as input_entry:
567
+ with EntryReader(
568
+ self.input_root_url, open_mode_for_reading="safe"
569
+ ) as input_entry:
558
570
  path = "/".join(
559
571
  ("measurement", "instrument", "sample", "setup", "detector_distance")
560
572
  )
@@ -568,7 +580,9 @@ class _DxFileToNxConverter(BaseConverter):
568
580
  return distance * unit
569
581
 
570
582
  def _read_energy(self):
571
- with EntryReader(self.input_root_url) as input_entry:
583
+ with EntryReader(
584
+ self.input_root_url, open_mode_for_reading="safe"
585
+ ) as input_entry:
572
586
  path = "/".join(("measurement", "instrument", "source", "energy"))
573
587
  dataset = input_entry[path]
574
588
  energy = float(h5py_read_dataset(dataset))
@@ -580,7 +594,9 @@ class _DxFileToNxConverter(BaseConverter):
580
594
  return energy * unit
581
595
 
582
596
  def _read_x_pixel_size(self):
583
- with EntryReader(self.input_root_url) as input_entry:
597
+ with EntryReader(
598
+ self.input_root_url, open_mode_for_reading="safe"
599
+ ) as input_entry:
584
600
  path = "/".join(
585
601
  ("measurement", "instrument", "detector", "actual_pixel_size_x")
586
602
  )
@@ -594,7 +610,9 @@ class _DxFileToNxConverter(BaseConverter):
594
610
  return pixel_size * unit
595
611
 
596
612
  def _read_y_pixel_size(self):
597
- with EntryReader(self.input_root_url) as input_entry:
613
+ with EntryReader(
614
+ self.input_root_url, open_mode_for_reading="safe"
615
+ ) as input_entry:
598
616
  path = "/".join(
599
617
  ("measurement", "instrument", "detector", "actual_pixel_size_y")
600
618
  )
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+ import numpy
3
+ from h5py import Dataset
4
+
5
+ try:
6
+ import blosc2
7
+ import blosc2_grok
8
+ except ImportError:
9
+ _has_blosc2 = False
10
+ else:
11
+ _has_blosc2 = True
12
+
13
+
14
+ class Blosc2Jp2kWrapper:
15
+ """Wrapper to apply JP2K conversion to a dataset"""
16
+
17
+ def __init__(self, dataset: Dataset, compression_params: dict):
18
+ self.dataset: Dataset = dataset
19
+ self.compression_params: dict = self.get_default_compression_params()
20
+ self.compression_params.update(compression_params)
21
+
22
+ blosc2_grok.set_params_defaults(
23
+ # codec=blosc2.Codec.GROK,
24
+ cod_format=blosc2_grok.GrkFileFmt.GRK_FMT_JP2,
25
+ num_threads=self.compression_params["nthreads"],
26
+ quality_mode="rates",
27
+ quality_layers=numpy.array(
28
+ [self.compression_params["cratio"]],
29
+ dtype=numpy.float64,
30
+ ),
31
+ verbose=True,
32
+ )
33
+
34
+ def __setitem__(self, name, value):
35
+ z, _, _ = name
36
+ Z, Y, X = self.dataset.shape
37
+
38
+ # Verify data type compatibility
39
+ if value.dtype not in [numpy.float32, numpy.float64, numpy.uint16]:
40
+ raise ValueError(f"Unsupported dtype: {value.dtype}")
41
+
42
+ b2im = blosc2.asarray(
43
+ value.reshape(1, Y, X),
44
+ chunks=(1, Y, X),
45
+ blocks=(1, Y, X),
46
+ cparams=self.compression_params,
47
+ )
48
+ cframe = b2im.schunk.to_cframe()
49
+ self.dataset.id.write_direct_chunk((z, 0, 0), cframe, filter_mask=0)
50
+
51
+ @classmethod
52
+ def get_default_compression_params(cls) -> dict:
53
+ if _has_blosc2:
54
+ return {
55
+ "codec": blosc2.Codec.GROK,
56
+ "filters": [],
57
+ "splitmode": blosc2.SplitMode.NEVER_SPLIT,
58
+ "nthreads": 4,
59
+ "cratio": 10,
60
+ "verbose": True,
61
+ }
62
+ else:
63
+ return {}
@@ -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,6 +64,7 @@ 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
  )
@@ -98,14 +99,10 @@ class BaseAcquisition:
98
99
 
99
100
  _SOURCE_NAME = ("instrument/machine/name",)
100
101
 
101
- _BEAMLINE_NAME = (
102
- "instrument/name",
103
- "instrument/title",
104
- )
105
-
106
102
  _SOURCE_TYPE = ("instrument/machine/type",)
107
103
 
108
104
  _FRAME_FLIP_PATHS = (
105
+ "instrument/{active_config_tomo_detector}/data_axes", # note: data_axes are stored in the optic and not in the camera name.
109
106
  "technique/detector/{detector_name}/flipping",
110
107
  "technique/detector/flipping",
111
108
  )
@@ -134,6 +131,7 @@ class BaseAcquisition:
134
131
  The idea is to avoid asking him if """
135
132
  self._configuration = copy.deepcopy(configuration)
136
133
  """configuration to the conversion to be done. As we are modifying some values (keys...) and those depends on the acquisition context we need to copy it"""
134
+ self._configuration.output_entries = configuration.output_entries
137
135
  self._start_index = start_index
138
136
 
139
137
  # set of properties when an acquisition needs to copy dark / flat (used in the case of z-series version 3)
@@ -182,13 +180,27 @@ class BaseAcquisition:
182
180
  output_file_basename.rstrip(possible_extension)
183
181
  file_extension_ = possible_extension
184
182
 
185
- def get_file_name_and_entry(index, divide_sub_files):
186
- entry = "entry" + str(index).zfill(4)
183
+ def get_file_name_and_entry(
184
+ index: int, divide_sub_files: bool, entry: str | None
185
+ ) -> tuple[str, str]:
186
+ """
187
+ Docstring for get_file_name_and_entry
188
+
189
+ :param index: index of the entry in the input file
190
+ :param divide_sub_files: If True this mean the NXtomo will be split into several NXtomo. Case of multi-tomo.
191
+ :param entry: entry path if defined directly by the user.
192
+ """
193
+ if entry is None:
194
+ entry = "entry" + str(index).zfill(4)
195
+ elif not isinstance(entry, str):
196
+ raise TypeError(
197
+ f"entry should be an instance of {str}. Got {type(entry)}"
198
+ )
187
199
 
188
200
  if self.configuration.single_file or not divide_sub_files:
189
201
  en_output_file = self.configuration.output_file
190
202
  else:
191
- ext = file_extension_ or self.configuration.file_extension
203
+ ext = file_extension_ or self.configuration.file_extension.value
192
204
  file_name = (
193
205
  os.path.splitext(output_file_basename)[0]
194
206
  + "_"
@@ -212,8 +224,20 @@ class BaseAcquisition:
212
224
 
213
225
  result = []
214
226
  for i_nx_tomo, nx_tomo in enumerate(nx_tomos):
227
+ if self.configuration.output_entries is not None:
228
+ try:
229
+ output_entry = self.configuration.output_entries.pop()
230
+ except IndexError:
231
+ raise ValueError(
232
+ "Not enough 'output_entries' provided for the number of nxtomo generated."
233
+ )
234
+ else:
235
+ output_entry = None
236
+
215
237
  output_file, data_path = get_file_name_and_entry(
216
- (shift_entry + i_nx_tomo), divide_sub_files=divide_into_sub_files
238
+ (shift_entry + i_nx_tomo),
239
+ divide_sub_files=divide_into_sub_files,
240
+ entry=output_entry,
217
241
  )
218
242
  output_file = abspath(os.path.relpath(output_file, os.getcwd()))
219
243
  output_file = abspath(output_file)
@@ -227,6 +251,11 @@ class BaseAcquisition:
227
251
  _logger.warning(
228
252
  f"No frame found for NXtomo number {i_nx_tomo}. Won't write any output for it"
229
253
  )
254
+ if self.configuration.output_entries is not None:
255
+ # append back output_entry. Will be the next one to (re)pop.
256
+ # Because of sequence of sequence we might consume one entry name for nothing...
257
+ self.configuration.output_entries.append(output_entry)
258
+
230
259
  continue
231
260
  vs_0 = nx_tomo.instrument.detector.data[0]
232
261
  if nx_tomo.detector_data_is_defined_by_url():
@@ -252,7 +281,10 @@ class BaseAcquisition:
252
281
  and self._copy_frames[url.path()]
253
282
  ):
254
283
  new_url = embed_url(url, output_file=output_file)
255
- n_vs, _, _ = from_data_url_to_virtual_source(new_url)
284
+ n_vs, _, _ = from_data_url_to_virtual_source(
285
+ new_url,
286
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
287
+ )
256
288
  new_vs.append(n_vs)
257
289
  else:
258
290
  new_vs.append(vs)
@@ -262,7 +294,11 @@ class BaseAcquisition:
262
294
  if input_file_path is not None:
263
295
  nx_tomo.bliss_original_files = (abspath(input_file_path),)
264
296
  # save data
265
- nx_tomo.save(file_path=output_file, data_path=data_path)
297
+ nx_tomo.save(
298
+ file_path=output_file,
299
+ data_path=data_path,
300
+ use_abs_path_for_vds=self.configuration.use_abs_path_for_vds,
301
+ )
266
302
  # check rotation angle
267
303
  if nx_tomo.sample.rotation_angle is not None:
268
304
  unique_angles = numpy.unique(
@@ -299,7 +335,10 @@ class BaseAcquisition:
299
335
  raise NotImplementedError("Base class")
300
336
 
301
337
  def read_entry(self):
302
- return EntryReader(self._root_url)
338
+ return EntryReader(
339
+ self._root_url,
340
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
341
+ )
303
342
 
304
343
  def is_different_sequence(self, entry):
305
344
  """
@@ -314,7 +353,9 @@ class BaseAcquisition:
314
353
  return False
315
354
 
316
355
  def read_sample_node(url: DataUrl) -> str | None:
317
- with EntryReader(url=url) as entry:
356
+ with EntryReader(
357
+ url=url, open_mode_for_reading=self.configuration.open_mode_for_reading
358
+ ) as entry:
318
359
  sample_node = self._get_sample_node(entry)
319
360
  if sample_node is None:
320
361
  return None
@@ -504,7 +545,10 @@ class BaseAcquisition:
504
545
  _logger.warning("no root url. Unable to read rotation motor")
505
546
  return None
506
547
  else:
507
- with EntryReader(self._root_url) as entry:
548
+ with EntryReader(
549
+ self._root_url,
550
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
551
+ ) as entry:
508
552
  for motor_path in self._TECHNIQUE_MOTOR_PATHS:
509
553
  if motor_path in entry:
510
554
  try:
@@ -777,7 +821,10 @@ class BaseAcquisition:
777
821
  _logger.warning("no root url. Unable to read detector roi")
778
822
  return None
779
823
  else:
780
- with EntryReader(self._root_url) as entry:
824
+ with EntryReader(
825
+ self._root_url,
826
+ open_mode_for_reading=self.configuration.open_mode_for_reading,
827
+ ) as entry:
781
828
  for roi_path in self._DETECTOR_ROI:
782
829
  if roi_path in entry:
783
830
  try: