예제 #1
0
def mask_CTBrain(CT_dir, T1_dir, frac):

    # nav to dir with T1 images
    os.chdir(T1_dir)

    # run BET to extract brain from T1
    bet = BET()
    bet.inputs.in_file = T1_dir + '/T1.nii'
    bet.inputs.frac = frac
    bet.inputs.robust = True
    bet.inputs.mask = True
    print "::: Extracting Brain mask from T1 using BET :::"
    bet.run()

    # use flrit to correg CT to T1
    flirt = FLIRT()
    flirt.inputs.in_file = CT_dir + '/CT.nii'
    flirt.inputs.reference = T1_dir + '/T1.nii'
    flirt.inputs.cost_func = 'mutualinfo'
    print "::: Estimating corregistration from CT to T1 using FLIRT :::"
    flirt.run()

    # get inverse of estimated coreg of CT tp T1
    print "::: Estimating inverse affine for Brain mask of CT :::"
    os.system('convert_xfm -omat inv_CT_flirt.mat -inverse CT_flirt.mat')
    os.system('mv inv_CT_flirt.mat %s' % (CT_dir))

    # apply inverse affine coreg to get brain mask in CT space
    applyxfm = ApplyXfm()
    applyxfm.inputs.in_file = T1_dir + '/T1_brain_mask.nii.gz'
    applyxfm.inputs.in_matrix_file = CT_dir + '/inv_CT_flirt.mat'
    applyxfm.inputs.out_file = CT_dir + '/CT_mask.nii.gz'
    applyxfm.inputs.reference = CT_dir + '/CT.nii'
    applyxfm.inputs.apply_xfm = True
    print "::: Applying inverse affine to Brain mask to get CT mask :::"
    applyxfm.run()

    # dilate brain mask to make sure all elecs are in final masked img
    CT_mask = nib.load(CT_dir + '/CT_mask.nii.gz')
    CT_mask_dat = CT_mask.get_data()
    kernel = np.ones((5, 5), np.uint8)

    print "::: Dilating CT mask :::"
    dilated = cv2.dilate(CT_mask_dat, kernel, iterations=1)
    hdr = CT_mask.get_header()
    affine = CT_mask.get_affine()
    N = nib.Nifti1Image(dilated, affine, hdr)
    new_fname = CT_dir + '/dilated_CT_mask.nii'
    N.to_filename(new_fname)

    # apply mask to CT
    os.chdir(CT_dir)
    print "::: masking CT with dilated brain mask :::"
    os.system(
        "fslmaths 'CT.nii' -mas 'dilated_CT_mask.nii.gz' 'masked_CT.nii'")
    os.system('gunzip masked_CT.nii.gz')
예제 #2
0
def func_register(img_original,img_template, img_registered):
    # img_original : original T2 or FLAIR image file
    # img_template : isovoxel T1C file used for registration template
    # img_registered :file name that stores registered (isovoxel) T2 or FLAIR file
    coregi_iso = FLIRT(bins=640, cost_func='mutualinfo', dof=12, output_type="NIFTI_GZ", verbose=0,
                          datatype = 'float', interp = 'trilinear',
                          in_file = img_original, 
                          reference = img_template,
                          out_file = img_registered)
    coregi_iso.run()
