def execution(self, context): tr = aims.AffineTransformation3d() for t in self.MNI_transform_chain: ti = aims.read(t.fullPath()) tr = ti * tr #context.write('transform:', tr) vol = aims.read(self.volume.fullPath()) trl = vol.header().get('transformations', []) refl = vol.header().get('referentials', []) rname = aims.StandardReferentials.mniTemplateReferential() if rname in refl: trl[refl.index(rname)] = tr.toVector() elif len(trl) < 2: #else: trl.append(tr.toVector()) refl.append(rname) else: trl = [list(trl[0]), list(tr.toVector())] \ + [list(t) for t in list(trl)[1:]] refl = [refl[0], rname] + list(refl)[1:] # context.write('now:', refl, trl) vol.header()['referentials'] = refl vol.header()['transformations'] = trl context.write('new header:', vol.header()) aims.write(vol, self.output_volume.fullPath()) self.output_volume.readAndUpdateMinf() tm = registration.getTransformationManager() tm.copyReferential(self.volume, self.output_volume, copy_transformations=False)
def execution(self, context): #Load light objects first csd = load(self.csd_model.fullPath()) dmri_vol = aims.read(self.diffusion_data.fullPath()) header = dmri_vol.header() data = np.asarray(dmri_vol) if self.mask is not None: mask_vol = aims.read(self.mask.fullPath()) mask_arr = np.array(mask_vol, copy=True) mask = mask_arr[..., 0] if data.shape[:-1] != mask.shape: raise ValueError( 'Diffusion data and mask used do not have the same shape') else: mask = self.mask csdfit = csd.fit(data, mask=mask) sh_coeff = csdfit.shm_coeff sh_coeff_volume = array_to_vol(sh_coeff, header) aims.write(sh_coeff_volume, self.fibre_odf_sh_coeff.fullPath()) transformManager = getTransformationManager() transformManager.copyReferential(self.diffusion_data, self.fibre_odf_sh_coeff) pass
def mesh_transform(path_mesh, path_transfo, path_mesh_out): transfo = aims.read(path_transfo) mesh = aims.read(path_mesh) h = mesh.header() aims.SurfaceManip.meshTransform(mesh, transfo) aims.write(mesh, path_mesh_out) pass
def execution(self, context): from soma import aims from soma.aims import fslTransformation trm = fslTransformation.fslMatToTrm(self.read.fullPath(), self.source_volume.fullPath(), self.registered_volume.fullPath()) aims.write(trm, self.write.fullPath())
def execution(self,context): sphere = create_repulsion_sphere(self.nb_points, self.nb_iterations) #At this stage sphere can have inconsistent faces orientations, reorienting them new_sphere = correct_sphere(sphere) mesh = sphere_to_mesh(new_sphere) aims.write(mesh, self.sphere.fullPath())
def mesh_from_arrays(coord, triangles, path=None): """ Create a mesh object from two arrays fixme: intent should be set ! """ carray = gifti.GiftiDataArray().from_array(coord.astype(np.float32), "NIFTI_INTENT_POINTSET", encoding='B64BIN') #endian="LittleEndian") tarray = gifti.GiftiDataArray().from_array(triangles.astype(np.int32), "NIFTI_INTENT_TRIANGLE", encoding='B64BIN') #endian="LittleEndian") img = gifti.GiftiImage(darrays=[carray, tarray]) if path is not None: try: from soma import aims mesh = aims.AimsTimeSurface(3) mesh.vertex().assign([aims.Point3df(x) for x in coord]) mesh.polygon().assign( [aims.AimsVector_U32_3(x) for x in triangles]) aims.write(mesh, path) except: print("soma writing failed") gifti.write(img, path) return img
def convert_raw_map(fname, out_fname): ''' convert one raw map from bdalti (.asc) to .ima format ''' with open(fname) as f: lines = f.readlines() types = { 'ncols': int, 'cellsize': float, 'xllcorner': float, 'yllcorner': float, 'NODATA_value': float, } metadata = {} for l in lines[:6]: item = l.strip().split() k = item[0] metadata[k] = types.get(k, str)(item[1]) # print(metadata) image = aims.Volume((int(metadata['ncols']), int(metadata['nrows'])), dtype='float') array = np.asarray(image) for i, l in enumerate(lines[6:]): array[:, i, 0, 0] = [float(x) for x in l.strip().split()] image.header().update(metadata) aims.write(image, out_fname)
def peaks_as_spheres(path_peaks_volume, path_spheres, radius=2): """ Represent peaks as spheres centered on peaks location and of radius radius :param path_peaks_volume: path of the boolean volume with peaks :param path_spheres: path of the mesh (spheres) representing the peaks :param radius: radius (in mm) of the spheres used for display :return: """ volume = aims.read(path_peaks_volume) data = np.array(volume)[..., 0] voxel_size = volume.header()['voxel_size'] + [1] scaling = aims.AffineTransformation3d() scaling.fromMatrix(np.diag(voxel_size)) peaks_vol_coord = np.transpose(np.vstack(np.where(data != 0))) centers = [aims.Point3df(p) for p in peaks_vol_coord] print(len(centers)) for i, center in enumerate(centers): center = scaling.transform(center) sphere = aims.SurfaceGenerator.sphere(center, radius,300) if i == 0: spheres = sphere else: aims.SurfaceManip.meshMerge(spheres, sphere) aims.write(spheres, path_spheres)
def execution(self, context): csd_model = load(self.csd_model.fullPath()) csd_coeff = aims.read(self.fibre_odf_sh_coeff.fullPath()) header = csd_coeff.header() sh_coeff = np.asarray(csd_coeff) mask_vol = aims.read(self.mask.fullPath()) mask = vol_to_array(mask_vol) mask = array_to_mask(mask) try: S0 = aims.read(self.S0_signal.fullPath()) except: context.write("No B0 volume provided, I assume the non ponderated signal value is 1.0 in all voxels") S0 = 1 csd_fit = SphHarmFit(csd_model,sh_coeff, mask) prediction = csd_fit.predict(gtab=None, S0=S0) prediction_volume = array_to_vol(prediction, header) aims.write(prediction_volume,self.predicted_signal.fullPath()) #Handling referentials transformManager = getTransformationManager() # Mandatory parameters transformManager.copyReferential(self.fibre_odf_sh_coeff, self.predicted_signal) pass
def fix_cortex_topology_files(input_filename, output_filename, filling_size, fclosing): """Call highres_cortex.cortex_topo.fix_cortex_topology on files.""" input_volume = aims.read(input_filename) output = highres_cortex.cortex_topo.fix_cortex_topology( input_volume, filling_size, fclosing) # BUG: aims.write offers no error checking, so the program will exit # successfully even if writing fails aims.write(output, output_filename)
def execution(self, context): data_vol = aims.read(self.dwi_data.fullPath()) header = data_vol.header() data = vol_to_array(data_vol) sigma = piesno(data, self.coil_number, alpha=self.alpha, l=self.trials, itermax=ITERMAX, eps=EPS, return_mask=False) sigma_arr = sigma*np.ones(data.shape[:-1], dtype=np.float32) sigma_vol = array_to_vol(sigma_arr, header=header) aims.write(sigma_vol, self.sigma.fullPath())
def execution(self, context): from soma import aims graph = aims.read(self.read.fullPath()) aims.GraphManip.buckets2Volume(graph) if self.extract_volume: vol = graph[self.extract_volume] else: atts = [ x for x in graph.keys() if isinstance(graph[x], aims.rc_ptr_Volume_S16) ] if len(atts) == 0: raise RuntimeError(_t_('the ROI graph contains no voxel data')) elif len(atts) > 1: raise RuntimeError( _t_('the ROI graph contains several volumes. ' 'Select the extract_volume parameter as one in ') + '( ' + ', '.join(atts) + ' )') vol = graph[atts[0]] # handle bounding box which may have cropped the data bmin = graph['boundingbox_min'] bmax = graph['boundingbox_max'] context.write('vol:', vol) context.write('bmin:', bmin, ', bmax:', bmax, ', size:', vol.getSize()) if bmin[:3] != [0, 0, 0] \ or bmax[:3] != [x+1 for x in vol.getSize()[:3]]: context.write('enlarging') # needs expanding in a bigger volume vol2 = aims.Volume_S16(bmax[0] + 1, bmax[1] + 1, bmax[2] + 1) vol2.fill(0) ar = vol2.np ar[bmin[0]:bmax[0] + 1, bmin[1]:bmax[1] + 1, bmin[2]:bmax[2] + 1, :] \ = vol.np if self.extract_contours == 'Yes': ar_copy = ar.copy() for label in [v['roi_label'] for v in graph.vertices()]: ind = list(zip(*np.where(ar_copy == label))) for i in ind: erase = True for neigh in neighbors(*i): if ar_copy[neigh] != label: erase = False if erase: ar[i] = 0 vol2.copyHeaderFrom(vol.header()) aims.write(vol2, self.write.fullPath()) else: # bounding box OK aims.write(vol.get(), self.write.fullPath()) registration.getTransformationManager().copyReferential( self.read, self.write) if self.removeSource: for f in self.read.fullPaths(): shelltools.rm(f)
def remove_ref_from_headers(fp, replace=False): print fp i = aims.read(fp) i.header().update({'referentials':[],'transformations':[]}) s = osp.basename(fp).split('.') basename, ext = s[0], '.'.join(s[1:]) suffix = '_nohdr' if not replace else '' fp2 = osp.join(osp.dirname(fp), '%s%s.%s'%(basename, suffix, ext)) print 'writing', fp2 aims.write(i, fp2)
def execution(self, context): from soma import aims import numpy as np vol = aims.read(self.input_image.fullPath()) vol_arr = np.asarray(vol) w = np.where(vol_arr == 0) noise = np.random.normal( self.noise_average, self.noise_stdev, w[0].shape) noise[noise < 0] = 0 vol_arr[w] = noise aims.write(vol, self.output_image.fullPath())
def execution(self, context): from soma import aims r = aims.Reader({'Volume': {'S16': 'Graph'}}) graph = r.read(self.read.fullPath()) graph['filename_base'] = '*' aims.GraphManip.volume2Buckets(graph) aims.write(graph, self.write.fullPath()) registration.getTransformationManager().copyReferential(self.read, self.write) if self.removeSource: for f in self.read.fullPaths(): shelltools.rm(f)
def getExchangedPropagationVolume(CSF_labels_on_white, white_labels_on_CSF, classif, resultDir, keyWord): output = aims.Volume(CSF_labels_on_white) np_CSF_labels_on_white = np.asarray(CSF_labels_on_white) np_white_labels_on_CSF = np.asarray(white_labels_on_CSF) np_classif = np.asarray(classif) np_output = np.asarray(output) white_mask = (np_classif == 150) CSF_mask = (np_classif == 50) np_output[white_mask] = np_CSF_labels_on_white[white_mask] np_output[CSF_mask] = np_white_labels_on_CSF[CSF_mask] aims.write(output, resultDir + 'raw_exchanged_labels_%s.nii' %(keyWord)) # These “failed components” will probably be separated by connexity #AimsReplaceLevel -i raw_exchanged_labels.nii.gz -o exchanged_labels.nii.gz -g 100000000 -n 0 -g 200000000 -n 0 subprocess.check_call(["AimsConnectComp", "-i", resultDir + 'raw_exchanged_labels_%s.nii' %(keyWord), "-o", resultDir + 'connected_exchanged_labels_%s.nii' %(keyWord)]) # The background is cut in one big region + many small, restore it then relabel propvol = aims.read(resultDir + 'connected_exchanged_labels_%s.nii' %(keyWord)) np_propvol = np.asarray(propvol) exclusion_mask = (np_CSF_labels_on_white == -1) bulk_mask = (np_CSF_labels_on_white == 0) np_propvol[bulk_mask] = 0 np_propvol[exclusion_mask] = -1 def relabel_positive_labels(volume): size_x = volume.getSizeX() size_y = volume.getSizeY() size_z = volume.getSizeZ() old_to_new_labels = {} next_label = 1 for z in xrange(size_z): for y in xrange(size_y): for x in xrange(size_x): old_label = volume.at(x, y, z) if old_label > 0: try: new_label = old_to_new_labels[old_label] except KeyError: new_label = next_label old_to_new_labels[old_label] = new_label next_label += 1 volume.setValue(new_label, x, y, z) relabel_positive_labels(propvol) return(propvol)
def execution(self, context): tex = aims.read(self.label_texture.fullPath()) mesh = aims.read(self.mesh.fullPath()) outmesh = aims.SurfaceManip.meshTextureBoundary(mesh, tex, -1) diffuse = [1., 0, 0., 1.] ncomp = min(len(self.mesh_color), 4) diffuse[:ncomp] = self.mesh_color[:ncomp] context.write(self.mesh_color) outmesh.header()[ 'material' ] = \ {'line_width': self.line_width, 'diffuse': diffuse} aims.write(outmesh, self.output_boundaries_mesh.fullPath()) tm = registration.getTransformationManager() tm.copyReferential(self.mesh, self.output_boundaries_mesh)
def get_exchanged_propvol_files(classif_filename, CSF_labels_on_white_filename, white_labels_on_CSF_filename, output_filename): classif = aims.read(classif_filename) CSF_labels_on_white = aims.read(CSF_labels_on_white_filename) white_labels_on_CSF = aims.read(white_labels_on_CSF_filename) output = aims.Volume(CSF_labels_on_white) np_CSF_labels_on_white = np.asarray(CSF_labels_on_white) np_white_labels_on_CSF = np.asarray(white_labels_on_CSF) np_classif = np.asarray(classif) np_output = np.asarray(output) white_mask = (np_classif == 150) CSF_mask = (np_classif == 50) np_output[white_mask] = np_CSF_labels_on_white[white_mask] np_output[CSF_mask] = np_white_labels_on_CSF[CSF_mask] temp_dir = None try: temp_dir = tempfile.mkdtemp(prefix="hcortex") temp_filename = os.path.join(temp_dir, 'raw_exchanged_labels.nii') aims.write(output, temp_filename) # These “failed components” will probably be separated by connexity # AimsReplaceLevel -i raw_exchanged_labels.nii.gz \ # -o exchanged_labels.nii.gz \ # -g 100000000 -n 0 -g 200000000 -n 0 subprocess.check_call(["AimsConnectComp", "-i", "raw_exchanged_labels.nii", "-o", "connected_exchanged_labels.nii"], cwd=temp_dir) # The background is cut in one big region + many small, restore it then # relabel propvol = aims.read( os.path.join(temp_dir, "connected_exchanged_labels.nii")) finally: if temp_dir: shutil.rmtree(temp_dir) np_propvol = np.asarray(propvol) exclusion_mask = (np_CSF_labels_on_white == -1) bulk_mask = (np_CSF_labels_on_white == 0) np_propvol[bulk_mask] = 0 np_propvol[exclusion_mask] = -1 relabel_positive_labels(propvol) aims.write(propvol, output_filename)
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 get_transformation(path_volume, path_reference_volume, path_transfo, path_inverse): volume = aims.read(path_volume) reference_volume = aims.read(path_reference_volume) header = volume.header() header_ref = reference_volume.header() transfo_vol_to_mni = aims.AffineTransformation3d( header["transformations"][0]) transfo_reference_to_mni = aims.AffineTransformation3d( header_ref["transformations"][0]) final_transfo = transfo_reference_to_mni.inverse() * transfo_vol_to_mni inverse = final_transfo.inverse() aims.write(final_transfo, path_transfo) aims.write(inverse, path_inverse) pass
def execution(self, context): # Read header information atts = aimsGlobals.aimsVolumeAttributes(self.volume_input) ref = atts['referentials'] trf = atts['transformations'] if ("Scanner-based anatomical coordinates" in ref): trm_to_scannerBased = trf[ ref.index("Scanner-based anatomical coordinates")] # Create a referential for Scanner-based tm = registration.getTransformationManager() dest = tm.referential(self.new_referential) context.write('dest:', dest) if dest is None: dest = tm.createNewReferentialFor( self.new_referential, referentialType='Scanner Based Referential') # Create a new referential if needed for the volume # src = tm.referential( self.volume_input ) # print "Attributes" # print self.volume_input.hierarchyAttributes() # if src is None: # print "create src" # src = tm.createNewReferentialFor(self.volume_input) # print "apres" # print src src = tm.referential(self.referential_volume_input) context.write('src:', src) # print "Attributes" # print self.volume_input.hierarchyAttributes() if src is None: src = tm.createNewReferentialFor(self.volume_input, referentialType='Referential of Raw T1 MRI', output_diskitem=self.referential_volume_input) dest.setMinf('direct_referential', 1, saveMinf=True) # Store information into the trm file mot = aims.Motion(trm_to_scannerBased) aims.write(mot, self.T1_TO_Scanner_Based.fullPath()) # set and update database tm.setNewTransformationInfo( self.T1_TO_Scanner_Based, source_referential=src, destination_referential=dest)
def execution(self, context): filetype = self.read.type if filetype is getDiskItemType( 'SPM99 normalization matrix' ) \ or self.read.fullName()[-5:] == '_sn3d': spm2 = 0 else: spm2 = 1 AtoT = aims.readSpmNormalization(self.read.fullPath(), self.source_volume.fullPath()) srcref = None h = AtoT.header() if 'source_referential' in h: srcref = h['source_referential'] tm = registration.getTransformationManager() if self.target != 'normalized_volume in AIMS orientation': aims.write(AtoT, self.write.fullPath()) if self.target == 'MNI template': destref = tm.referential(registration.talairachMNIReferentialId) else: destref = None else: # normalized_volume in AIMS orientation nim = self.normalized_volume if not nim or not nim.isReadable(): raise RuntimeError( _t_('normalized_volume shoud be specified when using this target mode' )) context.write('use normalized image:', nim.fullPath(), '\n') hasnorm = 1 attrs = shfjGlobals.aimsVolumeAttributes(nim) t1 = aims.Motion(attrs['transformations'][-1]) AIMS = t1.inverse() * AtoT AIMS.header().update(AtoT.header()) destref = tm.referential(nim) aims.write(AIMS, self.write.fullPath()) if srcref or destref: tm.setNewTransformationInfo(self.write, srcref, destref) if self.removeSource: for f in self.read.fullPaths(): os.unlink(f)
def execution(self, context): from soma import aims, aimsalgo import numpy as np vol = aims.read(self.image_input.fullPath()) old_t1_to_scanner = aims.AffineTransformation3d( vol.header()['transformations'][0]) new_t1 = aims.read(self.target_space_image.fullPath()) new_t1_to_scanner = aims.AffineTransformation3d( new_t1.header()['transformations'][0]) old_to_new = new_t1_to_scanner.inverse() * old_t1_to_scanner rsp = getattr(aims, 'ResamplerFactory_' + aims.typeCode(np.asarray(vol).dtype))().getResampler(0) rsp.setRef(vol) vol_resamp = rsp.doit(old_to_new, new_t1.getSizeX(), new_t1.getSizeY(), new_t1.getSizeZ(), new_t1.getVoxelSize()[:3]) aims.write(vol_resamp, self.image_output.fullPath()) tm = registration.getTransformationManager() tm.copyReferential(self.target_space_image, self.image_output)
def postprocess_equivolumetric_depth(input_filename, classif_filename, output_filename): depth_vol = aims.read(input_filename) classif_vol = aims.read(classif_filename) depth_arr = np.asarray(depth_vol) classif_arr = np.asarray(classif_vol) depth_arr[classif_arr == CSF_LABEL] = 0.0 depth_arr[classif_arr == WHITE_LABEL] = 1.0 header = depth_vol.header() header['cal_min'] = 0.0 header['cal_max'] = 1.0 header['intent_code'] = 1001 # NIFTI_INTENT_ESTIMATE header['intent_name'] = 'Equivol. depth' header['descrip'] = ( 'Equivolumetric cortical depth computed with highres-cortex') aims.write(depth_vol, output_filename)
def execution(self, context): context.write("Loading input files") data_vol = aims.read(self.diffusion_data.fullPath()) hdr = data_vol.header() data = vol_to_array(data_vol) del data_vol if self.mask is not None: mask_vol = aims.read(self.mask.fullPath()) mask = vol_to_array(mask_vol) del mask_vol mask = array_to_mask(mask) else: mask = self.mask tensor = load(self.tensor_model.fullPath()) context.write("Input files loaded successfully") context.write( "Fitting Diffusion Tensor model on data...it migh take some time") tenfit = tensor.fit(data, mask=mask) context.write("Diffusion Tensor Model fitted successfully") tensor_coefficients = tenfit.model_params vol_tensor = array_to_vol(tensor_coefficients, header=hdr) context.write('Writing coefficient volume on disk') aims.write(vol_tensor, self.tensor_coefficients.fullPath()) #saving other metadata self.tensor_coefficients.setMinf('model_uuid', self.tensor_model.uuid()) self.tensor_coefficients.setMinf('data_uuid', self.diffusion_data.uuid()) try: assert self.mask is not None self.tensor_coefficients.setMinf('mask_uuid', self.mask.uuid()) except Exception: self.tensor_coefficients.setMinf('mask_uuid', 'None') transformManager = getTransformationManager() transformManager.copyReferential(self.diffusion_data, self.tensor_coefficients) context.write("Processed Finished") pass
def execution(self, context): data_vol = aims.read(self.dwi_data.fullPath()) header = data_vol.header() data = vol_to_array(data_vol) sigma_vol = aims.read(self.sigma.fullPath()) sigma = vol_to_array(sigma_vol) if self.brain_mask is not None: brain_mask_vol = aims.read(self.brain_mask.fullPath()) brain_mask = vol_to_array(brain_mask_vol) else: brain_mask = None denoised_data = localpca(data, sigma, mask=brain_mask, pca_method=self.method, patch_radius=self.patch_radius, tau_factor=self.tau_factor) denoised_data_vol = array_to_vol(denoised_data, header=header) aims.write(denoised_data_vol, self.denoised_dwi_data.fullPath())
def execution(self, context): data_vol = aims.read(self.dwi_data.fullPath()) header = data_vol.header() data = vol_to_array(data_vol) sigma_vol = aims.read(self.sigma.fullPath()) sigma = vol_to_array(sigma_vol) if self.brain_mask is not None: brain_mask_vol = aims.read(self.brain_mask.fullPath()) brain_mask = vol_to_array(brain_mask_vol) else: brain_mask = None denoised_data = nlmeans(data, sigma, mask=brain_mask, patch_radius=self.patch_radius, block_radius=self.block_radius, rician=self.rician_noise) denoised_data_vol = array_to_vol(denoised_data, header=header) aims.write(denoised_data_vol, self.denoised_dwi_data.fullPath())
def execution(self, context): finder = aims.Finder() finder.check(self.read.fullPath()) hdr = finder.header() dims = hdr['volume_dimension'][:3] vs = hdr['voxel_size'][:3] dims[0] += self.added_border * 2 dims[1] += self.added_border * 2 dims[2] += self.added_border * 2 transfile = context.temporary('Transformation matrix') trans = aims.AffineTransformation3d() trans.setTranslation([ self.added_border * vs[0], self.added_border * vs[1], self.added_border * vs[2] ]) aims.write(trans, transfile.fullPath()) cmd = [ 'AimsResample', '-t', 'n', '-i', self.read, '-o', self.write, '--dx', dims[0], '--dy', dims[1], '--dz', dims[2], '-m', transfile ] context.system(*cmd)
def execution(self, context): csd_model = load(self.csd_model.fullPath()) csd_coeff = aims.read(self.fibre_odf_sh_coeff.fullPath()) h = csd_coeff.header() sh_coeff = np.asarray(csd_coeff) mask_vol = aims.read(self.mask.fullPath()) mask = np.array(mask_vol,copy=False)[...,0].copy() context.write(mask.shape) csd_fit = SphHarmFit(csd_model,sh_coeff, mask) transformManager = getTransformationManager() # Mandatory parameters gfa = csd_fit.gfa GFA = self.array_to_vol(gfa,h) aims.write(GFA, self.generalized_fractionnal_anisotropy.fullPath()) transformManager.copyReferential(self.fibre_odf_sh_coeff, self.generalized_fractionnal_anisotropy) pass
def execution(self, context): #reading object from the lightest to the biggest in memory model = load(self.csd_model.fullPath()) sphere = read_sphere(self.sphere.fullPath()) mask_vol = aims.read(self.mask.fullPath()) mask = vol_to_array(mask_vol) mask = array_to_mask(mask) sh_coeff_vol = aims.read(self.fibre_odf_sh_coeff.fullPath()) hdr = sh_coeff_vol.header() sh_coeff = np.asarray(sh_coeff_vol) context.write("Data were successfully loaded.") spharmfit = SphHarmFit(model, sh_coeff, mask) odf = extract_odf(spharmfit, mask, sphere) #odf = spharmfit.odf(sphere) #do not use the classical dipy function because it compute odf for the whole volume by default and take far too much #memory. odf_vol = array_to_vol(odf, header=hdr) aims.write(odf_vol, self.fibre_odf.fullPath()) pass
def execution(self, context): tensor_coeff = aims.read(self.tensor_coefficients.fullPath()) tensor_params = np.asarray(tensor_coeff) tensor_model = load(self.tensor_model.fullPath()) gtab = tensor_model.gtab #Loading base signal S0 = aims.read(self.S0_signal.fullPath()) S0 = vol_to_array(S0) tenfit = TensorFit(tensor_model, tensor_params) pred_sign = tenfit.predict(gtab=gtab, S0=S0) hdr = tensor_coeff.header() pred_vol = array_to_vol(pred_sign, header=hdr) aims.write(pred_vol, self.predicted_signal.fullPath()) #Handling metada transformManager = getTransformationManager() transformManager.copyReferential(self.predicted_signal, self.tensor_coefficients) context.write("Process finish successfully") pass
def fix_cortex_topology_files(input_filename, output_filename, filling_size, fclosing): """Call highres_cortex.cortex_topo.fix_cortex_topology on files.""" input_volume = aims.read(input_filename) try: output = highres_cortex.cortex_topo.fix_cortex_topology( input_volume, filling_size, fclosing) except OSError as exc: print("error: the VipHomotopic command cannot be" " found or executed ({0}). Please make sure that" " Morphologist is properly installed and that the" " command is in your PATH.".format(exc.strerror)) return 1 except subprocess.CalledProcessError as exc: print("error: the VipHomotopic command returned an error code ({0})." " Please inspect its output above for more information." .format(exc.returncode)) return 1 # BUG: aims.write offers no error checking, so the program will exit # successfully even if writing fails aims.write(output, output_filename)
def _create_truncated_file(self, filename, truncated_filename): ext = filename.split('.')[-1] tmp_file = None if truncated_filename.split('.')[-1] != ext: tmp_file = tempfile.mkstemp(suffix=ext, prefix='morpho') os.close(tmp_file[0]) from soma import aims im = aims.read(filename) aims.write(im, tmp_file[1]) filename = tmp_file[1] del im image_file = open(filename, "rb") image_piece = image_file.read(os.path.getsize(filename)/2) image_file.close() if tmp_file: os.unlink(tmp_file[1]) del tmp_file path = os.path.dirname(truncated_filename) if not os.path.exists(path): os.makedirs(path) truncated_file = open(truncated_filename, "w") truncated_file.write(image_piece) truncated_file.close()
def compute_distmaps_files(classif_filename, output_distwhite_filename, output_distCSF_filename, output_classif_filename): classif = aims.read(classif_filename) dist_from_white = highres_cortex.cortex_topo.signed_distance( classif, [100], [200], 150) aims.write(dist_from_white, output_distwhite_filename) dist_from_CSF = highres_cortex.cortex_topo.signed_distance( classif, [100], [0], 50) aims.write(dist_from_CSF, output_distCSF_filename) aims.write(classif, output_classif_filename)
def voronoiFromTexture(volGW_border, tex, hemi, stopLabel, directory, keyWord): """ This function takes a volume from which ROI will be cut out This volume should be read in with the border = 1 (for later dilation) It also takes a texture labelled (e.g. manually) from which seeds will be taken for the Voronoi classification. # DomainLabel - where to propagate the classification (is taken from the dilated volume) StopLabel - where to stop it directory - is a path where some intermediate file will be written to. Names will include the keyWord This function returns a volume with the selected region """ vs = volGW_border.getVoxelSize()[:3] dims = volGW_border.getSize() c = aims.Converter(intype=volGW_border, outtype=aims.Volume('S16')) volShort = c(volGW_border) volGW_dilated = aimsalgo.AimsMorphoDilation(volShort, 1) # Had problem with some textures: instead of value '10', it was '9.9999999999'. -> use round for i, vertex in enumerate(hemi.vertex()): label = round(tex[0].item(i)) + 1 posVox = (int(round(vertex[0] / vs[0])), int(round(vertex[1] / vs[1])), int(round(vertex[2] / vs[2]))) # print posVox if posVox[0] >= 0 and posVox[0] < dims[0] and posVox[1] >= 0 and posVox[1] < dims[1] and posVox[2] >= 0 and posVox[2] < dims[2]: volGW_dilated.setValue(label, posVox[0], posVox[1], posVox[2]) arrDilated = np.asarray(volGW_dilated.volume()) arrDilated[np.asarray(volGW_border) == 200] = 0 aims.write(volGW_dilated, directory + 'seedsNoWM_%s.nii.gz' %(keyWord)) # Voronoi classification subprocess.call(['AimsVoronoi', '-i', directory + 'seedsNoWM_%s.nii.gz' %(keyWord), '-o', directory + 'voronoi_%s.nii.gz' %(keyWord), '-d', '32767', '-f', str(stopLabel)]) volVoronoi = aims.read(directory + 'voronoi_%s.nii.gz' %(keyWord)) aims.write(volVoronoi, directory + 'outputFromVoronoi_%s.nii.gz' %(keyWord)) # label '0' in texture was transformed into '1'. So we will set all voxels with value '1' to '0' arrVor = np.array(volVoronoi, copy = False) arrVor[arrVor == (stopLabel + 1)] = 0 aims.write(volVoronoi, directory + 'voronoi_%s.nii.gz' %(keyWord)) return(volVoronoi)
def relabel_files(input_filename, output_filename): input_vol = aims.read(input_filename) output_vol = relabel(input_vol) aims.write(output_vol, output_filename)
for s in subj: lmesh_path = '/data/home/virgile/virgile_internship/%s/surf/lh.r.aims.white.mesh' %s rmesh_path = '/data/home/virgile/virgile_internship/%s/surf/rh.r.aims.white.mesh' %s R = aims.Reader() lmesh = R.read(lmesh_path) lvertices += np.asarray(lmesh.vertex()) ltriangles = np.asarray(lmesh.polygon()) rmesh = R.read(rmesh_path) rvertices += np.asarray(rmesh.vertex()) rtriangles = np.asarray(rmesh.polygon()) lvertices /= float(nsubj) rvertices /= float(nsubj) W = aims.Writer() new_rmesh = aims.AimsTimeSurface_3() rvert = new_rmesh.vertex() rpoly = new_rmesh.polygon() rvert.assign([aims.Point3df(x) for x in rvertices]) rpoly.assign([aims.AimsVector_U32_3(x) for x in rtriangles]) aims.write(new_rmesh, '/data/home/virgile/virgile_internship/group/surf/rh.r.aims.white.mesh') new_lmesh = aims.AimsTimeSurface_3() lvert = new_lmesh.vertex() lpoly = new_lmesh.polygon() lvert.assign([aims.Point3df(x) for x in lvertices]) lpoly.assign([aims.AimsVector_U32_3(x) for x in ltriangles]) aims.write(new_lmesh, '/data/home/virgile/virgile_internship/group/surf/lh.r.aims.white.mesh')
if options.classifFile is None: print >> sys.stderr, 'New: exit. no classification file given' sys.exit(1) else: classifFile = options.classifFile if options.resultDir is None: print >> sys.stderr, 'New: exit. no directory for results given' sys.exit(1) else: resultDir = options.resultDir if options.keyWord is None: print >> sys.stderr, 'New: exit. no keyWord given' sys.exit(1) else: keyWord = options.keyWord CSF_labels_on_white = aims.read(heat_CSF) white_labels_on_CSF = aims.read(heat_white) classif = aims.read(classifFile) output = aims.Volume(CSF_labels_on_white) exchangedPropVol = getExchangedPropagationVolume(CSF_labels_on_white, white_labels_on_CSF, classif, resultDir, keyWord) aims.write(exchangedPropVol, resultDir + "exchanged_propvol_%s.nii.gz" %(keyWord))
# in the given directory create the subdirectory for the results if not os.path.exists(result_directory): os.makedirs(result_directory) print '############################################# starting od_heatMain.py #####################################################' #subprocess.check_call(['AimsThreshold', '-b', '-m', 'di', '-t', '100', '-i', pathToClassifFile, '-o', result_directory + 'all_but_cortex_%s.nii' %(keyWord)]) #AimsThreshold -b -m di -t 100 \ #-i ../classif.nii.gz \ #-o ./all_but_cortex.nii volClassif = aims.read(pathToClassifFile) arrClassif = np.array(volClassif, copy = False) arrClassif[arrClassif != 100] = 32767 arrClassif[arrClassif == 100] = 0 aims.write(volClassif, result_directory + 'all_but_cortex_%s.nii' %(keyWord)) # read in the classification file and convert it into float format #AimsFileConvert -t FLOAT \ #-i ../classif.nii.gz \ #-o heat.nii.gz heatmap_before = aims.read(pathToClassifFile, 1) c = aims.Converter(intype = heatmap_before, outtype = aims.Volume('FLOAT')) heatmap_before = c(heatmap_before) aims.write(heatmap_before, result_directory + 'heat_before_%s.nii.gz' %(keyWord)) # Each run refines the previous one # python heat.py 500 0.01 #os.system("time python /volatile/od243208/brainvisa_sources/perso/domanova/trunk/to_sort/Test_lamination_randomized/heat/od_heat.py 500 0.01 result_directory + 'heat_%s.nii' %keyWord result_directory + 'all_but_cortex_%s.nii' %keyWord result_directory + 'heat_%s.nii' %keyWord") # time python /volatile/od243208/python/Test_lamination_randomized/heat/od_heat.py 500 0.01 /volatile/od243208/brainvisa_manual/ml140175/heat_ml140175_L.nii.gz /volatile/od243208/brainvisa_manual/ml140175/all_but_cortex_ml140175_L.nii /volatile/od243208/brainvisa_manual/ml140175/heat_ml140175_L.nii.gz
grad = HalfcentredGradients(heat) gradx, grady, gradz = grad.gradxyz() gradn = np.sqrt(gradx ** 2 + grady ** 2 + gradz ** 2) with np.errstate(divide="ignore", invalid="ignore"): gradx /= gradn grady /= gradn gradz /= gradn grad = HalfcentredGradients(gradx) ggradx = grad.gradx() grad = HalfcentredGradients(grady) ggrady = grad.grady() grad = HalfcentredGradients(gradz) ggradz = grad.gradz() div = ggradx + ggrady + ggradz div_volume = aims.Volume(heatmap_volume) div_volume.fill(float("NaN")) div_array = np.asarray(div_volume) div_array[1:-1, 1:-1, 1:-1] = div # This is needed since AIMS does not silently replace NaN values in input files # by zeros anymore. Without it, ylAdvectTubes ends up interpolating NaN values, # which ends badly. # TODO: remove this horrible hack!!! div_array[np.isnan(div_array)] = 0 aims.write(div_volume, "heat_div_gradn.nii.gz")
if options.keyWord is None: print >> sys.stderr, 'New: exit. No keyword for results was given' sys.exit(1) else: keyWord = options.keyWord # in the given directory create the subdirectory for the results if not os.path.exists(result_directory): os.makedirs(result_directory) print '####################################### starting od_dystmaps.py ##############################################' classif = aims.read(pathToClassifFile) #dist_from_white = highres_cortex.cortex_topo.fastmarching_negative(classif, [100], [200], 150) dist_from_white = highres_cortex.cortex_topo.fastmarching_negative(classif, [100], [200], 150, False) aims.write(dist_from_white, result_directory + 'distwhite_%s.nii.gz' %(keyWord)) print '####################################### done : dist_from_white ###############################################' # need to visualize the distance map. Therefore get all negative values and set them to some positive values volDistFromWhiteCopy = aims.read(result_directory + 'distwhite_%s.nii.gz' %(keyWord)) arrDistFromWhiteCopy = np.array(volDistFromWhiteCopy, copy = False) arrDistFromWhiteCopy[arrDistFromWhiteCopy < 0] = np.max(arrDistFromWhiteCopy) + 5 aims.write(volDistFromWhiteCopy, result_directory + 'distwhiteVisu_%s.nii.gz' %(keyWord)) # now calculate distance to CSF #dist_from_CSF = highres_cortex.cortex_topo.fastmarching_negative(classif, [100], [0], 50) dist_from_CSF = highres_cortex.cortex_topo.fastmarching_negative(classif, [100], [0], 50, False) print '####################################### done : dist_from_CSF #################################################' aims.write(dist_from_CSF, result_directory + 'distCSF_%s.nii.gz' %(keyWord)) volDistFromCSFCopy = aims.read(result_directory + 'distCSF_%s.nii.gz' %(keyWord))
if options.mergedFile is None: print >> sys.stderr, 'New: exit. no mergedFile given' sys.exit(1) else: mergedFile = options.mergedFile if options.resultDir is None: print >> sys.stderr, 'New: exit. no directory for results given' sys.exit(1) else: resultDir = options.resultDir if options.keyWord is None: print >> sys.stderr, 'New: exit. no keyWord given' sys.exit(1) else: keyWord = options.keyWord input_labels = aims.read(mergedFile) output = relabel(input_labels) aims.write(output, resultDir + "merged_relabelled_%s.nii" %(keyWord))
import numpy as np from soma import aims input_labels = aims.read("./merged.nii") def relabel(labels): output = aims.Volume(labels) size_x = output.getSizeX() size_y = output.getSizeY() size_z = output.getSizeZ() old_to_new_labels = {} next_label = 1 for z in xrange(size_z): for y in xrange(size_y): for x in xrange(size_x): label = labels.at(x, y, z) if label == 0: new_label = 0 else: try: new_label = old_to_new_labels[label] except KeyError: new_label = next_label old_to_new_labels[label] = new_label next_label += 1 output.setValue(new_label, x, y, z) return output output = relabel(input_labels) aims.write(output, "merged_relabelled.nii")
parser.add_option('-m', dest='mergedFile', help='mergedFile') parser.add_option('-d', dest='resultDir', help='directory for results') parser.add_option('-k', dest='keyWord', help='keyword for results') options, args = parser.parse_args(sys.argv) print options print args if options.mergedFile is None: print >> sys.stderr, 'New: exit. no mergedFile given' sys.exit(1) else: mergedFile = options.mergedFile if options.resultDir is None: print >> sys.stderr, 'New: exit. no directory for results given' sys.exit(1) else: resultDir = options.resultDir if options.keyWord is None: print >> sys.stderr, 'New: exit. no keyWord given' sys.exit(1) else: keyWord = options.keyWord input_labels = aims.read(mergedFile) output = relabel(input_labels) aims.write(output, resultDir + "merged_randomized_%s.nii.gz" %(keyWord))
def _convert_data(old_name, new_name): print('converting:', old_name, 'to:', new_name) data = aims.read(old_name) aims.write(data, new_name)
# In this respect, the user's attention is drawn to the risks associated # with loading, using, modifying and/or developing or reproducing the # software by the user in light of its specific status of scientific # software, that may mean that it is complicated to manipulate, and that # also therefore means that it is reserved for developers and experienced # professionals having in-depth computer knowledge. Users are therefore # encouraged to load and test the software's suitability as regards their # requirements in conditions enabling the security of their systems and/or # data to be ensured and, more generally, to use and operate it in the # same conditions as regards security. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL licence and that you accept its terms. import numpy as np from soma import aims, aimsalgo import highres_cortex.cortex_topo classif = aims.read("../classif.nii.gz") dist_from_white = highres_cortex.cortex_topo.fastmarching_negative( classif, [100], [200], 150) aims.write(dist_from_white, "./distwhite.nii.gz") dist_from_CSF = highres_cortex.cortex_topo.fastmarching_negative( classif, [100], [0], 50) aims.write(dist_from_CSF, "./distCSF.nii.gz") aims.write(classif, "./classif_with_outer_boundaries.nii.gz")
print >> sys.stderr, 'New: exit. No keyword for results was given' sys.exit(1) else: keyWord = options.keyWord # in the given directory create the subdirectory for the results if not os.path.exists(result_directory): os.makedirs(result_directory) #subprocess.check_call(['time', 'AimsThreshold', '-b', '--fg', '1', '-m', 'eq', '-t', '100', '-i', pathToClassifFile, '-o', result_directory + 'domain_%s.nii' %(keyWord)]) volClassif = aims.read(pathToClassifFile) arrClassif = np.array(volClassif, copy = False) arrClassif[arrClassif != 100] = 0 arrClassif[arrClassif == 100] = 1 aims.write(volClassif, result_directory + 'domain_%s.nii' %(keyWord)) subprocess.check_call(['time', 'ylAdvectTubes', '--verbose', '--step', '0.05', '--domain', result_directory + 'domain_%s.nii' %(keyWord), '--grad-field', heat_directory + 'heat_%s.nii.gz' %(keyWord), '--divergence', heat_directory + 'heat_div_gradn_%s.nii.gz' %(keyWord), '--output-volumes', result_directory + 'white-tube-volumes_%s.nii.gz' % (keyWord), '--output-surfaces', result_directory + 'white-tube-surfaces_%s.nii.gz' % (keyWord)]) # time for the whole cortex : 6m48.759s volWV = aims.read(result_directory + 'white-tube-volumes_%s.nii.gz' % (keyWord)) volWS = aims.read(result_directory + 'white-tube-surfaces_%s.nii.gz' % (keyWord)) volWVS = volWV / volWS aims.write(volWVS, result_directory + 'white-tube-VoverS_%s.nii.gz' % (keyWord)) del volWS, volWVS #time cartoLinearComb.py -f 'I1/I2' \ #-i /volatile/od243208/brainvisa_manual/ml140175/white-tube-volumes_ml140175_L.nii.gz \ #-i /volatile/od243208/brainvisa_manual/ml140175/white-tube-surfaces_ml140175_L.nii.gz \ #-o /volatile/od243208/brainvisa_manual/ml140175/white-tube-VoverS_ml140175_L.nii.gz
# in the given directory create the subdirectory for the results if not os.path.exists(result_directory): os.makedirs(result_directory) print '############################################# starting od_heatMain.py #####################################################' #subprocess.check_call(['AimsThreshold', '-b', '-m', 'di', '-t', '100', '-i', pathToClassifFile, '-o', result_directory + 'all_but_cortex_%s.nii' %(keyWord)]) #AimsThreshold -b -m di -t 100 \ #-i ../classif.nii.gz \ #-o ./all_but_cortex.nii volClassif = aims.read(pathToClassifFile) arrClassif = np.array(volClassif, copy = False) arrClassif[arrClassif != 100] = 32767 arrClassif[arrClassif == 100] = 0 aims.write(volClassif, result_directory + 'all_but_cortex_%s.nii' %(keyWord)) # read in the classification file and convert it into float format #AimsFileConvert -t FLOAT \ #-i ../classif.nii.gz \ #-o heat.nii.gz heatmap_before = aims.read(pathToClassifFile, 1) c = aims.Converter(intype = heatmap_before, outtype = aims.Volume('FLOAT')) heatmap_before = c(heatmap_before) aims.write(heatmap_before, result_directory + 'heat_before_%s.nii.gz' %(keyWord)) statFileName = result_directory + "statFile_%s.txt" %(keyWord) f = open(statFileName, "w") # Each run refines the previous one # python heat.py 500 0.01
# transfT1toT2 = aims.read(pathTot1_to_t2) ###################### todo!!!!!!!!!!!!!! # perform the Voronoi classification in the given GW segmentation volume using the seeds from the texture #print volGWBorder.header() print '######################### start Voronoi #################################' volVoronoi = highres_cortex.od_cutOutRois.voronoiFromTexture(volGWBorder, texture, volHemi, 0, data_directory, keyWord) # created the Voronoi classification that was 'cleaned' from the 'zero' value from texture # update the GW classif file, as now we will work with the selected regions volGW = aims.read(pathToClassifFile) volGWCut = highres_cortex.od_cutOutRois.excludeROI(volGW, volVoronoi, 100, 0) pathToClassifFile = data_directory + 'GWsegm_%s.nii.gz' %(keyWord) aims.write(volGWCut, pathToClassifFile) ############################# 2. eliminate sulci skeletons if requested . update the keyWord ################################# print 'eliminateSulci is ', eliminateSulci, 'type(eliminateSulci) is ', type(eliminateSulci) if eliminateSulci is True: print '###################################### eliminate sulci skeletons #################################################' pathToSulciFile = brainvisa_db_neurospin + realPatientID + '/t1mri/reversed_t1map_2/default_analysis/folds/3.1/default_session_auto/segmentation/%sSulci_%s_default_session_auto.nii.gz' %(realSide, realPatientID) print 'found the sulci skeletons file : ', pathToSulciFile volSulci = aims.read(pathToSulciFile) arrSulci = np.array(volSulci, copy = False) # if Voronoi was performed : eliminate sulci from there. Then correct the volume. Then project onto GW-classification if cutOut is True: print '############################ eliminate sulci skeletons from Voronoi classification ##########################' volVor = aims.read(data_directory + 'voronoi_%s.nii.gz' %(keyWord))
def randomize_labels_files(input_filename, output_filename): input_vol = aims.read(input_filename) output_vol = randomize_labels(input_vol) aims.write(output_vol, output_filename)
keyWord = options.keyWord if options.workOnT1inT2Space is not None: # need to change parameters for the heat equation calculation n_iter = 200 # 500 time_step = 0.04 n_iter2 = 10 # 100 time_step2 = 0.001 # in the given directory create the subdirectory for the results if not os.path.exists(result_directory): os.makedirs(result_directory) print '############################################# starting od_heatMain_NEW.py #####################################################' ############# new version by Yann (July 2015): #ylLaplacian --classif ../classif.nii.gz --output heat.nii.gz subprocess.check_call(['ylLaplacian', '--classif', pathToClassifFile, '--output', result_directory + 'heat_%s.nii.gz' %(keyWord)]) volHeat = aims.read(result_directory + 'heat_%s.nii.gz' %(keyWord)) # Normalized gradient's divergence vol_divGrad = highres_cortex.div_gradn.divergence_gradient(volHeat) aims.write(vol_divGrad, result_directory + "heat_div_gradn_%s.nii.gz" %(keyWord))
import os import sys import numpy as np from soma import aims PRD = os.environ['PRD'] os.chdir(os.path.join(PRD, 'surface')) rl = sys.argv[1] mesh = aims.AimsTimeSurface( 3 ) # a mesh has a header mesh.header()[ 'cortex_high' ] = 'cortex_high' vert = mesh.vertex() poly = mesh.polygon() c = np.loadtxt(rl+'_vertices_high.txt') vert.assign( [ aims.Point3df( x ) for x in c ] ) pol = np.loadtxt(rl+'_triangles_high.txt') poly.assign( [ aims.AimsVector(x, dtype='U32',dim=3) for x in pol ] ) # write result aims.write( mesh, rl+'_mesh_high.mesh' )
"s12898", "s12081", "s12165", "s12207", "s12344", "s12352", "s12370", "s12381", "s12405", "s12414", "s12432", ] # subjects = ['s12207'] for s in subjects: mesh = aims.read("/data/home/virgile/virgile_internship/%s/surf/lh.r.aims.white.normalized.mesh" % s) # anat = aims.read('/data/home/virgile/virgile_internship/s12069/mri/orig/001.nii') anat = aims.read( "/data/home/virgile/virgile_internship/s12069/experiments/smoothed_FWHM5/audio-video_z_map_smin5_theta3.3/leaves.nii" ) z = array(anat.header()["transformations"][0]).reshape(4, 4) for i in range(len(mesh.vertex())): mesh.vertex()[i] = dot(z, hstack((mesh.vertex()[i], [1])))[:3] for p in mesh.polygon(): p[0], p[2] = p[2], p[0] mesh.updateNormals() aims.write(mesh, "/data/home/virgile/virgile_internship/%s/surf/lh.r.white.normalized.gii" % s)
size_y = output.getSizeY() size_z = output.getSizeZ() old_to_new_labels = {} next_label = 1 for z in xrange(size_z): for y in xrange(size_y): for x in xrange(size_x): labels = (labels1.at(x, y, z), labels2.at(x, y, z)) # Negative means outside propagation region if labels[0] < 0 or labels[1] < 0: continue # Zeros are failed propagations, they should not be aggregated # together if labels[0] == 0 or labels[1] == 0: new_label = next_label next_label += 1 else: try: new_label = old_to_new_labels[labels] except KeyError: new_label = next_label old_to_new_labels[labels] = new_label next_label += 1 output.setValue(new_label, x, y, z) sys.stderr.write("{0}: {1} regions in conjunction\n".format(sys.argv[0], next_label - 1)) return output output = relabel_conjunctions(CSF_labels, white_labels) aims.write(output, "conjunction.nii.gz")
def fix_cortex_topology(input_classif, filling_size=2., fclosing=10.): """Fix the topology of a cortical segmentation. The topology of a hollow sphere is imposed onto a voxelwise segmentation of the cortex, which consists of the following labels: Label 0 (`CSF_LABEL`) Outside of the cortex, corresponding to the cerebrospinal fluid, defined in 26-connectivity. Label 100 (`CORTEX_LABEL`) The cortex itself, defined using 6-connectivity. Label 200 (`WHITE_LABEL`) Inside of the cortex, corresponds to the white matter, defined in 26-connectivity. Parameters ---------- classif: aims.Volume The input voxelwise classification. filling_size: float The size, in millimetres, of the largest holes in either cortical boundary that will be filled. This must be kept smaller than the smallest cortical thickness in the image (see `Method` below for a more precise description of this parameter). The default value is 2 mm, which is appropriate for a human brain. fclosing: float The radius, in millimetres, of the morphological closing which is used by VipHomotopic in Cortical surface mode to retrieve the brain's outer envelope. The default value, 10 mm, is appropriate for a human brain. Returns ------- The topology-corrected voxelwise classification is returned in an `aims.Volume_S16`. Raises ------ OSError This function throws ``OSError`` if ``VipHomotopic`` cannot be found or executed. soma.subprocess.CalledProcessError This exception can occur if ``VipHomotopic``, which is in charge of the homotopic morphological operations, terminates with an error. Environment ----------- This function needs the ``VipHomotopic`` command from the Morphologist image segmentation pipeline to reside in the ``PATH``. Note that the original ``VipHomotopic`` has hard-coded limits on the number of iterations for morphological operations, which may be exceeded when working on high-resolution (sub-millimetre) images. Input/output ------------ The command ``VipHomotopic``, which is used to perform the homotopic morphological operations, reports progress on stdout/stderr. Images are passed to ``VipHomotopic`` using files under a temporary directory allocated with `tempfile.mkdtemp`. Method ------ The topology correction is done in two main steps: 1. A topologically spherical bounding box of the brain is computed and dilated towards the inside until it reaches the white matter. This retrieves a topologically correct object which fits the grey--white boundary. 2. The previous object is eroded from the inside in the region where it overlaps with the cortex. This retrieves a topologically correct pial boundary. Each of these main steps is performed in two sub-steps: first the homotopic morpholological operation is performed until a boundary which is dilated by `filling_size`, then to the original boundary. This guides the front propagation, in order to prevent the formation of spurious strands. This method will change voxels from the cortex class to either the white matter or the CSF class, as needed to ensure the topology. Note that the output is not a deterministic function of the input, because the homotopic operations use a pseudo-random order for the front propagation. """ fclosing = float(fclosing) assert fclosing >= 0 filling_size = float(filling_size) assert filling_size >= 0 # VipHomotopic only works with 16-bit signed integer voxels. conv = aims.ShallowConverter(intype=input_classif, outtype="Volume_S16") classif = conv(input_classif) tmp_classif = _prepare_classif_for_VipHomotopic_Cortical(classif, filling_size) tmp_dir = None try: tmp_dir = tempfile.mkdtemp(prefix="highres-cortex.") aims.write(tmp_classif, os.path.join(tmp_dir, "tmp_classif.nii.gz")) del tmp_classif with open(os.path.join(tmp_dir, "fake.han"), "w") as f: f.write("sequence: unknown\n" "gray: mean: 120 sigma: 10\n" "white: mean: 433 sigma: 10\n") # VipHomotopic in Cortical surface mode retrieves a spherical # grey--white boundary by iteratively eroding the bounding box of the # cortex in a homotopic manner. It will proceed in two steps, first # stopping at STEP1_FRONT_BARRIER, and finally at WHITE_LABEL. subprocess.check_call(["VipHomotopic", "-mode", "C", "-input", "tmp_classif.nii.gz", "-classif", "tmp_classif.nii.gz", "-hana", "fake.han", "-fclosing", repr(fclosing), "-output", "cortex.nii.gz"], cwd=tmp_dir) aims.write(classif, os.path.join(tmp_dir, "classif.nii.gz")) # First boundary to guide VipHomotopic (prevent leaking through holes # in sulci). aimsdata_classif = aims.AimsData_S16(classif, 1) # Restore the header (in particular the voxel_size), which may not have # been copied in the constructor because a border is requested. aimsdata_classif.header().update(classif.header()) eroded = aimsalgo.AimsMorphoErosion(aimsdata_classif, filling_size) del classif, aimsdata_classif aims.write(eroded, os.path.join(tmp_dir, "eroded.nii.gz")) del eroded # The spherical grey--white boundary is dilated in a homotopic manner # until the border of eroded_classif is reached. subprocess.check_call(["VipHomotopic", "-mode", "H", "-input", "eroded.nii.gz", "-cortex", "cortex.nii.gz", "-fclosing", "0", "-output", "bigsulci.nii.gz"], cwd=tmp_dir) subprocess.check_call(["VipHomotopic", "-mode", "H", "-input", "classif.nii.gz", "-cortex", "bigsulci.nii.gz", "-fclosing", "0", "-output", "pial_surface.nii.gz"], cwd=tmp_dir) cortex = aims.read(os.path.join(tmp_dir, "cortex.nii.gz")) pial_surface = aims.read(os.path.join(tmp_dir, "pial_surface.nii.gz")) finally: shutil.rmtree(tmp_dir, ignore_errors=True) array_cortex = np.asarray(cortex) array_pial_surface = np.asarray(pial_surface) array_cortex[array_cortex == 0] = 200 array_cortex[array_cortex == 255] = 100 array_cortex[array_pial_surface != 0] = 0 return cortex
import os from soma import aims import numpy PRD = os.environ['PRD'] os.chdir(os.path.join(PRD, 'surface')) mesh = aims.AimsTimeSurface( 3 ) # a mesh has a header mesh.header()[ 'cortex_high' ] = 'cortex_high' vert = mesh.vertex() poly = mesh.polygon() c = numpy.loadtxt('lh_vertices_high.txt') vert.assign( [ aims.Point3df( x ) for x in c ] ) pol = numpy.loadtxt('lh_triangles_high.txt') poly.assign( [ aims.AimsVector(x, dtype='U32',dim=3) for x in pol ] ) # write result aims.write( mesh, 'lh_mesh_high.mesh' )
# brainvisa_db_neurospin + '%s/t1mri/reversed_t1map_2/default_analysis/segmentation/mesh/%s_%shemi.gii' %(realPatientID, realPatientID, realSide) print 'found the hemisphere file : ', fileHemi volHemi = aims.read(fileHemi) #################### problem!!! Texture is still in the "old space". Need to transform it to the new space # read in the transformation file (from T1 into T2 space) # pathTot1_to_t2 = pathToTrm + realPatientID + '/%s_t1_to_t2.trm' % (realPatientID) # transfT1toT2 = aims.read(pathTot1_to_t2) ###################### todo!!!!!!!!!!!!!! # perform the Voronoi classification in the given GW segmentation volume using the seeds from the texture #print volGWBorder.header() print '######################### start Voronoi #################################' aims.write(volGWBorder, data_directory + 'givenToVoronoi_%s.nii.gz' %(keyWord)) # TODO: delete it later volVoronoi = highres_cortex.od_cutOutRois.voronoiFromTexture(volGWBorder, texture, volHemi, 0, data_directory, keyWord) # created the Voronoi classification that was 'cleaned' from the 'zero' value from texture # update the GW classif file, as now we will work with the selected regions volGW = aims.read(pathToClassifFile) volGWCut = highres_cortex.od_cutOutRois.excludeROI(volGW, volVoronoi, 100, 0) pathToClassifFile = data_directory + 'GWsegm_%s.nii.gz' %(keyWord) aims.write(volGWCut, pathToClassifFile) # TODO- delete it after test!!!! #sys.exit(0) ############################# 2. eliminate sulci skeletons if requested . update the keyWord ################################# print 'eliminateSulci is ', eliminateSulci, 'type(eliminateSulci) is ', type(eliminateSulci)