Fourier Ring Correlation (FRC) — the 2-D analogue of the FSC.
Identical to FSCPlot but enforces two-dimensional input and
uses “FRC” in all labels and output filenames. FRC is standard in
cryo-EM and increasingly used in X-ray ptychography and nano-tomography.
Parameters:
img1 (ndarray) – A 2-dimensional array containing the first image.
img2 (ndarray) – A 2-dimensional array containing the second image.
threshold (str, optional) – 'halfbit' (default) or 'onebit'.
ring_thick (int, optional) – Ring thickness in pixels. Default 1.
apod_width (int, optional) – Apodization width in pixels. Default 20.
Returns:
fn (ndarray) – Spatial frequencies normalised by the Nyquist frequency.
FRC (ndarray) – Fourier Ring Correlation curve.
T (ndarray) – Threshold curve.
Raises:
ValueError – If either input image is not 2-dimensional.
Notes
The mathematical definition and threshold criteria are identical to the
FSC; only the geometry changes (rings in 2-D vs shells in 3-D).
Plot the FRC and threshold curves and return the underlying data.
Returns:
fn (ndarray) – Spatial frequencies normalised by the Nyquist frequency.
T (ndarray) – Threshold curve (half-bit or one-bit).
FRC (ndarray) – Fourier Ring Correlation curve (real part).
fn_res_cpx (float or None) – Resolution crossing frequency in cycles/pixel.
Use resolution_full or resolution_half for
results already converted to physical units.
None if FRC never exceeds the threshold.
Upper level object to plot the FSC and threshold curves
Parameters:
img1 (ndarray) – A 2-dimensional array containing the first image
img2 (ndarray) – A 2-dimensional array containing the second image
threshold (str, optional) – The option onebit means 1 bit threshold with SNRt=0.5, which
should be used for two independent measurements. The option halfbit
means 1/2 bit threshold with SNRt=0.2071, which should be
use for split tomogram. The default option is half-bit.
ring_thick (int, optional) – Thickness of the frequency rings. Normally the pixels get
assined to the closest integer pixel ring in Fourier Domain.
With ring_thick, each ring gets more pixels and more statistics.
The default value is 1.
apod_width (int, optional) – Width in pixel of the edges apodization. It applies a Hanning
window of the size of the data to the data before the Fourier
transform calculations to attenuate the border effects. The
default value is 20.
pixel_size (float, optional) – Physical size of one pixel/voxel in any consistent unit (e.g. metres,
nanometres). Used to compute resolution_full and
resolution_half in physical units. Default 1.0 (result
in pixels).
Full-period resolution in physical units (van Heel / FSC convention):
pixel_size/fn_res_cpx. This is the spatial period of the
finest resolvable grating — the standard quantity reported in FSC
analyses. None if FSC never exceeds the threshold.
Half-period resolution in physical units (Rayleigh / feature-size
convention): resolution_full/2. This equals the smallest
resolvable feature size and is the quantity most often reported in
optical microscopy. None if FSC never exceeds the threshold.
fn (ndarray) – Spatial frequencies normalised by the Nyquist frequency
(range [0,1]).
T (ndarray) – Threshold curve (half-bit or one-bit).
FSC (ndarray) – Real part of the Fourier Shell Correlation values.
fn_res_cpx (float or None) – Resolution crossing frequency in cycles/pixel.
Use resolution_full or resolution_half for
results already converted to physical units.
None if FSC never exceeds the threshold.
Computes the Fourier Shell Correlation [1]_ between image1 and image2,
and estimate the resolution based on the threshold funcion T of 1 or 1/2 bit.
Parameters:
img1 (ndarray) – A 2-dimensional array containing the first image
img2 (ndarray) – A 2-dimensional array containing the second image
threshold (str, optional) – The option onebit means 1 bit threshold with SNRt=0.5, which
should be used for two independent measurements. The option halfbit
means 1/2 bit threshold with SNRt=0.2071, which should be
use for split tomogram. The default option is half-bit.
ring_thick (int, optional) – Thickness of the frequency rings. Normally the pixels get
assined to the closest integer pixel ring in Fourier Domain.
With ring_thick, each ring gets more pixels and more statistics.
The default value is 1.
apod_width (int, optional) – Width in pixel of the edges apodization. It applies a Hanning
window of the size of the data to the data before the Fourier
transform calculations to attenuate the border effects. The
default value is 20.
Returns:
FSC (ndarray) – Fourier Shell correlation curve
T (ndarray) – Threshold curve
Notes
If 3D images, the first axis is the number of slices, ie., [slices,rows,cols]
Evaluate the Nyquist frequency and the corresponding frequency array.
The Nyquist ring index is nmax//2 (integer division), where
nmax is the largest image dimension. For an even-length DFT of
size N the highest unambiguous positive-frequency bin is exactly N/2,
so integer division gives the correct result for both even and odd N.
Returns:
f (ndarray of int32) – Integer ring indices from 0 (DC) to fnyquist (inclusive).
fnyquist (int) – Ring index of the Nyquist frequency (nmax//2).
Compute the shell index for each voxel in Fourier space.
Each dimension’s frequency axis is built with scipy.fft.fftfreq
(which returns values in cycles/pixel, already in FFT layout) and
then scaled so that every dimension’s Nyquist maps to the global
Nyquist ring index nmax//2. This is equivalent to the
previous manual construction
ifftshift(np.arange(-fix(n/2),ceil(n/2)))*(nmax//2)/(n//2)
but requires no ifftshift, np.fix, or np.ceil calls.
Uses broadcasting instead of np.meshgrid to avoid large
temporary arrays.
Returns:
index – Array of the same shape as the input image containing the
integer shell index (rounded radius in scaled Fourier pixels)
for each voxel.
SSNR > 1 indicates signal-dominated shells; SSNR = 1 corresponds to the
resolution limit. This method calls fouriercorr() internally if
the FSC has not already been computed.
Returns:
f (ndarray) – Integer shell indices (same as nyquist()).
fnyquist (float) – Nyquist frequency (in pixels).
FSC (ndarray) – Fourier Shell Correlation curve.
SSNR (ndarray) – Spectral Signal-to-Noise Ratio as a function of spatial frequency.
Compute a tapered Hanning-like (Tukey) apodization window.
The 1-D window construction is delegated to _make_1d_tukey()
to avoid duplication. The 3-D window is assembled with broadcasting
instead of per-column list-comprehensions with swapaxes calls.
Returns:
window – For 2-D images: a single 2-D window array of shape (nr,nc).
For 3-D volumes: a list [outer(w_row,w_col),outer(w_sli,w_col)]
matching the original API expected by fouriercorr().
Local resolution estimation via block-wise FSC (3-D) or FRC (2-D).
Divides the volume into overlapping boxes, computes an independent
Fourier Shell/Ring Correlation within each box, and assembles a
spatial map of local resolution interpolated to the input shape.
Parameters:
vol1 (ndarray) – First independent half-reconstruction (2-D or 3-D).
vol2 (ndarray) – Second independent half-reconstruction, same shape as vol1.
box_size (int, optional) – Side length (in voxels) of the cubic (or square) analysis box.
Smaller boxes give finer spatial sampling but noisier estimates.
Default 32.
step (int or None, optional) – Step size in voxels between adjacent box centres.
Default box_size//2 (50 % overlap).
threshold (float, optional) – FSC/FRC threshold used to define the local resolution limit.
Default 0.143 (half-bit criterion).
Phase-randomization test for FSC validation (Chen et al., 2013).
After computing the standard FSC, the Fourier phases of both
half-volumes are independently randomized above a chosen spatial
frequency *f*_cutoff (the shell where FSC_obs first drops below
fsc_cutoff). The FSC computed from the two phase-randomized
volumes (FSC_rand) is the noise floor expected from model bias or
overfitting. A corrected FSC is then defined as:
If no overfitting is present, FSC_rand drops quickly to zero beyond
*f*_cutoff and FSC_corr ≈ FSC_obs. An elevated FSC_rand indicates
that the two half-maps share information beyond *f*_cutoff via a
common external model used during iterative reconstruction.
Parameters:
img1 (ndarray) – First half-reconstruction (2-D or 3-D).
img2 (ndarray) – Second half-reconstruction, same shape as img1.
threshold (str, optional) – 'halfbit' (default) or 'onebit'.
ring_thick (int, optional) – Ring thickness in pixels. Default 1.
apod_width (int, optional) – Apodization width in pixels. Default 20.
fsc_cutoff (float, optional) – FSC value that defines the phase-randomization cut-off frequency.
Phases are randomized at all shells where FSC_obs < fsc_cutoff.
Default 0.8.
random_seed (int or None, optional) – Seed for the random phase generator (for reproducibility).
Default None (non-reproducible).
The resolution limit is defined by a frequency-dependent SSNR
threshold curve obtained by applying the same transformation to the
half-bit (or one-bit) FSC threshold \(T(r)\):
This curve is not a horizontal line — it starts very high at low
spatial frequencies (few Fourier coefficients, large \(T\)) and
asymptotes to a fixed value at high frequencies:
half-bit threshold: asymptote \(\approx 0.414\)
one-bit threshold: asymptote \(= 1.0\)
Using a horizontal line at SSNR = 1 as the resolution criterion is
therefore only correct for the one-bit case (two fully independent
measurements). For a split dataset (threshold='halfbit'), the
correct criterion is the frequency-dependent \(\mathrm{SSNR}_T(r)\)
curve, whose asymptote is ≈ 0.414.
Parameters:
img1 (ndarray) – First half-dataset (2-D or 3-D array).
img2 (ndarray) – Second half-dataset, same shape as img1.
threshold (str, optional) – 'halfbit' (default) or 'onebit'.
ring_thick (int, optional) – Ring thickness in pixels. Default 1.
apod_width (int, optional) – Apodization width in pixels. Default 20.
Full-period resolution in physical units (van Heel / FSC convention):
pixel_size/fn_res_cpx. This is the spatial period of the
finest resolvable grating — the standard quantity reported in FSC
analyses. None if SSNR never exceeds the threshold.
Half-period resolution in physical units (Rayleigh / feature-size
convention): resolution_full/2. This equals the smallest
resolvable feature size and is the quantity most often reported in
optical microscopy. None if SSNR never exceeds the threshold.
Plot the SSNR curve with its frequency-dependent threshold and return
the underlying data.
The plot shows:
The SSNR curve (blue).
The frequency-dependent SSNR threshold \(\mathrm{SSNR}_T(r)\)
(red solid curve), derived by transforming the FSC threshold
\(T(r)\) through \(\mathrm{SSNR}_T = 2T/(1-T)\).
A dotted horizontal line at the asymptotic threshold value
(≈ 0.414 for half-bit, 1.0 for one-bit).
A vertical dashed line at the estimated resolution (last frequency
where SSNR>SSNR_T).
Returns:
fn (ndarray) – Spatial frequencies normalised by the Nyquist frequency.
fn_res_cpx (float or None) – Resolution crossing frequency in cycles/pixel
(last frequency where SSNR>SSNR_T).
Divide pixel_size by this value to obtain the resolution
in physical units. None if SSNR never exceeds the threshold.
Compute 2 tomograms from an already-split tomographic dataset.
The two reconstructions are independent, so they are run concurrently
using a ThreadPoolExecutor. Because tomo_recons ultimately calls
scipy.ndimage / iradon C extensions that release the GIL, two OS threads
can execute true parallel C code with negligible overhead.
If threading fails for any reason (e.g. the backend is not thread-safe),
the function transparently falls back to the original sequential path.
Parameters:
sinogram1 (ndarray) – A 2-dimensional array containing sinogram 1
sinogram2 (ndarray) – A 2-dimensional array containing sinogram 2
theta1 (ndarray) – A 1-dimensional array of thetas for sinogram1
theta2 (ndarray) – A 1-dimensional array of thetas for sinogram2
Returns:
recon1 (ndarray) – A 2-dimensional array containing the 1st reconstruction
recon2 (ndarray) – A 2-dimensional array containing the 2nd reconstruction
Implements the slanted-edge MTF algorithm (ISO 12233 / Burns 2000
variant). A sharp edge in the image is located, its orientation
measured, and an oversampled Edge Spread Function (ESF) is
constructed by projecting all pixel values onto the edge-normal
direction. The ESF is differentiated to give the Line Spread
Function (LSF), and the MTF is the modulus of the Fourier transform
of the LSF normalised to unity at zero frequency.
Point-source method (method='point'):
A small bright feature (bead, wire cross-section) is used as an
approximation to the system Point Spread Function (PSF). The MTF
is the modulus of the 2-D FFT of the PSF, radially averaged and
normalised.
Parameters:
image (ndarray) – A 2-dimensional image containing the edge or point source.
pixel_size (float, optional) – Physical size of one pixel. Default 1.0.
roi (tuple of slice or None, optional) – (row_slice,col_slice) defining the region of interest.
For 'edge': crop to this region before edge fitting.
For 'point': crop to this region before bead finding.
None uses the full image.
center (tuple of int or None, optional) – (row,col) coordinates of the point source centre. Only used
when method='point'. None finds the brightest pixel.
roi_size (int, optional) – Half-size (in pixels) of the extraction box around the point
source. Only used when method='point'. Default 16.
oversample (int, optional) – Oversampling factor for the ESF construction (edge method only).
Typically 4. Default 4.
Single-image resolution estimation via decorrelation analysis [1]_.
For each radial spatial frequency r the image is correlated with its
phase-normalised ring-filtered self. In the signal-dominated band the
phase is coherent and the correlation is high; beyond the resolution
limit the Fourier phases are noise-dominated and the correlation drops.
The highest spatial frequency at which the normalised correlation
exceeds threshold is taken as the resolution limit.
No second image or half-dataset is required — the estimate is obtained
from a single 2-D image (or from a set of 2-D slices sampled from a
3-D volume).
Parameters:
image (ndarray) – A 2-dimensional array (single image) or a 3-dimensional array
(tomographic volume). When a 3-D volume is supplied the algorithm
is applied slice-by-slice along axis and summary statistics are
reported.
pixel_size (float, optional) – Physical size of one pixel (in any consistent unit, e.g. nm).
Used to convert the resolution from pixels to physical units.
Default 1.0 (result in pixels).
n_r (int, optional) – Number of radial frequency bins between the lowest non-zero
frequency and the Nyquist limit (0.5 cycles/pixel).
Default 100.
threshold (float, optional) – Correlation threshold used to define the resolution limit.
The default 0.15 matches the FSC/FRC half-bit criterion.
apod_width (int, optional) – Width in pixels of the Hanning apodization applied to the image
edges before computing the FFT. Set to 0 to disable
apodization. Default 20.
axis (int, optional) – Axis along which slices are taken when image is 3-D.
Default 0 (first axis, i.e. slices are image[i,:,:]).
n_slices (int, optional) – Number of evenly-spaced slices to sample from the 3-D volume
(or from the sub-range defined by slice_range).
Ignored when image is 2-D. Default 10.
slice_range (tuple of int or None, optional) – (start,stop) slice indices along axis that define the
sub-range from which slices are sampled, following standard
Python / NumPy half-open convention (start inclusive,
stop exclusive). Negative indices are supported and are
resolved against the axis length before use. None (default)
samples the full extent of the volume.
For a 2-D input (or after 3-D analysis) the decorrelation
curve A(r) is shown together with the threshold line and the
resolution estimate marker.
For a 3-D input a histogram of the per-slice resolution
estimates is shown in addition to the A(r) curve of the last
processed slice, so that the spread across slices is visible.
Single-map local resolution estimation via a ResMap-inspired statistical test.
For each voxel and each spatial-frequency band the local signal energy
is compared with the noise floor via a z-score derived from the
chi-squared distribution. The local resolution is the finest spatial
frequency at which the test passes at significance level significance.
A single reconstruction is sufficient — no half-datasets are required.
Three noise estimation strategies are available (see noise_method),
making the estimator usable even for local tomography datasets where
the sample fills the entire field of view and the volume corners are not
empty.
Parameters:
vol (ndarray) – A 2-dimensional image or 3-dimensional reconstruction.
No half-maps are needed.
pixel_size (float, optional) – Physical size of one voxel (any consistent unit, e.g. nm).
Default 1.0 (result in pixels).
significance (float, optional) – Significance level α for the one-sided z-test. Smaller values
require stronger evidence of signal and yield more conservative
(coarser) local resolution estimates. Default 0.05.
n_freq (int, optional) – Number of frequency bands tested between the lowest resolvable
frequency and the Nyquist limit. Default 20.
window_sigma (float, optional) – Standard deviation (in voxels) of the Gaussian window used to
estimate the local signal energy. Larger values produce a
smoother but spatially lower-resolution map. Default 7.0.
mask (ndarray of bool or None, optional) – Binary mask identifying the sample region. Voxels outside
the mask are set to NaN in the output map. If None
(default) a mask is estimated automatically via Gaussian blurring
and thresholding.
Strategy used to estimate the noise standard deviation:
'corners'(default)
Noise is estimated from small cubic sub-volumes at the eight
(four for 2-D) corners of the reconstruction. Requires the
corners to be free of sample signal. Not suitable for local
tomography.
'highfreq'
Noise is estimated from the high-frequency tail of the power
spectrum (frequencies above 1-highfreq_fraction of the
Nyquist range). Works even when the sample fills the entire
field of view, because signal power typically falls well below
the noise floor near the Nyquist limit. Suitable for
local tomography and any dataset where empty corners are
unavailable.
'mask'
Noise is estimated from the voxels indicated by noise_mask.
The user must supply a boolean array marking known empty
(noise-only) regions anywhere in the volume.
noise_mask (ndarray of bool or None, optional) – Boolean array (same shape as vol) whose True entries mark
voxels that contain only noise (i.e. no sample signal).
Required when noise_method='mask'; ignored otherwise.
sigma_noise (float or None, optional) – Directly supply the noise standard deviation, bypassing all
automatic estimation. When provided, noise_method,
noise_mask, and corner_fraction are all ignored.
corner_fraction (float, optional) – Fraction of each edge length used to define the corner noise
regions. Must be in (0,0.5). Only used when
noise_method='corners'. Default 0.10.
highfreq_fraction (float, optional) – Fraction of the frequency range (counting down from Nyquist) used
to estimate noise power. Only used when
noise_method='highfreq'. Default 0.10 (top 10 %, i.e.
frequencies from 0.45 to 0.50 cycles/pixel).
The implementation follows the methodology of ResMap [1]_ but uses a
Gaussian bandpass filter and a z-score threshold in place of the
original steerable-filter chi-squared test. For most practical
purposes the results are equivalent. The key advantage over the
block-wise LocalFSC approach is that only a single
reconstruction is required.
For local (region-of-interest) tomography, use
noise_method='highfreq' or supply sigma_noise directly:
# Local tomography — corners are not emptylr=LocalResolution(vol,pixel_size=28.6e-9,noise_method='highfreq')# Or if you already know sigma_noise from the sinogramlr=LocalResolution(vol,pixel_size=28.6e-9,sigma_noise=0.003)