pub struct Grid {
pub dims: (usize, usize, usize),
pub voxel_size: (f64, f64, f64),
}Expand description
A 3D volume grid with dimensions and voxel sizes.
Fields§
§dims: (usize, usize, usize)Volume dimensions (nx, ny, nz)
voxel_size: (f64, f64, f64)Voxel sizes in mm (vsx, vsy, vsz)
Implementations§
Source§impl Grid
impl Grid
Sourcepub fn new(
nx: usize,
ny: usize,
nz: usize,
vsx: f64,
vsy: f64,
vsz: f64,
) -> Self
pub fn new( nx: usize, ny: usize, nz: usize, vsx: f64, vsy: f64, vsz: f64, ) -> Self
Create a new Grid from dimensions and voxel sizes.
pub fn nx(&self) -> usize
pub fn ny(&self) -> usize
pub fn nz(&self) -> usize
pub fn vsx(&self) -> f64
pub fn vsy(&self) -> f64
pub fn vsz(&self) -> f64
Sourcepub fn require_contiguous_slices_if_known(
&self,
slices: Option<SliceGeometry>,
) -> Result<(), SliceGapError>
pub fn require_contiguous_slices_if_known( &self, slices: Option<SliceGeometry>, ) -> Result<(), SliceGapError>
Check contiguity against slice geometry the acquisition may not have recorded.
None means the acquisition did not say how thick its slices are, and a gap then
cannot be detected — nothing in a NIfTI distinguishes 3 mm slices every 3 mm from
2 mm slices every 3 mm, because the spacing is the pitch. This returns Ok in that
case, deliberately and in one place rather than at each call site: refusing every
acquisition that failed to record a recommended BIDS field would block the vast
majority of data, which has no gap. The missing information is in the input, not in
this crate, and the right response is for the host to say so once.
The name says if_known so no call site can read as though a gap had been ruled out.
Where the thickness is known, this is Grid::require_contiguous_slices.
Sourcepub fn require_contiguous_slices(
&self,
slice_thickness: f64,
slice_axis: usize,
) -> Result<(), SliceGapError>
pub fn require_contiguous_slices( &self, slice_thickness: f64, slice_axis: usize, ) -> Result<(), SliceGapError>
Check that the volume is contiguous along the slice axis, as the FFT dipole kernel requires.
A 2D multi-slice acquisition often leaves a gap between slices: the excited slab is
thinner than the slice-to-slice pitch, so the sampled volume has holes in it. A
Grid cannot express that — its voxel_size is the pitch, and nothing records the
thickness — so the gap has to be supplied, normally from the acquisition’s
SliceThickness sidecar field.
It matters because the dipole kernel, and the spherical kernels of the SHARP family, are evaluated as FFTs on a uniform grid. That is not an approximation that degrades with the gap; the convolution being computed is simply not the one the physics calls for, and the resulting map is wrong rather than noisy — wrong in a way that still looks like a susceptibility map. So this refuses rather than warns.
In-plane work is unaffected: a gap along z does not disturb a purely in-plane kernel, so slice-wise unwrapping is valid on gapped data and deliberately does not call this. Anything that convolves along the slice axis has to.
§Arguments
slice_thickness- Excited slice thickness in mm. For a contiguous acquisition this equals the slice spacing, which is what a 3D acquisition should pass.slice_axis- Axis the slices are stacked along: 0 = x, 1 = y, 2 = z.
§Panics
If slice_axis is not 0, 1 or 2.
Trait Implementations§
impl Copy for Grid
impl StructuralPartialEq for Grid
Auto Trait Implementations§
impl Freeze for Grid
impl RefUnwindSafe for Grid
impl Send for Grid
impl Sync for Grid
impl Unpin for Grid
impl UnsafeUnpin for Grid
impl UnwindSafe for Grid
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