예제 #3
0
def mask_CTBrain(CT_dir, T1_dir, frac):

    # nav to dir with T1 images
    os.chdir(T1_dir)

    # run BET to extract brain from T1
    bet = BET()
    bet.inputs.in_file = T1_dir + "/T1.nii"
    bet.inputs.frac = frac
    bet.inputs.robust = True
    bet.inputs.mask = True
    print "::: Extracting Brain mask from T1 using BET :::"
    bet.run()

    # use flrit to correg CT to T1
    flirt = FLIRT()
    flirt.inputs.in_file = CT_dir + "/CT.nii"
    flirt.inputs.reference = T1_dir + "/T1.nii"
    flirt.inputs.cost_func = "mutualinfo"
    print "::: Estimating corregistration from CT to T1 using FLIRT :::"
    flirt.run()

    # get inverse of estimated coreg of CT tp T1
    print "::: Estimating inverse affine for Brain mask of CT :::"
    os.system("convert_xfm -omat inv_CT_flirt.mat -inverse CT_flirt.mat")
    os.system("mv inv_CT_flirt.mat %s" % (CT_dir))

    # apply inverse affine coreg to get brain mask in CT space
    applyxfm = ApplyXfm()
    applyxfm.inputs.in_file = T1_dir + "/T1_brain_mask.nii.gz"
    applyxfm.inputs.in_matrix_file = CT_dir + "/inv_CT_flirt.mat"
    applyxfm.inputs.out_file = CT_dir + "/CT_mask.nii.gz"
    applyxfm.inputs.reference = CT_dir + "/CT.nii"
    applyxfm.inputs.apply_xfm = True
    print "::: Applying inverse affine to Brain mask to get CT mask :::"
    applyxfm.run()

    # dilate brain mask to make sure all elecs are in final masked img
    CT_mask = nib.load(CT_dir + "/CT_mask.nii.gz")
    CT_mask_dat = CT_mask.get_data()
    kernel = np.ones((5, 5), np.uint8)

    print "::: Dilating CT mask :::"
    dilated = cv2.dilate(CT_mask_dat, kernel, iterations=1)
    hdr = CT_mask.get_header()
    affine = CT_mask.get_affine()
    N = nib.Nifti1Image(dilated, affine, hdr)
    new_fname = CT_dir + "/dilated_CT_mask.nii"
    N.to_filename(new_fname)

    # apply mask to CT
    os.chdir(CT_dir)
    print "::: masking CT with dilated brain mask :::"
    os.system("fslmaths 'CT.nii' -mas 'dilated_CT_mask.nii.gz' 'masked_CT.nii'")
    os.system("gunzip masked_CT.nii.gz")
예제 #4
0
def isotropic_voxels():
    if verbose:
        print('Resampling to isotropic voxels')
    orig = nib.load('%s/opposedphase.nii.gz' % tmpdir)

    for f in ['opposedphase', 'inphase']:
        iso = FLIRT()
        iso.inputs.in_file = '%s/%s.nii.gz' % (tmpdir, f)
        iso.inputs.reference = '%s/%s.nii.gz' % (tmpdir, f)
        iso.inputs.out_file = '%s/%s_iso.nii.gz' % (tmpdir, f)
        iso.inputs.apply_isoxfm = orig.header.get_zooms()[0]
        iso.run()
예제 #5
0
def calculate_realignment_cost(target_id: str,
                               cost_function: str,
                               serialize: bool = True):
    realigned_subject_dirs = generate_subject_dirs("realigned", target_id,
                                                   cost_function)
    target_scan = get_target_scan(target_id)
    costs = {}
    for subject_dir in realigned_subject_dirs:
        subject_id = subject_dir.split("/")[-2]
        registered, mat_file = get_realigned_subject_data(subject_id)
        print(f"Calculating cost function value...", end="\t")
        flirt = FLIRT()
        flirt.inputs.in_file = registered
        flirt.inputs.reference = target_scan
        flirt.inputs.schedule = "/usr/local/fsl/etc/flirtsch/measurecost1.sch"
        flirt.inputs.in_matrix_file = mat_file
        tmp = os.path.join(subject_dir, "tmp")
        flirt.inputs.out_file = os.path.join(tmp, "cost.nii.gz")
        flirt.inputs.out_matrix_file = os.path.join(tmp, "cost.mat")
        os.makedirs(tmp, exist_ok=True)
        f = flirt.run()
        result = float(f.runtime.stdout.split()[0])
        print(f"done! [{result}]")
        shutil.rmtree(tmp)
        costs[subject_id] = result
        if serialize:
            serialize_results(target_id, cost_function, costs)
    return costs
