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
def anatomical_connectivity_matrix(track_file, label_file, t1_file, diffusion_file, trf_file, outdir, symmetric=True): """ Counts the tracks that start and end at each label pair in the anatomical space. Parameters ---------- track_file: str (mandatory) a text file containing tracks. label_file: str (mandatory) a file containing labels that represent a segmentation of the cortex surface. t1_file: str (mandatory) a file containing the t1 image used in FreeSurfer for the segmentation. diffusion_file: str (optional, default None) a file containing the diffusion b0 3d image. trf_file: str (mandatory) a file with the FSL flirt transformation from the diffusion to the t1 spaces. outdir: str (mandatory) the output directory. symmetric: bool (optional, default True) symmetric means we don't distinguish between start and end points. If symmetric is True, 'matrix[i, j] == matrix[j, i]'. Returns ------- matrix: array the number of connection between each pair of regions defined in the 'label_file'. """ # Load the dataset label_image = nibabel.load(label_file) label_array = label_image.get_data() label_shape = label_image.get_shape() tractogram = Tractogram(track_file) affine = flirt2aff(trf_file, diffusion_file, t1_file) # Check the validity of the label array kind = label_array.dtype.kind label_positive = ( (kind == "u") or ((kind == "i") and (label_array.min() >= 0))) if not (label_positive and label_array.ndim == 3): raise ValueError("Label array must be a 3d integer array with " "non-negative label values.") # To compute the connectivity matrix we consider only the first and last # point of each track tractogram.apply_affine(affine) endpoints = tractogram.endpoints().astype(int) pointsx, pointsy, pointsz = endpoints.T # Get labels associted to track end points endlabels = label_array[pointsx, pointsy, pointsz] if symmetric: endlabels.sort(axis=0) matrix = ndbincount(endlabels) if symmetric: matrix = numpy.maximum(matrix, matrix.T) # Remove the connectivity associated to the background matrix = matrix[1:, 1:] # Compute the fiber density map density_map = tractogram.density(shape=label_shape) # Save the resulting connectivity matrix and density map proba_file = os.path.join(outdir, "det_paths.nii.gz") density_image = nibabel.Nifti1Image(density_map, label_image.get_affine()) nibabel.save(density_image, proba_file) network_file = os.path.join(outdir, "det_network_matrix") numpy.savetxt(network_file, matrix) return proba_file, network_file
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)) # Go through all the hemisphere vertices textures = {} for index in vertices_indices: # Select the seeding vertex point = white_diff_vertices[index] # Create a directory for each seeding vertex in order to avoid collision
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)) # Go through all the hemisphere vertices textures = {} for index in vertices_indices: # Select the seeding vertex point = white_diff_vertices[index] # Create a directory for each seeding vertex in order to avoid collision
def anatomical_connectivity_matrix(track_file, label_file, t1_file, diffusion_file, trf_file, outdir, symmetric=True): """ Counts the tracks that start and end at each label pair in the anatomical space. Parameters ---------- track_file: str (mandatory) a text file containing tracks. label_file: str (mandatory) a file containing labels that represent a segmentation of the cortex surface. t1_file: str (mandatory) a file containing the t1 image used in FreeSurfer for the segmentation. diffusion_file: str (optional, default None) a file containing the diffusion b0 3d image. trf_file: str (mandatory) a file with the FSL flirt transformation from the diffusion to the t1 spaces. outdir: str (mandatory) the output directory. symmetric: bool (optional, default True) symmetric means we don't distinguish between start and end points. If symmetric is True, 'matrix[i, j] == matrix[j, i]'. Returns ------- matrix: array the number of connection between each pair of regions defined in the 'label_file'. """ # Load the dataset label_image = nibabel.load(label_file) label_array = label_image.get_data() label_shape = label_image.get_shape() tractogram = Tractogram(track_file) affine = flirt2aff(trf_file, diffusion_file, t1_file) # Check the validity of the label array kind = label_array.dtype.kind label_positive = ((kind == "u") or ((kind == "i") and (label_array.min() >= 0))) if not (label_positive and label_array.ndim == 3): raise ValueError("Label array must be a 3d integer array with " "non-negative label values.") # To compute the connectivity matrix we consider only the first and last # point of each track tractogram.apply_affine(affine) endpoints = tractogram.endpoints().astype(int) pointsx, pointsy, pointsz = endpoints.T # Get labels associted to track end points endlabels = label_array[pointsx, pointsy, pointsz] if symmetric: endlabels.sort(axis=0) matrix = ndbincount(endlabels) if symmetric: matrix = numpy.maximum(matrix, matrix.T) # Remove the connectivity associated to the background matrix = matrix[1:, 1:] # Compute the fiber density map density_map = tractogram.density(shape=label_shape) # Save the resulting connectivity matrix and density map proba_file = os.path.join(outdir, "det_paths.nii.gz") density_image = nibabel.Nifti1Image(density_map, label_image.get_affine()) nibabel.save(density_image, proba_file) network_file = os.path.join(outdir, "det_network_matrix") numpy.savetxt(network_file, matrix) return proba_file, network_file