struct Problem {}Expand description
The arrays of one run, on the padded grid. What is fixed across the NNLS iterations is kept in the least memory that gives the same numbers (see Performance in the module docs).
Fields§
§dims: (usize, usize, usize)§n: usize§dims0: (usize, usize, usize)input grid and padding
pad: [usize; 3]§vs: [f64; 3]§m: Vec<u8>mask (0/1)
inside: Supportthe mask’s voxels
drp: f64D_r,± in ppm
drn: f64§d: Kerneldipole kernel (dipole_kernel(..., 'kspace'))
w_i: Vec<f64>step 1’s data weight W_I at the mask’s voxels: w_mag = W_I.*m there, 0 elsewhere,
and w_phs = 2π·w_mag
b1: Vec<f64>step 1’s right-hand side, [b+; b−]
xm: BoxVolstep 2’s gradient weights are recomputed where used from the masked fast QSM and smoothed
R2′ (zero outside the mask, so kept on its bounding box) and their percentiles (lo, hi)
per source and axis
rm: BoxVol§wg_thr: [[(f64, f64); 3]; 2]§cone: Supportstep 2’s cone |D| < D2_thr
Implementations§
Source§impl Problem
impl Problem
Sourcefn new(
inputs: &ChiSepIlsqrInputs<'_>,
grid: &Grid,
bdir: (f64, f64, f64),
params: &ChiSepIlsqrParams,
) -> (Self, Workspace, Vec<f64>)
fn new( inputs: &ChiSepIlsqrInputs<'_>, grid: &Grid, bdir: (f64, f64, f64), params: &ChiSepIlsqrParams, ) -> (Self, Workspace, Vec<f64>)
The problem, the FFT workspace, and R2′ (ppm, clamped) on the padded grid for the start.
Sourcefn pad_input<T: Copy + Default>(&self, a: &[T]) -> Vec<T>
fn pad_input<T: Copy + Default>(&self, a: &[T]) -> Vec<T>
padarray(a, pad, 0, 'both') of an input-grid volume
Sourcefn on_mask(&self, x: &[f64], clamp: bool) -> Vec<f64>
fn on_mask(&self, x: &[f64], clamp: bool) -> Vec<f64>
[x+; x−] of a padded [x+; x−] at the mask’s voxels, with a.*(a > 0) if clamp
Sourcefn padded_from_mask(&self, v: &[f64], x: &mut [f64])
fn padded_from_mask(&self, v: &[f64], x: &mut [f64])
The padded [x+.*m; x−.*m] of [x+; x−] at the mask’s voxels, into x
Sourcefn crop_from_mask(&self, v: &[f64]) -> (Vec<f64>, Vec<f64>)
fn crop_from_mask(&self, v: &[f64]) -> (Vec<f64>, Vec<f64>)
(χ+, χ−) on the input grid from [x+; x−] at the mask’s voxels (χ− = −x−)
Sourcefn zero_ring(&self, a: &mut [f64])
fn zero_ring(&self, a: &mut [f64])
Zero the padding ring (the toolbox crops each step’s output and pads the next step’s input)
Sourcefn load_w(
&self,
c: &mut [Complex64],
f: impl Fn(usize, f64) -> f64 + Sync + Send,
)
fn load_w( &self, c: &mut [Complex64], f: impl Fn(usize, f64) -> f64 + Sync + Send, )
c ← f(l, w) as a real volume, with w = W_I at the mask’s voxels and 0 elsewhere (the
value of w_mag there)
Sourcefn dc_c(&self, ws: &mut Workspace)
fn dc_c(&self, ws: &mut Workspace)
c ← Dc(c), c holding a real volume: real(ifftn(D.*fftn(c))), as a real volume
Sourcefn a1(&self, ws: &mut Workspace, x: &[f64], out: &mut [f64])
fn a1(&self, ws: &mut Workspace, x: &[f64], out: &mut [f64])
Step 1’s normal operator on [x+; x−]
Sourcefn step1(
&self,
ws: &mut Workspace,
start: Start<'_, f64>,
tol: f64,
maxit: usize,
) -> Vec<f64>
fn step1( &self, ws: &mut Workspace, start: Start<'_, f64>, tol: f64, maxit: usize, ) -> Vec<f64>
Step 1: pcg from start; returns the solution with the padding ring zeroed.
Sourcefn cone_ifft(&self, ws: &mut Workspace, y: &[Complex64], out: &mut [f64])
fn cone_ifft(&self, ws: &mut Workspace, y: &[Complex64], out: &mut [f64])
out ← real(ifftn(M_ic.*y)), y on the cone’s voxels
Sourcefn g_pm(&self, s: usize, c: usize, p: [usize; 3]) -> f64
fn g_pm(&self, s: usize, c: usize, p: [usize; 3]) -> f64
The fgrad component c (voxel size vs) of the masked fast QSM and smoothed R2′ at p,
combined into |g+| (s = 0) or |g−| (s = 1)
Sourcefn wg2(&self, s: usize, c: usize, p: [usize; 3], l: usize) -> f64
fn wg2(&self, s: usize, c: usize, p: [usize; 3], l: usize) -> f64
W_G² of source s, axis c at voxel p (l): conj(W).*W with W = W_G.*M
Sourcefn cone_fft_reg(
&self,
ws: &mut Workspace,
s: usize,
x: &[f64],
out: &mut [Complex64],
)
fn cone_fft_reg( &self, ws: &mut Workspace, s: usize, x: &[f64], out: &mut [Complex64], )
out ← M_ic.*fftn(gT(W_G².*fgrad(x, 1), 1)) on the cone’s voxels, for source s
Sourcefn step2(&self, ws: &mut Workspace, x: &mut [f64], params: &ChiSepIlsqrParams)
fn step2(&self, ws: &mut Workspace, x: &mut [f64], params: &ChiSepIlsqrParams)
Step 2 on step 1’s [x+; x−], in place: each source minus its streaking component, masked.
Auto Trait Implementations§
impl Freeze for Problem
impl RefUnwindSafe for Problem
impl Send for Problem
impl Sync for Problem
impl Unpin for Problem
impl UnsafeUnpin for Problem
impl UnwindSafe for Problem
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> 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