nxtomomill 2.1.0.dev2__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.
- {nxtomomill-2.1.0.dev2/nxtomomill.egg-info → nxtomomill-2.1.0.dev3}/PKG-INFO +3 -2
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/h52nx.py +14 -12
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/patch_nx.py +4 -1
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/split_nxfile.py +18 -2
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/z_concatenate_scans.py +3 -1
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/dxfileconverter.py +28 -10
- nxtomomill-2.1.0.dev3/nxtomomill/converter/edf/_Blosc2Jp2kWrapper.py +63 -0
- nxtomomill-2.1.0.dev3/nxtomomill/converter/hdf5/acquisition/_bliss_activeconfig.py +34 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/baseacquisition.py +27 -12
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/multitomo.py +86 -9
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/standardacquisition.py +161 -48
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition.py +37 -0
- nxtomomill-2.1.0.dev3/nxtomomill/converter/hdf5/acquisition/tests/test_multitomo_zseries.py +109 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_multitomoacquisition.py +9 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/bliss_scan_type.py +4 -2
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/zseriesacquisition.py +10 -3
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisitionConstructor.py +12 -4
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/hdf5converter.py +10 -6
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/post_processing/dark_flat_copy.py +4 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_frame_flip.py +7 -5
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_hdf5converter.py +15 -12
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/confighandler.py +2 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/tests/test_confighandler.py +2 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/general_section.py +9 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/h52nx.py +1 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/datasets.py +4 -5
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/flat_reducer.py +19 -4
- nxtomomill-2.1.0.dev3/nxtomomill/utils/h5pyutils.py +219 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/hdf5.py +47 -21
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/nexus.py +14 -4
- nxtomomill-2.1.0.dev3/nxtomomill/utils/tests/test_h5pyutils.py +209 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_utils.py +15 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/utils.py +18 -8
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/version.py +1 -1
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3/nxtomomill.egg-info}/PKG-INFO +3 -2
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/SOURCES.txt +4 -10
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/requires.txt +2 -1
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/top_level.txt +2 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/pyproject.toml +2 -1
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/__init__.py +0 -8
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxdetector.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxinstrument.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxmonitor.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxobject.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxsample.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxsource.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxtomo.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/nxtransformations.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/nexus/utils.py +0 -10
- nxtomomill-2.1.0.dev2/nxtomomill/utils/h5pyutils.py +0 -58
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/LICENSE +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/README.md +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/doc/conf.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/__main__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/blissfluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/blissfluoconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/dxfile2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edf2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edf2nx_check.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edfconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fluoconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fscan2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/h5config.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/nxcopy.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_bliss_fluo2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_dxfile2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_edf2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_edf_config_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_fluo2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_h52nx_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_h5_config_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_nx_copy.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_patch_nx_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_split_nxfile_app.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/app/zstages2nxs.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/baseconverter.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/tests/test_dxfile.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/checks.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/edfconverter.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_checks.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_edf2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_edf2nx_check.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/blissfluoscan.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/fluoconverter.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/fluoscan.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/test_fluoscan2D.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/test_fluoscan3D.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fscan/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fscan/fscanconverter.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/backandforth.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/blisstomoconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/pcotomoacquisition.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/bliss_tomo_datasets.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition_utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_back_and_forth.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_bliss_tomo_config.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_holotomo.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_legacy.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_context.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_keys.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_scan_type_finder.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/detector.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/machine_current.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/series.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/timestamps.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/post_processing/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_h52nx_utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/version.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/configbase.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/dxconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/edfconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/fluoconfig.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/hdf5config.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/tests/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/tests/test_frame_group.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/io/tests/utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/ConfigBase.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/FrmFlatToNestedBase.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/NestedModelBase.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/general_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/instrument_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/source_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/blissfluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/general_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/dx2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/dark_and_flat_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/detector_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/edf2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/general_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/keys_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/sample_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/unit_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/fluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/general_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/FrameGroup.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/_acquisitionstep.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/_context.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/entries_and_title_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/extra_params_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/frame_type_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/keys_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/multitomo_section.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_context.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_edf2nx_model.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_fluo2nx_model.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_h52nx_model.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_io_utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/models/utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/settings.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/test.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/edf2nx_config_files/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/fluo2nx_config_files/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/h52nx_config_files/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/test_version.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/bliss.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/dxfile.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/__init__.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/_os.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/io.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/pintutils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_flat_reducer.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_nexus_utils.py +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/dependency_links.txt +0 -0
- {nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/entry_points.txt +0 -0
- {nxtomomill-2.1.0.dev2 → 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.
|
|
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.
|
|
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
|
-
"--
|
|
208
|
+
"--open_mode_for_reading",
|
|
209
|
+
"--open-mode-for-reading",
|
|
210
210
|
default="robust",
|
|
211
|
-
help="Options when reading bliss file. Valid values are '
|
|
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(
|
|
@@ -301,21 +301,23 @@ def main(argv):
|
|
|
301
301
|
help="file containing the full configuration to convert from h5 "
|
|
302
302
|
"bliss to nexus",
|
|
303
303
|
)
|
|
304
|
-
|
|
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
|
+
)
|
|
305
315
|
options = parser.parse_args(argv[1:])
|
|
306
316
|
if options.request_input:
|
|
307
317
|
callback_det_sel = _ask_for_selecting_detector
|
|
308
318
|
else:
|
|
309
319
|
callback_det_sel = None
|
|
310
320
|
|
|
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
321
|
try:
|
|
320
322
|
configuration_handler = TomoHDF5ConfigHandler(options)
|
|
321
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(
|
|
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,
|
|
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(
|
|
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
|
{nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/dxfileconverter.py
RENAMED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
)
|
|
@@ -203,7 +200,7 @@ class BaseAcquisition:
|
|
|
203
200
|
if self.configuration.single_file or not divide_sub_files:
|
|
204
201
|
en_output_file = self.configuration.output_file
|
|
205
202
|
else:
|
|
206
|
-
ext = file_extension_ or self.configuration.file_extension
|
|
203
|
+
ext = file_extension_ or self.configuration.file_extension.value
|
|
207
204
|
file_name = (
|
|
208
205
|
os.path.splitext(output_file_basename)[0]
|
|
209
206
|
+ "_"
|
|
@@ -284,7 +281,10 @@ class BaseAcquisition:
|
|
|
284
281
|
and self._copy_frames[url.path()]
|
|
285
282
|
):
|
|
286
283
|
new_url = embed_url(url, output_file=output_file)
|
|
287
|
-
n_vs, _, _ = from_data_url_to_virtual_source(
|
|
284
|
+
n_vs, _, _ = from_data_url_to_virtual_source(
|
|
285
|
+
new_url,
|
|
286
|
+
open_mode_for_reading=self.configuration.open_mode_for_reading,
|
|
287
|
+
)
|
|
288
288
|
new_vs.append(n_vs)
|
|
289
289
|
else:
|
|
290
290
|
new_vs.append(vs)
|
|
@@ -294,7 +294,11 @@ class BaseAcquisition:
|
|
|
294
294
|
if input_file_path is not None:
|
|
295
295
|
nx_tomo.bliss_original_files = (abspath(input_file_path),)
|
|
296
296
|
# save data
|
|
297
|
-
nx_tomo.save(
|
|
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
|
+
)
|
|
298
302
|
# check rotation angle
|
|
299
303
|
if nx_tomo.sample.rotation_angle is not None:
|
|
300
304
|
unique_angles = numpy.unique(
|
|
@@ -331,7 +335,10 @@ class BaseAcquisition:
|
|
|
331
335
|
raise NotImplementedError("Base class")
|
|
332
336
|
|
|
333
337
|
def read_entry(self):
|
|
334
|
-
return EntryReader(
|
|
338
|
+
return EntryReader(
|
|
339
|
+
self._root_url,
|
|
340
|
+
open_mode_for_reading=self.configuration.open_mode_for_reading,
|
|
341
|
+
)
|
|
335
342
|
|
|
336
343
|
def is_different_sequence(self, entry):
|
|
337
344
|
"""
|
|
@@ -346,7 +353,9 @@ class BaseAcquisition:
|
|
|
346
353
|
return False
|
|
347
354
|
|
|
348
355
|
def read_sample_node(url: DataUrl) -> str | None:
|
|
349
|
-
with EntryReader(
|
|
356
|
+
with EntryReader(
|
|
357
|
+
url=url, open_mode_for_reading=self.configuration.open_mode_for_reading
|
|
358
|
+
) as entry:
|
|
350
359
|
sample_node = self._get_sample_node(entry)
|
|
351
360
|
if sample_node is None:
|
|
352
361
|
return None
|
|
@@ -536,7 +545,10 @@ class BaseAcquisition:
|
|
|
536
545
|
_logger.warning("no root url. Unable to read rotation motor")
|
|
537
546
|
return None
|
|
538
547
|
else:
|
|
539
|
-
with EntryReader(
|
|
548
|
+
with EntryReader(
|
|
549
|
+
self._root_url,
|
|
550
|
+
open_mode_for_reading=self.configuration.open_mode_for_reading,
|
|
551
|
+
) as entry:
|
|
540
552
|
for motor_path in self._TECHNIQUE_MOTOR_PATHS:
|
|
541
553
|
if motor_path in entry:
|
|
542
554
|
try:
|
|
@@ -809,7 +821,10 @@ class BaseAcquisition:
|
|
|
809
821
|
_logger.warning("no root url. Unable to read detector roi")
|
|
810
822
|
return None
|
|
811
823
|
else:
|
|
812
|
-
with EntryReader(
|
|
824
|
+
with EntryReader(
|
|
825
|
+
self._root_url,
|
|
826
|
+
open_mode_for_reading=self.configuration.open_mode_for_reading,
|
|
827
|
+
) as entry:
|
|
813
828
|
for roi_path in self._DETECTOR_ROI:
|
|
814
829
|
if roi_path in entry:
|
|
815
830
|
try:
|
{nxtomomill-2.1.0.dev2 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/multitomo.py
RENAMED
|
@@ -5,7 +5,9 @@ module to define a multi-tomo acquistion (also know as pco-tomo)
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
+
import numpy
|
|
8
9
|
import logging
|
|
10
|
+
from datetime import timezone
|
|
9
11
|
|
|
10
12
|
from silx.io.url import DataUrl
|
|
11
13
|
from silx.utils.proxy import docstring
|
|
@@ -129,21 +131,27 @@ class MultiTomoAcquisition(StandardAcquisition):
|
|
|
129
131
|
)
|
|
130
132
|
|
|
131
133
|
def get_nb_loop(self, url) -> int | None:
|
|
132
|
-
with EntryReader(
|
|
134
|
+
with EntryReader(
|
|
135
|
+
url, open_mode_for_reading=self.configuration.open_mode_for_reading
|
|
136
|
+
) as entry:
|
|
133
137
|
for path in self._NB_LOOP_PATH:
|
|
134
138
|
if path in entry:
|
|
135
139
|
return entry[path][()]
|
|
136
140
|
return None
|
|
137
141
|
|
|
138
142
|
def get_nb_tomo(self, url) -> int | None:
|
|
139
|
-
with EntryReader(
|
|
143
|
+
with EntryReader(
|
|
144
|
+
url, open_mode_for_reading=self.configuration.open_mode_for_reading
|
|
145
|
+
) as entry:
|
|
140
146
|
for path in self._NB_TOMO_PATH:
|
|
141
147
|
if path in entry:
|
|
142
148
|
return entry[path][()]
|
|
143
149
|
return None
|
|
144
150
|
|
|
145
151
|
def get_nb_turns(self, url) -> int | None:
|
|
146
|
-
with EntryReader(
|
|
152
|
+
with EntryReader(
|
|
153
|
+
url, open_mode_for_reading=self.configuration.open_mode_for_reading
|
|
154
|
+
) as entry:
|
|
147
155
|
for path in self._NB_TURNS_PATH:
|
|
148
156
|
if path in entry:
|
|
149
157
|
return entry[path][()]
|
|
@@ -167,7 +175,12 @@ class MultiTomoAcquisition(StandardAcquisition):
|
|
|
167
175
|
return the multitomo version according to the provider version (aka bliss)
|
|
168
176
|
"""
|
|
169
177
|
with EntryReader(
|
|
170
|
-
url=DataUrl(
|
|
178
|
+
url=DataUrl(
|
|
179
|
+
file_path=url.file_path(),
|
|
180
|
+
data_path="/",
|
|
181
|
+
scheme=url.scheme(),
|
|
182
|
+
),
|
|
183
|
+
open_mode_for_reading=self.configuration.open_mode_for_reading,
|
|
171
184
|
) as entry:
|
|
172
185
|
if "creator_version" in entry.attrs:
|
|
173
186
|
creator_version = entry.attrs["creator_version"]
|
|
@@ -263,13 +276,43 @@ class MultiTomoAcquisition(StandardAcquisition):
|
|
|
263
276
|
elif len(projections_slices) == 0:
|
|
264
277
|
raise ValueError("No projection found")
|
|
265
278
|
else:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
279
|
+
tomo_n = self._get_tomo_n()
|
|
280
|
+
try:
|
|
281
|
+
start_times, end_times = self._estimate_start_and_stop_times(
|
|
282
|
+
proj_start_index=projections_slices[0].start,
|
|
283
|
+
proj_stop_index=projections_slices[0].stop,
|
|
284
|
+
time_stamps=sorted(self._frames_timestamp),
|
|
285
|
+
n_proj_per_nxtomo=tomo_n,
|
|
286
|
+
)
|
|
287
|
+
except IndexError as e:
|
|
288
|
+
_logger.error(
|
|
289
|
+
f"Fail to estimate sub-NXtomo start and stop time. Error is {e}."
|
|
271
290
|
)
|
|
291
|
+
start_times = end_times = None
|
|
292
|
+
|
|
293
|
+
sub_nxtomos = splitter.split(
|
|
294
|
+
projections_slices[0],
|
|
295
|
+
nb_part=int(self._nb_turns),
|
|
296
|
+
tomo_n=tomo_n,
|
|
272
297
|
)
|
|
298
|
+
# update sub-NXtomo `start_time` and `end_time`.
|
|
299
|
+
if start_times is not None and end_times is not None:
|
|
300
|
+
if len(start_times) != len(sub_nxtomos):
|
|
301
|
+
_logger.error(
|
|
302
|
+
"Incoherent number of 'start_time' and generated sub-NXtomo. Won't modify start time."
|
|
303
|
+
)
|
|
304
|
+
else:
|
|
305
|
+
for start_time, end_time, sub_nxtomo in zip(
|
|
306
|
+
start_times, end_times, sub_nxtomos
|
|
307
|
+
):
|
|
308
|
+
sub_nxtomo.start_time = start_time.item().replace(
|
|
309
|
+
tzinfo=timezone.utc
|
|
310
|
+
)
|
|
311
|
+
sub_nxtomo.end_time = end_time.item().replace(
|
|
312
|
+
tzinfo=timezone.utc
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
results.extend(sub_nxtomos)
|
|
273
316
|
|
|
274
317
|
if check_tomo_n:
|
|
275
318
|
# if angle offset provided there is an hight probably this will mess up with the tomo_n, which is expected...
|
|
@@ -374,6 +417,40 @@ class MultiTomoAcquisition(StandardAcquisition):
|
|
|
374
417
|
|
|
375
418
|
return tuple(results)
|
|
376
419
|
|
|
420
|
+
@staticmethod
|
|
421
|
+
def _estimate_start_and_stop_times(
|
|
422
|
+
proj_start_index: int,
|
|
423
|
+
proj_stop_index: int,
|
|
424
|
+
time_stamps: tuple[numpy.datetime64],
|
|
425
|
+
n_proj_per_nxtomo: None | int,
|
|
426
|
+
) -> tuple[tuple[numpy.datetime64], tuple[numpy.datetime64]] | None:
|
|
427
|
+
"""
|
|
428
|
+
Estimate the starts time for sub NXtomos. For this we read the timestamp of the first projection.
|
|
429
|
+
We canno use the dark / flats that could be duplicated or the original start time which is the start of the bliss sequence.
|
|
430
|
+
|
|
431
|
+
.. warning: this could create a discrepancy for other scans that are using the bliss-tomo start time.
|
|
432
|
+
"""
|
|
433
|
+
if n_proj_per_nxtomo is None:
|
|
434
|
+
_logger.error(
|
|
435
|
+
"Unable to know the number of projection expected per nxtomo. Unable to estimate start time."
|
|
436
|
+
)
|
|
437
|
+
return None
|
|
438
|
+
first_projection_indices = numpy.arange(
|
|
439
|
+
proj_start_index,
|
|
440
|
+
proj_stop_index,
|
|
441
|
+
step=n_proj_per_nxtomo,
|
|
442
|
+
dtype=numpy.uint32,
|
|
443
|
+
)
|
|
444
|
+
last_projection_indices = numpy.arange(
|
|
445
|
+
proj_start_index + n_proj_per_nxtomo - 1,
|
|
446
|
+
proj_stop_index + 1, # +1 because stop index is not included in the range
|
|
447
|
+
step=n_proj_per_nxtomo,
|
|
448
|
+
dtype=numpy.uint32,
|
|
449
|
+
)
|
|
450
|
+
return tuple([time_stamps[i] for i in first_projection_indices]), tuple(
|
|
451
|
+
[time_stamps[i] for i in last_projection_indices]
|
|
452
|
+
)
|
|
453
|
+
|
|
377
454
|
@staticmethod
|
|
378
455
|
def _get_projections_slices(nx_tomo: NXtomo) -> tuple:
|
|
379
456
|
"""Return a tuple of slices for each group of contiguous projections"""
|