def cortex(t1_file, fsdir, outdir, dest_file=None, prefix="cortex", generate_mask=True, generate_seeds=True): """ Compute a white matter mask and gyri labelization from the FreeSurfer 'white' surface. Parameters ---------- t1_file: str (mandatory) a file containing the t1 image used in FreeSurfer for the segmentation. fsdir: str( mandatory) the subject freesurfer segmentation directory. outdir: str (mandatory) the output directory. dest_file: str (optional, default None) a file containing an image where we want to project the segmentations: an affine transform is used to align this image to the t1 image. prefix: str (optional, default 'cortex') the output files prefix. generate_mask: bool (optional, default True) if True generate a white matter binary mask. generate_seeds: boll (optional, default False) if True create a 'seeds' directory containing all the gyri mask as idenpendent files. Returns ------- mask_file: str the white matter mask image file. label_file: str the gyri label image file. seeds: list of str a list with the seed volumes. """ # Create the output directory if necessary if not os.path.isdir(outdir): os.makedirs(outdir) # Load the dataset t1_image = nibabel.load(t1_file) t1_affine = t1_image.get_affine() # If a destination file is specified register it to the t1 if dest_file is not None: # Load dataset dest_image = nibabel.load(dest_file) dest_affine = dest_image.get_affine() dest_shape = dest_image.get_shape() # In case of temporal serie extract the first volume if len(dest_shape) > 3: temporal_dest_file = dest_file dest_file = os.path.join(outdir, prefix + "_volume-0.nii.gz") extract_image(temporal_dest_file, index=0, out_file=dest_file) dest_shape = dest_shape[:3] # Register destination image to t1 image trf_file = os.path.join(outdir, prefix + "_dest_to_t1.trf") reg_file = os.path.join(outdir, prefix + "_dest_to_t1.nii.gz") flirt(dest_file, t1_file, omat=trf_file, out=reg_file, usesqform=False, cost="normmi", dof=6) voxel_dest_to_t1 = flirt2aff(trf_file, dest_file, t1_file) voxel_t1_to_dest = numpy.linalg.inv(voxel_dest_to_t1) # Otherwise use identity transformation else: trf_file = None reg_file = None dest_affine = t1_affine dest_shape = t1_image.get_shape() voxel_t1_to_dest = numpy.identity(4) # Load the FreeSurfer surface in the 'dest_file' voxel coordinates or # 't1_file' coordinates if not specified t1_physical_to_voxel = numpy.linalg.inv(t1_affine) seg = read_cortex_surface_segmentation(fsdir, t1_physical_to_voxel, voxel_t1_to_dest) # Create a mask of the white matter of both hemisphere if generate_mask: mask_array = seg["lh"].voxelize(dest_shape) mask_array += seg["rh"].voxelize(dest_shape) # Create a gyri label image of both hemisphere label_array = {} try: label_array["lh"], shift_lh = seg["lh"].labelize(dest_shape) label_array["rh"], shift_rh = seg["rh"].labelize(dest_shape, shift_lh) except: if reg_file is not None: raise FSLResultError("flirt") raise # Create the seeds seeds = [] if generate_seeds: seedsdir = os.path.join(outdir, "gyri") if not os.path.isdir(seedsdir): os.mkdir(seedsdir) for hemi in ["lh", "rh"]: surf = seg[hemi] hemi_label_array = label_array[hemi] seed_array = numpy.zeros(hemi_label_array.shape, dtype=hemi_label_array.dtype) for index, item in surf.metadata.items(): if index != 0: if hemi == "rh": index += shift_lh seed_array[numpy.where(hemi_label_array == index)] = 1 seed_file = os.path.join( seedsdir, "{0}-{1}.nii.gz".format(hemi, item["region"])) seed_image = nibabel.Nifti1Image(seed_array, dest_affine) nibabel.save(seed_image, seed_file) seed_array[...] = 0 seeds.append(seed_file) # Save the mask and label images mask_file = None if generate_mask: mask_file = os.path.join(outdir, prefix + "_mask.nii.gz") mask_image = nibabel.Nifti1Image(mask_array, dest_affine) nibabel.save(mask_image, mask_file) label_array = label_array["lh"] + label_array["rh"] label_file = os.path.join(outdir, prefix + "_gyri_labels.nii.gz") label_image = nibabel.Nifti1Image(label_array, dest_affine) nibabel.save(label_image, label_file) return mask_file, label_file, seeds, reg_file, trf_file
sname = label_to_shortname(label, vois) if sname not in HABITAT: continue if tag == 'both': cumul += img3d.get_data() elif tag == sname: # should be edema or enhancement cumul = img3d.get_data() # resample lesion images in MNI 1mm to form a dict indexed by subject tmp_lesion_name = os.path.basename(lesion) res_lesion_name = 'res_{}'.format(tmp_lesion_name) cumul[cumul != 0] = 1 ni.save(ni.Nifti1Image(cumul, affine=vois.affine), tmp_lesion_name) flirt(in_file=tmp_lesion_name, ref_file=aal_name, applyxfm=True, init=path_dict[s]['xfm'][0], out=res_lesion_name, interp='nearestneighbour') resamp_lesion = ni.load(res_lesion_name).get_data() # crawl the AAL labels to count lesions occ to form a dict indexed by l for l in aal_label: # acummulate for the cases with multiples lesions res_dict[s][l] += np.sum(resamp_lesion[aal_dict[l]]) # save as a json for manipulation in R with open("stat_localisation.json", 'w') as fpout: json.dump(res_dict, fpout, indent=4) fpout.write('\n') # move selected files flist = ["stat_localisation.json"] for f in flist:
def get_profile(ico_order, nodif_file, nodifmask_file, seed_file, bedpostx_samples, outdir, t1_file, trf_file, dat_file, fsdir, sid, fsconfig): """ Probabilistic profile Computes the tractography using FSL probtrackx2 and projects the result on the cortical surface using FS mri_vol2surf. Parameters ---------- ico_order: int (mandatory) icosahedron order in [0, 7] that will be used to generate the cortical surface texture at a specific tessalation (the corresponding cortical surface can be resampled using the 'clindmri.segmentation.freesurfer.resample_cortical_surface' function). nodif_file: str (mandatory) file for probtrackx2 containing the no diffusion volume and associated space information. nodifmask_file: str (mandatory) file for probtrackx2 containing the tractography mask (ie., a mask of the white matter). seed_file: str (mandatory) text file for probtrackx2 containing seed coordinates. bedpostx_samples: str (mandatory) path prefix for bedpostX model samples files injected in probtrackx2 (eg., fsl.bedpostX/merged). outdir: str (mandatory) the output directory. t1_file : str (mandatory) T1 image file used to align the produced probabilitic tractography map to the T1 space. trf_file : str (mandatory) diffusion to t1 space affine transformation matrix file. dat_file: str (mandatory) structural to FreeSurfer space affine transformation matrix '.dat' file as computed by 'tkregister2'. fsdir: str (mandatory) FreeSurfer subjects directory 'SUBJECTS_DIR'. sid: str (mandatory) FreeSurfer subject identifier. fsconfig: str (mandatory) the FreeSurfer '.sh' config file. Returns ------- proba_file: str the seed probabilistic tractography volume. textures: dict a dictionary containing the probabilist texture for each hemisphere. """ # Generates the diffusion probability map proba_files, _ = probtrackx2(simple=True, seedref=nodif_file, out="fdt_paths", seed=seed_file, loopcheck=True, onewaycondition=True, samples=bedpostx_samples, mask=nodifmask_file, dir=outdir) # Check that only one 'fdt_paths' has been generated if len(proba_files) != 1: raise Exception("One probabilistic tractography file expected at this " "point: {0}".format(proba_files)) proba_file = proba_files[0] proba_fname = os.path.basename(proba_file).replace(".nii.gz", "") # Apply 'trf_file' affine transformation matrix using FSL flirt function: # probability map (diffusion space) -> probability map (T1 space). flirt_t1_file = os.path.join(outdir, proba_fname + "_t1_flirt.nii.gz") flirt(proba_file, t1_file, out=flirt_t1_file, applyxfm=True, init=trf_file) # Project the volumic probability map (T1 space) generated with FSL flirt # on the cortical surface (Freesurfer space) (both hemispheres) using # Freesurfer's mri_vol2surf and applying the 'dat_file' transformation. textures = {} for hemi in ["lh", "rh"]: prob_texture_file = os.path.join( outdir, "{0}.{1}_vol2surf.mgz".format(hemi, proba_fname)) mri_vol2surf(hemi, flirt_t1_file, prob_texture_file, ico_order, dat_file, fsdir, sid, surface_name="white", fsconfig=fsconfig) textures[hemi] = prob_texture_file return proba_file, textures
infile = args.infile if not os.path.isdir(os.path.dirname(outfile)): os.makedirs(os.path.dirname(outfile)) omatfile = os.path.splitext(outfile)[0] if os.path.splitext(omatfile)[0] != '': omatfile = '{}.txt'.format(os.path.splitext(outfile)[0]) else: omatfile = '{}.txt'.format(omatfile) outfileAxi = '{}/qc_axi.pdf'.format(os.path.dirname(outfile)) outfileSag = '{}/qc_sag.pdf'.format(os.path.dirname(outfile)) # Register : call to the wrapping function flirt(in_file=infile, ref_file=anat, omat=omatfile, out=outfile, cost='mutualinfo', interp='sinc', datatype='float') # QC : pdf sheet bg = nibabel.load(outfile) anat = nibabel.load(anat) # image axial display = plotting.plot_anat(bg, title="T1 Gado contours", display_mode='z', cut_coords=10) display.add_edges(anat) display.savefig(outfileAxi) display.close()
def get_profile(ico_order, nodif_file, nodifmask_file, seed_file, bedpostx_samples, outdir, t1_file, trf_file, dat_file, fsdir, sid, fsconfig): """ Probabilistic profile Computes the tractography using FSL probtrackx2 and projects the result on the cortical surface using FS mri_vol2surf. Parameters ---------- ico_order: int (mandatory) icosahedron order in [0, 7] that will be used to generate the cortical surface texture at a specific tessalation (the corresponding cortical surface can be resampled using the 'clindmri.segmentation.freesurfer.resample_cortical_surface' function). nodif_file: str (mandatory) file for probtrackx2 containing the no diffusion volume and associated space information. nodifmask_file: str (mandatory) file for probtrackx2 containing the tractography mask (ie., a mask of the white matter). seed_file: str (mandatory) text file for probtrackx2 containing seed coordinates. bedpostx_samples: str (mandatory) path prefix for bedpostX model samples files injected in probtrackx2 (eg., fsl.bedpostX/merged). outdir: str (mandatory) the output directory. t1_file : str (mandatory) T1 image file used to align the produced probabilitic tractography map to the T1 space. trf_file : str (mandatory) diffusion to t1 space affine transformation matrix file. dat_file: str (mandatory) structural to FreeSurfer space affine transformation matrix '.dat' file as computed by 'tkregister2'. fsdir: str (mandatory) FreeSurfer subjects directory 'SUBJECTS_DIR'. sid: str (mandatory) FreeSurfer subject identifier. fsconfig: str (mandatory) the FreeSurfer '.sh' config file. Returns ------- proba_file: str the seed probabilistic tractography volume. textures: dict a dictionary containing the probabilist texture for each hemisphere. """ # Generates the diffusion probability map proba_files, _ = probtrackx2( simple=True, seedref=nodif_file, out="fdt_paths", seed=seed_file, loopcheck=True, onewaycondition=True, samples=bedpostx_samples, mask=nodifmask_file, dir=outdir) # Check that only one 'fdt_paths' has been generated if len(proba_files) != 1: raise Exception("One probabilistic tractography file expected at this " "point: {0}".format(proba_files)) proba_file = proba_files[0] proba_fname = os.path.basename(proba_file).replace(".nii.gz", "") # Apply 'trf_file' affine transformation matrix using FSL flirt function: # probability map (diffusion space) -> probability map (T1 space). flirt_t1_file = os.path.join(outdir, proba_fname + "_t1_flirt.nii.gz") flirt(proba_file, t1_file, out=flirt_t1_file, applyxfm=True, init=trf_file) # Project the volumic probability map (T1 space) generated with FSL flirt # on the cortical surface (Freesurfer space) (both hemispheres) using # Freesurfer's mri_vol2surf and applying the 'dat_file' transformation. textures = {} for hemi in ["lh", "rh"]: prob_texture_file = os.path.join( outdir, "{0}.{1}_vol2surf.mgz".format(hemi, proba_fname)) mri_vol2surf(hemi, flirt_t1_file, prob_texture_file, ico_order, dat_file, fsdir, sid, surface_name="white", fsconfig=fsconfig) textures[hemi] = prob_texture_file return proba_file, textures
dat_file = os.path.join(subjdir, "convert", "register.native.dat") if not os.path.isfile(dat_file): raise ValueError("'{0}' has not been generated with the " "'clindmri.scripts.freesurfer_conversion' " "script.".format(dat_file)) """ If no '.trf' file is provided, register the nodif image on the t1 image to get it. """ if trf_file is None: trf_file = os.path.join(connectdir, "dmri_to_t1.trf") reg_file = os.path.join(connectdir, "nodif_to_t1.nii.gz") flirt(nodif_file, t1_file, omat=trf_file, out=reg_file, usesqform=False, cost="normmi", dof=6) """ Launch the tractography on the requested point of the cortical surface on the selected hemisphere """ # Load the white mesh in the diffusion space surface = TriSurface.load(whitefile) voxel_diff_to_t1 = flirt2aff(trf_file, nodif_file, t1_file) voxel_t1_to_diff = numpy.linalg.inv(voxel_diff_to_t1) white_diff_vertices = apply_affine_on_mesh(surface.vertices, voxel_t1_to_diff) # Select the vertices of interest if vertices_indices is None:
if dat_file is None: dat_file = os.path.join(subjdir, "convert", "register.native.dat") if not os.path.isfile(dat_file): raise ValueError("'{0}' has not been generated with the " "'clindmri.scripts.freesurfer_conversion' " "script.".format(dat_file)) """ If no '.trf' file is provided, register the nodif image on the t1 image to get it. """ if trf_file is None: trf_file = os.path.join(connectdir, "dmri_to_t1.trf") reg_file = os.path.join(connectdir, "nodif_to_t1.nii.gz") flirt(nodif_file, t1_file, omat=trf_file, out=reg_file, usesqform=False, cost="normmi", dof=6) """ Launch the tractography on the requested point of the cortical surface on the selected hemisphere """ # Load the white mesh in the diffusion space surface = TriSurface.load(whitefile) voxel_diff_to_t1 = flirt2aff(trf_file, nodif_file, t1_file) voxel_t1_to_diff = numpy.linalg.inv(voxel_diff_to_t1) white_diff_vertices = apply_affine_on_mesh(surface.vertices, voxel_t1_to_diff) # Select the vertices of interest if vertices_indices is None: vertices_indices = range(len(surface.vertices))