Exemple #1
0
def qc(t1files, wmfiles, asegfiles, whitefiles, pialfiles, annotfiles,
       actor_ang=[0., 0., 0.], output_directory=None,
       fsconfig="/i2bm/local/freesurfer/SetUpFreeSurfer.sh"):
    """ Compute some quality check plots on the converted FrreSurfer
    outputs.

    The subjecy id in the input files must appear in the -3 position:
        xxx/subject_id/convert/t1.nii.gz

    Steps:

    * t1-images overlays
    * 3d surface segmentation snaps
    * t1-surfaces overlays

    actor_ang: float (optional, default 0)
        the actor rotation in the z direction.

    <unit>
        <input name="t1files" type="List_File" description="The
            t1 subject files."/>
        <input name="wmfiles" type="List_File" description="The
            white matter subject files."/>
        <input name="asegfiles" type="List_File" description="The
            subcortical segmentation subject files."/>
        <input name="output_directory" type="Directory" description="The
            conversion destination folder."/>
        <input name="whitefiles" type="List_File" description="The subject
            cortex surfaces."/>
        <input name="pialfiles" type="List_File" description="The subject pial
            surfaces."/>
        <input name="annotfiles" type="List_File" description="The pial/white
            surface annotations."/>
        <input name="actor_ang" type="List_Float" description="The actor x, y,
            z position (in degrees)."/>
        <input name="fsconfig" type="File" description="The freesurfer
            configuration batch."/>
        <output name="qcfiles" type="List_File" description="The quality check
            snaps."/>
    </unit>
    """
    import clindmri.plot.pvtk as pvtk
    from clindmri.plot.slicer import plot_image

    # Create a t1 subject map
    t1map = {}
    for fname in t1files:
        subject_id = fname.split("/")[-3]
        if subject_id in t1map:
            raise Exception("Can't map two t1 for subject '{0}'"
                            ".".format(subject_id))
        t1map[subject_id] = fname

    # Create the output list that will contain all the qc files
    qcfiles = []

    # Construct the t1-surfaces overlays and the 3d surface segmentation snaps
    ren = pvtk.ren()
    for name, files in [("white", whitefiles), ("pial", pialfiles)]:
        for fname in files:

            # Get the t1 reference image
            subject_id = fname.split("/")[-3]
            t1file = t1map[subject_id]
            t1_image = nibabel.load(t1file)

            # Get the qc output directory
            qcdir = os.path.join(os.path.dirname(fname), "qc")
            qcname = os.path.basename(fname)
            if not os.path.isdir(qcdir):
                os.makedirs(qcdir)

            # Get the triangular mesh
            basename = os.path.basename(fname).replace(
                name, "aparc.annot").replace(".native", "")
            annotfile = os.path.join(os.path.dirname(fname), basename)
            if annotfile not in annotfiles:
                raise ValueError(
                    "Annotation file '{0}' can't be found.".format(annotfile))
            surface = TriSurface.load(fname, annotfile=annotfile)

            # Construct the surfaces binarized volume
            binarizedfile = os.path.join(qcdir, qcname + ".nii.gz")
            overlay = numpy.zeros(t1_image.shape, dtype=numpy.uint)
            indices = numpy.round(surface.vertices).astype(int).T
            indices[0, numpy.where(indices[0] >= t1_image.shape[0])] = 0
            indices[1, numpy.where(indices[1] >= t1_image.shape[1])] = 0
            indices[2, numpy.where(indices[2] >= t1_image.shape[2])] = 0
            overlay[indices.tolist()] = 1
            overlay_image = nibabel.Nifti1Image(overlay, t1_image.get_affine())
            nibabel.save(overlay_image, binarizedfile)
            snap_file = os.path.join(qcdir, qcname + ".png")
            plot_image(t1file, overlay_file=binarizedfile, snap_file=snap_file,
                       name=qcname, overlay_cmap="cold_hot")
            qcfiles.append(snap_file)

            # Create a vtk surface actor of the cortex surface with the
            # associated labels
            ctab = [item["color"] for _, item in surface.metadata.items()]
            actor = pvtk.surface(
                surface.vertices, surface.triangles, surface.labels, ctab)
            actor.RotateX(actor_ang[0])
            actor.RotateY(actor_ang[1])
            actor.RotateZ(actor_ang[2])

            # Create a 3d surface segmentation snap
            pvtk.add(ren, actor)
            snaps = pvtk.record(ren, qcdir, qcname, n_frames=36,
                                az_ang=10, animate=True, delay=50)
            qcfiles.append(snaps[0])
            snaps = pvtk.record(ren, qcdir, qcname + ".3d", n_frames=1)
            qcfiles.append(snaps[0])
            pvtk.clear(ren)

    # Get the FreeSurfer lookup table
    fs_lut_names, fs_lut_colors = parse_fs_lut(os.path.join(
        os.path.dirname(fsconfig), "FreeSurferColorLUT.txt"))
    cmap = []
    nb_values = numpy.asarray(fs_lut_colors.keys()).max()
    cmap = numpy.zeros((nb_values, 4), dtype=numpy.single)
    for key, color in fs_lut_colors.items():
        if key > 0:
            cmap[key - 1, :3] = color
    cmap[:, 3] = 200.
    cmap /= 255.

    # Compute t1-images overlays
    for name, files in [("aseg", asegfiles), ("wm", wmfiles)]:
        for fname in files:

            # Get the t1 reference image
            subject_id = fname.split("/")[-3]
            t1file = t1map[subject_id]
            t1_image = nibabel.load(t1file)

            # Get the qc output directory
            qcdir = os.path.join(os.path.dirname(fname), "qc")
            if not os.path.isdir(qcdir):
                os.makedirs(qcdir)

            # Troncate the color map based on the label max
            array = nibabel.load(fname).get_data()
            order = sorted(set(array.flatten()))
            ccmap = cmap[order[1]: order[-1] + 1]

            # Overlay the current image with the t1 image
            qcname = "t1-{0}".format(name)
            snap_file = os.path.join(qcdir, qcname + ".png")
            plot_image(t1file, overlay_file=fname, snap_file=snap_file,
                       name=qcname, overlay_cmap=ccmap, cut_coords=(0, 0, 0))
            qcfiles.append(snap_file)

    return qcfiles
