nabu 2024.1.9__py3-none-any.whl → 2024.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. nabu/__init__.py +1 -1
  2. nabu/app/bootstrap.py +2 -3
  3. nabu/app/cast_volume.py +4 -2
  4. nabu/app/cli_configs.py +5 -0
  5. nabu/app/composite_cor.py +1 -1
  6. nabu/app/create_distortion_map_from_poly.py +5 -6
  7. nabu/app/diag_to_pix.py +7 -19
  8. nabu/app/diag_to_rot.py +14 -29
  9. nabu/app/double_flatfield.py +32 -44
  10. nabu/app/parse_reconstruction_log.py +3 -0
  11. nabu/app/reconstruct.py +53 -15
  12. nabu/app/reconstruct_helical.py +2 -2
  13. nabu/app/stitching.py +27 -13
  14. nabu/app/tests/test_reduce_dark_flat.py +4 -1
  15. nabu/cuda/kernel.py +11 -2
  16. nabu/cuda/processing.py +2 -2
  17. nabu/cuda/src/cone.cu +77 -0
  18. nabu/cuda/src/hierarchical_backproj.cu +271 -0
  19. nabu/cuda/utils.py +0 -6
  20. nabu/estimation/alignment.py +5 -19
  21. nabu/estimation/cor.py +173 -599
  22. nabu/estimation/cor_sino.py +356 -26
  23. nabu/estimation/focus.py +63 -11
  24. nabu/estimation/tests/test_cor.py +124 -58
  25. nabu/estimation/tests/test_focus.py +6 -6
  26. nabu/estimation/tilt.py +2 -1
  27. nabu/estimation/utils.py +5 -33
  28. nabu/io/__init__.py +1 -1
  29. nabu/io/cast_volume.py +1 -1
  30. nabu/io/reader.py +416 -21
  31. nabu/io/tests/test_readers.py +422 -0
  32. nabu/io/tests/test_writers.py +1 -102
  33. nabu/io/writer.py +4 -433
  34. nabu/opencl/kernel.py +14 -3
  35. nabu/opencl/processing.py +8 -0
  36. nabu/pipeline/config_validators.py +5 -2
  37. nabu/pipeline/datadump.py +12 -5
  38. nabu/pipeline/estimators.py +162 -188
  39. nabu/pipeline/fullfield/chunked.py +168 -92
  40. nabu/pipeline/fullfield/chunked_cuda.py +7 -3
  41. nabu/pipeline/fullfield/computations.py +2 -7
  42. nabu/pipeline/fullfield/dataset_validator.py +0 -4
  43. nabu/pipeline/fullfield/nabu_config.py +37 -13
  44. nabu/pipeline/fullfield/processconfig.py +22 -13
  45. nabu/pipeline/fullfield/reconstruction.py +13 -9
  46. nabu/pipeline/helical/helical_chunked_regridded.py +1 -1
  47. nabu/pipeline/helical/helical_chunked_regridded_cuda.py +1 -0
  48. nabu/pipeline/helical/helical_reconstruction.py +1 -1
  49. nabu/pipeline/params.py +21 -1
  50. nabu/pipeline/processconfig.py +1 -12
  51. nabu/pipeline/reader.py +146 -0
  52. nabu/pipeline/tests/test_estimators.py +44 -72
  53. nabu/pipeline/utils.py +4 -2
  54. nabu/pipeline/writer.py +10 -2
  55. nabu/preproc/ccd_cuda.py +1 -1
  56. nabu/preproc/ctf.py +14 -7
  57. nabu/preproc/ctf_cuda.py +2 -3
  58. nabu/preproc/double_flatfield.py +5 -12
  59. nabu/preproc/double_flatfield_cuda.py +2 -2
  60. nabu/preproc/flatfield.py +5 -1
  61. nabu/preproc/flatfield_cuda.py +5 -1
  62. nabu/preproc/phase.py +24 -73
  63. nabu/preproc/phase_cuda.py +5 -8
  64. nabu/preproc/tests/test_ctf.py +11 -7
  65. nabu/preproc/tests/test_flatfield.py +67 -122
  66. nabu/preproc/tests/test_paganin.py +54 -30
  67. nabu/processing/azim.py +206 -0
  68. nabu/processing/convolution_cuda.py +1 -1
  69. nabu/processing/fft_cuda.py +15 -17
  70. nabu/processing/histogram.py +2 -0
  71. nabu/processing/histogram_cuda.py +2 -1
  72. nabu/processing/kernel_base.py +3 -0
  73. nabu/processing/muladd_cuda.py +1 -0
  74. nabu/processing/padding_opencl.py +1 -1
  75. nabu/processing/roll_opencl.py +1 -0
  76. nabu/processing/rotation_cuda.py +2 -2
  77. nabu/processing/tests/test_fft.py +17 -10
  78. nabu/processing/unsharp_cuda.py +1 -1
  79. nabu/reconstruction/cone.py +104 -40
  80. nabu/reconstruction/fbp.py +3 -0
  81. nabu/reconstruction/fbp_base.py +7 -2
  82. nabu/reconstruction/filtering.py +20 -7
  83. nabu/reconstruction/filtering_cuda.py +7 -1
  84. nabu/reconstruction/hbp.py +424 -0
  85. nabu/reconstruction/mlem.py +99 -0
  86. nabu/reconstruction/reconstructor.py +2 -0
  87. nabu/reconstruction/rings_cuda.py +19 -19
  88. nabu/reconstruction/sinogram_cuda.py +1 -0
  89. nabu/reconstruction/sinogram_opencl.py +3 -1
  90. nabu/reconstruction/tests/test_cone.py +10 -5
  91. nabu/reconstruction/tests/test_deringer.py +7 -6
  92. nabu/reconstruction/tests/test_fbp.py +124 -10
  93. nabu/reconstruction/tests/test_filtering.py +13 -11
  94. nabu/reconstruction/tests/test_halftomo.py +30 -4
  95. nabu/reconstruction/tests/test_mlem.py +91 -0
  96. nabu/reconstruction/tests/test_reconstructor.py +8 -3
  97. nabu/resources/dataset_analyzer.py +142 -92
  98. nabu/resources/gpu.py +1 -0
  99. nabu/resources/nxflatfield.py +134 -125
  100. nabu/resources/templates/id16a_fluo.conf +42 -0
  101. nabu/resources/tests/test_extract.py +10 -0
  102. nabu/resources/tests/test_nxflatfield.py +2 -2
  103. nabu/stitching/alignment.py +80 -24
  104. nabu/stitching/config.py +105 -68
  105. nabu/stitching/definitions.py +1 -0
  106. nabu/stitching/frame_composition.py +68 -60
  107. nabu/stitching/overlap.py +91 -51
  108. nabu/stitching/single_axis_stitching.py +32 -0
  109. nabu/stitching/slurm_utils.py +6 -6
  110. nabu/stitching/stitcher/__init__.py +0 -0
  111. nabu/stitching/stitcher/base.py +124 -0
  112. nabu/stitching/stitcher/dumper/__init__.py +3 -0
  113. nabu/stitching/stitcher/dumper/base.py +94 -0
  114. nabu/stitching/stitcher/dumper/postprocessing.py +356 -0
  115. nabu/stitching/stitcher/dumper/preprocessing.py +60 -0
  116. nabu/stitching/stitcher/post_processing.py +555 -0
  117. nabu/stitching/stitcher/pre_processing.py +1068 -0
  118. nabu/stitching/stitcher/single_axis.py +484 -0
  119. nabu/stitching/stitcher/stitcher.py +0 -0
  120. nabu/stitching/stitcher/y_stitcher.py +13 -0
  121. nabu/stitching/stitcher/z_stitcher.py +45 -0
  122. nabu/stitching/stitcher_2D.py +278 -0
  123. nabu/stitching/tests/test_config.py +12 -37
  124. nabu/stitching/tests/test_frame_composition.py +33 -59
  125. nabu/stitching/tests/test_overlap.py +149 -7
  126. nabu/stitching/tests/test_utils.py +1 -1
  127. nabu/stitching/tests/test_y_preprocessing_stitching.py +132 -0
  128. nabu/stitching/tests/{test_z_stitching.py → test_z_postprocessing_stitching.py} +167 -561
  129. nabu/stitching/tests/test_z_preprocessing_stitching.py +431 -0
  130. nabu/stitching/utils/__init__.py +1 -0
  131. nabu/stitching/utils/post_processing.py +281 -0
  132. nabu/stitching/utils/tests/test_post-processing.py +21 -0
  133. nabu/stitching/{utils.py → utils/utils.py} +79 -52
  134. nabu/stitching/y_stitching.py +27 -0
  135. nabu/stitching/z_stitching.py +32 -2263
  136. nabu/testutils.py +1 -152
  137. nabu/thirdparty/tomocupy_remove_stripe.py +43 -9
  138. nabu/utils.py +158 -61
  139. {nabu-2024.1.9.dist-info → nabu-2024.2.0.dist-info}/METADATA +10 -3
  140. {nabu-2024.1.9.dist-info → nabu-2024.2.0.dist-info}/RECORD +144 -121
  141. nabu/io/tiffwriter_zmm.py +0 -99
  142. nabu/pipeline/fallback_utils.py +0 -149
  143. nabu/pipeline/helical/tests/test_accumulator.py +0 -158
  144. nabu/pipeline/helical/tests/test_pipeline_elements_full.py +0 -355
  145. nabu/pipeline/helical/tests/test_strategy.py +0 -61
  146. nabu/pipeline/helical/utils.py +0 -51
  147. nabu/pipeline/tests/test_chunk_reader.py +0 -74
  148. {nabu-2024.1.9.dist-info → nabu-2024.2.0.dist-info}/LICENSE +0 -0
  149. {nabu-2024.1.9.dist-info → nabu-2024.2.0.dist-info}/WHEEL +0 -0
  150. {nabu-2024.1.9.dist-info → nabu-2024.2.0.dist-info}/entry_points.txt +0 -0
  151. {nabu-2024.1.9.dist-info → nabu-2024.2.0.dist-info}/top_level.txt +0 -0
