예제 #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
예제 #2
0
                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:
예제 #3
0
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
예제 #4
0
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()
예제 #5
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
예제 #6
0
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
예제 #7
0
    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))