Exemple #2
0
def qc_profile(nodif_file,
               proba_file,
               proba_texture,
               ico_order,
               fsdir,
               sid,
               outdir,
               fsconfig,
               actor_ang=(0., 0., 0.)):
    """ Connectivity profile QC.

    Generates views of:
    - the superposition of the nodif image with tractography result volume.
    - the connected points on the cortical surface
    Resample cortical meshes if needed.
    Results output are available as gif and png.

    Parameters
    ----------
    nodif_file: str (mandatory)
        file for probtrackx2 containing the no diffusion volume and associated
        space information.
    proba_file: str (mandatory)
        the protrackx2 output seeding probabilistic path volume.
    proba_texture: dict (mandatory)
        the FreeSurfer mri_vol2surf '.mgz' 'lh' and 'rh' textrue that contains
        the cortiacal connection strength.
    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).
    fsdir: str (mandatory)
        FreeSurfer subjects directory 'SUBJECTS_DIR'.
    sid: str (mandatory)
        FreeSurfer subject identifier.
    outdir: str (mandatory)
        The QC output directory.
    fsconfig: str (mandatory)
        the FreeSurfer '.sh' config file.
    actor_ang: 3-uplet (optinal, default (0, 0, 0))
        the actor x, y, z position (in degrees).

    Returns
    -------
    snaps: list of str
        two gifs images, one showing the connection profile as a texture on
        the cortical surface, the other a volumic representation of the
        deterministic tractography.
    """
    import clindmri.plot.pvtk as pvtk
    from clindmri.plot.slicer import animate_image

    # Construct/check the subject directory
    subjectdir = os.path.join(fsdir, sid)
    if not os.path.isdir(subjectdir):
        raise ValueError(
            "'{0}' is not a FreeSurfer subject directory.".format(subjectdir))

    # Check that the output QC directory exists
    if not os.path.isdir(outdir):
        os.makedirs(outdir)

    # Superpose the nodif and probabilistic tractography volumes
    proba_shape = nibabel.load(proba_file).shape
    snaps = []
    snaps.append(
        animate_image(nodif_file,
                      overlay_file=proba_file,
                      clean=True,
                      overlay_cmap="Spectral",
                      cut_coords=proba_shape[2],
                      outdir=outdir))

    # Define a renderer
    ren = pvtk.ren()

    # For each hemisphere
    for hemi in ["lh", "rh"]:

        # Get the the white mesh on the desired icosphere
        meshfile = os.path.join(subjectdir, "convert",
                                "{0}.white.{1}.native".format(hemi, ico_order))
        if not os.path.isfile(meshfile):
            raise ValueError(
                "'{0}' is not a valid white mesh. Generate it through the "
                "'clindmri.scripts.freesurfer_conversion' script.".format(
                    meshfile))

        # Check texture has the expected extension, size
        texture_file = proba_texture[hemi]
        if not texture_file.endswith(".mgz"):
            raise ValueError("'{0}' is not a '.mgz' file. Format not "
                             "supported.".format(texture_file))
        profile_array = nibabel.load(texture_file).get_data()
        profile_dim = profile_array.ndim
        profile_shape = profile_array.shape
        if profile_dim != 3:
            raise ValueError(
                "Expected profile texture array of dimension 3 not "
                "'{0}'".format(profile_dim))
        if (profile_shape[1] != 1) or (profile_shape[2] != 1):
            raise ValueError(
                "Expected profile texture array of shape (*, 1, 1) not "
                "'{0}'.".format(profile_shape))

        # Flatten the profile texture array
        texture = profile_array.ravel()

        # Load the white mesh
        surface = TriSurface.load(meshfile)

        # Define a textured surface actor
        actor = pvtk.surface(surface.vertices, surface.triangles, texture)
        actor.RotateX(actor_ang[0])
        actor.RotateY(actor_ang[1])
        actor.RotateZ(actor_ang[2])
        pvtk.add(ren, actor)

    # Create a animaton with the generated surface
    qcname = "profile_as_texture"
    snaps.extend(
        pvtk.record(ren,
                    outdir,
                    qcname,
                    n_frames=36,
                    az_ang=10,
                    animate=True,
                    delay=10))

    return snaps