예제 #6
0
def flirt_t1_epi(subject_id, data_dir, run, sink_dir):
    def get_niftis(subject_id, data_dir, run, sink_dir):
        from os.path import join, exists

        t1 = join(
            data_dir,
            subject_id,
            "session-1",
            "anatomical",
            "anatomical-0",
            "anatomical.nii.gz",
        )
        # t1_brain_mask = join(data_dir, subject, 'session-1', 'anatomical', 'anatomical-0', 'fsl', 'anatomical-bet.nii.gz')
        ex_func = join(
            sink_dir,
            subject_id,
            "{0}-{1}_retr-example_func.nii.gz".format(subject_id, run),
        )
        assert exists(t1), "t1 does not exist"
        assert exists(ex_func), "example func does not exist"
        standard = "/home/applications/fsl/5.0.8/data/standard/MNI152_T1_2mm.nii.gz"
        return t1, ex_func, standard

    coreg = join(sink_dir, "qa", "{0}-{1}_t1_flirt.png".format(subject, run))

    data = Function(
        function=get_niftis,
        input_names=["subject_id", "data_dir", "run", "sink_dir"],
        output_names=["t1", "ex_func", "standard"],
    )
    data.inputs.data_dir = data_dir
    data.inputs.sink_dir = sink_dir
    data.inputs.subject_id = subject
    data.inputs.run = run
    grabber = data.run()

    re_flit = FLIRT(
        cost_func="normmi",
        dof=12,
        searchr_x=[-90, 90],
        searchr_y=[-90, 90],
        searchr_z=[-90, 90],
        interp="trilinear",
        bins=256,
    )
    re_flit.inputs.reference = grabber.outputs.ex_func
    re_flit.inputs.in_file = grabber.outputs.t1
    re_flit.inputs.out_file = join(
        sink_dir, subject, "{0}-{1}_t1-flirt-retr.nii.gz".format(subject, run))
    re_flit.inputs.out_matrix_file = join(
        sink_dir, subject, "{0}-{1}_t1-flirt-retr.mat".format(subject, run))
    reg_func = re_flit.run()

    display = plotting.plot_anat(grabber.outputs.ex_func, dim=0)
    display.add_edges(reg_func.outputs.out_file)
    display.savefig(coreg, dpi=300)
    return
예제 #7
0
def func_regi2mni(path_T1C_isovoxel, path_mask_isovoxel):
    
    matrix_2mni = 'matrix_2mni.mat'
    mni_reference = 'MNI152_T1_1mm_brain.nii.gz'
    
    coregi_t1gd2mni= FLIRT(bins=640, cost_func='mutualinfo', dof=12, output_type="NIFTI_GZ", verbose=0,
                           datatype = 'float', interp = 'trilinear',
                           in_file = path_T1C_isovoxel, 
                           reference = mni_reference,
                           out_file = 'img_2mni.nii.gz',
                           out_matrix_file = matrix_2mni)
    coregi_t1gd2mni.run()
    
    coregi_mask2MNI = ApplyXFM(in_file = path_mask_isovoxel,
                                in_matrix_file = matrix_2mni,
                                out_file = 'mask_2mni.nii.gz',
                                reference= mni_reference)
   
    coregi_mask2MNI.run()
예제 #8
0
def resample_to_umap(DeepX, reference):
    if verbose:
        print('Resampling to umap resolution')
    # Rehape to in-phase resolution
    DeepX = np.swapaxes(np.flipud(np.fliplr(DeepX)), 2, 0)
    DeepX_padded = np.zeros(reference.shape)
    DeepX_padded[96:288, 6:198, :192] = DeepX
    DeepX_nii = nib.Nifti1Image(DeepX_padded, reference.affine,
                                reference.header)
    nib.save(DeepX_nii, '%s/DeepDixon.nii.gz' % tmpdir)

    # Resample to UMAP resolution
    DeepX_rsl = FLIRT()
    DeepX_rsl.inputs.in_file = '%s/DeepDixon.nii.gz' % tmpdir
    DeepX_rsl.inputs.reference = '%s/umap.nii.gz' % tmpdir
    DeepX_rsl.inputs.out_file = '%s/DeepDixon_rsl.nii.gz' % tmpdir
    DeepX_rsl.run()
    DeepX = nib.load('%s/DeepDixon_rsl.nii.gz' % tmpdir).get_fdata()
    DeepX = DeepX.astype(np.uint16)
    DeepX = np.fliplr(np.flipud(np.swapaxes(np.swapaxes(DeepX, 0, 1), 1, 2)))

    return DeepX
