bartorch.linop.NoncartesianSense

bartorch.linop.NoncartesianSense#

class bartorch.linop.NoncartesianSense(sensitivities, image_shape, traj=None, kspace_shape=None, kernels=False, toeplitz=True, modulated=False, weights=None, basis=None, device=None, coil_batch=1, fold_maps=True)#

Sensitivities followed by a NUFFT, applied coil_batch coils at a time.

Memory held – and the doubled grid the Toeplitz normal convolves on – scales with coil_batch rather than with the number of coils.

A trajectory is what this operator is for. On a grid the operator is CartesianSense(), which is this one’s own Cartesian path under the name that says so.

Parameters:
  • sensitivities (tensor) –

    Coil sensitivities of shape (coils, *image_shape[1:]), or their k-space kernels when kernels is set. A bank on the host while the transform is on a card is transferred a slab at a time.

    Several sets of maps – ESPIRiT’s second, ENLIVE’s relaxed model – are (sets, coils, *spatial), which is what bartorch.tools.ecalib() and bartorch.tools.nlinv() return for maps > 1. The image then carries the sets and the samples do not: the encoding is y[c] = sum_m S[m, c] x[m], summed in BART’s own contraction rather than by anything here.

  • image_shape (tuple of int) – Coil-image shape, C order, for instance (coils, y, x).

  • traj (tensor) – Trajectory in grid units, as bartorch.tools.traj() produces.

  • kspace_shape (tuple of int, optional) – Sample shape; by default the trajectory’s, or the image’s on a grid.

  • kernels (bool) – Read sensitivities as k-space kernels, zero-padded to the image grid and transformed a slab at a time. The operator then applies the maps band-limited to the kernel; bartorch.maps_to_kernels() makes such kernels and bartorch.kernels_to_maps() gives the maps they stand for.

  • toeplitz (bool) – Apply the normal as a convolution with a point spread function.

  • modulated (bool) –

    On a grid, answer in BART’s own sample convention rather than the centred one – a scale and a modulation folded into the sensitivities and the plain transform after them, which is what pics works in and what its k-space is written in. The two differ by an fftmod on the sample axes; the default is the centred convention, which is what bartorch.fft() produces and so what an operator chained against one expects.

    It does not depend on coil_batch: every slab answers in the convention that was asked for. At coil_batch=0 this is BART’s own operator, arithmetic and all, which is what reproduces pics to the last bit. Refused off a grid, where there is only one convention, and with kernels, because the modulation is the whole grid’s and a kernel cannot carry it.

  • weights (tensor, optional) – Diagonal in k-space, as NUFFT takes it.

  • basis (tensor, optional) – Subspace basis (coeffs, frames, 1, 1, 1, 1, 1), as NUFFT takes it. The image then has shape (coeffs, 1, 1, 1, *spatial) and the samples one set per frame.

  • device (device, optional) – Where the operator is built and does its arithmetic; by default where the trajectory is, or the sensitivities for a Cartesian operator. With a card here, operands may stay on the host: the image crosses once each way per application, the samples a slab at a time, and between applications the card holds the operator only.

  • coil_batch (int) –

    Coils applied at once; 0 uses BART’s own operator over all coils. A larger batch is faster and holds proportionally more. A single-coil operator is always BART’s own. A batch that does not divide the coils is cut down to one that does, because the loop steps by the slab and the transform is built for a slab.

    What it changes is residency, not arithmetic. The sample convention is modulated’s to say and not this one’s.

  • fold_maps (bool) – Apply the sensitivities inside the transform of the normal, which saves two coil images per batch. Takes effect only where the transform works one coefficient at a time, the gathered arrangement of a compressed Toeplitz function.

__init__(sensitivities, image_shape, traj=None, kspace_shape=None, kernels=False, toeplitz=True, modulated=False, weights=None, basis=None, device=None, coil_batch=1, fold_maps=True)#

Methods

A(x, **kwargs)

A x, under deepinv's name.

A_adjoint(y, **kwargs)

A^H y, under deepinv's name, recorded for autograd.

A_adjoint_A(x, **kwargs)

A^H A x, under deepinv's name, recorded for autograd.

A_dagger(y, **kwargs)

The pseudo-inverse, under deepinv's name.

__init__(sensitivities, image_shape[, traj, ...])

adjoint(y[, out])

A^H y, without recording for autograd.

cogram()

A A^H as an operator.

conj()

conj(A): conjugate the input, apply, conjugate the output.

forward(x[, out])

A x, without recording for autograd.

gram()

A^H A as an operator.

normal(x[, out])

A^H A x.

opnorm()

The spectral norm, by BART's power iteration on A^H A.

pinv(y[, damp])

(A^H A + damp I)^-1 A^H y, the damped least-squares solution.

to_nonlinear()

The same operator as a NonlinearOperator.

Attributes

H

A^H, from BART's own adjoint constructor.

T

A^T, the adjoint without the conjugation, as conj(A).H.

codim_rank

How many axes the codomain has.

codim_shape

The codomain, under pyxu's name for it; the same as oshape.

codim_size

How many elements the codomain holds.

device

dim_rank

How many axes the domain has.

dim_shape

The domain, under pyxu's name for it; the same as ishape.

dim_size

How many elements the domain holds.

ishape

oshape