Exemple #1
0
                                  write_output=True)

    _ = expand_coordinate_mapping(os.path.join(path_output,
                                               "target2source.nii.gz"),
                                  path_output,
                                  name_output="target2source",
                                  write_output=True)
"""
apply deformation
"""
# source -> target
apply_coordinate_mappings(
    file_mean_epi_source,  # input 
    os.path.join(path_output, "source2target.nii.gz"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="source2target_example"  # base name with file extension for output
)

# target -> source
apply_coordinate_mappings(
    file_mean_epi_target,  # input 
    os.path.join(path_output, "target2source.nii.gz"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="target2source_example"  # base name with file extension for output
Exemple #2
0
if not os.path.exists(path_output):
    os.makedirs(path_output)

if not os.path.exists(path_levelset):
    os.makedirs(path_levelset)

if not os.path.exists(path_border):
    os.makedirs(path_border)

# deformation
if file_deformation is not None:
    wm_label = apply_coordinate_mappings(
        file_wm,  # input 
        file_deformation,  # cmap
        interpolation="nearest",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,  # save output data to file (boolean)
        overwrite=False,  # overwrite existing results (boolean)
        output_dir=None,  # output directory
        file_name=None  # base name with file extension for output
    )

    csf_label = apply_coordinate_mappings(
        file_csf,  # input 
        file_deformation,  # cmap
        interpolation="nearest",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,  # save output data to file (boolean)
        overwrite=False,  # overwrite existing results (boolean)
        output_dir=None,  # output directory
        file_name=None  # base name with file extension for output
    )
Exemple #3
0
""" do not edit below """

# output folders
path_def = os.path.join(path_output,"def")
path_surf = os.path.join(path_output,"surf")

for i in range(len(file_in)):
    
    # apply deformation    
    if deformation_in1 is not None:
        apply_coordinate_mappings(file_in[i], 
                                  deformation_in1,
                                  deformation_in2, 
                                  interpolation=interpolation, 
                                  padding='closest', 
                                  save_data=True, 
                                  overwrite=True, 
                                  output_dir=path_def,
                                  file_name=None,
                                  )
    
    # get filename of deformed file
    if deformation_in1 is not None:
        _, name_file, _ = get_filename(file_in[i])
        filename_def = os.path.join(path_def, name_file+"_def-img.nii") 
    else:
        filename_def = file_in[i]
        
    # map to ana
    for j in range(len(surf_in)):
        
Exemple #4
0
def get_flash2orig(file_flash,
                   file_inv2,
                   file_orig,
                   path_output,
                   cleanup=False):
    """
    This function computes the deformation field for the registration between a partial coverage
    GRE image and the freesurfer orig file. The following steps are performed: (1) set output 
    folder structure, (2) get scanner transform GRE <-> inv2 and inv2 -> orig, (3) generate flash
    cmap, (4) apply scanner transform inv2 -> GRE, (5) get flirt registration GRE -> inv2, (6) apply
    flirt to GRE cmap, (7) apply scanner transform to GRE cmap, (8) apply final deformation to GRE.
    The function needs the FSL environment set.
    Inputs:
        *file_flash: input path for GRE image.
        *file_inv2: input path for MP2RAGE INV2 image.
        *file_orig: input path for freesurfer orig image.
        *path_output: path where output is saved.
        *cleanup: delete intermediate files (boolean).
    
    created by Daniel Haenelt
    Date created: 18-04-2019
    Last modified: 16-05-2019
    """
    import os
    import shutil as sh
    from nipype.interfaces.fsl import FLIRT
    from nipype.interfaces.fsl.preprocess import ApplyXFM
    from nipype.interfaces.freesurfer.preprocess import MRIConvert
    from nighres.registration import apply_coordinate_mappings
    from lib.cmap import generate_coordinate_mapping
    from lib.registration.get_scanner_transform import get_scanner_transform
    """
    set folder structure
    """
    path_temp = os.path.join(path_output, "temp")

    if not os.path.exists(path_output):
        os.makedirs(path_output)

    if not os.path.exists(path_temp):
        os.makedirs(path_temp)

    # copy input files
    sh.copyfile(file_inv2, os.path.join(path_temp, "inv2.nii"))
    sh.copyfile(file_flash, os.path.join(path_temp, "flash.nii"))
    """
    convert orig to nifti
    """
    mc = MRIConvert()
    mc.inputs.in_file = file_orig
    mc.inputs.out_file = os.path.join(path_temp, "orig.nii")
    mc.inputs.in_type = "mgz"
    mc.inputs.out_type = "nii"
    mc.run()
    """
    scanner transformation
    """
    get_scanner_transform(os.path.join(path_temp, "inv2.nii"),
                          os.path.join(path_temp, "flash.nii"), path_temp,
                          False)
    get_scanner_transform(os.path.join(path_temp, "flash.nii"),
                          os.path.join(path_temp, "inv2.nii"), path_temp,
                          False)
    get_scanner_transform(os.path.join(path_temp, "inv2.nii"),
                          os.path.join(path_temp, "orig.nii"), path_temp,
                          False)
    """
    generate coordinate mapping
    """
    generate_coordinate_mapping(os.path.join(path_temp, "flash.nii"), 0,
                                path_temp, "flash", False, True)
    """
    scanner transform inv2 to flash
    """
    apply_coordinate_mappings(
        os.path.join(path_temp, "inv2.nii"),  # input 
        os.path.join(path_temp, "inv2_2_flash_scanner.nii"),  # cmap
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=True,  # save output data to file (boolean)
        overwrite=True,  # overwrite existing results (boolean)
        output_dir=path_temp,  # output directory
        file_name=
        "inv2_apply_scanner"  # base name with file extension for output
    )
    """
    flirt flash to inv2
    """
    os.chdir(path_temp)
    flirt = FLIRT()
    flirt.inputs.cost_func = "mutualinfo"
    flirt.inputs.dof = 6
    flirt.inputs.interp = "trilinear"  # trilinear, nearestneighbour, sinc or spline
    flirt.inputs.in_file = os.path.join(path_temp, "flash.nii")
    flirt.inputs.reference = os.path.join(path_temp,
                                          "inv2_apply_scanner_def-img.nii.gz")
    flirt.inputs.output_type = "NIFTI_GZ"
    flirt.inputs.out_file = os.path.join(path_temp,
                                         "flash_apply_flirt_def-img.nii.gz")
    flirt.inputs.out_matrix_file = os.path.join(path_temp, "flirt_matrix.txt")
    flirt.run()
    """
    apply flirt to flash cmap
    """
    applyxfm = ApplyXFM()
    applyxfm.inputs.in_file = os.path.join(path_temp, "cmap_flash.nii")
    applyxfm.inputs.reference = os.path.join(path_temp, "flash.nii")
    applyxfm.inputs.in_matrix_file = os.path.join(path_temp,
                                                  "flirt_matrix.txt")
    applyxfm.inputs.interp = "trilinear"
    applyxfm.inputs.padding_size = 0
    applyxfm.inputs.output_type = "NIFTI_GZ"
    applyxfm.inputs.out_file = os.path.join(path_temp,
                                            "cmap_apply_flirt_def-img.nii.gz")
    applyxfm.inputs.apply_xfm = True
    applyxfm.run()
    """
    apply scanner transform to flash cmap
    """
    apply_coordinate_mappings(
        os.path.join(path_temp, "cmap_apply_flirt_def-img.nii.gz"),
        os.path.join(path_temp, "flash_2_inv2_scanner.nii"),  # cmap 1
        os.path.join(path_temp, "inv2_2_orig_scanner.nii"),  # cmap 2
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=True,  # save output data to file (boolean)
        overwrite=True,  # overwrite existing results (boolean)
        output_dir=path_temp,  # output directory
        file_name=
        "cmap_apply_scanner"  # base name with file extension for output
    )
    """
    apply deformation to source image
    """
    apply_coordinate_mappings(
        os.path.join(path_temp, "flash.nii"),  # input 
        os.path.join(path_temp, "cmap_apply_scanner_def-img.nii.gz"),
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=True,  # save output data to file (boolean)
        overwrite=True,  # overwrite existing results (boolean)
        output_dir=path_temp,  # output directory
        file_name=
        "flash_apply_deformation"  # base name with file extension for output
    )

    # rename final deformation examples
    os.rename(os.path.join(path_temp, "cmap_apply_scanner_def-img.nii.gz"),
              os.path.join(path_output, "flash2orig.nii.gz"))
    os.rename(
        os.path.join(path_temp, "flash_apply_deformation_def-img.nii.gz"),
        os.path.join(path_output, "flash2orig_example.nii.gz"))

    # clean intermediate files
    if cleanup:
        sh.rmtree(path_temp, ignore_errors=True)
Exemple #5
0
get_scanner_transform(os.path.join(path_mpm, "mpm_t1.nii"),
                      os.path.join(path_mp2rage, "mp2rage_t1.nii"),
                      path_deformation, False)

get_scanner_transform(os.path.join(path_mp2rage, "mp2rage_t1.nii"),
                      os.path.join(path_mpm, "mpm_t1.nii"), path_deformation,
                      False)

# apply scanner transformation to MPM
apply_coordinate_mappings(
    os.path.join(path_mpm, "mpm_t1.nii"),  # input
    os.path.join(path_deformation,
                 "mpm_t1_2_mp2rage_t1_scanner.nii"),  # first cmap
    mapping2=None,  # second cmap
    mapping3=None,  # third cmap
    mapping4=None,  # fourth cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_mpm,  # output directory
    file_name="scanner"  # base name with file extension for output
)

# flirt
os.chdir(path_deformation)
flirt = FLIRT()
flirt.inputs.cost_func = "corratio"
flirt.inputs.dof = 6
flirt.inputs.interp = "trilinear"  # trilinear, nearestneighbour, sinc or spline
flirt.inputs.in_file = os.path.join(path_mpm, "scanner_def-img.nii.gz")
flirt.inputs.reference = os.path.join(path_mp2rage, "mp2rage_t1.nii")
Exemple #6
0
def mask_epi(file_epi, file_t1, file_mask, niter, sigma, file_reg=""):
    """
    This function masks a mean epi image based on a skullstrip mask of the 
    corresponding anatomy. The mask is transformed to native epi space via an
    initial transformation or via scanner coordinates. A rigid registration is
    applied to ensure a match between mask and epi. Finally, holes in the mask 
    are filled, the mask is dilated and a Gaussian filter is applied. The masked 
    epi is saved in the same folder with the prefix p.
    Inputs:
        *file_epi: input mean epi image.
        *file_t1: input of corresponding skullstripped anatomy.
        *file_mask: input of skullstrip mask of the corresponding anatomy.
        *niter: number of dilation iterations.
        *sigma: gaussian smoothing kernel.
        *file_reg: filename of ana -> epi coordinate mapping.
        
    created by Daniel Haenelt
    Date created: 13-02-2019
    Last modified: 10-09-2020
    """
    import os
    import numpy as np
    import nibabel as nb
    import shutil as sh
    from scipy.ndimage import binary_fill_holes, gaussian_filter
    from scipy.ndimage.morphology import binary_dilation
    from nighres.registration import embedded_antsreg, apply_coordinate_mappings
    from lib.registration.get_scanner_transform import get_scanner_transform
    from lib.io.get_filename import get_filename
    from lib.cmap.expand_coordinate_mapping import expand_coordinate_mapping

    # get paths and filenames
    path_t1, name_t1, _ = get_filename(file_t1)
    path_epi, name_epi, _ = get_filename(file_epi)

    if file_reg:
        _, _, ext_reg = get_filename(file_reg)
    else:
        ext_reg = '.nii.gz'

    # filenames
    file_cmap_reg = os.path.join(path_t1, "cmap_reg" + ext_reg)
    file_cmap_ants = os.path.join(path_t1, "cmap_ants.nii.gz")
    file_cmap_def = os.path.join(path_t1, "cmap_def.nii.gz")
    file_ana_reg = os.path.join(path_t1, "ana_reg.nii.gz")
    file_ana_def = os.path.join(path_t1, "ana_def.nii.gz")
    file_mask_def = os.path.join(path_t1, "mask_def.nii.gz")
    file_mask_def2 = os.path.join(path_t1, "mask_def2.nii.gz")

    # get initial ana -> epi transformation from existing cmap or header
    if file_reg:
        sh.copyfile(file_reg, file_cmap_reg)
    else:
        get_scanner_transform(file_t1, file_epi, path_t1, True)
        os.rename(
            os.path.join(path_t1,
                         name_t1 + "_2_" + name_epi + "_scanner.nii.gz"),
            file_cmap_reg)

    # scanner transform peeled t1 to epi
    ana_reg = apply_coordinate_mappings(
        file_t1,  # input 
        file_cmap_reg,  # cmap
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,
        overwrite=False,
        output_dir=None,
        file_name=None)
    nb.save(ana_reg["result"], file_ana_reg)

    # rigid registration
    embedded_antsreg(
        file_ana_reg,  # source image
        file_epi,  # target image 
        run_rigid=True,  # whether or not to run a rigid registration first 
        rigid_iterations=1000,  # number of iterations in the rigid step
        run_affine=False,  # whether or not to run an affine registration first
        affine_iterations=0,  # number of iterations in the affine step
        run_syn=False,  # whether or not to run a SyN registration
        coarse_iterations=0,  # number of iterations at the coarse level
        medium_iterations=0,  # number of iterations at the medium level
        fine_iterations=0,  # number of iterations at the fine level
        cost_function=
        "CrossCorrelation",  # CrossCorrelation or MutualInformation
        interpolation=
        "Linear",  # interpolation for registration result (NeareastNeighbor or Linear)
        convergence=
        1e-6,  # threshold for convergence (can make algorithm very slow)
        ignore_affine=
        True,  # ignore the affine matrix information extracted from the image header 
        ignore_header=
        True,  # ignore the orientation information and affine matrix information extracted from the image header
        save_data=True,  # save output data to file
        overwrite=True,  # overwrite existing results 
        output_dir=path_t1,  # output directory
        file_name="syn",  # output basename
    )

    # remove unnecessary files
    os.remove(os.path.join(path_t1, "syn_ants-def0.nii.gz"))
    os.remove(os.path.join(path_t1, "syn_ants-invmap.nii.gz"))

    # rename cmap
    os.rename(os.path.join(path_t1, "syn_ants-map.nii.gz"), file_cmap_ants)

    # remove outliers and expand
    cmap = nb.load(file_cmap_ants)
    arr_cmap = cmap.get_fdata()

    pts_cmap0 = arr_cmap[0, 0, 0, 0]
    pts_cmap1 = arr_cmap[0, 0, 0, 1]
    pts_cmap2 = arr_cmap[0, 0, 0, 2]

    arr_cmap[arr_cmap == 0] = 0
    arr_cmap[arr_cmap == pts_cmap0] = 0
    arr_cmap[arr_cmap == pts_cmap1] = 0
    arr_cmap[arr_cmap == pts_cmap2] = 0

    output = nb.Nifti1Image(arr_cmap, cmap.affine, cmap.header)
    nb.save(output, file_cmap_ants)

    expand_coordinate_mapping(cmap_in=file_cmap_ants,
                              path_output=path_t1,
                              name_output="cmap_ants",
                              write_output=True)

    # apply ants cmap to header transformation
    cmap_def = apply_coordinate_mappings(
        file_cmap_reg,  # input
        file_cmap_ants,
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,
        overwrite=False,
        output_dir=None,
        file_name=None)
    nb.save(cmap_def["result"], file_cmap_def)

    # remove outliers and expand
    arr_cmap = cmap_def["result"].get_fdata()

    pts_cmap0 = arr_cmap[0, 0, 0, 0]
    pts_cmap1 = arr_cmap[0, 0, 0, 1]
    pts_cmap2 = arr_cmap[0, 0, 0, 2]

    arr_cmap[arr_cmap == 0] = 0
    arr_cmap[arr_cmap == pts_cmap0] = 0
    arr_cmap[arr_cmap == pts_cmap1] = 0
    arr_cmap[arr_cmap == pts_cmap2] = 0

    output = nb.Nifti1Image(arr_cmap, cmap_def["result"].affine,
                            cmap_def["result"].header)
    nb.save(output, file_cmap_def)

    expand_coordinate_mapping(cmap_in=file_cmap_def,
                              path_output=path_t1,
                              name_output="cmap_def",
                              write_output=True)

    # apply final cmap to t1 and mask
    ana_def = apply_coordinate_mappings(
        file_t1,  # input 
        file_cmap_def,
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,
        overwrite=False,
        output_dir=None,
        file_name=None)
    nb.save(ana_def["result"], file_ana_def)

    mask_def = apply_coordinate_mappings(
        file_mask,  # input 
        file_cmap_def,
        interpolation="nearest",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,
        overwrite=False,
        output_dir=None,
        file_name=None)
    nb.save(mask_def["result"], file_mask_def)

    # finalise mask
    arr_mask = mask_def["result"].get_fdata()
    arr_mask = binary_fill_holes(arr_mask).astype(int)  # fill holes in mask
    arr_mask = binary_dilation(arr_mask, iterations=niter).astype(
        np.float)  # dilate mask
    arr_mask = gaussian_filter(arr_mask, sigma=sigma)  # apply gaussian filter

    # write final epi mask
    out_img = nb.Nifti1Image(arr_mask, mask_def["result"].affine,
                             mask_def["result"].header)
    nb.save(out_img, file_mask_def2)

    # multiply epi and binary mask
    epi_img = nb.load(file_epi)
    arr_epi = epi_img.get_fdata()
    arr_epi *= arr_mask  # multiply epi and mask

    # write masked epi
    out_img = nb.Nifti1Image(arr_epi, epi_img.affine, epi_img.header)
    nb.save(out_img, os.path.join(path_epi, "p" + name_epi + ".nii"))
Exemple #7
0
    ignore_header=
    False,  # ignore the orientation information and affine matrix information extracted from the image header
    save_data=True,  # save output data to file
    overwrite=True,  # overwrite existing results 
    output_dir=path_syn,  # output directory
    file_name="syn",  # output basename
)
"""
merge deformations
"""
# ana -> epi
apply_coordinate_mappings(
    file_ana2epi,  # input 
    os.path.join(path_syn, "syn_ants-map.nii.gz"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="ana2epi"  # base name with file extension for output
)

# epi -> ana
apply_coordinate_mappings(
    os.path.join(path_syn, "syn_ants-invmap.nii.gz"),  # input
    file_epi2ana,  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="epi2ana"  # base name with file extension for output
def apply_registration(file_in,
                       cmap_in,
                       file_out,
                       interpolation="linear",
                       r=[0.4, 0.4, 0.4]):
    """
    This function applies a coordinate mapping to a volume. Optionally, the voxel size of the output
    volume can be changed. This is achieved by adjusting the coordinate mapping to the new voxel 
    size before application.
    Inputs:
        *file_in: filename of input volume.
        *cmap_in: filename of coordinate mapping.
        *file_out: filename of output volume.
        *interpolation: interpolation type (linear or nearest).
        *r: destination voxel size after upsampling (performed if not None).
    Outputs:
        *nibabel object instance of transformed input.
    
    created by Daniel Haenelt
    Date created: 30-05-2020
    Last modified: 02-06-2020
    """
    import os
    import numpy as np
    import nibabel as nb
    from nighres.registration import apply_coordinate_mappings
    from lib.io.get_filename import get_filename
    from lib.utils.upsample_volume import upsample_volume

    # make output folder
    path_output = os.path.dirname(file_out)
    if not os.path.exists(path_output):
        os.makedirs(path_output)

    # filename for temporary cmap copy
    _, _, ext_cmap = get_filename(cmap_in)
    tmp = np.random.randint(0, 10, 5)
    tmp_string = ''.join(str(i) for i in tmp)
    file_tmp = os.path.join(path_output, "tmp_" + tmp_string + ext_cmap)
    file_tmp2 = os.path.join(path_output, "tmp2_" + tmp_string + ext_cmap)

    # adjust coordinate mapping
    if r:

        # upsample cmap
        upsample_volume(cmap_in, file_tmp, dxyz=r, rmode="Linear")
        upsample_volume(cmap_in, file_tmp2, dxyz=r, rmode="NN")

        # mask upsampled cmap
        cmap = nb.load(file_tmp)
        mask = nb.load(file_tmp2)

        cmap_array = cmap.get_fdata()
        mask_array = mask.get_fdata()

        mask_array = np.sum(mask_array, axis=3)
        mask_array[mask_array != 0] = 1

        cmap_array[:, :, :, 0][mask_array == 0] = 0
        cmap_array[:, :, :, 1][mask_array == 0] = 0
        cmap_array[:, :, :, 2][mask_array == 0] = 0

        cmap = nb.Nifti1Image(cmap_array, cmap.affine, cmap.header)

    else:

        cmap = nb.load(cmap_in)

    # apply coordinate mapping
    res = apply_coordinate_mappings(
        image=file_in,  # input 
        mapping1=cmap,  # cmap
        interpolation=interpolation,  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=False,  # save output data to file (boolean)
        overwrite=False,  # overwrite existing results (boolean)
        output_dir=None,  # output directory
        file_name=None,  # base name with file extension for output
    )

    # write output
    nb.save(res["result"], file_out)

    # remove temporary files
    if r:
        os.remove(file_tmp)
        os.remove(file_tmp2)

    return res["result"]
Exemple #9
0
def get_nuisance_mask(input,
                      pathSPM,
                      deformation,
                      path_output,
                      nerode_white=1,
                      nerode_csf=1,
                      segmentation=True,
                      cleanup=True):
    """
    This function calculates WM and CSF masks in space of the functional time series. It uses SPM
    to compute WM and CSF probability maps. These maps are masked with a skullstrip mask and 
    transformed to native epi space.
    Inputs:
        *input: input anatomy (orig.mgz).
        *pathSPM: path to spm toolbox.
        *deformation: coordinate mapping for ana to epi transformation.
        *path_output: path where output is saved.
        *nerode_white: number of wm mask eroding steps.
        *nerode_csf: number of csf mask eroding steps.
        *segmentation: do not calculate new masks to not rerun everything.
        *cleanup: delete intermediate files.

    created by Daniel Haenelt
    Date created: 01-03-2019
    Last modified: 01-03-2019
    """
    import os
    import shutil as sh
    import nibabel as nb
    from scipy.ndimage.morphology import binary_erosion
    from nipype.interfaces.fsl import BET
    from nipype.interfaces.freesurfer.preprocess import MRIConvert
    from nighres.registration import apply_coordinate_mappings
    from lib.skullstrip.skullstrip_spm12 import skullstrip_spm12

    # make output folder
    if not os.path.exists(path_output):
        os.mkdir(path_output)

    # get filename without file extension of input file
    file = os.path.splitext(os.path.basename(input))[0]

    # convert to nifti format
    mc = MRIConvert()
    mc.inputs.in_file = input
    mc.inputs.out_file = os.path.join(path_output, file + ".nii")
    mc.inputs.out_type = "nii"
    mc.run()

    # bet skullstrip mask
    btr = BET()
    btr.inputs.in_file = os.path.join(path_output, file + ".nii")
    btr.inputs.frac = 0.5
    btr.inputs.mask = True
    btr.inputs.no_output = True
    btr.inputs.out_file = os.path.join(path_output, "bet")
    btr.inputs.output_type = "NIFTI"
    btr.run()

    # segmentation
    if segmentation:
        skullstrip_spm12(os.path.join(path_output, file + ".nii"), pathSPM,
                         path_output)

    # load tissue maps
    wm_array = nb.load(os.path.join(path_output, "skull",
                                    "c2" + file + ".nii")).get_fdata()
    csf_array = nb.load(
        os.path.join(path_output, "skull", "c3" + file + ".nii")).get_fdata()
    mask_array = nb.load(os.path.join(path_output, "bet_mask.nii")).get_fdata()

    # binarize
    wm_array[wm_array > 0] = 1
    csf_array[csf_array > 0] = 1

    # apply brain mask
    wm_array = wm_array * mask_array
    csf_array = csf_array * mask_array

    # erode wm
    wm_array = binary_erosion(
        wm_array,
        structure=None,
        iterations=nerode_white,
        mask=None,
        output=None,
        border_value=0,
        origin=0,
        brute_force=False,
    )

    # erode csf
    csf_array = binary_erosion(
        csf_array,
        structure=None,
        iterations=nerode_csf,
        mask=None,
        output=None,
        border_value=0,
        origin=0,
        brute_force=False,
    )

    # write wm and csf mask
    data_img = nb.load(input)
    wm_out = nb.Nifti1Image(wm_array, data_img.affine, data_img.header)
    nb.save(wm_out, os.path.join(path_output, "wm_mask_orig.nii"))
    csf_out = nb.Nifti1Image(csf_array, data_img.affine, data_img.header)
    nb.save(csf_out, os.path.join(path_output, "csf_mask_orig.nii"))

    # apply deformation to mask
    apply_coordinate_mappings(
        os.path.join(path_output, "wm_mask_orig.nii"),  # input 
        deformation,  # cmap
        interpolation="nearest",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=True,  # save output data to file (boolean)
        overwrite=True,  # overwrite existing results (boolean)
        output_dir=path_output,  # output directory
        file_name="wm_mask"  # base name with file extension for output
    )

    apply_coordinate_mappings(
        os.path.join(path_output, "csf_mask_orig.nii"),  # input 
        deformation,  # cmap
        interpolation="nearest",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=True,  # save output data to file (boolean)
        overwrite=True,  # overwrite existing results (boolean)
        output_dir=path_output,  # output directory
        file_name="csf_mask"  # base name with file extension for output
    )

    # rename transformed masks
    os.rename(os.path.join(path_output, "wm_mask_def-img.nii.gz"),
              os.path.join(path_output, "wm_mask.nii.gz"))
    os.rename(os.path.join(path_output, "csf_mask_def-img.nii.gz"),
              os.path.join(path_output, "csf_mask.nii.gz"))

    # cleanup
    if cleanup:
        os.remove(os.path.join(path_output, "bet_mask.nii"))
        os.remove(os.path.join(path_output, "csf_mask_orig.nii"))
        os.remove(os.path.join(path_output, "wm_mask_orig.nii"))
        os.remove(os.path.join(path_output, "orig.nii"))
        sh.rmtree(os.path.join(path_output, "skull"), ignore_errors=True)
Exemple #10
0
header = data_img.header
affine = data_img.affine

# get image dimension
dim = data_img.header["dim"][1:4]

# get outlier dummy array if not outlier input
if not len(outlier_input):
    outlier_input = np.zeros(len(img_input))

# deform mask
apply_coordinate_mappings(mask_input, # input 
                          epi2orig_input, # cmap1
                          orig2epi_input,
                          interpolation = "nearest", # nearest or linear
                          padding = "zero", # closest, zero or max
                          save_data = True, # save output data to file (boolean)
                          overwrite = True, # overwrite existing results (boolean)
                          output_dir = path_output, # output directory
                          file_name = "mask" # base name with file extension for output
                          )

# rename final deformations
os.rename(os.path.join(path_output,"mask_def-img.nii.gz"),
          os.path.join(path_output,"mask.nii.gz"))

# load mask
mask = nb.load(os.path.join(path_output,"mask.nii.gz")).get_fdata()

mean_od_index1 = np.zeros(dim)
mean_od_index2 = np.zeros(dim)
for i in range(len(img_input)):
Exemple #11
0
# nibabel instance of final cmap
t2s_header = copy_header(input_source)
t2s_header["dim"][0] = 4
t2s_header["dim"][4] = 3
t2s_header["pixdim"][0] = 1
t2s_header["pixdim"][4] = 1
t2s_affine = nb.load(input_source).affine
t2s = nb.Nifti1Image(arr_cmap_transformed, t2s_affine, t2s_header)

# apply cmap to target
t2s_example = apply_coordinate_mappings(input_target,
                                        mapping1=t2s,
                                        mapping2=None,
                                        mapping3=None,
                                        mapping4=None,
                                        interpolation="linear",
                                        padding="closest",
                                        save_data=False,
                                        overwrite=False,
                                        output_dir=None,
                                        file_name=None)

# source to target transformation
cmap_target = generate_coordinate_mapping(input_target, pad=0)
arr_cmap_target = cmap_target.get_fdata()

xdim = cmap_target.header["dim"][1]
ydim = cmap_target.header["dim"][2]
zdim = cmap_target.header["dim"][3]

# transform source volume
Exemple #12
0
    data_array = data_array[:,:,:,:-end_vol]

# write single volumes
data.header["dim"][4] = 1
data.header["dim"][0] = 3
for i in range(np.shape(data_array)[3]):
    output = nb.Nifti1Image(data_array[:,:,:,i], data.affine, data.header)
    nb.save(output, os.path.join(path_native,str(i+1)+".nii")) 

# apply deformation    
for i in range(np.shape(data_array)[3]):
    apply_coordinate_mappings(os.path.join(path_native,str(i+1)+".nii"), 
                              input_deformation, 
                              interpolation=interpolation, 
                              padding='closest', 
                              save_data=True, 
                              overwrite=True, 
                              output_dir=path_def,
                              file_name=None,
                              )

# map to ana
for i in range(np.shape(data_array)[3]):
    for j in range(len(input_surf)):
        
        # hemisphere
        hemi = os.path.splitext(os.path.basename(input_surf[j]))[0]
    
        # sample on surface
        map2surface(input_surf[j], 
                    os.path.join(path_def,str(i+1)+"_def-img.nii.gz"), 
def mesh_sampling_layer_other(surf_in,
                              file_in,
                              target2source_in,
                              source2target_in,
                              boundaries_in,
                              path_output,
                              layer,
                              smooth_iter=0,
                              r=[0.4, 0.4, 0.4],
                              interpolation="Cu",
                              average_layer=False,
                              write_profile=False,
                              write_upsampled=True,
                              cleanup=True):
    """
    This function samples data from an image volume to a surface mesh which is located in a 
    different space. Boundaries and surface mesh are first transformed to the space of the image 
    volume using coordinate mappings before data sampling. If average_layer is true, the parameter 
    layer should contain only two integers which denote the start and ending layer. The basename
    of the surface file should have no file extension and the hemisphere should be stated as prefix.
    Inputs:
        *surf_in: filename of input surface mesh.
        *file_in: filename of input volume from which data is sampled.
        *target2source_in: target to source coordinate mapping.
        *source2target_in: source to target coordinate mapping.
        *boundaries_in: filename of 4D levelset image.
        *path_output: path where output is written.
        *layer: which layers to sample (array of integers).
        *smooth_iter: number of smoothing iterations after mesh deformation.
        *r: destination voxel size after upsampling (performed if not None).
        *interpolation: interpolation method for upsampling of file from which data is sampled.
        *average_layer: average across cortex.
        *write_profile: write sampled profile.
        *write_upsampled: write upsampled file.
        *cleanup: remove intermediate files.
    
    created by Daniel Haenelt
    Date created: 13-01-2020
    Last modified: 24-06-2020
    """
    import os
    import shutil as sh
    import numpy as np
    import nibabel as nb
    from nighres.registration import apply_coordinate_mappings
    from lib.io.get_filename import get_filename
    from lib.utils.upsample_volume import upsample_volume
    from lib.surface.deform_surface import deform_surface
    from lib.surface.mesh_sampling_layer import mesh_sampling_layer
    """
    set folder structure
    """
    tmp = np.random.randint(0, 10, 5)
    tmp_string = ''.join(str(i) for i in tmp)

    path_temp = os.path.join(path_output, "temp_" + tmp_string)
    path_cmap = os.path.join(path_temp, "cmap")
    path_data = os.path.join(path_temp, "data")
    path_surf = os.path.join(path_temp, "surf")

    if not os.path.exists(path_output):
        os.makedirs(path_output)

    if not os.path.exists(path_temp):
        os.makedirs(path_temp)

    if not os.path.exists(path_cmap):
        os.makedirs(path_cmap)

    if not os.path.exists(path_data):
        os.makedirs(path_data)

    if not os.path.exists(path_surf):
        os.makedirs(path_surf)

    # get filenames
    _, hemi, name_surf = get_filename(surf_in)
    _, name_file, ext_file = get_filename(file_in)
    _, name_t2s, ext_t2s = get_filename(target2source_in)
    _, name_s2t, ext_s2t = get_filename(source2target_in)

    # copy input files
    sh.copyfile(target2source_in, os.path.join(path_cmap, "t2s" + ext_t2s))
    sh.copyfile(source2target_in, os.path.join(path_cmap, "s2t" + ext_s2t))
    sh.copyfile(file_in, os.path.join(path_data, name_file + ext_file))

    # set filenames
    data = os.path.join(path_data, name_file + ext_file)
    data_upsampled = os.path.join(path_data,
                                  name_file + "_upsampled" + ext_file)
    t2s = os.path.join(path_cmap, "t2s" + ext_t2s)
    t2s_upsampled = os.path.join(path_cmap, "t2s_upsampled" + ext_t2s)
    t2s_rescaled = os.path.join(path_cmap, "t2s_upsampled_rescaled" + ext_t2s)
    s2t = os.path.join(path_cmap, "s2t" + ext_s2t)
    s2t_upsampled = os.path.join(path_cmap, "s2t_upsampled" + ext_s2t)
    s2t_rescaled = os.path.join(path_cmap, "s2t_upsampled_rescaled" + ext_s2t)
    """
    upsample data
    """
    if r:
        upsample_volume(data, data_upsampled, dxyz=r, rmode=interpolation)
        upsample_volume(t2s, t2s_upsampled, dxyz=r, rmode="Linear")
        upsample_volume(s2t, s2t_upsampled, dxyz=r, rmode="Linear")
    """
    rescale cmap
    """
    dim_target = nb.load(s2t).header["dim"][1:4] - 1
    dim_source = nb.load(t2s).header["dim"][1:4] - 1
    dim_target_upsampled = nb.load(s2t_upsampled).header["dim"][1:4] - 1
    dim_source_upsampled = nb.load(t2s_upsampled).header["dim"][1:4] - 1

    cmap_t2s = nb.load(t2s_upsampled)
    cmap_s2t = nb.load(s2t_upsampled)
    cmap_t2s_array = cmap_t2s.get_fdata()
    cmap_s2t_array = cmap_s2t.get_fdata()

    for i in range(3):
        cmap_t2s_array[:, :, :, i] = cmap_t2s_array[:, :, :, i] / dim_target[
            i] * dim_target_upsampled[i]
        cmap_s2t_array[:, :, :, i] = cmap_s2t_array[:, :, :, i] / dim_source[
            i] * dim_source_upsampled[i]

    cmap_t2s_rescaled = nb.Nifti1Image(cmap_t2s_array, cmap_t2s.affine,
                                       cmap_t2s.header)
    cmap_s2t_rescaled = nb.Nifti1Image(cmap_s2t_array, cmap_s2t.affine,
                                       cmap_s2t.header)
    nb.save(cmap_t2s_rescaled, t2s_rescaled)
    nb.save(cmap_s2t_rescaled, s2t_rescaled)
    """
    deform boundaries
    """
    apply_coordinate_mappings(
        image=boundaries_in,  # input 
        mapping1=t2s_rescaled,  # cmap
        interpolation="linear",  # nearest or linear
        padding="zero",  # closest, zero or max
        save_data=True,  # save output data to file (boolean)
        overwrite=True,  # overwrite existing results (boolean)
        output_dir=path_data,  # output directory
        file_name="boundaries"  # base name with file extension for output
    )
    """
    deform mesh
    """
    deform_surface(input_surf=surf_in,
                   input_orig=s2t_upsampled,
                   input_deform=s2t_rescaled,
                   input_target=data_upsampled,
                   hemi=hemi,
                   path_output=path_surf,
                   input_mask=None,
                   interp_method="trilinear",
                   smooth_iter=smooth_iter,
                   flip_faces=False,
                   cleanup=True)
    """
    sample data
    """
    if smooth_iter:
        surf_in = os.path.join(path_surf, hemi + name_surf + "_def_smooth")
    else:
        surf_in = os.path.join(path_surf, hemi + name_surf + "_def")

    mesh_sampling_layer(surf_in=surf_in,
                        file_in=data_upsampled,
                        boundaries_in=os.path.join(
                            path_data, "boundaries_def-img.nii.gz"),
                        path_output=path_output,
                        layer=layer,
                        r=None,
                        average_layer=average_layer,
                        write_profile=write_profile,
                        write_upsampled=write_upsampled)

    # delete intermediate files
    if cleanup:
        sh.rmtree(path_temp, ignore_errors=True)
Exemple #14
0
    ignore_header=
    False,  # ignore the orientation information and affine matrix information extracted from the image header
    save_data=True,  # save output data to file
    overwrite=True,  # overwrite existing results 
    output_dir=path_syn,  # output directory
    file_name="syn",  # output basename
)
"""
merge deformations
"""
# orig -> epi
apply_coordinate_mappings(
    os.path.join(path_scanner, "orig_2_T1_scanner.nii"),  # input 
    os.path.join(path_syn, "syn_ants-map.nii.gz"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="orig2epi"  # base name with file extension for output
)

# epi -> orig
apply_coordinate_mappings(
    os.path.join(path_syn, "syn_ants-invmap.nii.gz"),  # input
    os.path.join(path_scanner, "T1_2_orig_scanner.nii"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="epi2orig"  # base name with file extension for output
Exemple #15
0
        nt = nb.load(input_epi[i]).header["dim"][4]
        data.header["dim"][4] = 1  # change header for single 3d volumes

        for j in range(nt):

            # save single time frame
            output = nb.Nifti1Image(data_array[:, :, :, j], data.affine,
                                    data.header)
            nb.save(output, os.path.join(path_tmp, str(j) + ".nii"))

            apply_coordinate_mappings(
                os.path.join(path_tmp,
                             str(j) + ".nii"),
                input_reg[i],
                interpolation=interpolation,
                padding=padding,
                save_data=True,
                overwrite=True,
                output_dir=path_tmp,
                file_name=None,
            )

            # unzip output
            gunzip(os.path.join(path_tmp, str(j) + "_def-img.nii.gz"))

        # merge final deformed time series
        data = nb.load(os.path.join(path_tmp, "0_def-img.nii"))
        data.header["dim"][4] = nt
        data_res = np.zeros(data.header["dim"][1:5])

        for j in range(nt):
Exemple #16
0
"""
get output
"""
os.rename(os.path.join(path_temp, "orig_2_T1_scanner.nii.gz"),
          os.path.join(path_output, "orig2T1.nii.gz"))
os.rename(os.path.join(path_temp, "T1_2_orig_scanner.nii.gz"),
          os.path.join(path_output, "T12orig.nii.gz"))
"""
apply deformation
"""
# ana -> epi
apply_coordinate_mappings(
    os.path.join(path_temp, "orig.nii"),  # input 
    os.path.join(path_output, "orig2T1.nii.gz"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="orig2T1_example"  # base name with file extension for output
)

# epi -> ana
apply_coordinate_mappings(
    os.path.join(path_temp, "T1.nii"),  # input 
    os.path.join(path_output, "T12orig.nii.gz"),  # cmap
    interpolation="linear",  # nearest or linear
    padding="zero",  # closest, zero or max
    save_data=True,  # save output data to file (boolean)
    overwrite=True,  # overwrite existing results (boolean)
    output_dir=path_output,  # output directory
    file_name="T12orig_example"  # base name with file extension for output