def warp_coords_dipy(warp_file, coords_file): import os from builtins import str import numpy as np from nipype.utils.filemanip import fname_presuffix import dipy.align.vector_fields as vfu import nibabel as nb coords = np.loadtxt(coords_file, delimiter=',', dtype=np.float) coords[:, :2] = -coords[:, :2] # flip as the atlas is in itk convention warp = np.load(warp_file) backward = warp['backward'] prealign = warp['prealign'] postalign = np.linalg.inv(prealign) shift = vfu.interpolate_vector_3d(backward, coords[:, :3])[0] coords[:, :3] += shift coords[:, :3] = nb.affines.apply_affine(postalign, coords[:, :3]) out_fname = os.path.abspath( fname_presuffix(coords_file, newpath='./', suffix='_warped', use_ext=True)) np.savetxt(out_fname, coords, fmt='%f,' * 3 + '%d,' * 3 + '%d') return out_fname
def warp_coords_dipy(warp_file, coords_file): import os from builtins import str import numpy as np from nipype.utils.filemanip import fname_presuffix import dipy.align.vector_fields as vfu import nibabel as nb coords = np.loadtxt(coords_file, delimiter=',', dtype=np.float) coords[:,:2] = -coords[:,:2] # flip as the atlas is in itk convention warp = np.load(warp_file) backward = warp['backward'] prealign = warp['prealign'] postalign = np.linalg.inv(prealign) shift = vfu.interpolate_vector_3d(backward, coords[:,:3])[0] coords[:,:3] += shift coords[:,:3] = nb.affines.apply_affine(postalign, coords[:,:3]) out_fname = os.path.abspath(fname_presuffix(coords_file, newpath='./', suffix='_warped', use_ext=True)) np.savetxt(out_fname, coords, fmt='%f,'*3+'%d,'*3+'%d') return out_fname
def _extract_vals(data, streamlines, affine=None, threedvec=False): """ Helper function for use with `values_from_volume`. Parameters ---------- data : 3D or 4D array Scalar (for 3D) and vector (for 4D) values to be extracted. For 4D data, interpolation will be done on the 3 spatial dimensions in each volume. streamlines : ndarray or list If array, of shape (n_streamlines, n_nodes, 3) If list, len(n_streamlines) with (n_nodes, 3) array in each element of the list. affine : ndarray, shape (4, 4) Affine transformation from voxels (image coordinates) to streamlines. Default: identity. threedvec : bool Whether the last dimension has length 3. This is a special case in which we can use :func:`vfu.interpolate_vector_3d` for the interploation of 4D volumes without looping over the elements of the last dimension. Return ------ array or list (depending on the input) : values interpolate to each coordinate along the length of each streamline """ data = data.astype(np.float) if (isinstance(streamlines, list) or isinstance(streamlines, types.GeneratorType)): if affine is not None: streamlines = ut.move_streamlines(streamlines, np.linalg.inv(affine)) vals = [] for sl in streamlines: if threedvec: vals.append( list( vfu.interpolate_vector_3d(data, sl.astype(np.float))[0])) else: vals.append( list( vfu.interpolate_scalar_3d(data, sl.astype(np.float))[0])) elif isinstance(streamlines, np.ndarray): sl_shape = streamlines.shape sl_cat = streamlines.reshape(sl_shape[0] * sl_shape[1], 3).astype(np.float) if affine is not None: inv_affine = np.linalg.inv(affine) sl_cat = (np.dot(sl_cat, inv_affine[:3, :3]) + inv_affine[:3, 3]) # So that we can index in one operation: if threedvec: vals = np.array(vfu.interpolate_vector_3d(data, sl_cat)[0]) else: vals = np.array(vfu.interpolate_scalar_3d(data, sl_cat)[0]) vals = np.reshape(vals, (sl_shape[0], sl_shape[1], -1)) if vals.shape[-1] == 1: vals = np.reshape(vals, vals.shape[:-1]) else: raise RuntimeError("Extracting values from a volume ", "requires streamlines input as an array, ", "a list of arrays, or a streamline generator.") return vals
def _extract_vals(data, streamlines, affine=None, threedvec=False): """ Helper function for use with `values_from_volume`. Parameters ---------- data : 3D or 4D array Scalar (for 3D) and vector (for 4D) values to be extracted. For 4D data, interpolation will be done on the 3 spatial dimensions in each volume. streamlines : ndarray or list If array, of shape (n_streamlines, n_nodes, 3) If list, len(n_streamlines) with (n_nodes, 3) array in each element of the list. affine : ndarray, shape (4, 4) Affine transformation from voxels (image coordinates) to streamlines. Default: identity. threedvec : bool Whether the last dimension has length 3. This is a special case in which we can use :func:`vfu.interpolate_vector_3d` for the interploation of 4D volumes without looping over the elements of the last dimension. Return ------ array or list (depending on the input) : values interpolate to each coordinate along the length of each streamline """ data = data.astype(np.float) if (isinstance(streamlines, list) or isinstance(streamlines, types.GeneratorType)): if affine is not None: streamlines = ut.move_streamlines(streamlines, np.linalg.inv(affine)) vals = [] for sl in streamlines: if threedvec: vals.append(list(vfu.interpolate_vector_3d(data, sl.astype(np.float))[0])) else: vals.append(list(vfu.interpolate_scalar_3d(data, sl.astype(np.float))[0])) elif isinstance(streamlines, np.ndarray): sl_shape = streamlines.shape sl_cat = streamlines.reshape(sl_shape[0] * sl_shape[1], 3).astype(np.float) if affine is not None: inv_affine = np.linalg.inv(affine) sl_cat = (np.dot(sl_cat, inv_affine[:3, :3]) + inv_affine[:3, 3]) # So that we can index in one operation: if threedvec: vals = np.array(vfu.interpolate_vector_3d(data, sl_cat)[0]) else: vals = np.array(vfu.interpolate_scalar_3d(data, sl_cat)[0]) vals = np.reshape(vals, (sl_shape[0], sl_shape[1], -1)) if vals.shape[-1] == 1: vals = np.reshape(vals, vals.shape[:-1]) else: raise RuntimeError("Extracting values from a volume ", "requires streamlines input as an array, ", "a list of arrays, or a streamline generator.") return vals