示例#1
0
    def mask_image(self,folder,in_path,out_path):
        """
        This function for creating mask_image.
        It is dependent on the class name: func.
        folder : read the string, new folder's name.
        in_path : read the list, element: string, directory address of data.
        out_path : read the string, name of the new data.

        For complete details, see the BET() documentation.
        <https://nipype.readthedocs.io/en/latest/interfaces.html>
        """
        print('#################_Mask_image_started_#######################')
        preprocessing = time.time()

        # Check and if not make the directory
        if not os.path.isdir(folder):
            func.newfolder(folder)

        # Create, and save the data : anatomy and whole brain mask image 
        for i in range(len(in_path)):
            output = folder+'/'+out_path[i]
            print(in_path[i], "mask image started")
            skullstrip = BET(in_file=in_path[i],
                             out_file=output,
                             mask=True)
            skullstrip.run()
            print(output,"mask image completed")
        print("computation_time :","%.2fs" %(time.time() - preprocessing))
        print('#################_Mask_image_completed_#####################')
示例#2
0
文件: app.py 项目: nicholsn/niquery
def bet(record):
    import nipype
    from nipype.interfaces.fsl import BET
    from nipype.utils.filemanip import hash_infile

    nipype.config.enable_provenance()

    in_file_uri = record['t1_uri']
    os.chdir('/tmp')
    fname = 'anatomy.nii.gz'

    with open(fname, 'wb') as fd:
        response = requests.get(in_file_uri, stream=True)
        if not response.ok:
            response.raise_for_status()
        for chunk in response.iter_content(1024):
            fd.write(chunk)

    # Check if interface has run with this input before
    sha = hash_infile(os.path.abspath(fname), crypto=hashlib.sha512)
    select = SelectQuery(config=app.config)
    res = select.execute_select('E0921842-1EDB-49F8-A4B3-BA51B85AD407')
    sha_recs = res[res.sha512.str.contains(sha)]
    bet_recs = res[res.interface.str.contains('BET')]
    results = dict()
    if sha_recs.empty or \
            (not sha_recs.empty and bet_recs.empty):
        better = BET()
        better.inputs.in_file = os.path.abspath(fname)
        result = better.run()
        prov = result.provenance.rdf().serialize(format='json-ld')
        results.update({'prov': prov})
    else:
        results.update({'prov': res.to_json(orient='records')})
    return results
示例#3
0
def skullstrip(infile: Path) -> Tuple[Path, Path]:
    cmd = BET()
    cmd.inputs.in_file = str(infile)
    cmd.inputs.out_file = str(infile).replace(SLICETIME_SUFFIX, BET_SUFFIX)
    cmd.inputs.output_type = "NIFTI_GZ"
    cmd.inputs.functional = True
    cmd.inputs.mask = True
    results = cmd.run()
    return results.outputs.out_file, results.outputs.mask_file
示例#4
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')
示例#5
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")
示例#6
0
def run_bet(
        skip_existing: bool = True
):
    full_pattern = os.path.join(DATA_DIR, PATTERN)
    scans = glob.iglob(full_pattern, recursive=True)
    for scan in scans:
        print(f'\nCurrent series: {scan}')
        if skip_existing:
            print('Checking for existing skull-stripping output...', end='\t')
        dest = get_default_destination(scan)
        if skip_existing and os.path.isfile(dest):
            print(f'\u2714')
            continue
        print(f'\u2718')
        print('Running skull-stripping with BET...')
        try:
            bet = Node(BET(robust=True), name='bet_node')
            bet.inputs.in_file = scan
            bet.inputs.out_file = dest
            bet.run()
            print(f'\u2714\tDone!')
        except Exception as e:
            print(f'\u2718')
            print(e.args)
            break
示例#7
0
def init_mpm_wf(me_params, mtsat_params):
    inputnode = Node(IdentityInterface(fields=['pdw_file', 't1w_file', 'mtw_file',
                                               'pdw_cal', 't1w_cal', 'mtw_cal']),
                     name='inputnode')
    outputnode = Node(IdentityInterface(fields=['pd_map', 'r1_map', 'r2s_map', 'mtsat_map']),
                      name='outputnode')

    bet = Node(BET(mask=True, no_output=True), name='brain_mask')
    mpm = Node(MPMR2s(sequence=me_params, verbose=True), name='MPM_R2s')
    mtsat = Node(MTSat(sequence=mtsat_params, verbose=True), name='MPM_MTSat')

    wf = Workflow(name='Multi-Parametric-Mapping')
    wf.connect([(inputnode, bet, [('t1w_file', 'in_file')]),
                (inputnode, mpm, [('pdw_file', 'pdw_file'),
                                  ('t1w_file', 't1w_file'),
                                  ('mtw_file', 'mtw_file')]),
                (bet, mpm, [('mask_file', 'mask_file')]),
                (mpm, mtsat, [('s0_pdw', 'pdw_file'),
                              ('s0_t1w', 't1w_file'),
                              ('s0_mtw', 'mtw_file')]),
                (bet, mtsat, [('mask_file', 'mask_file')]),
                (mpm, outputnode, [('r2s_map', 'r2s_map')]),
                (mtsat, outputnode, [('s0_map', 'pd_map'),
                                     ('r1_map', 'r1_map'),
                                     ('delta_map', 'mtsat_map')])])
    return wf
示例#8
0
def run_brain_extraction_bet(image, frac, subject_label, bids_dir):
    """
    Setup and FSLs brainextraction (BET) workflow.

    Parameters
    ----------
    image : str
        Path to image that should be defaced.
    frac : float
        Fractional intensity threshold (0 - 1).
    outfile : str
        Name of the defaced file.
    bids_dir : str
        Path to BIDS root directory.
    """

    import os

    outfile = os.path.join(
        bids_dir, "sourcedata/bidsonym/sub-%s" % subject_label,
        image[image.rfind('/') + 1:image.rfind('.nii')] +
        '_brainmask_desc-nondeid.nii.gz')

    brainextraction_wf = pe.Workflow('brainextraction_wf')
    inputnode = pe.Node(niu.IdentityInterface(['in_file']), name='inputnode')
    bet = pe.Node(BET(mask=False), name='bet')
    brainextraction_wf.connect([
        (inputnode, bet, [('in_file', 'in_file')]),
    ])
    inputnode.inputs.in_file = image
    bet.inputs.frac = float(frac)
    bet.inputs.out_file = outfile
    brainextraction_wf.run()
示例#9
0
def fmri_bmsk_workflow(name='fMRIBrainMask', use_bet=False):
    """Comute brain mask of an fmri dataset"""

    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']),
                        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
                         name='outputnode')

    if not use_bet:
        afni_msk = pe.Node(afni.Automask(
            outputtype='NIFTI_GZ'), name='afni_msk')

        # Connect brain mask extraction
        workflow.connect([
            (inputnode, afni_msk, [('in_file', 'in_file')]),
            (afni_msk, outputnode, [('out_file', 'out_file')])
        ])

    else:
        from nipype.interfaces.fsl import BET, ErodeImage
        bet_msk = pe.Node(BET(mask=True, functional=True), name='bet_msk')
        erode = pe.Node(ErodeImage(kernel_shape='box', kernel_size=1.0),
                        name='erode')

        # Connect brain mask extraction
        workflow.connect([
            (inputnode, bet_msk, [('in_file', 'in_file')]),
            (bet_msk, erode, [('mask_file', 'in_file')]),
            (erode, outputnode, [('out_file', 'out_file')])
        ])

    return workflow
示例#10
0
def run_quickshear(image, outfile):
    """
    Setup and run quickshear workflow.

    Parameters
    ----------
    image : str
        Path to image that should be defaced.
    outfile : str
        Name of the defaced file.
    """

    deface_wf = pe.Workflow('deface_wf')
    inputnode = pe.Node(niu.IdentityInterface(['in_file']),
                        name='inputnode')
    bet = pe.Node(BET(mask=True, frac=0.5), name='bet')
    quickshear = pe.Node(Quickshear(buff=50), name='quickshear')
    deface_wf.connect([
        (inputnode, bet, [('in_file', 'in_file')]),
        (inputnode, quickshear, [('in_file', 'in_file')]),
        (bet, quickshear, [('mask_file', 'mask_file')]),
        ])
    inputnode.inputs.in_file = image
    quickshear.inputs.out_file = outfile
    deface_wf.run()
示例#11
0
def create_workflow_coreg_epi2t1w():

    input_node = Node(IdentityInterface(fields=[
        'bold_mean',
        't2star_fov',
        't2star_whole',
        't1w',
        ]), name='input')
    output = Node(IdentityInterface(fields=[
        'mat_epi2t1w',
        ]), name='output')

    # node skull
    skull = Node(interface=BET(), name="skull_stripping")

    coreg_epi2fov = Node(FLIRT(), name='epi_2_fov')
    coreg_epi2fov.inputs.cost = 'mutualinfo'
    coreg_epi2fov.inputs.dof = 12
    coreg_epi2fov.inputs.no_search = True
    coreg_epi2fov.inputs.output_type = 'NIFTI_GZ'

    coreg_fov2whole = Node(FLIRT(), name='fov_2_whole')
    coreg_fov2whole.inputs.cost = 'mutualinfo'
    coreg_fov2whole.inputs.dof = 6
    coreg_fov2whole.inputs.output_type = 'NIFTI_GZ'

    coreg_whole2t1w = Node(EpiReg(), name='whole_2_t1w')

    concat_fov2t1w = Node(interface=ConvertXFM(), name='mat_fov2t1w')
    concat_fov2t1w.inputs.concat_xfm = True
    concat_epi2t1w = Node(interface=ConvertXFM(), name='mat_epi2t1w')
    concat_epi2t1w.inputs.concat_xfm = True

    w = Workflow('coreg_epi2t1w')

    w.connect(input_node, 'bold_mean', coreg_epi2fov, 'in_file')
    w.connect(input_node, 't2star_fov', coreg_epi2fov, 'reference')

    w.connect(input_node, 't2star_fov', coreg_fov2whole, 'in_file')
    w.connect(input_node, 't2star_whole', coreg_fov2whole, 'reference')

    w.connect(input_node, 't1w', skull, 'in_file')

    w.connect(input_node, 't2star_whole', coreg_whole2t1w, 'epi')
    w.connect(skull, 'out_file', coreg_whole2t1w, 't1_brain')
    w.connect(input_node, 't1w', coreg_whole2t1w, 't1_head')

    w.connect(coreg_fov2whole, 'out_matrix_file', concat_fov2t1w, 'in_file')
    w.connect(coreg_whole2t1w, 'epi2str_mat', concat_fov2t1w, 'in_file2')

    w.connect(coreg_epi2fov, 'out_matrix_file', concat_epi2t1w, 'in_file')
    w.connect(concat_fov2t1w, 'out_file', concat_epi2t1w, 'in_file2')

    w.connect(concat_epi2t1w, 'out_file', output, 'mat_epi2t1w')

    return w
示例#12
0
def test_skull_stripping_ids_only():

    data_dir = os.path.abspath('.') + '/data/ds114'
    pipeline_name = 'test_skullStrippingTransformer_ds114'

    IDS = ['01', '02', '03']
    sessions = ['test', 'retest']

    transformer = SkullStrippingTransformer(
        data_dir=data_dir,
        pipeline_name=pipeline_name,
        search_param=dict(extensions='T1w.nii.gz'),
        variant='skullStrippingIDsOnly')
    transformer.fit_transform(IDS)

    for subject in IDS:
        for session in sessions:

            in_file = build_T1w_in_file_path(data_dir, subject, session)

            out_file = build_T1w_out_file_path(data_dir, pipeline_name,
                                               subject, session,
                                               'skullStrippingIDsOnly',
                                               'neededBrain')

            dirname = os.path.dirname(out_file)
            if not os.path.exists(dirname):
                os.makedirs(dirname)

            betfsl = BET(in_file=in_file, out_file=out_file)
            betfsl.run()

            res_file = build_T1w_out_file_path(data_dir, pipeline_name,
                                               subject, session,
                                               'skullStrippingIDsOnly',
                                               'brain')

            result_mat = nib.load(res_file).affine
            output_mat = nib.load(out_file).affine
            assert np.allclose(result_mat, output_mat)
            os.remove(res_file)
            os.remove(out_file)
示例#13
0
def test_global_CommandLine_output(tmpdir):
    """Ensures CommandLine.set_default_terminal_output works"""
    from nipype.interfaces.fsl import BET

    ci = nib.CommandLine(command='ls -l')
    assert ci.terminal_output == 'stream'  # default case

    ci = BET()
    assert ci.terminal_output == 'stream'  # default case

    nib.CommandLine.set_default_terminal_output('allatonce')
    ci = nib.CommandLine(command='ls -l')
    assert ci.terminal_output == 'allatonce'

    nib.CommandLine.set_default_terminal_output('file')
    ci = nib.CommandLine(command='ls -l')
    assert ci.terminal_output == 'file'

    # Check default affects derived interfaces
    ci = BET()
    assert ci.terminal_output == 'file'
