Skip to main content

Module iqsm_plus

Module iqsm_plus 

Source
Expand description

iQSM+ single-step deep-learning reconstruction (onnx feature).

iQSM+ (Gao 2024) extends iQSM with orientation-adaptive latent feature editing (OA-LFE): the B0 direction (z_prjs) is a network input, so oblique/sagittal/coronal acquisitions reconstruct correctly. The exported graph takes six inputs: phase, mask, te (s), b0 (T), z_prjs (B0 dir, [1,1,3]), and border (the LoT boundary mask, as for iQSM).

Pipeline (mirrors the authors’ inference.run_iqsm_plus): flip the phase sign, erode the mask by a radius-3 sphere, crop to the brain bounding box + 16-voxel margin, centre-pad to a multiple of 16, run, ×mask, then paste the result back into the full grid. Multi-echo data is combined with (magnitude·TE)² weighting.

Only axial-ish acquisitions are handled directly here; the authors’ extra axis-permutation for strongly oblique fields (|dir_y| > |dir_z|) is not applied.

Weights are not bundled; the caller passes the exported iqsm-plus.onnx bytes.

§Reference pipeline

As for iQSM (normalisation, bet2 -f 0.5 default mask), with two differences in the authors’ sunhongfu/iQSM_Plus code:

  • Resampling: inference.py:443-471 (and legacy/matlab/iQSM_plus.m:175-210) interpolates anisotropic phase to an isotropic grid at the finest voxel size in the complex domain whenever the rounded grid would change. This crate does not resample.
  • Phase masking: inference.py:425 and legacy/matlab/fcns/Save_Input_iQSMplus.m multiply the phase by the unmodified mask before erosion. This crate does not; with an erosion radius of at least 1 that cannot change the result, since the 3×3×3 LoT stencil only reaches voxels inside the unmodified mask wherever its output survives the eroded mask.

§Agreement with the original

tests/models_onnx/field.rs runs it on a 36×32×28 box of in-vivo data (1 mm, 2.89 T, across the brain’s edge) against its original’s verified QSM-CI entry, iQSM+ a534d94 (iqsm-plus) (QSMxT/QSM-CI#316; the fixture is regenerated in Actions by tests/data/dl_field_qsmci_small.py): per echo, NRMSE 2.7e-4 to 3.3e-4 %, max |Δ| up to 6.8e-7 ppm: float32 rounding.

The original runs one echo at a time and combines the echoes afterwards with weights (mag·TE)², in both of the authors’ implementations (see iqsm_plus_multi_echo), and so does this crate. On the box’s first and third echoes the driver’s combination is (mag·TE)² of its per-echo outputs to 1.6e-3 %, and mag·TE² weighting (iQSM’s MATLAB echo fit, which this crate used for iQSM+ until 2026-10-31) differs from it by 3.1 % NRMSE (measured 2026-10-30); iqsm_plus_multi_echo matches the (mag·TE)² combination of the original’s per-echo outputs to 2.5e-4 % (measured 2026-10-31).

§Pipeline rules

The facts above that a configuration can depart from are published as rules in crate::pipeline::rules::RULES (each with its strength, basis, reason and source): iqsm.mask-bet.

Functions§

iqsm_plus
Run iQSM+ on a single echo of wrapped phase.
iqsm_plus_multi_echo
Multi-echo iQSM+: reconstruct each echo and combine them with weights (magnitude·TE)², i.e. IqsmEchoWeighting::MagnitudeSquaredTeSquared; without magnitudes, TE² alone.
iqsm_plus_with 🔒
One pass of the network. With crop, on the eroded mask’s bounding box plus 16 voxels, centre-padded to a multiple of 16; without, on the whole input, which must already be one.