Skip to main content

Module qsmgan

Module qsmgan 

Source
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 head tanh, 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 and predict.py:112 zooms 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.