@@ -1,61 +0,0 @@
1
- import pytest
2
- import numpy as np
3
- from nabu.testutils import get_data as nabu_get_data
4
- from nabu.pipeline.helical.span_strategy import SpanStrategy
5
-
6
-
7
- @pytest.fixture(scope="class")
8
- def bootstrap_TestStrategy(request):
9
- cls = request.cls
10
- cls.abs_tol = 1.0e-6
11
-
12
- # from the Paul telephone dataset
13
- test_data = nabu_get_data("data_test_strategy.npz")
14
-
15
- cls.z_pix_per_proj = test_data["z_pix_per_proj"]
16
- cls.x_pix_per_proj = test_data["x_pix_per_proj"]
17
- cls.detector_shape_vh = test_data["detector_shape_vh"]
18
- cls.phase_margin_pix = test_data["phase_margin_pix"]
19
- cls.projection_angles_deg = test_data["projection_angles_deg"]
20
- cls.require_redundancy = test_data["require_redundancy"]
21
- cls.pixel_size_mm = test_data["pixel_size_mm"]
22
-
23
- cls.result_angle_index_span = test_data["result_angle_index_span"]
24
- cls.result_angles_rad = test_data["result_angles_rad"]
25
- cls.result_fract_complement_to_integer_shift_v = test_data["result_fract_complement_to_integer_shift_v"]
26
- cls.result_integer_shift_v = test_data["result_integer_shift_v"]
27
- cls.result_span_v = test_data["result_span_v"]
28
- cls.result_x_pix_per_proj = test_data["result_x_pix_per_proj"]
29
- cls.result_z_pix_per_proj = test_data["result_z_pix_per_proj"]
30
-
31
- cls.test_data = test_data
32
-
33
-
34
- @pytest.mark.usefixtures("bootstrap_TestStrategy")
35
- class TestStrategy:
36
- def test_strategy(self):
37
- # the python implementation is slow. so we take only a p[art of the scan
38
- limit = 4000
39
- span_info = SpanStrategy(
40
- z_pix_per_proj=self.z_pix_per_proj[:limit],
41
- x_pix_per_proj=self.x_pix_per_proj[:limit],
42
- detector_shape_vh=self.detector_shape_vh,
43
- phase_margin_pix=self.phase_margin_pix,
44
- projection_angles_deg=self.projection_angles_deg[:limit],
45
- pixel_size_mm=self.pixel_size_mm,
46
- require_redundancy=self.require_redundancy,
47
- )
48
-
49
- print(span_info.get_informative_string())
50
- chunk_info = span_info.get_chunk_info(self.result_span_v)
51
-
52
- for key, val in chunk_info.__dict__.items():
53
- reference = getattr(self, "result_" + key)
54
- ref_array = np.array(reference)
55
- res_array = np.array(val)
56
- if res_array.dtype in [bool, np.int32, np.int64]:
57
- message = f" different result for {key} attribute in the chunk_info returned value "
58
- assert np.array_equal(res_array, ref_array), message
59
- elif res_array.dtype in [np.float32, np.float64]:
60
- message = f" different result for {key} attribute in the chunk_info returned value "
61
- assert np.all(np.isclose(res_array, ref_array, atol=self.abs_tol)), message
@@ -1,51 +0,0 @@
1
- from ...utils import *
2
- from ...io.writer import Writers, NXProcessWriter
3
- from ...io.tiffwriter_zmm import TIFFWriter
4
- from ...resources.logger import LoggerOrPrint
5
- from ...resources.utils import is_hdf5_extension
6
- from os import path, mkdir
7
- from ...utils import check_supported
8
- from ..fallback_utils import WriterConfigurator
9
- from ..params import files_formats
10
-
11
- Writers["tif"] = TIFFWriter
12
- Writers["tiff"] = TIFFWriter
13
-
14
-
15
- class WriterConfiguratorHelical(WriterConfigurator):
16
- def _get_initial_writer_kwarg(self):
17
- if self.file_format in ["tif", "tiff"]:
18
- return {"heights_above_stage_mm": self.heights_above_stage_mm}
19
- else:
20
- return {}
21
-
22
- def __init__(
23
- self,
24
- output_dir,
25
- file_prefix,
26
- file_format="hdf5",
27
- overwrite=False,
28
- start_index=None,
29
- logger=None,
30
- nx_info=None,
31
- write_histogram=False,
32
- histogram_entry="entry",
33
- writer_options=None,
34
- extra_options=None,
35
- heights_above_stage_mm=None,
36
- ):
37
- self.heights_above_stage_mm = heights_above_stage_mm
38
- self.file_format = file_format
39
- super().__init__(
40
- output_dir,
41
- file_prefix,
42
- file_format=file_format,
43
- overwrite=overwrite,
44
- start_index=start_index,
45
- logger=logger,
46
- nx_info=nx_info,
47
- write_histogram=write_histogram,
48
- histogram_entry=histogram_entry,
49
- writer_options=writer_options,
50
- extra_options=extra_options,
51
- )
@@ -1,74 +0,0 @@
1
- import numpy as np
2
- import pytest
3
- from nabu.io.utils import get_compacted_dataslices
4
- from nabu.resources.dataset_analyzer import HDF5DatasetAnalyzer
5
- from nabu.testutils import compare_arrays, __do_long_tests__, get_file
6
- from nabu.io.reader import ChunkReader
7
-
8
-
9
- @pytest.fixture(scope="class")
10
- def bootstrap(request):
11
- cls = request.cls
12
-
13
- cls.dataset_fname = get_file("bamboo_reduced.nx")
14
- cls.tol = 1e-7
15
-
16
-
17
- def get_compacted_dataslices_as_sorted_tuples(reader):
18
- slice_to_tuple = lambda s: (s.start, s.stop, s.step)
19
- data_slices_tuples = list(
20
- set(
21
- [
22
- slice_to_tuple(u.data_slice())
23
- for u in get_compacted_dataslices(
24
- reader.files, subsampling=reader.dataset_subsampling, begin=reader._files_begin_idx
25
- ).values()
26
- ]
27
- )
28
- )
29
- return sorted(data_slices_tuples, key=lambda t: t[0])
30
-
31
-
32
- @pytest.mark.skipif(not (__do_long_tests__), reason="Use __do_long_tests__ for this test")
33
- @pytest.mark.usefixtures("bootstrap")
34
- class TestChunkReader:
35
- def test_subsampling(self):
36
- """
37
- Test reading data from even/odd projections
38
- """
39
- dataset_info = HDF5DatasetAnalyzer(self.dataset_fname)
40
-
41
- # Read all projections, then only even-numbered ones, then odd-numbered ones
42
- # Use the same object to hopefully use less memory (through garbage collection)
43
- reader = ChunkReader(dataset_info.projections, dataset_subsampling=None)
44
- reader.load_data()
45
- first_sino_all = reader.data[:, 0, :].copy()
46
- compacted_dataslices_all = get_compacted_dataslices_as_sorted_tuples(reader)
47
-
48
- reader = ChunkReader(dataset_info.projections, dataset_subsampling=(2, 0))
49
- reader.load_data()
50
- first_sino_even = reader.data[:, 0, :].copy()
51
- compacted_dataslices_even = get_compacted_dataslices_as_sorted_tuples(reader)
52
-
53
- reader = ChunkReader(dataset_info.projections, dataset_subsampling=(2, 1))
54
- reader.load_data()
55
- first_sino_odd = reader.data[:, 0, :].copy()
56
- compacted_dataslices_odd = get_compacted_dataslices_as_sorted_tuples(reader)
57
-
58
- # Check that the compacted data slices are correct
59
- assert len(compacted_dataslices_all) == len(compacted_dataslices_even) == len(compacted_dataslices_odd)
60
- for data_slice_all, data_slice_even, data_slice_odd in zip(
61
- compacted_dataslices_all, compacted_dataslices_even, compacted_dataslices_odd
62
- ):
63
- indices_all = np.arange(100000)[slice(*data_slice_all)]
64
- indices_even = np.arange(100000)[slice(*data_slice_even)]
65
- indices_odd = np.arange(100000)[slice(*data_slice_odd)]
66
- assert indices_all[::2].size == indices_even.size
67
- assert np.allclose(indices_all[::2], indices_even)
68
- assert indices_all[1::2].size == indices_odd.size
69
- assert np.allclose(indices_all[1::2], indices_odd)
70
-
71
- is_close, max_err = compare_arrays(first_sino_all[::2, :], first_sino_even, self.tol, return_residual=True)
72
- assert is_close, "ChunkReader: something wrong when subsampling for even projections. max_err=%.3e" % max_err
73
- is_close, max_err = compare_arrays(first_sino_all[1::2, :], first_sino_odd, self.tol, return_residual=True)
74
- assert is_close, "ChunkReader: something wrong when subsampling for odd projections. max_err=%.3e" % max_err