示例#14
0
def test_global_CommandLine_output(tmpdir):
    """Ensures CommandLine.set_default_terminal_output works"""
    from nipype.interfaces.fsl import BET

    ci = nib.CommandLine(command="ls -l")
    assert ci.terminal_output == "stream"  # default case

    ci = BET()
    assert ci.terminal_output == "stream"  # default case

    nib.CommandLine.set_default_terminal_output("allatonce")
    ci = nib.CommandLine(command="ls -l")
    assert ci.terminal_output == "allatonce"

    nib.CommandLine.set_default_terminal_output("file")
    ci = nib.CommandLine(command="ls -l")
    assert ci.terminal_output == "file"

    # Check default affects derived interfaces
    ci = BET()
    assert ci.terminal_output == "file"
示例#15
0
    def process_data_files(self, analysis, options):

        # since the conversion takes a while, change cursor to hourglass
        QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)

        if analysis == 'eddy':
            process = EddyCorrect()
        elif analysis == 'bet':
            process = BET()
        else:
            process = []

        for opt, value in options.items():
            process.inputs.__setattr__(opt, value)

        # get selected files
        in_files, out_files, temp_files = self.return_selected_files(analysis)

        for in_file, out_file, temp_file in zip(in_files, out_files,
                                                temp_files):

            if not os.path.isdir(os.path.split(out_file)[0]):
                os.mkdir(os.path.split(out_file)[0])

            process.inputs.in_file = in_file
            process.inputs.out_file = out_file

            if os.path.isfile(out_file):
                overwrite = self.overwrite_prompt(out_file)
                if not overwrite:
                    out_file = os.path.join(
                        os.path.split(out_file)[0],
                        'new_' + os.path.split(out_file)[1])
                elif overwrite is None:
                    return
            try:
                out = process.run()
            except RuntimeError as err:
                self.logFile += str(err)
            else:
                self.logFile += out.runtime.stdout
                if temp_file:
                    self.move_from_temp(out_file)
            if temp_file:
                self.move_from_temp(in_file)

        # update GUI
        self.scanDirectory(self.baseDir)
        self.updateGUI(0)
        self.updateFileNavigator(['.nii'])

        QApplication.restoreOverrideCursor()
        self.postProcessDisplayUpdate()
示例#16
0
def run_bet(robust: bool = True, skip_existing: bool = True):
    scans = get_scans(LOCATION_DICT["raw"])
    for scan in scans:
        print(f"\nCurrent series: {scan}")
        if skip_existing:
            print("Checking for existing skull-stripping output...", end="\t")
        dest = get_default_destination(scan)
        if skip_existing and os.path.isfile(dest):
            print(f"\u2714")
            continue
        print(f"\u2718")
        print("Running skull-stripping with BET...", end="\t")
        try:
            bet = BET(robust=True)
            bet.inputs.in_file = scan
            bet.inputs.out_file = dest
            bet.run()
            print(f"\u2714\tDone!")
        except Exception as e:
            print(f"\u2718")
            print(e.args)
            break
def run_quickshear(image, outfile):

    deface_wf = pe.Workflow('deface_wf')
    inputnode = pe.Node(niu.IdentityInterface(['in_file']), name='inputnode')
    bet = pe.Node(BET(mask=True, frac=0.5), name='bet')
    quickshear = pe.Node(Quickshear(buff=50), name='quickshear')
    deface_wf.connect([
        (inputnode, bet, [('in_file', 'in_file')]),
        (inputnode, quickshear, [('in_file', 'in_file')]),
        (bet, quickshear, [('mask_file', 'mask_file')]),
    ])
    inputnode.inputs.in_file = image
    quickshear.inputs.out_file = outfile
    deface_wf.run()
示例#18
0
def init_complex_mcf(name='', ref=False, fix_ge=True, negate=True):
    inputnode = Node(
        IdentityInterface(fields=['real_file', 'imag_file', 'ref_file']),
        name='inputnode')
    outputnode = Node(
        IdentityInterface(fields=['x_file', 'ref_file', 'mask_file']),
        name='outputnode')

    ri = Node(Complex(fix_ge=fix_ge,
                      negate=negate,
                      magnitude_out_file=name + '_mag.nii.gz',
                      real_out_file=name + '_r.nii.gz',
                      imag_out_file=name + '_i.nii.gz'),
              name='ri_' + name)
    moco = Node(MCFLIRT(mean_vol=not ref, save_mats=True), name='moco_' + name)
    apply_r = Node(ApplyXfm4D(four_digit=True), name='apply_r' + name)
    apply_i = Node(ApplyXfm4D(four_digit=True), name='apply_i' + name)
    x = Node(Complex(complex_out_file=name + '_x.nii.gz'), name='x_' + name)
    f = Node(Filter(complex_in=True, complex_out=True, filter_spec='Tukey'),
             name='filter_' + name)

    wf = Workflow(name='prep_' + name)
    wf.connect([(inputnode, ri, [('real_file', 'real')]),
                (inputnode, ri, [('imag_file', 'imag')]),
                (ri, moco, [('magnitude_out_file', 'in_file')]),
                (ri, apply_r, [('real_out_file', 'in_file')]),
                (ri, apply_i, [('imag_out_file', 'in_file')]),
                (moco, apply_r, [('mat_dir', 'trans_dir')]),
                (moco, apply_i, [('mat_dir', 'trans_dir')]),
                (apply_r, x, [('out_file', 'real')]),
                (apply_i, x, [('out_file', 'imag')]),
                (x, f, [('complex_out_file', 'in_file')]),
                (f, outputnode, [('out_file', 'x_file')])])
    if not ref:
        mask = Node(BET(mask=True, no_output=True), name='mask')
        wf.connect([(moco, mask, [('mean_img', 'in_file')]),
                    (moco, apply_r, [('mean_img', 'ref_vol')]),
                    (moco, apply_i, [('mean_img', 'ref_vol')]),
                    (moco, outputnode, [('mean_img', 'ref_file')]),
                    (mask, outputnode, [('mask_file', 'mask_file')])])
    else:
        wf.connect([(inputnode, moco, [('ref_file', 'ref_file')]),
                    (inputnode, apply_r, [('ref_file', 'ref_vol')]),
                    (inputnode, apply_i, [('ref_file', 'ref_vol')])])

    return wf
示例#19
0
def run_quickshear(image, outfile):
    # quickshear anat_file mask_file defaced_file [buffer]
    deface_wf = pe.Workflow("deface_wf")
    inputnode = pe.Node(niu.IdentityInterface(["in_file"]), name="inputnode")
    outputnode = pe.Node(niu.IdentityInterface(["out_file"]), name="outputnode")
    bet = pe.Node(BET(mask=True, frac=0.5), name="bet")
    quickshear = pe.Node(Quickshear(buff=50), name="quickshear")
    deface_wf.connect(
        [
            (inputnode, bet, [("in_file", "in_file")]),
            (inputnode, quickshear, [("in_file", "in_file")]),
            (bet, quickshear, [("mask_file", "mask_file")]),
        ]
    )
    inputnode.inputs.in_file = image
    quickshear.inputs.out_file = outfile
    res = deface_wf.run()
示例#20
0
文件: utils.py 项目: iPsych/BIDSonym
def run_brain_extraction_bet(image, frac, subject_label, bids_dir):

    import os

    outfile = os.path.join(
        bids_dir, "sourcedata/bidsonym/sub-%s" % subject_label,
        "sub-%s_space-native_brainmask.nii.gz" % subject_label)

    brainextraction_wf = pe.Workflow('brainextraction_wf')
    inputnode = pe.Node(niu.IdentityInterface(['in_file']), name='inputnode')
    bet = pe.Node(BET(mask=True), name='bet')
    brainextraction_wf.connect([
        (inputnode, bet, [('in_file', 'in_file')]),
    ])
    inputnode.inputs.in_file = image
    bet.inputs.frac = float(frac)
    bet.inputs.out_file = outfile
    brainextraction_wf.run()
示例#21
0
def runNipypeBet(controller, subject_list, anatomical_id, proj_directory):

    infosource = Node(IdentityInterface(fields=['subject_id']),
                      name="infosource")
    infosource.iterables = [('subject_id', subject_list)]

    #anat_file = opj('{subject_id}','{subject_id}_{anatomical_id}.nii')
    seperator = ''
    concat_words = ('{subject_id}_', anatomical_id, '.nii.gz')
    anat_file_name = seperator.join(concat_words)

    if controller.b_radiological_convention.get() == True:
        anat_file = opj('{subject_id}', anat_file_name)
    else:
        anat_file = opj('{subject_id}', 'Intermediate_Files', 'Original_Files',
                        anat_file_name)

    templates = {'anat': anat_file}

    selectfiles = Node(SelectFiles(templates, base_directory=proj_directory),
                       name="selectfiles")

    skullstrip = Node(BET(robust=True,
                          frac=0.5,
                          vertical_gradient=0,
                          output_type='NIFTI_GZ'),
                      name="skullstrip")

    # Datasink - creates output folder for important outputs
    datasink = Node(DataSink(base_directory=proj_directory), name="datasink")

    wf_sub = Workflow(name="wf_sub")
    wf_sub.base_dir = proj_directory
    wf_sub.connect(infosource, "subject_id", selectfiles, "subject_id")
    wf_sub.connect(selectfiles, "anat", skullstrip, "in_file")
    wf_sub.connect(skullstrip, "out_file", datasink, "bet.@out_file")

    substitutions = [('%s_brain' % (anatomical_id), 'brain')]
    # Feed the substitution strings to the DataSink node
    datasink.inputs.substitutions = substitutions
    # Run the workflow again with the substitutions in place
    wf_sub.run(plugin='MultiProc')

    return 'brain'
示例#22
0
def deface(in_file):
    deface_wf = pe.Workflow('deface_wf')
    inputnode = pe.Node(niu.IdentityInterface(['in_file']),
                     name='inputnode')
    # outputnode = pe.Node(niu.IdentityInterface(['out_file']),
    #                      name='outputnode')
    bet = pe.Node(BET(mask=True), name='bet')
    quickshear = pe.Node(Quickshear(), name='quickshear')
    sinker = pe.Node(DataSink(), name='store_results')
    sinker.inputs.base_directory = os.getcwd()

    deface_wf.connect([
        (inputnode, bet, [('in_file', 'in_file')]),
        (inputnode, quickshear, [('in_file', 'in_file')]),
        (bet, quickshear, [('mask_file', 'mask_file')]),
        (quickshear, sinker, [('out_file', '@')]),
    ])
    inputnode.inputs.in_file = in_file
    res = deface_wf.run()
示例#23
0
def fmri_bmsk_workflow(name='fMRIBrainMask', use_bet=False):
    """
    Computes a brain mask for the input :abbr:`fMRI (functional MRI)`
    dataset

    .. workflow::

      from mriqc.workflows.functional import fmri_bmsk_workflow
      wf = fmri_bmsk_workflow()


    """

    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']),
                        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']),
                         name='outputnode')

    if not use_bet:
        afni_msk = pe.Node(afni.Automask(outputtype='NIFTI_GZ'),
                           name='afni_msk')

        # Connect brain mask extraction
        workflow.connect([(inputnode, afni_msk, [('in_file', 'in_file')]),
                          (afni_msk, outputnode, [('out_file', 'out_file')])])

    else:
        from nipype.interfaces.fsl import BET, ErodeImage
        bet_msk = pe.Node(BET(mask=True, functional=True), name='bet_msk')
        erode = pe.Node(ErodeImage(), name='erode')

        # Connect brain mask extraction
        workflow.connect([(inputnode, bet_msk, [('in_file', 'in_file')]),
                          (bet_msk, erode, [('mask_file', 'in_file')]),
                          (erode, outputnode, [('out_file', 'out_file')])])

    return workflow
def iterPipeline(resultsDir, workDir, subDir, subid):
	ANAT_DIR = abspath(join(subDir, 'ses-test/anat'))
	ANAT_T1W = abspath(join(ANAT_DIR,  subid + '_ses-test_T1w.nii.gz'))
	ANAT_BET_T1W=abspath(join(resultsDir, subid + '_ses-test_T1w_bet.nii.gz'))

	betNodeInputs={}
	betNodeInputs['in_file']=ANAT_T1W
	betNodeInputs['mask']=True
	skullstrip = createNiPypeNode(BET(),'skullstrip',betNodeInputs)

	smoothNodeInputs = {}
	isosmooth = createNiPypeNode(IsotropicSmooth(),'isosmooth',smoothNodeInputs)

	isosmooth.iterables = ("fwhm", [4, 8, 16])

	# Create the workflow
	wfName = "isosmoothflow"
	wf = Workflow(name=wfName)
	WF_DIR=abspath(join(workDir, wfName))
	wf.base_dir = WF_DIR
	wf.connect(skullstrip, 'out_file', isosmooth, 'in_file')

	# Run it in parallel (one core for each smoothing kernel)
	wf.run('MultiProc', plugin_args={'n_procs': 3})
	#graph showing summary of embedded workflow
	wfGraph='smoothflow_graph.dot'
	wf.write_graph(join(WF_DIR,wfGraph), graph2use='exec', format='png', simple_form=True)
	wfImg = plt.imread(join(WF_DIR,wfGraph+'.png'))
	plt.imshow(wfImg)
	plt.gca().set_axis_off()
	plt.show()

	# First, let's specify the list of input variables
	subject_list = ['sub-01', 'sub-02', 'sub-03', 'sub-04', 'sub-05']
	session_list = ['ses-retest', 'ses-test']
	fwhm_widths = [4, 8]
