def viz_subcortical_points(self, subjects_dir=None, subject=None): ''' add transparent voxel structures at the subcortical structures ''' if subjects_dir is None: subjects_dir = os.environ['SUBJECTS_DIR'] if subject is None: subject = os.environ['SUBJECT'] structures_list = { 'hippocampus': ([53, 17], (.69, .65, .93)), 'amgydala': ([54, 18], (.8, .5, .29)), 'thalamus': ([49, 10], (.318, 1, .447)), 'caudate': ([50, 11], (1, .855, .67)), 'putamen': ([51, 12], (0, .55, 1)), 'insula': ([55, 19], (1, 1, 1)), 'accumbens': ([58, 26], (1, .44, 1)), } asegf = os.path.join(subjects_dir, subject, 'mri', 'aseg.mgz') aseg = nib.load(asegf) asegd = aseg.get_data() for struct in structures_list: (strucl, strucr), color = structures_list[struct] for strucu in (strucl, strucr): strucw = np.where(asegd == strucu) if np.size(strucw) == 0: print 'Nonne skippy %s' % struct continue import geometry as geo xfm = geo.get_vox2rasxfm(asegf, stem='vox2ras-tkr') strucd = np.array(geo.apply_affine(np.transpose(strucw), xfm)) print np.shape(strucd) src = mlab.pipeline.scalar_scatter( strucd[:, 0], strucd[:, 1], strucd[:, 2], figure=self.scene.mayavi_scene) mlab.pipeline.glyph(src, scale_mode='none', scale_factor=0.4, mode='sphere', opacity=1, figure=self.scene.mayavi_scene, color=color)
def get_orig2std(orig): ''' Given an orig file, get the transformation from the orig to ras2mni. ''' vox2ras = get_vox2rasxfm(orig) bx, by, bz = vox2ras[0:3,3] reorient_orig2std_mat = np.array(((1, 0, 0, bx-128), (0, 0, -1, by+128), (0, 1, 0, bz-128), (0, 0, 0, 1))) return reorient_orig2std_mat
def load_img(self, imgf, reorient2std=False, image_name=None): self._finished_plotting = False img = nib.load(imgf) aff = np.dot( get_orig2std(imgf) if reorient2std else np.eye(4), img.get_affine()) tkr_aff = np.dot( reorient_orig2std_tkr_mat if reorient2std else np.eye(4), get_vox2rasxfm(imgf, stem='vox2ras-tkr')) #from nilearn.image.resampling import reorder_img #img = reorder_img(uimg, resample='continuous') xsz, ysz, zsz = img.shape #print 'image coordinate transform', img.get_affine() imgd = img.get_data() if reorient2std: imgd = np.swapaxes(imgd, 1, 2)[:,:,::-1] #print 'image size', imgd.shape if image_name is None: from utils import gensym image_name = 'image%s'%gensym() self.images[image_name] = (imgd, aff, tkr_aff) self.currently_showing_list.append( NullInstanceHolder(name=image_name)) self.currently_showing = self.currently_showing_list[-1] self.pins[image_name] = {} #self.current_pin = image_name self.show_image(image_name)
def coronal_slice(elecs, start=None, end=None, outfile=None, subjects_dir=None, subject=None, reorient2std=True, dpi=150, size=(200,200), title=None): ''' create an image of a coronal slice which serves as a guesstimate of a depth lead inserted laterally and nonvaryingly in the Y axis plot the electrodes from the lead overlaid on the slice in the X and Z directions Paramaters ---------- elecs : List( Electrode ) list of electrode objects forming this depth lead start : Electrode Electrode object at one end of the depth lead end : Electrode Electrode object at the other end of the depth lead outfile : Str Filename to save the image to subjects_dir : Str | None The freesurfer subjects_dir. If this is None, it is assumed to be the $SUBJECTS_DIR environment variable. If this folder is not writable, the program will crash. subject : Str | None The freesurfer subject. If this is None, it is assumed to be the $SUBJECT environment variable. reorient2std : Bool Apply a matrix to rotate orig.mgz to the standard MNI orientation emulating fslreorient2std. Pretty much always true here. dpi : Int Dots per inch of output image size : Tuple Specify a 2-tuple to control the image size, default is (200,200) title : Str Specify a matplotlib title ''' print 'creating coronal slice with start electrodes %s' % str(start) subjdir_subj = get_subjects_dir( subjects_dir=subjects_dir, subject=subject ) orig = os.path.join(subjdir_subj, 'mri', 'orig.mgz') x_size, y_size, z_size = nib.load(orig).shape # vox2ras and ras2vox shouldnt have different procedures for # getting the different dimensions. the matrix showing those # dimensions has the correct dimensions by inversion beforehand # in the complex 3-way case vox2ras = get_vox2rasxfm(orig, stem='vox2ras') ras2vox = np.linalg.inv(vox2ras) ras2vox[0:3,3] = (x_size/2, y_size/2, z_size/2) rd, ad, sd = get_std_orientation(ras2vox) # rd, = np.where(np.abs(ras2vox[:,0]) == np.max(np.abs(ras2vox[:,0]))) # ad, = np.where(np.abs(ras2vox[:,1]) == np.max(np.abs(ras2vox[:,1]))) # sd, = np.where(np.abs(ras2vox[:,2]) == np.max(np.abs(ras2vox[:,2]))) r_size = [x_size, y_size, z_size][rd] a_size = [x_size, y_size, z_size][ad] s_size = [x_size, y_size, z_size][sd] #starty = pd.map_cursor( start.asras(), pd.current_affine, invert=True)[1] #endy = pd.map_cursor( end.asras(), pd.current_affine, invert=True )[1] #midy = (starty+endy)/2 #pd.move_cursor(128, midy, 128) electrodes = np.squeeze([apply_affine([e.asras()], ras2vox) for e in elecs]) #electrodes = np.array([pd.map_cursor(e.asras(), ras2vox, # invert=True) for e in elecs]) vol = np.transpose( nib.load(orig).get_data(), (rd, ad, sd) ) if start is not None and end is not None: start_coord = np.squeeze(apply_affine([start.asras()], ras2vox)) end_coord = np.squeeze(apply_affine([end.asras()], ras2vox)) if start_coord[rd] == end_coord[rd]: raise ValueError('This lead has no variation in the X axis. It shouldnt be displayed coronally') slice = np.zeros((s_size, r_size)) m = (start_coord[ad]-end_coord[ad])/(start_coord[rd]-end_coord[rd]) b = start_coord[ad]-m*start_coord[rd] rnew = np.arange(r_size) anew = m*rnew+b alower = np.floor(anew) afrac = np.mod(anew, 1) try: for rvox in rnew: slice[:, rvox] = (vol[rvox, alower[rvox], :] * (1-afrac[rvox])+vol[rvox, alower[rvox]+1, :] * afrac[rvox]) except IndexError: raise ValueError('This lead has minimal variation in the X axis. It shouldnt be displayed coronally') else: slice_nr = np.mean(electrodes[:,ad]) slice = vol[:, slice_nr, :].T vox2pix = np.zeros((2,4)) vox2pix[0, rd] = 1 vox2pix[1, sd] = 1 ras2pix = np.dot(vox2pix, ras2vox) pix = np.dot(ras2pix, np.transpose([np.append(e.asras(), 1) for e in elecs])) #add data to coronal plane import pylab as pl fig = pl.figure() pl.imshow(slice, cmap='gray') pl.scatter(pix[0,:], pix[1,:], s=10, c='red', edgecolor='yellow', linewidths=0.4) if title is not None: pl.title(title) pl.axis('off') #pl.show() if outfile is not None: pl.savefig(outfile, dpi=dpi) return fig