예제 #9
0
             os.path.join(path_t1[i], "mask.nii"), niter_mask, sigma_mask,
             file_cmap)
"""
flirt
"""
os.chdir(path_flirt)
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_epi_target, "pbepi.nii")
flirt.inputs.reference = os.path.join(path_epi_source, "pbepi.nii")
flirt.inputs.output_type = "NIFTI"
flirt.inputs.out_file = os.path.join(path_flirt, "flirt.nii")
flirt.inputs.out_matrix_file = os.path.join(path_flirt, "flirt_matrix.mat")
flirt.run()
"""
invert matrix
"""
invt = ConvertXFM()
invt.inputs.in_file = os.path.join(path_flirt, "flirt_matrix.mat")
invt.inputs.invert_xfm = True
invt.inputs.out_file = os.path.join(path_flirt, "flirt_inv_matrix.mat")
invt.run()
"""
get cmap
"""
generate_coordinate_mapping(os.path.join(path_epi_target, "bepi.nii"),
                            pad=0,
                            path_output=path_flirt,
                            suffix="target",
예제 #10
0
def preproc(data_dir, sink_dir, subject, task, session, run, masks,
            motion_thresh, moco):
    from nipype.interfaces.fsl import MCFLIRT, FLIRT, FNIRT, ExtractROI, ApplyWarp, MotionOutliers, InvWarp, FAST
    #from nipype.interfaces.afni import AlignEpiAnatPy
    from nipype.interfaces.utility import Function
    from nilearn.plotting import plot_anat
    from nilearn import input_data

    #WRITE A DARA GRABBER
    def get_niftis(subject_id, data_dir, task, run, session):
        from os.path import join, exists
        t1 = join(data_dir, subject_id, 'session-{0}'.format(session),
                  'anatomical', 'anatomical-0', 'anatomical.nii.gz')
        #t1_brain_mask = join(data_dir, subject_id, 'session-1', 'anatomical', 'anatomical-0', 'fsl', 'anatomical-bet.nii.gz')
        epi = join(data_dir, subject_id, 'session-{0}'.format(session), task,
                   '{0}-{1}'.format(task, run), '{0}.nii.gz'.format(task))
        assert exists(t1), "t1 does not exist at {0}".format(t1)
        assert exists(epi), "epi does not exist at {0}".format(epi)
        standard = '/home/applications/fsl/5.0.8/data/standard/MNI152_T1_2mm.nii.gz'
        return t1, epi, standard

    data = Function(
        function=get_niftis,
        input_names=["subject_id", "data_dir", "task", "run", "session"],
        output_names=["t1", "epi", "standard"])
    data.inputs.data_dir = data_dir
    data.inputs.subject_id = subject
    data.inputs.run = run
    data.inputs.session = session
    data.inputs.task = task
    grabber = data.run()

    if session == 0:
        sesh = 'pre'
    if session == 1:
        sesh = 'post'

    #reg_dir = '/home/data/nbc/physics-learning/data/first-level/{0}/session-1/retr/retr-{1}/retr-5mm.feat/reg'.format(subject, run)
    #set output paths for quality assurance pngs
    qa1 = join(
        sink_dir, 'qa',
        '{0}-session-{1}_{2}-{3}_t1_flirt.png'.format(subject, session, task,
                                                      run))
    qa2 = join(
        sink_dir, 'qa',
        '{0}-session-{1}_{2}-{3}_mni_flirt.png'.format(subject, session, task,
                                                       run))
    qa3 = join(
        sink_dir, 'qa',
        '{0}-session-{1}_{2}-{3}_mni_fnirt.png'.format(subject, session, task,
                                                       run))
    confound_file = join(
        sink_dir, sesh, subject,
        '{0}-session-{1}_{2}-{3}_confounds.txt'.format(subject, session, task,
                                                       run))

    #run motion correction if indicated
    if moco == True:
        mcflirt = MCFLIRT(ref_vol=144, save_plots=True, output_type='NIFTI_GZ')
        mcflirt.inputs.in_file = grabber.outputs.epi
        #mcflirt.inputs.in_file = join(data_dir, subject, 'session-1', 'retr', 'retr-{0}'.format(run), 'retr.nii.gz')
        mcflirt.inputs.out_file = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_mcf.nii.gz'.format(
                subject, session, task, run))
        flirty = mcflirt.run()
        motion = np.genfromtxt(flirty.outputs.par_file)
    else:
        print "no moco needed"
        motion = 0

    #calculate motion outliers
    try:
        mout = MotionOutliers(metric='fd', threshold=motion_thresh)
        mout.inputs.in_file = grabber.outputs.epi
        mout.inputs.out_file = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_fd-gt-{3}mm'.format(
                subject, session, task, run, motion_thresh))
        mout.inputs.out_metric_plot = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_metrics.png'.format(
                subject, session, task, run))
        mout.inputs.out_metric_values = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_fd.txt'.format(subject, session, task,
                                                    run))
        moutliers = mout.run()
        outliers = np.genfromtxt(moutliers.outputs.out_file)
        e = 'no errors in motion outliers, yay'
    except Exception as e:
        print(e)
        outliers = np.genfromtxt(mout.inputs.out_metric_values)
        #set everything above the threshold to 1 and everything below to 0
        outliers[outliers > motion_thresh] = 1
        outliers[outliers < motion_thresh] = 0

    #concatenate motion parameters and motion outliers to form confounds file

    #outliers = outliers.reshape((outliers.shape[0],1))
    conf = outliers
    np.savetxt(confound_file, conf, delimiter=',')

    #extract an example volume for normalization
    ex_fun = ExtractROI(t_min=144, t_size=1)
    ex_fun.inputs.in_file = flirty.outputs.out_file
    ex_fun.inputs.roi_file = join(
        sink_dir, sesh, subject,
        '{0}-session-{1}_{2}-{3}-example_func.nii.gz'.format(
            subject, session, task, run))
    fun = ex_fun.run()

    warp = ApplyWarp(interp="nn", abswarp=True)

    if not exists(
            '/home/data/nbc/physics-learning/data/first-level/{0}/session-{1}/{2}/{2}-{3}/{2}-5mm.feat/reg/example_func2standard_warp.nii.gz'
            .format(subject, session, task, run)):
        #two-step normalization using flirt and fnirt, outputting qa pix
        flit = FLIRT(cost_func="corratio", dof=12)
        reg_func = flit.run(
            reference=fun.outputs.roi_file,
            in_file=grabber.outputs.t1,
            searchr_x=[-180, 180],
            searchr_y=[-180, 180],
            out_file=join(
                sink_dir, sesh, subject,
                '{0}-session-{1}_{2}-{3}_t1-flirt.nii.gz'.format(
                    subject, session, task, run)),
            out_matrix_file=join(
                sink_dir, sesh, subject,
                '{0}-session-{1}_{2}-{3}_t1-flirt.mat'.format(
                    subject, session, task, run)))
        reg_mni = flit.run(
            reference=grabber.outputs.t1,
            in_file=grabber.outputs.standard,
            searchr_y=[-180, 180],
            searchr_z=[-180, 180],
            out_file=join(
                sink_dir, sesh, subject,
                '{0}-session-{1}_{2}-{3}_mni-flirt-t1.nii.gz'.format(
                    subject, session, task, run)),
            out_matrix_file=join(
                sink_dir, sesh, subject,
                '{0}-session-{1}_{2}-{3}_mni-flirt-t1.mat'.format(
                    subject, session, task, run)))

        #plot_stat_map(aligner.outputs.out_file, bg_img=fun.outputs.roi_file, colorbar=True, draw_cross=False, threshold=1000, output_file=qa1a, dim=-2)
        display = plot_anat(fun.outputs.roi_file, dim=-1)
        display.add_edges(reg_func.outputs.out_file)
        display.savefig(qa1, dpi=300)
        display.close()

        display = plot_anat(grabber.outputs.t1, dim=-1)
        display.add_edges(reg_mni.outputs.out_file)
        display.savefig(qa2, dpi=300)
        display.close()

        perf = FNIRT(output_type='NIFTI_GZ')
        perf.inputs.warped_file = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_mni-fnirt-t1.nii.gz'.format(
                subject, session, task, run))
        perf.inputs.affine_file = reg_mni.outputs.out_matrix_file
        perf.inputs.in_file = grabber.outputs.standard
        perf.inputs.subsampling_scheme = [8, 4, 2, 2]
        perf.inputs.fieldcoeff_file = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_mni-fnirt-t1-warpcoeff.nii.gz'.format(
                subject, session, task, run))
        perf.inputs.field_file = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_mni-fnirt-t1-warp.nii.gz'.format(
                subject, session, task, run))
        perf.inputs.ref_file = grabber.outputs.t1
        reg2 = perf.run()
        warp.inputs.field_file = reg2.outputs.field_file
        #plot fnirted MNI overlaid on example func
        display = plot_anat(grabber.outputs.t1, dim=-1)
        display.add_edges(reg2.outputs.warped_file)
        display.savefig(qa3, dpi=300)
        display.close()
    else:
        warpspeed = InvWarp(output_type='NIFTI_GZ')
        warpspeed.inputs.warp = '/home/data/nbc/physics-learning/data/first-level/{0}/session-{1}/{2}/{2}-{3}/{2}-5mm.feat/reg/example_func2standard_warp.nii.gz'.format(
            subject, session, task, run)
        warpspeed.inputs.reference = fun.outputs.roi_file
        warpspeed.inputs.inverse_warp = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_mni-fnirt-t1-warp.nii.gz'.format(
                subject, session, task, run))
        mni2epiwarp = warpspeed.run()
        warp.inputs.field_file = mni2epiwarp.outputs.inverse_warp

    for key in masks.keys():
        #warp takes us from mni to epi
        warp.inputs.in_file = masks[key]
        warp.inputs.ref_file = fun.outputs.roi_file
        warp.inputs.out_file = join(
            sink_dir, sesh, subject,
            '{0}-session-{1}_{2}-{3}_{4}.nii.gz'.format(
                subject, session, task, run, key))
        net_warp = warp.run()

        qa_file = join(
            sink_dir, 'qa', '{0}-session-{1}_{2}-{3}_qa_{4}.png'.format(
                subject, session, task, run, key))

        display = plotting.plot_roi(net_warp.outputs.out_file,
                                    bg_img=fun.outputs.roi_file,
                                    colorbar=True,
                                    vmin=0,
                                    vmax=18,
                                    draw_cross=False)
        display.savefig(qa_file, dpi=300)
        display.close()

    return flirty.outputs.out_file, confound_file, e
