def extract_nodif_volume(outdir, dwi, bval): """ Parameters ---------- outdir: Str, path to directory where to write "b0.nii.gz" dwi: Str, path to DW data in which at least one volume was acquired with bvalue=0. bval: Str, path to .bval file associated to the DW data. Return ------ nodif_volume: Str, path to a/the volume for which bvalue is 0. <unit> <input name="outdir" type="Directory" /> <input name="dwi" type="File" /> <input name="bval" type="File" /> <output name="nodif_volume" type="File" /> </unit> """ # Get index of the first volume acquired with bvalue=0 b0_index = select_first_b0(bval) # Extract volume to a temporary Nifti nodif_volume = os.path.join(outdir, "nodif.nii.gz") extract_image(dwi, index=b0_index, out_file=nodif_volume) return nodif_volume
--------------------------- We need to generate a mask on which the model is estimated. We first select the first non-diffusion weighted volume of the DTI sequence and then use 'bet2' on this image with a fractional intensity threshold of 0.25 (this is generally a robust threshold to remove unwanted tissue from a non-diffusion weighted image) and the 'm' option that creates a binary 'nodif_brain_mask' image. """ # get the b0 file bvals = numpy.loadtxt(args.bvals_file).tolist() b0_index = bvals.index(0) b0_file = os.path.join(subjdir, "nodif.nii.gz") if not os.path.isfile(b0_file): extract_image( args.diffusion_file, index=b0_index, out_file=b0_file) # Get the qc output directory if args.graphics: qcdir = os.path.join(subjdir, "qc") if not os.path.isdir(qcdir): os.makedirs(qcdir) # create a pdf snap of the b0 image if args.graphics: snap_file = os.path.join(qcdir, "nodif.pdf") plot_image(b0_file, snap_file=snap_file, name="nodif") # generate a brain mask on the corrected b0 data b0_brain_file = os.path.join(subjdir, "nodif_brain")
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
Non-diffusion-weighted mask --------------------------- For probabalistic tractography, we need to generate a mask within which we constrain tractography. We first select the first non-diffusion weighted volume of the DTI sequence and then use 'bet2' on this image with a fractional intensity threshold of 0.25 (this is generally a robust threshold to remove unwanted tissue from a non-diffusion weighted image) and the 'm' option that creates a binary 'nodif_brain_mask' image. """ bvals = numpy.loadtxt(bvals_file).tolist() b0_index = bvals.index(0) b0_file = os.path.join(outdir, "nodif.nii.gz") if not os.path.isfile(b0_file): extract_image(diffusion_file, index=b0_index, out_file=b0_file) snap_file = os.path.join(qcdir, "nodif.pdf") plot_image(b0_file, snap_file=snap_file, name="nodif") b0_brain_file = os.path.join(outdir, "nodif_brain") bet_files = glob.glob(b0_brain_file + "*") if len(bet_files) == 0: (output, mask_file, mesh_file, outline_file, inskull_mask_file, inskull_mesh_file, outskull_mask_file, outskull_mesh_file, outskin_mask_file, outskin_mesh_file, skull_mask_file) = bet2(b0_file, b0_brain_file, m=True, f=0.25) else: mask_file = sorted(bet_files)[0] if not os.path.isfile(mask_file): raise IOError("FileDoesNotExist: '{0}'.".format(mask_file))
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