Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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
Ejemplo n.º 6
0
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