mesharray = numpy.zeros(t1shape, dtype=numpy.uint)
for basename in surf:
    # > construc path
    fpath = os.path.join(mripath, basename)
    if not os.path.isfile(fpath):
        raise ValueError("'{0}' is not a valid file name.".format(fpath))
    surf[basename] = fpath

    # > load mesh
    name = basename.split(".")[1]
    annot_basename = basename.replace(
        name, "aparc.annot").replace(".native", "")
    annotfile = os.path.join(mripath, annot_basename)
    if not os.path.isfile(fpath):
        raise ValueError("'{0}' is not a valid file name.".format(fpath))
    surface = TriSurface.load(fpath, annotfile=annotfile)

    # > binarize mesh
    indices = numpy.round(surface.vertices).astype(int).T
    indices[0, numpy.where(indices[0] >= t1shape[0])] = 0
    indices[1, numpy.where(indices[1] >= t1shape[1])] = 0
    indices[2, numpy.where(indices[2] >= t1shape[2])] = 0
    mesharray[indices.tolist()] = colors[basename]

# Save the mesh volume
meshim = nibabel.Nifti1Image(mesharray, t1affine)
nibabel.save(meshim, meshfile)

# Need to reorient the image to MNI standard space
reomeshfile = os.path.join(qcdir, "reo." + os.path.basename(meshfile))
fslreorient2std(meshfile, reomeshfile, shfile=fslconfig)
Exemple #4
0
def qc(t1files,
       wmfiles,
       asegfiles,
       whitefiles,
       pialfiles,
       annotfiles,
       actor_ang=[0., 0., 0.],
       output_directory=None,
       fsconfig="/i2bm/local/freesurfer/SetUpFreeSurfer.sh"):
    """ Compute some quality check plots on the converted FrreSurfer
    outputs.

    The subjecy id in the input files must appear in the -3 position:
        xxx/subject_id/convert/t1.nii.gz

    Steps:

    * t1-images overlays
    * 3d surface segmentation snaps
    * t1-surfaces overlays

    actor_ang: float (optional, default 0)
        the actor rotation in the z direction.

    <unit>
        <input name="t1files" type="List_File" description="The
            t1 subject files."/>
        <input name="wmfiles" type="List_File" description="The
            white matter subject files."/>
        <input name="asegfiles" type="List_File" description="The
            subcortical segmentation subject files."/>
        <input name="output_directory" type="Directory" description="The
            conversion destination folder."/>
        <input name="whitefiles" type="List_File" description="The subject
            cortex surfaces."/>
        <input name="pialfiles" type="List_File" description="The subject pial
            surfaces."/>
        <input name="annotfiles" type="List_File" description="The pial/white
            surface annotations."/>
        <input name="actor_ang" type="List_Float" description="The actor x, y,
            z position (in degrees)."/>
        <input name="fsconfig" type="File" description="The freesurfer
            configuration batch."/>
        <output name="qcfiles" type="List_File" description="The quality check
            snaps."/>
    </unit>
    """
    import clindmri.plot.pvtk as pvtk
    from clindmri.plot.slicer import plot_image

    # Create a t1 subject map
    t1map = {}
    for fname in t1files:
        subject_id = fname.split("/")[-3]
        if subject_id in t1map:
            raise Exception("Can't map two t1 for subject '{0}'"
                            ".".format(subject_id))
        t1map[subject_id] = fname

    # Create the output list that will contain all the qc files
    qcfiles = []

    # Construct the t1-surfaces overlays and the 3d surface segmentation snaps
    ren = pvtk.ren()
    for name, files in [("white", whitefiles), ("pial", pialfiles)]:
        for fname in files:

            # Get the t1 reference image
            subject_id = fname.split("/")[-3]
            t1file = t1map[subject_id]
            t1_image = nibabel.load(t1file)

            # Get the qc output directory
            qcdir = os.path.join(os.path.dirname(fname), "qc")
            qcname = os.path.basename(fname)
            if not os.path.isdir(qcdir):
                os.makedirs(qcdir)

            # Get the triangular mesh
            basename = os.path.basename(fname).replace(name,
                                                       "aparc.annot").replace(
                                                           ".native", "")
            annotfile = os.path.join(os.path.dirname(fname), basename)
            if annotfile not in annotfiles:
                raise ValueError(
                    "Annotation file '{0}' can't be found.".format(annotfile))
            surface = TriSurface.load(fname, annotfile=annotfile)

            # Construct the surfaces binarized volume
            binarizedfile = os.path.join(qcdir, qcname + ".nii.gz")
            overlay = numpy.zeros(t1_image.shape, dtype=numpy.uint)
            indices = numpy.round(surface.vertices).astype(int).T
            indices[0, numpy.where(indices[0] >= t1_image.shape[0])] = 0
            indices[1, numpy.where(indices[1] >= t1_image.shape[1])] = 0
            indices[2, numpy.where(indices[2] >= t1_image.shape[2])] = 0
            overlay[indices.tolist()] = 1
            overlay_image = nibabel.Nifti1Image(overlay, t1_image.get_affine())
            nibabel.save(overlay_image, binarizedfile)
            snap_file = os.path.join(qcdir, qcname + ".png")
            plot_image(t1file,
                       overlay_file=binarizedfile,
                       snap_file=snap_file,
                       name=qcname,
                       overlay_cmap="cold_hot")
            qcfiles.append(snap_file)

            # Create a vtk surface actor of the cortex surface with the
            # associated labels
            ctab = [item["color"] for _, item in surface.metadata.items()]
            actor = pvtk.surface(surface.vertices, surface.triangles,
                                 surface.labels, ctab)
            actor.RotateX(actor_ang[0])
            actor.RotateY(actor_ang[1])
            actor.RotateZ(actor_ang[2])

            # Create a 3d surface segmentation snap
            pvtk.add(ren, actor)
            snaps = pvtk.record(ren,
                                qcdir,
                                qcname,
                                n_frames=36,
                                az_ang=10,
                                animate=True,
                                delay=50)
            qcfiles.append(snaps[0])
            snaps = pvtk.record(ren, qcdir, qcname + ".3d", n_frames=1)
            qcfiles.append(snaps[0])
            pvtk.clear(ren)

    # Get the FreeSurfer lookup table
    fs_lut_names, fs_lut_colors = parse_fs_lut(
        os.path.join(os.path.dirname(fsconfig), "FreeSurferColorLUT.txt"))
    cmap = []
    nb_values = numpy.asarray(fs_lut_colors.keys()).max()
    cmap = numpy.zeros((nb_values, 4), dtype=numpy.single)
    for key, color in fs_lut_colors.items():
        if key > 0:
            cmap[key - 1, :3] = color
    cmap[:, 3] = 200.
    cmap /= 255.

    # Compute t1-images overlays
    for name, files in [("aseg", asegfiles), ("wm", wmfiles)]:
        for fname in files:

            # Get the t1 reference image
            subject_id = fname.split("/")[-3]
            t1file = t1map[subject_id]
            t1_image = nibabel.load(t1file)

            # Get the qc output directory
            qcdir = os.path.join(os.path.dirname(fname), "qc")
            if not os.path.isdir(qcdir):
                os.makedirs(qcdir)

            # Troncate the color map based on the label max
            array = nibabel.load(fname).get_data()
            order = sorted(set(array.flatten()))
            ccmap = cmap[order[1]:order[-1] + 1]

            # Overlay the current image with the t1 image
            qcname = "t1-{0}".format(name)
            snap_file = os.path.join(qcdir, qcname + ".png")
            plot_image(t1file,
                       overlay_file=fname,
                       snap_file=snap_file,
                       name=qcname,
                       overlay_cmap=ccmap,
                       cut_coords=(0, 0, 0))
            qcfiles.append(snap_file)

    return qcfiles