示例#25
0
def canonical(subjects_participants, regdir, f2s,
	template = "~/GitHub/mriPipeline/templates/waxholm/WHS_SD_rat_T2star_v1.01_downsample3.nii.gz",
	f_file_format = "~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_SE_EPI/f_bru2nii/",
	s_file_format = "~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_T2_TurboRARE/s_bru2nii/",
	):

	"""Warp a functional image based on the functional-to-structural and the structural-to-template registrations.
	Currently this approach is failing because the functiona-to-structural registration pushes the brain stem too far down.
	This may be

	"""
	template = os.path.expanduser(template)
	for subject_participant in subjects_participants:
		func_image_dir = os.path.expanduser(f_file_format.format(**subject_participant))
		struct_image_dir = os.path.expanduser(s_file_format.format(**subject_participant))
		try:
			for myfile in os.listdir(func_image_dir):
				if myfile.endswith((".nii.gz", ".nii")):
					func_image = os.path.join(func_image_dir,myfile)
			for myfile in os.listdir(struct_image_dir):
				if myfile.endswith((".nii.gz", ".nii")):
					struct_image = os.path.join(struct_image_dir,myfile)
		except FileNotFoundError:
			pass
		else:
			#struct
			n4 = ants.N4BiasFieldCorrection()
			n4.inputs.dimension = 3
			n4.inputs.input_image = struct_image
			# correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
			n4.inputs.bspline_fitting_distance = 100
			n4.inputs.shrink_factor = 2
			n4.inputs.n_iterations = [200,200,200,200]
			n4.inputs.convergence_threshold = 1e-11
			n4.inputs.output_image = '{}/ss_n4_{}_ofM{}.nii.gz'.format(regdir,participant,i)
			n4_res = n4.run()

			_n4 = ants.N4BiasFieldCorrection()
			_n4.inputs.dimension = 3
			_n4.inputs.input_image = struct_image
			# correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
			_n4.inputs.bspline_fitting_distance = 95
			_n4.inputs.shrink_factor = 2
			_n4.inputs.n_iterations = [500,500,500,500]
			_n4.inputs.convergence_threshold = 1e-14
			_n4.inputs.output_image = '{}/ss__n4_{}_ofM{}.nii.gz'.format(regdir,participant,i)
			_n4_res = _n4.run()

			#we do this on a separate bias-corrected image to remove hyperintensities which we have to create in order to prevent brain regions being caught by the negative threshold
			struct_cutoff = ImageMaths()
			struct_cutoff.inputs.op_string = "-thrP 20 -uthrp 98"
			struct_cutoff.inputs.in_file = _n4_res.outputs.output_image
			struct_cutoff_res = struct_cutoff.run()

			struct_BET = BET()
			struct_BET.inputs.mask = True
			struct_BET.inputs.frac = 0.3
			struct_BET.inputs.robust = True
			struct_BET.inputs.in_file = struct_cutoff_res.outputs.out_file
			struct_BET_res = struct_BET.run()

			struct_mask = ApplyMask()
			struct_mask.inputs.in_file = n4_res.outputs.output_image
			struct_mask.inputs.mask_file = struct_BET_res.outputs.mask_file
			struct_mask_res = struct_mask.run()

			struct_registration = ants.Registration()
			struct_registration.inputs.fixed_image = template
			struct_registration.inputs.output_transform_prefix = "output_"
			struct_registration.inputs.transforms = ['Affine', 'SyN'] ##
			struct_registration.inputs.transform_parameters = [(1.0,), (1.0, 3.0, 5.0)] ##
			struct_registration.inputs.number_of_iterations = [[2000, 1000, 500], [100, 100, 100]] #
			struct_registration.inputs.dimension = 3
			struct_registration.inputs.write_composite_transform = True
			struct_registration.inputs.collapse_output_transforms = True
			struct_registration.inputs.initial_moving_transform_com = True
			# Tested on Affine transform: CC takes too long; Demons does not tilt, but moves the slices too far caudally; GC tilts too much on
			struct_registration.inputs.metric = ['MeanSquares', 'Mattes']
			struct_registration.inputs.metric_weight = [1, 1]
			struct_registration.inputs.radius_or_number_of_bins = [16, 32] #
			struct_registration.inputs.sampling_strategy = ['Random', None]
			struct_registration.inputs.sampling_percentage = [0.3, 0.3]
			struct_registration.inputs.convergence_threshold = [1.e-11, 1.e-8] #
			struct_registration.inputs.convergence_window_size = [20, 20]
			struct_registration.inputs.smoothing_sigmas = [[4, 2, 1], [4, 2, 1]]
			struct_registration.inputs.sigma_units = ['vox', 'vox']
			struct_registration.inputs.shrink_factors = [[3, 2, 1],[3, 2, 1]]
			struct_registration.inputs.use_estimate_learning_rate_once = [True, True]
			# if the fixed_image is not acquired similarly to the moving_image (e.g. RARE to histological (e.g. AMBMC)) this should be False
			struct_registration.inputs.use_histogram_matching = [False, False]
			struct_registration.inputs.winsorize_lower_quantile = 0.005
			struct_registration.inputs.winsorize_upper_quantile = 0.98
			struct_registration.inputs.args = '--float'
			struct_registration.inputs.num_threads = 6

			struct_registration.inputs.moving_image = struct_mask_res.outputs.out_file
			struct_registration.inputs.output_warped_image = '{}/s_{}_ofM{}.nii.gz'.format(regdir,participant,i)
			struct_registration_res = struct_registration.run()

			#func
			func_n4 = ants.N4BiasFieldCorrection()
			func_n4.inputs.dimension = 3
			func_n4.inputs.input_image = func_image
			func_n4.inputs.bspline_fitting_distance = 100
			func_n4.inputs.shrink_factor = 2
			func_n4.inputs.n_iterations = [200,200,200,200]
			func_n4.inputs.convergence_threshold = 1e-11
			func_n4.inputs.output_image = '{}/f_n4_{}_ofM{}.nii.gz'.format(regdir,participant,i)
			func_n4_res = func_n4.run()

			func_registration = ants.Registration()
			func_registration.inputs.fixed_image = n4_res.outputs.output_image
			func_registration.inputs.output_transform_prefix = "func_"
			func_registration.inputs.transforms = [f2s]
			func_registration.inputs.transform_parameters = [(0.1,)]
			func_registration.inputs.number_of_iterations = [[40, 20, 10]]
			func_registration.inputs.dimension = 3
			func_registration.inputs.write_composite_transform = True
			func_registration.inputs.collapse_output_transforms = True
			func_registration.inputs.initial_moving_transform_com = True
			func_registration.inputs.metric = ['MeanSquares']
			func_registration.inputs.metric_weight = [1]
			func_registration.inputs.radius_or_number_of_bins = [16]
			func_registration.inputs.sampling_strategy = ["Regular"]
			func_registration.inputs.sampling_percentage = [0.3]
			func_registration.inputs.convergence_threshold = [1.e-2]
			func_registration.inputs.convergence_window_size = [8]
			func_registration.inputs.smoothing_sigmas = [[4, 2, 1]] # [1,0.5,0]
			func_registration.inputs.sigma_units = ['vox']
			func_registration.inputs.shrink_factors = [[3, 2, 1]]
			func_registration.inputs.use_estimate_learning_rate_once = [True]
			func_registration.inputs.use_histogram_matching = [False]
			func_registration.inputs.winsorize_lower_quantile = 0.005
			func_registration.inputs.winsorize_upper_quantile = 0.995
			func_registration.inputs.args = '--float'
			func_registration.inputs.num_threads = 6

			func_registration.inputs.moving_image = func_n4_res.outputs.output_image
			func_registration.inputs.output_warped_image = '{}/f_{}_ofM{}.nii.gz'.format(regdir,participant,i)
			func_registration_res = func_registration.run()

			warp = ants.ApplyTransforms()
			warp.inputs.reference_image = template
			warp.inputs.input_image_type = 3
			warp.inputs.interpolation = 'Linear'
			warp.inputs.invert_transform_flags = [False, False]
			warp.inputs.terminal_output = 'file'
			warp.inputs.output_image = '{}/{}_ofM{}.nii.gz'.format(regdir,participant,i)
			warp.num_threads = 6

			warp.inputs.input_image = func_image
			warp.inputs.transforms = [func_registration_res.outputs.composite_transform, struct_registration_res.outputs.composite_transform]
			warp.run()
#from mriqc.motion import plot_frame_displacement
#
#test_workflow = Workflow(name="qc_workflow")
#
#test_workflow.base_dir = work_dir


#from nipype import SelectFiles
#templates = dict(T1="*_{subject_id}_*/T1w_MPR_BIC_v1/*00001.nii*")
#file_list = Node(SelectFiles(templates), name = "EPI_and_T1_File_Selection")
#file_list.inputs.base_directory = data_dir
#file_list.iterables = [("subject_id", subject_list), ("p_dir", ["LR", "RL"])]


from nipype.interfaces.fsl import BET

mask_gen = BET()
mask_gen.inputs.in_file = "/Users/craigmoodie/Documents/AA_Connectivity_Psychosis/AA_Connectivity_Analysis/10_Subject_ICA_test/Subject_1/T1w_MPR_BIC_v1/S1543TWL_P126317_1_19_00001.nii"
mask_gen.inputs.mask = True
mask_gen.inputs.out_file = "bet_mean"
mask_gen.run()


#mask_gen = MapNode(BET(), name="Mask_Generation", iterfield="in_file")



#from spatial_qc import summary_mask, ghost_all, ghost_direction, ghost_mask, fwhm, artifacts, efc, cnr, snr
#
#
#summary_mask()
def create_workflow(subject_id, outdir, file_url):
    """Create a workflow for a single participant"""

    sink_directory = os.path.join(outdir, subject_id)

    wf = Workflow(name=subject_id)

    getter = Node(Function(input_names=['url'],
                           output_names=['localfile'],
                           function=download_file),
                  name="download_url")
    getter.inputs.url = file_url

    orienter = Node(Reorient2Std(), name='reorient_brain')
    wf.connect(getter, 'localfile', orienter, 'in_file')

    better = Node(BET(), name='extract_brain')
    wf.connect(orienter, 'out_file', better, 'in_file')

    faster = Node(FAST(), name='segment_brain')
    wf.connect(better, 'out_file', faster, 'in_files')

    firster = Node(FIRST(), name='parcellate_brain')
    structures = [
        'L_Hipp', 'R_Hipp', 'L_Accu', 'R_Accu', 'L_Amyg', 'R_Amyg', 'L_Caud',
        'R_Caud', 'L_Pall', 'R_Pall', 'L_Puta', 'R_Puta', 'L_Thal', 'R_Thal'
    ]
    firster.inputs.list_of_specific_structures = structures
    wf.connect(orienter, 'out_file', firster, 'in_file')

    fslstatser = MapNode(ImageStats(),
                         iterfield=['op_string'],
                         name="compute_segment_stats")
    fslstatser.inputs.op_string = [
        '-l {thr1} -u {thr2} -v'.format(thr1=val + 0.5, thr2=val + 1.5)
        for val in range(3)
    ]
    wf.connect(faster, 'partial_volume_map', fslstatser, 'in_file')

    jsonfiler = Node(Function(
        input_names=['stats', 'seg_file', 'structure_map', 'struct_file'],
        output_names=['out_file'],
        function=toJSON),
                     name='save_json')
    structure_map = [('Background', 0), ('Left-Thalamus-Proper', 10),
                     ('Left-Caudate', 11), ('Left-Putamen', 12),
                     ('Left-Pallidum', 13), ('Left-Hippocampus', 17),
                     ('Left-Amygdala', 18), ('Left-Accumbens-area', 26),
                     ('Right-Thalamus-Proper', 49), ('Right-Caudate', 50),
                     ('Right-Putamen', 51), ('Right-Pallidum', 52),
                     ('Right-Hippocampus', 53), ('Right-Amygdala', 54),
                     ('Right-Accumbens-area', 58)]
    jsonfiler.inputs.structure_map = structure_map
    wf.connect(fslstatser, 'out_stat', jsonfiler, 'stats')
    wf.connect(firster, 'segmentation_file', jsonfiler, 'seg_file')

    sinker = Node(DataSink(), name='store_results')
    sinker.inputs.base_directory = sink_directory
    wf.connect(better, 'out_file', sinker, 'brain')
    wf.connect(faster, 'bias_field', sinker, 'segs.@bias_field')
    wf.connect(faster, 'partial_volume_files', sinker, 'segs.@partial_files')
    wf.connect(faster, 'partial_volume_map', sinker, 'segs.@partial_map')
    wf.connect(faster, 'probability_maps', sinker, 'segs.@prob_maps')
    wf.connect(faster, 'restored_image', sinker, 'segs.@restored')
    wf.connect(faster, 'tissue_class_files', sinker, 'segs.@tissue_files')
    wf.connect(faster, 'tissue_class_map', sinker, 'segs.@tissue_map')
    wf.connect(firster, 'bvars', sinker, 'parcels.@bvars')
    wf.connect(firster, 'original_segmentations', sinker, 'parcels.@origsegs')
    wf.connect(firster, 'segmentation_file', sinker, 'parcels.@segfile')
    wf.connect(firster, 'vtk_surfaces', sinker, 'parcels.@vtk')
    wf.connect(jsonfiler, 'out_file', sinker, '@stats')

    return wf
