Skip to content

Standalone tools

Beyond the end-to-end pipeline, QSMxT exposes each building block as a standalone command that reads and writes NIfTI files. These are handy for experimentation, teaching, scripting, or slotting a single step into another workflow.

Every command takes NIfTI input and produces NIfTI output. Run qsmxt <command> --help (and qsmxt <command> <subcommand> --help) for exact arguments.

Generate or refine binary masks.

Subcommand Operation
otsu Otsu automatic thresholding
value Fixed-value thresholding
percentile Percentile thresholding
sti-gui STI Suite QSM_GUI’s thresholding: the level its thresh_tool starts at (Otsu’s threshold of the middle slice, scaled to that slice’s maximum)
bet Brain extraction (BET); --orientation as-stored runs it on the voxels as stored, as MEDI’s BET.m does
hd-bet Deep-learning brain extraction (HD-BET); whole volume by default; --window, --low-memory or --patch XxYxZ for sliding-window patches, --tta. Weights are downloaded on first use
rs2-net Deep-learning rodent brain extraction (RS2-Net); --tta, --tile-step. Weights are downloaded on first use
mindgrab Deep-learning brain extraction for any contrast (MindGrab); --tta. Needs the image’s NIfTI affine. Weights are downloaded on first use
preset Run a --mask-preset recipe on an image: robust-threshold, bet, hd-bet, bet-and-phase, rs2-net, mindgrab
robust Alias for preset robust-threshold
erode / dilate Morphological erosion / dilation
close Morphological closing
majority 3×3×3 majority filter (MATLAB’s bwmorph3 'majority')
largest-component Keep only the largest 26-connected component (MATLAB’s bwlabeln)
imfill Fill every hole, whatever its size (MATLAB’s imfill 'holes')
fill-holes Fill holes in a binary mask (--max-size 0, the default, is automatic: 5% of the volume)
smooth Gaussian smooth (re-thresholded at 0.5)
and / or Intersect / union two or more masks on the same grid

Every subcommand is the first link of a chain: it does its own operation, then applies any --op refinements in order — erode:2, fill-holes:0, close:1, gaussian:4.0, majority, min-intensity:100, signal-erode, the same spellings as a --mask section. So qsmxt mask erode m.nii -o out.nii --op fill-holes erodes, then fills. What each op does is defined once, in the same code the pipeline runs, so a mask built here matches the one a --mask section would produce.

and and or are the standalone form of the pipeline’s --mask-combine, for trying combinations on masks you already have without a pipeline run. Their --op refinements run on the combined mask, like --mask-refine does. The consensus recipe by hand, step by step:

Terminal window
qsmxt quality-map phase_e1.nii -o quality.nii --magnitude mag_e1.nii
qsmxt mask bet mag_e1.nii -o bet.nii
qsmxt mask otsu quality.nii -o phase.nii
qsmxt mask and bet.nii phase.nii -o brain.nii --op fill-holes:0 --op erode:1

— or in one go, since it is a preset:

Terminal window
qsmxt mask preset bet-and-phase mag_e1.nii --quality quality.nii -o brain.nii

The subcommands that make a mask from an image (otsu to robust) take a 3D image, or a 4D multi-echo magnitude, whose echoes they combine by root-sum-of-squares first, as qsmxt run does for a magnitude mask section. The subcommands that take masks refuse a 4D file.

preset reads its input image for every section; sections that read phase quality use --quality when given, and the input image otherwise, as run --masking-input would; --bet-orientation sets its BET steps’ orientation. --op signal-erode needs a magnitude image, and --op min-intensity the image whose intensity it reads: for and/or, whose inputs are masks, pass it as --magnitude.

Combine uncombined receive-coil channels into one phase and magnitude per echo with MCPC-3D-S (mcpc3ds). Inputs are the per-coil, per-echo 3D NIfTIs; files named with BIDS coil-NN / echo-N entities are ordered by those, otherwise pass them coil-major with --num-echoes. Echo times come from --tes or the phase sidecars.