Exemple #5
0
def qc_profile(nodif_file, proba_file, proba_texture,  ico_order,
               fsdir, sid, outdir, fsconfig, actor_ang=(0., 0., 0.)):
    """ Connectivity profile QC.

    Generates views of:
    - the superposition of the nodif image with tractography result volume.
    - the connected points on the cortical surface
    Resample cortical meshes if needed.
    Results output are available as gif and png.

    Parameters
    ----------
    nodif_file: str (mandatory)
        file for probtrackx2 containing the no diffusion volume and associated
        space information.
    proba_file: str (mandatory)
        the protrackx2 output seeding probabilistic path volume.
    proba_texture: dict (mandatory)
        the FreeSurfer mri_vol2surf '.mgz' 'lh' and 'rh' textrue that contains
        the cortiacal connection strength.
    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).
    fsdir: str (mandatory)
        FreeSurfer subjects directory 'SUBJECTS_DIR'.
    sid: str (mandatory)
        FreeSurfer subject identifier.
    outdir: str (mandatory)
        The QC output directory.
    fsconfig: str (mandatory)
        the FreeSurfer '.sh' config file.
    actor_ang: 3-uplet (optinal, default (0, 0, 0))
        the actor x, y, z position (in degrees).

    Returns
    -------
    snaps: list of str
        two gifs images, one showing the connection profile as a texture on
        the cortical surface, the other a volumic representation of the
        deterministic tractography.
    """
    import clindmri.plot.pvtk as pvtk
    from clindmri.plot.slicer import animate_image

    # Construct/check the subject directory
    subjectdir = os.path.join(fsdir, sid)
    if not os.path.isdir(subjectdir):
        raise ValueError(
            "'{0}' is not a FreeSurfer subject directory.".format(subjectdir))

    # Check that the output QC directory exists
    if not os.path.isdir(outdir):
        os.makedirs(outdir)

    # Superpose the nodif and probabilistic tractography volumes
    proba_shape = nibabel.load(proba_file).shape
    snaps = []
    snaps.append(
        animate_image(nodif_file, overlay_file=proba_file, clean=True,
                      overlay_cmap="Spectral", cut_coords=proba_shape[2],
                      outdir=outdir))

    # Define a renderer
    ren = pvtk.ren()

    # For each hemisphere
    for hemi in ["lh", "rh"]:

        # Get the the white mesh on the desired icosphere
        meshfile = os.path.join(
            subjectdir, "convert", "{0}.white.{1}.native".format(
                hemi, ico_order))
        if not os.path.isfile(meshfile):
            raise ValueError(
                "'{0}' is not a valid white mesh. Generate it through the "
                "'clindmri.scripts.freesurfer_conversion' script.".format(
                    meshfile))

        # Check texture has the expected extension, size
        texture_file = proba_texture[hemi]
        if not texture_file.endswith(".mgz"):
            raise ValueError("'{0}' is not a '.mgz' file. Format not "
                             "supported.".format(texture_file))
        profile_array = nibabel.load(texture_file).get_data()
        profile_dim = profile_array.ndim
        profile_shape = profile_array.shape
        if profile_dim != 3:
            raise ValueError(
                "Expected profile texture array of dimension 3 not "
                "'{0}'".format(profile_dim))
        if (profile_shape[1] != 1) or (profile_shape[2] != 1):
            raise ValueError(
                "Expected profile texture array of shape (*, 1, 1) not "
                "'{0}'.".format(profile_shape))

        # Flatten the profile texture array
        texture = profile_array.ravel()

        # Load the white mesh
        surface = TriSurface.load(meshfile)

        # Define a textured surface actor
        actor = pvtk.surface(surface.vertices, surface.triangles, texture)
        actor.RotateX(actor_ang[0])
        actor.RotateY(actor_ang[1])
        actor.RotateZ(actor_ang[2])
        pvtk.add(ren, actor)

    # Create a animaton with the generated surface
    qcname = "profile_as_texture"
    snaps.extend(
        pvtk.record(ren, outdir, qcname, n_frames=36, az_ang=10, animate=True,
                    delay=10))

    return snaps
