Common MRI Data Classes#
- class atommic.collections.common.data.mri_loader.MRIDataset(*args: Any, **kwargs: Any)[source]#
Bases:
DatasetA 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_slicesis > 1, then the array will have shape(self.consecutive_slices, *data[key].shape[1:]). Otherwise, the array will have shapedata[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:
objectMaskFunc 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)
- class atommic.collections.common.data.subsample.Equispaced1DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#
Bases:
MaskFuncEquispaced1DMaskFunc 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:
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:
MaskFuncSame 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:
MaskFuncSame 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
- class atommic.collections.common.data.subsample.Gaussian2DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#
Bases:
MaskFuncCreates 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
- class atommic.collections.common.data.subsample.Poisson2DMaskFunc(center_fractions: Sequence[float], accelerations: Sequence[int])[source]#
Bases:
MaskFuncGenerate 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:
MaskFuncRandom1DMaskFunc 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:
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
- 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])