import os 
from os.path import abspath
from datetime import datetime
from IPython.display import Image
import pydot
from nipype import Workflow, Node, MapNode, Function, config
from nipype.interfaces.fsl import TOPUP, ApplyTOPUP, BET, ExtractROI,  Eddy, FLIRT, FUGUE
from nipype.interfaces.fsl.maths import MathsCommand
import nipype.interfaces.utility as util 
import nipype.interfaces.mrtrix3 as mrt
#Requirements for the workflow to run smoothly: All files as in NIfTI-format and named according to the following standard: 
#Images are from the tonotopy DKI sequences on the 7T Philips Achieva scanner in Lund. It should work with any DKI sequence and possibly also a standard DTI but the setting for B0-corrections, epi-distortion corrections and eddy current corrections will be wrong. 
#DKI file has a base name shared with bvec and bval in FSL format. E.g. "DKI.nii.gz" "DKI.bvec" and "DKI.bval". 
#There is one b0-volume with reversed (P->A) phase encoding called DKIbase+_revenc. E.g. "DKI_revenc.nii.gz". 
#Philips B0-map magnitude and phase offset (in Hz) images. 
#One input file for topup describing the images as specified by topup. 
#Set nbrOfThreads to number of available CPU threads to run the analyses. 
### Need to make better revenc for the 15 version if we choose to use it (i.e. same TE and TR)
#Set to relevant directory/parameters
datadir=os.path.abspath("/Users/ling-men/Documents/MRData/testDKI")
rawDKI_base='DKI_15' 
B0map_base = 'B0map'
nbrOfThreads=6
print_graph = True 
acqparam_file = os.path.join(datadir,'acqparams.txt')
index_file = os.path.join(datadir,'index.txt')
####
#config.enable_debug_mode()
DKI_nii=os.path.join(datadir, rawDKI_base+'.nii.gz')
DKI_bval=os.path.join(datadir, rawDKI_base+'.bval')
示例#29
0
                                             delimiter=','),
                            name='extract_confounds_global_signal')

signal_extraction = Node(SignalExtraction(
    time_series_out_file='time_series.csv',
    correlation_matrix_out_file='correlation_matrix.png',
    atlas_identifier='cort-maxprob-thr25-2mm',
    tr=TR,
    plot=True),
                         name='signal_extraction')

art_remotion = Node(ArtifacRemotion(out_file='fmri_art_removed.nii'),
                    name='artifact_remotion')

# BET - Skullstrip anatomical anf funtional images
bet_t1 = Node(BET(frac=0.55, robust=True, mask=True, output_type='NIFTI_GZ'),
              name="bet_t1")

bet_fmri = Node(BET(frac=0.6, functional=True, output_type='NIFTI_GZ'),
                name="bet_fmri")

# FAST - Image Segmentation
segmentation = Node(FAST(output_type='NIFTI'), name="segmentation")

# Normalize - normalizes functional and structural images to the MNI template
normalize_fmri = Node(Normalize12(jobtype='estwrite',
                                  tpm=template,
                                  write_voxel_sizes=[2, 2, 2],
                                  write_bounding_box=[[-90, -126, -72],
                                                      [90, 90, 108]]),
                      name="normalize_fmri")
示例#30
0
                                             delimiter=','),
                            name='extract_confounds_global_signal')

signal_extraction = Node(SignalExtraction(
    time_series_out_file='time_series.csv',
    correlation_matrix_out_file='correlation_matrix.png',
    atlas_identifier='cort-maxprob-thr25-2mm',
    tr=TR,
    plot=True),
                         name='signal_extraction')

art_remotion = Node(ArtifacRemotion(out_file='fmri_art_removed.nii'),
                    name='artifact_remotion')

# BET - Skullstrip anatomical anf funtional images
bet_t1 = Node(BET(frac=0.5, robust=True, mask=True, output_type='NIFTI_GZ'),
              name="bet_t1")

# FAST - Image Segmentation
segmentation = Node(FAST(output_type='NIFTI'), name="segmentation")

# Normalize - normalizes functional and structural images to the MNI template
normalize_fmri = Node(Normalize12(jobtype='estwrite',
                                  tpm=template,
                                  write_voxel_sizes=[2, 2, 2],
                                  write_bounding_box=[[-90, -126, -72],
                                                      [90, 90, 108]]),
                      name="normalize_fmri")

gunzip = Node(Gunzip(), name="gunzip")
示例#31
0
    def __init__(self, parent, dir_dic, bids):
        super().__init__(parent, dir_dic, bids)

        # Create interfaces ============================================================================================
        # BET
        T1w_BET = Node(BET(), name="T1w_BET")
        T1w_BET.btn_string = 'T1w Brain Extraction'
        self.interfaces.append(T1w_BET)

        T1w_gad_BET = Node(BET(), name="T1w_gad_BET")
        T1w_gad_BET.btn_string = 'T1w Gadolinium Enhanced Brain Extraction'
        self.interfaces.append(T1w_gad_BET)

        T2w_dbs_BET = Node(BET(), name="T2w_dbs_BET")
        T2w_dbs_BET.btn_string = 'T2w DBS Acquisition Brain Extraction'
        self.interfaces.append(T2w_dbs_BET)

        dwi_BET = Node(BET(), name="dwi_BET")
        dwi_BET.btn_string = 'dwi Brain Extraction'
        self.interfaces.append(dwi_BET)

        # BFC
        T1w_BFC = Node(N4BiasFieldCorrection(), name="T1w_BFC")
        T1w_BFC.btn_string = 'T1w Bias Field Correction'
        self.interfaces.append(T1w_BFC)

        # Split
        dwi_ROI_b0 = Node(ExtractROI(), name="dwi_ROI_b0")
        dwi_ROI_b0.btn_string = 'dwi Extract b0'
        self.interfaces.append(dwi_ROI_b0)

        # Eddy current correction
        dwi_Eddy = Node(Eddy(), name="dwi_Eddy")
        dwi_Eddy.btn_string = 'dwi Eddy Current Correction'
        self.interfaces.append(dwi_Eddy)

        # Distortion correction
        # as this section is script/comment heavy it was put into a function
        self.distortion_correction_workflow()

        # Data output (i.e. sink) ======================================================================================
        self.sink = Node(DataSink(), name="sink")
        self.sink.btn_string = 'data sink'
        self.sink.inputs.base_directory = self.dir_dic['data_dir']

        self.jsink = Node(JSONFileSink(), name="jsink")
        self.jsink.btn_string = 'json sink'
        self.jsink.inputs.base_directory = self.dir_dic['data_dir']

        # Initialize workflow ==========================================================================================
        self.wf = Workflow(name='pre_processing')

        # T1w BET to ants N4BiasFieldCorrection
        self.wf.connect([(self.return_interface("T1w_BET"),
                          self.return_interface("T1w_BFC"),
                          [("out_file", "input_image")])])
        self.wf.connect([(self.return_interface("T1w_BET"),
                          self.return_interface("T1w_BFC"), [("mask_file",
                                                              "mask_image")])])

        # Eddy
        self.wf.connect([(self.return_interface("dwi_BET"),
                          self.return_interface("dwi_Eddy"), [("out_file",
                                                               "in_file")])])

        self.wf.connect([(self.return_interface("dwi_BET"),
                          self.return_interface("dwi_Eddy"), [("mask_file",
                                                               "in_mask")])])

        # ROI b0
        self.wf.connect([(self.return_interface("dwi_Eddy"),
                          self.return_interface("dwi_ROI_b0"),
                          [("out_corrected", "in_file")])])

        # Distortion Correction:
        # b0_T1_Reg:
        #   -i: moving image
        #   -r: T1
        #   -x: T1 mask
        self.wf.connect([(self.return_interface("dwi_ROI_b0"),
                          self.return_interface("b0_T1w_Reg"),
                          [("roi_file", "moving_image")])])

        self.wf.connect([(self.return_interface("T1w_BFC"),
                          self.return_interface("b0_T1w_Reg"),
                          [("output_image", "fixed_image")])])

        # test remove as doesn't seem useful (see self.distortion_correction_workflow()) and causes a crash when added
        # self.wf.connect([(self.return_interface("T1w_BET"), self.return_interface("b0_T1w_Reg"),
        #                   [("mask_file", "fixed_image_mask")])])

        # dwi_T1_Tran:
        #   -i: Eddy corrected image
        #   -r: Eddy corrected b0
        #   -t: transforms
        self.wf.connect([(self.return_interface("dwi_Eddy"),
                          self.return_interface("dwi_T1w_Tran"),
                          [("out_corrected", "input_image")])])

        self.wf.connect([(self.return_interface("dwi_ROI_b0"),
                          self.return_interface("dwi_T1w_Tran"),
                          [("roi_file", "reference_image")])])

        self.wf.connect([(self.return_interface("b0_T1w_Reg"),
                          self.return_interface("dwi_T1w_Tran"),
                          [("composite_transform", "transforms")])])

        # BaseInterface generates a dict mapping button strings to the workflow nodes
        # self.map_workflow()
        graph_file = self.wf.write_graph("pre_processing", graph2use='flat')
        self.graph_file = graph_file.replace("pre_processing.png",
                                             "pre_processing_detailed.png")

        self.init_settings()
        self.init_ui()
示例#32
0
def canonical(
    subjects_participants,
    regdir,
    f2s,
    template="~/GitHub/mriPipeline/templates/waxholm/WHS_SD_rat_T2star_v1.01_downsample3.nii.gz",
    f_file_format="~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_SE_EPI/f_bru2nii/",
    s_file_format="~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_T2_TurboRARE/s_bru2nii/",
):
    """Warp a functional image based on the functional-to-structural and the structural-to-template registrations.
	Currently this approach is failing because the functiona-to-structural registration pushes the brain stem too far down.
	This may be

	"""
    template = os.path.expanduser(template)
    for subject_participant in subjects_participants:
        func_image_dir = os.path.expanduser(
            f_file_format.format(**subject_participant))
        struct_image_dir = os.path.expanduser(
            s_file_format.format(**subject_participant))
        try:
            for myfile in os.listdir(func_image_dir):
                if myfile.endswith((".nii.gz", ".nii")):
                    func_image = os.path.join(func_image_dir, myfile)
            for myfile in os.listdir(struct_image_dir):
                if myfile.endswith((".nii.gz", ".nii")):
                    struct_image = os.path.join(struct_image_dir, myfile)
        except FileNotFoundError:
            pass
        else:
            #struct
            n4 = ants.N4BiasFieldCorrection()
            n4.inputs.dimension = 3
            n4.inputs.input_image = struct_image
            # correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
            n4.inputs.bspline_fitting_distance = 100
            n4.inputs.shrink_factor = 2
            n4.inputs.n_iterations = [200, 200, 200, 200]
            n4.inputs.convergence_threshold = 1e-11
            n4.inputs.output_image = '{}/ss_n4_{}_ofM{}.nii.gz'.format(
                regdir, participant, i)
            n4_res = n4.run()

            _n4 = ants.N4BiasFieldCorrection()
            _n4.inputs.dimension = 3
            _n4.inputs.input_image = struct_image
            # correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
            _n4.inputs.bspline_fitting_distance = 95
            _n4.inputs.shrink_factor = 2
            _n4.inputs.n_iterations = [500, 500, 500, 500]
            _n4.inputs.convergence_threshold = 1e-14
            _n4.inputs.output_image = '{}/ss__n4_{}_ofM{}.nii.gz'.format(
                regdir, participant, i)
            _n4_res = _n4.run()

            #we do this on a separate bias-corrected image to remove hyperintensities which we have to create in order to prevent brain regions being caught by the negative threshold
            struct_cutoff = ImageMaths()
            struct_cutoff.inputs.op_string = "-thrP 20 -uthrp 98"
            struct_cutoff.inputs.in_file = _n4_res.outputs.output_image
            struct_cutoff_res = struct_cutoff.run()

            struct_BET = BET()
            struct_BET.inputs.mask = True
            struct_BET.inputs.frac = 0.3
            struct_BET.inputs.robust = True
            struct_BET.inputs.in_file = struct_cutoff_res.outputs.out_file
            struct_BET_res = struct_BET.run()

            struct_mask = ApplyMask()
            struct_mask.inputs.in_file = n4_res.outputs.output_image
            struct_mask.inputs.mask_file = struct_BET_res.outputs.mask_file
            struct_mask_res = struct_mask.run()

            struct_registration = ants.Registration()
            struct_registration.inputs.fixed_image = template
            struct_registration.inputs.output_transform_prefix = "output_"
            struct_registration.inputs.transforms = ['Affine', 'SyN']  ##
            struct_registration.inputs.transform_parameters = [(1.0, ),
                                                               (1.0, 3.0, 5.0)
                                                               ]  ##
            struct_registration.inputs.number_of_iterations = [[
                2000, 1000, 500
            ], [100, 100, 100]]  #
            struct_registration.inputs.dimension = 3
            struct_registration.inputs.write_composite_transform = True
            struct_registration.inputs.collapse_output_transforms = True
            struct_registration.inputs.initial_moving_transform_com = True
            # Tested on Affine transform: CC takes too long; Demons does not tilt, but moves the slices too far caudally; GC tilts too much on
            struct_registration.inputs.metric = ['MeanSquares', 'Mattes']
            struct_registration.inputs.metric_weight = [1, 1]
            struct_registration.inputs.radius_or_number_of_bins = [16, 32]  #
            struct_registration.inputs.sampling_strategy = ['Random', None]
            struct_registration.inputs.sampling_percentage = [0.3, 0.3]
            struct_registration.inputs.convergence_threshold = [1.e-11,
                                                                1.e-8]  #
            struct_registration.inputs.convergence_window_size = [20, 20]
            struct_registration.inputs.smoothing_sigmas = [[4, 2, 1],
                                                           [4, 2, 1]]
            struct_registration.inputs.sigma_units = ['vox', 'vox']
            struct_registration.inputs.shrink_factors = [[3, 2, 1], [3, 2, 1]]
            struct_registration.inputs.use_estimate_learning_rate_once = [
                True, True
            ]
            # if the fixed_image is not acquired similarly to the moving_image (e.g. RARE to histological (e.g. AMBMC)) this should be False
            struct_registration.inputs.use_histogram_matching = [False, False]
            struct_registration.inputs.winsorize_lower_quantile = 0.005
            struct_registration.inputs.winsorize_upper_quantile = 0.98
            struct_registration.inputs.args = '--float'
            struct_registration.inputs.num_threads = 6

            struct_registration.inputs.moving_image = struct_mask_res.outputs.out_file
            struct_registration.inputs.output_warped_image = '{}/s_{}_ofM{}.nii.gz'.format(
                regdir, participant, i)
            struct_registration_res = struct_registration.run()

            #func
            func_n4 = ants.N4BiasFieldCorrection()
            func_n4.inputs.dimension = 3
            func_n4.inputs.input_image = func_image
            func_n4.inputs.bspline_fitting_distance = 100
            func_n4.inputs.shrink_factor = 2
            func_n4.inputs.n_iterations = [200, 200, 200, 200]
            func_n4.inputs.convergence_threshold = 1e-11
            func_n4.inputs.output_image = '{}/f_n4_{}_ofM{}.nii.gz'.format(
                regdir, participant, i)
            func_n4_res = func_n4.run()

            func_registration = ants.Registration()
            func_registration.inputs.fixed_image = n4_res.outputs.output_image
            func_registration.inputs.output_transform_prefix = "func_"
            func_registration.inputs.transforms = [f2s]
            func_registration.inputs.transform_parameters = [(0.1, )]
            func_registration.inputs.number_of_iterations = [[40, 20, 10]]
            func_registration.inputs.dimension = 3
            func_registration.inputs.write_composite_transform = True
            func_registration.inputs.collapse_output_transforms = True
            func_registration.inputs.initial_moving_transform_com = True
            func_registration.inputs.metric = ['MeanSquares']
            func_registration.inputs.metric_weight = [1]
            func_registration.inputs.radius_or_number_of_bins = [16]
            func_registration.inputs.sampling_strategy = ["Regular"]
            func_registration.inputs.sampling_percentage = [0.3]
            func_registration.inputs.convergence_threshold = [1.e-2]
            func_registration.inputs.convergence_window_size = [8]
            func_registration.inputs.smoothing_sigmas = [[4, 2,
                                                          1]]  # [1,0.5,0]
            func_registration.inputs.sigma_units = ['vox']
            func_registration.inputs.shrink_factors = [[3, 2, 1]]
            func_registration.inputs.use_estimate_learning_rate_once = [True]
            func_registration.inputs.use_histogram_matching = [False]
            func_registration.inputs.winsorize_lower_quantile = 0.005
            func_registration.inputs.winsorize_upper_quantile = 0.995
            func_registration.inputs.args = '--float'
            func_registration.inputs.num_threads = 6

            func_registration.inputs.moving_image = func_n4_res.outputs.output_image
            func_registration.inputs.output_warped_image = '{}/f_{}_ofM{}.nii.gz'.format(
                regdir, participant, i)
            func_registration_res = func_registration.run()

            warp = ants.ApplyTransforms()
            warp.inputs.reference_image = template
            warp.inputs.input_image_type = 3
            warp.inputs.interpolation = 'Linear'
            warp.inputs.invert_transform_flags = [False, False]
            warp.inputs.terminal_output = 'file'
            warp.inputs.output_image = '{}/{}_ofM{}.nii.gz'.format(
                regdir, participant, i)
            warp.num_threads = 6

            warp.inputs.input_image = func_image
            warp.inputs.transforms = [
                func_registration_res.outputs.composite_transform,
                struct_registration_res.outputs.composite_transform
            ]
            warp.run()