예제 #11
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)
예제 #12
0
def elecDetect(CT_dir, fs_dir, img, thresh_f, thresh_c, frac, num_gridStrips,
               n_elects):

    # run CT_electhresh
    print "::: Thresholding CT at %f stdv :::" % (thresh)
    CT_img = CT_dir + img
    electhresh(CT_img, thresh_f, thresh_c)

    # run im_filt to gaussian smooth thresholded image
    fname = CT_dir + "thresh_" + img
    print "::: Applying guassian smooth of 2.5mm to thresh-CT :::"
    img_filt(fname)

    # compute cv alg to find electrode center coordinates
    mlab = matlab.MatlabCommand()
    mlab.inputs.script = "" % (CT_dir, CT_dir, CT_dir, CT_dir)

    print "::: Applying 3D cv alg to smoothed thresh-CT :::"
    out = mlab.run()
    # run the hough and get errors if any ocur

    # save txt version of hough putputs
    coords = scipy.io.loadmat(CT_dir + '/' + '3dcv_coords.mat').get('coords')
    np.savetxt('dirty_elecsAll.txt', coords, delimiter=' ', fmt='%-7.1f')

    # run fsl FLIRT to compute CT-MRI registration
    flirt = FLIRT()
    flirt.inputs.in_file = CT_dir + '/CT.nii'
    flirt.inputs.reference = fs_dir + '/orig.nii'
    flirt.inputs.cost_func = 'mutualinfo'
    print "::: Computing corregistration between CT and MRI using FLIRT :::"
    flirt.run()

    # use fsl to calc voxel coords for elec centers in CT registered to orig
    # in RAS voxel coordinates using affine from FLIRT
    print "::: Applying FLIRT transformation to 3d cv ouput :::"
    orig_brain = fs_dir + '/orig.nii'
    os.system(
        'cat %s/dirty_elecsAll.txt | img2imgcoord -src %s/CT.nii -dest %s \
    -xfm %s/CT_flirt.mat -vox > %s/dirty_elecsAll_RAS.txt' %
        (CT_dir, CT_dir, orig_brain, fs_dir, CT_dir))

    # remove outliers caused by staples in the most superior portion of the img
    print "::: Removing outliers from detected electrode coordinates :::"
    elecs_dirty_RAS = scipy.loadtxt('dirty_elecsAll_RAS.txt', skiprows=1)
    clean_elecs_RAS = []
    for i in elecs_dirty_RAS:
        if i[1] > (0.3 * np.max(elecs_dirty_RAS[:, 2])):
            clean_elecs_RAS.append(i)
    clean_elecs_RAS = np.array(clean_elecs_RAS)

    # save surface RAS coords for cleaned coords
    # first apply vox2Ras affine for all fs orig volumes
    print "::: Applying freesurfer vox2RAS transformation :::"
    affine = np.array([[-1., 0., 0., 128.], [0., 0., 1., -128.],
                       [0., -1., 0., 128.], [0., 0., 0., 1.]])

    intercept = np.ones(len(clean_elecs_RAS))
    vox_elecs = np.column_stack((clean_elecs_RAS, intercept))
    vox_elecs = np.transpose(vox_elecs)
    sRAS_coords = np.matrix.dot(affine, vox_elecs)
    sRAS_coords = np.transpose(sRAS_coords)
    sRAS_coords = sRAS_coords[:, 0:3]

    # apply difference coord (lh_pial.asc  - lh.pial) to shift all elecmatrix coords
    c_RAS = get_cRAS(fs_dir, subj)
    sRAS_coords = coords - c_RAS
    # shifted to correct back to lh.pial coords
    scipy.io.savemat('elecs_all_cleaned.mat', {'elecmatrix': sRAS_coords})

    # run K means to find grid and strip clusters
    n_clusts = num_gridStrips
    # number of cluster to find = number of electrodes
    iters = 1000
    init_clusts = n_clusts
    print "::: Performing K-means cluster to find %d grid-strip and noise clusters :::" % (
        n_clusts)
    [clust_coords, clust_labels] = clust(sRAS_coords, n_clusts, iters,
                                         init_clusts)

    # save cluster results as individual arrays
    grid_strip_iter = np.linspace(0, num_gridStrips - 1, num_gridStrips)
    sRAS_coords_list = [list(b) for b in sRAS_coords]
    clust_labels_list = list(clust_labels)
    for i in grid_strip_iter:
        coords = []
        for d in sRAS_coords_list:
            if clust_labels_list[sRAS_coords_list.index(d)] == int(i):
                coords.append(d)
        coords = np.array(coords)
        scipy.io.savemat('clust%s.mat' % (i), {'elecmatrix': coords})
