make_cartesian_plane_sampling

make_cartesian_plane_sampling#

pypulseqpp.make_cartesian_plane_sampling()[source]#

Select the acquired (line, partition) views of a Cartesian ky-kz plane.

A view is a zero-based encoded coordinate (y, z) on the (n_y, n_z) grid, whose k-space centre is (n_y // 2, n_z // 2).

With sampling='lattice' the support is the CAIPIRINHA lattice. With R_y, R_z = acceleration and Δ = caipi_shift, line y is acquired when (y - n_y // 2) mod R_y = 0; on the j-th acquired line counted from the centre line, j = (y - n_y // 2) // R_y, partition z is acquired when (z - n_z // 2 - Δ j) mod R_z = 0. The centre view is always acquired; Δ = 0 gives a rectangular lattice.

With sampling='poisson' the support is a variable-density Poisson-disc draw at nominal acceleration R_y * R_z from make_poisson_disc_mask(). A rectangular calibration region is seeded into the draw as a fully sampled block; an elliptical one (elliptical_acs=True) is not, so the corners of its bounding rectangle follow the draw and only the ellipse is acquired in full. caipi_shift is ignored.

For either scheme, partial Fourier and the elliptical crop are applied to the views outside the calibration region, and the calibration region is acquired in full within partial Fourier. elliptical has the same meaning for both schemes: with False no view is removed for lying outside the inscribed ellipse.

Parameters:
  • shape (tuple of int) – (n_y, n_z), the number of lines and partitions.

  • acceleration (tuple of int, default=(1, 1)) – (R_y, R_z), the undersampling factor on each axis.

  • n_acs (tuple of int, default=(0, 0)) – (n_acs_y, n_acs_z), extent of the fully sampled calibration region centred on the centre view. Ignored when R_y * R_z is 1.

  • caipi_shift (int, default=0) – CAIPIRINHA shift Δ: partitions the lattice is displaced by per acquired line. sampling='lattice' only.

  • partial_fourier (tuple of float, default=(1.0, 1.0)) – Fraction of each axis acquired, in (0.5, 1]. The views with the lowest indices are removed.

  • elliptical (bool, default=False) – Restrict the views outside the calibration region to the ellipse inscribed in the grid, for both support schemes.

  • elliptical_acs (bool, default=False) – Make the fully sampled calibration region the ellipse inscribed in its n_acs rectangle. The rectangle’s corners are then acquired only where the support scheme selects them.

  • sampling ({'lattice', 'poisson'}, default='lattice') – Support scheme: the deterministic CAIPIRINHA lattice, or a variable-density Poisson-disc draw.

  • seed (int, default=0) – Random seed of the Poisson-disc draw. sampling='poisson' only.

Returns:

  • calibration (list of tuple of int) – Calibration views (y, z), ordered by line and then by partition. Empty when there is no calibration region.

  • imaging (list of tuple of int) – Acquired views (y, z) not in calibration, in the same order. The two lists are disjoint; the acquired support is their union. Neither list is an acquisition order: the sequence application decides when each view is acquired, and creates its labels.

Raises:

ValueError – If an undersampling factor is below one, a calibration extent is negative, a partial-Fourier fraction is outside (0.5, 1], or sampling is unknown.

See also

make_cartesian_axis_sampling

the same selection over one encoding axis.

make_caipirinha_mask

the lattice as a boolean mask, without calibration.

make_poisson_disc_mask

the Poisson-disc support as a boolean mask.

make_radial_order

assignment of the selected views to echo trains.

Notes

This routine is the prescription-level support selection used by the shipped 3D Cartesian sequences. The mask generators produce support only; this routine combines a support scheme with the calibration region, partial Fourier and elliptical cropping, and returns the result as coordinate lists separated by role. With sampling='poisson' the realised acceleration can differ from R_y * R_z: partial Fourier and an elliptical calibration region are applied after the draw.

Examples

Twofold undersampling on both axes of a 4 x 4 grid, with a 2 x 2 calibration region at the centre view (2, 2):

>>> import pypulseqpp as pp
>>> calibration, imaging = pp.make_cartesian_plane_sampling(
...     (4, 4), acceleration=(2, 2), n_acs=(2, 2)
... )
>>> calibration
[(1, 1), (1, 2), (2, 1), (2, 2)]
>>> imaging
[(0, 0), (0, 2), (2, 0)]

The view (2, 2) is on the lattice and in the calibration region; it is listed once, in calibration. A CAIPIRINHA shift of one partition per acquired line displaces the partitions of line 0 relative to line 2:

>>> pp.make_cartesian_plane_sampling((4, 4), (2, 2), caipi_shift=1)[1]
[(0, 1), (0, 3), (2, 0), (2, 2)]

The coordinates convert directly to a boolean mask:

>>> import numpy as np
>>> mask = np.zeros((4, 4), dtype=bool)
>>> mask[tuple(np.transpose(calibration + imaging))] = True
>>> mask.astype(int)
array([[1, 0, 1, 0],
       [0, 1, 1, 0],
       [1, 1, 1, 0],
       [0, 0, 0, 0]])