Expand description
QSMGAN dipole inversion (onnx feature).
QSMGAN (Chen 2020) inverts the dipole with a 3D U-Net generator refined by a
Wasserstein GAN. Inference is patch-based with an increased receptive field: a
64³ local-field patch maps to a 48³ susceptibility patch (a centre crop baked
into the exported graph — the “i64o48” scheme). The network itself is the only
part in ONNX; this glue reproduces the authors’ recon.py pipeline:
- sign flip — the QSM-CI runner negates the local field before the net;
- tile by non-overlapping 48³ output patches, each fed a 64³ input patch (same centre, 8-voxel context margin, zero-padded at the volume edges);
input_scale = 100; output headtanh, soχ = atanh(clip(out)) / 10;- mask the result.
The input is the SEPIA-style local field in ppm (already background-removed).
Weights are not bundled; the caller passes the exported qsmgan.onnx bytes.
§Reference pipeline
From Chen et al., NeuroImage 2020 (doi:10.1016/j.neuroimage.2019.116389), Methods, and the
authors’ code (mmorri10/QSMGAN-LupoLab code_pytorch_v3.zip):
- Training data: 7T GE, 4-echo GRE (TE 6/9.5/13/16.5 ms), 0.8 mm isotropic; COSMOS labels
(checkpoint
WGAN_i64o48/config.json:data_path: 7T_cosmos,input_algo: vsharp). - Phase processing: Laplacian unwrapping, FSL BET mask from magnitude, V-SHARP.
- Resampling: patient data acquired at 0.8×0.8×1 mm were resampled to 0.8 mm isotropic
(paper); the authors’
utils/data.py:201,221(QsmPatchDataHD) zooms those scans to 0.8 mm isotropic before the net andpredict.py:112zooms the result back. This crate does not resample. - Input unit: the README feeds SEPIA’s local field; the paper and code scale it by 100 without stating its unit. This crate passes ppm (as the QSM-CI runner does).
§Agreement with the original
tests/models_onnx/dipole.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, QSMGAN 521d202 (qsmgan)
(QSMxT/QSM-CI#316; the fixture is regenerated in Actions by
tests/data/dl_dipole_qsmci_small.py): NRMSE 1.7e-4 %, max |Δ| 8.4e-8 ppm (measured
2026-10-30): float32 rounding.
§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): qsmgan.mask-bet, qsmgan.unwrap-laplacian, qsmgan.bg-vsharp.
Constants§
- INPUT_
SCALE 🔒 - IPS 🔒
- OPS 🔒
- OUTPUT_
SCALE 🔒
Functions§
- qsmgan
- Run QSMGAN on a background-removed local field (ppm), column-major
(nx,ny,nz). Returns susceptibility (ppm), masked, in the same layout.