Exemple #6
0
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]
Exemple #7
0
mesharray = numpy.zeros(t1shape, dtype=numpy.uint)
for basename in surf:
    # > construc path
    fpath = os.path.join(mripath, basename)
    if not os.path.isfile(fpath):
        raise ValueError("'{0}' is not a valid file name.".format(fpath))
    surf[basename] = fpath

    # > load mesh
    name = basename.split(".")[1]
    annot_basename = basename.replace(name,
                                      "aparc.annot").replace(".native", "")
    annotfile = os.path.join(mripath, annot_basename)
    if not os.path.isfile(fpath):
        raise ValueError("'{0}' is not a valid file name.".format(fpath))
    surface = TriSurface.load(fpath, annotfile=annotfile)

    # > binarize mesh
    indices = numpy.round(surface.vertices).astype(int).T
    indices[0, numpy.where(indices[0] >= t1shape[0])] = 0
    indices[1, numpy.where(indices[1] >= t1shape[1])] = 0
    indices[2, numpy.where(indices[2] >= t1shape[2])] = 0
    mesharray[indices.tolist()] = colors[basename]

# Save the mesh volume
meshim = nibabel.Nifti1Image(mesharray, t1affine)
nibabel.save(meshim, meshfile)

# Need to reorient the image to MNI standard space
reomeshfile = os.path.join(qcdir, "reo." + os.path.basename(meshfile))
fslreorient2std(meshfile, reomeshfile, shfile=fslconfig)
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))

# Go through all the hemisphere vertices
textures = {}
for index in vertices_indices:

    # Select the seeding vertex
    point = white_diff_vertices[index]