Source code for dipy.stats.qc

import numpy as np

from dipy.core.geometry import cart_distance
from dipy.testing.decorators import warning_for_keywords


[docs] def find_qspace_neighbors(gtab): """Create a mapping of dwi volume index to its nearest neighbor. An approximate q-space is used (the deltas are not included). Note that neighborhood is not necessarily bijective. One neighbor is found per dwi volume. Parameters ---------- gtab: dipy.core.gradients.GradientTable Gradient table. Returns ------- neighbors: list of tuple A list of 2-tuples indicating the nearest q-space neighbor of each dwi volume. Examples -------- >>> from dipy.core.gradients import gradient_table >>> import numpy as np >>> gtab = gradient_table( ... np.array([0, 1000, 1000, 2000]), ... bvecs=np.array([ ... [1, 0, 0], ... [1, 0, 0], ... [0.99, 0.0001, 0.0001], ... [1, 0, 0]])) >>> find_qspace_neighbors(gtab) [(1, 2), (2, 1), (3, 1)] """ dwi_neighbors = [] # Only correlate the b>0 images dwi_mask = np.logical_not(gtab.b0s_mask) dwi_indices = np.flatnonzero(dwi_mask) # Get a pseudo-qspace value for b>0s qvecs = np.sqrt(gtab.bvals)[:, np.newaxis] * gtab.bvecs for dwi_index in dwi_indices: qvec = qvecs[dwi_index] # Calculate distance in q-space, accounting for symmetry pos_dist = cart_distance(qvec[np.newaxis, :], qvecs) neg_dist = cart_distance(qvec[np.newaxis, :], -qvecs) distances = np.min(np.column_stack([pos_dist, neg_dist]), axis=1) # Be sure we don't select the image as its own neighbor distances[dwi_index] = np.inf # Or a b=0 distances[gtab.b0s_mask] = np.inf neighbor_index = np.argmin(distances) dwi_neighbors.append((dwi_index, neighbor_index)) return dwi_neighbors
[docs] @warning_for_keywords() def neighboring_dwi_correlation(dwi_data, gtab, *, mask=None): """Calculate the Neighboring DWI Correlation (NDC) from dMRI data. Using a mask is highly recommended, otherwise the FOV will influence the correlations. According to :footcite:t:`Yeh2019`, an NDC less than 0.4 indicates a low quality image. Parameters ---------- dwi_data : 4D ndarray dwi data on which to calculate NDC gtab : dipy.core.gradients.GradientTable Gradient table. mask : 3D ndarray, optional Mask of voxels to include in the NDC calculation Returns ------- ndc : float The neighboring DWI correlation References ---------- .. footbibliography:: """ neighbor_indices = find_qspace_neighbors(gtab) neighbor_correlations = [] if mask is not None: binary_mask = mask > 0 for from_index, to_index in neighbor_indices: # Flatten the dwi images if mask is not None: flat_from_image = dwi_data[..., from_index][binary_mask] flat_to_image = dwi_data[..., to_index][binary_mask] else: flat_from_image = dwi_data[..., from_index].flatten() flat_to_image = dwi_data[..., to_index].flatten() neighbor_correlations.append(np.corrcoef(flat_from_image, flat_to_image)[0, 1]) return np.mean(neighbor_correlations)