folder='example_data') csv_file = path_to_visbrain_data(file='MIST_ROI.csv', folder='example_data') # Read the .csv file : arr = np.genfromtxt(csv_file, delimiter=';', dtype=str) # Get column names, labels and index : column_names = arr[0, :] arr = np.delete(arr, 0, 0) n_roi = arr.shape[0] roi_index = arr[:, 0].astype(int) roi_labels = arr[:, [1, 2]].astype(object) # Build the struct array : label = np.zeros(n_roi, dtype=[('label', object), ('name', object)]) label['label'] = roi_labels[:, 0] label['name'] = roi_labels[:, 1] # Get the volume and the hdr transformation : vol, _, hdr = read_nifti(nifti_file, hdr_as_array=True) # Define the ROI object and save it : roi_custom = RoiObj('custom_roi', vol=vol, labels=label, index=roi_index, hdr=hdr) # Find thalamus entries : idx_thalamus = roi_custom.where_is('THALAMUS') colors = {55: 'slateblue', 56: 'olive', 63: 'darkred', 64: '#ab4642'} roi_custom.select_roi(idx_thalamus, roi_to_color=colors) sc.add_to_subplot(roi_custom, row=1, col=2, zoom=.5, title='Plot dorsal and ventral thalamus with fixed colors') ############################################################################### # .. note:: # Once your RoiObj is defined, you can save it using # :class:`visbrain.objects.RoiObj.save`. Once the object is saved, you can # reload it using the name you've used (here we've used the `custom_roi`
nifti_file = path_to_visbrain_data('MIST_ROI.nii.gz') csv_file = path_to_visbrain_data('MIST_ROI.csv') # Read the .csv file : arr = np.genfromtxt(csv_file, delimiter=';', dtype=str) # Get column names, labels and index : column_names = arr[0, :] arr = np.delete(arr, 0, 0) n_roi = arr.shape[0] roi_index = arr[:, 0].astype(int) roi_labels = arr[:, [1, 2]].astype(object) # Build the struct array : label = np.zeros(n_roi, dtype=[('label', object), ('name', object)]) label['label'] = roi_labels[:, 0] label['name'] = roi_labels[:, 1] # Get the volume and the hdr transformation : vol, _, hdr = read_nifti(nifti_file, hdr_as_array=True) class TestRoiObj(_TestVolumeObject): """Test BrainObj.""" OBJ = roi_obj def test_definition(self): """Test function definition.""" for k in ['aal', 'talairach', 'brodmann']: RoiObj(k) def test_get_labels(self): """Test function get_labels.""" import pandas as pd
vb = Brain(s_xyz=s_xyz) # Print the list of volumes available : print('Volumes available by default : ', vb.volume_list()) """ If you don't have access to a Nifti file, download one of the volume available at https://brainder.org/download/flair/. """ path_to_nifti1 = os.getenv("HOME") # Path to the Nifti file file_nifti1 = 'GG-853-GM-0.7mm.nii.gz' # Name of the Nifti file path1 = os.path.join(path_to_nifti1, file_nifti1) """ Load the Nifti file. The read_nifti function load the data and the transformation to convert data into the MNI space : """ data1, header1, tf1 = read_nifti(path1) # print(header1) # Add the volume to the GUI : vb.add_volume('Volume1', data1, transform=tf1) print('Add Volume1 to the list of volumes : ', vb.volume_list()) # You can add multiple volumes : path_to_nifti2 = os.getenv("HOME") file_nifti2 = 'GG-853-WM-0.7mm.nii.gz' path2 = os.path.join(path_to_nifti2, file_nifti2) data2, header2, tf2 = read_nifti(path2) vb.add_volume('Volume2', data2, transform=tf2) print('Add Volume2 to the list of volumes : ', vb.volume_list()) # Set the cross-section to be centered on the last source :
def add_activation(self, data=None, vertices=None, smoothing_steps=5, file=None, hemisphere=None, hide_under=None, n_contours=None, cmap='viridis', clim=None, vmin=None, vmax=None, under='gray', over='red'): """Add activation to the brain template. This method can be used for : * Add activations to specific vertices (`data` and `vertices`) * Add an overlay (`file` input) Parameters ---------- data : array_like | None Vector array of data of shape (n_data,). vertices : array_like | None Vector array of vertex indices of shape (n_vtx). Must be an array of integers. If hemisphere is 'left' or 'right' indexation is done with respect to the specified hemisphere. smoothing_steps : int | 20 Number of smoothing steps (smoothing is used if n_data < n_vtx). If None or 0, no smoothing is performed. file : string | None Full path to the overlay file. Can either be a nii.gz or gii file. hemisphrere : {None, 'both', 'left', 'right'} The hemisphere to use to add the overlay. If None, the method tries to infer the hemisphere from the file name. hide_under : float | None Hide activations under a certain threshold. n_contours : int | None Display activations as contour. cmap : string | 'viridis' The colormap to use. clim : tuple | None The colorbar limits. If None, (data.min(), data.max()) will be used instead. vmin : float | None Minimum threshold. vmax : float | None Maximum threshold. under : string/tuple/array_like | 'gray' The color to use for values under vmin. over : string/tuple/array_like | 'red' The color to use for values over vmax. """ kw = self._update_cbar_args(cmap, clim, vmin, vmax, under, over) is_under = isinstance(hide_under, (int, float)) mask = np.zeros((len(self.mesh), ), dtype=bool) data_vec = np.zeros((len(self.mesh), ), dtype=np.float32) sm_data = np.zeros((len(self.mesh), ), dtype=np.float32) self._default_cblabel = "Activation" # ============================= METHOD ============================= if isinstance(data, np.ndarray): # Hemisphere : hemisphere, activ_vert = self._hemisphere_from_file( hemisphere, file) activ_vert_idx = np.where(activ_vert)[0] is_do_smoothing = True if vertices is None: # Data are defined on a dense grid assert len(activ_vert_idx) == len(data) vertices = np.arange(len(activ_vert_idx)) is_do_smoothing = False if smoothing_steps: logger.warning( 'Data defined on a dense grid; ignore smoothing.') else: assert len(vertices) == len(data) logger.info(" Add data to specific vertices.") assert (data.ndim == 1) and (np.asarray(vertices).ndim == 1) assert smoothing_steps is None or isinstance(smoothing_steps, int) # Get smoothed vertices // data : if hemisphere != 'both': # Transform to indexing with respect to the whole brain vert_whole = activ_vert_idx[vertices] else: vert_whole = vertices if smoothing_steps and is_do_smoothing: edges = mesh_edges(self.mesh._faces) sm_mat = smoothing_matrix(vert_whole, edges, smoothing_steps) sc = sm_mat * data # actual data smoothing if hemisphere != 'both': sc = sc[activ_vert] else: sc = np.zeros_like(sm_data[activ_vert]) sc[vertices] = data elif isinstance(file, str): assert os.path.isfile(file) if '.nii' in file: logger.info(" Add overlay from a NIFTI file") from visbrain.io import read_nifti # Load data using Nibabel : sc, _, _ = read_nifti(file) sc = sc.ravel(order="F") elif '.gii' in file: logger.info(" Add overlay from a GIFTI file") is_nibabel_installed(raise_error=True) import nibabel nib = nibabel.load(file) sc = nib.darrays[0].data.squeeze() hemisphere = 'both' if len(sc) == len(self.mesh) else hemisphere # Hemisphere : _, activ_vert = self._hemisphere_from_file(hemisphere, file) else: raise ValueError("Unknown activation type.") # Define the data to send to the vertices : logger.info(" Data scaled between (%.3f, " "%.3f)" % (sc.min(), sc.max())) sm_data[activ_vert] = sc data_vec[activ_vert] = self._data_to_contour(sc, clim, n_contours) mask[activ_vert] = True # Hide under : if is_under: mask[sm_data < hide_under] = False # Clim : clim = (sc.min(), sc.max()) if clim is None else clim assert len(clim) == 2 kw['clim'] = clim # Add overlay : self.mesh.add_overlay(data_vec[mask], vertices=np.where(mask)[0], **kw)
def add_activation(self, data=None, vertices=None, smoothing_steps=5, file=None, hemisphere=None, hide_under=None, n_contours=None, cmap='viridis', clim=None, vmin=None, vmax=None, under='gray', over='red'): """Add activation to the brain template. This method can be used for : * Add activations to specific vertices (`data` and `vertices`) * Add an overlay (`file` input) Parameters ---------- data : array_like | None Vector array of data of shape (n_data,). vertices : array_like | None Vector array of vertex indices of shape (n_vtx). Must be an array of integers. If hemisphere is 'left' or 'right' indexation is done with respect to the specified hemisphere. smoothing_steps : int | 20 Number of smoothing steps (smoothing is used if n_data < n_vtx). If None or 0, no smoothing is performed. file : string | None Full path to the overlay file. Can either be a nii.gz or gii file. hemisphrere : {None, 'both', 'left', 'right'} The hemisphere to use to add the overlay. If None, the method tries to infer the hemisphere from the file name. hide_under : float | None Hide activations under a certain threshold. n_contours : int | None Display activations as contour. cmap : string | 'viridis' The colormap to use. clim : tuple | None The colorbar limits. If None, (data.min(), data.max()) will be used instead. vmin : float | None Minimum threshold. vmax : float | None Maximum threshold. under : string/tuple/array_like | 'gray' The color to use for values under vmin. over : string/tuple/array_like | 'red' The color to use for values over vmax. """ kw = self._update_cbar_args(cmap, clim, vmin, vmax, under, over) is_under = isinstance(hide_under, (int, float)) mask = np.zeros((len(self.mesh),), dtype=bool) data_vec = np.zeros((len(self.mesh),), dtype=np.float32) sm_data = np.zeros((len(self.mesh),), dtype=np.float32) self._default_cblabel = "Activation" # ============================= METHOD ============================= if isinstance(data, np.ndarray): # Hemisphere : hemisphere, activ_vert = self._hemisphere_from_file(hemisphere, file) activ_vert_idx = np.where(activ_vert)[0] is_do_smoothing = True if vertices is None: # Data are defined on a dense grid assert len(activ_vert_idx) == len(data) vertices = np.arange(len(activ_vert_idx)) is_do_smoothing = False if smoothing_steps: logger.warning( 'Data defined on a dense grid; ignore smoothing.') else: assert len(vertices) == len(data) logger.info(" Add data to specific vertices.") assert (data.ndim == 1) and (np.asarray(vertices).ndim == 1) assert smoothing_steps is None or isinstance(smoothing_steps, int) # Get smoothed vertices // data : if hemisphere != 'both': # Transform to indexing with respect to the whole brain vert_whole = activ_vert_idx[vertices] else: vert_whole = vertices if smoothing_steps and is_do_smoothing: edges = mesh_edges(self.mesh._faces) sm_mat = smoothing_matrix(vert_whole, edges, smoothing_steps) sc = sm_mat * data # actual data smoothing if hemisphere != 'both': sc = sc[activ_vert] else: sc = np.zeros_like(sm_data[activ_vert]) sc[vertices] = data elif isinstance(file, str): assert os.path.isfile(file) if '.nii' in file: logger.info(" Add overlay from a NIFTI file") from visbrain.io import read_nifti # Load data using Nibabel : sc, _, _ = read_nifti(file) sc = sc.ravel(order="F") elif '.gii' in file: logger.info(" Add overlay from a GIFTI file") is_nibabel_installed(raise_error=True) import nibabel nib = nibabel.load(file) sc = nib.darrays[0].data.squeeze() hemisphere = 'both' if len(sc) == len(self.mesh) else hemisphere # Hemisphere : _, activ_vert = self._hemisphere_from_file(hemisphere, file) else: raise ValueError("Unknown activation type.") # Define the data to send to the vertices : logger.info(" Data scaled between (%.3f, " "%.3f)" % (sc.min(), sc.max())) sm_data[activ_vert] = sc data_vec[activ_vert] = self._data_to_contour(sc, clim, n_contours) mask[activ_vert] = True # Hide under : if is_under: mask[sm_data < hide_under] = False # Clim : clim = (sc.min(), sc.max()) if clim is None else clim assert len(clim) == 2 kw['clim'] = clim # Add overlay : self.mesh.add_overlay(data_vec[mask], vertices=np.where(mask)[0], **kw)
Control the cross-section panel and the volume. This script use a custom nifti volume downloadable at : https://brainder.org/download/flair/ The nibabel package should also be installed. .. image:: ../../picture/picbrain/ex_crossec_and_volume.png """ import os from visbrain import Brain from visbrain.io import read_nifti """Import the volume and the associated affine transformation """ volume_name = 'GG-853-WM-0.7mm' path_to_nifti = os.getenv("HOME") file_nifti = 'GG-853-WM-0.7mm.nii.gz' path = os.path.join(path_to_nifti, file_nifti) data, header, tf = read_nifti(path) vb = Brain() # Add the volume to the GUI vb.add_volume(volume_name, data, transform=tf) """Set the cross-section to be centered on the slice (70, 171, 80) with the gist_stern colormap. """ vb.cross_sections_control(center=(70, 171, 80), volume=volume_name, cmap='gist_stern') """Display the 3D volume using the translucent rendering method. """ vb.volume_control(volume_name, cmap='TransFire', rendering='translucent') """Finally, rotate the scene and hide the main brain.