nabu 2025.1.0rc4__tar.gz → 2025.1.0rc5__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.
- {nabu-2025.1.0rc4/nabu.egg-info → nabu-2025.1.0rc5}/PKG-INFO +1 -1
- nabu-2025.1.0rc5/doc/doc_config.py +32 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/__init__.py +1 -1
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/cli_configs.py +15 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/estimate_motion.py +21 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/estimators.py +7 -2
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/azim.py +7 -3
- nabu-2025.1.0rc5/nabu/reconstruction/astra.py +245 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/mlem.py +2 -2
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/nxflatfield.py +1 -1
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5/nabu.egg-info}/PKG-INFO +1 -1
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu.egg-info/SOURCES.txt +2 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu.egg-info/top_level.txt +0 -1
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/LICENSE +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/README.md +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/doc/conf.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/doc/create_conf_doc.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/doc/get_mathjax.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/bootstrap.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/bootstrap_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/cast_volume.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/compare_volumes.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/composite_cor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/create_distortion_map_from_poly.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/diag_to_pix.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/diag_to_rot.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/double_flatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/generate_header.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/histogram.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/multicor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/nx_z_splitter.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/parse_reconstruction_log.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/pcaflats.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/prepare_weights_double.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/reconstruct.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/reconstruct_helical.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/reduce_dark_flat.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/rotate.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/shrink_dataset.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/tests/test_reduce_dark_flat.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/app/validator.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/convolution.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/fft.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/kernel.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/medfilt.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/padding.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/processing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/ElementOp.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/backproj.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/backproj_polar.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/boundary.h +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/cone.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/convolution.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/dfi_fftshift.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/flatfield.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/fourier_wavelets.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/halftomo.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/helical_padding.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/hierarchical_backproj.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/histogram.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/interpolation.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/medfilt.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/normalization.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/padding.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/proj.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/rotation.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/src/transpose.cu +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/cuda/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/alignment.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/cor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/cor_sino.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/distortion.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/focus.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/motion.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/test_alignment.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/test_cor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/test_focus.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/test_motion_estimation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/test_tilt.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tests/test_translation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/tilt.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/translation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/estimation/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/cast_volume.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/detector_distortion.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/reader.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/reader_helical.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/tests/test_cast_volume.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/tests/test_readers.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/tests/test_remove_volume.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/tests/test_writers.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/io/writer.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/binning.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/fftshift.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/filters.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/fourier_filters.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/histogram.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/histogram_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/kernel_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/padding.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/padding_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/processing_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/rotation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/rotation_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/tests/test_binning.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/tests/test_interpolation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/transpose.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/unsharp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/unsharp_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/unsharp_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/misc/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/fft.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/kernel.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/memcpy.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/padding.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/processing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/ElementOp.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/backproj.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/fftshift.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/halftomo.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/padding.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/roll.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/src/transpose.cl +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/opencl/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/config.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/config_validators.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/datadump.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/dataset_validator.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/detector_distortion_provider.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/chunked.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/chunked_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/computations.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/dataset_validator.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/get_double_flatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/nabu_config.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/processconfig.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/fullfield/reconstruction.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/dataset_validator.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/fbp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/filtering.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/gridded_accumulator.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/helical_chunked_regridded.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/helical_chunked_regridded_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/helical_reconstruction.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/helical_utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/nabu_config.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/processconfig.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/span_strategy.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/helical/weight_balancer.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/params.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/processconfig.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/reader.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/tests/test_estimators.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/writer.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/pipeline/xrdct/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/alignment.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/ccd.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/ccd_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/ctf.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/ctf_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/distortion.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/double_flatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/double_flatfield_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/double_flatfield_variable_region.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/flatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/flatfield_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/flatfield_variable_region.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/phase.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/phase_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/shift.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/shift_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_ccd_corr.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_ctf.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_double_flatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_flatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_paganin.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_pcaflats.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/preproc/tests/test_vshift.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/convolution_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/fft_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/fft_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/fft_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/fftshift.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/histogram.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/histogram_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/kernel_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/medfilt_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/muladd.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/muladd_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/padding_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/padding_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/padding_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/processing_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/roll_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/rotation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/rotation_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_fft.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_fftshift.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_histogram.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_medfilt.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_muladd.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_padding.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_roll.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_rotation.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_transpose.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/tests/test_unsharp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/transpose.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/unsharp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/unsharp_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/processing/unsharp_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/cone.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/fbp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/fbp_base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/fbp_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/filtering.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/filtering_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/filtering_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/hbp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/projection.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/reconstructor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/reconstructor_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/rings.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/rings_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/sinogram.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/sinogram_cuda.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/sinogram_opencl.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_cone.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_deringer.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_fbp.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_filtering.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_halftomo.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_mlem.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_projector.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_reconstructor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/reconstruction/tests/test_sino_normalization.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/cli/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/cor.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/dataset_analyzer.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/gpu.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/logger.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/templates/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/templates/bm05_pag.conf +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/templates/id16_ctf.conf +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/templates/id16_holo.conf +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/templates/id16a_fluo.conf +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/templates/id19_pag.conf +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/tests/test_extract.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/tests/test_nxflatfield.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/tests/test_units.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/resources/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/alignment.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/config.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/definitions.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/frame_composition.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/overlap.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/sample_normalization.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/single_axis_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/slurm_utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/dumper/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/dumper/base.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/dumper/postprocessing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/dumper/preprocessing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/post_processing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/pre_processing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/single_axis.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/stitcher.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/y_stitcher.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher/z_stitcher.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/stitcher_2D.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_alignment.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_config.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_frame_composition.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_overlap.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_sample_normalization.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_slurm_utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_y_preprocessing_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_z_postprocessing_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/tests/test_z_preprocessing_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/utils/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/utils/post_processing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/utils/tests/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/utils/tests/test_post-processing.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/utils/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/y_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/stitching/z_stitching.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/tests.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/testutils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/thirdparty/__init__.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/thirdparty/algotom_convert_sino.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/thirdparty/pore3d_deringer_munch.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/thirdparty/tomocupy_remove_stripe.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/thirdparty/tomopy_phase.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/thirdparty/tomwer_load_flats_darks.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu/utils.py +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu.egg-info/dependency_links.txt +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu.egg-info/entry_points.txt +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/nabu.egg-info/requires.txt +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/pyproject.toml +0 -0
- {nabu-2025.1.0rc4 → nabu-2025.1.0rc5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nabu
|
3
|
-
Version: 2025.1.
|
3
|
+
Version: 2025.1.0rc5
|
4
4
|
Summary: Nabu - Tomography software
|
5
5
|
Author-email: Pierre Paleo <pierre.paleo@esrf.fr>, Henri Payno <henri.payno@esrf.fr>, Alessandro Mirone <mirone@esrf.fr>, Jérôme Lesaint <jerome.lesaint@esrf.fr>
|
6
6
|
Maintainer-email: Pierre Paleo <pierre.paleo@esrf.fr>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
from nabu.resources.nabu_config import nabu_config
|
4
|
+
|
5
|
+
|
6
|
+
def generate(file_):
|
7
|
+
def write(content):
|
8
|
+
print(content, file=file_)
|
9
|
+
for section, values in nabu_config.items():
|
10
|
+
if section == "about":
|
11
|
+
continue
|
12
|
+
write("## %s\n" % section)
|
13
|
+
for key, val in values.items():
|
14
|
+
if val["type"] == "unsupported":
|
15
|
+
continue
|
16
|
+
write(val["help"] + "\n")
|
17
|
+
write(
|
18
|
+
"```ini\n%s = %s\n```"
|
19
|
+
% (key, val["default"])
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
if __name__ == "__main__":
|
25
|
+
|
26
|
+
import sys, os
|
27
|
+
print(os.path.abspath(__file__))
|
28
|
+
exit(0)
|
29
|
+
|
30
|
+
fname = "/tmp/test.md"
|
31
|
+
with open(fname, "w") as f:
|
32
|
+
generate(f)
|
@@ -353,6 +353,11 @@ EstimateMotionConfig = {
|
|
353
353
|
"default": 2,
|
354
354
|
"type": int,
|
355
355
|
},
|
356
|
+
"win_size": {
|
357
|
+
"help": "Size of the look-up window for half-tomography",
|
358
|
+
"default": 300,
|
359
|
+
"type": int,
|
360
|
+
},
|
356
361
|
"verbose": {
|
357
362
|
"help": "Whether to plot the movement estimation fit",
|
358
363
|
"default": 1,
|
@@ -365,6 +370,16 @@ EstimateMotionConfig = {
|
|
365
370
|
"help": "Whether to only generate motion file for horizontal or vertical movement: --only horizontal or --only vertical",
|
366
371
|
"default": "",
|
367
372
|
},
|
373
|
+
"ccd_filter_size": {
|
374
|
+
"help": "Size of conditional median filter to apply on radios. Default is zero (disabled)",
|
375
|
+
"default": 0,
|
376
|
+
"type": int,
|
377
|
+
},
|
378
|
+
"ccd_filter_threshold": {
|
379
|
+
"help": "Threshold for median filter, 'ccd_filter_size' is not zero. Default is 0.04",
|
380
|
+
"default": 0.04,
|
381
|
+
"type": float,
|
382
|
+
},
|
368
383
|
}
|
369
384
|
|
370
385
|
# Default configuration for "stitching" command
|
@@ -1,8 +1,11 @@
|
|
1
1
|
from os import path
|
2
|
+
from multiprocessing.pool import ThreadPool
|
2
3
|
|
4
|
+
from ..utils import get_num_threads
|
3
5
|
from ..resources.nxflatfield import update_dataset_info_flats_darks
|
4
6
|
from ..resources.logger import LoggerOrPrint
|
5
7
|
from ..resources.dataset_analyzer import analyze_dataset
|
8
|
+
from ..preproc.ccd import CCDFilter
|
6
9
|
from ..pipeline.config_validators import convert_to_bool
|
7
10
|
from ..pipeline.estimators import TranslationsEstimator
|
8
11
|
from .utils import parse_params_values
|
@@ -26,6 +29,22 @@ def estimate_motion():
|
|
26
29
|
if do_ff:
|
27
30
|
update_dataset_info_flats_darks(dataset_info, True, loading_mode="load_if_present")
|
28
31
|
|
32
|
+
radios_filter = None
|
33
|
+
do_ccd_filter = args["ccd_filter_size"] > 0
|
34
|
+
if do_ccd_filter:
|
35
|
+
radios_filter_obj = CCDFilter(
|
36
|
+
dataset_info.radio_dims[::-1],
|
37
|
+
kernel_size=args["ccd_filter_size"],
|
38
|
+
median_clip_thresh=args["ccd_filter_threshold"],
|
39
|
+
)
|
40
|
+
|
41
|
+
def radios_filter(images):
|
42
|
+
def _apply_median_clip(img):
|
43
|
+
radios_filter_obj.median_clip_correction(img, output=img)
|
44
|
+
|
45
|
+
with ThreadPool(get_num_threads()) as tp:
|
46
|
+
tp.map(_apply_median_clip, images)
|
47
|
+
|
29
48
|
est = TranslationsEstimator(
|
30
49
|
dataset_info,
|
31
50
|
do_flatfield=do_ff,
|
@@ -34,6 +53,8 @@ def estimate_motion():
|
|
34
53
|
deg_xy=args["deg_xy"],
|
35
54
|
deg_z=args["deg_z"],
|
36
55
|
shifts_estimator="phase_cross_correlation",
|
56
|
+
radios_filter=radios_filter,
|
57
|
+
extra_options={"window_size": args["win_size"]},
|
37
58
|
)
|
38
59
|
|
39
60
|
estimated_shifts_h, estimated_shifts_v, cor = est.estimate_motion()
|
@@ -1000,7 +1000,7 @@ def estimate_translations(dataset_info, do_flatfield=True): ...
|
|
1000
1000
|
class TranslationsEstimator:
|
1001
1001
|
|
1002
1002
|
_default_extra_options = {
|
1003
|
-
"window_size":
|
1003
|
+
"window_size": 300,
|
1004
1004
|
}
|
1005
1005
|
|
1006
1006
|
def __init__(
|
@@ -1013,6 +1013,7 @@ class TranslationsEstimator:
|
|
1013
1013
|
deg_xy=2,
|
1014
1014
|
deg_z=2,
|
1015
1015
|
shifts_estimator="phase_cross_correlation",
|
1016
|
+
radios_filter=None,
|
1016
1017
|
extra_options=None,
|
1017
1018
|
):
|
1018
1019
|
self._configure_extra_options(extra_options)
|
@@ -1021,6 +1022,7 @@ class TranslationsEstimator:
|
|
1021
1022
|
self.angular_subsampling = angular_subsampling
|
1022
1023
|
self.do_360 = self.dataset_info.is_360
|
1023
1024
|
self.do_flatfield = do_flatfield
|
1025
|
+
self.radios_filter = radios_filter
|
1024
1026
|
self.radios = None
|
1025
1027
|
self._deg_xy = deg_xy
|
1026
1028
|
self._deg_z = deg_z
|
@@ -1163,6 +1165,9 @@ class TranslationsEstimator:
|
|
1163
1165
|
def estimate_motion(self):
|
1164
1166
|
self._load_data()
|
1165
1167
|
self._apply_flatfield()
|
1168
|
+
if self.radios_filter is not None:
|
1169
|
+
self.logger.debug("[MotionEstimation] applying radios filter")
|
1170
|
+
self.radios_filter(self.radios)
|
1166
1171
|
|
1167
1172
|
n_projs_tot = self.dataset_info.n_angles
|
1168
1173
|
if self.do_360:
|
@@ -1210,7 +1215,7 @@ class TranslationsEstimator:
|
|
1210
1215
|
self.sample_shifts_z = estimated_shifts_v
|
1211
1216
|
if self._cor is None:
|
1212
1217
|
self.logger.info(
|
1213
|
-
"[MotionEstimation] Estimated center of rotation (relative to
|
1218
|
+
"[MotionEstimation] Estimated center of rotation (relative to left-most pixel): %.2f" % cor
|
1214
1219
|
)
|
1215
1220
|
return estimated_shifts_h, estimated_shifts_v, cor
|
1216
1221
|
|
@@ -96,8 +96,11 @@ def do_radial_distribution(ip, X0, Y0, mR, nBins=None, use_calibration=False, ca
|
|
96
96
|
Accumulator = np.zeros((2, nBins))
|
97
97
|
|
98
98
|
# Define the bounding box
|
99
|
-
|
100
|
-
|
99
|
+
height, width = ip.shape
|
100
|
+
xmin = max(int(X0 - mR), 0)
|
101
|
+
xmax = min(int(X0 + mR), width)
|
102
|
+
ymin = max(int(Y0 - mR), 0)
|
103
|
+
ymax = min(int(Y0 + mR), height)
|
101
104
|
|
102
105
|
# Create grid of coordinates
|
103
106
|
x = np.arange(xmin, xmax)
|
@@ -112,10 +115,11 @@ def do_radial_distribution(ip, X0, Y0, mR, nBins=None, use_calibration=False, ca
|
|
112
115
|
bins = np.clip(bins - 1, 0, nBins - 1) # Adjust bins to be in range [0, nBins-1]
|
113
116
|
|
114
117
|
# Accumulate values
|
118
|
+
sub_image = ip[xmin:xmax, ymin:ymax] # prevent issue on non-square images
|
115
119
|
for b in range(nBins):
|
116
120
|
mask = bins == b
|
117
121
|
Accumulator[0, b] = np.sum(mask)
|
118
|
-
Accumulator[1, b] = np.sum(
|
122
|
+
Accumulator[1, b] = np.sum(sub_image[mask])
|
119
123
|
|
120
124
|
# Normalize integrated intensity
|
121
125
|
Accumulator[1] /= Accumulator[0]
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# ruff: noqa
|
2
|
+
try:
|
3
|
+
import astra
|
4
|
+
|
5
|
+
__have_astra__ = True
|
6
|
+
except ImportError:
|
7
|
+
__have_astra__ = False
|
8
|
+
astra = None
|
9
|
+
|
10
|
+
|
11
|
+
class AstraReconstructor:
|
12
|
+
"""
|
13
|
+
Base class for reconstructors based on the Astra toolbox
|
14
|
+
"""
|
15
|
+
|
16
|
+
default_extra_options = {
|
17
|
+
"axis_correction": None,
|
18
|
+
"clip_outer_circle": False,
|
19
|
+
"scale_factor": None,
|
20
|
+
"filter_cutoff": 1.0,
|
21
|
+
"outer_circle_value": 0.0,
|
22
|
+
}
|
23
|
+
|
24
|
+
def __init__(
|
25
|
+
self,
|
26
|
+
sinos_shape,
|
27
|
+
angles=None,
|
28
|
+
volume_shape=None,
|
29
|
+
rot_center=None,
|
30
|
+
pixel_size=None,
|
31
|
+
padding_mode="zeros",
|
32
|
+
filter_name=None,
|
33
|
+
slice_roi=None,
|
34
|
+
cuda_options=None,
|
35
|
+
extra_options=None,
|
36
|
+
):
|
37
|
+
self._configure_extra_options(extra_options)
|
38
|
+
self._init_cuda(cuda_options)
|
39
|
+
self._set_sino_shape(sinos_shape)
|
40
|
+
self._orig_prog_geom = None
|
41
|
+
self._init_geometry(
|
42
|
+
source_origin_dist,
|
43
|
+
origin_detector_dist,
|
44
|
+
pixel_size,
|
45
|
+
angles,
|
46
|
+
volume_shape,
|
47
|
+
rot_center,
|
48
|
+
relative_z_position,
|
49
|
+
slice_roi,
|
50
|
+
)
|
51
|
+
self._init_fdk(padding_mode, filter_name)
|
52
|
+
self._alg_id = None
|
53
|
+
self._vol_id = None
|
54
|
+
self._proj_id = None
|
55
|
+
|
56
|
+
def _configure_extra_options(self, extra_options):
|
57
|
+
self.extra_options = self.default_extra_options.copy()
|
58
|
+
self.extra_options.update(extra_options or {})
|
59
|
+
|
60
|
+
def _init_cuda(self, cuda_options):
|
61
|
+
cuda_options = cuda_options or {}
|
62
|
+
self.cuda = CudaProcessing(**cuda_options)
|
63
|
+
|
64
|
+
def _set_sino_shape(self, sinos_shape):
|
65
|
+
if len(sinos_shape) != 3:
|
66
|
+
raise ValueError("Expected a 3D shape")
|
67
|
+
self.sinos_shape = sinos_shape
|
68
|
+
self.n_sinos, self.n_angles, self.prj_width = sinos_shape
|
69
|
+
|
70
|
+
def _set_pixel_size(self, pixel_size):
|
71
|
+
if pixel_size is None:
|
72
|
+
det_spacing_y = det_spacing_x = 1
|
73
|
+
elif np.iterable(pixel_size):
|
74
|
+
det_spacing_y, det_spacing_x = pixel_size
|
75
|
+
else:
|
76
|
+
# assuming scalar
|
77
|
+
det_spacing_y = det_spacing_x = pixel_size
|
78
|
+
self._det_spacing_y = det_spacing_y
|
79
|
+
self._det_spacing_x = det_spacing_x
|
80
|
+
|
81
|
+
def _set_slice_roi(self, slice_roi):
|
82
|
+
self.slice_roi = slice_roi
|
83
|
+
self._vol_geom_n_x = self.n_x
|
84
|
+
self._vol_geom_n_y = self.n_y
|
85
|
+
self._crop_data = True
|
86
|
+
if slice_roi is None:
|
87
|
+
return
|
88
|
+
start_x, end_x, start_y, end_y = slice_roi
|
89
|
+
if roi_is_centered(self.volume_shape[1:], (slice(start_y, end_y), slice(start_x, end_x))):
|
90
|
+
# Astra can only reconstruct subregion centered around the origin
|
91
|
+
self._vol_geom_n_x = self.n_x - start_x * 2
|
92
|
+
self._vol_geom_n_y = self.n_y - start_y * 2
|
93
|
+
else:
|
94
|
+
raise NotImplementedError(
|
95
|
+
"Astra supports only slice_roi centered around origin (got slice_roi=%s with n_x=%d, n_y=%d)"
|
96
|
+
% (str(slice_roi), self.n_x, self.n_y)
|
97
|
+
)
|
98
|
+
|
99
|
+
def _init_geometry(
|
100
|
+
self,
|
101
|
+
source_origin_dist,
|
102
|
+
origin_detector_dist,
|
103
|
+
pixel_size,
|
104
|
+
angles,
|
105
|
+
volume_shape,
|
106
|
+
rot_center,
|
107
|
+
relative_z_position,
|
108
|
+
slice_roi,
|
109
|
+
):
|
110
|
+
if angles is None:
|
111
|
+
self.angles = np.linspace(0, 2 * np.pi, self.n_angles, endpoint=True)
|
112
|
+
else:
|
113
|
+
self.angles = angles
|
114
|
+
if volume_shape is None:
|
115
|
+
volume_shape = (self.sinos_shape[0], self.sinos_shape[2], self.sinos_shape[2])
|
116
|
+
self.volume_shape = volume_shape
|
117
|
+
self.n_z, self.n_y, self.n_x = self.volume_shape
|
118
|
+
self.source_origin_dist = source_origin_dist
|
119
|
+
self.origin_detector_dist = origin_detector_dist
|
120
|
+
self.magnification = 1 + origin_detector_dist / source_origin_dist
|
121
|
+
self._set_slice_roi(slice_roi)
|
122
|
+
self.vol_geom = astra.create_vol_geom(self._vol_geom_n_y, self._vol_geom_n_x, self.n_z)
|
123
|
+
self.vol_shape = astra.geom_size(self.vol_geom)
|
124
|
+
self._cor_shift = 0.0
|
125
|
+
self.rot_center = rot_center
|
126
|
+
if rot_center is not None:
|
127
|
+
self._cor_shift = (self.sinos_shape[-1] - 1) / 2.0 - rot_center
|
128
|
+
self._set_pixel_size(pixel_size)
|
129
|
+
self._axis_corrections = self.extra_options.get("axis_correction", None)
|
130
|
+
self._create_astra_proj_geometry(relative_z_position)
|
131
|
+
|
132
|
+
def _create_astra_proj_geometry(self, relative_z_position):
|
133
|
+
# This object has to be re-created each time, because once the modifications below are done,
|
134
|
+
# it is no more a "cone" geometry but a "cone_vec" geometry, and cannot be updated subsequently
|
135
|
+
# (see astra/functions.py:271)
|
136
|
+
self.proj_geom = astra.create_proj_geom(
|
137
|
+
"cone",
|
138
|
+
self._det_spacing_x,
|
139
|
+
self._det_spacing_y,
|
140
|
+
self.n_sinos,
|
141
|
+
self.prj_width,
|
142
|
+
self.angles,
|
143
|
+
self.source_origin_dist,
|
144
|
+
self.origin_detector_dist,
|
145
|
+
)
|
146
|
+
self.relative_z_position = relative_z_position or 0.0
|
147
|
+
# This will turn the geometry of type "cone" into a geometry of type "cone_vec"
|
148
|
+
if self._orig_prog_geom is None:
|
149
|
+
self._orig_prog_geom = self.proj_geom
|
150
|
+
self.proj_geom = astra.geom_postalignment(self.proj_geom, (self._cor_shift, 0))
|
151
|
+
# (src, detector_center, u, v) = (srcX, srcY, srcZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ)
|
152
|
+
vecs = self.proj_geom["Vectors"]
|
153
|
+
|
154
|
+
# To adapt the center of rotation:
|
155
|
+
# dX = cor_shift * cos(theta) - origin_detector_dist * sin(theta)
|
156
|
+
# dY = origin_detector_dist * cos(theta) + cor_shift * sin(theta)
|
157
|
+
if self._axis_corrections is not None:
|
158
|
+
# should we check that dX and dY match the above formulas ?
|
159
|
+
cor_shifts = self._cor_shift + self._axis_corrections
|
160
|
+
vecs[:, 3] = cor_shifts * np.cos(self.angles) - self.origin_detector_dist * np.sin(self.angles)
|
161
|
+
vecs[:, 4] = self.origin_detector_dist * np.cos(self.angles) + cor_shifts * np.sin(self.angles)
|
162
|
+
|
163
|
+
# To adapt the z position:
|
164
|
+
# Component 2 of vecs is the z coordinate of the source, component 5 is the z component of the detector position
|
165
|
+
# We need to re-create the same inclination of the cone beam, thus we need to keep the inclination of the two z positions.
|
166
|
+
# The detector is centered on the rotation axis, thus moving it up or down, just moves it out of the reconstruction volume.
|
167
|
+
# We can bring back the detector in the correct volume position, by applying a rigid translation of both the detector and the source.
|
168
|
+
# The translation is exactly the amount that brought the detector up or down, but in the opposite direction.
|
169
|
+
vecs[:, 2] = -self.relative_z_position
|
170
|
+
|
171
|
+
def _set_output(self, volume):
|
172
|
+
if volume is not None:
|
173
|
+
expected_shape = self.vol_shape # if not (self._crop_data) else self._output_cropped_shape
|
174
|
+
self.cuda.check_array(volume, expected_shape)
|
175
|
+
self.cuda.set_array("output", volume)
|
176
|
+
if volume is None:
|
177
|
+
self.cuda.allocate_array("output", self.vol_shape)
|
178
|
+
d_volume = self.cuda.get_array("output")
|
179
|
+
z, y, x = d_volume.shape
|
180
|
+
self._vol_link = astra.data3d.GPULink(d_volume.ptr, x, y, z, d_volume.strides[-2])
|
181
|
+
self._vol_id = astra.data3d.link("-vol", self.vol_geom, self._vol_link)
|
182
|
+
|
183
|
+
def _set_input(self, sinos):
|
184
|
+
self.cuda.check_array(sinos, self.sinos_shape)
|
185
|
+
self.cuda.set_array("sinos", sinos) # self.cuda.sinos is now a GPU array
|
186
|
+
# TODO don't create new link/proj_id if ptr is the same ?
|
187
|
+
# But it seems Astra modifies the input sinogram while doing FDK, so this might be not relevant
|
188
|
+
d_sinos = self.cuda.get_array("sinos")
|
189
|
+
|
190
|
+
# self._proj_data_link = astra.data3d.GPULink(d_sinos.ptr, self.prj_width, self.n_angles, self.n_z, sinos.strides[-2])
|
191
|
+
self._proj_data_link = astra.data3d.GPULink(
|
192
|
+
d_sinos.ptr, self.prj_width, self.n_angles, self.n_sinos, d_sinos.strides[-2]
|
193
|
+
)
|
194
|
+
self._proj_id = astra.data3d.link("-sino", self.proj_geom, self._proj_data_link)
|
195
|
+
|
196
|
+
def _preprocess_data(self):
|
197
|
+
d_sinos = self.cuda.sinos
|
198
|
+
for i in range(d_sinos.shape[0]):
|
199
|
+
self.sino_filter.filter_sino(d_sinos[i], output=d_sinos[i])
|
200
|
+
|
201
|
+
def _update_reconstruction(self):
|
202
|
+
cfg = astra.astra_dict("BP3D_CUDA")
|
203
|
+
cfg["ReconstructionDataId"] = self._vol_id
|
204
|
+
cfg["ProjectionDataId"] = self._proj_id
|
205
|
+
if self._alg_id is not None:
|
206
|
+
astra.algorithm.delete(self._alg_id)
|
207
|
+
self._alg_id = astra.algorithm.create(cfg)
|
208
|
+
|
209
|
+
def reconstruct(self, sinos, output=None, relative_z_position=None):
|
210
|
+
"""
|
211
|
+
sinos: numpy.ndarray or pycuda.gpuarray
|
212
|
+
Sinograms, with shape (n_sinograms, n_angles, width)
|
213
|
+
output: pycuda.gpuarray, optional
|
214
|
+
Output array. If not provided, a new numpy array is returned
|
215
|
+
relative_z_position: int, optional
|
216
|
+
Position of the central slice of the slab, with respect to the full stack of slices.
|
217
|
+
By default it is set to zero, meaning that the current slab is assumed in the middle of the stack
|
218
|
+
"""
|
219
|
+
self._create_astra_proj_geometry(relative_z_position)
|
220
|
+
self._set_input(sinos)
|
221
|
+
self._set_output(output)
|
222
|
+
self._preprocess_data()
|
223
|
+
self._update_reconstruction()
|
224
|
+
astra.algorithm.run(self._alg_id)
|
225
|
+
#
|
226
|
+
# NB: Could also be done with
|
227
|
+
# from astra.experimental import direct_BP3D
|
228
|
+
# projector_id = astra.create_projector("cuda3d", self.proj_geom, self.vol_geom, options=None)
|
229
|
+
# direct_BP3D(projector_id, self._vol_link, self._proj_data_link)
|
230
|
+
#
|
231
|
+
result = self.cuda.get_array("output")
|
232
|
+
if output is None:
|
233
|
+
result = result.get()
|
234
|
+
if self.extra_options.get("scale_factor", None) is not None:
|
235
|
+
result *= np.float32(self.extra_options["scale_factor"]) # in-place for pycuda
|
236
|
+
self.cuda.recover_arrays_references(["sinos", "output"])
|
237
|
+
return result
|
238
|
+
|
239
|
+
def __del__(self):
|
240
|
+
if getattr(self, "_alg_id", None) is not None:
|
241
|
+
astra.algorithm.delete(self._alg_id)
|
242
|
+
if getattr(self, "_vol_id", None) is not None:
|
243
|
+
astra.data3d.delete(self._vol_id)
|
244
|
+
if getattr(self, "_proj_id", None) is not None:
|
245
|
+
astra.data3d.delete(self._proj_id)
|
@@ -104,7 +104,7 @@ class MLEMReconstructor:
|
|
104
104
|
def reset_rot_center(self, cor):
|
105
105
|
self.cor = -cor + (self.sinos_shape[-1] - 1) / 2.0
|
106
106
|
|
107
|
-
def reconstruct(self, data_vwu):
|
107
|
+
def reconstruct(self, data_vwu, x0=None):
|
108
108
|
"""
|
109
109
|
data_align_vwu: numpy.ndarray or pycuda.gpuarray
|
110
110
|
Raw data, with shape (n_sinograms, n_angles, width)
|
@@ -134,5 +134,5 @@ class MLEMReconstructor:
|
|
134
134
|
with cct.projectors.ProjectorUncorrected(
|
135
135
|
self.vol_geom_align, self.angles_rad, rot_axis_shift_pix=self.cor, prj_geom=self.prj_geom_align
|
136
136
|
) as A:
|
137
|
-
rec, _ = solver(A, data_vwu, iterations=self.n_iterations, **self.solver_opts)
|
137
|
+
rec, _ = solver(A, data_vwu, iterations=self.n_iterations, x0=x0, **self.solver_opts)
|
138
138
|
return rec * self.scale_factor
|
@@ -71,7 +71,7 @@ def save_reduced_frames(dataset_info, reduced_frames_arrays, reduced_frames_urls
|
|
71
71
|
darks_flats_dir_url = reduced_frames_urls.get("user", None)
|
72
72
|
if darks_flats_dir_url is not None:
|
73
73
|
output_url = darks_flats_dir_url
|
74
|
-
elif is_writeable(os.path.dirname(reduced_frames_urls["dataset"]["flats"].file_path())):
|
74
|
+
elif is_writeable(os.path.abspath(os.path.dirname(reduced_frames_urls["dataset"]["flats"].file_path()))):
|
75
75
|
output_url = reduced_frames_urls["dataset"]
|
76
76
|
else:
|
77
77
|
output_url = reduced_frames_urls["output"]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nabu
|
3
|
-
Version: 2025.1.
|
3
|
+
Version: 2025.1.0rc5
|
4
4
|
Summary: Nabu - Tomography software
|
5
5
|
Author-email: Pierre Paleo <pierre.paleo@esrf.fr>, Henri Payno <henri.payno@esrf.fr>, Alessandro Mirone <mirone@esrf.fr>, Jérôme Lesaint <jerome.lesaint@esrf.fr>
|
6
6
|
Maintainer-email: Pierre Paleo <pierre.paleo@esrf.fr>
|
@@ -3,6 +3,7 @@ README.md
|
|
3
3
|
pyproject.toml
|
4
4
|
doc/conf.py
|
5
5
|
doc/create_conf_doc.py
|
6
|
+
doc/doc_config.py
|
6
7
|
doc/get_mathjax.py
|
7
8
|
nabu/__init__.py
|
8
9
|
nabu/tests.py
|
@@ -236,6 +237,7 @@ nabu/processing/tests/test_rotation.py
|
|
236
237
|
nabu/processing/tests/test_transpose.py
|
237
238
|
nabu/processing/tests/test_unsharp.py
|
238
239
|
nabu/reconstruction/__init__.py
|
240
|
+
nabu/reconstruction/astra.py
|
239
241
|
nabu/reconstruction/cone.py
|
240
242
|
nabu/reconstruction/fbp.py
|
241
243
|
nabu/reconstruction/fbp_base.py
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|