recovar.core¶
Low-level primitives for cryo-EM forward modeling, geometry, CTF handling, and Fourier-space operations.
configs¶
Equinox-based configuration containers for the forward model, batch data, and model state.
recovar.core.configs
¶
Equinox-based configuration modules for clean parameter passing.
These modules bundle the many parameters that are passed to JAX-jitted functions
throughout RECOVAR into structured, typed containers. This eliminates the need for
complex static_argnums lists and keeps function signatures readable.
ForwardModelConfig
¶
Bases: Module
Bundles geometry, CTF, and discretization parameters.
All fields are static (compile-time constants), so changing any value triggers JAX recompilation — but these values are fixed for a given dataset and reconstruction run.
base_volume_shape
property
¶
Original (non-upsampled) volume shape.
compute_ctf(ctf_params, *, half_image=False)
¶
Compute CTF values for a batch of images.
Parameters¶
half_image : if True, evaluate on the rfft-packed half-spectrum grid.
compute_ctf_half(ctf_params)
¶
Convenience alias for compute_ctf(ctf_params, half_image=True).
compute_ctf_at_shape(ctf_params, image_shape)
¶
Compute CTF on a different frequency grid (e.g. upsampled).
replace(**kwargs)
¶
Create a new config with some fields replaced.
Useful for changing static fields (e.g. disc_type) which cannot
be modified via eqx.tree_at.
from_dataset(cryo, disc_type='linear_interp', process_fn=None, upsampling_factor=None)
classmethod
¶
Create from a CryoEMDataset instance.
Parameters¶
cryo : CryoEMDataset Source dataset for geometry and CTF configuration. disc_type : str Discretization type (e.g. 'linear_interp', 'cubic', ''). process_fn : callable, optional Image preprocessing function applied inside jitted code. upsampling_factor : int, optional Volume upsampling factor (e.g. 2 for 2× oversampled grid). Computes the upsampled volume shape directly without mutating the dataset object.
ModelState
¶
Bases: Module
Current reconstruction state passed to jitted functions.
Contains the mean estimate, volume mask, and optionally the PCA basis and eigenvalues used for covariance/embedding computations.
CovColumnOpts
¶
Bases: Module
Static options for covariance column (H/B) computation.
CovarianceOpts
¶
Bases: Module
Options for covariance estimation inner functions.
EmbeddingOpts
¶
Bases: Module
Options for embedding / latent coordinate computation.
ctf¶
CTF evaluation and parameter handling.
recovar.core.ctf
¶
CTF evaluation and parameter handling for cryo-EM images.
Provides :class:CTFEvaluator, a unified equinox module dispatched by
:class:CTFMode that evaluates the Contrast Transfer Function for all
supported cryo-EM/ET imaging modes.
CTFParamIndex
¶
Bases: IntEnum
Enum for CTF parameter indices to avoid magic numbers.
CTFMode
¶
Bases: IntEnum
CTF evaluation mode, determined by the imaging modality.
Attributes:
| Name | Type | Description |
|---|---|---|
SPA |
Standard single-particle analysis CTF. |
|
SPA_ANTIALIASED |
SPA with 2x-upsampled antialiasing filter. |
|
TILT_SERIES |
Parametric dose weighting from |
|
CRYO_ET |
Per-image dose and tilt-angle columns already present in the CTF parameter array. |
CTFEvaluator
¶
Bases: Module
Unified CTF evaluator for all cryo-EM/ET imaging modes.
An equinox module that is callable with the standard CTF signature::
evaluator(ctf_params, image_shape, voxel_size, *, half_image=False)
All fields are static (compile-time constants). Changing mode or
dose parameters triggers JAX recompilation, which is the correct
behaviour since these are fixed per dataset.
Parameters¶
mode : CTFMode
Imaging modality. Defaults to :attr:CTFMode.SPA.
dose_per_tilt : float
Dose per tilt in e-/A^2. Only used when mode == TILT_SERIES.
angle_per_tilt : float
Tilt-angle increment in degrees. Only used when mode == TILT_SERIES.
__call__(ctf_params, image_shape, voxel_size, *, half_image=False)
¶
Evaluate the CTF for a batch of images.
Parameters¶
ctf_params : jax.Array
Per-image CTF parameters, shape (N, K).
image_shape : tuple[int, int]
Image dimensions in pixels.
voxel_size : float
Pixel size in Angstroms.
half_image : bool
If True, evaluate on the rfft-packed half-spectrum grid.
as_ctf_evaluator(fn_or_evaluator)
¶
Coerce a callable into a CTFEvaluator-compatible eqx.Module.
If fn_or_evaluator is already a :class:CTFEvaluator or
:class:_LegacyCTFAdapter, return it unchanged. Otherwise wrap it
in a :class:_LegacyCTFAdapter.
evaluate_ctf(freqs, ctf_params)
¶
Evaluate the Contrast Transfer Function for a batch of images.
Broadcasts per-image parameters over a shared frequency grid in a single fused kernel (no vmap).
Parameters¶
freqs : array (n_pixels, 2)
Shared frequency coordinates in 1/Angstrom.
ctf_params : array (n_images, K)
Packed CTF parameters per image. Layout: [DFU, DFV, DFANG,
VOLT, CS, W, PHASE_SHIFT, BFACTOR, CONTRAST, ...] — see
:class:CTFParamIndex.
Returns¶
array (n_images, n_pixels)
compute_antialiased_ctf_squared(ctf_fn, ctf_params, image_shape, voxel_size, *, half_image=False)
¶
Compute CTF² with 2x-upsampled antialiasing, in full or half-image format.
Evaluates CTF on a 2x grid, squares, box-filters, and downsamples. This reduces aliasing in the Wiener weight accumulator.
geometry¶
Image translation, rotation, and coordinate transforms.
recovar.core.geometry
¶
Image translation, rotation matrix construction, and coordinate transforms.
get_gridpoint_coords(rotation_matrix, image_shape, volume_shape)
¶
Compute 3-D Fourier grid coordinates for a rotated central slice.
Applies rotation_matrix to the unrotated 2-D frequency plane and returns the corresponding 3-D grid indices in the volume.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation_matrix
|
Rotation matrix, shape |
required | |
image_shape
|
2-D image side length (static). |
required | |
volume_shape
|
3-D volume shape tuple (static). |
required |
Returns:
| Type | Description |
|---|---|
|
Rotated grid coordinates, shape |
get_unrotated_half_plane_grid_points(image_shape, three_d_upsampling_factor=1)
¶
Unrotated 2-D frequency grid for only the H*(W//2+1) half-image pixels.
Like :func:get_unrotated_plane_grid_points but generates coordinates
directly for only the non-redundant rfft-packed pixels.
Pixel ordering matches :func:~recovar.core.fourier_transform_utils.full_image_to_half_image:
uses _half_image_pixel_indices to select the same packed indices as
full_image_to_half_image. This keeps behavior correct for non-square
frequency grids.
translate_images(image, translation, image_shape, *, half_image=False)
¶
Apply in-plane translations to Fourier-space images via phase shifts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Fourier-space image(s), shape |
required | |
translation
|
Shift(s) in fractional pixel units, shape
|
required | |
image_shape
|
Image side length (static). |
required | |
half_image
|
If True, use rfft-packed half-spectrum frequency grid. |
False
|
Returns:
| Type | Description |
|---|---|
|
Translated image(s) with the same shape as image. |
forward¶
Forward model and adjoint operations for cryo-EM image formation.
recovar.core.forward
¶
Forward model and adjoint operations for cryo-EM image formation.
Provides Equinox-based APIs (forward_model, adjoint_forward_model, etc.)
that take a :class:~recovar.configs.ForwardModelConfig as first argument.
forward_model(config, volume, ctf_params, rotation_matrices, skip_ctf=False, half_image=False, half_volume=False)
¶
Project volume into images via slice-and-CTF forward model.
Parameters¶
half_image : bool
If True, return rfft-packed half-spectrum images and use
config.compute_ctf_half for CTF, roughly halving memory and compute.
half_volume : bool
If True, volume is an rfft-packed half-volume (N0*N1*(N2//2+1),).
forward_model_and_adjoint(config, volume, ctf_params, rotation_matrices, skip_ctf=False)
¶
Forward model plus its VJP (adjoint) closure.
adjoint_forward_model(config, slices, ctf_params, rotation_matrices, skip_ctf=False, volume=None, half_image=False, half_volume=False)
¶
Adjoint of the forward model (direct back-projection).
Uses :func:adjoint_slice_volume which dispatches to CUDA
when available, avoiding the VJP-through-FFI overhead.
Parameters¶
volume : optional accumulator array to add into (avoids fresh allocation).
half_image : if True, slices are rfft-packed half-spectrum images.
CTF is computed in half-spectrum format when skip_ctf=False.
half_volume : if True, output volume uses rfft-packed layout
(N0 * N1 * (N2 // 2 + 1),). Only supported with CUDA.
compute_AtAv(config, volume, ctf_params, rotation_matrices, noise_variance, skip_ctf=False)
¶
Compute A^T (A v / noise_variance) for normal equations.
slicing¶
Fourier slice extraction and backprojection.
recovar.core.slicing
¶
Fourier slice extraction and adjoint (backprojection) operations.
Dispatch rules
- GPU + order 0/1 → CUDA project + CUDA backproject
- GPU + order 3 → CUDA project + JAX VJP backproject (cubic)
- CPU + order 0/1 → RELION-style JAX (explicit scatter backproject)
- CPU + order 3 → JAX
map_coordinates+ VJP backproject
Three core public functions handle all volume/image format combinations via
half_volume and half_image parameters:
- :func:slice_volume (forward projection)
- :func:batch_slice_volume (batched forward)
- :func:adjoint_slice_volume (backprojection)
CUDA custom-VJP wrappers live in :mod:recovar.core.cuda_ops.
RELION-style JAX reference: :mod:recovar.core.relion_interp.
slice_volume(volume, rotation_matrices, image_shape, volume_shape, disc_type, half_volume=False, half_image=False, max_r=_AUTO)
¶
Project volume to images via interpolation.
Parameters¶
volume : array, flat (vol_size,) or grid-shaped.
Real or complex. Promoted to complex for the CUDA kernel.
half_volume : if True, volume is rfft-packed (N0*N1*(N2//2+1),).
half_image : if True, output images are rfft-packed (n, H*(W//2+1)).
max_r : sphere clipping radius. Default (_AUTO) uses
image_shape[0]//2 - 1. Pass None to disable clipping.
batch_slice_volume(volumes, rotation_matrices, image_shape, volume_shape, disc_type, half_volume=False, half_image=False, max_r=_AUTO)
¶
Project a batch of volumes to images.
Parameters¶
volumes : array (batch, vol_size).
Real or complex. Promoted to complex for the CUDA kernel.
half_volume : if True, volumes are rfft-packed half-volumes.
half_image : if True, output images are rfft-packed.
max_r : sphere clipping radius. Default uses
image_shape[0]//2 - 1. Pass None to disable.
adjoint_slice_volume(slices, rotation_matrices, image_shape, volume_shape, disc_type, volume=None, half_image=False, half_volume=False, max_r=_AUTO)
¶
Adjoint slice extraction (backprojection).
Parameters¶
slices : array (n_images, n_pixels).
Real or complex. If volume is complex, slices are promoted
to match (and vice versa).
half_image : if True, slices are rfft-packed half-spectrum images.
half_volume : if True, output uses rfft-packed half-volume layout.
volume : optional accumulator to add the result into.
max_r : sphere clipping radius. Default uses
image_shape[0]//2 - 1. Pass None to disable.
batch_adjoint_slice_volume(slices, rotation_matrices, image_shape, volume_shape, disc_type, volumes=None, half_image=False, half_volume=False, max_r=_AUTO)
¶
Batch backprojection: per-volume image sets to batch of volumes.
Parameters¶
slices : shape (batch, n_images, n_pixels).
Real or complex. Promoted to match volumes dtype (and vice versa).
rotation_matrices : shape (n_images, 3, 3) — shared across batch.
volumes : optional (batch, vol_flat_size) accumulators.
half_image, half_volume : same semantics as adjoint_slice_volume.
max_r : sphere clipping radius. Default uses
image_shape[0]//2 - 1. Pass None to disable.
precompute_cubic_coefficients(volume, volume_shape)
¶
Precompute periodic cubic B-spline coefficients for a full volume.
Uses periodic boundary conditions (FFT-based circulant solve). Output has the same shape as input (no boundary padding).
precompute_cubic_coefficients_half(volume, volume_shape)
¶
Precompute periodic cubic coefficients, stored as half-volume.
Since periodic coefficients preserve Hermitian symmetry, this is lossless.
slice_from_cubic_coefficients(coeffs, rotation_matrices, image_shape, volume_shape, half_image=False)
¶
Project from precomputed periodic cubic coefficients to images.
Parameters¶
coeffs : precomputed spline coefficients from :func:precompute_cubic_coefficients.
Can be full-volume (N0,N1,N2) or half-volume (N0N1(N2//2+1),) layout.
half_image : if True, output images are rfft-packed (n, H*(W//2+1)).
indexing¶
Frequency-to-volume index mapping and radial shell utilities.
recovar.core.indexing
¶
Frequency-to-volume index mapping and radial shell utilities.
mask¶
Real-space and Fourier-space mask generation and manipulation.
recovar.core.mask
¶
Real-space and Fourier-space mask generation and manipulation.
Provides masks for the reconstruction pipeline:
- Volume masks:
make_mask(standalone, RELION-style),make_mask_from_half_maps(averages half-maps then callsmake_mask),masking_options(pipeline entry point),make_mask_from_gt,make_union_gt_mask - Radial / spherical masks:
get_radial_mask,raised_cosine_mask,soft_mask_outside_map - Image masks:
window_mask,smooth_circular_mask - Softening:
soften_volume_mask(distance-transform cosine taper)
masking_options(volume_mask_option, means, volume_shape, dtype_real=np.float32, mask_dilation_iter=0, keep_input_mask=False, dilated_mask_dilations_iter=None)
¶
Build volume mask and dilated mask from a pipeline mask specification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
volume_mask_option
|
One of: path to |
required | |
means
|
Object with |
required | |
volume_shape
|
3-tuple giving the grid dimensions. |
required | |
dtype_real
|
Output dtype. |
float32
|
|
mask_dilation_iter
|
Extra dilation iterations for the input mask. |
0
|
|
keep_input_mask
|
If True, use the MRC mask as-is (no softening). |
False
|
|
dilated_mask_dilations_iter
|
Dilation iterations for the dilated mask.
Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
|
|
make_mask(volume, *, threshold='auto', lowpass_sigma=None, extend=None, soft_edge=3, cleanup=True)
¶
Create a solvent mask from a 3-D real-space volume.
Follows the same conceptual pipeline as RELION's relion_mask_create:
low-pass filter → threshold → (optional cleanup) → extend → soft cosine edge.
Key differences from RELION:
- Gaussian low-pass in real space (RELION uses a Fourier-space raised-cosine).
"auto"threshold via Otsu's method (RELION requires a user-specified density threshold, default 0.02 in postprocessing).- Optional morphological cleanup (fill holes, keep largest connected component) — RELION does not do this.
- Extension uses
distance_transform_edtfor spherical (Euclidean) dilation, matching RELION's brute-force Euclidean approach. - Soft edge uses
distance_transform_edt+ cosine (RELION computes min-Euclidean-distance per voxel — mathematically equivalent).
This function is the building block for :func:make_mask_from_half_maps
and can also be called directly on any volume (e.g. a consensus
reconstruction loaded from MRC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
volume
|
3-D real-space array (e.g. averaged half-maps, or a single reconstruction). |
required | |
threshold
|
How to binarize.
|
'auto'
|
|
lowpass_sigma
|
Gaussian sigma in voxels for low-pass smoothing
before thresholding. |
None
|
|
extend
|
Extension (dilation) of the binary mask in voxels.
|
None
|
|
soft_edge
|
Width of the cosine soft edge in voxels. (RELION postprocessing default: 6 pixels.) |
3
|
|
cleanup
|
If |
True
|
Returns:
| Type | Description |
|---|---|
|
Soft mask as a float32 array in [0, 1]. |
Example::
import mrcfile
from recovar.core.mask import make_mask
h1 = mrcfile.open("half1.mrc").data
h2 = mrcfile.open("half2.mrc").data
avg = (h1 + h2) / 2.0
# Automatic (recommended)
mask = make_mask(avg)
# RELION-like with manual parameters
mask = make_mask(avg, threshold=0.02, extend=3, soft_edge=6,
lowpass_sigma=3, cleanup=False)
make_mask_from_half_maps(halfmap1, halfmap2, smax=3, method='auto', **kwargs)
¶
Generate a solvent mask from two real-space half-map volumes.
Averages the two half-maps and delegates to :func:make_mask.
All keyword arguments are forwarded to make_mask.
For the legacy EMDA local-correlation method, pass
method="local_correlation".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
halfmap1, halfmap2
|
Real-space half-map volumes (same shape). |
required | |
smax
|
Kernel radius in pixels (only for |
3
|
|
method
|
|
'auto'
|
|
**kwargs
|
Forwarded to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
|
Soft mask as a float array in [0, 1]. |
make_mask_from_gt(gt_map, smax=3, iter=10, from_ft=True)
¶
Generate a mask from a ground-truth volume.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gt_map
|
Ground-truth volume (Fourier or real space). |
required | |
smax
|
Kernel radius for thresholding. |
3
|
|
iter
|
Dilation iterations. |
10
|
|
from_ft
|
If True, |
True
|
Returns:
| Type | Description |
|---|---|
|
Soft mask as a float array in [0, 1]. |
make_union_gt_mask(gt_volumes_real, volume_shape, smax=3, iter=1, dilation_iters=None, kern_rad=3)
¶
Create a union mask from multiple ground-truth real-space volumes.
For each volume, generates a per-volume mask via make_mask_from_gt,
thresholds at 0.5, then takes the logical OR of all per-volume masks.
The union is dilated and softened to produce the final mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gt_volumes_real
|
Either a list of 3-D arrays or a 2-D array of shape
|
required | |
volume_shape
|
Tuple giving the 3-D grid dimensions. |
required | |
smax
|
Gaussian kernel radius for |
3
|
|
iter
|
Dilation iterations inside |
1
|
|
dilation_iters
|
Additional dilation iterations applied to the union
mask. Defaults to |
None
|
|
kern_rad
|
Kernel radius for |
3
|
Returns:
| Type | Description |
|---|---|
|
Tuple |
|
|
in [0, 1] and binary_mask is the pre-softening boolean array. |
soften_volume_mask(binary_volume_mask, kern_rad=3)
¶
Soften a binary mask with a cosine taper based on distance transform.
Voxels inside the mask get value 1; voxels within kern_rad of the
boundary get a raised-cosine transition; voxels further out get 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
binary_volume_mask
|
Binary mask (values near 0 or 1). |
required | |
kern_rad
|
Width of the cosine transition in voxels. |
3
|
Returns:
| Type | Description |
|---|---|
|
Soft mask as float32 array in [0, 1]. |
get_radial_mask(shape, radius=None)
¶
Binary spherical mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shape
|
Volume or image shape tuple. |
required | |
radius
|
Mask radius in voxels. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
|
Boolean array with True inside the sphere. |
raised_cosine_mask(volume_shape, radius, radius_p, offset)
¶
3D raised-cosine mask with adjustable center.
Value is 1 for r < radius, cosine-tapered for radius <= r < radius_p,
and 0 beyond.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
volume_shape
|
3-tuple of grid dimensions. |
required | |
radius
|
Inner radius (full value). |
required | |
radius_p
|
Outer radius (zero value). |
required | |
offset
|
3-element center offset. |
required |
Returns:
| Type | Description |
|---|---|
|
Mask array of shape |
soft_mask_outside_map(vol, radius=-1, cosine_width=3, Mnoise=None)
¶
Soft mask outside map, adapted from RELION.
Applies a raised-cosine mask to vol, replacing voxels outside the
mask with the mean background value (or Mnoise if provided).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vol
|
Input volume (JAX or numpy array). |
required | |
radius
|
Mask radius in voxels. Defaults to half the box size. |
-1
|
|
cosine_width
|
Width of the cosine transition band. |
3
|
|
Mnoise
|
Optional replacement value for masked-out regions. |
None
|
Returns:
| Type | Description |
|---|---|
|
|
window_mask(D, in_rad, out_rad)
¶
2D circular window mask with linear taper (normalised coordinates).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
D
|
Image size in pixels (must be even). |
required | |
in_rad
|
Inner radius in normalised coordinates (1.0 = edge). |
required | |
out_rad
|
Outer radius in normalised coordinates. |
required |
Returns:
| Type | Description |
|---|---|
|
Float32 mask of shape |
smooth_circular_mask(image_size, radius, thickness)
¶
2D circular mask with a raised-cosine transition band.
Values are 1 inside radius, 0 outside radius + thickness,
and follow a cosine taper in between.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image_size
|
Image size in pixels. |
required | |
radius
|
Inner radius in pixels. |
required | |
thickness
|
Width of the cosine transition in pixels. |
required |
Returns:
| Type | Description |
|---|---|
|
Float mask of shape |
make_soft_edged_kernel(r1, shape)
¶
Create a soft-edged convolution kernel for local correlation.
Adapted from EMDA (https://gitlab.com/ccpem/emda).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r1
|
Kernel radius in pixels. |
required | |
shape
|
Volume shape for coordinate generation. |
required |
Returns:
| Type | Description |
|---|---|
|
Normalised soft-edged kernel. |
threshold_map(arr, prob=0.99, dthresh=None)
¶
Zero out voxels below the prob percentile threshold.
make_moving_gt_mask(gt_volumes_real, volume_shape, smax=3, iter=1, dilation_iters=None, kern_rad=3)
¶
Create a mask for the moving region across GT volumes.
linalg¶
Linear algebra helpers (batch SVD, QR, eigendecomposition).
recovar.core.linalg
¶
Linear algebra helpers: batch SVD, QR, eigendecomposition on CPU/GPU.
thin_svd_in_blocks(X, np=np, memory_to_use=5, epsilon=1e-08, n_components=-1)
¶
This is an unstable method for SVD but that can run on GPU. This should be only (maybe) used for matrices that cannot fit on the GPU.
Same as SVD but dispatch matrices in blocks to gpu (also pretty unstable)
thin_svd(X, np=np, epsilon=1e-08)
¶
For some reason, the built in svd seems to allocate a lot more memory than necessary.
randomized_svd(A, n_pcs=200)
¶
Randomized SVD for large matrices that don't fit on GPU.
broadcast_dot(x, y)
¶
Batched conjugate inner product: sum_k conj(x[...,k]) * y[...,k].
broadcast_outer(x, y)
¶
Batched outer product: x[..., i] * conj(y[..., j]).
inner_product(x, y)
¶
Conjugate inner product for non-batched arrays of identical shape.
batch_inner_product(x, y)
¶
Conjugate inner product over batch dimension 0.
Accepts arrays shaped (B, ...) and returns (B,).
half_spectrum_last_axis_weights(last_axis_size, dtype=jnp.float32)
¶
Weights to recover full-spectrum inner products from packed real FFT coefficients.
rfft2_hermitian_weights(image_shape, dtype=jnp.float32)
¶
Precompute sqrt(w) weights for 2-D half-spectrum (rfft2) inner products.
For Hermitian-symmetric arrays A, B of shape (H, W) stored in
rfft2 half-spectrum format (shape (H, W//2+1)), the weighted inner
product over the half equals the full-spectrum inner product::
sum_{k in half} w[k] * conj(A[k]) * B[k] == sum_{k in full} conj(A[k]) * B[k]
Built from :func:half_spectrum_last_axis_weights, then tiled over the H rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image_shape
|
|
required | |
dtype
|
dtype for the returned array (default float32). |
float32
|
Returns:
| Type | Description |
|---|---|
|
JAX array of shape |
half_spectrum_inner_product(x_half, y_half, full_shape)
¶
Inner product from packed half-spectrum inputs, equivalent to full-spectrum inner product.
This computes the weighted packed-spectrum sum directly (no full-spectrum reconstruction), applying factor-2 to non-edge frequencies on the packed axis.
batch_half_spectrum_inner_product(x_half, y_half, full_shape)
¶
Batched inner products from packed half-spectrum inputs.
Equivalent to computing full-spectrum batched inner products.
fourier_transform_utils¶
FFT utilities and frequency grid construction.
recovar.core.fourier_transform_utils
¶
get_1d_frequency_grid_rfft(n, voxel_size=1, scaled=False)
¶
Frequency grid for Hermitian-packed real FFT axis.
Returns non-negative bins [0, 1, ..., n//2] (or scaled equivalent).
get_k_coordinate_of_each_pixel_real(image_shape, voxel_size, scaled=True)
¶
2D packed-spectrum frequency coordinates for real-input FFT.
image_shape is the original real image shape (H, W). The returned
coordinates enumerate the packed spectrum with shape (H, W//2 + 1).
get_k_coordinate_of_each_pixel_3d_real(image_shape, voxel_size, scaled=True)
¶
3D packed-spectrum frequency coordinates for real-input FFT.
image_shape is the original real volume shape (D1, D2, D3). The
returned coordinates enumerate the packed spectrum with shape
(D1, D2, D3//2 + 1).
get_grid_of_radial_distances_real(image_shape, voxel_size=1, scaled=False, frequency_shift=0, rounded=True)
¶
Radial distance grid for Hermitian-packed real FFT spectra.
image_shape is the original real-space shape; output shape is the packed
spectrum shape with last axis N//2 + 1.
get_real_fft_packed_shape(shape)
¶
Return Hermitian-packed spectrum shape for a real-valued signal.
The last axis is reduced from N to N//2 + 1 as in rfft/rfftn.
get_real_fft_packed_last_axis_indices(n)
¶
Indices in shifted full spectrum that correspond to packed real bins.
get_k_coordinate_of_each_pixel_half(image_shape, voxel_size, scaled=True)
¶
Half-image frequency coords consistent with full_image_to_half_image.
get_shifted_conjugate_partner_indices(n)
¶
Index of the conjugate-symmetric partner for each bin in a shifted FFT axis.
For a length-n axis after fftshift, bin i holds frequency
u = (i + n//2) % n. Its conjugate partner is at frequency -u % n,
which maps back to shifted index (-u % n - n//2) % n. This function
returns that mapping as an int32 array of length n.
get_real_fft_memory_saving_ratio(shape)
¶
Ratio of packed (rfft) to full spectrum size: prod(packed) / prod(shape).
image_shape_to_half_image_shape(image_shape)
¶
Packed real-spectrum shape for 2D image shape under last-axis rFFT.
volume_shape_to_half_volume_shape(volume_shape)
¶
Packed real-spectrum shape for 3D volume shape under last-axis rFFT.
full_image_to_half_image(image, image_shape)
¶
Map centered full 2D spectrum to packed Hermitian representation.
Accepts either trailing grid shape (..., *image_shape) or flattened
trailing axis (..., prod(image_shape)). Returns in the same style.
half_image_to_full_image(half_image, image_shape)
¶
Map packed Hermitian 2D spectrum to centered full complex spectrum.
Uses index-based Hermitian conjugation: non-redundant columns are placed
at their packed positions, redundant columns are filled as
conj(half[(-i0)%H, |kx|]).
IMPORTANT: Do NOT change this to an FFT-based round-trip (e.g. irfft2 → fft2). This must stay consistent with half_volume_to_full_volume's approach so that VJPs match the CUDA kernel's Hermitian fold scatter.
Accepts either trailing packed grid shape
(..., *image_shape_to_half_image_shape(image_shape)) or flattened
trailing axis (..., prod(half_shape)). Returns in the same style.
full_volume_to_half_volume(volume, volume_shape)
¶
Map centered full 3D spectrum to packed Hermitian representation.
Accepts either trailing grid shape (..., *volume_shape) or flattened
trailing axis (..., prod(volume_shape)). Returns in the same style.
half_volume_to_full_volume(half_volume, volume_shape)
¶
Map packed Hermitian 3D spectrum to centered full complex spectrum.
Uses index-based Hermitian conjugation: non-redundant columns are placed
at their packed positions, redundant columns (negative last-axis
frequencies) are filled as conj(half[(-i0)%N0, (-i1)%N1, |kz|]).
This approach has a simple VJP that matches per-voxel Hermitian folding in the CUDA backproject kernel (unlike the FFT round-trip which distributes gradients through the FFT chain differently).
IMPORTANT: Do NOT change this to an FFT-based round-trip (e.g. irfft3 → fft3). The VJP of an FFT round-trip distributes gradients differently than per-voxel Hermitian folding, breaking the CUDA half-volume backproject kernel's correctness. The CUDA kernel's Hermitian fold scatter is specifically designed to be the correct adjoint of THIS index-based expand.
Accepts either trailing packed grid shape
(..., *volume_shape_to_half_volume_shape(volume_shape)) or flattened
trailing axis (..., prod(half_shape)). Returns in the same style.
get_dft2_real(img, norm=DEFAULT_FFT_NORM)
¶
Centered 2D FFT for real-valued inputs using Hermitian packing.
Output shape is (..., H, W//2 + 1) with only the non-redundant last-axis
frequencies stored.
get_idft2_real(img, image_shape=None, norm=DEFAULT_FFT_NORM)
¶
Inverse of get_dft2_real returning a real-valued image.
get_dft3_real(img, norm=DEFAULT_FFT_NORM, axes=(-3, -2, -1))
¶
Centered 3D FFT for real-valued inputs using Hermitian packing.
The packed axis is the last transform axis in axes.
get_idft3_real(img, volume_shape=None, norm=DEFAULT_FFT_NORM, axes=(-3, -2, -1))
¶
Inverse of get_dft3_real returning a real-valued volume.
cubic_interpolation¶
Cubic spline interpolation on 3-D grids.
recovar.core.cubic_interpolation
¶
JAX-based cubic spline interpolation for multi-dimensional arrays.
Provides cubic spline interpolation functionality with precomputed coefficients.
Uses periodic boundary conditions (circulant system solved via FFT), which
preserve Hermitian symmetry of the input: if V[k] = conj(V[-k]) then
C[k] = conj(C[-k]). Output shape equals input shape (no boundary padding).
The periodic circulant system [1, 4, 1] is solved as:
C = ifft(fft(V) / eigenvalues)
where eigenvalues_k = 4 + 2cos(2pi*k/N).
calculate_spline_coefficients(data)
¶
Calculate periodic cubic spline coefficients for an array.
Solves the periodic circulant system [1, 4, 1] along each dimension
using FFT. Output has the same shape as input (no boundary padding).
Preserves Hermitian symmetry: if data[k] = conj(data[-k]) then
the coefficients satisfy the same property.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Array
|
Input array (any number of dimensions). |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Spline coefficients with same shape as input. |
interpolate_with_spline(spline_coeffs, coords, boundary_mode='wrap', fill_value=0.0)
¶
Interpolate using cubic spline coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spline_coeffs
|
ArrayLike
|
Precomputed spline coefficients from calculate_spline_coefficients |
required |
coords
|
Sequence[ArrayLike]
|
Sequence of coordinate arrays, one per dimension |
required |
boundary_mode
|
str
|
Boundary handling mode ('wrap' for periodic) |
'wrap'
|
fill_value
|
ArrayLike
|
Fill value for out-of-bounds when boundary_mode='fill' |
0.0
|
Returns:
| Type | Description |
|---|---|
Array
|
Interpolated values at the specified coordinates |
map_coordinates(input, coordinates, order, mode='wrap', cval=0.0)
¶
Cubic spline interpolation compatible with scipy/cryojax API.
Only supports order=3 (cubic spline interpolation). Coordinates are shifted by -1 for periodic convention.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input
|
Input array to interpolate |
required | |
coordinates
|
Sequence of coordinate arrays |
required | |
order
|
Interpolation order (must be 3) |
required | |
mode
|
Boundary mode (default 'wrap' for periodic) |
'wrap'
|
|
cval
|
Fill value for out-of-bounds |
0.0
|
Returns:
| Type | Description |
|---|---|
|
Interpolated values |
map_coordinates_with_cubic_spline(coefficients, coordinates, mode='wrap', cval=0.0)
¶
Interpolate using precomputed cubic spline coefficients.
Coordinates are shifted by -1 for periodic convention.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coefficients
|
Precomputed spline coefficients (ndim-dimensional). |
required | |
coordinates
|
Either a sequence of ndim coordinate arrays, or a single
array of shape |
required | |
mode
|
Boundary mode (default 'wrap' for periodic). |
'wrap'
|
|
cval
|
Fill value for out-of-bounds. |
0.0
|
padding¶
Real-space zero-padding and unpadding for Fourier oversampling.
recovar.core.padding
¶
Real-space zero-padding and unpadding for Fourier oversampling.
padded_rfft(images, image_size, padding)
¶
Pad real-space images and compute real FFT → half-spectrum output.
Like :func:padded_dft but uses rfft2, producing flattened half-spectrum
images of shape (n_images, H * (W // 2 + 1)).