pub enum B0EstimationMethod {
WeightedAvg {
weighting: B0WeightType,
},
LinearFit(LinearFitParams),
RobustFit(RobustFitParams),
ComplexFit(FitPpmComplexParams),
QsmartEchofit {
fit_threshold: QsmartFitThreshold,
},
}Expand description
How run_field_mapping combines the unwrapped echoes into one
B0 map. Each method carries exactly the settings it reads, so a weighting cannot be set on a
fit that ignores it.
Only multi-echo data is combined. A single echo is φ/TE whatever is chosen here, except
that Self::RobustFit refuses a series too short for it (see RobustFitParams::min_echoes)
and Self::ComplexFit needs the echo’s magnitude (it is also φ/TE there, as in MEDI).
Variants§
WeightedAvg
Weighted mean of the per-echo frequencies, B0 = Σ wₑ (φₑ/TEₑ) / Σ wₑ, with wₑ from
weighting (default B0WeightType::PhaseSNR). The default method.
Fields
weighting: B0WeightTypePer-echo weight; B0WeightType::AssumedDecay needs a finite, positive T2*.
LinearFit(LinearFitParams)
Magnitude-weighted least-squares fit of phase against TE
(multi_echo_linear_fit). The weight is always the
magnitude; there is no B0WeightType here.
RobustFit(RobustFitParams)
Motion-robust echo combination
(multi_echo_robust_fit): the same
magnitude-weighted fit as Self::LinearFit, iteratively reweighted so that an echo which
departs from a straight line in TE at a voxel stops pulling the slope there. The weight is
magnitude × robust weight; there is no B0WeightType, because the robust scale is measured
on magnitude-standardised residuals and another weighting would break that.
Needs at least RobustFitParams::min_echoes echoes (4 with estimate_offset, else 3);
fewer is PipelineError::InvalidConfig rather than a silent plain fit. The per-echo
report is returned in FieldMappingResult::robust_fit.
ComplexFit(FitPpmComplexParams)
MEDI’s field map: the complex fit of Fit_ppm_complex.m
(fit_ppm_complex) to the wrapped echoes, then spatial
unwrapping of the fitted phase per echo spacing with unwrapping_algorithm, then division
by the echo spacing. MEDI uses its region-growing unwrapPhase
(UnwrappingAlgorithm::MediRegionGrowing); the rule complex-fit.unwrap-region-growing
offers it as the authors’ setting, never preselected, and ROMEO (given MEDI’s iMag, the
root-sum-of-squares of the echo magnitudes) stays the default.
This replaces the per-echo path rather than combining unwrapped echoes: the fit has its own
phase offset (p0), so phase_offset_removal does not apply and is not run;
bipolar_correction is refused (MEDI’s Fit_ppm_complex_bipolar is not ported). Needs the
magnitude of every echo and evenly spaced echoes. Also returns the field’s noise map
(FieldMappingResult::field_noise_ppm, MEDI’s N_std).
QsmartEchofit
QSMART’s echo fit (echofit.m, qsmart_echofit): the
magnitude-weighted fit of phase against TE through the origin, over every voxel of the
unwrapped echoes, with no per-echo constant removed after Laplacian unwrapping (with ROMEO,
whole turns between echoes are aligned, as for the weighted mean). Also returns QSMART’s
reliability map R_0 (FieldMappingResult::reliability): voxels whose fit residual,
box-filtered over ~1 mm, reaches fit_threshold (by default the 99th percentile of the
blurred residual, as QSMART’s authors run it; see
QsmartFitThreshold). The field is converted to ppm
with QSMART’s γ = 2.675e8 rad/s/T.
The echoes come from the configured unwrapping, phase-offset removal and bipolar
correction. QSMART unwraps each echo with Laplacian unwrapping on the raw phase
(unwrap_phase.m: LaplacianSolver::Mirror,
FieldMappingConfig::laplacian_unmasked) and does neither of the others; with those
settings this is QSMART’s field map, bit for bit. The rules qsmart.unwrap-laplacian,
qsmart.laplacian-solver and qsmart.unwrap-unmasked suggest them for a QSMART run.
Fields
fit_threshold: QsmartFitThresholdResidual threshold for R_0
Implementations§
Trait Implementations§
Source§impl Clone for B0EstimationMethod
impl Clone for B0EstimationMethod
Source§fn clone(&self) -> B0EstimationMethod
fn clone(&self) -> B0EstimationMethod
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for B0EstimationMethod
impl Debug for B0EstimationMethod
Source§impl Default for B0EstimationMethod
impl Default for B0EstimationMethod
Source§impl PartialEq for B0EstimationMethod
impl PartialEq for B0EstimationMethod
impl StructuralPartialEq for B0EstimationMethod
Auto Trait Implementations§
impl Freeze for B0EstimationMethod
impl RefUnwindSafe for B0EstimationMethod
impl Send for B0EstimationMethod
impl Sync for B0EstimationMethod
impl Unpin for B0EstimationMethod
impl UnsafeUnpin for B0EstimationMethod
impl UnwindSafe for B0EstimationMethod
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T> CloneAny for T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more