mrpro.operators.SliceProjectionOp

class mrpro.operators.SliceProjectionOp[source]

Bases: LinearOperator

Slice Projection Operator.

This operation samples from a 3D Volume a slice with a given rotation and shift (relative to the center of the volume) according to the slice_profile. It can, for example, be used to describe the slice selection of a 2D MRI sequence from the 3D Volume.

The projection will be done by sparse matrix multiplication.

slice_rotation, slice_shift, and slice_profile can have (multiple) batch dimensions. These dimensions will be broadcasted to a common shape and added to the front of the volume. Different settings for different volume batches are NOT supported, consider creating multiple operators if required.

__init__(input_shape: SpatialDimension[int], slice_rotation: Rotation | None = None, slice_shift: float | Tensor = 0.0, slice_profile: Callable[[Tensor], Tensor] | ndarray | NestedSequence[Callable[[Tensor], Tensor]] | float = 2.0, optimize_for: Literal['forward', 'adjoint', 'both'] = 'both')[source]

Create a module that represents the ‘projection’ of a volume onto a plane.

This operation samples from a 3D Volume a slice with a given rotation and shift (relative to the center of the volume) according to the slice_profile. It can, for example, be used to describe the slice selection of a 2D MRI sequence from the 3D Volume.

The projection will be done by sparse matrix multiplication.

Rotation, shift, and profile can have (multiple) batch dimensions. These dimensions will be broadcasted to a common shape and added to the front of the volume. Different settings for different volume batches are NOT supported, consider creating multiple operators if required.

Note

All parameters must be on cpu when creating the operator. Preparation of the operator on the GPU would be slower than transferring the parameters to the CPU, creation, then transferring the operator back to the GPU.

Parameters:
  • input_shape (SpatialDimension[int]) – Shape of the 3D volume to sample from. (z, y, x)

  • slice_rotation (Rotation | None, default: None) – Rotation that describes the orientation of the plane. If None, an identity rotation is used.

  • slice_shift (float | Tensor, default: 0.0) – Offset of the plane in the volume perpendicular plane from the center of the volume. (The center of a 4 pixel volume is between 1 and 2.)

  • slice_profile (Union[Callable[[Tensor], Tensor], ndarray, NestedSequence[Callable[[Tensor], Tensor]], float], default: 2.0) – A function returning the relative intensity of the slice profile at a position x (relative to the nominal profile center). This can also be a nested Sequence or an numpy array of functions. See mrpro.utils.slice_profiles for examples. If it is a single float, it will be interpreted as the full-width-at-half-maximum (FWHM) of a rectangular profile.

  • optimize_for (Literal['forward', 'adjoint', 'both'], default: 'both') – Whether to optimize for forward or adjoint operation or both. Optimizing for both takes more memory but is faster for both operations.

property H: LinearOperator[source]

Adjoint operator.

Obtains the adjoint of an instance of this operator as an AdjointLinearOperator, which itself is a an LinearOperator that can be applied to tensors.

Note: linear_operator.H.H == linear_operator

property gram: LinearOperator[source]

Gram operator.

For a LinearOperator \(A\), the self-adjoint Gram operator is defined as \(A^H A\).

Note

This is the inherited default implementation.

__call__(*args: Unpack[Tin]) Tout[source]

Apply the forward operator.

For more information, see forward.

Note

Prefer using operator_instance(*parameters), i.e. using __call__ over using forward.

adjoint(x: Tensor) tuple[Tensor][source]

Transform from a 2D slice to a 3D Volume.

Parameters:

x (Tensor) – 2D Slice with shape (..., 1, max(z, y, x), (max(z, y, x))) with z, y, x matching the input_shape

Returns:

A 3D Volume with shape (..., z, y, x) – with` z, y, x` matching the input_shape

forward(x: Tensor) tuple[Tensor][source]

Transform from a 3D Volume to a 2D Slice.

Parameters:

x (Tensor) – 3D Volume with shape (..., z, y, x) with z, y, x matching the input_shape

Returns:

A 2D slice with shape (..., 1, max(z, y, x), (max(z, y, x)))

static join_matrices(matrices: Sequence[Tensor]) Tensor[source]

Join multiple sparse matrices into a block diagonal matrix.

Parameters:

matrices (Sequence[Tensor]) – List of sparse matrices to join by stacking them as a block diagonal matrix

static projection_matrix(input_shape: SpatialDimension[int], output_shape: SpatialDimension[int], rotation: Rotation, offset: Tensor, w: int, slice_function: Callable[[Tensor], Tensor], rotation_center: Tensor | None = None) Tensor[source]