示例#33
0
def structural_to_functional_per_participant_test(
    subjects_sessions,
    template="~/GitHub/mriPipeline/templates/waxholm/new/WHS_SD_masked.nii.gz",
    f_file_format="~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_SE_EPI/f_bru2nii/",
    s_file_format="~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_T2_TurboRARE/s_bru2nii/",
    num_threads=3,
):

    template = os.path.expanduser(template)
    for subject_session in subjects_sessions:
        func_image_dir = os.path.expanduser(
            f_file_format.format(**subject_session))
        struct_image_dir = os.path.expanduser(
            s_file_format.format(**subject_session))
        try:
            for myfile in os.listdir(func_image_dir):
                if myfile.endswith((".nii.gz", ".nii")):
                    func_image = os.path.join(func_image_dir, myfile)
            for myfile in os.listdir(struct_image_dir):
                if myfile.endswith((".nii.gz", ".nii")):
                    struct_image = os.path.join(struct_image_dir, myfile)
        except FileNotFoundError:
            pass
        else:
            n4 = ants.N4BiasFieldCorrection()
            n4.inputs.dimension = 3
            n4.inputs.input_image = struct_image
            # correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
            n4.inputs.bspline_fitting_distance = 100
            n4.inputs.shrink_factor = 2
            n4.inputs.n_iterations = [200, 200, 200, 200]
            n4.inputs.convergence_threshold = 1e-11
            n4.inputs.output_image = '{}_{}_1_biasCorrection_forRegistration.nii.gz'.format(
                *subject_session.values())
            n4_res = n4.run()

            _n4 = ants.N4BiasFieldCorrection()
            _n4.inputs.dimension = 3
            _n4.inputs.input_image = struct_image
            # correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
            _n4.inputs.bspline_fitting_distance = 95
            _n4.inputs.shrink_factor = 2
            _n4.inputs.n_iterations = [500, 500, 500, 500]
            _n4.inputs.convergence_threshold = 1e-14
            _n4.inputs.output_image = '{}_{}_1_biasCorrection_forMasking.nii.gz'.format(
                *subject_session.values())
            _n4_res = _n4.run()

            #we do this on a separate bias-corrected image to remove hyperintensities which we have to create in order to prevent brain regions being caught by the negative threshold
            struct_cutoff = ImageMaths()
            struct_cutoff.inputs.op_string = "-thrP 20 -uthrp 98"
            struct_cutoff.inputs.in_file = _n4_res.outputs.output_image
            struct_cutoff_res = struct_cutoff.run()

            struct_BET = BET()
            struct_BET.inputs.mask = True
            struct_BET.inputs.frac = 0.3
            struct_BET.inputs.robust = True
            struct_BET.inputs.in_file = struct_cutoff_res.outputs.out_file
            struct_BET.inputs.out_file = '{}_{}_2_brainExtraction.nii.gz'.format(
                *subject_session.values())
            struct_BET_res = struct_BET.run()

            # we need/can not apply a fill, because the "holes" if any, will be at the rostral edge (touching it, and thus not counting as holes)
            struct_mask = ApplyMask()
            struct_mask.inputs.in_file = n4_res.outputs.output_image
            struct_mask.inputs.mask_file = struct_BET_res.outputs.mask_file
            struct_mask.inputs.out_file = '{}_{}_3_brainMasked.nii.gz'.format(
                *subject_session.values())
            struct_mask_res = struct_mask.run()

            struct_registration = ants.Registration()
            struct_registration.inputs.fixed_image = template
            struct_registration.inputs.output_transform_prefix = "output_"
            struct_registration.inputs.transforms = ['Affine', 'SyN']  ##
            struct_registration.inputs.transform_parameters = [(1.0, ),
                                                               (1.0, 3.0, 5.0)
                                                               ]  ##
            struct_registration.inputs.number_of_iterations = [[
                2000, 1000, 500
            ], [100, 100, 100]]  #
            struct_registration.inputs.dimension = 3
            struct_registration.inputs.write_composite_transform = True
            struct_registration.inputs.collapse_output_transforms = True
            struct_registration.inputs.initial_moving_transform_com = True
            # Tested on Affine transform: CC takes too long; Demons does not tilt, but moves the slices too far caudally; GC tilts too much on
            struct_registration.inputs.metric = ['MeanSquares', 'Mattes']
            struct_registration.inputs.metric_weight = [1, 1]
            struct_registration.inputs.radius_or_number_of_bins = [16, 32]  #
            struct_registration.inputs.sampling_strategy = ['Random', None]
            struct_registration.inputs.sampling_percentage = [0.3, 0.3]
            struct_registration.inputs.convergence_threshold = [1.e-11,
                                                                1.e-8]  #
            struct_registration.inputs.convergence_window_size = [20, 20]
            struct_registration.inputs.smoothing_sigmas = [[4, 2, 1],
                                                           [4, 2, 1]]
            struct_registration.inputs.sigma_units = ['vox', 'vox']
            struct_registration.inputs.shrink_factors = [[3, 2, 1], [3, 2, 1]]
            struct_registration.inputs.use_estimate_learning_rate_once = [
                True, True
            ]
            # if the fixed_image is not acquired similarly to the moving_image (e.g. RARE to histological (e.g. AMBMC)) this should be False
            struct_registration.inputs.use_histogram_matching = [False, False]
            struct_registration.inputs.winsorize_lower_quantile = 0.005
            struct_registration.inputs.winsorize_upper_quantile = 0.98
            struct_registration.inputs.args = '--float'
            struct_registration.inputs.num_threads = num_threads

            struct_registration.inputs.moving_image = struct_mask_res.outputs.out_file
            struct_registration.inputs.output_warped_image = '{}_{}_4_structuralRegistration.nii.gz'.format(
                *subject_session.values())
            struct_registration_res = struct_registration.run()

            warp = ants.ApplyTransforms()
            warp.inputs.reference_image = template
            warp.inputs.input_image_type = 3
            warp.inputs.interpolation = 'Linear'
            warp.inputs.invert_transform_flags = [False]
            warp.inputs.terminal_output = 'file'
            warp.inputs.output_image = '{}_{}_5_functionalWarp.nii.gz'.format(
                *subject_session.values())
            warp.num_threads = num_threads

            warp.inputs.input_image = func_image
            warp.inputs.transforms = struct_registration_res.outputs.composite_transform
            warp.run()
