pyepri.processing
This module provides high-level tools for EPR image reconstruction (filtered-backprojection, TV-regularized least-squares, …).
Functions
|
EPR single source image reconstruction using TV-regularized least-squares. |
|
EPR source separation TV-regularized least-squares. |
|
Filtered back-projection for 2D image reconstruction from EPR measurements. |
|
Filtered back-projection for 3D image reconstruction from EPR measurements. |
|
Factorized consistency checks for functions in the |
Module Contents
- pyepri.processing.tv_monosrc(proj, B, fgrad, delta, h, lbda, out_shape, backend=None, init=None, tol=1e-05, nitermax=None, eval_energy=False, verbose=False, video=False, displayer=None, Ndisplay=20, eps=1e-06, disable_toeplitz_kernel=False, notest=False)[source]
EPR single source image reconstruction using TV-regularized least-squares.
This functions performs EPR image reconstruction by minimization of the TV-regularized least-squares energy
\[E(u) := \frac{1}{2} \|A(u) - s\|_2^2 + \lambda_{\text{unrm}} \mathrm{TV}(u)\]Where \(u\) is a 2D or 3D image, \(A\) denotes the EPR projection operator (that changes an image u into EPR projections), \(s\) denotes the measured projections (input parameter
proj
below), \(TV\) denotes a discrete total variation regularizer, and \(\lambda_{\text{unrm}} > 0\) is a regularity parameter (or TV weight) whose value is set proportional to thelbda
input parameter (see below).This functions relies on the numerical optimization scheme
pyepri.optimization.tvsolver_cp2016()
to perform the minimization of the TV-regularized least-squares energy \(E\) (see [ABDF23] for more details).- Parameters:
proj (array_like (with type backend.cls)) – Two-dimensional array with shape
(Nproj, len(B))
(whereNproj = fgrad.shape[1]
) such thatproj[k,:]
corresponds to the k-th EPR projection (acquired with field gradientfgrad[:,k]
and sampled over the gridB
).B (array_like (with type backend.cls)) – One dimensional array corresponding to the homogeneous magnetic field sampling grid, with unit denoted below as [B-unit] (can be Gauss (G), millitesla (mT), …), associated to the input projections
proj
.fgrad (array_like (with type backend.cls)) –
Two or three dimensional array such that
fgrad[:,k]
corresponds to the coordinates of the field gradient vector associated to the k-th EPR projection to be computed.The physical unit of the field gradient should be consistent with that of B and delta, i.e., fgrad must be provided in [B-unit] / [length-unit] (e.g., G/cm, mT/cm, …).
delta (float) – Pixel size for the reconstruction, given in a length unit denoted as [length-unit] (can be centimeter (cm), millimeter (mm), …).
h (array_like (with type backend.cls)) – One dimensional array with same length as B corresponding to the reference spectrum sampled over the grid B.
lbda (float) –
Normalized regularization parameter, the actual TV weight \(\lambda_{\text{unrm}}\) (denoted below by
lbda_unrm
) will be computed using>>> Bsw = (B[-1] - B[0]).item() >>> ndim = fgrad.shape[0] >>> cof1 = (h.max() - h.min()).item() >>> cof2 = fgrad.shape[1] / (2.**(ndim - 1) * math.pi) >>> cof3 = (len(B) / Bsw) >>> lbda_unrm = cof1 * cof2 * cof3 * delta**(ndim-1) * lbda
out_shape (tuple or list of int with length 2 or 3) – Shape of the output image.
backend (<class 'pyepri.backends.Backend'> or None, optional) –
A numpy, cupy or torch backend (see
pyepri.backends
module).When backend is None, a default backend is inferred from the input arrays
(proj, B, fgrad, h)
.init (array_like (with type backend.cls)) – Initializer for the numerical optimization scheme (
pyepri.optimization.tvsolver_cp2016()
).tol (float, optional) – A tolerance parameter used to stop the iterations of the numerical optimization scheme.
nitermax (int, optional) – Maximal number of iterations for the numerical optimization scheme.
eval_energy (bool, optional) –
Enable / disable energy evaluation during the iterations of the numerical optimization scheme.
When
eval_energy is True
, the TV-regularized least-squares energy to be minimized will be computed eachNdisplay
iteration of the scheme. The computed energy values are displayed whenverbose
orvideo
modes are enabled (see below).The computed energy values are not returned by this function (to retrieve the energy value, the user can directly use the
pyepri.optimization.tvsolver_cp2016()
function).Enabling energy computation will increase computation time.
verbose (bool, optional) – Enable / disable verbose mode. Set
verbose = True
to print each enable verbose mode of the numerical optimization scheme.video (bool, optional) – Enable / disable video mode (display and refresh the latent image each
Ndisplay
iteration).displayer (<class 'pyepri.displayers.Displayer'>, optional) –
Image displayer used to display the latent image during the scheme iteration. When not given (
displayer is None
), a default displayer is instantiated.Enabling video is definitely helpful but also slows-down the execution (it is recommended to use the
Ndisplay
parameter to control the image refreshing rate).Ndisplay (int, optional) – Can be used to limit energy evaluation, image display, and verbose mode to the iteration indexes
k
that are multiples of Ndisplay (useful to speed-up the process).eps (float, optional) – Precision requested (>1e-16) for the EPR related monosrc involved in the reconstruction model (see functions in the
pyepri.monosrc
submodule).disable_toeplitz_kernel (bool, optional) –
The numerical optimization scheme performs at each iteration a projection followed by a backprojection operation. By default (i.e., when
disable_toeplitz_kernel is False
), this operation is done by means of a circular convolution using a Toeplitz kernel (which can be evaluated efficiently using FFT).When
disable_toeplitz_kernel is True
, the Toeplitz kernel is not used and the evaluation is down sequentially (compute projection and then backprojection).The setting of this parameter should not affect the returned image, but only the computation time (the default setting should be the faster).
notest (bool, optional) – Set
notest=True
to disable consistency checks.
- Returns:
out – Output image (when convergence of the numerical optimization scheme, this image is a minimizer of the TV-regularized least-squares energy).
- Return type:
array_like (with type backend.cls)
- pyepri.processing.tv_multisrc(proj, B, fgrad, delta, h, lbda, out_shape, backend=None, init=None, tol=1e-05, nitermax=None, eval_energy=False, disable_toeplitz_kernel=False, verbose=False, video=False, Ndisplay=20, displayer=None, eps=1e-06, notest=False)[source]
EPR source separation TV-regularized least-squares.
This function implements the multi-sources EPR image reconstruction method presented in [BADF23]. This function can be viewed as a generalization of
tv_monosrc()
which has be extended to address either one or both of the following situations:the sample is made of K >= 1 EPR source, leading to the problem of reconstructing K image(s) (one image per EPR source);
projections acquisitions are done in different experimental setups (for instance by changing the microwave power from one experiment to another), so that the reconstruction is done according to L >= 1 sinogram acquisitions.
- Parameters:
proj (sequence of array_like (with type backend.cls)) –
A sequence with length L such that
proj[i]
is a two-dimensional array containing the EPR projections acquired in the i-th acquisition setup.In particular, each
proj[i]
must containlen(B)
columns (see parameterB
below) and each rowpi in proj[i]
corresponds to an EPR projection of the multisources sample in the i-th acquisition setup.B (array_like (with type backend.cls)) – One dimensional array corresponding to the homogeneous magnetic field sampling grid, with unit denoted below as [B-unit] (can be Gauss (G), millitesla (mT), …), associated to the input projections
proj
.fgrad (sequence of array_like (with type backend.cls)) –
A sequence with length L, such that each
frad[i]
is a two or three dimensional array with the following properties:fgrad[i].shape[0]
is 2 or 3 (depending on the dimension of the images to be reconstructed);fgrad[i].shape[1] == proj[i].shape[0]
;fgrad[i][:,k]
corresponds to the coordinates of the field gradient vector used to acquireproj[i][k,:]
.
The physical unit of the provided field gradients [B-unit] / [length-unit] (e.g., G/cm, mT/cm, …) and must be consistent with that units of the input parameters
B
anddelta
.When
L > 1
andlen(fgrad) = 1
, we assume thatfgrad[i][j] = fgrad[0][i]`
for alli in range(L)
and allj in range(K)
.delta (float) – Pixel size for the reconstruction, given in [length-unit] consistent with that used in
fgrad
(can be centimeter (cm), millimeter (mm), …).h (sequence of sequence of array_like (with type backend.cls)) –
Contains the reference spectra (sampled over the grid
B
) of each individual source (j) for each experimental setup (i). More precisely,h[i][j]
is a monodimensional array corresponding to the sampling overB
of the reference spectrum of the j-th source in the i-th experimental setting.When
L > 1
andlen(h) = 1
, we assume thath[i][j] = h[0][j]`
for alli in range(L)
and allj in range(K)
.lbda (float) –
Normalized regularization parameter, the actual TV weight (denoted below by
lbda_unrm
) that will be passed to the numerical optimization scheme (pyepri.optimization.tvsolver_cp2016_multisrc()
) will be computed using>>> Bsw = (B[-1] - B[0]).item() >>> cof1 = max(tuple((h_ij.max() - h_ij.min()).item() for h_i ... in h for h_ij in h_i)) >>> cof2 = float(Nproj) / (2.**(ndim - 1) * math.pi * len(fgrad)) >>> cof3 = (len(B) / Bsw) >>> lbda_unrm = cof1 * cof2 * cof3 * delta**(ndim-1) * lbda
out_shape (sequence of sequence of int) – Sequence made of each source shape. More precisely,
out_shape[j]
corresponds the the shape of the j-th source image.backend (<class 'pyepri.backends.Backend'> or None, optional) –
A numpy, cupy or torch backend (see
pyepri.backends
module).When backend is None, a default backend is inferred from the input arrays
(proj, B, fgrad)
.init (sequence of array_like (with type backend.cls)) – A sequence of length L used as initializer for the numerical optimization scheme (
pyepri.optimization.tvsolver_cp2016_multisrc()
).tol (float, optional) – A tolerance parameter used to stop the iterations of the numerical optimization scheme.
nitermax (int, optional) – Maximal number of iterations for the numerical optimization scheme.
eval_energy (bool, optional) –
Enable / disable energy evaluation during the iterations of the numerical optimization scheme.
When
eval_energy is True
, the TV-regularized least-squares energy to be minimized will be computed eachNdisplay
iteration of the scheme. The computed energy values are displayed whenverbose
orvideo
modes are enabled (see below).The computed energy values are not returned by this function (to retrieve the energy value, the user can directly use the
pyepri.optimization.tvsolver_cp2016_multisrc()
function).Enabling energy computation will increase computation time.
verbose (bool, optional) – Enable / disable verbose mode. Set
verbose = True
to print each enable verbose mode of the numerical optimization scheme.video (bool, optional) – Enable / disable video mode (display and refresh the latent image each
Ndisplay
iteration).displayer (<class 'pyepri.displayers.Displayer'>, optional) –
Image displayer used to display the latent multi-source image during the scheme iteration. When not given (
displayer is None
), a default displayer is instantiated.Enabling video is definitely helpful but also slows-down the execution (it is recommended to use the
Ndisplay
parameter to control the image refreshing rate).Ndisplay (int, optional) – Can be used to limit energy evaluation, image display, and verbose mode to the iteration indexes
k
that are multiples of Ndisplay (useful to speed-up the process).eps (float, optional) – Precision requested (>1e-16) for the EPR related monosrc involved in the reconstruction model (see functions in the
pyepri.monosrc
submodule).disable_toeplitz_kernel (bool, optional) –
The numerical optimization scheme performs at each iteration a projection followed by a backprojection operation. By default (i.e., when
disable_toeplitz_kernel is False
), this operation is done by means of a circular convolutions between some Toeplitz kernels and the sources images. Those convolutions can be evaluated efficiently using FFT.When
disable_toeplitz_kernel is True
, the Toeplitz kernels are not used and the evaluation is down sequentially (compute projection and then backprojection).The setting of this parameter should not affect the returned images, but only the computation time (the default setting should be the faster).
notest (bool, optional) – Set
notest=True
to disable consistency checks.
- Returns:
out – Output image (when convergence of the numerical optimization scheme, this image is a minimizer of the TV-regularized least-squares energy).
- Return type:
array_like (with type backend.cls)
- pyepri.processing.eprfbp2d(proj, fgrad, h, B, xgrid, ygrid, interp1, backend=None, frequency_cutoff=1.0, verbose=False, video=False, displayer=None, Ndisplay=1, shuffle=False, notest=False)[source]
Filtered back-projection for 2D image reconstruction from EPR measurements.
- Parameters:
proj (array_like (with type backend.cls)) – Two-dimensional array containing the measured EPR projections (each row represents a measured projection).
fgrad (array_like (with type backend.cls)) –
Two dimensional array with shape
(2, proj.shape[0])
such thatfgrad[:,k,]
corresponds to the (X,Y) coordinates of the field gradient vector associated toproj[k,:]
.We shall denote below by [B-unit]/[length-unit] the physical unit of the field gradient, where [B-unit] stands for the magnetic B-field stength unit (e.g., Gauss (G), millitesla (mT), …) and [length-unit] stends for the lenght unit (e.g., centimeter (cm), millimeter (mm), …).
h (array_like (with type backend.cls)) – One dimensional array with length
proj.shape[1]
corresponding to the reference (or zero-gradient) spectrum sampled over the same sampling grid as the measured projections.B (array_like (with type backend.cls)) – One dimensional array with length
proj.shape[1]
corresponding to the homogeneous magnetic field sampling grid (with unit [B-unit]) used to measure the projections (proj
) and the reference spectrum (h
).xgrid (array_like (with type backend.cls)) – Sampling nodes (with unit [length-unit]) along the X-axis of the 2D space (axis with index 1 of the reconstructed image).
ygrid (array_like (with type backend.cls)) – Sampling nodes (with unit [length-unit]) along the Y-axis of the 2D space (axis with index 0 of the reconstructed image).
interp1 (<class 'function'>) –
One-dimensional interpolation function with prototype
y = interp1(xp,fp,x)
, wherexp
,fp
andx
are one-dimensional arrays (with type backend.cls) corresponding respectively tothe coordinate nodes of the input data points,
the input data points,
the coordinate query nodes at which to evaluate the interpolated values,
the interpolated values.
Some examples of linear interpolations in numpy, cupy and torch are given below :
>>> lambda xp, fp, x : numpy.interp(x, xp, fp, left=0., right=0.) >>> lambda xp, fp, x : cupy.interp(x, xp, fp, left=0., right=0.) >>> lambda xp, fp, x : torchinterp1d.interp1d(xp, fp, x)
The last example above, relies on the torchinterp1d package (available from Github <https://github.com/aliutkus/torchinterp1d>).
backend (<class 'pyepri.backends.Backend'> or None, optional) –
A numpy, cupy or torch backend (see
pyepri.backends
module).When backend is None, a default backend is inferred from the input arrays
(proj, fgrad, h, B, xgrid, ygrid)
.frequency_cutoff (float, optional) –
Apply a frequency cutoff to the projections during the filtering process (to avoid noise amplification caused by the Ram-Lak filter).
The input frequency_cutoff value corresponds to the proportion of Fourier coefficients to preserve (e.g., use
frequency_cutoff = 0.1
to preserve 10% of the (lowest-frequency) Fourier coefficients and set to zero the 90% remaining (high-frequency) Fourier coefficients).Since frequency cutoff causes ringing artifact (i.e., generates spurious oscillation patterns), we recommend to avoid using this parameter (i.e., to keep
frequency_cutoff = 1.
) and perform instead apodization of the input projections using a smoother apodization profile as a preprocessing before calling this function (see Example section below).verbose (bool, optional) – Enable / disable verbose mode (display a message each time a projection is processed).
video (bool, optional) –
Enable / disable video mode. When video mode is enable (
video=True
), show the latent image and refresh display each time a chunk ofNdisplay
projections has been processed.Please note that enabling video mode will slow down the computation (especially when a GPU device is used because the the displayed images are transferred to the CPU device).
displayer (<class 'pyepri.displayers.Displayer'>, optional) –
When video is True, the attribute
displayer.init_display
anddisplayer.update_display
will be used to display the latent imageu
along the iteration of the numerical scheme.When not given (
displayer=None
), a default displayer will be instantiated.Ndisplay (int, optional) – Refresh the displayed image each time a chunk of Ndisplay projections has been processed (this parameter is not used when
video is False
).shuffle (bool, optional) – Enable / disable shuffling of the projections order (shuffling has no effect on the final returned volume, but may lead to faster shape appearance when video mode is enabled).
notest (bool, optional) – Set
notest=True
to disable consistency checks.
- Returns:
out – Two dimensional array corresponding to the reconstructed image.
The dimensions (0,1) correspond to the spatial axes (Y,X) of the image (this is the classical convention in image processing).
The reconstruction is performed over the rectangular grid generated from the input grids along each coordinate axis (xgrid, ygrid), i.e.,
out[i,j]
corresponds to the reconstructed image at the spatial location
X, Y = xgrid[j], ygrid[i]
.- Return type:
array_like (with type backend.cls)
See also
- pyepri.processing.eprfbp3d(proj, fgrad, h, B, xgrid, ygrid, zgrid, interp1, backend=None, frequency_cutoff=1.0, verbose=False, video=False, displayer=None, Ndisplay=1, shuffle=False, notest=False)[source]
Filtered back-projection for 3D image reconstruction from EPR measurements.
- Parameters:
proj (array_like (with type backend.cls)) – Two-dimensional array containing the measured EPR projections (each row represents a measured projection).
fgrad (array_like (with type backend.cls)) –
Two dimensional array with shape
(3, proj.shape[0])
such thatfgrad[:,k,]
corresponds to the (X,Y,Z) coordinates of the field gradient vector associated toproj[k,:]
.We shall denote below by [B-unit]/[length-unit] the physical unit of the field gradient, where [B-unit] stands for the magnetic B-field stength unit (e.g., Gauss (G), millitesla (mT), …) and [length-unit] stends for the lenght unit (e.g., centimeter (cm), millimeter (mm), …).
h (array_like (with type backend.cls)) – One dimensional array with length
proj.shape[1]
corresponding to the reference (or zero-gradient) spectrum sampled over the same sampling grid as the measured projections.B (array_like (with type backend.cls)) – One dimensional array with length
proj.shape[1]
corresponding to the homogeneous magnetic field sampling grid (with unit [B-unit]) used to measure the projections (proj
) and the reference spectrum (h
).xgrid (array_like (with type backend.cls)) – Sampling nodes (with unit [length-unit]) along the X-axis of the 3D space (axis with index 1 of the reconstructed volume).
ygrid (array_like (with type backend.cls)) – Sampling nodes (with unit [length-unit]) along the Y-axis of the 3D space (axis with index 0 of the reconstructed volume).
zgrid (array_like (with type backend.cls)) – Sampling nodes (with unit [length-unit]) along the Z-axis of the 3D space (axis with index 2 of the reconstructed volume).
interp1 (<class 'function'>) –
One-dimensional interpolation function with prototype
y = interp1(xp,fp,x)
, wherexp
,fp
andx
are one-dimensional arrays (with type backend.cls) corresponding respectively tothe coordinate nodes of the input data points,
the input data points,
the coordinate query nodes at which to evaluate the interpolated values,
the interpolated values.
Some examples of linear interpolations in numpy, cupy and torch are given below :
>>> lambda xp, fp, x : numpy.interp(x, xp, fp, left=0., right=0.) >>> lambda xp, fp, x : cupy.interp(x, xp, fp, left=0., right=0.) >>> lambda xp, fp, x : torchinterp1d.interp1d(xp, fp, x)
The last example above, relies on the torchinterp1d package (available from Github <https://github.com/aliutkus/torchinterp1d>).
backend (<class 'pyepri.backends.Backend'> or None, optional) –
A numpy, cupy or torch backend (see
pyepri.backends
module).When backend is None, a default backend is inferred from the input arrays
(proj, fgrad, h, B, xgrid, ygrid, zgrid)
.frequency_cutoff (float, optional) –
Apply a frequency cutoff to the projections during the filtering process (to avoid noise amplification caused by the Ram-Lak filter).
The input frequency_cutoff value corresponds to the proportion of Fourier coefficients to preserve (e.g., use frequency_cutoff = 0.1 to preserve 10% of the (lowest-frequency) Fourier coefficients and set to zero the 90% remaining (high-frequency) Fourier coefficients).
Since frequency cutoff causes ringing artifact (i.e., generates spurious oscillation patterns), we recommend to avoid using this parameter (i.e., to keep
frequency_cutoff = 1.
) and perform instead apodization of the input projections using a smoother apodization profile as a preprocessing before calling this function (see Example section below).verbose (bool, optional) – Enable / disable verbose mode (display a message each time a projection is processed).
video (bool, optional) –
Enable / disable video mode. When video mode is enable (video=True), show three slices of the latent volume and refresh the display each time a chunk of Ndisplay projections has been processed.
Please note that enabling video mode will slow down the computation (especially when a GPU device is used because the the displayed images are transferred to the CPU device).
displayer (<class 'pyepri.displayers.Displayer'>, optional) –
When video is True, the attribute
displayer.init_display
anddisplayer.update_display
will be used to display the latent imageu
along the iteration of the numerical scheme.When not given (
displayer=None
), a default displayer will be instantiated.Ndisplay (int, optional) – Refresh the displayed images each time a chunk of Ndisplay projections has been processed (this parameter is not used when
video is False
).shuffle (bool, optional) – Enable / disable shuffling of the projections order (shuffling has no effect on the final returned volume, but may lead to faster shape appearance when video mode is enabled).
notest (bool, optional) – Set
notest=True
to disable consistency checks.
- Returns:
vol – Three dimensional array corresponding to the reconstructed volume.
The dimensions (0,1,2) correspond to the spatial axes (Y,X,Z) (we used this convention for compliance with data ordering in the 2D setting).
The reconstruction is performed over the rectangular grid generated from the input grids along each coordinate axis (xgrid, ygrid, zgrid), i.e.,
vol[i,j,k]
corresponds to the reconstructed volume at the spatial location
X, Y, Z = xgrid[j], ygrid[i], zgrid[k]
.- Return type:
array_like (with type backend.cls)
See also
- pyepri.processing._check_inputs_(caller, backend, proj=None, B=None, fgrad=None, delta=None, h=None, lbda=None, out_shape=None, init=None, tol=None, nitermax=None, eval_energy=None, disable_toeplitz_kernel=None, verbose=None, video=None, displayer=None, eps=None, Ndisplay=None, xgrid=None, ygrid=None, zgrid=None, interp1=None, frequency_cutoff=None, shuffle=None)[source]
Factorized consistency checks for functions in the
pyepri.processing
submodule.