Common MRI Data Classes#

class atommic.collections.common.data.mri_loader.MRIDataset(*args: Any, **kwargs: Any)[source]#

Bases: Dataset

A generic class for loading an MRI dataset for any task.

Note

Extends torch.utils.data.Dataset.

get_consecutive_slices(data: Dict, key: str, dataslice: int) numpy.ndarray[source]#

Get consecutive slices from a given data dictionary.

Parameters
  • data (dict) – Data to extract slices from.

  • key (str) – Key to extract slices from.

  • dataslice (int) – Slice to index.

Returns

Array of consecutive slices. If self.consecutive_slices is > 1, then the array will have shape (self.consecutive_slices, *data[key].shape[1:]). Otherwise, the array will have shape data[key].shape[1:].

Return type

np.ndarray

Examples

>>> data = {"kspace": np.random.rand(10, 640, 368)}
>>> from atommic.collections.common.data.mri_loader import MRIDataset
>>> MRIDataset.get_consecutive_slices(data, "kspace", 1).shape
(1, 640, 368)
>>> MRIDataset.get_consecutive_slices(data, "kspace", 5).shape
(5, 640, 368)
class atommic.collections.common.data.subsample.MaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: object

MaskFunc is an abstract base class for creating sub-sampling masks.

This class is used to create a mask for MRI data that can be used to randomly under-sample the k-space data. The mask is created by retaining a specified fraction of the low-frequency columns and setting the rest to zero. The fraction of low-frequency columns to retain and the amount of under-sampling can be specified at initialization.

Examples

>>> from atommic.collections.common.data.subsample import MaskFunc
>>> mask_func = MaskFunc(center_fractions=[0.08, 0.04], accelerations=[4, 8])
>>> mask_func.choose_acceleration()
(0.08, 4)
choose_acceleration() Tuple[float, int][source]#

Chooses an acceleration factor and center fractions from a list of multiple values.

Returns

A tuple of the center fraction and the acceleration factor.

Return type

Tuple[float, int]

class atommic.collections.common.data.subsample.Equispaced1DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: MaskFunc

Equispaced1DMaskFunc creates a sub-sampling mask of a given shape.

The mask selects a subset of columns from the input k-space data. If the k-space data has N columns, the mask picks out:

  1. N_low_freqs = (N * center_fraction) columns in the center corresponding to low-frequencies.

2. The other columns are selected with equal spacing at a proportion that reaches the desired acceleration rate taking into consideration the number of low frequencies. This ensures that the expected number of columns selected is equal to (N / acceleration).

It is possible to use multiple center_fractions and accelerations, in which case one possible (center_fraction, acceleration) is chosen uniformly at random each time the Equispaced1DMaskFunc object is called.

