def loadMesh(self): path = str( QtGui.QFileDialog.getOpenFileName(self, "Open Mesh", "", "All meshes(*.gii *.mesh)")) if not path: return obj = self.a.loadObject(path) #self.a.addObjects(obj, self.axWindow) self.mesh = obj self.aimsMesh = None texture = aims.TimeTexture('S16') texture2 = aims.TimeTexture('FLOAT') AimsMesh = self.mesh.toAimsObject() #gp = aims.GeodesicPath(AimsMesh, 0, 0) newTextureObj = texture[0] newTextureObj.reserve(len(AimsMesh.vertex())) newTextureObj2 = texture2[0] newTextureObj2.reserve(len(AimsMesh.vertex())) self.texture = texture self.texture2 = texture2 self.texture2[0].assign([0] * len(AimsMesh.vertex())) if self.TextObj is None: self.TextObj = self.a.toAObject(self.texture2) self.TextObj.setPalette(palette="RED-ufusion") newFusionObj = self.a.fusionObjects([self.mesh, self.TextObj], method='FusionTexSurfMethod') #set palette to Blue-Red-fusion_invert self.a.addObjects(newFusionObj, self.axWindow) self.currentObj = newFusionObj
def projectOnSurface(myelin, surface): norm = surface.normal() vert = surface.vertex() Nv = vert.size() surfMap = aims.TimeTexture('FLOAT') surfMap[0].resize(Nv) dx, dy, dz, dt = myelin.getVoxelSize() volVox = aims.Volume(myelin.getSizeX(), myelin.getSizeY(), myelin.getSizeZ(), myelin.getSizeT(), 'FLOAT') volVox.header().update(myelin.header()) volVox.fill(0.0) print dx, dy, dz for i in range(Nv): v = vert[i] + t * norm[i] x = int(round(v[0] / dx)) y = int(round(v[1] / dy)) z = int(round(v[2] / dz)) val = myelin.value(x, y, z) volVox.setValue(val, x, y, z) surfMap[0][i] = val return surfMap, volVox
def texture_to_label_texture(texture): """Convert a texture into a label (S16) texture :param texture: AimsTimeTexture :return label_texture: AimsTimeTexture with int16 type (label) """ t = np.asarray(texture) #transpose due to weird handling of numpy array in TimeTexture class l = np.transpose(t) l = l.astype(np.int16) label_texture = aims.TimeTexture(l) return label_texture
def array_to_texture(array): ''' Build a TimeTexture from numpy array :param array: Text dim, temporal dim :return: aims TimeTexture object ''' #numpy new behavior is to have float64 by default # cast it to float32 to use the TimeTexture method if array.dtype == 'float64': array = array.astype(np.float32) texture = aims.TimeTexture(array) return texture
def execution(self, context): spherical_function = aims.read(self.spherical_function.fullPath()) #only valid if volume is isotropic vox_size = np.array(spherical_function.header()['voxel_size'])[0] sf = np.asarray(spherical_function) sphere = read_sphere(self.sphere.fullPath()) assert len(sphere.vertices) == sf.shape[-1] #removing all non physical values sf[sf < 0] = 0 context.write(sf.shape) index = np.where(np.all(sf == 0, axis=-1) == False) context.write(len(index[0])) sf_function = sf[index].copy() context.write(sf_function.shape) del sf ################################################""###"""""" #Normalisation to have distributions (the 2 is to reach size 1 (voxel) sf_vizu = sf_function.copy() sf_vizu = sf_vizu / (np.sum(sf_function, axis=1)[..., np.newaxis]) context.write(sf_function.shape) sf_vizu = sf_vizu / (2 * sf_vizu.max()) sf_vizu = sf_vizu * vox_size sf_vizu = sf_vizu * self.scaling_factor centers = np.zeros((len(index[0]), 3)) centers[:, 0] = index[0] centers[:, 1] = index[1] centers[:, 2] = index[2] centers = centers * vox_size vertices, faces = quickview_spherical_functions(centers, sphere, sf_vizu) mesh = vertices_and_faces_to_mesh(vertices, faces) #creation of the texture texture = aims.TimeTexture('FLOAT') visu = sf_function.flatten() t = texture[0] t.reserve(len(visu)) for i in range(len(visu)): t[i] = visu[i] #saving mesh and texture aims.write(mesh, self.mesh.fullPath()) aims.write(texture, self.texture.fullPath())
def save_texture(filename, data): try: from nibabel import gifti import codecs darray = gifti.GiftiDataArray(data) gii = gifti.GiftiImage(darrays=[darray]) f = codecs.open(filename, 'wb') #, encoding='utf-8') f.write(gii.to_xml(enc='utf-8')) f.close() except: from soma import aims tex = aims.TimeTexture('FLOAT') tex[0].assign(data) aims.write(tex, filename)
def indexMerge(mesh_list): """ :param list of mesh to be fusionned :return: AimsTimeTexture aims.meshMerge "concatenate the two meshes", this function create an index texture to keep trace of origin mesh. Useful for example for left and right hemisphere """ # TO DO : remplace mesh list by *args sizes = np.array([len(np.array(m.vertex())) for m in mesh_list], dtype=int) tot = np.sum(sizes) c = np.cumsum(sizes) t = np.zeros(tot) for i, n in enumerate(c): if i == 0: continue else: t[c[i - 1]:c[i]] = i texture = aims.TimeTexture(t) return texture
else: template_mesh = '/neurospin/imagen/workspace/cati/templates/average_' + sid + 'mesh_BL.gii' meshes[side] = ana.loadObject(template_mesh) windows[side] = ana.createWindow('3D', geometry=[0, 0, 584, 584]) if SYMMETRIC: file_parcels_on_atlas = path_parcels + 'pits_density_update/clusters_total_average_pits_smoothed0.7_60_sym_dist15.0_area100.0_ridge2.0.gii' else: file_parcels_on_atlas = path_parcels + 'pits_density_update/clusters_' + side + '_average_pits_smoothed0.7_60_dist15.0_area100.0_ridge2.0.gii' array_parcels = gio.read(file_parcels_on_atlas).darrays[0].data array_h2 = np.zeros(len(array_parcels)) parcels_org = np.unique(array_parcels) for parcel in parcels_org: if dict_h2[pheno].has_key(str(int(parcel))): ind = np.where(array_parcels == parcel)[0] array_h2[ind] = dict_h2[pheno][str(int(parcel))] tex = aims.TimeTexture(dtype='FLOAT') tex[0].assign(array_h2) pits_tex[side] = ana.toAObject(tex) tex_mesh[side] = ana.fusionObjects([meshes[side], pits_tex[side]], method='FusionTexSurfMethod') if "Freesurfer" in path_parcels: ref = ana.createReferential() tr = ana.createTransformation( [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -1], ref, ana.centralReferential()) tex_mesh[side].assignReferential(ref) tex_mesh[side].setMaterial(front_face='counterclockwise') pits_tex[side].setPalette(colorbar, minVal=INTERVAL[0], maxVal=INTERVAL[1], absoluteMode=True)
SIDES, GYRI, MESHES, GYRAL_CRESTS, GEO_DISTS, PARTITIONS, ADJ_GYRI_ROI, ROI_DISTANCES, ) for i, subject in enumerate(SUBJ_LIST): for j, side in enumerate(SIDES): mesh = aims.read(MESHES[(subject, side, "white")]) for k, gyrus in enumerate(GYRI): # Gyral line indexes gyral_line = np.load(GYRAL_CRESTS[(subject, side,gyrus, "cleaned", "array")]) gyral_line = gyral_line.tolist() # Geodesic distance map geo_dist_t = aims.read(GEO_DISTS[(subject, side, "white", gyrus)]) geo_dist = np.array(geo_dist_t[0]) # Mesh partitionned by geodesic distance partition = np.load(PARTITIONS[(subject, side, gyrus, "array")]) # Varying distance threshold dist_threshold = np.load(ROI_DISTANCES[(subject, side, gyrus)]) # Output texture roi = np.zeros(len(geo_dist), dtype=np.uint32) for l, g in enumerate(gyral_line): roi[(partition == g) * (geo_dist <= dist_threshold[l])] = 1 roi_t = aims.TimeTexture(roi) aims.write(roi_t, ADJ_GYRI_ROI[(subject, side, gyrus)])
def map_pits_heritability(template, side, areals, indir, cb, interval_cb, dict_freq, pval_thresh, outdir): """ Parameters template: path to template mesh file areals: path to gii file containing the texture of areals side: hemisphere side from which SOLAR estimates are displayed indir: directory containing h2 and pval dictionaries cb: colorbar names must be an array with [cb_h2, cb_pval] interval_cb: number boundaries for the colobar display must be a double array [inter_h2[0,1], inter_pval[0,1]] dict_freq: dictionary containing pits frequency per areal pval_thresh: p-value threshold outdir: output directory for the snapshots """ if not os.path.isdir(outdir): os.makedirs(outdir) # Define the quaternions that are gonna be used for the snapshots if (side == "L"): view_quaternions = { 'intern': [0.5, 0.5, 0.5, 0.5], 'extern': [0.5, -0.5, -0.5, 0.5], 'bottom': [1, 0, 0, 0], 'top': [0, 0, 1, 0] } else: view_quaternions = { 'intern': [0.5, 0.5, 0.5, 0.5], 'extern': [0.5, -0.5, -0.5, 0.5], 'bottom': [1, 0, 0, 0], 'top': [0, 0, 1, 0] } # Load h2 and pval dictionaries path_h2 = os.path.join(indir, 'h2_dict.json') with open(path_h2, 'r') as f: data = json.load(f) dict_h2 = json.loads(data) path_pval = os.path.join(indir, 'pval_dict.json') with open(path_pval, 'r') as f: data = json.load(f) dict_pval = json.loads(data) # Areal value in each vertex array_areals = gio.read(areals).darrays[0].data # Create arrays that will contain h2 and pval estimates on each vertex array_h2 = np.zeros(len(array_areals)) array_pval = np.zeros(len(array_areals)) list_areals = np.unique(array_areals) # Load the mesh in anatomist mesh = ana.loadObject(template) for areal in list_areals: # make sure areal has the right format areal = str(int(areal)) if (dict_h2[side].has_key(areal) and # Check if areal passed the threshold frequency in both hemispheres dict_freq['L']["Areal_" + areal] * dict_freq['R']["Areal_" + areal] > 0): # Finally, checl if the p-value pass the pval threshold if dict_pval[side][areal] < pval_thresh: # Select the index of vertices belonging to the areal ind = np.where(array_areals == float(areal))[0] # Give them the h2 estimate of this areal array_h2[ind] = dict_h2[side][areal] # And the log10 pvalue array_pval[ind] = -np.log10(dict_pval[side][areal]) ### Block performing the display of h2 estimates ### # Create anatomist window window = ana.createWindow('3D', geometry=[0, 0, 584, 584]) tex = aims.TimeTexture(dtype='FLOAT') tex[0].assign(array_h2) pits_tex = ana.toAObject(tex) tex_mesh = ana.fusionObjects([mesh, pits_tex], method='FusionTexSurfMethod') tex_mesh.assignReferential(ref) tex_mesh.setMaterial(front_face='counterclockwise') pits_tex.setPalette(cb[0], minVal=interval_cb[0][0], maxVal=interval_cb[0][1], absoluteMode=True) updateWindow(window, tex_mesh) # Loop through the quaternions and do the snapshot for sd in view_quaternions.keys(): q = aims.Quaternion(view_quaternions[sd]) window.camera(view_quaternion=view_quaternions[sd], zoom=0.65) # Snapshot file output output = os.path.join(outdir, 'snapshot_h2_' + side + '_' + sd + '.png') ana.execute('WindowConfig', windows=[window], snapshot=output) #### Block performing the display of pvalues estimates ### # Create anatomist window, second time (else zoom problem for snapshots) window = ana.createWindow('3D', geometry=[0, 0, 584, 584]) tex = aims.TimeTexture(dtype='FLOAT') tex[0].assign(array_pval) pits_tex = ana.toAObject(tex) tex_mesh = ana.fusionObjects([mesh, pits_tex], method='FusionTexSurfMethod') tex_mesh.assignReferential(ref) tex_mesh.setMaterial(front_face='counterclockwise') pits_tex.setPalette(cb[1], minVal=interval_cb[1][0], maxVal=interval_cb[1][1], absoluteMode=True) updateWindow(window, tex_mesh) # Loop through the quaternions and do the snapshot for sd in view_quaternions.keys(): q = aims.Quaternion(view_quaternions[sd]) window.camera(view_quaternion=view_quaternions[sd], zoom=0.65) # Snapshot file output output = os.path.join(outdir, 'snapshot_pval_' + side + '_' + sd + '.png') ana.execute('WindowConfig', windows=[window], snapshot=output)
file_DPF_on_atlas = os.path.join( path, s_id, "t1mri", "BL", "default_analysis", "segmentation", "mesh", "surface_analysis", "" + s_id + "_" + side + "white_DPF_on_atlas.gii") if os.path.isfile(file_pits_on_atlas) and os.path.isfile( file_DPF_on_atlas): array_pits = gio.read(file_pits_on_atlas).darrays[0].data array_DPF = gio.read(file_DPF_on_atlas).darrays[0].data for k, parcel in enumerate(parcels_org): ind = np.where(parcel == array_parcels) array_pits[ ind] = array_pits[ind] * array_DPF[ind] > thresholds[k] if pits_data.size == 0: pits_data = array_pits.astype(int) else: pits_data += array_pits.astype(int) else: print "WARNING " + s_id + " for side " + side + " doesn't exist !" template_mesh = '/neurospin/imagen/workspace/cati/templates/average_' + side + 'mesh_BL.gii' white_meshes[side] = ana.loadObject(template_mesh) windows[side] = ana.createWindow('3D') aims_pits = aims.TimeTexture(dtype='FLOAT') aims_pits[0].assign(pits_data) tex_pits[side] = ana.toAObject(aims_pits) tex_mesh_pits[side] = ana.fusionObjects( [white_meshes[side], tex_pits[side]], method='FusionTexSurfMethod') tex_pits[side].setPalette('actif_ret') updateWindow(windows[side], tex_mesh_pits[side]) ana.execute('WindowConfig', windows=[windows[side]], cursor_visibility=0)
def map_shared_genetic(template, sd, areals, indir, cb, interval_cb, rho, trait, pval_thresh, outdir): """ Parameters template: path to template mesh file areals: path to gii file containing the texture of areals sd: hemisphere side from which SOLAR estimates are displayed indir: directory containing h2 and pval dictionaries cb: colorbar names must be an array with [cb_h2, cb_pval] interval_cb: number boundaries for the colobar display must be a double array [inter_h2[0,1], inter_pval[0,1]] pval_thresh: p-value threshold outdir: output directory for the snapshots """ if not os.path.isdir(outdir): os.makedirs(outdir) # Define the quaternions that are gonna be used for the snapshots if (sd == "L"): view_quaternions = { 'intern': [0.5, 0.5, 0.5, 0.5], 'extern': [0.5, -0.5, -0.5, 0.5], 'bottom': [1, 0, 0, 0], 'top': [0, 0, 1, 0] } else: view_quaternions = { 'intern': [0.5, -0.5, -0.5, 0.5], 'extern': [0.5, 0.5, 0.5, 0.5], 'bottom': [1, 0, 0, 0], 'top': [0, 0, 1, 0] } # Load h2 and pval dictionaries path_h2 = os.path.join(indir, sd + rho + '_dict.json') with open(path_h2, 'r') as f: data = json.load(f) dict_h2 = json.loads(data) path_pval = os.path.join(indir, sd + rho + '_pval_dict.json') with open(path_pval, 'r') as f: data = json.load(f) dict_pval = json.loads(data) # Load h2 and pval dictionaries rho2 = 'scipy_rhop' path_h2 = os.path.join(indir, sd + rho2 + '_dict.json') with open(path_h2, 'r') as f: data = json.load(f) dict_rhop = json.loads(data) path_pval = os.path.join(indir, sd + rho2 + '_pval_dict.json') with open(path_pval, 'r') as f: data = json.load(f) dict_pval_rhop = json.loads(data) # Areal value in each vertex array_areals = gio.read(areals).darrays[0].data # Create arrays that will contain h2 and pval estimates on each vertex array_h2 = np.zeros(len(array_areals)) array_pval = np.zeros(len(array_areals)) list_areals = np.unique(array_areals) # Load the mesh in anatomist mesh = ana.loadObject(template) for areal in list_areals: # make sure areal has the right format areal = str(int(areal)) if dict_h2.has_key(areal + '_' + col): # Finally, checl if the p-value pass the pval threshold if (dict_pval[areal + '_' + col] < pval_thresh and # Force the phenotypic correlation to be significant dict_pval_rhop[areal + '_' + col] < 5e-2 / (2 * 180)): # Select the index of vertices belonging to the areal ind = np.where(array_areals == float(areal))[0] # Give them the h2 estimate of this areal if 'rhog' in rho: # Change this line for Figure 3 array_h2[ind] = abs(dict_h2[areal + '_' + col]) else: array_h2[ind] = dict_h2[areal + '_' + col] # And the log10 pvalue array_pval[ind] = -np.log10(dict_pval[areal + '_' + col]) ### Block performing the display of h2 estimates ### # Create anatomist window window = ana.createWindow('3D', geometry=[0, 0, 584, 584]) tex = aims.TimeTexture(dtype='FLOAT') tex[0].assign(array_h2) pits_tex = ana.toAObject(tex) tex_mesh = ana.fusionObjects([mesh, pits_tex], method='FusionTexSurfMethod') tex_mesh.assignReferential(ref) tex_mesh.setMaterial(front_face='counterclockwise') pits_tex.setPalette(cb[0], minVal=interval_cb[0][0], maxVal=interval_cb[0][1], absoluteMode=True) updateWindow(window, tex_mesh) ana.execute('TexturingParams', objects=[tex_mesh], interpolation='rgb') # Loop through the quaternions and do the snapshot for vw in view_quaternions.keys(): q = aims.Quaternion(view_quaternions[vw]) window.camera(view_quaternion=view_quaternions[vw], zoom=0.65) # Snapshot file output output = os.path.join( outdir, '_'.join(['snapshot', trait, rho, sd, vw + '.png'])) ana.execute('WindowConfig', windows=[window], snapshot=output) if False: ana.releaseObject(pits_tex) pits_tex = None ana.releaseObject(tex_mesh) tex_mesh = None #### Block performing the display of pvalues estimates ### # Create anatomist window, second time (else zoom problem for snapshots) window = ana.createWindow('3D', geometry=[0, 0, 584, 584]) tex = aims.TimeTexture(dtype='FLOAT') tex[0].assign(array_pval) pits_tex = ana.toAObject(tex) tex_mesh = ana.fusionObjects([mesh, pits_tex], method='FusionTexSurfMethod') tex_mesh.assignReferential(ref) tex_mesh.setMaterial(front_face='counterclockwise') pits_tex.setPalette(cb[1], minVal=interval_cb[1][0], maxVal=interval_cb[1][1], absoluteMode=True) updateWindow(window, tex_mesh) ana.execute('TexturingParams', objects=[tex_mesh], interpolation='rgb') # Loop through the quaternions and do the snapshot for vw in view_quaternions.keys(): q = aims.Quaternion(view_quaternions[vw]) window.camera(view_quaternion=view_quaternions[vw], zoom=0.65) # Snapshot file output output = os.path.join( outdir, '_'.join(['snapshot', trait, rho, 'pval', sd, vw + '.png'])) ana.execute('WindowConfig', windows=[window], snapshot=output) if False: ana.releaseObject(pits_tex) pits_tex = None ana.releaseObject(tex_mesh) tex_mesh = None
from configuration.configuration import ( SUBJ_LIST, SIDES, MESHES, SULCUS_FUNDI, SULCUS, FUNDI_PARAMETRISATIONS, ) if __name__ == "__main__": for subject in SUBJ_LIST: for side in SIDES: fundus_index = np.load(SULCUS_FUNDI[(subject, side, SULCUS, "cleaned", "array")]) mesh = aims.read(MESHES[(subject, side, 'white')]) vertices = np.array(mesh.vertex()) fundus = vertices[fundus_index] norm_param = normalized_curv_parametrisation(fundus) norm_param_tex = aims.TimeTexture(norm_param) np.save( FUNDI_PARAMETRISATIONS[(subject, side, SULCUS, "cleaned", "array", "iso")], norm_param, ) aims.write( norm_param_tex, FUNDI_PARAMETRISATIONS[(subject, side, SULCUS, "cleaned", "texture", "iso")], )
mesh = aims.read(MESHES[(subject, side, "white")]) vertices = np.array(mesh.vertex()) for k, gyrus in enumerate(GYRI): gyrus_tex = aims.read(GYRAL_CRESTS[(subject, side, gyrus, "drawn", "texture")]) gyrus_a = np.array(gyrus_tex[0]) # removing additionnal triangles to obtain a real line cleaned_gyrus = clean_line(mesh, gyrus_a) np.save( GYRAL_CRESTS[(subject, side, gyrus, "cleaned", "array")], cleaned_gyrus, ) # saving also the cleaned gyrus as a texture for displays cleaned_gyrus_t = np.zeros(vertices.shape[0]) cleaned_gyrus_t[cleaned_gyrus] = 100 cleaned_gyrus_tex = aims.TimeTexture( cleaned_gyrus_t.astype(np.float32)) aims.write( cleaned_gyrus_tex, GYRAL_CRESTS[(subject, side, gyrus, "cleaned", "texture")], ) # creating a gyral line mesh gyrus_vertices = vertices[cleaned_gyrus] gyrus_mesh = vertices_to_2d_line(gyrus_vertices) aims.write( gyrus_mesh, GYRAL_CRESTS[(subject, side, gyrus, "cleaned", "mesh")]) # computing normalized curv absciss param gyrus_param = normalized_curv_parametrisation(gyrus_vertices) np.save( GYRAL_PARAMETRISATIONS[(subject, side, gyrus, "cleaned", "array", "iso")],