- Config name
model: vfa_t1BIDS suffixVFAMethod family- T1 Relaxometry Acquired volumes
- 2 Fit granularity
- voxelwise
Fits the longitudinal relaxation time T1 from spoiled gradient-echo images acquired at two or more excitation flip angles and a single repetition time. Dividing the steady-state signal by the sine of the flip angle linearizes the model, so T1 and the equilibrium magnetization follow from an ordinary least-squares line through the transformed data — a closed-form solve, with no iteration. That transform also divides the noise, which biases the estimate at low SNR, so a nonlinear fit_type is available that minimises residuals on the signal equation itself. A transmit field map, when supplied, scales the nominal flip angles to the actual ones before the fit.
Signal model¶
| Symbol | Quantity | Unit |
|---|---|---|
M0 | Equilibrium magnetization | — |
T1 | Longitudinal relaxation time | s |
What the model reads¶
A series of 2 volumes indexed by FlipAngle. Volumes are matched to these identities by value, so reordering the acquisition yields an identical fit.
| # | FlipAngle |
|---|---|
| 1 | 3 |
| 2 | 20 |
Where the protocol comes from¶
In a BIDS dataset these values are resolved for you:
| Protocol parameter | Source | Key | Resolved |
|---|---|---|---|
FlipAngle | sidecar field | FlipAngle | per volume |
RepetitionTimeExcitation | derived from sidecar metadata | — | whole collection |
Inputs¶

Figure 1:The 2 acquired volumes, each labeled with the identity the model reads it by.

Figure 2:Auxiliary maps and the mask applied to this fit.
Auxiliary maps¶
| Input | Required | BIDS suffix | CLI flag |
|---|---|---|---|
B1map | optional | TB1map | --b1map |
Outputs¶
| Map | BIDS suffix | Unit | Fit bounds | Fitted |
|---|---|---|---|---|
T1 | T1map | s | 1e-05 … 5 | free |
M0 | M0map | — | 0 … 6000 | free |

Figure 3:Fitted maps for one example subject.
Usage¶
The acquisition comes from the sidecars, so recipes/bids/vfa_t1_config.yaml carries only algorithm options:
model: vfa_t1
# BIDS input: FlipAngle and RepetitionTimeExcitation are read from the JSON
# sidecars via the model's protocol_schema(), so neither is declared here.
# Fit algorithm (an option, not BIDS metadata): `linear` is qMRLab's closed-form
# Fram linearization; `nonlinear` minimises residuals on the signal equation by
# Levenberg-Marquardt, avoiding the bias the linearizing transform puts into the
# noise at low SNR.
fit_type: linear
# BIDS mask selection — disambiguates which mask in the dataset to apply.
mask:
desc: brainqmrust fit --bids-dir ds-mydata \
--config recipes/bids/vfa_t1_config.yaml --output-dir outFitted maps are written as BIDS derivatives:
out/derivatives/qmrust/sub-01/anat/
sub-01_T1map.nii.gz
sub-01_T1map.json
sub-01_M0map.nii.gz
sub-01_M0map.jsonNo sidecars, so recipes/non-bids/vfa_t1_config.yaml declares the acquisition itself:
model: vfa_t1
# non-BIDS: protocol from this file; mask via --mask
# Flip angles in degrees (BIDS-MRI convention), times in seconds (BIDS/SI).
# The linearization assumes one repetition time for the whole series.
flip_angles:
- 3
- 20
repetition_time: 0.015
# Fit algorithm. `linear` (default) is qMRLab's closed-form Fram linearization;
# `nonlinear` refines it with Levenberg-Marquardt on the signal equation, which
# avoids the bias the linearizing transform puts into the noise at low SNR.
fit_type: linearqmrust fit --data data.nii.gz --mask mask.nii.gz \
--config recipes/non-bids/vfa_t1_config.yaml \
--b1map <file> \
--output-dir outSee Fitting without BIDS.
model: vfa_t1
# Simulation: the acquisition comes from this file. Flip angles in degrees
# (BIDS-MRI convention), times in seconds (BIDS/SI).
flip_angles:
- 3
- 20
repetition_time: 0.015
fit_type: linear
# Ground truth: white matter at 3 T, T1 near 1 s.
sim:
params: { T1: 1.0, M0: 1000.0 }
noise: { type: rician, snr: 100.0 }
seed: 0
trials: 100
sweep: { param: T1, start: 0.4, stop: 3.0, steps: 10 }
distributions:
T1: { mean: 1.0, std: 0.2 }qmrust sim signal --config recipes/sim/vfa_t1_sim.yaml --output signal.json
qmrust sim single-voxel --config recipes/sim/vfa_t1_sim.yaml --output sv.json
qmrust sim sensitivity --config recipes/sim/vfa_t1_sim.yaml --output sens.json
qmrust sim montecarlo --config recipes/sim/vfa_t1_sim.yaml --output mc.jsonSee Simulation.
The same core, compiled to WebAssembly:
import init, { fit_volume } from './pkg/qmrust_wasm.js';
await init();
const maps = fit_volume(configYaml, data, [nx, ny, nz, nt],
JSON.stringify(volumeIds), mask, '{}');Try it on real data in the playground, or read Browser & wasm.

Figure 4:One voxel’s measured data with the model’s forward signal at the fitted parameters. The curve is computed by the same Rust code that does the fitting.
Implementation¶
model.rs— theModelimplementation: measurement contract, protocol schema, BIDS outputs.fit.rs— the numerical fit.config.rs— configuration and validation.
Fully-resolved configuration
Every default materialized, as qmrust dump-config prints it.
model: vfa_t1
flip_angles:
- 3.0
- 20.0
repetition_time: 0.015
fit_type: linearReferences¶
Fram et al. (1987)
- Fram, E. K., Herfkens, R. J., Johnson, G. A., Glover, G. H., Karis, J. P., Shimakawa, A., Perkins, T. G., & Pelc, N. J. (1987). Rapid calculation of T1 using variable flip angle gradient refocused imaging. Magnetic Resonance Imaging, 5(3), 201–208.