Note that this function may not give equispaced samples (documented in facebookresearch/fastMRI#54), which will require modifications to standard GRAPPA approaches. Nonetheless, this aspect of the function has been preserved to match the public multicoil data.

Examples

>>> import torch
>>> from atommic.collections.common.data.subsample import Equispaced1DMaskFunc
>>> mask_func = Equispaced1DMaskFunc(center_fractions=[0.08, 0.04], accelerations=[4, 8])
>>> mask_func.choose_acceleration()
(0.08, 4)
>>> kspace = torch.randn(1, 1, 640, 368)
>>> mask, acceleration = mask_func(kspace.shape)
>>> mask.shape
torch.Size([1, 1, 1, 368])
>>> acceleration
4
class atommic.collections.common.data.subsample.Equispaced2DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: MaskFunc

Same as Equispaced1DMaskFunc, but for 2D k-space data.

Note

See ..class::atommic.collections.common.data.subsample.Equispaced1DMaskFunc for more details.

Examples

>>> import torch
>>> from atommic.collections.common.data.subsample import Equispaced2DMaskFunc
>>> mask_func = Equispaced2DMaskFunc(center_fractions=[0.08, 0.04], accelerations=[4, 8])
>>> mask_func.choose_acceleration()
(0.08, 4)
>>> kspace = torch.randn(1, 1, 640, 368)
>>> mask, acceleration = mask_func(kspace.shape)
>>> mask.shape
torch.Size([1, 1, 640, 368])
>>> acceleration
4
class atommic.collections.common.data.subsample.Gaussian1DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: MaskFunc

Same as Gaussian2DMaskFunc, but for 1D k-space data.

Note

See ..class::atommic.collections.common.data.subsample.Gaussian2DMaskFunc for more details.

Examples

>>> import torch
>>> from atommic.collections.common.data.subsample import Gaussian1DMaskFunc
>>> mask_func = Gaussian1DMaskFunc(center_fractions=[0.7, 0.7], accelerations=[4, 8])
>>> mask_func.choose_acceleration()
(0.7, 4)
>>> kspace = torch.randn(1, 1, 640, 368)
>>> mask, acceleration = mask_func(kspace.shape)
>>> mask.shape
torch.Size([1, 1, 1, 368])
>>> acceleration
4
gaussian_coordinates() Tuple[numpy.ndarray, numpy.ndarray][source]#

Returns Gaussian sampled k-space coordinates.

Returns

  • xsamples (np.ndarray) – A 1D numpy array of x-coordinates.

  • ysamples (np.ndarray) – A 1D numpy array of y-coordinates.

Notes

The number of samples taken is determined by n_sample which is calculated as self.shape[0] / self.acceleration. The selection of the samples is based on the probabilities calculated from gaussian_kernel.

gaussian_kernel() numpy.ndarray[source]#

Creates a Gaussian sampled k-space kernel.

Note

The function calculates the Gaussian kernel by computing the sum of the exponential of the squared x-values divided by 2 times the square of the standard deviation. The standard deviation is calculated from the full width at half maximum (FWHM) of the Gaussian curve and is defined as the FWHM divided by the square root of 8 times the natural logarithm of 2. The FWHM and the kern_len are obtained from the full_width_half_maximum and shape attributes of the class respectively.

Returns

The Gaussian kernel.

Return type

ndarray

gaussian_kspace() numpy.ndarray[source]#

Creates a Gaussian sampled k-space center.

class atommic.collections.common.data.subsample.Gaussian2DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: MaskFunc

Creates a 2D sub-sampling mask of a given shape.

The sub-sampling mask is generated in k-space, with data points near the k-space center being fully sampled within an ellipse. The half-axes of the ellipse are set to the center_scale percentage of the fully sampled region. The remaining points are sampled according to a Gaussian distribution.

The center fractions act as Full-Width at Half-Maximum (FWHM) values.

Examples

>>> import torch
>>> from atommic.collections.common.data.subsample import Gaussian2DMaskFunc
>>> mask_func = Gaussian2DMaskFunc(center_fractions=[0.7, 0.7], accelerations=[4, 8])
>>> mask_func.choose_acceleration()
(0.7, 4)
>>> kspace = torch.randn(1, 1, 640, 368)
>>> mask, acceleration = mask_func(kspace.shape)
>>> mask.shape
torch.Size([1, 1, 640, 368])
>>> acceleration
4
gaussian_coordinates() List[Tuple[int, int]][source]#

Returns Gaussian sampled k-space coordinates.

Returns

  • xsamples (np.ndarray) – A 1D numpy array of x-coordinates.

  • ysamples (np.ndarray) – A 1D numpy array of y-coordinates.

Notes

The number of samples taken is determined by n_sample which is calculated as self.shape[0] / self.acceleration. The selection of the samples is based on the probabilities calculated from gaussian_kernel.

gaussian_kernel() numpy.ndarray[source]#

Creates a Gaussian sampled k-space kernel.

Note

The function calculates the Gaussian kernel by computing the sum of the exponential of the squared x-values divided by 2 times the square of the standard deviation. The standard deviation is calculated from the full width at half maximum (FWHM) of the Gaussian curve and is defined as the FWHM divided by the square root of 8 times the natural logarithm of 2. The FWHM and the kern_len are obtained from the full_width_half_maximum and shape attributes of the class respectively.

Returns

The Gaussian kernel.

Return type

ndarray

gaussian_kspace() numpy.ndarray[source]#

Creates a Gaussian sampled k-space center.

class atommic.collections.common.data.subsample.Poisson2DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: MaskFunc

Generate variable-density Poisson-disc sampling pattern, as described in 1.

The function generates a variable density Poisson-disc sampling mask with density proportional to \(1 / (1 + s |r|)\), where \(r\) represents the k-space radius, and \(s\) represents the slope. A binary search is performed on the slope \(s\) such that the resulting acceleration factor is close to the prescribed acceleration factor accel. The parameter tol determines how much they can deviate.

References

1

Bridson, Robert. “Fast Poisson disk sampling in arbitrary dimensions.” SIGGRAPH sketches. 2007

Note

Taken and adapted from: mikgroup/sigpy

centered_circle() numpy.ndarray[source]#

Creates a boolean centered circle image using the center_scale as a radius.

Returns

A 2D array of type bool, where True values indicate the points inside the centered circle and False values indicate the points outside the centered circle. The circle has its center at the center of the input shape and its radius is determined by the center_scale attribute.

Return type

np.ndarray

static generate_poisson_mask(nx: int, ny: int, max_attempts: int, radius_x: numpy.ndarray, radius_y: numpy.ndarray, calib: Tuple[float, float]) numpy.ndarray#

Generates a Poisson mask of shape (ny, nx) by placing points on the grid according to a Poisson distribution.

Parameters
  • nx (int) – The number of columns in the output mask.

  • ny (int) – The number of rows in the output mask.

  • max_attempts (int) – The maximum number of attempts to generate a mask with the desired acceleration factor.

  • radius_x (np.ndarray) – An array of shape (ny, nx) representing the radius of the Poisson distribution in the x-direction.

  • radius_y (np.ndarray) – An array of shape (ny, nx) representing the radius of the Poisson distribution in the y-direction.

  • calib (Tuple[float, float]) – Defines the size of the calibration region. The calibration region is a square region in the center of k-space. The first value defines the percentage of the center that is sampled. The second value defines the size of the calibration region in the center of k-space.

Returns

A binary mask with points placed according to a Poisson distribution.

Return type

np.ndarray

class atommic.collections.common.data.subsample.Random1DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#

Bases: MaskFunc

Random1DMaskFunc creates a sub-sampling mask of a given shape.

The mask selects a subset of columns from the input k-space data. If the k-space data has N columns, the mask picks out:

  1. N_low_freqs = (N * center_fraction) columns in the center corresponding to low-frequencies.

2. The other columns are selected uniformly at random with a probability equal to: prob = (N / acceleration - N_low_freqs) / (N - N_low_freqs). This ensures that the expected number of columns selected is equal to (N / acceleration).

It is possible to use multiple center_fractions and accelerations, in which case one possible (center_fraction, acceleration) is chosen uniformly at random each time the Random1DMaskFunc object is called.

For example, if accelerations = [4, 8] and center_fractions = [0.08, 0.04], then there is a 50% probability that 4-fold acceleration with 8% center fraction is selected and a 50% probability that 8-fold acceleration with 4% center fraction is selected.

atommic.collections.common.data.subsample.create_masker(mask_type_str: str, center_fractions: Union[Sequence[float], float], accelerations: Union[Sequence[int], int]) MaskFunc[source]#

Creates a MaskFunc object based on the specified mask type.

Parameters
  • mask_type_str (str) – The string representation of the mask type. Must be one of the following: ‘equispaced1d’, ‘equispaced2d’, ‘gaussian1d’, ‘gaussian2d’, ‘poisson2d’, ‘random1d’.

  • center_fractions (Sequence[float] or float) – The center fractions for the mask.

  • accelerations (Sequence[int] or int) – The accelerations for the mask.

Returns

A MaskFunc object that corresponds to the specified mask type.

Return type

MaskFunc

Raises

NotImplementedError – If the specified mask_type_str is not supported.

Examples

>>> from atommic.collections.common.data.subsample import create_masker
>>> create_masker("random1d", [0.5], [4])
Random1DMaskFunc([0.5], [4])
>>> create_masker("equispaced2d", [0.3, 0.7], [8, 6])
Equispaced2DMaskFunc([0.3, 0.7], [8, 6])
>>> create_masker("poisson2d", [0.3, 0.7], [8, 6])
Poisson2DMaskFunc([0.3, 0.7], [8, 6])
>>> create_masker("gaussian1d", [0.3, 0.7], [8, 6])
Gaussian1DMaskFunc([0.3, 0.7], [8, 6])
>>> create_masker("gaussian2d", [0.3, 0.7], [8, 6])
Gaussian2DMaskFunc([0.3, 0.7], [8, 6])