示例#34
0
def structural_to_functional_per_participant_test(subjects_sessions,
	template = "~/GitHub/mriPipeline/templates/waxholm/new/WHS_SD_masked.nii.gz",
	f_file_format = "~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_SE_EPI/f_bru2nii/",
	s_file_format = "~/GitHub/mripipeline/base/preprocessing/generic_work/_subject_session_{subject}.{session}/_scan_type_T2_TurboRARE/s_bru2nii/",
	num_threads = 3,
	):

	template = os.path.expanduser(template)
	for subject_session in subjects_sessions:
		func_image_dir = os.path.expanduser(f_file_format.format(**subject_session))
		struct_image_dir = os.path.expanduser(s_file_format.format(**subject_session))
		try:
			for myfile in os.listdir(func_image_dir):
				if myfile.endswith((".nii.gz", ".nii")):
					func_image = os.path.join(func_image_dir,myfile)
			for myfile in os.listdir(struct_image_dir):
				if myfile.endswith((".nii.gz", ".nii")):
					struct_image = os.path.join(struct_image_dir,myfile)
		except FileNotFoundError:
			pass
		else:
			n4 = ants.N4BiasFieldCorrection()
			n4.inputs.dimension = 3
			n4.inputs.input_image = struct_image
			# correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
			n4.inputs.bspline_fitting_distance = 100
			n4.inputs.shrink_factor = 2
			n4.inputs.n_iterations = [200,200,200,200]
			n4.inputs.convergence_threshold = 1e-11
			n4.inputs.output_image = '{}_{}_1_biasCorrection_forRegistration.nii.gz'.format(*subject_session.values())
			n4_res = n4.run()

			_n4 = ants.N4BiasFieldCorrection()
			_n4.inputs.dimension = 3
			_n4.inputs.input_image = struct_image
			# correction bias is introduced (along the z-axis) if the following value is set to under 85. This is likely contingent on resolution.
			_n4.inputs.bspline_fitting_distance = 95
			_n4.inputs.shrink_factor = 2
			_n4.inputs.n_iterations = [500,500,500,500]
			_n4.inputs.convergence_threshold = 1e-14
			_n4.inputs.output_image = '{}_{}_1_biasCorrection_forMasking.nii.gz'.format(*subject_session.values())
			_n4_res = _n4.run()

			#we do this on a separate bias-corrected image to remove hyperintensities which we have to create in order to prevent brain regions being caught by the negative threshold
			struct_cutoff = ImageMaths()
			struct_cutoff.inputs.op_string = "-thrP 20 -uthrp 98"
			struct_cutoff.inputs.in_file = _n4_res.outputs.output_image
			struct_cutoff_res = struct_cutoff.run()

			struct_BET = BET()
			struct_BET.inputs.mask = True
			struct_BET.inputs.frac = 0.3
			struct_BET.inputs.robust = True
			struct_BET.inputs.in_file = struct_cutoff_res.outputs.out_file
			struct_BET.inputs.out_file = '{}_{}_2_brainExtraction.nii.gz'.format(*subject_session.values())
			struct_BET_res = struct_BET.run()

			# we need/can not apply a fill, because the "holes" if any, will be at the rostral edge (touching it, and thus not counting as holes)
			struct_mask = ApplyMask()
			struct_mask.inputs.in_file = n4_res.outputs.output_image
			struct_mask.inputs.mask_file = struct_BET_res.outputs.mask_file
			struct_mask.inputs.out_file = '{}_{}_3_brainMasked.nii.gz'.format(*subject_session.values())
			struct_mask_res = struct_mask.run()

			struct_registration = ants.Registration()
			struct_registration.inputs.fixed_image = template
			struct_registration.inputs.output_transform_prefix = "output_"
			struct_registration.inputs.transforms = ['Affine', 'SyN'] ##
			struct_registration.inputs.transform_parameters = [(1.0,), (1.0, 3.0, 5.0)] ##
			struct_registration.inputs.number_of_iterations = [[2000, 1000, 500], [100, 100, 100]] #
			struct_registration.inputs.dimension = 3
			struct_registration.inputs.write_composite_transform = True
			struct_registration.inputs.collapse_output_transforms = True
			struct_registration.inputs.initial_moving_transform_com = True
			# Tested on Affine transform: CC takes too long; Demons does not tilt, but moves the slices too far caudally; GC tilts too much on
			struct_registration.inputs.metric = ['MeanSquares', 'Mattes']
			struct_registration.inputs.metric_weight = [1, 1]
			struct_registration.inputs.radius_or_number_of_bins = [16, 32] #
			struct_registration.inputs.sampling_strategy = ['Random', None]
			struct_registration.inputs.sampling_percentage = [0.3, 0.3]
			struct_registration.inputs.convergence_threshold = [1.e-11, 1.e-8] #
			struct_registration.inputs.convergence_window_size = [20, 20]
			struct_registration.inputs.smoothing_sigmas = [[4, 2, 1], [4, 2, 1]]
			struct_registration.inputs.sigma_units = ['vox', 'vox']
			struct_registration.inputs.shrink_factors = [[3, 2, 1],[3, 2, 1]]
			struct_registration.inputs.use_estimate_learning_rate_once = [True, True]
			# if the fixed_image is not acquired similarly to the moving_image (e.g. RARE to histological (e.g. AMBMC)) this should be False
			struct_registration.inputs.use_histogram_matching = [False, False]
			struct_registration.inputs.winsorize_lower_quantile = 0.005
			struct_registration.inputs.winsorize_upper_quantile = 0.98
			struct_registration.inputs.args = '--float'
			struct_registration.inputs.num_threads = num_threads

			struct_registration.inputs.moving_image = struct_mask_res.outputs.out_file
			struct_registration.inputs.output_warped_image = '{}_{}_4_structuralRegistration.nii.gz'.format(*subject_session.values())
			struct_registration_res = struct_registration.run()

			warp = ants.ApplyTransforms()
			warp.inputs.reference_image = template
			warp.inputs.input_image_type = 3
			warp.inputs.interpolation = 'Linear'
			warp.inputs.invert_transform_flags = [False]
			warp.inputs.terminal_output = 'file'
			warp.inputs.output_image = '{}_{}_5_functionalWarp.nii.gz'.format(*subject_session.values())
			warp.num_threads = num_threads

			warp.inputs.input_image = func_image
			warp.inputs.transforms = struct_registration_res.outputs.composite_transform
			warp.run()
