Advanced Nabu usage¶
- Using darks/flats from another dataset
- CTF pipeline (ID16A, ID16B)
- Excluding projections from reconstruction
- Binning
- Reconstructing from even/odd projections
- Using nabu through the Python API
Using darks/flats from another dataset¶
Sometimes for practical reasons, you want to use flats/darks from another dataset (or even custom darks/flats). For example:
- Flats/darks could not be acquired during the scan
- The sample is in a container whose contribution should be "removed" from the main signal
For the record (see "Part 3 - Flat-field normalization"):
- Nabu will attempt at loading darks/flats named
{dataset_prefix}_darks.h5
and{dataset_prefix}_flats.h5
- If not present, nabu will compute the reduced flats/darks
In this case we want to force nabu to use provided flats/darks.
To do so, simply replace the files {dataset_prefix}_darks.h5
and {dataset_prefix}_flats.h5
with your custom darks/flats.
Note that creating HDF5/NXTomo files from scratch can be tedious. You can use nxtomo
, see for example https://nxtomo.readthedocs.io/en/latest/tutorials/create_from_scratch.html
CTF pipeline¶
Contrast Transfer Function (CTF) is another phase retrieval method.
Nabu implements a single-distance CTF method, possibly accounting for conicity.
Note that in this case, the overall processing is usually slower, as reconstruction cannot be done simply by sub-volumes.
The usual parameters for ID16A and ID16B are the following:
[preproc]
flatfield = 1
flat_distortion_correction_enabled = 0
flat_distortion_params = tile_size=100; interpolation_kind='linear'; padding_mode='edge'
take_logarithm = 0
ccd_filter_enabled = 1
ccd_filter_threshold = 0.04
[phase]
method = ctf
delta_beta = 80
ctf_geometry = z1_v=None; z1_h=None; detec_pixel_size=None; magnification=True
ctf_advanced_params = length_scale=1e-5; lim1=1e-5; lim2=0.2; normalize_by_mean=True
[reconstruction]
rotation_axis_position = global
cor_options =
Wavefront "distortion" correction
Nano-tomography beamlines use a very structured wavefront.
The projection images have to be aligned onto a reference (empty beam, i.e flat) image before flat-field normalization and phase retrieval.
In the configuration file:
[preproc]
flat_distortion_correction_enabled = 1
flat_distortion_params = tile_size=100; interpolation_kind='linear'; padding_mode='edge'
Translation movements
Step-by-step scans can be done with "random" motions to avoid rings artefacts. The motors displacements are recorded in a text file, where each line has two values for the horizontal and vertical displacements (in pixel units).
In the configuration file:
[reconstruction]
translation_movements_file = correct.txt
Excluding projections from reconstruction¶
Sometimes some projections, or even a whole angular range, have to be discarded from reconstruction.
In the configuration file, there is a exclude_projection
parameter in [dataset]
, which can be used in three ways:
exclude_projections = indices = exclude_indices.txt
: Path to a text file with one integer per line. Each corresponding projection INDEX will be ignored. This is the former default.exclude_projections = angles = exclude_angles.txt
: Path to a text file with angle in DEGREES, one per line. The corresponding angles will be ignored.exclude_projections = angular_range = [a, b]
ignore angles belonging to angular range [a, b] in degrees, with b included.
Reconstruction with binning¶
Binning is an operation consisting in averaging the contribution of several pixels, to form one equivalent pixel.
For example, in a 2X2 binning of an image, each output pixel is the average of 4 adjacent pixels.
Nabu allows to perform binning in both dimensions:
- Horizontal binning: the horizontal dimension is reduced (number of detector columns). Each output slice will be smaller, eg. 1024x1024 instead of 2048x2048.
- Vertical binning: the vertical dimension is reduced (number of detector rows). There will be less output slices, ex. 1080 horizontal slices instead of 2160 horizontal slices.
In the configuration file:
# Binning factor in the horizontal dimension when reading the data.
# The final slices dimensions will be divided by this factor.
binning = 2
# Binning factor in the vertical dimension when reading the data.
# This results in a lesser number of reconstructed slices.
binning_z = 2
(nabu allows any integer number).
Note that only the reconstruction step will be faster, as data still has to be loaded to perform pixels averaging.
Projections subsampling
It's also possible to reconstruct a volume using only one projection out of $N$.
In the configuration file, the parameter can be
- an integer: take 1 projection out of N
- in the form or N:M : take 1 projection out of N, start from projection M
projections_subsampling = 2
Note that in the current HDF5 library implementation, reading one image out of N is not faster (actually slower !!).
This means that subsampling has no performance benefit when using HDF5.
Reconstructing from even/odd projections¶
In some cases it can be useful to reconstruct the data from only even-numbered or odd-numbered projections.
For example the denoiser noise2inverse
needs to split the (reconstructed) data.
- To reconstruct from only the even projections, use
projections_subsampling = 2
orprojections_subsampling = 2:0
. - To reconstruct from only the odd projections, use
projections_subsampling = 2:1
.
Using Nabu API¶
This is an overview of Nabu API usage.
For a comprehensive API documentation, please refer to the API reference
Nabu provides building blocks that aim at being easy to use:
- Input parameters are numpy arrays
- Each function/class has a clear and decoupled role
Reconstruction¶
A frequent use of nabu API is to simply reconstruct a sinogram.
import numpy as np
from nabu.testutils import get_data
from nabu.reconstruction.fbp import Backprojector
sino = get_data("mri_sino500.npz")["data"]
# Backprojection operator
B = Backprojector(sino.shape)
rec = B.fbp(sino)
Phase retrieval¶
from nabu.preproc.phase import PaganinPhaseRetrieval
P = PaganinPhaseRetrieval(
radio.shape,
distance=0.5, # meters
energy=20, # keV
delta_beta=50.0,
pixel_size=1e-06, # meters
)
radio_phase = P.apply_filter(radio)
Pipeline processing from a configuration file (from within Python !)¶
from nabu.pipeline.fullfield.processconfig import ProcessConfig
from nabu.pipeline.fullfield.reconstruction import FullFieldReconstructor
# Parse the configuration file, build the processing steps/options
conf = ProcessConfig("/path/to/nabu.conf")
# Spawn a "reconstructor"
R = FullFieldReconstructor(conf)
print(R.backend) # cuda or numpy
R._print_tasks() # preview how the volume will be reconstructed
# Launch reconstruction
R.reconstruct()