bartorch.nlop.NonlinearSense#
- class bartorch.nlop.NonlinearSense(image_shape, pattern=None, trajectory=None, *, kspace_shape=None, coil_shape=None, coefficient_shape=None, weights=None, basis=None, mask=None, sobolev=(220.0, 32.0), c=1.0, real=False, sos=False, oversampling_coils=None, oversampled_coils=False, toeplitz=True, optimized=False)#
BART’s
noirmodel: the image and the coil profiles fitted together.The operator takes two inputs – the image, and the coils as k-space coefficients – and returns data. Its Jacobian by either one is a linear operator (
jacobian()), which is what a Gauss-Newton step solves over.The coils are unknown as coefficients, not as maps: BART carries the Sobolev weighting
(1 + a |k|^2)^(-b/2)that keeps them smooth inside the model, so the quantity being fitted is already regularised.coilsis the operator that turns fitted coefficients into sensitivities.Off the grid the model is asymmetric, as BART builds it: it returns gridded coil images rather than samples, so a measurement has to be gridded to match.
prepare()does that, and does nothing on a grid, where the model returns k-space directly.- Parameters:
image_shape (tuple of int) – Coil-image shape,
(coils, *spatial), C order – the same shape the linear encodings take. The image itself is this with one coil.pattern (tensor, optional) – On a grid: ones where a sample was taken, zeros where it was not. Without one the acquisition is taken to be fully sampled, which is what
nlinvestimates from a complete measurement.trajectory (tensor, optional) – Off the grid: the trajectory,
(..., samples, 3)in grid units, asbartorch.linop.NUFFTtakes it. Giving one makes the non-Cartesian model.kspace_shape (tuple of int, optional) – Sample shape. Off the grid it defaults to the trajectory’s with the image’s coil axes in front, as the NUFFT’s does; on the grid it is the coil-image shape.
coil_shape (tuple of int, optional) – Where the sensitivities live and where their coefficients do; both default to the coil-image shape.
coefficient_shape (tuple of int, optional) – Where the sensitivities live and where their coefficients do; both default to the coil-image shape.
weights (tensor, optional) – Density compensation, off the grid.
basis (tensor, optional) – Temporal subspace basis, off the grid. BART’s Cartesian model refuses one.
mask (tensor, optional) – A support the image is restricted to –
nlinv’srestrict-fov.sobolev (tuple of float) –
(a, b)of the coil weighting, BART’s220, 32.c (float) – The exponent’s scaling, BART’s
1.real (bool) – Constrain the image to be real,
nlinv -g’srvc.sos (bool) – BART’s sum-of-squares variant of the coil weighting.
oversampling_coils (float, optional) – Fit the coils on a finer grid than the image. By default whichever
nlinvuses: two off the grid, one on it.oversampled_coils (bool) – Return them on that grid rather than on the image’s.
toeplitz (bool) – Off the grid, apply the NUFFT’s normal as a convolution.
optimized (bool) – BART’s
noir2_noncart_optimized_create, off the grid.
Examples
>>> F = NonlinearSense((8, 128, 128), pattern=mask) >>> F.ishapes ((1, 128, 128), (8, 128, 128)) >>> image, coefficients = optim.IRGNM()(F.prepare(kspace), F.flatten(), ...)
- __init__(image_shape, pattern=None, trajectory=None, *, kspace_shape=None, coil_shape=None, coefficient_shape=None, weights=None, basis=None, mask=None, sobolev=(220.0, 32.0), c=1.0, real=False, sos=False, oversampling_coils=None, oversampled_coils=False, toeplitz=True, optimized=False)#
Methods
__init__(image_shape[, pattern, trajectory, ...])adjoint(dy)DF(x)^H dyat the last evaluated point, for one input and one output.chain(other, *[, output, input])Output
outputofselfinto inputinputofother.combine(other)selfandotherside by side, sharing nothing.del_out([output])Drop an output, and everything computed only for it.
derivative(dx)DF(x) dxat the last evaluated point, for one input and one output.dup([a, b])Make two inputs of the same shape one input, kept at
a.flatten([inputs_only])Every input as one flat vector, and every output as another.
forward(*xs)F(x), which also fixes where every derivative is taken.jacobian([output, input])DF/dx_inputof one output, as aLinearOperator.linearize(*xs)The derivative at
x, as aLinearOperator.link([output, input])Tie an output back into an input; both arguments go away.
permute_inputs(perm)Reorder the inputs: the new input
iis the oldperm[i].permute_outputs(perm)Reorder the outputs: the new output
ois the oldperm[o].pin(input, value)Fix one input to
value; the input goes away.prepare(kspace)The measurement in the shape the model returns.
reshape_input(input, shape)This operator with one input's shape written differently.
reshape_output(output, shape)This operator with one output's shape written differently.
shift_input(new, old)Move one input to another position, the rest closing up behind it.
shift_output(new, old)Move one output to another position, the rest closing up behind it.
stack_inputs(a, b, axis)Make two inputs one, concatenated along a C-order
axis.stack_outputs(a, b, axis)Make two outputs one, concatenated along a C-order
axis.Attributes
coilsthe Sobolev weighting and the transform.
dataFrom what the model returns to the measurement.
deviceimageThe image's own linear part -- the mask, and the real constraint if asked for.
ishapeThe domain, for an operator with one input.
ishapesThe shape of each argument, outputs and inputs kept apart.
oshapeThe codomain, for an operator with one output.
oshapestransformThe transform from coil images to k-space, without the model in front of it.