示例#35
0
def main(paths, options_binary_string, ANAT, num_proc=7):

    json_path = paths[0]
    base_directory = paths[1]
    motion_correction_bet_directory = paths[2]
    parent_wf_directory = paths[3]
    # functional_connectivity_directory=paths[4]
    coreg_reg_directory = paths[5]
    atlas_resize_reg_directory = paths[6]
    subject_list = paths[7]
    datasink_name = paths[8]
    # fc_datasink_name=paths[9]
    atlasPath = paths[10]
    # brain_path=paths[11]
    # mask_path=paths[12]
    # atlas_path=paths[13]
    # tr_path=paths[14]
    # motion_params_path=paths[15]
    # func2std_mat_path=paths[16]
    # MNI3mm_path=paths[17]
    # demographics_file_path = paths[18]
    # phenotype_file_path = paths[19]
    data_directory = paths[20]

    number_of_subjects = len(subject_list)
    print("Working with ", number_of_subjects, " subjects.")

    # Create our own custom function - BIDSDataGrabber using a Function Interface.

    # In[858]:

    def get_nifti_filenames(subject_id, data_dir):
        #     Remember that all the necesary imports need to be INSIDE the function for the Function Interface to work!
        from bids.grabbids import BIDSLayout

        layout = BIDSLayout(data_dir)
        run = 1

        anat_file_path = [
            f.filename for f in layout.get(
                subject=subject_id, type='T1w', extensions=['nii', 'nii.gz'])
        ]
        func_file_path = [
            f.filename for f in layout.get(subject=subject_id,
                                           type='bold',
                                           run=run,
                                           extensions=['nii', 'nii.gz'])
        ]

        if len(anat_file_path) == 0:
            return None, func_file_path[0]  # No Anatomical files present
        return anat_file_path[0], func_file_path[0]

    BIDSDataGrabber = Node(Function(
        function=get_nifti_filenames,
        input_names=['subject_id', 'data_dir'],
        output_names=['anat_file_path', 'func_file_path']),
                           name='BIDSDataGrabber')
    # BIDSDataGrabber.iterables = [('subject_id',subject_list)]
    BIDSDataGrabber.inputs.data_dir = data_directory

    # ## Return TR

    def get_TR(in_file):
        from bids.grabbids import BIDSLayout

        data_directory = '/home1/varunk/data/ABIDE1/RawDataBIDs'
        layout = BIDSLayout(data_directory)
        metadata = layout.get_metadata(path=in_file)
        TR = metadata['RepetitionTime']
        return TR

    # ---------------- Added new Node to return TR and other slice timing correction params-------------------------------
    def _getMetadata(in_file):
        from bids.grabbids import BIDSLayout
        import logging

        logger = logging.getLogger(__name__)
        logger.setLevel(logging.DEBUG)

        # create a file handler
        handler = logging.FileHandler('progress.log')

        # add the handlers to the logger
        logger.addHandler(handler)

        interleaved = True
        index_dir = False
        data_directory = '/home1/varunk/data/ABIDE1/RawDataBIDs'
        layout = BIDSLayout(data_directory)
        metadata = layout.get_metadata(path=in_file)
        print(metadata)

        logger.info('Extracting Meta Data of file: %s', in_file)
        try:
            tr = metadata['RepetitionTime']
        except KeyError:
            print(
                'Key RepetitionTime not found in task-rest_bold.json so using a default of 2.0 '
            )
            tr = 2
            logger.error(
                'Key RepetitionTime not found in task-rest_bold.json for file %s so using a default of 2.0 ',
                in_file)

        try:
            slice_order = metadata['SliceAcquisitionOrder']
        except KeyError:
            print(
                'Key SliceAcquisitionOrder not found in task-rest_bold.json so using a default of interleaved ascending '
            )
            logger.error(
                'Key SliceAcquisitionOrder not found in task-rest_bold.json for file %s so using a default of interleaved ascending',
                in_file)
            return tr, index_dir, interleaved

        if slice_order.split(' ')[0] == 'Sequential':
            interleaved = False
        if slice_order.split(' ')[1] == 'Descending':
            index_dir = True

        return tr, index_dir, interleaved

    getMetadata = Node(Function(
        function=_getMetadata,
        input_names=['in_file'],
        output_names=['tr', 'index_dir', 'interleaved']),
                       name='getMetadata')

    # ### Skipping 4 starting scans
    # Extract ROI for skipping first 4 scans of the functional data
    # > **Arguments:**
    # t_min: (corresponds to time dimension) Denotes the starting time of the inclusion
    # t_size: Denotes the number of scans to include
    #
    # The logic behind skipping 4 initial scans is to take scans after the subject has stabalized in the scanner.

    # In[863]:

    # ExtractROI - skip dummy scans
    extract = Node(ExtractROI(t_min=4, t_size=-1),
                   output_type='NIFTI',
                   name="extract")

    # ### Slice time correction
    # Created a Node that does slice time correction
    # > **Arguments**:
    # index_dir=False -> Slices were taken bottom to top i.e. in ascending order
    # interleaved=True means odd slices were acquired first and then even slices [or vice versa(Not sure)]

    slicetimer = Node(SliceTimer(output_type='NIFTI'), name="slicetimer")

    # ### Motion Correction
    # Motion correction is done using fsl's mcflirt. It alligns all the volumes of a functional scan to each other

    # MCFLIRT - motion correction
    mcflirt = Node(MCFLIRT(mean_vol=True, save_plots=True,
                           output_type='NIFTI'),
                   name="mcflirt")

    #  Just a dummy node to transfer the output of Mcflirt to the next workflow. Needed if we didnt want to use the Mcflirt
    from_mcflirt = Node(IdentityInterface(fields=['in_file']),
                        name="from_mcflirt")

    # ### Skull striping
    # I used fsl's BET

    # In[868]:

    skullStrip = Node(BET(mask=False, frac=0.3, robust=True),
                      name='skullStrip')  #

    # *Note*: Do not include special characters in ```name``` field above coz then  wf.writegraph will cause issues

    # ## Resample
    # I needed to resample the anatomical file from 1mm to 3mm. Because registering a 1mm file was taking a huge amount of time.
    #

    # In[872]:

    # Resample - resample anatomy to 3x3x3 voxel resolution
    resample_mni = Node(
        Resample(
            voxel_size=(3, 3, 3),
            resample_mode='Cu',  # cubic interpolation
            outputtype='NIFTI'),
        name="resample_mni")

    resample_anat = Node(
        Resample(
            voxel_size=(3, 3, 3),
            resample_mode='Cu',  # cubic interpolation
            outputtype='NIFTI'),
        name="resample_anat")

    # In[873]:

    resample_atlas = Node(
        Resample(
            voxel_size=(3, 3, 3),
            resample_mode='NN',  # cubic interpolation
            outputtype='NIFTI'),
        name="resample_atlas")

    resample_atlas.inputs.in_file = atlasPath

    # # Matrix operations
    # ### For concatenating the transformation matrices

    concat_xform = Node(ConvertXFM(concat_xfm=True), name='concat_xform')

    # Node to calculate the inverse of func2std matrix
    inv_mat = Node(ConvertXFM(invert_xfm=True), name='inv_mat')

    # ## Extracting the mean brain

    meanfunc = Node(interface=ImageMaths(op_string='-Tmean', suffix='_mean'),
                    name='meanfunc')

    meanfuncmask = Node(interface=BET(mask=True, no_output=True, frac=0.3),
                        name='meanfuncmask')

    # ## Apply Mask

    # Does BET (masking) on the whole func scan [Not using this, creates bug for join node]
    maskfunc = Node(interface=ImageMaths(suffix='_bet', op_string='-mas'),
                    name='maskfunc')

    # Does BET (masking) on the mean func scan
    maskfunc4mean = Node(interface=ImageMaths(suffix='_bet', op_string='-mas'),
                         name='maskfunc4mean')

    # ## Datasink
    # I needed to define the structure of what files are saved and where.

    # Create DataSink object
    dataSink = Node(DataSink(), name='datasink')

    # Name of the output folder
    dataSink.inputs.base_directory = opj(base_directory, datasink_name)

    # Define substitution strings so that the data is similar to BIDS
    substitutions = [
        ('_subject_id_', 'sub-'), ('_resample_brain_flirt.nii_brain', ''),
        ('_roi_st_mcf_flirt.nii_brain_flirt', ''),
        ('task-rest_run-1_bold_roi_st_mcf.nii', 'motion_params'),
        ('T1w_resample_brain_flirt_sub-0050002_task-rest_run-1_bold_roi_st_mcf_mean_bet_flirt',
         'fun2std')
    ]

    # Feed the substitution strings to the DataSink node
    dataSink.inputs.substitutions = substitutions

    # ### Apply Mask to functional data
    # Mean file of the motion corrected functional scan is sent to
    # skullStrip to get just the brain and the mask_image.
    # Mask_image is just a binary file (containing 1 where brain is present and 0 where it isn't).
    # After getting the mask_image form skullStrip, apply that mask to aligned
    # functional image to extract its brain and remove the skull

    # In[889]:

    # Function
    # in_file: The file on which you want to apply mask
    # in_file2 = mask_file:  The mask you want to use. Make sure that mask_file has same size as in_file
    # out_file : Result of applying mask in in_file -> Gives the path of the output file

    def applyMask_func(in_file, in_file2):
        import numpy as np
        import nibabel as nib
        import os
        from os.path import join as opj

        # convert from unicode to string : u'/tmp/tmp8daO2Q/..' -> '/tmp/tmp8daO2Q/..' i.e. removes the prefix 'u'
        mask_file = in_file2

        brain_data = nib.load(in_file)
        mask_data = nib.load(mask_file)

        brain = brain_data.get_data().astype('float32')
        mask = mask_data.get_data()

        # applying mask by multiplying elementwise to the binary mask

        if len(brain.shape) == 3:  # Anat file
            brain = np.multiply(brain, mask)
        elif len(brain.shape) > 3:  # Functional File
            for t in range(brain.shape[-1]):
                brain[:, :, :, t] = np.multiply(brain[:, :, :, t], mask)
        else:
            pass

        # Saving the brain file

        path = os.getcwd()

        in_file_split_list = in_file.split('/')
        in_file_name = in_file_split_list[-1]

        out_file = in_file_name + '_brain.nii.gz'  # changing name
        brain_with_header = nib.Nifti1Image(brain,
                                            affine=brain_data.affine,
                                            header=brain_data.header)
        nib.save(brain_with_header, out_file)

        out_file = opj(path, out_file)
        out_file2 = in_file2

        return out_file, out_file2

    # #### Things learnt:
    # 1. I found out that whenever a node is being executed, it becomes the current directory and whatever file you create now, will be stored here.
    # 2. #from IPython.core.debugger import Tracer; Tracer()()    # Debugger doesnt work in nipype

    # Wrap the above function inside a Node

    # In[890]:

    applyMask = Node(Function(function=applyMask_func,
                              input_names=['in_file', 'in_file2'],
                              output_names=['out_file', 'out_file2']),
                     name='applyMask')

    # ### Some nodes needed for Co-registration and Normalization

    # Node for getting the xformation matrix
    func2anat_reg = Node(FLIRT(output_type='NIFTI'), name="func2anat_reg")

    # Node for applying xformation matrix to functional data
    func2std_xform = Node(FLIRT(output_type='NIFTI', apply_xfm=True),
                          name="func2std_xform")

    # Node for applying xformation matrix to functional data
    std2func_xform = Node(FLIRT(output_type='NIFTI',
                                apply_xfm=True,
                                interp='nearestneighbour'),
                          name="std2func_xform")

    # Node for Normalizing/Standardizing the anatomical and getting the xformation matrix
    anat2std_reg = Node(FLIRT(output_type='NIFTI'), name="anat2std_reg")

    # I wanted to use the MNI file as input to the workflow so I created an Identity
    # Node that reads the MNI file path and outputs the same MNI file path.
    # Then I connected this node to whereever it was needed.

    MNI152_2mm = Node(IdentityInterface(fields=['standard_file', 'mask_file']),
                      name="MNI152_2mm")
    # Set the mask_file and standard_file input in the Node. This setting sets the input mask_file permanently.
    MNI152_2mm.inputs.mask_file = os.path.expandvars(
        '$FSLDIR/data/standard/MNI152_T1_2mm_brain_mask.nii.gz')

    MNI152_2mm.inputs.standard_file = os.path.expandvars(
        '$FSLDIR/data/standard/MNI152_T1_2mm_brain.nii.gz')
    # MNI152_2mm.inputs.mask_file = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask.nii.gz'
    # MNI152_2mm.inputs.standard_file = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain.nii.gz'

    # ## Band Pass Filtering
    # Let's do a band pass filtering on the data using the code from https://neurostars.org/t/bandpass-filtering-different-outputs-from-fsl-and-nipype-custom-function/824/2

    ### AFNI

    bandpass = Node(afni.Bandpass(highpass=0.008,
                                  lowpass=0.08,
                                  despike=False,
                                  no_detrend=True,
                                  notrans=True,
                                  outputtype='NIFTI_GZ'),
                    name='bandpass')

    # ### Following is a Join Node that collects the preprocessed file paths and saves them in a file

    # In[902]:

    def save_file_list_function_in_brain(in_brain):
        import numpy as np
        import os
        from os.path import join as opj

        file_list = np.asarray(in_brain)
        print('######################## File List ######################: \n',
              file_list)

        np.save('brain_file_list', file_list)
        file_name = 'brain_file_list.npy'
        out_brain = opj(os.getcwd(), file_name)  # path
        return out_brain

    def save_file_list_function_in_mask(in_mask):
        import numpy as np
        import os
        from os.path import join as opj

        file_list2 = np.asarray(in_mask)
        print('######################## File List ######################: \n',
              file_list2)

        np.save('mask_file_list', file_list2)
        file_name2 = 'mask_file_list.npy'
        out_mask = opj(os.getcwd(), file_name2)  # path
        return out_mask

    def save_file_list_function_in_motion_params(in_motion_params):
        import numpy as np
        import os
        from os.path import join as opj

        file_list3 = np.asarray(in_motion_params)
        print('######################## File List ######################: \n',
              file_list3)

        np.save('motion_params_file_list', file_list3)
        file_name3 = 'motion_params_file_list.npy'
        out_motion_params = opj(os.getcwd(), file_name3)  # path
        return out_motion_params

    def save_file_list_function_in_motion_outliers(in_motion_outliers):
        import numpy as np
        import os
        from os.path import join as opj

        file_list4 = np.asarray(in_motion_outliers)
        print('######################## File List ######################: \n',
              file_list4)

        np.save('motion_outliers_file_list', file_list4)
        file_name4 = 'motion_outliers_file_list.npy'
        out_motion_outliers = opj(os.getcwd(), file_name4)  # path
        return out_motion_outliers

    def save_file_list_function_in_joint_xformation_matrix(
            in_joint_xformation_matrix):
        import numpy as np
        import os
        from os.path import join as opj

        file_list5 = np.asarray(in_joint_xformation_matrix)
        print('######################## File List ######################: \n',
              file_list5)

        np.save('joint_xformation_matrix_file_list', file_list5)
        file_name5 = 'joint_xformation_matrix_file_list.npy'
        out_joint_xformation_matrix = opj(os.getcwd(), file_name5)  # path
        return out_joint_xformation_matrix

    def save_file_list_function_in_tr(in_tr):
        import numpy as np
        import os
        from os.path import join as opj

        tr_list = np.asarray(in_tr)
        print('######################## TR List ######################: \n',
              tr_list)

        np.save('tr_list', tr_list)
        file_name6 = 'tr_list.npy'
        out_tr = opj(os.getcwd(), file_name6)  # path
        return out_tr

    def save_file_list_function_in_atlas(in_atlas):
        import numpy as np
        import os
        from os.path import join as opj

        file_list7 = np.asarray(in_atlas)
        print('######################## File List ######################: \n',
              file_list7)

        np.save('atlas_file_list', file_list7)
        file_name7 = 'atlas_file_list.npy'
        out_atlas = opj(os.getcwd(), file_name7)  # path
        return out_atlas

    save_file_list_in_brain = JoinNode(Function(
        function=save_file_list_function_in_brain,
        input_names=['in_brain'],
        output_names=['out_brain']),
                                       joinsource="infosource",
                                       joinfield=['in_brain'],
                                       name="save_file_list_in_brain")

    save_file_list_in_mask = JoinNode(Function(
        function=save_file_list_function_in_mask,
        input_names=['in_mask'],
        output_names=['out_mask']),
                                      joinsource="infosource",
                                      joinfield=['in_mask'],
                                      name="save_file_list_in_mask")

    save_file_list_in_motion_outliers = JoinNode(
        Function(function=save_file_list_function_in_motion_outliers,
                 input_names=['in_motion_outliers'],
                 output_names=['out_motion_outliers']),
        joinsource="infosource",
        joinfield=['in_motion_outliers'],
        name="save_file_list_in_motion_outliers")

    save_file_list_in_motion_params = JoinNode(
        Function(function=save_file_list_function_in_motion_params,
                 input_names=['in_motion_params'],
                 output_names=['out_motion_params']),
        joinsource="infosource",
        joinfield=['in_motion_params'],
        name="save_file_list_in_motion_params")

    save_file_list_in_joint_xformation_matrix = JoinNode(
        Function(function=save_file_list_function_in_joint_xformation_matrix,
                 input_names=['in_joint_xformation_matrix'],
                 output_names=['out_joint_xformation_matrix']),
        joinsource="infosource",
        joinfield=['in_joint_xformation_matrix'],
        name="save_file_list_in_joint_xformation_matrix")

    save_file_list_in_tr = JoinNode(Function(
        function=save_file_list_function_in_tr,
        input_names=['in_tr'],
        output_names=['out_tr']),
                                    joinsource="infosource",
                                    joinfield=['in_tr'],
                                    name="save_file_list_in_tr")

    save_file_list_in_atlas = JoinNode(Function(
        function=save_file_list_function_in_atlas,
        input_names=['in_atlas'],
        output_names=['out_atlas']),
                                       joinsource="infosource",
                                       joinfield=['in_atlas'],
                                       name="save_file_list_in_atlas")

    # save_file_list = JoinNode(Function(function=save_file_list_function, input_names=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix', 'in_tr', 'in_atlas'],
    #                output_names=['out_brain','out_mask','out_motion_params','out_motion_outliers','out_joint_xformation_matrix','out_tr', 'out_atlas']),
    #                joinsource="infosource",
    #                joinfield=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix','in_tr', 'in_atlas'],
    #                name="save_file_list")

    # def save_file_list_function(in_brain, in_mask, in_motion_params, in_motion_outliers, in_joint_xformation_matrix, in_tr, in_atlas):
    #     # Imports
    #     import numpy as np
    #     import os
    #     from os.path import join as opj
    #
    #
    #     file_list = np.asarray(in_brain)
    #     print('######################## File List ######################: \n',file_list)
    #
    #     np.save('brain_file_list',file_list)
    #     file_name = 'brain_file_list.npy'
    #     out_brain = opj(os.getcwd(),file_name) # path
    #
    #
    #     file_list2 = np.asarray(in_mask)
    #     print('######################## File List ######################: \n',file_list2)
    #
    #     np.save('mask_file_list',file_list2)
    #     file_name2 = 'mask_file_list.npy'
    #     out_mask = opj(os.getcwd(),file_name2) # path
    #
    #
    #     file_list3 = np.asarray(in_motion_params)
    #     print('######################## File List ######################: \n',file_list3)
    #
    #     np.save('motion_params_file_list',file_list3)
    #     file_name3 = 'motion_params_file_list.npy'
    #     out_motion_params = opj(os.getcwd(),file_name3) # path
    #
    #
    #     file_list4 = np.asarray(in_motion_outliers)
    #     print('######################## File List ######################: \n',file_list4)
    #
    #     np.save('motion_outliers_file_list',file_list4)
    #     file_name4 = 'motion_outliers_file_list.npy'
    #     out_motion_outliers = opj(os.getcwd(),file_name4) # path
    #
    #
    #     file_list5 = np.asarray(in_joint_xformation_matrix)
    #     print('######################## File List ######################: \n',file_list5)
    #
    #     np.save('joint_xformation_matrix_file_list',file_list5)
    #     file_name5 = 'joint_xformation_matrix_file_list.npy'
    #     out_joint_xformation_matrix = opj(os.getcwd(),file_name5) # path
    #
    #     tr_list = np.asarray(in_tr)
    #     print('######################## TR List ######################: \n',tr_list)
    #
    #     np.save('tr_list',tr_list)
    #     file_name6 = 'tr_list.npy'
    #     out_tr = opj(os.getcwd(),file_name6) # path
    #
    #
    #     file_list7 = np.asarray(in_atlas)
    #     print('######################## File List ######################: \n',file_list7)
    #
    #     np.save('atlas_file_list',file_list7)
    #     file_name7 = 'atlas_file_list.npy'
    #     out_atlas = opj(os.getcwd(),file_name7) # path
    #
    #
    #
    #
    #     return out_brain, out_mask, out_motion_params, out_motion_outliers, out_joint_xformation_matrix, out_tr , out_atlas
    #
    #
    #
    # save_file_list = JoinNode(Function(function=save_file_list_function, input_names=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix', 'in_tr', 'in_atlas'],
    #                  output_names=['out_brain','out_mask','out_motion_params','out_motion_outliers','out_joint_xformation_matrix','out_tr', 'out_atlas']),
    #                  joinsource="infosource",
    #                  joinfield=['in_brain', 'in_mask', 'in_motion_params','in_motion_outliers','in_joint_xformation_matrix','in_tr', 'in_atlas'],
    #                  name="save_file_list")

    # ### Motion outliers

    motionOutliers = Node(MotionOutliers(no_motion_correction=False,
                                         metric='fd',
                                         out_metric_plot='fd_plot.png',
                                         out_metric_values='fd_raw.txt'),
                          name='motionOutliers')

    # ## Workflow for atlas registration  from std to functional

    wf_atlas_resize_reg = Workflow(name=atlas_resize_reg_directory)

    wf_atlas_resize_reg.connect([

        # Apply the inverse matrix to the 3mm Atlas to transform it to func space
        (maskfunc4mean, std2func_xform, [(('out_file', 'reference'))]),
        (resample_atlas, std2func_xform, [('out_file', 'in_file')]),

        # Now, applying the inverse matrix
        (inv_mat, std2func_xform, [('out_file', 'in_matrix_file')]
         ),  # output: Atlas in func space
        (std2func_xform, save_file_list_in_atlas, [('out_file', 'in_atlas')]),

        # ---------------------------Save the required files --------------------------------------------
        (save_file_list_in_motion_params, dataSink,
         [('out_motion_params', 'motion_params_paths.@out_motion_params')]),
        (save_file_list_in_motion_outliers, dataSink,
         [('out_motion_outliers', 'motion_outliers_paths.@out_motion_outliers')
          ]),
        (save_file_list_in_brain, dataSink,
         [('out_brain', 'preprocessed_brain_paths.@out_brain')]),
        (save_file_list_in_mask, dataSink,
         [('out_mask', 'preprocessed_mask_paths.@out_mask')]),
        (save_file_list_in_joint_xformation_matrix, dataSink,
         [('out_joint_xformation_matrix',
           'joint_xformation_matrix_paths.@out_joint_xformation_matrix')]),
        (save_file_list_in_tr, dataSink, [('out_tr', 'tr_paths.@out_tr')]),
        (save_file_list_in_atlas, dataSink, [('out_atlas',
                                              'atlas_paths.@out_atlas')])
    ])

    # In[909]:

    wf_coreg_reg = Workflow(name=coreg_reg_directory)
    # wf_coreg_reg.base_dir = base_directory
    # Dir where all the outputs will be stored(inside coregistrationPipeline folder).

    if ANAT == 1:
        wf_coreg_reg.connect(BIDSDataGrabber, 'anat_file_path', skullStrip,
                             'in_file')  # Resampled the anat file to 3mm

        wf_coreg_reg.connect(skullStrip, 'out_file', resample_anat, 'in_file')

        wf_coreg_reg.connect(
            resample_anat, 'out_file', func2anat_reg, 'reference'
        )  # Make the resampled file as reference in func2anat_reg

        # Sec 1. The above 3 steps registers the mean image to resampled anat image and
        # calculates the xformation matrix .. I hope the xformation matrix will be saved

        wf_coreg_reg.connect(MNI152_2mm, 'standard_file', resample_mni,
                             'in_file')

        wf_coreg_reg.connect(resample_mni, 'out_file', anat2std_reg,
                             'reference')

        wf_coreg_reg.connect(resample_anat, 'out_file', anat2std_reg,
                             'in_file')

        # Calculates the Xformationmatrix from anat3mm to MNI 3mm

        # We can get those matrices by refering to func2anat_reg.outputs.out_matrix_file and similarly for anat2std_reg

        wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file', concat_xform,
                             'in_file')

        wf_coreg_reg.connect(anat2std_reg, 'out_matrix_file', concat_xform,
                             'in_file2')

        wf_coreg_reg.connect(concat_xform, 'out_file', dataSink,
                             'tranformation_matrix_fun2std.@out_file')

        wf_coreg_reg.connect(concat_xform, 'out_file',
                             save_file_list_in_joint_xformation_matrix,
                             'in_joint_xformation_matrix')

        # Now inverse the func2std MAT to std2func
        wf_coreg_reg.connect(concat_xform, 'out_file', wf_atlas_resize_reg,
                             'inv_mat.in_file')