Terminal window
qsmxt combine mcpc3ds \
--phase sub-1/anat/*rec-uncombined*part-phase_MEGRE.nii.gz \
--magnitude sub-1/anat/*rec-uncombined*part-mag_MEGRE.nii.gz \
-o combined/sub-1_rec-uncombined
# writes combined/sub-1_rec-mcpc3ds_echo-N_part-{phase,mag}_MEGRE.nii and
# combined/sub-1_rec-uncombined_desc-mcpc3ds_mask.nii — the pipeline's names

Unwrap a wrapped phase image (romeo, laplacian, prelude or medi-region-growing; prelude takes --prelude-labelling and --prelude-partitions, and medi-region-growing takes a --magnitude and no mask).

Turn multi-echo wrapped phase into one B0 field map in ppm, as the pipeline’s field-mapping stage does: romeo (phase-offset removal, ROMEO unwrapping and the B0 fit), laplacian (per-echo Laplacian unwrapping, then echo combination), prelude (phase-offset removal, per-echo PRELUDE unwrapping and the B0 fit) or medi-region-growing (the same with MEDI’s region growing; needs --magnitude). qsmxt fieldmap medi-region-growing --b0-estimation complex-fit is MEDI’s field map.

With --b0-estimation complex-fit (MEDI’s fit of the complex echoes, which needs --magnitude and evenly spaced echoes), --complex-fit-output also saves the fit before spatial unwrapping, the phase accrued per echo spacing (radians, wrapped), and --complex-fit-noise-output its noise map, the standard deviation of that phase (radians per echo spacing). MEDI calls these iFreq_raw and N_std.

Background field removal — qsmxt bgremove

Section titled “Background field removal — qsmxt bgremove”

Remove background fields from an unwrapped total field map in ppm:

Subcommand Method
vsharp Variable-radius SHARP
pdf Projection onto Dipole Fields
lbv Laplacian Boundary Value
ismv Iterative Spherical Mean Value
sharp SHARP
resharp Regularised SHARP
harperella HARPERELLA, joint unwrapping and background removal
iharperella Improved HARPERELLA
bfrnet BFRnet deep-learning background removal (weights downloaded on first use)
iqfm iQFM deep-learning joint unwrapping and background removal, from wrapped phase (weights downloaded on first use)

qsmxt bgremove iqfm reads every echo’s wrapped phase (one 4D file) instead of a field, with --echo-times, --field-strength and, to weight the echoes, the magnitude (--magnitude, 4D), and writes the local field in ppm.

qsmxt bgremove harperella and iharperella read one wrapped echo in rad when given --te and --field-strength, or an unwrapped total field in ppm without them (which iHARPERELLA takes as it is), and write the local field in ppm.

qsmxt bgremove pdf takes every echo’s magnitude (--magnitude, one 4D file or one file per echo), --echo-times and --field-strength: PDF weights its fit by a noise map made from them.

qsmxt bgremove vsharp takes --deconvolve <true|false> (default false, as qsmxt run), --threshold (used only with deconvolution), --max-radius/--min-radius/--radius-step in mm, and --grid <isotropic|native|finest> with --grid-spacing in mm (the working grid, as qsmxt run’s --vsharp-grid).

qsmxt bgremove sharp --variant qsmjl runs QSM.jl’s SHARP (at QSM.jl’s defaults, 18 × the smallest voxel dimension and 0.05, unless --radius/--threshold say otherwise), and qsmxt bgremove vsharp --ball qsmjl QSM.jl’s SMV ball, for comparison with that implementation; qsmxt run always runs the defaults.

Invert a field map into a susceptibility map. One subcommand per method; most take the local field, and tfi, autoqsm and nextqsm the total field:

Subcommand Method
rts Rapid Two-Step
tv Total Variation (ADMM)
tkd Truncated K-space Division
tsvd Truncated SVD
tgv Total Generalized Variation
tikhonov Tikhonov regularization
nltv Nonlinear Total Variation
medi Morphology-Enabled Dipole Inversion
tfi Total Field Inversion (total field in)
ilsqr Iterative Least-Squares QR
star STAR-QSM — Streaking Artifact Reduction
lsqr Minimally regularised LSQR
heidi LSQR+HEIDI — Homogeneity Enabled Incremental Dipole Inversion; with --seed, HEIDI on another inversion’s map
ndi Nonlinear Dipole Inversion
fansi / fansi-tgv FANSI nonlinear TV / TGV
l1qsm L1 data-fidelity QSM
whqsm Weak-harmonic QSM
hdqsm Hybrid data-fidelity QSM
amp-pe Approximate Message Passing with Parameter Estimation
xqsm, qsmnet, qsmnet-plus, qsmnetme, qsmgan, ir2qsm, lpcnn, modl-qsm Deep-learning dipole inversions (weights downloaded on first use)
autoqsm, nextqsm Deep-learning single-step reconstructions from the total field
iqsm, iqsm-plus Deep-learning single-step reconstructions from wrapped phase (iQSM, and the orientation-adaptive iQSM+)
cosmos COSMOS — multi-orientation least squares (2+ orientations)
sti Susceptibility tensor imaging (6+ orientations)

QSMART is its own command, qsmxt qsmart, since it takes the total field and runs its own two-stage reconstruction. To prepare its inputs as QSMART’s authors do, map the field with qsmxt fieldmap laplacian --laplacian-solver mirror --laplacian-unmasked --b0-estimation qsmart-echofit --reliability-output r0.nii, then pass --reliability r0.nii and every echo’s magnitude (4D) as --magnitude. --intermediates DIR also writes QSMART’s own maps into DIR as <name>.nii: vessel_mask (1 = vessel), localfield_stage1, chimap_stage1, localfield_stage2, chimap_stage2, and vessel_magnitude when QSMART makes its own from the echoes. --qsmart-offset-grid qsmart-reference combines the two stages on the k-space grid of the authors’ code instead of the FFT grid; the two differ only when a matrix dimension is odd, and the option is there for comparing with their code. --ilsqr-precision single runs the inner iLSQR’s two LSQR solves in single precision, as STI Suite’s QSM_iLSQR, which QSMART calls, does (--pipeline qsmart does the same). iqsm and iqsm-plus read every echo’s wrapped phase (one 4D file) instead of a field, with --echo-times, --field-strength, --b0-direction (an input of iQSM+’s network) and, to weight the echoes, the magnitude (--magnitude, 4D).

Each subcommand runs its method as qsmxt run does, through QSM.rs’s pipeline: the field goes in in ppm, and the methods that work in radians (ndi, nltv, fansi, fansi-tgv, l1qsm, whqsm, medi, tfi, heidi, tgv, star) convert it themselves with --field-strength and --echo-times (every echo’s). ndi, nltv, fansi, fansi-tgv, l1qsm, lsqr and heidi (without --seed) need --magnitude as their data weight; medi and tfi need the magnitude of every echo (one 4D file or one file per echo). MEDI-mSMV is qsmxt invert medi --msmv.

qsmxt invert heidi is LSQR+HEIDI, HEIDI as published. qsmxt invert heidi --seed chi.nii instead runs HEIDI on a map another inversion made of the same field, as qsmxt run --heidi does after it (HEIDI streaking reduction says which inversions suit it); --lsqr-* and --magnitude then do nothing.

qsmxt invert tgv --reference-divergence --reference-edge-erosion --reference-output-box reproduces QuantitativeSusceptibilityMappingTGV.jl’s divergence, mask erosion and output box, for comparison with that package; qsmxt run always uses the exact adjoint, erodes from the array’s edge too, and returns χ inside the eroded mask only.

Terminal window
# e.g. inspect the parameters of a method
qsmxt invert tgv --help

cosmos and sti take several --input field maps plus one --b0-direction per orientation, and expect them already co-registered onto a common grid. See multi-orientation.

Split a susceptibility map into paramagnetic and diamagnetic sources, writing <prefix>_desc-paramagnetic_Chimap.nii, _desc-diamagnetic_Chimap.nii and _desc-total_Chimap.nii (the pipeline’s names):

Subcommand Method and inputs
r2star-qsm R2*-QSM closed form — QSM + R2*
decompose DECOMPOSE-QSM — a QSM per echo (--qsm-per-echo) + multi-echo magnitude. qsmxt run --qsm-per-echo true gives it each echo’s map; without it, its one QSM at every echo
chi-sep-ilsqr χ-separation, iLSQR — local field + R2′ + QSM (qsmxt run reconstructs this QSM from the local field by iLSQR; here it is the one given)
chi-sep-medi χ-separation, MEDI — local field + R2′ + multi-echo magnitude (--magnitude, --echo-times) + QSM
wavesep WaveSep — QSM + R2′
hc-chisep Hollow-cylinder χ-separation — QSM + R2′ + multi-echo magnitude
susep-net SUSEP-Net (deep learning) — QSM + R2′ + local field
chi-sepnet χ-sepnet (deep learning) — local field + R2′ or R2* (the authors’ route; --route native takes a QSM too)
Command Output
swi Susceptibility-weighted image (CLEAR-SWI) from one or more echoes (--phase, --magnitude, --tes), and with --mip its minimum-intensity projection (named like the pipeline’s: sub-01_swi.nii → sub-01_minIP.nii, unless --mip-output is given)
r2star R2* map from multi-echo magnitude
t2star T2* map from multi-echo magnitude
r2 R2 map from multi-echo spin-echo (MESE) magnitude (EPG fit)
r2prime R2’ map from an R2* and an R2 map, over the region R2 covers; or, with --r2primenet, estimated from the R2* map alone by R2PRIMEnet
segment SynthSeg whole-brain segmentation of a magnitude image (_dseg.nii and its .tsv lookup)
quality-map ROMEO phase-quality map

r2prime computes R2' = R2* - R2 only where R2 was actually measured, because a multi-echo spin-echo acquisition is often a slab and R2' = R2* - 0 = R2* outside it would put the whole of R2* forward as reversible. Coverage is inferred from R2 > 0, which is exact for an R2 fitted on the same grid; for an R2 map resampled from another one, interpolation leaves plausible-looking non-zero values just past its field of view, so say where it reached:

Terminal window
qsmxt r2prime --r2star r2star.nii --r2 r2.nii -m mask.nii -o r2prime.nii \
--r2-coverage mese_fov.nii --output-coverage r2prime_coverage.nii

Without an R2 map, --r2primenet estimates R2’ from R2* with R2PRIMEnet, as qsmxt run --r2prime-strategy r2primenet does. It needs --field-strength: the network is trained at 3 T and refuses another field strength unless --r2primenet-ignore-field-mismatch is given. An estimate is not a measurement.

Terminal window
qsmxt r2prime --r2star r2star.nii --r2primenet --field-strength 3 -m mask.nii -o r2prime.nii
Command Purpose
homogeneity Correct intensity inhomogeneity on magnitude data, with makehomogeneous (default) or N4 (--method n4; --n4-geometry make-nii gives N4 the axis-aligned header MATLAB’s make_nii writes, as QSMART does)
resample Resample an oblique volume to axial orientation. Continuous data (magnitude, an unwrapped field, χ) as a positional argument; wrapped phase needs --phase with --magnitude so the interpolation goes through the complex domain
Terminal window
# continuous data
qsmxt resample mag.nii -o mag_axial.nii
# wrapped phase, with its magnitude, interpolated as mag·e^{iφ}
qsmxt resample --phase phase.nii --magnitude mag.nii \
--phase-out phase_axial.nii --magnitude-out mag_axial.nii