Expand description
TFI (preconditioned Total Field Inversion)
Single-step QSM: inverts the total field, before background removal, over the whole field of
view. Background sources outside the mask are part of the solution, made cheap to reach by a
preconditioner P, and the susceptibility is χ = P·y:
min_y ||wG ∇(P y)||₁ + 2λ ||m (D P y − f)||²₂
§What follows which source
Cornell’s own TFI script (TFI_L1.m) is not public. The 2024.11.26 MEDI toolbox has the TFI
solver inside MEDI_L1.m: when RDF.mat holds a preconditioner P (parse_QSM_input.m),
MEDI_L1 solves for y with χ = P·y. This port follows that code line for line:
- 2024
MEDI_L1.mand its helpers (fgrad.m,bdiv.m,gradient_mask.m,dataterm_mask.m,cgsolve.m,dipole_kernel.m): the'linear'data term (and the toolbox’s default exponential one, as an option), the data weightmfromN_std, the edge maskwGand thenwG.*Mask(no regularisation outside the mask), the lagged-diffusivity weight1/sqrt(|wG ∇(P y)|² + 1e-6·P²)(epsilon scaled byP²), the operatorPH(reg(P dx)) + 2λ·PH(Dconv(|w|² Dconv(P dx))), the right-hand side, the Gauss-Newton stop||dy||/||y||, MERIT, the outputP yin ppm masked byMask, and the defaults ofparse_QSM_input.m(λ = 1000, MERIT on, 10 Gauss-Newton and 100 CG iterations, tolerances 0.1 and 0.01,percentage0.9). - Liu et al. 2017, for what the toolbox does not settle for TFI:
P = 1inside the mask andP_B = 30outside (eq. 3; 30 is the paper’s in-vivo value); the input is the total field over the whole field of view, so there is no SMV step (an SMV high-pass would remove the background TFI is meant to fit); and the data term is the linear one of eq. 5, which isMEDI_L1’s'linear'option rather than its exponential default. (With the exponential term,MEDI_L1itself fails on in-vivo total fields in radians: the field wraps insideexp(i·). Setlinear: falseto run the toolbox default.)
Not ported: the R2*-based preconditioner (eq. 4), zero padding and the CSF zero reference.
§Parity
Against TFI as the verified QSM-CI tfi-cornell container runs it (MEDI 2024.11.26 MEDI_L1.m
with a preconditioner, identical to licensed MATLAB R2023b), astewartau/QSM.rs#407. Two
departures are deliberate, each with the original’s behaviour as an option:
- Dipole kernel on odd grids (
TfiKernel).dipole_kernel.mbuilds its k grid as-N/2:N/2-1, half a frequency step off the DFT grid on an odd axis, so it is not the dipole kernel there. On QSM-CI’s simulated head (164×205×205) that alone made the port’s χ 0.77× the original’s (42 % NRMSE); withTfiKernel::MediOddGrid2.5 %. The DFT-grid kernel fits the true χ better (demeaned, in the mask: NRMSE 62.1 % against 71.4 %, r 0.785 against 0.718), so it stays the default. On even grids the two are the same. - Precision (
TfiPrecision).MEDI_L1.mruns in single precision (tempn = single(N_std)makes the data weight single, and MATLAB’s mixed arithmetic carries that into everything). On the fixture’s small odd phantom (tests/tfi_cornell_parity.rs) the port with both options is 2.9e-6 relative after one Gauss-Newton step and 4.7e-4 with all defaults; in double precision 4.7e-3. The container itself differs by 3.0e-4 there on another CPU.
Beyond that the original is not reproducible at full size: its 100-iteration CG solves at
cg_tol 0.01 in single precision amplify rounding. In the same container, 1e-7 relative noise
on the simulated head’s total field moves its χ by 1.6 % NRMSE, and the container on another
CPU (QSM-CI’s runner against this VM) differs from itself by 2.8 % on the KKI travelling head.
On the reference’s own inputs the port with both options is 3.6 % (sim) and 1.26 % (KKI) from
it; with the DFT-grid kernel in double precision, 42 % and 1.25 %.
§Reference pipeline
From Liu et al. 2017 (Methods, in-vivo experiments); not stated above:
- Brain mask (the
MwhereP = 1): BET. Field map: nonlinear (complex) field estimation followed by graph-cut phase unwrapping. No background removal or high-pass before TFI. - In vivo the paper uses the R2*-based preconditioner of eq. 4,
P = 1inM ∩ {R2* < 30 s⁻¹}andP_Belsewhere, withP_B= 30 (10 for the phantom). Only eq. 3 is ported here. - Data: 3 T, 6 echoes, TE₁ 3.5 ms, ΔTE 3.6 ms, 1×1×3 mm³, monopolar readout.
- The paper’s solver settings differ from
MEDI_L1’s defaults, which this port uses: λ = 1e-3 on the L1 term (not the data term), Gauss-Newton stop||dy||/||y|| < 0.01, up to 300 CG iterations. CSF is the reference for reported values.
§Units
Like the other inversions, tfi takes the field in ppm and returns ppm. MEDI_L1 works on the
field in radians accumulated over the echo spacing (delta_TE) at CF = γ·B0; the field is
converted with 2π·CF·delta_TE·1e-6 first and back at the end, as MEDI_L1.m does. The
result depends on this scale, so b0 and echo_times are scan parameters
that the pipeline fills from metadata, and TfiParams::te picks the echo time the
conversion uses (by default the reference’s choice; see there).
§Magnitude and data weight
As for medi, the echo magnitudes (EchoMagnitudes) are required: the edge
mask uses their root sum of squares (iMag = sqrt(sum(abs(iField).^2,4))) and the data weight
m = Mask./N_std (mean 1 in the mask) uses Fit_ppm_complex.m’s noise map
(fit_ppm_complex_noise), as MEDI’s pipeline makes
them, so TFI always weights the data as the reference does.
Reference: Liu, Z., Kee, Y., Zhou, D., Wang, Y., Spincemaille, P. (2017). “Preconditioned total field inversion (TFI) method for quantitative susceptibility mapping.” Magnetic Resonance in Medicine, 78(1):303-315. https://doi.org/10.1002/mrm.26331
Reference implementation: MEDI toolbox 2024.11.26 (Weill Cornell), functions/MEDI_L1.m.
§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): tfi.mask-bet, tfi.te-spacing.
Structs§
- TfiParams
- TFI parameters (2024
MEDI_L1.m/parse_QSM_input.mdefaults;P_Band the linear data term from Liu et al. 2017)
Enums§
- TfiKernel
- Which dipole kernel
tfiuses: they differ only on grids with an odd number of voxels along some axis. - TfiPrecision
- Arithmetic of
tfi’s Gauss-Newton iterations.
Functions§
- tfi
- Preconditioned total field inversion (2024
MEDI_L1.mwith a preconditioner) - tfi_l1 🔒
MEDI_L1.mwith the preconditioner, on aniMagand anN_std- tfi_
single 🔒 tfi_l1in MATLAB’s single precision (TfiPrecision::Single):MEDI_L1.mline for line with MATLAB’s types.tempn = single(N_std)makes the data weightm, and with it the datab0 = m.*RDF, single; from there every product with a single operand is single, so the operator, the right-hand side,cgsolve.m’s vectors and scalars,dxand the iteratex(x + dx) are single. Double operands (P, the edge mask,ε, the kernel, and after MERIT the data weight and data, whichdataterm_maskremakes fromdouble(N_std)) are rounded to single where they meet a single one. FFTs are single precision.