def display_extent(self, x1, x2, y1, y2, z1, z2): tmp_mask = np.zeros(grid_shape, dtype=np.bool) tmp_mask[x1:x2 + 1, y1:y2 + 1, z1:z2 + 1] = True tmp_mask = np.bitwise_and(tmp_mask, mask) ijk = np.ascontiguousarray(np.array(np.nonzero(tmp_mask)).T) if len(ijk) == 0: self.SetMapper(None) return if affine is not None: ijk_trans = np.ascontiguousarray(apply_affine(affine, ijk)) list_dirs = [] for index, center in enumerate(ijk): # center = tuple(center) if affine is None: xyz = center[:, None] else: xyz = ijk_trans[index][:, None] xyz = xyz.T for i in range(peaks_dirs[tuple(center)].shape[-2]): if peaks_values is not None: pv = peaks_values[tuple(center)][i] else: pv = 1. symm = np.vstack((-peaks_dirs[tuple(center)][i] * pv + xyz, peaks_dirs[tuple(center)][i] * pv + xyz)) list_dirs.append(symm) self.mapper = line(list_dirs, colors=colors, opacity=opacity, linewidth=linewidth, lod=lod, lod_points=lod_points, lod_points_size=lod_points_size).GetMapper() self.SetMapper(self.mapper)
def __init__(self, odfs, vertices, faces, indices, scale, norm, radial_scale, shape, global_cm, colormap, opacity, affine=None, B=None): self.vertices = vertices self.faces = faces self.odfs = odfs self.indices = indices self.B = B self.radial_scale = radial_scale self.colormap = colormap self.grid_shape = shape self.global_cm = global_cm # declare a mask to be instantiated in slice_along_axis self.mask = None # If a B matrix is given, odfs are expected to # be in SH basis coefficients. if self.B is not None: # In that case, we need to save our normalisation and scale # to apply them after conversion from SH to SF. self.norm = norm self.scale = scale else: # If our input is in SF coefficients, we can normalise and # scale it only once, here. if norm: self.odfs /= np.abs(self.odfs).max(axis=-1, keepdims=True) self.odfs *= scale # Compute world coordinates of an affine is supplied self.affine = affine if self.affine is not None: self.w_verts = self.vertices.dot(affine[:3, :3]) self.w_pos = apply_affine(affine, np.asarray(self.indices).T) # Initialize mapper and slice to the # middle of the volume along Z axis self.mapper = PolyDataMapper() self.SetMapper(self.mapper) self.slice_along_axis(self.grid_shape[-1] // 2) self.set_opacity(opacity)
def __init__(self, directions, indices, values=None, affine=None, colors=None, lookup_colormap=None, linewidth=1): if affine is not None: w_pos = apply_affine(affine, np.asarray(indices).T) valid_dirs = directions[indices] num_dirs = len(np.nonzero(np.abs(valid_dirs).max(axis=-1) > 0)[0]) pnts_per_line = 2 points_array = np.empty((num_dirs * pnts_per_line, 3)) centers_array = np.empty_like(points_array, dtype=int) diffs_array = np.empty_like(points_array) line_count = 0 for idx, center in enumerate(zip(indices[0], indices[1], indices[2])): if affine is None: xyz = np.asarray(center) else: xyz = w_pos[idx, :] valid_peaks = np.nonzero( np.abs(valid_dirs[idx, :, :]).max(axis=-1) > 0.)[0] for direction in valid_peaks: if values is not None: pv = values[center][direction] else: pv = 1. point_i = directions[center][direction] * pv + xyz point_e = -directions[center][direction] * pv + xyz diff = point_e - point_i points_array[line_count * pnts_per_line, :] = point_e points_array[line_count * pnts_per_line + 1, :] = point_i centers_array[line_count * pnts_per_line, :] = center centers_array[line_count * pnts_per_line + 1, :] = center diffs_array[line_count * pnts_per_line, :] = diff diffs_array[line_count * pnts_per_line + 1, :] = diff line_count += 1 vtk_points = numpy_to_vtk_points(points_array) vtk_cells = _points_to_vtk_cells(points_array) colors_tuple = _peaks_colors_from_points(points_array, colors=colors) vtk_colors, colors_are_scalars, self.__global_opacity = colors_tuple poly_data = vtk.vtkPolyData() poly_data.SetPoints(vtk_points) poly_data.SetLines(vtk_cells) poly_data.GetPointData().SetScalars(vtk_colors) self.__mapper = vtk.vtkPolyDataMapper() self.__mapper.SetInputData(poly_data) self.__mapper.ScalarVisibilityOn() self.__mapper.SetScalarModeToUsePointFieldData() self.__mapper.SelectColorArray('colors') self.__mapper.Update() self.SetMapper(self.__mapper) attribute_to_actor(self, centers_array, 'center') attribute_to_actor(self, diffs_array, 'diff') vs_dec_code = load('peak_dec.vert') vs_impl_code = load('peak_impl.vert') fs_dec_code = load('peak_dec.frag') fs_impl_code = load('peak_impl.frag') shader_to_actor(self, 'vertex', decl_code=vs_dec_code, impl_code=vs_impl_code) shader_to_actor(self, 'fragment', decl_code=fs_dec_code) shader_to_actor(self, 'fragment', impl_code=fs_impl_code, block='light') # Color scale with a lookup table if colors_are_scalars: if lookup_colormap is None: lookup_colormap = colormap_lookup_table() self.__mapper.SetLookupTable(lookup_colormap) self.__mapper.UseLookupTableScalarRangeOn() self.__mapper.Update() self.__lw = linewidth self.GetProperty().SetLineWidth(self.__lw) if self.__global_opacity >= 0: self.GetProperty().SetOpacity(self.__global_opacity) self.__min_centers = np.min(indices, axis=1) self.__max_centers = np.max(indices, axis=1) self.__is_range = True self.__low_ranges = self.__min_centers self.__high_ranges = self.__max_centers self.__cross_section = self.__high_ranges // 2 self.__mapper.AddObserver(vtk.vtkCommand.UpdateShaderEvent, self.__display_peaks_vtk_callback)
def _tensor_slicer_mapper(evals, evecs, affine=None, mask=None, sphere=None, scale=2.2, norm=True, opacity=1., scalar_colors=None): """Helper function for slicing tensor fields Parameters ---------- evals : (3,) or (X, 3) or (X, Y, 3) or (X, Y, Z, 3) ndarray eigenvalues evecs : (3, 3) or (X, 3, 3) or (X, Y, 3, 3) or (X, Y, Z, 3, 3) ndarray eigenvectors affine : array 4x4 transformation array from native coordinates to world coordinates mask : ndarray 3D mask sphere : Sphere a sphere scale : float Distance between spheres. norm : bool Normalize `sphere_values`. opacity : float Takes values from 0 (fully transparent) to 1 (opaque) scalar_colors : (3,) or (X, 3) or (X, Y, 3) or (X, Y, Z, 3) ndarray RGB colors used to show the tensors Default None, color the ellipsoids using ``color_fa`` Returns --------- mapper : vtkPolyDataMapper Ellipsoid mapper """ if mask is None: mask = np.ones(evals.shape[:3]) ijk = np.ascontiguousarray(np.array(np.nonzero(mask)).T) if len(ijk) == 0: return None if affine is not None: ijk = np.ascontiguousarray(apply_affine(affine, ijk)) faces = np.asarray(sphere.faces, dtype=int) vertices = sphere.vertices if scalar_colors is None: from dipy.reconst.dti import color_fa, fractional_anisotropy cfa = color_fa(fractional_anisotropy(evals), evecs) else: cfa = _makeNd(scalar_colors, 4) cols = np.zeros((ijk.shape[0], ) + sphere.vertices.shape, dtype='f4') all_xyz = [] all_faces = [] for (k, center) in enumerate(ijk): ea = evals[tuple(center.astype(np.int))] if norm: ea /= ea.max() ea = np.diag(ea.copy()) ev = evecs[tuple(center.astype(np.int))].copy() xyz = np.dot(ev, np.dot(ea, vertices.T)) xyz = xyz.T all_xyz.append(scale * xyz + center) all_faces.append(faces + k * xyz.shape[0]) cols[k, ...] = np.interp(cfa[tuple(center.astype(np.int))], [0, 1], [0, 255]).astype('ubyte') all_xyz = np.ascontiguousarray(np.concatenate(all_xyz)) all_xyz_vtk = numpy_support.numpy_to_vtk(all_xyz, deep=True) all_faces = np.concatenate(all_faces) all_faces = np.hstack((3 * np.ones((len(all_faces), 1)), all_faces)) ncells = len(all_faces) all_faces = np.ascontiguousarray(all_faces.ravel(), dtype='i8') all_faces_vtk = numpy_support.numpy_to_vtkIdTypeArray(all_faces, deep=True) points = vtk.vtkPoints() points.SetData(all_xyz_vtk) cells = vtk.vtkCellArray() cells.SetCells(ncells, all_faces_vtk) cols = np.ascontiguousarray(np.reshape( cols, (cols.shape[0] * cols.shape[1], cols.shape[2])), dtype='f4') vtk_colors = numpy_support.numpy_to_vtk(cols, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) vtk_colors.SetName("Colors") polydata = vtk.vtkPolyData() polydata.SetPoints(points) polydata.SetPolys(cells) polydata.GetPointData().SetScalars(vtk_colors) mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(polydata) return mapper
def _odf_slicer_mapper(odfs, affine=None, mask=None, sphere=None, scale=2.2, norm=True, radial_scale=True, opacity=1., colormap='plasma', global_cm=False): """ Helper function for slicing spherical fields Parameters ---------- odfs : ndarray 4D array of spherical functions affine : array 4x4 transformation array from native coordinates to world coordinates mask : ndarray 3D mask sphere : Sphere a sphere scale : float Distance between spheres. norm : bool Normalize `sphere_values`. radial_scale : bool Scale sphere points according to odf values. opacity : float Takes values from 0 (fully transparent) to 1 (opaque) colormap : None or str If None then white color is used. Otherwise the name of colormap is given. Matplotlib colormaps are supported (e.g., 'inferno'). global_cm : bool If True the colormap will be applied in all ODFs. If False it will be applied individually at each voxel (default False). Returns --------- mapper : vtkPolyDataMapper Spheres mapper """ if mask is None: mask = np.ones(odfs.shape[:3]) ijk = np.ascontiguousarray(np.array(np.nonzero(mask)).T) if len(ijk) == 0: return None if affine is not None: ijk = np.ascontiguousarray(apply_affine(affine, ijk)) faces = np.asarray(sphere.faces, dtype=int) vertices = sphere.vertices all_xyz = [] all_faces = [] all_ms = [] for (k, center) in enumerate(ijk): m = odfs[tuple(center.astype(np.int))].copy() if norm: m /= np.abs(m).max() if radial_scale: xyz = vertices * m[:, None] else: xyz = vertices.copy() all_xyz.append(scale * xyz + center) all_faces.append(faces + k * xyz.shape[0]) all_ms.append(m) all_xyz = np.ascontiguousarray(np.concatenate(all_xyz)) all_xyz_vtk = numpy_support.numpy_to_vtk(all_xyz, deep=True) all_faces = np.concatenate(all_faces) all_faces = np.hstack((3 * np.ones((len(all_faces), 1)), all_faces)) ncells = len(all_faces) all_faces = np.ascontiguousarray(all_faces.ravel(), dtype='i8') all_faces_vtk = numpy_support.numpy_to_vtkIdTypeArray(all_faces, deep=True) if global_cm: all_ms = np.ascontiguousarray(np.concatenate(all_ms), dtype='f4') points = vtk.vtkPoints() points.SetData(all_xyz_vtk) cells = vtk.vtkCellArray() cells.SetCells(ncells, all_faces_vtk) if colormap is not None: if global_cm: cols = create_colormap(all_ms.ravel(), colormap) else: cols = np.zeros((ijk.shape[0], ) + sphere.vertices.shape, dtype='f4') for k in range(ijk.shape[0]): tmp = create_colormap(all_ms[k].ravel(), colormap) cols[k] = tmp.copy() cols = np.ascontiguousarray(np.reshape( cols, (cols.shape[0] * cols.shape[1], cols.shape[2])), dtype='f4') vtk_colors = numpy_support.numpy_to_vtk( np.asarray(255 * cols), deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) vtk_colors.SetName("Colors") polydata = vtk.vtkPolyData() polydata.SetPoints(points) polydata.SetPolys(cells) if colormap is not None: polydata.GetPointData().SetScalars(vtk_colors) mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(polydata) return mapper