# ------------------------------------------------------------------------------------------------------------------------------

# Registration of Functional to MNI 3mm space w/o using anatomical
    if ANAT == 0:
        print('Not using Anatomical high resoulution files')
        wf_coreg_reg.connect(MNI152_2mm, 'standard_file', resample_mni,
                             'in_file')
        wf_coreg_reg.connect(
            resample_mni, 'out_file', func2anat_reg, 'reference'
        )  # Make the resampled file as reference in func2anat_reg

        wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file', dataSink,
                             'tranformation_matrix_fun2std.@out_file')

        wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file',
                             save_file_list_in_joint_xformation_matrix,
                             'in_joint_xformation_matrix')

        # Now inverse the func2std MAT to std2func
        wf_coreg_reg.connect(func2anat_reg, 'out_matrix_file',
                             wf_atlas_resize_reg, 'inv_mat.in_file')

    # ## Co-Registration, Normalization and Bandpass Workflow
    # 1. Co-registration means alligning the func to anat
    # 2. Normalization means aligning func/anat to standard
    # 3. Applied band pass filtering in range - highpass=0.008, lowpass=0.08

    # In[910]:

    wf_motion_correction_bet = Workflow(name=motion_correction_bet_directory)
    # wf_motion_correction_bet.base_dir = base_directory

    wf_motion_correction_bet.connect([
        (from_mcflirt, meanfunc, [('in_file', 'in_file')]),
        (meanfunc, meanfuncmask, [('out_file', 'in_file')]),
        (from_mcflirt, applyMask, [('in_file', 'in_file')]),  # 1
        (meanfuncmask, applyMask, [
            ('mask_file', 'in_file2')
        ]),  # 2 output: 1&2,  BET on coregistered fmri scan
        (meanfunc, maskfunc4mean, [('out_file', 'in_file')]),  # 3
        (meanfuncmask, maskfunc4mean,
         [('mask_file', 'in_file2')]),  # 4 output: 3&4, BET on mean func scan
        (applyMask, save_file_list_in_brain, [('out_file', 'in_brain')]),
        (applyMask, save_file_list_in_mask, [('out_file2', 'in_mask')]),
        (maskfunc4mean, wf_coreg_reg, [('out_file', 'func2anat_reg.in_file')])
    ])

    infosource = Node(IdentityInterface(fields=['subject_id']),
                      name="infosource")

    infosource.iterables = [('subject_id', subject_list)]

    # Create the workflow

    wf = Workflow(name=parent_wf_directory)
    # base_dir = opj(s,'result')
    wf.base_dir = base_directory  # Dir where all the outputs will be stored(inside BETFlow folder).

    # wf.connect([      (infosource, BIDSDataGrabber, [('subject_id','subject_id')]),
    #                   (BIDSDataGrabber, extract, [('func_file_path','in_file')]),
    #
    #                   (BIDSDataGrabber,getMetadata, [('func_file_path','in_file')]),
    #
    #                   (getMetadata,slicetimer, [('tr','time_repetition')]),
    #
    #
    #                   (getMetadata,slicetimer, [('index_dir','index_dir')]),
    #
    #                   (getMetadata,slicetimer, [('interleaved','interleaved')]),
    #
    #                   (getMetadata,save_file_list_in_tr, [('tr','in_tr')]),
    #
    #                   (extract,slicetimer,[('roi_file','in_file')]),
    #
    #                   (slicetimer, mcflirt,[('slice_time_corrected_file','in_file')])
    #                   (mcflirt,dataSink,[('par_file','motion_params.@par_file')]), # saves the motion parameters calculated before
    #
    #                   (mcflirt,save_file_list_in_motion_params,[('par_file','in_motion_params')]),
    #
    #                   (mcflirt,wf_motion_correction_bet,[('out_file','from_mcflirt.in_file')])
    #            ])
    # # Run it in parallel
    # wf.run('MultiProc', plugin_args={'n_procs': num_proc})
    #
    #
    #
    # # Visualize the detailed graph
    # # from IPython.display import Image
    # wf.write_graph(graph2use='flat', format='png', simple_form=True)

    # Options:
    # discard 4 Volumes (extract), slicetimer, mcflirt
    print('Preprocessing Options:')
    print('Skipping 4 dummy volumes - ', options_binary_string[0])
    print('Slicetiming correction - ', options_binary_string[1])
    print('Finding Motion Outliers - ', options_binary_string[2])
    print('Doing Motion Correction - ', options_binary_string[3])

    # ANAT = 0
    nodes = [extract, slicetimer, motionOutliers, mcflirt]
    wf.connect(infosource, 'subject_id', BIDSDataGrabber, 'subject_id')
    wf.connect(BIDSDataGrabber, 'func_file_path', getMetadata, 'in_file')
    wf.connect(getMetadata, 'tr', save_file_list_in_tr, 'in_tr')

    old_node = BIDSDataGrabber
    old_node_output = 'func_file_path'

    for idx, include in enumerate(options_binary_string):

        if old_node == extract:
            old_node_output = 'roi_file'
        elif old_node == slicetimer:
            old_node_output = 'slice_time_corrected_file'
        # elif old_node == mcflirt:

        # old_node_output = 'out_file'

        if int(include):
            new_node = nodes[idx]

            if new_node == slicetimer:
                wf.connect(getMetadata, 'tr', slicetimer, 'time_repetition')
                wf.connect(getMetadata, 'index_dir', slicetimer, 'index_dir')
                wf.connect(getMetadata, 'interleaved', slicetimer,
                           'interleaved')
                new_node_input = 'in_file'
            elif new_node == extract:
                new_node_input = 'in_file'
            elif new_node == mcflirt:
                new_node_input = 'in_file'
                wf.connect(mcflirt, 'par_file', dataSink,
                           'motion_params.@par_file'
                           )  # saves the motion parameters calculated before

                wf.connect(mcflirt, 'par_file',
                           save_file_list_in_motion_params, 'in_motion_params')

                wf.connect(mcflirt, 'out_file', wf_motion_correction_bet,
                           'from_mcflirt.in_file')

            elif new_node == motionOutliers:

                wf.connect(meanfuncmask, 'mask_file', motionOutliers, 'mask')

                wf.connect(motionOutliers, 'out_file', dataSink,
                           'motionOutliers.@out_file')

                wf.connect(motionOutliers, 'out_metric_plot', dataSink,
                           'motionOutliers.@out_metric_plot')

                wf.connect(motionOutliers, 'out_metric_values', dataSink,
                           'motionOutliers.@out_metric_values')

                wf.connect(motionOutliers, 'out_file',
                           save_file_list_in_motion_outliers,
                           'in_motion_outliers')

                new_node_input = 'in_file'

                wf.connect(old_node, old_node_output, new_node, new_node_input)

                continue

            wf.connect(old_node, old_node_output, new_node, new_node_input)

            old_node = new_node

        else:
            if idx == 3:
                # new_node = from_mcflirt
                # new_node_input = 'from_mcflirt.in_file'

                wf.connect(old_node, old_node_output, wf_motion_correction_bet,
                           'from_mcflirt.in_file')

                # old_node = new_node

    TEMP_DIR_FOR_STORAGE = opj(base_directory, 'crash_files')
    wf.config = {"execution": {"crashdump_dir": TEMP_DIR_FOR_STORAGE}}

    # Visualize the detailed graph
    # from IPython.display import Image

    wf.write_graph(graph2use='flat', format='png', simple_form=True)

    # Run it in parallel
    wf.run('MultiProc', plugin_args={'n_procs': num_proc})
示例#36
0
def functional_per_participant_test():
	for i in ["","_aF","_cF1","_cF2","_pF"]:
		template = "~/ni_data/templates/ds_QBI_chr.nii.gz"
		participant = "4008"
		image_dir = "~/ni_data/ofM.dr/preprocessing/generic_work/_subject_session_{}.ofM{}/_scan_type_7_EPI_CBV/temporal_mean/".format(participant,i)
		try:
			for myfile in os.listdir(image_dir):
				if myfile.endswith(".nii.gz"):
					mimage = os.path.join(image_dir,myfile)
		except FileNotFoundError:
			pass
		else:
			n4 = ants.N4BiasFieldCorrection()
			n4.inputs.dimension = 3
			n4.inputs.input_image = mimage
			n4.inputs.bspline_fitting_distance = 100
			n4.inputs.shrink_factor = 2
			n4.inputs.n_iterations = [200,200,200,200]
			n4.inputs.convergence_threshold = 1e-11
			n4.inputs.output_image = 'n4_{}_ofM{}.nii.gz'.format(participant,i)
			n4_res = n4.run()

			functional_cutoff = ImageMaths()
			functional_cutoff.inputs.op_string = "-thrP 30"
			functional_cutoff.inputs.in_file = n4_res.outputs.output_image
			functional_cutoff_res = functional_cutoff.run()

			functional_BET = BET()
			functional_BET.inputs.mask = True
			functional_BET.inputs.frac = 0.5
			functional_BET.inputs.in_file = functional_cutoff_res.outputs.out_file
			functional_BET_res = functional_BET.run()

			registration = ants.Registration()
			registration.inputs.fixed_image = template
			registration.inputs.output_transform_prefix = "output_"
			registration.inputs.transforms = ['Affine', 'SyN']
			registration.inputs.transform_parameters = [(0.1,), (3.0, 3.0, 5.0)]
			registration.inputs.number_of_iterations = [[10000, 10000, 10000], [100, 100, 100]]
			registration.inputs.dimension = 3
			registration.inputs.write_composite_transform = True
			registration.inputs.collapse_output_transforms = True
			registration.inputs.initial_moving_transform_com = True
			registration.inputs.metric = ['Mattes'] * 2 + [['Mattes', 'CC']]
			registration.inputs.metric_weight = [1] * 2 + [[0.5, 0.5]]
			registration.inputs.radius_or_number_of_bins = [32] * 2 + [[32, 4]]
			registration.inputs.sampling_strategy = ['Regular'] * 2 + [[None, None]]
			registration.inputs.sampling_percentage = [0.3] * 2 + [[None, None]]
			registration.inputs.convergence_threshold = [1.e-8] * 2 + [-0.01]
			registration.inputs.convergence_window_size = [20] * 2 + [5]
			registration.inputs.smoothing_sigmas = [[4, 2, 1]] * 2 + [[1, 0.5, 0]]
			registration.inputs.sigma_units = ['vox'] * 3
			registration.inputs.shrink_factors = [[3, 2, 1]]*2 + [[4, 2, 1]]
			registration.inputs.use_estimate_learning_rate_once = [True] * 3
			registration.inputs.use_histogram_matching = [False] * 2 + [True]
			registration.inputs.winsorize_lower_quantile = 0.005
			registration.inputs.winsorize_upper_quantile = 0.995
			registration.inputs.args = '--float'
			registration.inputs.num_threads = 4
			registration.plugin_args = {'qsub_args': '-pe orte 4', 'sbatch_args': '--mem=6G -c 4'}

			registration.inputs.moving_image = functional_BET_res.outputs.out_file
			registration.inputs.output_warped_image = '{}_ofM{}.nii.gz'.format(participant,i)
			res = registration.run()