pub struct MotionSeries {
pub reference: usize,
pub volumes: Vec<VolumeMotion>,
}Expand description
Where every volume of a series was, relative to the reference.
The output grid is the reference volume’s grid throughout: apply* resamples onto it, and
VolumeMotion::bdir is expressed in it.
Fields§
§reference: usizeIndex of the reference volume within the series.
volumes: Vec<VolumeMotion>One entry per input volume, in input order. The reference’s own entry is present and is the identity, so indices line up with the caller’s data and nothing has to be skipped.
Implementations§
Source§impl MotionSeries
impl MotionSeries
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether the series is empty. Never true for a MotionSeries estimate_motion
returned, which rejects an empty series.
Sourcepub fn dims(&self) -> (usize, usize, usize)
pub fn dims(&self) -> (usize, usize, usize)
Dimensions of the output grid — the reference volume’s.
Sourcepub fn affine(&self) -> [f64; 16]
pub fn affine(&self) -> [f64; 16]
Voxel→world affine of the output grid — the reference volume’s.
Sourcepub fn bdirs(&self) -> Vec<(f64, f64, f64)>
pub fn bdirs(&self) -> Vec<(f64, f64, f64)>
Every volume’s B0 direction in the reference grid’s voxel frame, in input order — ready to hand to a multi-orientation inversion alongside the resampled field maps.
Sourcepub fn max_displacement_mm(&self) -> f64
pub fn max_displacement_mm(&self) -> f64
The largest tissue displacement anywhere in the series, in mm — the one number to compare
against the voxel size when deciding whether the motion mattered. See
VolumeMotion::max_displacement_mm.
Sourcepub fn rotation_spread_deg(&self) -> f64
pub fn rotation_spread_deg(&self) -> f64
The largest angle between any two volumes’ recovered B0 directions, in degrees.
This, not the rotation relative to the reference, is what decides whether the series can be averaged: it is the spread of dipole-kernel orientations the average would be taken over. Zero for a series that only translated, however far it translated.
Sourcepub fn suspect(&self) -> impl Iterator<Item = &VolumeMotion>
pub fn suspect(&self) -> impl Iterator<Item = &VolumeMotion>
The volumes whose estimate looks untrustworthy. See VolumeMotion::suspect.
Sourcepub fn apply(&self, t: usize, data: &[f64]) -> Option<Vec<f64>>
pub fn apply(&self, t: usize, data: &[f64]) -> Option<Vec<f64>>
Resample volume t’s continuous data (magnitude, an unwrapped field map, χ) onto the
reference grid.
Not for wrapped phase. Interpolating wrapped phase directly turns every wrap into a
band of wrong values; use Self::apply_complex, which is why it exists.
Sourcepub fn apply_complex(
&self,
t: usize,
magnitude: &[f64],
phase: &[f64],
) -> Option<(Vec<f64>, Vec<f64>)>
pub fn apply_complex( &self, t: usize, magnitude: &[f64], phase: &[f64], ) -> Option<(Vec<f64>, Vec<f64>)>
Resample volume t’s magnitude and wrapped phase onto the reference grid together,
interpolating mag·e^{iφ} so the wraps survive. Returns (magnitude, phase).
Sourcepub fn apply_mask(&self, t: usize, mask: &[u8]) -> Option<Vec<u8>>
pub fn apply_mask(&self, t: usize, mask: &[u8]) -> Option<Vec<u8>>
Resample volume t’s binary mask or label volume onto the reference grid (nearest
neighbour).
Sourcepub fn coverage(&self, t: usize) -> Option<Vec<u8>>
pub fn coverage(&self, t: usize) -> Option<Vec<u8>>
Which reference voxels volume t reaches at all.
A rotated volume cannot fill the whole reference grid, and resampling leaves zeros where it does not reach. Those zeros are “no data”, not a zero measurement, and this is what tells them apart.
Sourcepub fn common_coverage(&self) -> Option<Vec<u8>>
pub fn common_coverage(&self) -> Option<Vec<u8>>
Reference voxels that every volume of the series reaches.
Sourcepub fn average_complex<T: AsRef<[f64]>>(
&self,
magnitudes: &[T],
phases: &[T],
) -> Option<MotionAverage>
pub fn average_complex<T: AsRef<[f64]>>( &self, magnitudes: &[T], phases: &[T], ) -> Option<MotionAverage>
Complex-average the series onto the reference grid: resample every volume’s magnitude/phase pair through its recovered transform, then take the complex mean over the volumes that reached each voxel.
The plain complex mean, not a magnitude-weighted one: for repeats with the same noise level that is the maximum-likelihood combination, and weighting by magnitude would bias the result toward whichever volume happened to be brightest.
Read MotionAverage before using this on a series that rotated.
Returns None if the number of magnitude or phase volumes disagrees with the series, or
if any volume’s length disagrees with its own grid.
Trait Implementations§
Source§impl Clone for MotionSeries
impl Clone for MotionSeries
Source§fn clone(&self) -> MotionSeries
fn clone(&self) -> MotionSeries
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for MotionSeries
impl RefUnwindSafe for MotionSeries
impl Send for MotionSeries
impl Sync for MotionSeries
impl Unpin for MotionSeries
impl UnsafeUnpin for MotionSeries
impl UnwindSafe for MotionSeries
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