nabu 2024.1.6__py3-none-any.whl → 2024.1.8__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.
- doc/doc_config.py +32 -0
- nabu/__init__.py +1 -1
- nabu/pipeline/fullfield/chunked.py +18 -10
- nabu/pipeline/fullfield/dataset_validator.py +5 -1
- nabu/pipeline/fullfield/processconfig.py +8 -3
- nabu/pipeline/fullfield/reconstruction.py +10 -0
- nabu/pipeline/helical/tests/test_accumulator.py +2 -1
- nabu/pipeline/processconfig.py +4 -1
- nabu/processing/tests/test_fftshift.py +1 -0
- nabu/reconstruction/cone.py +22 -1
- nabu/reconstruction/tests/test_cone.py +61 -2
- nabu/reconstruction/tests/test_deringer.py +3 -3
- nabu/reconstruction/tests/test_halftomo.py +2 -1
- nabu/stitching/tests/test_z_stitching.py +0 -13
- nabu/stitching/z_stitching.py +1 -1
- {nabu-2024.1.6.dist-info → nabu-2024.1.8.dist-info}/METADATA +3 -3
- {nabu-2024.1.6.dist-info → nabu-2024.1.8.dist-info}/RECORD +21 -21
- {nabu-2024.1.6.dist-info → nabu-2024.1.8.dist-info}/WHEEL +1 -1
- nabu/app/tests/__init__.py +0 -0
- {nabu-2024.1.6.dist-info → nabu-2024.1.8.dist-info}/LICENSE +0 -0
- {nabu-2024.1.6.dist-info → nabu-2024.1.8.dist-info}/entry_points.txt +0 -0
- {nabu-2024.1.6.dist-info → nabu-2024.1.8.dist-info}/top_level.txt +0 -0
doc/doc_config.py
ADDED
@@ -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)
|
nabu/__init__.py
CHANGED
@@ -548,7 +548,6 @@ class ChunkedPipeline:
|
|
548
548
|
|
549
549
|
if options["method"] == "FBP":
|
550
550
|
n_slices = self.n_slices
|
551
|
-
radios_shape_for_sino_builder = self.radios_cropped_shape
|
552
551
|
self.reconstruction = self.FBPClass(
|
553
552
|
self.sinos_shape[1:],
|
554
553
|
angles=options["angles"],
|
@@ -567,7 +566,6 @@ class ChunkedPipeline:
|
|
567
566
|
)
|
568
567
|
|
569
568
|
if options["method"] == "cone":
|
570
|
-
radios_shape_for_sino_builder = self.radios_shape
|
571
569
|
n_slices = self.n_slices + sum(self.margin[0])
|
572
570
|
# For numerical stability, normalize all lengths with respect to detector pixel size
|
573
571
|
pixel_size_m = self.dataset_info.pixel_size * 1e-6
|
@@ -577,17 +575,16 @@ class ChunkedPipeline:
|
|
577
575
|
(self.radios_shape[1],) + self.sino_shape,
|
578
576
|
source_sample_dist,
|
579
577
|
sample_detector_dist,
|
580
|
-
angles
|
581
|
-
# TODO one center for each angle to handle "x translations"
|
578
|
+
angles=-options["angles"],
|
582
579
|
rot_center=options["rotation_axis_position"],
|
580
|
+
axis_correction=-options["axis_correction"],
|
583
581
|
pixel_size=1,
|
582
|
+
scale_factor=1.0 / options["voxel_size_cm"][0],
|
584
583
|
)
|
585
584
|
|
586
585
|
self._allocate_recs(*self.process_config.rec_shape, n_slices=n_slices)
|
587
586
|
n_a, _, n_x = self.radios_cropped_shape
|
588
587
|
self._tmp_sino = self._allocate_array((n_a, n_x), "f", name="tmp_sino")
|
589
|
-
if options["method"] == "cone":
|
590
|
-
self.sinos = self._allocate_array(self.sino_builder.output_shape, "f", name="sinos")
|
591
588
|
|
592
589
|
@use_options("histogram", "histogram")
|
593
590
|
def _init_histogram(self):
|
@@ -734,14 +731,25 @@ class ChunkedPipeline:
|
|
734
731
|
"""
|
735
732
|
This reconstructs the entire sinograms stack at once
|
736
733
|
"""
|
737
|
-
|
734
|
+
|
735
|
+
n_angles, n_z, n_x = self.radios.shape
|
736
|
+
|
737
|
+
# FIXME
|
738
|
+
# can't do a discontiguous single copy...
|
739
|
+
sinos_contig = self._allocate_array((n_z, n_angles, n_x), np.float32, "sinos_cone")
|
740
|
+
for i in range(n_z):
|
741
|
+
sinos_contig[i] = self.radios[:, i, :]
|
742
|
+
# ---
|
743
|
+
|
744
|
+
# In principle radios are not cropped at this stage,
|
745
|
+
# so self.sub_region[2][0] can be used instead of self.get_slice_start_index() instead of self.sub_region[2][0]
|
738
746
|
z_min, z_max = self.sub_region_xz[2:]
|
739
|
-
|
747
|
+
n_z_tot = self.process_config.radio_shape(binning=True)[0]
|
740
748
|
|
741
749
|
self.reconstruction.reconstruct( # pylint: disable=E1101
|
742
|
-
|
750
|
+
sinos_contig,
|
743
751
|
output=self.recs,
|
744
|
-
relative_z_position=((z_min + z_max) / self.process_config.binning_z / 2) -
|
752
|
+
relative_z_position=((z_min + z_max) / self.process_config.binning_z / 2) - n_z_tot / 2,
|
745
753
|
)
|
746
754
|
|
747
755
|
@pipeline_step("histogram", "Computing histogram")
|
@@ -29,7 +29,7 @@ class FullFieldDatasetValidator(DatasetValidatorBase):
|
|
29
29
|
def _check_slice_indices(self):
|
30
30
|
nx, nz = self.dataset_info.radio_dims
|
31
31
|
rec_params = self.rec_params
|
32
|
-
if
|
32
|
+
if self.is_halftomo:
|
33
33
|
ny, nx = self._get_nx_ny()
|
34
34
|
what = (("start_x", "end_x", nx), ("start_y", "end_y", nx), ("start_z", "end_z", nz))
|
35
35
|
for start_name, end_name, numels in what:
|
@@ -61,3 +61,7 @@ class FullFieldDatasetValidator(DatasetValidatorBase):
|
|
61
61
|
self.logger.warning(
|
62
62
|
"Cone-beam reconstruction: 'sample_detector_dist' not provided, will use the one in dataset metadata"
|
63
63
|
)
|
64
|
+
if self.is_halftomo:
|
65
|
+
err_msg = "Cone-beam reconstruction with half-acquisition is not supported yet"
|
66
|
+
self.logger.fatal(err_msg)
|
67
|
+
raise NotImplementedError(err_msg)
|
@@ -517,10 +517,15 @@ class ProcessConfig(ProcessConfigBase):
|
|
517
517
|
#
|
518
518
|
# Translation movements
|
519
519
|
#
|
520
|
+
|
520
521
|
translations = dataset_info.translations
|
521
522
|
if translations is not None:
|
522
|
-
|
523
|
-
|
523
|
+
if np.max(np.abs(translations[:, 1])) < 1e-5:
|
524
|
+
self.logger.warning("No vertical translation greater than 1e-5 - disabling vertical shifts")
|
525
|
+
# horizontal movements are handled in backprojector
|
526
|
+
else:
|
527
|
+
tasks.append("radios_movements")
|
528
|
+
options["radios_movements"] = {"translation_movements": dataset_info.translations}
|
524
529
|
#
|
525
530
|
# Sinogram normalization (before half-tomo)
|
526
531
|
#
|
@@ -600,7 +605,7 @@ class ProcessConfig(ProcessConfigBase):
|
|
600
605
|
)
|
601
606
|
if all([m is not None for m in mean_positions_xyz]):
|
602
607
|
rec_options["position"] = mean_positions_xyz
|
603
|
-
if rec_options["sample_detector_dist"] is None:
|
608
|
+
if rec_options["method"] == "cone" and rec_options["sample_detector_dist"] is None:
|
604
609
|
rec_options["sample_detector_dist"] = self.dataset_info.distance # was checked to be not None earlier
|
605
610
|
|
606
611
|
# New key
|
@@ -359,6 +359,16 @@ class FullFieldReconstructor:
|
|
359
359
|
|
360
360
|
return (max_overlap, 0)
|
361
361
|
|
362
|
+
def _compute_rotation_margin(self):
|
363
|
+
if "rotate_projections" in self.process_config.processing_steps:
|
364
|
+
# Partial radios rotation yields too much error in single-slice mode
|
365
|
+
# Forcing a big margin circumvents the problem
|
366
|
+
# This is likely to trigger the 'grouped mode', but perhaps grouped mode should always be used when rotating radios
|
367
|
+
nz, nx = self.process_config.radio_shape(binning=True)
|
368
|
+
return nz // 3, nx // 3
|
369
|
+
else:
|
370
|
+
return 0, 0
|
371
|
+
|
362
372
|
def _ensure_good_chunk_size_and_margin(self):
|
363
373
|
"""
|
364
374
|
Check that "chunk_size" and "margin" (if any) are a multiple of binning factor.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from nabu.pipeline.helical import gridded_accumulator, span_strategy
|
2
|
-
from nabu.testutils import get_data
|
2
|
+
from nabu.testutils import get_data, __do_long_tests__
|
3
3
|
|
4
4
|
import pytest
|
5
5
|
import numpy as np
|
@@ -49,6 +49,7 @@ def bootstrap(request):
|
|
49
49
|
cls.rtol_regridded = 1.0e-6
|
50
50
|
|
51
51
|
|
52
|
+
@pytest.mark.skipif(not (__do_long_tests__), reason="need environment variable NABU_LONG_TESTS=1")
|
52
53
|
@pytest.mark.usefixtures("bootstrap")
|
53
54
|
class TestGriddedAccumulator:
|
54
55
|
"""
|
nabu/pipeline/processconfig.py
CHANGED
@@ -181,7 +181,10 @@ class ProcessConfigBase:
|
|
181
181
|
#
|
182
182
|
if isinstance(tilt, str): # auto-tilt
|
183
183
|
self.tilt_estimator = DetectorTiltEstimator(
|
184
|
-
self.dataset_info,
|
184
|
+
self.dataset_info,
|
185
|
+
do_flatfield=self.nabu_config["preproc"]["flatfield"],
|
186
|
+
logger=self.logger,
|
187
|
+
autotilt_options=self.nabu_config["preproc"]["autotilt_options"],
|
185
188
|
)
|
186
189
|
tilt = self.tilt_estimator.find_tilt(tilt_method=tilt)
|
187
190
|
self.dataset_info.detector_tilt = tilt
|
nabu/reconstruction/cone.py
CHANGED
@@ -23,7 +23,9 @@ class ConebeamReconstructor:
|
|
23
23
|
volume_shape=None,
|
24
24
|
rot_center=None,
|
25
25
|
relative_z_position=None,
|
26
|
+
axis_correction=None,
|
26
27
|
pixel_size=None,
|
28
|
+
scale_factor=None,
|
27
29
|
cuda_options=None,
|
28
30
|
):
|
29
31
|
"""
|
@@ -88,6 +90,7 @@ class ConebeamReconstructor:
|
|
88
90
|
Optics Express. 24. 25129-25147. 10.1364/OE.24.025129.
|
89
91
|
"""
|
90
92
|
self._init_cuda(cuda_options)
|
93
|
+
self.scale_factor = scale_factor
|
91
94
|
self._init_geometry(
|
92
95
|
sinos_shape,
|
93
96
|
source_origin_dist,
|
@@ -97,6 +100,7 @@ class ConebeamReconstructor:
|
|
97
100
|
volume_shape,
|
98
101
|
rot_center,
|
99
102
|
relative_z_position,
|
103
|
+
axis_correction,
|
100
104
|
)
|
101
105
|
self._alg_id = None
|
102
106
|
self._vol_id = None
|
@@ -133,6 +137,7 @@ class ConebeamReconstructor:
|
|
133
137
|
volume_shape,
|
134
138
|
rot_center,
|
135
139
|
relative_z_position,
|
140
|
+
axis_correction,
|
136
141
|
):
|
137
142
|
self._set_sino_shape(sinos_shape)
|
138
143
|
if angles is None:
|
@@ -153,6 +158,7 @@ class ConebeamReconstructor:
|
|
153
158
|
if rot_center is not None:
|
154
159
|
self._cor_shift = (self.prj_width - 1) / 2.0 - rot_center
|
155
160
|
self._set_pixel_size(pixel_size)
|
161
|
+
self._axis_corrections = axis_correction
|
156
162
|
self._create_astra_proj_geometry(relative_z_position)
|
157
163
|
|
158
164
|
def _create_astra_proj_geometry(self, relative_z_position):
|
@@ -170,13 +176,26 @@ class ConebeamReconstructor:
|
|
170
176
|
self.origin_detector_dist,
|
171
177
|
)
|
172
178
|
self.relative_z_position = relative_z_position or 0.0
|
179
|
+
# This will turn the geometry of type "cone" into a geometry of type "cone_vec"
|
173
180
|
self.proj_geom = astra.geom_postalignment(self.proj_geom, (self._cor_shift, 0))
|
181
|
+
# (src, detector_center, u, v) = (srcX, srcY, srcZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ)
|
182
|
+
vecs = self.proj_geom["Vectors"]
|
183
|
+
|
184
|
+
# To adapt the center of rotation:
|
185
|
+
# dX = cor_shift * cos(theta) - origin_detector_dist * sin(theta)
|
186
|
+
# dY = origin_detector_dist * cos(theta) + cor_shift * sin(theta)
|
187
|
+
if self._axis_corrections is not None:
|
188
|
+
# should we check that dX and dY match the above formulas ?
|
189
|
+
cor_shifts = self._cor_shift + self._axis_corrections
|
190
|
+
vecs[:, 3] = cor_shifts * np.cos(self.angles) - self.origin_detector_dist * np.sin(self.angles)
|
191
|
+
vecs[:, 4] = self.origin_detector_dist * np.cos(self.angles) + cor_shifts * np.sin(self.angles)
|
192
|
+
|
193
|
+
# To adapt the z position:
|
174
194
|
# Component 2 of vecs is the z coordinate of the source, component 5 is the z component of the detector position
|
175
195
|
# We need to re-create the same inclination of the cone beam, thus we need to keep the inclination of the two z positions.
|
176
196
|
# The detector is centered on the rotation axis, thus moving it up or down, just moves it out of the reconstruction volume.
|
177
197
|
# We can bring back the detector in the correct volume position, by applying a rigid translation of both the detector and the source.
|
178
198
|
# The translation is exactly the amount that brought the detector up or down, but in the opposite direction.
|
179
|
-
vecs = self.proj_geom["Vectors"]
|
180
199
|
vecs[:, 2] = -self.relative_z_position
|
181
200
|
|
182
201
|
def _set_output(self, volume):
|
@@ -229,6 +248,8 @@ class ConebeamReconstructor:
|
|
229
248
|
result = self.cuda.get_array("output")
|
230
249
|
if output is None:
|
231
250
|
result = result.get()
|
251
|
+
if self.scale_factor is not None:
|
252
|
+
result *= np.float32(self.scale_factor) # in-place for pycuda
|
232
253
|
self.cuda.recover_arrays_references(["sinos", "output"])
|
233
254
|
return result
|
234
255
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import pytest
|
2
2
|
import numpy as np
|
3
|
-
from scipy.ndimage import gaussian_filter
|
4
|
-
from nabu.utils import subdivide_into_overlapping_segment
|
3
|
+
from scipy.ndimage import gaussian_filter, shift
|
4
|
+
from nabu.utils import subdivide_into_overlapping_segment, clip_circle
|
5
5
|
|
6
6
|
try:
|
7
7
|
import astra
|
@@ -238,6 +238,65 @@ class TestCone:
|
|
238
238
|
assert np.max(err_max_profile) < 2e-3
|
239
239
|
assert np.max(err_median_profile) < 5e-6
|
240
240
|
|
241
|
+
def test_reconstruction_horizontal_translations(self):
|
242
|
+
n_z = n_y = n_x = 256
|
243
|
+
n_a = 500
|
244
|
+
src_orig_dist = 1000
|
245
|
+
orig_det_dist = 50
|
246
|
+
|
247
|
+
volume, cone_data = generate_hollow_cube_cone_sinograms(
|
248
|
+
vol_shape=(n_z, n_y, n_x),
|
249
|
+
n_angles=n_a,
|
250
|
+
src_orig_dist=src_orig_dist,
|
251
|
+
orig_det_dist=orig_det_dist,
|
252
|
+
apply_filter=False,
|
253
|
+
)
|
254
|
+
|
255
|
+
# Apply horizontal translations on projections. This could have been done directly with astra
|
256
|
+
shift_min, shift_max = -2, 5
|
257
|
+
shifts_float = (shift_max - shift_min) * np.random.rand(n_a) - shift_min
|
258
|
+
shifts_int = np.random.randint(shift_min, high=shift_max + 1, size=n_a)
|
259
|
+
|
260
|
+
reconstructor_args = [
|
261
|
+
cone_data.shape,
|
262
|
+
src_orig_dist,
|
263
|
+
orig_det_dist,
|
264
|
+
]
|
265
|
+
reconstructor_kwargs = {
|
266
|
+
"volume_shape": volume.shape,
|
267
|
+
"cuda_options": {"ctx": self.ctx},
|
268
|
+
}
|
269
|
+
cone_reconstructor = ConebeamReconstructor(*reconstructor_args, **reconstructor_kwargs)
|
270
|
+
rec = cone_reconstructor.reconstruct(cone_data)
|
271
|
+
|
272
|
+
# Translations done with floating-point shift values give a blurring of the image that cannot be recovered.
|
273
|
+
# Error tolerance has to be higher for these shifts.
|
274
|
+
for shift_type, shifts, err_tol in [
|
275
|
+
("integer shifts", shifts_int, 5e-3),
|
276
|
+
("float shifts", shifts_float, 1.4e-1),
|
277
|
+
]:
|
278
|
+
cone_data_shifted = np.zeros_like(cone_data)
|
279
|
+
[shift(cone_data[:, i, :], (0, shifts[i]), output=cone_data_shifted[:, i, :]) for i in range(n_a)]
|
280
|
+
|
281
|
+
# Reconstruct with horizontal shifts
|
282
|
+
cone_reconstructor_with_correction = ConebeamReconstructor(
|
283
|
+
*reconstructor_args,
|
284
|
+
axis_corrections=shifts,
|
285
|
+
**reconstructor_kwargs,
|
286
|
+
)
|
287
|
+
|
288
|
+
rec_with_correction = cone_reconstructor_with_correction.reconstruct(cone_data_shifted)
|
289
|
+
|
290
|
+
metric = lambda img: np.max(np.abs(clip_circle(img, radius=int(0.85 * img.shape[1] // 2))))
|
291
|
+
error_profile = np.array([metric(rec[i] - rec_with_correction[i]) for i in range(n_z)])
|
292
|
+
assert error_profile.max() < err_tol, "Max error with %s is too high" % shift_type
|
293
|
+
|
294
|
+
# import matplotlib.pyplot as plt
|
295
|
+
# plt.figure()
|
296
|
+
# plt.plot(np.arange(n_z), error_profile)
|
297
|
+
# plt.legend([shift_type])
|
298
|
+
# plt.show()
|
299
|
+
|
241
300
|
|
242
301
|
def generate_hollow_cube_cone_sinograms(
|
243
302
|
vol_shape, n_angles, src_orig_dist, orig_det_dist, prj_width=None, apply_filter=True
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import numpy as np
|
2
2
|
import pytest
|
3
3
|
from nabu.reconstruction.rings_cuda import CudaSinoMeanDeringer
|
4
|
-
from nabu.testutils import compare_arrays, get_data, generate_tests_scenarios, __do_long_tests__
|
4
|
+
from nabu.testutils import compare_arrays, get_data, generate_tests_scenarios, __do_long_tests__, __do_large_mem_tests__
|
5
5
|
from nabu.reconstruction.rings import MunchDeringer, SinoMeanDeringer, VoDeringer, __has_algotom__
|
6
6
|
from nabu.thirdparty.pore3d_deringer_munch import munchetal_filter
|
7
7
|
from nabu.cuda.utils import __has_pycuda__, get_cuda_context
|
@@ -144,8 +144,8 @@ class TestMunchDeringer:
|
|
144
144
|
# TODO check result. The generated test sinogram is "too synthetic" for this kind of deringer
|
145
145
|
|
146
146
|
@pytest.mark.skipif(
|
147
|
-
not (__have_tomocupy_deringer__),
|
148
|
-
reason="Need cupy for this test",
|
147
|
+
not (__have_tomocupy_deringer__ and __do_large_mem_tests__),
|
148
|
+
reason="Need cupy for this test, and use NABU_LARGE_MEM_TESTS",
|
149
149
|
)
|
150
150
|
def test_cuda_vo_deringer(self):
|
151
151
|
# Beware, this deringer seems to be buggy for "too-small" sinograms
|
@@ -3,10 +3,11 @@ import pytest
|
|
3
3
|
from nabu.testutils import get_data, generate_tests_scenarios, compare_shifted_images
|
4
4
|
from nabu.cuda.utils import get_cuda_context, __has_pycuda__, __has_cufft__
|
5
5
|
from nabu.opencl.utils import get_opencl_context, __has_pyopencl__
|
6
|
+
from nabu.processing.fft_opencl import has_vkfft as has_vkfft_cl
|
6
7
|
from nabu.thirdparty.algotom_convert_sino import extend_sinogram
|
7
8
|
|
8
9
|
__has_pycuda__ = __has_pycuda__ and __has_cufft__ # need both for using Cuda backprojector
|
9
|
-
|
10
|
+
__has_pyopencl__ = __has_pyopencl__ and has_vkfft_cl()
|
10
11
|
|
11
12
|
if __has_pycuda__:
|
12
13
|
from nabu.reconstruction.fbp import CudaBackprojector
|
@@ -695,11 +695,6 @@ def test_DistributePostProcessZStitcher(tmp_path, configuration_dist, flip_ud):
|
|
695
695
|
if complete:
|
696
696
|
concatenate_volumes(output_volume=final_vol, volumes=tuple(reconstructed_sub_volumes), axis=1)
|
697
697
|
final_vol.load_data(store=True)
|
698
|
-
with h5py.File("debug.hdf5", mode="w") as h5f:
|
699
|
-
h5f["raw_volume"] = raw_volume
|
700
|
-
h5f["final_vol"] = final_vol.data
|
701
|
-
h5f["volume1"] = volume_1.data
|
702
|
-
h5f["volume2"] = volume_2.data
|
703
698
|
numpy.testing.assert_almost_equal(
|
704
699
|
raw_volume,
|
705
700
|
final_vol.data,
|
@@ -925,14 +920,6 @@ def test_vol_z_stitching_with_alignment_axis_2(tmp_path, alignment_axis_2):
|
|
925
920
|
|
926
921
|
assert output_volume.data.shape == (120, 4, 120)
|
927
922
|
|
928
|
-
import h5py
|
929
|
-
|
930
|
-
with h5py.File("input.h5", mode="w") as h5f:
|
931
|
-
h5f["data"] = raw_volume
|
932
|
-
|
933
|
-
with h5py.File("output.h5", mode="w") as h5f:
|
934
|
-
h5f["data"] = output_volume.data
|
935
|
-
|
936
923
|
if alignment_axis_2 == "center":
|
937
924
|
numpy.testing.assert_array_almost_equal(raw_volume[:, :, 10:-10], output_volume.data[:, :, 10:-10])
|
938
925
|
elif alignment_axis_2 == "left":
|
nabu/stitching/z_stitching.py
CHANGED
@@ -1975,7 +1975,7 @@ def stitch_vertically_raw_frames(
|
|
1975
1975
|
| | Frame 2 | --------------
|
1976
1976
|
| | |
|
1977
1977
|
| --------------
|
1978
|
-
|
1978
|
+
|
|
1979
1979
|
|
1980
1980
|
returns stitched_projection, raw_img_1, raw_img_2, computed_overlap
|
1981
1981
|
proj_0 and pro_1 are already expected to be in a row. Having stitching_height_in_px in common. At top of proj_0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: nabu
|
3
|
-
Version: 2024.1.
|
3
|
+
Version: 2024.1.8
|
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>
|
@@ -49,7 +49,7 @@ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
49
49
|
Requires-Python: >=3.7
|
50
50
|
Description-Content-Type: text/markdown
|
51
51
|
License-File: LICENSE
|
52
|
-
Requires-Dist: numpy
|
52
|
+
Requires-Dist: numpy <2,>1.9.0
|
53
53
|
Requires-Dist: scipy
|
54
54
|
Requires-Dist: h5py >=3.0
|
55
55
|
Requires-Dist: silx >=0.15.0
|
@@ -66,7 +66,7 @@ Provides-Extra: full
|
|
66
66
|
Requires-Dist: scikit-image ; extra == 'full'
|
67
67
|
Requires-Dist: PyWavelets ; extra == 'full'
|
68
68
|
Requires-Dist: glymur ; extra == 'full'
|
69
|
-
Requires-Dist: pycuda ; extra == 'full'
|
69
|
+
Requires-Dist: pycuda <2024.1.1 ; extra == 'full'
|
70
70
|
Requires-Dist: scikit-cuda ; extra == 'full'
|
71
71
|
Requires-Dist: pycudwt ; extra == 'full'
|
72
72
|
Requires-Dist: sluurp >=0.3 ; extra == 'full'
|
@@ -1,7 +1,8 @@
|
|
1
1
|
doc/conf.py,sha256=3xtCarCHrXPr50GbeRDuH-o3Jzojw7mpr7vpGfZPLAE,3787
|
2
2
|
doc/create_conf_doc.py,sha256=IVOdP70KvbW9WS_UQu3Iyd0YfS60E2fJ5IDtQ_s4cDw,1143
|
3
|
+
doc/doc_config.py,sha256=anqeOVjqE2e7eVzg7yuh9dvIneTkrA5doGl1cVBqT7Q,730
|
3
4
|
doc/get_mathjax.py,sha256=VIvKRCdDuF2VoY8JD3mSey9XX13AZMmwTJBHdt1tUs4,1012
|
4
|
-
nabu/__init__.py,sha256=
|
5
|
+
nabu/__init__.py,sha256=DO4fHjlr5q2r3IDpkSpuzsOIMuHK5R3I2w91UQaUEdY,270
|
5
6
|
nabu/tests.py,sha256=cew9OY2uTyncHI_HM32W8CP6B1GTGKaOW65XtMEqs7o,1417
|
6
7
|
nabu/testutils.py,sha256=qqtGgkIhpOpXhgeoXlqCb91Rx-JlI4ALaDF6nt8YRRk,13298
|
7
8
|
nabu/utils.py,sha256=w-xfRb6TFQpS-tao6nlvfmr962pmeec-WH1GltSUCrk,23767
|
@@ -31,7 +32,6 @@ nabu/app/shrink_dataset.py,sha256=P9dorO0Q-gPAWgSHyZi3XQp4jkMTJacDYzNvJY4oh98,35
|
|
31
32
|
nabu/app/stitching.py,sha256=Ibp1oVokLVMz-VX762j1C0E88Di0YJvRt-b8NjGoe7g,3310
|
32
33
|
nabu/app/utils.py,sha256=XUBRWDmth4i3BZHd27rfarFAUP7OEcsMeVmDJ6T4EXA,1178
|
33
34
|
nabu/app/validator.py,sha256=IR-DcUV5h1Fc5CChBfBIaglrGpfKNICX7tGirAroMiw,3368
|
34
|
-
nabu/app/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
35
|
nabu/app/tests/test_reduce_dark_flat.py,sha256=T-_zyzD0-f2c5Z-tlzmRF5p3vPtyL2RFb-D5fIYYEoM,2641
|
36
36
|
nabu/cuda/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
nabu/cuda/convolution.py,sha256=n8KsJ7IZdPOs_K5QZC6qblnOvIKYwxtdt03oNa0GiMU,241
|
@@ -132,17 +132,17 @@ nabu/pipeline/detector_distortion_provider.py,sha256=ru1AxbcuO-FA8FYooPBWgp1lzdS
|
|
132
132
|
nabu/pipeline/estimators.py,sha256=4V5pwl5vUFMJDanWnmw7POnSsa9lKyKtUzvq9GLcJwc,41374
|
133
133
|
nabu/pipeline/fallback_utils.py,sha256=7ccrKYE-rp3fydb72VA6W0_eKcEoqYBEAPlmij_lyEc,6086
|
134
134
|
nabu/pipeline/params.py,sha256=VdrekcxOnbrMzvvLcwEWINiMM0uVKmPxJJBwp3lhHBg,3479
|
135
|
-
nabu/pipeline/processconfig.py,sha256=
|
135
|
+
nabu/pipeline/processconfig.py,sha256=O0phgvfWtL9bg3_GE3cw9MZXS8PUy8z2rzhpoqP9U84,8320
|
136
136
|
nabu/pipeline/utils.py,sha256=NONAgBfTfUYvBNfoTqD33MAYaPZyCJL10SnR6B0lLec,3462
|
137
137
|
nabu/pipeline/writer.py,sha256=0ts40VNN3RiRURvZ2gNqsigsAJuwcjnYF4RJ15qaMpI,7558
|
138
138
|
nabu/pipeline/fullfield/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
139
|
-
nabu/pipeline/fullfield/chunked.py,sha256=
|
139
|
+
nabu/pipeline/fullfield/chunked.py,sha256=IElD8g_KtYS7VOXuIEsRbdb9fMmtpB_AK7mAyejbEs0,37125
|
140
140
|
nabu/pipeline/fullfield/chunked_cuda.py,sha256=aGzjY8MX6OL8auEj6Y0RfOGCmFnczsdfj6-8Net5AbQ,5645
|
141
141
|
nabu/pipeline/fullfield/computations.py,sha256=VpIURVXh8EpNSfait_AIFM4Ci-GK_546Wkb-Wn9r31Y,9935
|
142
|
-
nabu/pipeline/fullfield/dataset_validator.py,sha256=
|
142
|
+
nabu/pipeline/fullfield/dataset_validator.py,sha256=8B2lB9j7elF_NmOOOyr8UADVfC15Oofzy2AyWoPufQM,3265
|
143
143
|
nabu/pipeline/fullfield/nabu_config.py,sha256=a0mMoLkvlvHgX6RmUS1m1UhJS-XB3O6wBCnkNoI90Cs,30358
|
144
|
-
nabu/pipeline/fullfield/processconfig.py,sha256=
|
145
|
-
nabu/pipeline/fullfield/reconstruction.py,sha256=
|
144
|
+
nabu/pipeline/fullfield/processconfig.py,sha256=qSVeUvpt9BS2kR3zNk95_MGoLV4idiSJyYHlAPXbgTs,36405
|
145
|
+
nabu/pipeline/fullfield/reconstruction.py,sha256=b-ErQE__Ttz2XECJjmdoY6Msfh-lrUOPZCsAhn6p-nA,37150
|
146
146
|
nabu/pipeline/helical/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
147
147
|
nabu/pipeline/helical/dataset_validator.py,sha256=0YQc0hdYdpaXznFaKmlj9SIu7mNs0xXMejcRkhOZHaI,640
|
148
148
|
nabu/pipeline/helical/fbp.py,sha256=0fAz-Fb0Rn_FzellvcS2cy-Wvm-5dxEf494YFt4pLws,5845
|
@@ -158,7 +158,7 @@ nabu/pipeline/helical/span_strategy.py,sha256=7zV_Oo_liFiuv6m70o08XyoEIo_7QYs7MV
|
|
158
158
|
nabu/pipeline/helical/utils.py,sha256=51Qbh8db6-DX0iB9B9Kb07uwIG6_upAJg_8nhyzbB7o,1555
|
159
159
|
nabu/pipeline/helical/weight_balancer.py,sha256=j0TGe50tbbsilQvml9CgMxeSy83CNaifHj-xuMGl8uE,3981
|
160
160
|
nabu/pipeline/helical/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
161
|
-
nabu/pipeline/helical/tests/test_accumulator.py,sha256=
|
161
|
+
nabu/pipeline/helical/tests/test_accumulator.py,sha256=DCwTAWQLdUNJBJpjhHT8o1gLbznpuj_zqbQOfQnrShw,6534
|
162
162
|
nabu/pipeline/helical/tests/test_pipeline_elements_full.py,sha256=zeR9SaeD0mnhtKU7qo4Qrn_lg1I1Vhg4dqzj6jy8tpg,14569
|
163
163
|
nabu/pipeline/helical/tests/test_strategy.py,sha256=rt8SsUHBMMcVFl48kRGcOyf1y4bYqaA2xDznQxE7wFs,2721
|
164
164
|
nabu/pipeline/tests/test_chunk_reader.py,sha256=OB279hSvgmVhWv_OauZNWTJeaaiheETayGYK79Op10Q,3410
|
@@ -213,7 +213,7 @@ nabu/processing/unsharp_cuda.py,sha256=tbgw3selI4x4qsSxyQJ8Q4HUxdEBbZOJtSys-0yzj
|
|
213
213
|
nabu/processing/unsharp_opencl.py,sha256=ikmZhQB-kji3UFrvFzHJNvDUpaVSpzcCJRX_bqSQeGQ,2637
|
214
214
|
nabu/processing/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
215
215
|
nabu/processing/tests/test_fft.py,sha256=zDGDTXZjHBVbiVFiQfkrkYFFMyotJRFU-KgoNm1FGms,9827
|
216
|
-
nabu/processing/tests/test_fftshift.py,sha256
|
216
|
+
nabu/processing/tests/test_fftshift.py,sha256=-XgJUm0eF3D-rMTlI9u3jaWYIlPFZEpM0PwW3SMDLG0,2618
|
217
217
|
nabu/processing/tests/test_histogram.py,sha256=25CLs1WZpLF9xZ2DR82x4_YokA5Z76Qsnn6zY8YdJj8,2283
|
218
218
|
nabu/processing/tests/test_medfilt.py,sha256=lVfLWIxWiLfODFc14WYbq1W02rgQDtCnrSgXnWgU6yU,2722
|
219
219
|
nabu/processing/tests/test_muladd.py,sha256=cRhAC5hgmRV0BAwPA4o4M-kcx-UDniLK7sSyiN0F3kE,1927
|
@@ -223,7 +223,7 @@ nabu/processing/tests/test_rotation.py,sha256=vedRXV9RePJywBKoyBkGANP1dhZCjphbYO
|
|
223
223
|
nabu/processing/tests/test_transpose.py,sha256=hTG17wTaB5Wv6twbW3ZFhBv6BYfqJY7DTQPoO0-KdkM,2760
|
224
224
|
nabu/processing/tests/test_unsharp.py,sha256=R3ovbwDDp3ccy2A8t6CcUVELXRWkED5EnQdN2FQOfQM,4391
|
225
225
|
nabu/reconstruction/__init__.py,sha256=EmKVvx_-FJvzJngG4ielIC7FhMCpI1Waaflg_lF44tk,163
|
226
|
-
nabu/reconstruction/cone.py,sha256=
|
226
|
+
nabu/reconstruction/cone.py,sha256=ET0xCoFRt5oD7IpzHNmlm-bX4eanBenH186VGTgLAj0,12159
|
227
227
|
nabu/reconstruction/fbp.py,sha256=5GB7XCnxftSHq1ZBLjWi-7OTiyCU4qe-M4EPzvsoxLg,4829
|
228
228
|
nabu/reconstruction/fbp_base.py,sha256=igY--_GiKGAcephOU1I8O1GjVcryJnReyywlgtROXW4,16833
|
229
229
|
nabu/reconstruction/fbp_opencl.py,sha256=coEGLq65PCuvWnhAbIyLPHACkWjMB0XOceMp9ZIDWtc,3274
|
@@ -239,11 +239,11 @@ nabu/reconstruction/sinogram.py,sha256=KTSGP_JJABf4Yr9l628HPbyWsBnpbnyGKyPEq3ZrP
|
|
239
239
|
nabu/reconstruction/sinogram_cuda.py,sha256=wS84AIy3T00d1kTtuJOQmA3hktbDVs4ybwB9haiBcoY,10623
|
240
240
|
nabu/reconstruction/sinogram_opencl.py,sha256=p793N26VknU8KIZLtDgFY6HNx0TylemZ1YL4WKD3fHs,1403
|
241
241
|
nabu/reconstruction/tests/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
242
|
-
nabu/reconstruction/tests/test_cone.py,sha256=
|
243
|
-
nabu/reconstruction/tests/test_deringer.py,sha256=
|
242
|
+
nabu/reconstruction/tests/test_cone.py,sha256=xrFsIFGmpE9txpR3d93upF2S4yS_53IjZdZEKaaYspg,14313
|
243
|
+
nabu/reconstruction/tests/test_deringer.py,sha256=C5wj6RNzmpt_Cry4fonC8KXWvgPpcXfRbG8Bex_30S4,8380
|
244
244
|
nabu/reconstruction/tests/test_fbp.py,sha256=p80zPCZkgJpERpqG5HHfbtbHBeqJUT8WY-q6FXOJJ7M,10053
|
245
245
|
nabu/reconstruction/tests/test_filtering.py,sha256=PFJLQMDBQo-UuS_CfKrWZ_DdHarmVlcbsiZ_kmToWXY,4782
|
246
|
-
nabu/reconstruction/tests/test_halftomo.py,sha256=
|
246
|
+
nabu/reconstruction/tests/test_halftomo.py,sha256=j-vq9Oyxl7dYGuAMMO2G-Y7EcryD1RGEyXqmycc0o_8,4290
|
247
247
|
nabu/reconstruction/tests/test_projector.py,sha256=W4zntShzL47HjMGQG11zIYzMXwX0KfMN4BVIAapdy_I,6033
|
248
248
|
nabu/reconstruction/tests/test_reconstructor.py,sha256=dEGqlQHfFwX_V2Ybnq5AAM5tprXn_2OuCSrC6cW4S0A,3221
|
249
249
|
nabu/reconstruction/tests/test_sino_normalization.py,sha256=fGv5Dlidxgm8ZC70Nk6oqVgpY2jzOW9NJaGlo44IJOo,3692
|
@@ -272,7 +272,7 @@ nabu/stitching/overlap.py,sha256=eXAKsILS5jwqFY62JhDijeNW8H50rP-yjdUUGqjj0aY,157
|
|
272
272
|
nabu/stitching/sample_normalization.py,sha256=_radin_wxnuD3MMmZNAOKA__aPa2z3ss4TFbZeocpXc,2069
|
273
273
|
nabu/stitching/slurm_utils.py,sha256=sZ-VQPh_YlJ1Lkh7ap8qxII0rBpZryMyoxE5Xn557t8,8906
|
274
274
|
nabu/stitching/utils.py,sha256=kMn2JEMDhcBQMweSlM0rUd-037H7iNUURTFMhXOTzC8,23651
|
275
|
-
nabu/stitching/z_stitching.py,sha256=
|
275
|
+
nabu/stitching/z_stitching.py,sha256=_DnPn4einJgzjqYu4u-LSwLAOoDgp5Jdu7iTYdsx9bw,103399
|
276
276
|
nabu/stitching/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
277
277
|
nabu/stitching/tests/test_alignment.py,sha256=MACak1ILOr8nRKeT0mWfMd-ZvhCl3SWjjcp6GjRbITc,2735
|
278
278
|
nabu/stitching/tests/test_config.py,sha256=ttWuVB9Y_MM3_wGdKbcbYi_PG3vN87cL7o5zKsMzn9g,8490
|
@@ -281,16 +281,16 @@ nabu/stitching/tests/test_overlap.py,sha256=vfZuK32pclWL0Hg8u5NH0JoxKO28qk3ObRMm
|
|
281
281
|
nabu/stitching/tests/test_sample_normalization.py,sha256=E49E_Quv-Qon6qSuaH9ZBZLqq4TPuBl8RqgB18Rwjc0,1348
|
282
282
|
nabu/stitching/tests/test_slurm_utils.py,sha256=bbhCQd06R3irGB4B9r79KKlf0AlBchI53N2ldsXoAQQ,4950
|
283
283
|
nabu/stitching/tests/test_utils.py,sha256=CjV0vPvXEchJ5vo6o7hGQA-PsOOAyAamuQ6fiHKCQ9M,641
|
284
|
-
nabu/stitching/tests/test_z_stitching.py,sha256=
|
284
|
+
nabu/stitching/tests/test_z_stitching.py,sha256=7VbNb7LwAahkLrxmx4V1M292op3e8W5M5NMZ2KABhFw,42160
|
285
285
|
nabu/thirdparty/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
286
286
|
nabu/thirdparty/algotom_convert_sino.py,sha256=iZVRilvyqMyLTu8RKgbqDFUjObWW5X69rCARrnNizuI,13872
|
287
287
|
nabu/thirdparty/pore3d_deringer_munch.py,sha256=o4bisnFc-wMjuohWBT8wgWmfNehPQGtCl6G2NebJlbg,4500
|
288
288
|
nabu/thirdparty/tomocupy_remove_stripe.py,sha256=VgXHr2tzTAAGZix5pwhFfbPxj4tt3yXBcjCPNQSLPAg,22810
|
289
289
|
nabu/thirdparty/tomopy_phase.py,sha256=hK4oPpkogLOhv23XzzEXQY2u3r8fJvASY_bINVs6ERE,8634
|
290
290
|
nabu/thirdparty/tomwer_load_flats_darks.py,sha256=ZNoVAinUb_wGYbfvs_4BVnWsjsQmNxSvCh1bWhR2WWg,5611
|
291
|
-
nabu-2024.1.
|
292
|
-
nabu-2024.1.
|
293
|
-
nabu-2024.1.
|
294
|
-
nabu-2024.1.
|
295
|
-
nabu-2024.1.
|
296
|
-
nabu-2024.1.
|
291
|
+
nabu-2024.1.8.dist-info/LICENSE,sha256=1eAIPSnEsnSFNUODnLtNtQTs76exG3ZxJ1DJR6zoUBA,1066
|
292
|
+
nabu-2024.1.8.dist-info/METADATA,sha256=qlqJl5Qy-ajxs4_j-PfKcIvwds6vYOT9j8V21egtvQs,5237
|
293
|
+
nabu-2024.1.8.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
294
|
+
nabu-2024.1.8.dist-info/entry_points.txt,sha256=cJKGkBeykVL7uK3E4R0RLRqMXifTL2qdO573syPAvJc,1288
|
295
|
+
nabu-2024.1.8.dist-info/top_level.txt,sha256=fsm_N3eXLRZk2QXF9OSKPNDPFXOz8FAQjHh5avT3dok,9
|
296
|
+
nabu-2024.1.8.dist-info/RECORD,,
|
nabu/app/tests/__init__.py
DELETED
File without changes
|
File without changes
|
File without changes
|
File without changes
|