nlop.SignalModel#

class bartorch.nlop.SignalModel#

Bases: NonlinearOperator

A TorchSim signal model as a BART nonlinear operator.

The operator maps parameter maps to one image per contrast. What it does at each point is TorchSim’s: A() for the value, A_jvp for the derivative and A_vjp for its adjoint, none of which builds a Jacobian – the model is voxel-diagonal, so one forward-mode pass gives the whole volume’s derivative whatever the parameter count.

Parameters:
  • model (torchsim.recon.ModelOperator) – The signal model, with its unknowns, bounds and scales already set.

  • shape (tuple of int, default=()) – The voxel shape, C order – (y, x), (z, y, x), whatever the maps are. The operator’s domain is (channels, *shape) and its codomain (contrasts, *shape).

  • contrasts (int, default=None) – How many images the model returns. Measured from the model when it is not given.

channels#

Map channels the domain carries, in TorchSim’s order.

Type:

int

Examples

>>> from torchsim.recon import ModelOperator
>>> from torchsim.simulators import MultiEchoSimulator
>>> model = ModelOperator(
...     MultiEchoSimulator(TE=echo_times), "T2", bounds={"T2": (10.0, 300.0)}
... )
>>> M = SignalModel(model, (128, 128))
>>> M.ishape, M.oshape
((3, 128, 128), (8, 128, 128))
>>> images = M(M.initial(T2=80.0))

Under an encoding:

>>> F = encoding @ M
>>> maps = nlop.IRGNM()(kspace, F, x0=M.initial(T2=80.0))
>>> M.split(maps)["T2"]
property names#

What each channel of the domain is, in order.

initial()#

Maps to start from, in this operator’s layout.

Accepts the arguments of initial() – {name: value} in each property’s own units – and returns a complex tensor of ishape.

split()#

The named maps x stands for, in their own units.

The inverse of the packing initial() does: what a fit returns is the variables actually solved for, and this turns them back into a T1 in milliseconds and a complex amplitude.

Also has the methods and properties of NonlinearOperator.