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.
- {nxtomomill-2.1.0.dev1/nxtomomill.egg-info → nxtomomill-2.1.0.dev3}/PKG-INFO +3 -2
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/h52nx.py +21 -13
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/patch_nx.py +4 -1
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/split_nxfile.py +18 -2
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/z_concatenate_scans.py +3 -1
- {nxtomomill-2.1.0.dev1 → 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.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/baseacquisition.py +62 -15
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/multitomo.py +86 -9
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/standardacquisition.py +161 -48
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition.py +37 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_acquisition_utils.py +2 -1
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_holotomo.py +7 -0
- nxtomomill-2.1.0.dev3/nxtomomill/converter/hdf5/acquisition/tests/test_multitomo_zseries.py +109 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_multitomoacquisition.py +9 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/bliss_scan_type.py +4 -2
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/zseriesacquisition.py +10 -3
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisitionConstructor.py +12 -4
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/hdf5converter.py +17 -16
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/post_processing/dark_flat_copy.py +4 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_frame_flip.py +7 -5
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_hdf5converter.py +15 -12
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/confighandler.py +3 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/tests/test_confighandler.py +3 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/general_section.py +43 -1
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/h52nx.py +2 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/datasets.py +4 -5
- {nxtomomill-2.1.0.dev1 → 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.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/hdf5.py +51 -24
- {nxtomomill-2.1.0.dev1 → 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.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_utils.py +15 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/utils.py +18 -8
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/version.py +1 -1
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3/nxtomomill.egg-info}/PKG-INFO +3 -2
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/SOURCES.txt +4 -10
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/requires.txt +2 -1
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/top_level.txt +1 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/pyproject.toml +2 -1
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/__init__.py +0 -8
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxdetector.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxinstrument.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxmonitor.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxobject.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxsample.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxsource.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxtomo.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/nxtransformations.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/nexus/utils.py +0 -10
- nxtomomill-2.1.0.dev1/nxtomomill/utils/h5pyutils.py +0 -58
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/LICENSE +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/README.md +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/doc/conf.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/__main__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/blissfluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/blissfluoconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/dxfile2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edf2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edf2nx_check.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/edfconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fluoconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/fscan2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/h5config.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/nxcopy.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_bliss_fluo2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_dxfile2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_edf2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_edf_config_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_fluo2nx_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_h52nx_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_h5_config_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_nx_copy.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_patch_nx_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/tests/test_split_nxfile_app.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/app/zstages2nxs.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/baseconverter.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/dxfile/tests/test_dxfile.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/checks.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/edfconverter.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_checks.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_edf2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/edf/tests/test_edf2nx_check.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/blissfluoscan.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/fluoconverter.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/fluoscan.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/test_fluoscan2D.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fluo/tests/test_fluoscan3D.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fscan/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/fscan/fscanconverter.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/backandforth.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/blisstomoconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/pcotomoacquisition.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/bliss_tomo_datasets.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_back_and_forth.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_bliss_tomo_config.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/tests/test_legacy.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_context.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_keys.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/_scan_type_finder.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/detector.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/machine_current.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/series.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/acquisition/utils/timestamps.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/post_processing/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/tests/test_h52nx_utils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/hdf5/utils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/converter/version.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/configbase.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/dxconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/edfconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/fluoconfig.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/hdf5config.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/config/tests/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/tests/test_frame_group.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/io/tests/utils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/ConfigBase.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/FrmFlatToNestedBase.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/NestedModelBase.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/general_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/instrument_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/base/source_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/blissfluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/blissfluo2nx/general_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/dx2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/dark_and_flat_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/detector_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/edf2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/general_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/keys_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/sample_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/edf2nx/unit_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/fluo2nx.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/fluo2nx/general_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/FrameGroup.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/_acquisitionstep.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/_context.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/entries_and_title_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/extra_params_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/frame_type_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/keys_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/h52nx/multitomo_section.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_context.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_edf2nx_model.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_fluo2nx_model.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_h52nx_model.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/tests/test_io_utils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/models/utils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/settings.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/test.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/edf2nx_config_files/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/fluo2nx_config_files/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/resources/h52nx_config_files/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/test_version.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/bliss.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/tests/utils/dxfile.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/__init__.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/_os.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/io.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/pintutils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_flat_reducer.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill/utils/tests/test_nexus_utils.py +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/dependency_links.txt +0 -0
- {nxtomomill-2.1.0.dev1 → nxtomomill-2.1.0.dev3}/nxtomomill.egg-info/entry_points.txt +0 -0
- {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.
|
|
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
|
-
"--
|
|
210
|
-
|
|
211
|
-
|
|
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(
|
|
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.dev1 → 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
|
)
|
|
@@ -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(
|
|
186
|
-
|
|
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),
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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:
|