Expand description
Scan geometry from the NIfTI affine: B0 direction, obliquity, and resampling to an axial grid.
The dipole kernel lives in the voxel grid, so an oblique acquisition must either supply the
true B0 direction or be resampled to a cardinal-aligned grid. Wrapped phase has to be
resampled in the complex domain — see geometry::resample_complex_to_axial.
Scan geometry derived from the NIfTI affine, and resampling to an axial grid.
Two things QSM needs from the affine and nothing else provides:
- Which way B0 points in voxel space. The dipole kernel is built in the voxel grid, so an
oblique acquisition must either be told the true B0 direction ([
b0_direction_from_affine]) or be resampled so that the grid is cardinal-aligned and B0 is(0, 0, 1)by construction ([resample_complex_to_axial]). Getting this wrong rotates the kernel and suppresses susceptibility contrast in exactly the iron-rich structures QSM is usually measuring. - How oblique the acquisition is ([
obliquity_from_affine]), so a pipeline can decide whether resampling is worth the interpolation.
§Phase must be resampled in the complex domain
Wrapped phase cannot be interpolated directly: halfway between +3.0 and -3.0 rad, a linear
interpolator returns 0.0, when the correct answer is near ±π. Every wrap in the volume
becomes a band of wrong values. [resample_complex_to_axial] takes magnitude and phase
together, interpolates mag·e^{iφ} as real and imaginary parts, and recovers magnitude and
phase afterwards, which is well defined across wraps. Use [resample_to_axial] only for
quantities that are already continuous (magnitude, an unwrapped field map, χ).
§The same result on every target
The complex resamplers give the same bits natively and in WebAssembly. Their sines, cosines,
atan2 and hypot come from [crate::utils::portable_math] rather than the platform’s maths
library, which differs between targets in the last bit; the rest is IEEE arithmetic in a
fixed order. That matters beyond the last bit: the empty-corner fill in
[resample_complex_to_axial] is seeded from a hash of the whole phase volume, and phase-based
masking thresholds what comes out, so one differing ulp anywhere used to give the browser a
different mask from qsmxt run. Where the interpolated value is exactly zero (outside the
source, or where the source magnitude is zero) there is no phase to recover, and the phase is
defined as 0 rather than whatever atan2 makes of the signs of the zeros.
Structs§
- Axial
Grid - The cardinal-aligned grid an oblique volume resamples onto, plus the mapping back to the
original voxel space. Build once with
axial_grid_forand reuse for every volume that shares the geometry (magnitude, phase, mask), so they land on identical grids. - Axial
Resample Params - Options for
resample_complex_to_axial. - GridMap
- Mapping from one voxel grid to another, each described by its own affine.
- Resampled
Complex - Magnitude and phase resampled together onto a cardinal-aligned grid.
- Resampled
Volume - A volume resampled onto a cardinal-aligned grid.
- Split
Mix64 🔒 - SplitMix64 — small, dependency-free, and adequate for filling empty corners with noise.
Enums§
- Axis
Code - The anatomical direction an array axis runs toward.
Constants§
- QSMX
T8_ NOISE_ FILL_ FRACTION - The zero fraction above which QSMxT 8.x filled resampled phase with noise, for a caller that
opts in to that behaviour through
AxialResampleParams::noise_fill_fraction.
Functions§
- alignment_
is_ identity - Whether a
(perm, flip)pair leaves a volume untouched. - alignment_
to - The axis permutation and per-axis flips that take a volume into
targetorientation. - axial_
grid_ for - Build the axial grid covering the same world-space extent as an oblique volume, keeping its
voxel sizes. The new affine is diagonal, so
b0_direction_from_affineon it returns(0, 0, 1). - b0_
angle_ from_ affine - Angle (degrees) between B0 and the voxel
+zaxis — the tilt that matters for the dipole kernel. Zero for an axial acquisition; equals the scanner’s slice tilt for a simple oblique. - b0_
direction_ from_ affine - Direction of the scanner’s B0 field (world
+z) expressed in voxel coordinates, normalised. - from_
complex 🔒 - Magnitude and phase of interpolated real and imaginary parts, the same on every target (see
the module docs). Phase is 0 where both parts are zero: there is no signal there, and
atan2would otherwise return 0 or ±π depending on the signs of the zeros. - invert_
3x3 🔒 - invert_
alignment - The
(perm, flip)that undoesalignment_to— pass it toreorientto get back. - majority_
label 🔒 - The label with the largest total trilinear weight among the (up to) eight source voxels around a fractional coordinate: the argmax of each label’s indicator, linearly interpolated. A tie goes to the nearest voxel’s label, then to the first found.
- obliquity_
axes_ from_ affine - Per-axis obliquity (degrees), matching
nibabel.affines.obliquity: for each voxel axis, the angle between it and the closest world axis.[0, 0, 0]for a cardinal-aligned acquisition. - obliquity_
from_ affine - Scalar obliquity (degrees): the Euclidean norm of
obliquity_axes_from_affine. - ras_
axes - Which volume axis each of R, A, S runs along — lab2im’s
get_ras_axes. - reorient
- Permute and flip a column-major volume. Returns the volume and its new dimensions.
- resample_
complex_ onto - Resample magnitude and wrapped phase from one grid onto another, through the complex domain
so the wraps survive. Returns
(magnitude, phase). - resample_
complex_ to_ axial - Resample magnitude and wrapped phase to a cardinal-aligned grid, interpolating in the complex domain so wraps survive.
- resample_
labels_ onto - Resample a label image (a segmentation, a parcellation) from one grid onto another.
- resample_
mask_ onto - Resample a binary mask from one grid onto another (nearest neighbour). For a label image,
use
resample_labels_onto. - resample_
mask_ to_ axial - Resample a binary mask to a cardinal-aligned grid with nearest-neighbour interpolation.
- resample_
onto - Resample continuous data (magnitude, an unwrapped field, χ) from one grid onto another.
Returns
Noneif the source affine is singular. - resample_
to_ axial - Resample a continuous volume (magnitude, unwrapped field, χ) to a cardinal-aligned grid.
- seed_
from_ 🔒slice - Deterministic seed from volume contents (FNV-1a over the bit patterns).
- to_
complex 🔒 mag·cos φandmag·sin φ, the same on every target (see the module docs).- trilinear_
sample 🔒 - Trilinear interpolation at a fractional voxel coordinate, clamped at the edges.
- voxel_
sizes_ from_ affine - Voxel sizes (mm) from a row-major 4×4 affine: the norms of its three columns.
- world_
to_ 🔒voxel - Invert the 3×3 of an affine and fold in its translation, giving world→voxel as a 3×4.