Create a sparse matrix that represents the projection of a volume onto a plane.

Outside the volume values are approximately zero padded

Parameters:
  • input_shape (SpatialDimension[int]) – Shape of the volume to sample from

  • output_shape (SpatialDimension[int]) – Shape of the resulting plane, 2D. Only the x and y values are used.

  • rotation (Rotation) – Rotation that describes the orientation of the plane

  • offset (Tensor) – Shift of the plane from the center of the volume in the rotated coordinate system in units of the 3D volume, order z, y, x

  • w (int) – Factor that determines the number of pixels that are considered in the projection along the slice profile direction.

  • slice_function (Callable[[Tensor], Tensor]) – Function that describes the slice profile. See mrpro.utils.slice_profiles for examples.

  • rotation_center (Tensor | None, default: None) – Center of rotation, if None the center of the volume is used, i.e. for 4 pixels 0 1 2 3 it is between 1 and 2

Returns:

torch.sparse_coo_matrix – Sparse matrix that represents the projection of the volume onto the plane

operator_norm(initial_value: Tensor, dim: Sequence[int] | None, max_iterations: int = 20, relative_tolerance: float = 1e-4, absolute_tolerance: float = 1e-5, callback: Callable[[Tensor], None] | None = None) Tensor[source]

Power iteration for computing the operator norm of the operator.

Parameters:
  • initial_value (Tensor) – initial value to start the iteration; must be element of the domain. if the initial value contains a zero-vector for one of the considered problems, the function throws an ValueError.

  • dim (Sequence[int] | None) –

    The dimensions of the tensors on which the operator operates. The choice of dim determines how the operator norm is inperpreted. For example, for a matrix-vector multiplication with a batched matrix tensor of shape (batch1, batch2, row, column) and a batched input tensor of shape (batch1, batch2, row):

    • If dim=None, the operator is considered as a block diagonal matrix with batch1*batch2 blocks and the result is a tensor containing a single norm value (shape (1, 1, 1)).

    • If dim=(-1), batch1*batch2 matrices are considered, and for each a separate operator norm is computed.

    • If dim=(-2,-1), batch1 matrices with batch2 blocks are considered, and for each matrix a separate operator norm is computed.

    Thus, the choice of dim determines implicitly determines the domain of the operator.

  • max_iterations (int, default: 20) – maximum number of iterations

  • relative_tolerance (float, default: 1e-4) – absolute tolerance for the change of the operator-norm at each iteration; if set to zero, the maximal number of iterations is the only stopping criterion used to stop the power iteration.

  • absolute_tolerance (float, default: 1e-5) – absolute tolerance for the change of the operator-norm at each iteration; if set to zero, the maximal number of iterations is the only stopping criterion used to stop the power iteration.

  • callback (Callable[[Tensor], None] | None, default: None) – user-provided function to be called at each iteration

Returns:

An estimaton of the operator norm. Shape corresponds to the shape of the input tensor initial_value with the dimensions specified in dim reduced to a single value. The pointwise multiplication of initial_value with the result of the operator norm will always be well-defined.

__add__(other: LinearOperator | Tensor) LinearOperator[source]
__add__(other: Operator[Tensor, tuple[Tensor]]) Operator[Tensor, tuple[Tensor]]

Operator addition.

Returns lambda x: self(x) + other(x) if other is a operator, lambda x: self(x) + other if other is a tensor

__and__(other: LinearOperator) LinearOperatorMatrix[source]

Vertical stacking of two LinearOperators.

A&B is a LinearOperatorMatrix with two rows, with (A&B)(x) == (A(x), B(x)). See mrpro.operators.LinearOperatorMatrix for more information.

__matmul__(other: LinearOperator) LinearOperator[source]
__matmul__(other: Operator[Unpack[Tin2], tuple[Tensor]]) Operator[Unpack[Tin2], tuple[Tensor]]

Operator composition.

Returns lambda x: self(other(x))

__mul__(other: Tensor | complex) LinearOperator[source]

Operator elementwise left multiplication with tensor/scalar.

Returns lambda x: self(x*other)

__or__(other: LinearOperator) LinearOperatorMatrix[source]

Horizontal stacking of two LinearOperators.

A|B is a LinearOperatorMatrix with two columns, with (A|B)(x1,x2) == A(x1)+B(x2). See mrpro.operators.LinearOperatorMatrix for more information.

__radd__(other: Tensor) LinearOperator[source]

Operator addition.

Returns lambda x: self(x) + other*x

__rmul__(other: Tensor | complex) LinearOperator[source]

Operator elementwise right multiplication with tensor/scalar.

Returns lambda x: other*self(x)