def find_activation(map, mask=None, pvalue=0.05, upper_only=False): """ Use the empirical normal null estimator to find threshold for negative and positive activation. Parameters ---------- map : 3D ndarray The activation map, as a 3D image. mask : 3D ndarray, boolean, optional The brain mask. If None, the mask is computed from the map. pvalue : float, optional The pvalue of the false discovery rate used. upper_only : boolean, optional If true, only a threshold for positive activation is estimated. Returns ------- vmin : float, optional The upper threshold for negative activation, not returned if upper_only is True. vmax : float The lower threshod for positive activation. """ if mask is None: mask = compute_mask(map) map = map[mask] vmax = ENN(map).threshold(alpha=pvalue) if upper_only: return vmax vmin = -ENN(-map).threshold(alpha=pvalue) return vmin, vmax
def plot_niftifile(filename, outputname=None, do3d=False, vmin=None, cut_coords=None, anat_filename=None, figure_num=None, mask_filename=None, auto_sign=True): """ Given a nifti filename, plot a view of it to a file (png by default). Parameters ---------- filename : string The name of the Nifti file of the map to be plotted outputname : string, optional The file name of the output file created. By default the name of the input file with a png extension is used. do3d : boolean, optional If do3d is True, a 3D plot is created if Mayavi is installed. vmin : float, optional The lower threshold of the positive activation. This parameter is used to threshold the activation map. cut_coords: 3-tuple of floats, optional The MNI coordinates of the point where the cut is performed, in MNI coordinates and order. If None is given, the cut_coords are automaticaly estimated. anat : string, optional Name of the Nifti image file to be used as a background. If None, the MNI152 T1 1mm template is used. title : string, optional The title dispayed on the figure. figure_num : integer, optional The number of the matplotlib and Mayavi figures used. If None is given, a new figure is created. mask_filename : string, optional Name of the Nifti file to be used as brain mask. If None, the mask is computed from the map. auto_sign : boolean, optional If auto_sign is True, the sign of the activation is automaticaly computed: negative activation can thus be plotted. Notes ----- Cut coordinates are in Talairach coordinates. Warning: Talairach coordinates are (y, x, z), if (x, y, z) are in voxel-ordering convention. """ if outputname is None: outputname = os.path.splitext(filename)[0] + '.png' if not os.path.exists(filename): raise OSError, 'File %s does not exist' % filename nim = load(filename) sform = nim.get_affine() if any(np.linalg.eigvals(sform)==0): raise SformError, "sform affine is not inversible" if anat_filename is not None: anat_im = load(anat_filename) anat = anat_im.data anat_sform = anat_im.get_affine() else: anat = None anat_sform = None if mask_filename is not None: mask_im = load(mask_filename) mask = mask_im.data.astype(np.bool) if not np.allclose(mask_im.get_affine(), sform): raise SformError, 'Mask does not have same sform as image' if not np.allclose(mask.shape, nim.data.shape[:3]): raise NiftiIndexError, 'Mask does not have same shape as image' else: mask = None output_files = list() if nim.data.ndim == 3: map = nim.data.T auto_plot_map(map, sform, vmin=vmin, cut_coords=cut_coords, do3d=do3d, anat=anat, anat_sform=anat_sform, mask=mask, title=os.path.basename(filename), figure_num=figure_num, auto_sign=auto_sign) pl.savefig(outputname) output_files.append(outputname) elif nim.data.ndim == 4: outputname, outputext = os.path.splitext(outputname) if len(nim.data) < 10: fmt = '%s_%i%s' elif len(nim.data) < 100: fmt = '%s_%02i%s' elif len(nim.data) < 1000: fmt = '%s_%03i%s' else: fmt = '%s_%04i%s' if mask is None: mask = compute_mask(nim.data.mean(axis=0)).T for index, data in enumerate(nim.data): map = data.T auto_plot_map(map, sform, vmin=vmin, cut_coords=cut_coords, do3d=do3d, anat=anat, anat_sform=anat_sform, title='%s, %i' % (os.path.basename(filename), index), figure_num=figure_num, mask=mask, auto_sign=auto_sign) this_outputname = fmt % (outputname, index, outputext) pl.savefig(this_outputname) pl.clf() output_files.append(this_outputname) else: raise NiftiIndexError, 'File %s: incorrect number of dimensions' return output_files
def auto_plot_map(map, sform, vmin=None, cut_coords=None, do3d=False, anat=None, anat_sform=None, title='', figure_num=None, mask=None, auto_sign=True): """ Automatic plotting of an activation map. Plot a together a 3D volume rendering view of the activation, with an outline of the brain, and 2D cuts. If Mayavi is not installed, falls back to 2D views only. Parameters ---------- map : 3D ndarray The activation map, as a 3D image. sform : 4x4 ndarray The affine matrix going from image voxel space to MNI space. vmin : float, optional The lower threshold of the positive activation. This parameter is used to threshold the activation map. cut_coords: 3-tuple of floats, optional The MNI coordinates of the point where the cut is performed, in MNI coordinates and order. If None is given, the cut_coords are automaticaly estimated. do3d : boolean, optional If do3d is True, a 3D plot is created if Mayavi is installed. anat : 3D ndarray, optional The anatomical image to be used as a background. If None, the MNI152 T1 1mm template is used. anat_sform : 4x4 ndarray, optional The affine matrix going from the anatomical image voxel space to MNI space. This parameter is not used when the default anatomical is used, but it is compulsory when using an explicite anatomical image. title : string, optional The title dispayed on the figure. figure_num : integer, optional The number of the matplotlib and Mayavi figures used. If None is given, a new figure is created. mask : 3D ndarray, boolean, optional The brain mask. If None, the mask is computed from the map. auto_sign : boolean, optional If auto_sign is True, the sign of the activation is automaticaly computed: negative activation can thus be plotted. Returns ------- vmin : float The lower threshold of the activation used. cut_coords : 3-tuple of floats The Talairach coordinates of the cut performed for the 2D view. Notes ----- All the 3D arrays are in numpy convention: (x, y, z) Cut coordinates are in Talairach coordinates. Warning: Talairach coordinates are (y, x, z), if (x, y, z) are in voxel-ordering convention. """ if do3d: if do3d == 'offscreen': try: from enthought.mayavi import mlab mlab.options.offscreen = True except: pass plotter = plot_map else: plotter = plot_map_2d if mask is None: mask = compute_mask(map) if vmin is None: vmin = np.inf pvalue = 0.04 while not np.isfinite(vmin): pvalue *= 1.25 vmax, vmin = find_activation(map, mask=mask, pvalue=pvalue) if not np.isfinite(vmin) and auto_sign: if np.isfinite(vmax): vmin = -vmax if mask is not None: map[mask] *= -1 else: map *= -1 if cut_coords is None: x, y, z = find_cut_coords(map, activation_threshold=vmin) # XXX: Careful with Voxel/MNI ordering y, x, z = coord_transform(x, y, z, sform) cut_coords = (x, y, z) plotter(map, sform, vmin=vmin, cut_coords=cut_coords, anat=anat, anat_sform=anat_sform, title=title, figure_num=figure_num, mask=mask) return vmin, cut_coords