pub fn r2primenet(
r2star: &[f64],
mask: &[u8],
grid: &Grid,
b0_tesla: f64,
model_onnx: &[u8],
norm: &R2PrimeNetNorm,
params: &R2PrimeNetParams,
progress: impl FnMut(usize, usize),
) -> Result<Vec<f64>, OnnxError>Expand description
Run R2PRIMEnet: predict R2′ (Hz) from an R2* map (Hz).
§Arguments
r2star— R2* map in Hz, column-major(nx,ny,nz).mask— binary brain mask (same layout).grid— volume dimensions and voxel sizes.b0_tesla— field strength the R2* map was acquired at, in Tesla. An argument rather than aR2PrimeNetParamsfield precisely because it must not have a default: a 3 T that nobody chose is indistinguishable from a 3 T that nobody checked, which is the whole of the failure this guards. See the module docs.model_onnx— bytes of the exportedr2primenet.onnx(1→1 chan, dynamic spatial axes).norm— training normalization constants.params— patch size and the field-strength override; seeR2PrimeNetParams.progress— progress callback(patches_done, patches_total).
§Returns
R2′ in Hz, clipped at zero and restricted to mask, in the same layout.
Deviation: the authors’ test.py (χ-sepnet-R2*) passes R2PRIMEnet’s output on to
χ-sepnet without truncating it. Here negative R2′ is set to 0, since a negative reversible
decay rate has no physical meaning; every non-negative value is the network’s unchanged.
QSM.rs clamps R2′ the same way wherever it makes it (this and
r2prime), so every consumer, χ-sepnet included, gets the
clamped map. The effect on χ-sepnet is negligible: on two travelling-head scans (Philips
and GE, 3 T) 0.3–0.4% of brain voxels were clamped (all above −1 Hz), χ+ and χ− changed by at
most 1.5 ppb (median < 0.001 ppb), and mean χ+/χ− in deep grey matter by under 0.001 ppb,
about 1e-5 of its value.
§Errors
OnnxError::Domain when b0_tesla is more than B0_TOLERANCE_T from TRAINED_B0_T
and R2PrimeNetParams::ignore_field_mismatch is not set — checked before anything is
allocated or loaded.
§Panics
If a patch dimension is not a multiple of 16 (the network’s four pooling levels).