IQMs for diffusion images

Image quality metrics for diffusion MRI data

IQMs relating to spatial information

Definitions are given in the summary of structural IQMs.

  • Entropy-focus criterion (efc()).

  • Signal-to-noise ratio (snr()).

IQMs relating to diffusion weighting

IQMs specific to diffusion weighted imaging.

Noise in raw dMRI estimated with PIESNO (piesno_sigma)

Employs PIESNO (Probabilistic Identification and Estimation of Noise) algorithm [Koay2009] to estimate the standard deviation (sigma) of the noise in each voxel of a 4D dMRI data array.

SNR estimated in the Corpus Callosum (cc_snr)

Worst-case and best-case signal-to-noise ratio (SNR) within the corpus callosum.

Number of not-a-number (NaN) values in the FA map (fa_nan)

Fraction of NaNs within the brain mask, in ppm.

Number of degenerate modeled voxels in the FA map (fa_degenerate)

Fraction of invalid FA values (i.e., outside the [0, 1] closed range) within the brain mask, in ppm.

IQMs relating artifacts and other

IQMs targeting artifacts that are specific of DWI images.

Global and slice-wise spike fractions (spikes_ppm)

Fractions of voxels classified as spikes (in parts-per-million, ppm). The spikes mask is calculated by identifying voxels with signal intensities exceeding a threshold based on standard deviations above the mean.

References

[Koay2009]

Koay C.G., E. Ozarslan, C. Pierpaoli. Probabilistic Identification and Estimation of Noise (PIESNO): A self-consistent approach and its applications in MRI. JMR, 199(1):94-103, 2009.

mriqc.qc.diffusion.cc_snr(in_b0: ndarray, dwi_shells: list[numpy.ndarray], cc_mask: ndarray, b_values: ndarray, b_vectors: ndarray, bval_thres: int = 50, decimals: int = 2) dict[int, (<class 'float'>, <class 'float'>)][source]

Calculates the worst-case and best-case signal-to-noise ratio (SNR) within the corpus callosum.

This function estimates the SNR in the corpus callosum (CC) by comparing the mean signal intensity within the CC mask to the standard deviation of the background signal (extracted from the b0 image). It performs separate calculations for each diffusion-weighted imaging (DWI) shell.

Worst-case SNR: The mean signal intensity along the diffusion direction with the lowest signal is considered the worst-case scenario.

Best-case SNR: The mean signal intensity averaged across the two diffusion directions with the highest signal is considered the best-case scenario.

Parameters:
  • in_b0 (ndarray (float, 3D)) – T1-weighted or b0 image used for background signal estimation.

  • dwi_shells (list[ndarray (float, 4D)]) – List of DWI data for each diffusion shell.

  • cc_mask (ndarray (bool, 3D)) – Boolean mask of the corpus callosum.

  • b_values (ndarray (int)) – Array of b-values for each DWI volume in dwi_shells.

  • b_vectors (ndarray (float)) – Array of diffusion-encoding vectors for each DWI volume in dwi_shells.

Returns:

cc_snr_estimates – Dictionary containing SNR estimates for each b-value. Keys are the b-values (integers), and values are tuples containing two elements:

  • The first element is the worst-case SNR (float).

  • The second element is the best-case SNR (float).

Return type:

dict

mriqc.qc.diffusion.neighboring_dwi_correlation(dwi_data: np.ndarray, neighbor_indices: list[tuple[int, int]], mask: np.ndarray | None = None, decimals: int = 4) float[source]

Calculates the Neighboring DWI Correlation (NDC) from diffusion MRI (dMRI) data.

The NDC is a measure of the correlation between signal intensities in neighboring diffusion-weighted images (DWIs) within a mask. A low NDC (typically below 0.4) can indicate poor image quality, according to Yeh et al. [Yeh2019].

Parameters:
  • dwi_data (4D ndarray) – DWI data on which to calculate NDC

  • neighbor_indices (list of tuple) – List of (from, to) index neighbors.

  • mask (3D ndarray, optional) – optional mask of voxels to include in the NDC calculation

Returns:

The NDC value.

Return type:

float

References

[Yeh2019]

Yeh, Fang-Cheng, et al. “Differential tractography as a track-based biomarker for neuronal injury.” NeuroImage 202 (2019): 116131.

Notes

This is a copy of DIPY’s code to be removed (and just imported) as soon as a new release of DIPY is cut including dipy/dipy#3156.

mriqc.qc.diffusion.noise_b0(in_b0: np.ndarray, percentiles: tuple[float, float, float] = (25.0, 50.0, 75.0), mask: np.ndarray | None = None) dict[str, float][source]

Estimates noise levels in raw dMRI data using the variance of the $b$=0 volumes.

This function calculates the variance of the $b$=0 volumes in a 4D dMRI array within a provided mask. It then computes the noise estimates at specified percentiles of the variance distribution. This approach assumes that noise primarily contributes to the lower end of the variance distribution.

Parameters:
  • in_b0 (ndarray) – The 3D or 4D dMRI data array. If 4D, the first volume (assumed to be the $b$=0 image) is used for noise estimation.

  • percentiles (tuple (float, float, float), optional (default=(25, 50, 75))) – A tuple of three integers specifying the percentiles of the variance distribution to use for noise estimation. These percentiles represent different noise levels within the data.

  • mask (ndarray, optional (default=``None``)) – A boolean mask used to restrict the noise estimation to specific brain regions. If None, a mask of ones with the same shape as the first 3 dimensions of in_b0 is used.

Returns:

A dictionary containing the noise estimates at the specified percentiles:

  • keys: str - Percentile values (e.g., ‘25’, ‘50’, ‘75’).

  • values: float - Noise level estimates at the corresponding percentiles.

Return type:

dict

mriqc.qc.diffusion.spike_ppm(spike_mask: np.ndarray, slice_threshold: float = 0.05, decimals: int = 2) dict[str, float | np.ndarray][source]

Calculates fractions (global and slice-wise) of voxels classified as spikes in ppm.

This function computes two metrics:

  • Global spike parts-per-million [ppm]: Fraction of voxels exceeding the spike threshold across the entire data array.

  • Slice-wise spiking [ppm]: The fraction of slices along each dimension of the data array where the average fraction of spiking voxels within the slice exceeds a user-defined threshold (slice_threshold).

Parameters:
  • spike_mask (ndarray (bool, same shape as data)) – The binary mask indicating spike voxels (True) and non-spike voxels (False).

  • slice_threshold (float, optional (default=0.05)) – The minimum fraction of voxels in a slice that must be classified as spikes for the slice to be considered spiking.

  • decimals (int) – The number of decimals to round the fractions.

Returns:

A dictionary containing the calculated spike percentages:

  • ’global’: float - global spiking voxels ppm.

  • ’slice_{i,j,k,t}’: float - Slice-wise spiking voxel fractions in ppm for each dimension of the data array.

Return type:

dict