예제 #13
0
def elecDetect(CT_dir, fs_dir,img, thresh_f, thresh_c, frac, num_gridStrips, n_elects):
    
    # run CT_electhresh
    print "::: Thresholding CT at %f stdv :::" %(thresh);
    CT_img = CT_dir + img;
    electhresh(CT_img,thresh_f, thresh_c);
    
    # run im_filt to gaussian smooth thresholded image
    fname = CT_dir + "thresh_" + img;
    print "::: Applying guassian smooth of 2.5mm to thresh-CT :::";
    img_filt(fname);
    
    # compute hough transform to find electrode center coordinates
    mlab = matlab.MatlabCommand();
    mlab.inputs.script = "addpath(genpath('/Volumes/Thunderbolt_Duo/Scripts/Matlab/SphericalHough')); \
    img = readFileNifti('%s/smoothed_thresh_CT.nii');img = img.data(); \
    fltr4LM_R = 3; obj_cint = 0.0; radrange = [0.1, 3]; multirad = 0.3; \
    grdthres = 0.33;\
    [center_img,sphere_img,sphcen2,sphrad]=SphericalHough(img,radrange,grdthres, \
    fltr4LM_R, multirad, obj_cint); save('%s/elec_spheres.mat', 'sphere_img'); \
    save('%s/elec_centers.mat', 'center_img'); \
    save('%s/3d_hough_elect_coords.mat', 'sphcen2');" %(CT_dir, CT_dir , CT_dir, CT_dir);
    
    print "::: Applying 3D hough transform to smoothed thresh-CT :::";        
    out = mlab.run(); # run the hough and get errors if any ocur

    # save txt version of hough putputs
    coords = scipy.io.loadmat(CT_dir + '/'+ '3dHough_coords.mat').get('coords')
    np.savetxt('dirty_elecsAll.txt', coords, delimiter=' ', fmt='%-7.1f');
    
    # run fsl FLIRT to compute CT-MRI registration
    flirt = FLIRT();
    flirt.inputs.in_file = CT_dir + '/CT.nii';
    flirt.inputs.reference = fs_dir + '/orig.nii';
    flirt.inputs.cost_func = 'mutualinfo';
    print "::: Computing corregistration between CT and MRI using FLIRT :::";
    flirt.run();
            
    # use fsl to calc voxel coords for elec centers in CT registered to orig 
    # in RAS voxel coordinates using affine from FLIRT
    print "::: Applying FLIRT transformation to 3d Hough ouput :::";
    orig_brain = fs_dir + '/orig.nii';
    os.system('cat %s/dirty_elecsAll.txt | img2imgcoord -src %s/CT.nii -dest %s \
    -xfm %s/CT_flirt.mat -vox > %s/dirty_elecsAll_RAS.txt' %(CT_dir, CT_dir, orig_brain, fs_dir, CT_dir));
    
    # remove outliers caused by staples in the most superior portion of the img
    print "::: Removing outliers from detected electrode coordinates :::";
    elecs_dirty_RAS = scipy.loadtxt('dirty_elecsAll_RAS.txt', skiprows=1);
    clean_elecs_RAS = [];
    for i in elecs_dirty_RAS:
        if i[1] > (0.3*np.max(elecs_dirty_RAS[:,2])):
            clean_elecs_RAS.append(i);
    clean_elecs_RAS = np.array(clean_elecs_RAS);
    
    # save surface RAS coords for cleaned coords
    # first apply vox2Ras affine for all fs orig volumes
    print "::: Applying freesurfer vox2RAS transformation :::";
    affine = np.array([[  -1.,    0.,    0.,  128.],
           [   0.,    0.,    1., -128.],
           [   0.,   -1.,    0.,  128.],
           [   0.,    0.,    0.,    1.]]);
    
    intercept = np.ones(len(clean_elecs_RAS));
    vox_elecs = np.column_stack((clean_elecs_RAS,intercept));
    vox_elecs = np.transpose(vox_elecs);
    sRAS_coords = np.matrix.dot(affine,vox_elecs);
    sRAS_coords = np.transpose(sRAS_coords);
    sRAS_coords = sRAS_coords[:,0:3];
        
    # apply difference coord (lh_pial.asc  - lh.pial) to shift all elecmatrix coords
    c_RAS = get_cRAS(fs_dir,subj);
    sRAS_coords = coords - c_RAS; # shifted to correct back to lh.pial coords
    scipy.io.savemat('elecs_all_cleaned.mat', {'elecmatrix':sRAS_coords});
    
    # run K means to find grid and strip clusters
    n_clusts = num_gridStrips; # number of cluster to find = number of electrodes
    iters = 1000;
    init_clusts = n_clusts;
    print "::: Performing K-means cluster to find %d grid-strip and noise clusters :::" %(n_clusts);
    [clust_coords, clust_labels] = clust(sRAS_coords, n_clusts, iters, init_clusts);
    
    # save cluster results as individual arrays
    grid_strip_iter = np.linspace(0,num_gridStrips-1, num_gridStrips);
    sRAS_coords_list = [list(b) for b in sRAS_coords];
    clust_labels_list = list(clust_labels);
    for i in grid_strip_iter:
        coords = [];
        for d in sRAS_coords_list:
            if clust_labels_list[sRAS_coords_list.index(d)] == int(i):
               coords.append(d);
        coords = np.array(coords);
        scipy.io.savemat('clust%s.mat' %(i), {'elecmatrix':coords});