def make_neuromet1_workflow(self):

        # Infosource: Iterate through subject names
        infosource = Node(interface=IdentityInterface(fields=['subject_id']),
                          name="infosource")
        infosource.iterables = ('subject_id', self.subject_list)

        # unidensource, return for every subject uni and den
        unidensource = Node(interface=IdentityInterface(fields=['uniden']),
                            name="unidensource")
        unidensource.iterables = ('uniden', ['UNI', 'DEN'])

        info = dict(t1=[['subject_id', 'subject_id', 'uniden']])

        datasource = Node(interface=DataGrabber(
            infields=['subject_id', 'uniden'], outfields=['t1']),
                          name='datasource')
        datasource.inputs.base_directory = self.w_dir
        datasource.inputs.template = '{prefix}%s/{prefix}%s.%s_mp2rage_orig.nii.gz'.format(
            prefix=self.subject_prefix)
        datasource.inputs.template_args = info
        datasource.inputs.sort_filelist = False

        sink = self.make_sink()

        segment = self.make_segment()

        mask = self.make_mask()

        neuromet = Workflow(name=self.subject_prefix, base_dir=self.temp_dir)
        neuromet.connect(infosource, 'subject_id', datasource, 'subject_id')
        neuromet.connect(unidensource, 'uniden', datasource, 'uniden')
        neuromet.connect(datasource, 't1', segment, 'ro.in_file')

        # neuromet.connect()
        neuromet.connect(segment, 'spm_tissues_split.gm', mask,
                         'sum_tissues1.in_file')
        neuromet.connect(segment, 'spm_tissues_split.wm', mask,
                         'sum_tissues1.operand_files')
        neuromet.connect(segment, 'spm_tissues_split.csf', mask,
                         'sum_tissues2.operand_files')
        neuromet.connect(segment, 'spm_tissues_split.gm', sink, '@gm')
        neuromet.connect(segment, 'spm_tissues_split.wm', sink, '@wm')
        neuromet.connect(segment, 'spm_tissues_split.csf', sink, '@csf')
        neuromet.connect(segment, 'seg.bias_corrected_images', sink,
                         '@biascorr')

        # neuromet.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', sink, '@img')
        neuromet.connect(mask, 'gen_mask.out_file', sink, '@mask')
        neuromet.connect(segment, 'ro.out_file', sink, '@ro')

        return neuromet
Пример #2
0
    def create(self):  #, **kwargs):
        """ Create the nodes and connections for the workflow """
        # Preamble
        csvReader = CSVReader()
        csvReader.inputs.in_file = self.csv_file.default_value
        csvReader.inputs.header = self.hasHeader.default_value
        csvOut = csvReader.run()

        print("=" * 80)
        print(csvOut.outputs.__dict__)
        print("=" * 80)

        iters = {}
        label = list(csvOut.outputs.__dict__.keys())[0]
        result = eval("csvOut.outputs.{0}".format(label))
        iters['tests'], iters['trains'] = subsample_crossValidationSet(
            result, self.sample_size.default_value)
        # Main event
        out_fields = ['T1', 'T2', 'Label', 'trainindex', 'testindex']
        inputsND = Node(interface=IdentityInterface(fields=out_fields),
                        run_without_submitting=True,
                        name='inputs')
        inputsND.iterables = [('trainindex', iters['trains']),
                              ('testindex', iters['tests'])]
        if not self.hasHeader.default_value:
            inputsND.inputs.T1 = csvOut.outputs.column_0
            inputsND.inputs.Label = csvOut.outputs.column_1
            inputsND.inputs.T2 = csvOut.outputs.column_2
        else:
            inputsND.inputs.T1 = csvOut.outputs.__dict__['t1']
            inputsND.inputs.Label = csvOut.outputs.__dict__['label']
            inputsND.inputs.T2 = csvOut.outputs.__dict__['t2']
            pass  #TODO
        metaflow = Workflow(name='metaflow')
        metaflow.config['execution'] = {
            'plugin': 'Linear',
            'stop_on_first_crash': 'false',
            'stop_on_first_rerun':
            'false',  # This stops at first attempt to rerun, before running, and before deleting previous results.
            'hash_method': 'timestamp',
            'single_thread_matlab':
            'true',  # Multi-core 2011a  multi-core for matrix multiplication.
            'remove_unnecessary_outputs': 'true',
            'use_relative_paths':
            'false',  # relative paths should be on, require hash update when changed.
            'remove_node_directories': 'false',  # Experimental
            'local_hash_check': 'false'
        }

        metaflow.add_nodes([inputsND])
        """import pdb; pdb.set_trace()"""
        fusionflow = FusionLabelWorkflow()
        self.connect([
            (metaflow, fusionflow, [('inputs.trainindex', 'trainT1s.index'),
                                    ('inputs.T1', 'trainT1s.inlist')]),
            (metaflow, fusionflow, [('inputs.trainindex', 'trainLabels.index'),
                                    ('inputs.Label', 'trainLabels.inlist')]),
            (metaflow, fusionflow, [('inputs.testindex', 'testT1s.index'),
                                    ('inputs.T1', 'testT1s.inlist')])
        ])
Пример #3
0
def make_workflow():

    flairs = [os.path.abspath(i) for i in glob.glob(args.flair)]
    weights = [os.path.abspath(i) for i in glob.glob(args.weights)]
    weights_source = Node(interface=IdentityInterface(fields=['weights']),
                          name='weights_source')
    weights_source.inputs.weights = weights

    data_source = Node(IdentityInterface(fields=['flairs']),
                       name='data_source')
    data_source.iterables = ('flairs', flairs)

    sink = Node(interface=DataSink(), name='sink')
    sink.inputs.base_directory = wmh_dir
    sink.inputs.substitutions = [
        ('_flairs_', ''),
        ('_FLAIR.nii.gz/', '/'),
    ]
    sink.inputs.regexp_substitutions = [
        ('\.\..*\.\.', ''),
    ]

    test_wf = ibbmTum_wf.get_test_wf(row_st=192, cols_st=192, thres_mask=10)

    wmh = Workflow(name='wmh', base_dir=wf_temp)

    wmh.connect(weights_source, 'weights', test_wf, 'inputspec.weights')
    wmh.connect(data_source, 'flairs', test_wf, 'inputspec.flair')
    wmh.connect(test_wf, 'outputspec.wmh_mask', sink, '@pred')

    return wmh
Пример #4
0
        def test_nipype_srtm_zhou2003_roi(self):
            from temporalimage import Quantity
            from temporalimage.t4d import _csvwrite_frameTiming
            import pandas as pd
            from .generate_test_data import generate_fakeTAC_SRTM

            self.t, self.dt, self.TAC, self.refTAC = generate_fakeTAC_SRTM(BP=0.5, R1=0.7)

            frameStart = self.t - self.dt/2
            frameEnd = self.t + self.dt/2
            csvfilename = os.path.join(self.tmpdirname,'srtm_roi_timing.csv')
            _csvwrite_frameTiming(frameStart, frameEnd, csvfilename, time_unit='min')

            roiTACcsvfile = os.path.join(self.tmpdirname,'roi_tacs.csv')
            roiTACs = pd.DataFrame({'target': self.TAC,
                                    'ref': self.refTAC})
            roiTACs.T.to_csv(roiTACcsvfile, index_label='ROI')

            infosource = Node(IdentityInterface(fields=['in_file']),
                              name="infosource")
            infosource.iterables = ('in_file', [roiTACcsvfile])

            km = Node(KineticModelROI(model='SRTM_Zhou2003',
                                      #roiTACcsvFile=roiTACcsvfile,
                                      frameTimingFile=csvfilename,
                                      refRegion='ref',
                                      startActivity=self.startActivity,
                                      weights=self.weights), name="km")

            km_workflow = Workflow(name="km_workflow", base_dir=self.tmpdirname)
            km_workflow.connect([
                (infosource, km, [('in_file', 'roiTACcsvFile')])
            ])
            km_workflow.run()
Пример #5
0
def create_workflow_allin_slices(name='motion_correction', iterfield=['in_file']):
    workflow = Workflow(name=name)
    inputs = Node(IdentityInterface(fields=[
        'subject_id',
        'session_id',

        'ref_func', 
        'ref_func_weights',

        'funcs',
        'funcs_masks',

        'mc_method',
    ]), name='in')
    inputs.iterables = [
        ('mc_method', ['afni:3dAllinSlices'])
    ]

    mc = MapNode(
        AFNIAllinSlices(),
        iterfield=iterfield,  
        name='mc')
    workflow.connect(
        [(inputs, mc,
          [('funcs', 'in_file'),
           ('ref_func_weights', 'in_weight_file'),
           ('ref_func', 'ref_file'),
           ])])
    return workflow
    def make_infosource(self):

        # Infosource: Iterate through subject names
        infosource = Node(interface=IdentityInterface(fields=['subject_id']),
                          name="infosource")

        infosource.iterables = ('subject_id', self.subject_list)
        return infosource
Пример #7
0
    def create(self):  # , **kwargs):
        """ Create the nodes and connections for the workflow """
        # Preamble
        csvReader = CSVReader()
        csvReader.inputs.in_file = self.csv_file.default_value
        csvReader.inputs.header = self.hasHeader.default_value
        csvOut = csvReader.run()

        print(("=" * 80))
        print((csvOut.outputs.__dict__))
        print(("=" * 80))

        iters = OrderedDict()
        label = list(csvOut.outputs.__dict__.keys())[0]
        result = eval("csvOut.outputs.{0}".format(label))
        iters['tests'], iters['trains'] = subsample_crossValidationSet(result, self.sample_size.default_value)
        # Main event
        out_fields = ['T1', 'T2', 'Label', 'trainindex', 'testindex']
        inputsND = Node(interface=IdentityInterface(fields=out_fields),
                        run_without_submitting=True, name='inputs')
        inputsND.iterables = [('trainindex', iters['trains']),
                              ('testindex', iters['tests'])]
        if not self.hasHeader.default_value:
            inputsND.inputs.T1 = csvOut.outputs.column_0
            inputsND.inputs.Label = csvOut.outputs.column_1
            inputsND.inputs.T2 = csvOut.outputs.column_2
        else:
            inputsND.inputs.T1 = csvOut.outputs.__dict__['t1']
            inputsND.inputs.Label = csvOut.outputs.__dict__['label']
            inputsND.inputs.T2 = csvOut.outputs.__dict__['t2']
            pass  # TODO
        metaflow = Workflow(name='metaflow')
        metaflow.config['execution'] = {
            'plugin': 'Linear',
            'stop_on_first_crash': 'false',
            'stop_on_first_rerun': 'false',
        # This stops at first attempt to rerun, before running, and before deleting previous results.
            'hash_method': 'timestamp',
            'single_thread_matlab': 'true',  # Multi-core 2011a  multi-core for matrix multiplication.
            'remove_unnecessary_outputs': 'true',
            'use_relative_paths': 'false',  # relative paths should be on, require hash update when changed.
            'remove_node_directories': 'false',  # Experimental
            'local_hash_check': 'false'
        }

        metaflow.add_nodes([inputsND])
        """import pdb; pdb.set_trace()"""
        fusionflow = FusionLabelWorkflow()
        self.connect(
            [(metaflow, fusionflow, [('inputs.trainindex', 'trainT1s.index'), ('inputs.T1', 'trainT1s.inlist')]),
             (metaflow, fusionflow,
              [('inputs.trainindex', 'trainLabels.index'), ('inputs.Label', 'trainLabels.inlist')]),
             (metaflow, fusionflow, [('inputs.testindex', 'testT1s.index'), ('inputs.T1', 'testT1s.inlist')])
             ])
Пример #8
0
def create_conversion(name, subject, scans, working_dir, out_dir, folder,
                      xnat_server, xnat_user, xnat_pass, project_id, exp_id):

    convert = Workflow(name=name)
    convert.base_dir = working_dir
    convert.config['execution'][
        'crashdump_dir'] = convert.base_dir + "/crash_files"

    # infosource to iterate over scans
    scan_infosource = Node(
        util.IdentityInterface(fields=['scan_key', 'scan_val']),
        name='scan_infosource')
    scan_infosource.iterables = [('scan_key', scans.keys()),
                                 ('scan_val', scans.values())]
    scan_infosource.synchronize = True

    # xnat source
    xnatsource = Node(nio.XNATSource(
        infields=['project_id', 'subject_id', 'exp_id', 'scan_id'],
        outfields=['dicom'],
        server=xnat_server,
        user=xnat_user,
        pwd=xnat_pass,
        cache_dir=working_dir),
                      name='xnatsource')

    xnatsource.inputs.query_template = (
        '/projects/%s/subjects/%s/experiments/%s/scans/%d/resources/DICOM/files'
    )  #files')
    xnatsource.inputs.query_template_args['dicom'] = [[
        'project_id', 'subject_id', 'exp_id', 'scan_id'
    ]]
    xnatsource.inputs.project_id = project_id
    xnatsource.inputs.subject_id = subject
    xnatsource.inputs.exp_id = exp_id
    convert.connect([(scan_infosource, xnatsource, [('scan_val', 'scan_id')])])

    # workflow to convert dicoms
    dcmconvert = create_dcmconvert_pipeline()
    convert.connect([
        (scan_infosource, dcmconvert, [('scan_key', 'inputnode.filename')]),
        (xnatsource, dcmconvert, [('dicom', 'inputnode.dicoms')])
    ])

    # xnat sink
    sink = Node(nio.DataSink(base_directory=out_dir, parameterization=False),
                name='sink')

    convert.connect([(dcmconvert, sink, [('outputnode.nifti', folder)])])

    convert.run()
Пример #9
0
def create_conversion(
    name, subject, scans, working_dir, out_dir, folder, xnat_server, xnat_user, xnat_pass, project_id, exp_id
):

    convert = Workflow(name=name)
    convert.base_dir = working_dir
    convert.config["execution"]["crashdump_dir"] = convert.base_dir + "/crash_files"

    # infosource to iterate over scans
    scan_infosource = Node(util.IdentityInterface(fields=["scan_key", "scan_val"]), name="scan_infosource")
    scan_infosource.iterables = [("scan_key", scans.keys()), ("scan_val", scans.values())]
    scan_infosource.synchronize = True

    # xnat source
    xnatsource = Node(
        nio.XNATSource(
            infields=["project_id", "subject_id", "exp_id", "scan_id"],
            outfields=["dicom"],
            server=xnat_server,
            user=xnat_user,
            pwd=xnat_pass,
            cache_dir=working_dir,
        ),
        name="xnatsource",
    )

    xnatsource.inputs.query_template = (
        "/projects/%s/subjects/%s/experiments/%s/scans/%d/resources/DICOM/files"
    )  # files')
    xnatsource.inputs.query_template_args["dicom"] = [["project_id", "subject_id", "exp_id", "scan_id"]]
    xnatsource.inputs.project_id = project_id
    xnatsource.inputs.subject_id = subject
    xnatsource.inputs.exp_id = exp_id
    convert.connect([(scan_infosource, xnatsource, [("scan_val", "scan_id")])])

    # workflow to convert dicoms
    dcmconvert = create_dcmconvert_pipeline()
    convert.connect(
        [
            (scan_infosource, dcmconvert, [("scan_key", "inputnode.filename")]),
            (xnatsource, dcmconvert, [("dicom", "inputnode.dicoms")]),
        ]
    )

    # xnat sink
    sink = Node(nio.DataSink(base_directory=out_dir, parameterization=False), name="sink")

    convert.connect([(dcmconvert, sink, [("outputnode.nifti", folder)])])

    convert.run()
Пример #10
0
def results(cenc_participant_id,  cenc_participant_dir, cenc_freesurfer_dir,cenc_results_dir, verbose):

     util.mkcd_dir( [ cenc_results_dir ], True)

     files_to_convert = [ os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'nu.mgz'),
                          os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'aseg.mgz'),
                          os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'brainmask.mgz'),
                          os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'aparc.a2009s+aseg.mgz'),
                          os.path.join( cenc_freesurfer_dir, cenc_participant_id, 'mri', 'wmparc.mgz')
                          ]

     # Check if files exist

     print files_to_convert

     if util.check_files(files_to_convert, True) == False:
          sys.exit()

     # Create link to directory

     freesurfer_results_dir =  os.path.abspath(os.path.join( cenc_participant_dir, 'freesurfer','results'))

     if not os.path.exists(freesurfer_results_dir):
          util.force_symbolic_link( os.path.join( cenc_freesurfer_dir,  cenc_participant_id ), freesurfer_results_dir)

     # TODO use input node to run this instead of a loop

     mc = Node( fs.MRIConvert( out_type = 'niigz'
                               ),
                name="mri_convert"
                )  
       
     mc.iterables = ( "in_file", files_to_convert )

     reorient = Node( fsl.Reorient2Std(), name="reorient" )

     workflow_convert = Workflow(name='cenc_freesurfer_nipype_workflow')
     workflow_convert.base_dir = cenc_results_dir
     
     workflow_convert.connect( [ (mc,       reorient, [('out_file', 'in_file')] )]
                               )    
     workflow_convert.run()
     
     # Create final brain mask. This takes forever. Speeding it up would be helpful. 

     cenc.create_mask( os.path.join( cenc_results_dir, 'brainmask.nii.gz'),         
                       os.path.join( cenc_results_dir, 'aparc.a2009s+aseg.nii.gz'), 
                       os.path.join( cenc_results_dir, 'mask.nii.gz')
                       )
Пример #11
0
    def create(self):  #, **kwargs):
        """ Create the nodes and connections for the workflow """
        # Preamble
        csvReader = CSVReader()
        csvReader.inputs.in_file = self.csv_file.default_value
        csvReader.inputs.header = self.hasHeader.default_value
        csvOut = csvReader.run()

        iters = {}
        label = csvOut.outputs.__dict__.keys()[0]
        result = eval("csvOut.outputs.{0}".format(label))
        iters['tests'], iters['samples'] = sample_test_lists(
            result, self.sample_size.default_value)
        # Main event
        out_fields = ['T1', 'T2', 'Label', 'sampleindex', 'testindex']
        inputs = Node(interface=IdentityInterface(fields=out_fields),
                      run_without_submitting=True,
                      name='inputs')
        inputs.iterables = [('sampleindex', iters['samples']),
                            ('testindex', iters['tests'])]
        if not self.hasHeader.default_value:
            inputs.inputs.T1 = csvOut.outputs.column_0
            inputs.inputs.Label = csvOut.outputs.column_1
            inputs.inputs.T2 = csvOut.outputs.column_2
        else:
            pass  #TODO
        metaflow = Workflow(name='metaflow')
        metaflow.add_nodes([inputs])
        import pdb
        pdb.set_trace()
        fusionflow = FusionLabelWorkflow()
        self.connect([
            (metaflow, fusionflow, [('inputs.sampleindex', 'sampleT1s.index'),
                                    ('inputs.T1', 'sampleT1s.inlist')]),
            (metaflow, fusionflow, [('inputs.sampleindex', 'sampleT2s.index'),
                                    ('inputs.T2', 'sampleT2s.inlist')]),
            (metaflow, fusionflow, [('inputs.sampleindex',
                                     'sampleLabels.index'),
                                    ('inputs.Label', 'sampleLabels.inlist')]),
            (metaflow, fusionflow, [('inputs.testindex', 'testT1s.index'),
                                    ('inputs.T1', 'testT1s.inlist')]),
            (metaflow, fusionflow, [('inputs.testindex', 'testT2s.index'),
                                    ('inputs.T2', 'testT2s.inlist')]),
            (metaflow, fusionflow, [('inputs.testindex', 'testLabels.index'),
                                    ('inputs.Label', 'testLabels.inlist')])
        ])
Пример #12
0
        def test_nipype_srtm_zhou2003(self):
            infosource = Node(IdentityInterface(fields=['in_file']),
                              name="infosource")
            infosource.iterables = ('in_file', [self.pet4D_file])

            km = Node(KineticModel(model='SRTM_Zhou2003',
                                   #timeSeriesImgFile=self.pet4D_file,
                                   frameTimingFile=self.timing_file,
                                   refRegionMaskFile=self.refRegionMaskFile,
                                   startActivity=self.startActivity,
                                   weights=self.weights,
                                   fwhm=self.fwhm), name="km")

            km_workflow = Workflow(name="km_workflow",
                                   base_dir=self.tmpdirname)
            km_workflow.connect([
                (infosource, km, [('in_file', 'timeSeriesImgFile')])
            ])

            km_workflow.run()
Пример #13
0
def builder(subject_id,
            subId,
            project_dir,
            data_dir,
            output_dir,
            output_final_dir,
            output_interm_dir,
            layout,
            anat=None,
            funcs=None,
            fmaps=None,
            task_name='',
            session=None,
            apply_trim=False,
            apply_dist_corr=False,
            apply_smooth=False,
            apply_filter=False,
            mni_template='2mm',
            apply_n4=True,
            ants_threads=8,
            readable_crash_files=False,
            write_logs=True):
    """
    Core function that returns a workflow. See wfmaker for more details.

    Args:
        subject_id: name of subject folder for final outputted sub-folder name
        subId: abbreviate name of subject for intermediate outputted sub-folder name
        project_dir: full path to root of project
        data_dir: full path to raw data files
        output_dir: upper level output dir (others will be nested within this)
        output_final_dir: final preprocessed sub-dir name
        output_interm_dir: intermediate preprcess sub-dir name
        layout: BIDS layout instance
    """

    ##################
    ### PATH SETUP ###
    ##################
    if session is not None:
        session = int(session)
        if session < 10:
            session = '0' + str(session)
        else:
            session = str(session)

    # Set MNI template
    MNItemplate = os.path.join(get_resource_path(),
                               'MNI152_T1_' + mni_template + '_brain.nii.gz')
    MNImask = os.path.join(get_resource_path(),
                           'MNI152_T1_' + mni_template + '_brain_mask.nii.gz')
    MNItemplatehasskull = os.path.join(get_resource_path(),
                                       'MNI152_T1_' + mni_template + '.nii.gz')

    # Set ANTs files
    bet_ants_template = os.path.join(get_resource_path(),
                                     'OASIS_template.nii.gz')
    bet_ants_prob_mask = os.path.join(
        get_resource_path(), 'OASIS_BrainCerebellumProbabilityMask.nii.gz')
    bet_ants_registration_mask = os.path.join(
        get_resource_path(), 'OASIS_BrainCerebellumRegistrationMask.nii.gz')

    #################################
    ### NIPYPE IMPORTS AND CONFIG ###
    #################################
    # Update nipype global config because workflow.config[] = ..., doesn't seem to work
    # Can't store nipype config/rc file in container anyway so set them globaly before importing and setting up workflow as suggested here: http://nipype.readthedocs.io/en/latest/users/config_file.html#config-file

    # Create subject's intermediate directory before configuring nipype and the workflow because that's where we'll save log files in addition to intermediate files
    if not os.path.exists(os.path.join(output_interm_dir, subId, 'logs')):
        os.makedirs(os.path.join(output_interm_dir, subId, 'logs'))
    log_dir = os.path.join(output_interm_dir, subId, 'logs')
    from nipype import config
    if readable_crash_files:
        cfg = dict(execution={'crashfile_format': 'txt'})
        config.update_config(cfg)
    config.update_config({
        'logging': {
            'log_directory': log_dir,
            'log_to_file': write_logs
        },
        'execution': {
            'crashdump_dir': log_dir
        }
    })
    from nipype import logging
    logging.update_logging(config)

    # Now import everything else
    from nipype.interfaces.io import DataSink
    from nipype.interfaces.utility import Merge, IdentityInterface
    from nipype.pipeline.engine import Node, Workflow
    from nipype.interfaces.nipy.preprocess import ComputeMask
    from nipype.algorithms.rapidart import ArtifactDetect
    from nipype.interfaces.ants.segmentation import BrainExtraction, N4BiasFieldCorrection
    from nipype.interfaces.ants import Registration, ApplyTransforms
    from nipype.interfaces.fsl import MCFLIRT, TOPUP, ApplyTOPUP
    from nipype.interfaces.fsl.maths import MeanImage
    from nipype.interfaces.fsl import Merge as MERGE
    from nipype.interfaces.fsl.utils import Smooth
    from nipype.interfaces.nipy.preprocess import Trim
    from .interfaces import Plot_Coregistration_Montage, Plot_Quality_Control, Plot_Realignment_Parameters, Create_Covariates, Down_Sample_Precision, Create_Encoding_File, Filter_In_Mask

    ##################
    ### INPUT NODE ###
    ##################

    # Turn functional file list into interable Node
    func_scans = Node(IdentityInterface(fields=['scan']), name='func_scans')
    func_scans.iterables = ('scan', funcs)

    # Get TR for use in filtering below; we're assuming all BOLD runs have the same TR
    tr_length = layout.get_metadata(funcs[0])['RepetitionTime']

    #####################################
    ## TRIM ##
    #####################################
    if apply_trim:
        trim = Node(Trim(), name='trim')
        trim.inputs.begin_index = apply_trim

    #####################################
    ## DISTORTION CORRECTION ##
    #####################################

    if apply_dist_corr:
        # Get fmap file locations
        fmaps = [
            f.filename for f in layout.get(
                subject=subId, modality='fmap', extensions='.nii.gz')
        ]
        if not fmaps:
            raise IOError(
                "Distortion Correction requested but field map scans not found..."
            )

        # Get fmap metadata
        totalReadoutTimes, measurements, fmap_pes = [], [], []

        for i, fmap in enumerate(fmaps):
            # Grab total readout time for each fmap
            totalReadoutTimes.append(
                layout.get_metadata(fmap)['TotalReadoutTime'])

            # Grab measurements (for some reason pyBIDS doesn't grab dcm_meta... fields from side-car json file and json.load, doesn't either; so instead just read the header using nibabel to determine number of scans)
            measurements.append(nib.load(fmap).header['dim'][4])

            # Get phase encoding direction
            fmap_pe = layout.get_metadata(fmap)["PhaseEncodingDirection"]
            fmap_pes.append(fmap_pe)

        encoding_file_writer = Node(interface=Create_Encoding_File(),
                                    name='create_encoding')
        encoding_file_writer.inputs.totalReadoutTimes = totalReadoutTimes
        encoding_file_writer.inputs.fmaps = fmaps
        encoding_file_writer.inputs.fmap_pes = fmap_pes
        encoding_file_writer.inputs.measurements = measurements
        encoding_file_writer.inputs.file_name = 'encoding_file.txt'

        merge_to_file_list = Node(interface=Merge(2),
                                  infields=['in1', 'in2'],
                                  name='merge_to_file_list')
        merge_to_file_list.inputs.in1 = fmaps[0]
        merge_to_file_list.inputs.in1 = fmaps[1]

        # Merge AP and PA distortion correction scans
        merger = Node(interface=MERGE(dimension='t'), name='merger')
        merger.inputs.output_type = 'NIFTI_GZ'
        merger.inputs.in_files = fmaps
        merger.inputs.merged_file = 'merged_epi.nii.gz'

        # Create distortion correction map
        topup = Node(interface=TOPUP(), name='topup')
        topup.inputs.output_type = 'NIFTI_GZ'

        # Apply distortion correction to other scans
        apply_topup = Node(interface=ApplyTOPUP(), name='apply_topup')
        apply_topup.inputs.output_type = 'NIFTI_GZ'
        apply_topup.inputs.method = 'jac'
        apply_topup.inputs.interp = 'spline'

    ###################################
    ### REALIGN ###
    ###################################
    realign_fsl = Node(MCFLIRT(), name="realign")
    realign_fsl.inputs.cost = 'mutualinfo'
    realign_fsl.inputs.mean_vol = True
    realign_fsl.inputs.output_type = 'NIFTI_GZ'
    realign_fsl.inputs.save_mats = True
    realign_fsl.inputs.save_rms = True
    realign_fsl.inputs.save_plots = True

    ###################################
    ### MEAN EPIs ###
    ###################################
    # For coregistration after realignment
    mean_epi = Node(MeanImage(), name='mean_epi')
    mean_epi.inputs.dimension = 'T'

    # For after normalization is done to plot checks
    mean_norm_epi = Node(MeanImage(), name='mean_norm_epi')
    mean_norm_epi.inputs.dimension = 'T'

    ###################################
    ### MASK, ART, COV CREATION ###
    ###################################
    compute_mask = Node(ComputeMask(), name='compute_mask')
    compute_mask.inputs.m = .05

    art = Node(ArtifactDetect(), name='art')
    art.inputs.use_differences = [True, False]
    art.inputs.use_norm = True
    art.inputs.norm_threshold = 1
    art.inputs.zintensity_threshold = 3
    art.inputs.mask_type = 'file'
    art.inputs.parameter_source = 'FSL'

    make_cov = Node(Create_Covariates(), name='make_cov')

    ################################
    ### N4 BIAS FIELD CORRECTION ###
    ################################
    if apply_n4:
        n4_correction = Node(N4BiasFieldCorrection(), name='n4_correction')
        n4_correction.inputs.copy_header = True
        n4_correction.inputs.save_bias = False
        n4_correction.inputs.num_threads = ants_threads
        n4_correction.inputs.input_image = anat

    ###################################
    ### BRAIN EXTRACTION ###
    ###################################
    brain_extraction_ants = Node(BrainExtraction(), name='brain_extraction')
    brain_extraction_ants.inputs.dimension = 3
    brain_extraction_ants.inputs.use_floatingpoint_precision = 1
    brain_extraction_ants.inputs.num_threads = ants_threads
    brain_extraction_ants.inputs.brain_probability_mask = bet_ants_prob_mask
    brain_extraction_ants.inputs.keep_temporary_files = 1
    brain_extraction_ants.inputs.brain_template = bet_ants_template
    brain_extraction_ants.inputs.extraction_registration_mask = bet_ants_registration_mask
    brain_extraction_ants.inputs.out_prefix = 'bet'

    ###################################
    ### COREGISTRATION ###
    ###################################
    coregistration = Node(Registration(), name='coregistration')
    coregistration.inputs.float = False
    coregistration.inputs.output_transform_prefix = "meanEpi2highres"
    coregistration.inputs.transforms = ['Rigid']
    coregistration.inputs.transform_parameters = [(0.1, ), (0.1, )]
    coregistration.inputs.number_of_iterations = [[1000, 500, 250, 100]]
    coregistration.inputs.dimension = 3
    coregistration.inputs.num_threads = ants_threads
    coregistration.inputs.write_composite_transform = True
    coregistration.inputs.collapse_output_transforms = True
    coregistration.inputs.metric = ['MI']
    coregistration.inputs.metric_weight = [1]
    coregistration.inputs.radius_or_number_of_bins = [32]
    coregistration.inputs.sampling_strategy = ['Regular']
    coregistration.inputs.sampling_percentage = [0.25]
    coregistration.inputs.convergence_threshold = [1e-08]
    coregistration.inputs.convergence_window_size = [10]
    coregistration.inputs.smoothing_sigmas = [[3, 2, 1, 0]]
    coregistration.inputs.sigma_units = ['mm']
    coregistration.inputs.shrink_factors = [[4, 3, 2, 1]]
    coregistration.inputs.use_estimate_learning_rate_once = [True]
    coregistration.inputs.use_histogram_matching = [False]
    coregistration.inputs.initial_moving_transform_com = True
    coregistration.inputs.output_warped_image = True
    coregistration.inputs.winsorize_lower_quantile = 0.01
    coregistration.inputs.winsorize_upper_quantile = 0.99

    ###################################
    ### NORMALIZATION ###
    ###################################
    # Settings Explanations
    # Only a few key settings are worth adjusting and most others relate to how ANTs optimizer starts or iterates and won't make a ton of difference
    # Brian Avants referred to these settings as the last "best tested" when he was aligning fMRI data: https://github.com/ANTsX/ANTsRCore/blob/master/R/antsRegistration.R#L275
    # Things that matter the most:
    # smoothing_sigmas:
    # how much gaussian smoothing to apply when performing registration, probably want the upper limit of this to match the resolution that the data is collected at e.g. 3mm
    # Old settings [[3,2,1,0]]*3
    # shrink_factors
    # The coarseness with which to do registration
    # Old settings [[8,4,2,1]] * 3
    # >= 8 may result is some problems causing big chunks of cortex with little fine grain spatial structure to be moved to other parts of cortex
    # Other settings
    # transform_parameters:
    # how much regularization to do for fitting that transformation
    # for syn this pertains to both the gradient regularization term, and the flow, and elastic terms. Leave the syn settings alone as they seem to be the most well tested across published data sets
    # radius_or_number_of_bins
    # This is the bin size for MI metrics and 32 is probably adequate for most use cases. Increasing this might increase precision (e.g. to 64) but takes exponentially longer
    # use_histogram_matching
    # Use image intensity distribution to guide registration
    # Leave it on for within modality registration (e.g. T1 -> MNI), but off for between modality registration (e.g. EPI -> T1)
    # convergence_threshold
    # threshold for optimizer
    # convergence_window_size
    # how many samples should optimizer average to compute threshold?
    # sampling_strategy
    # what strategy should ANTs use to initialize the transform. Regular here refers to approximately random sampling around the center of the image mass

    normalization = Node(Registration(), name='normalization')
    normalization.inputs.float = False
    normalization.inputs.collapse_output_transforms = True
    normalization.inputs.convergence_threshold = [1e-06]
    normalization.inputs.convergence_window_size = [10]
    normalization.inputs.dimension = 3
    normalization.inputs.fixed_image = MNItemplate
    normalization.inputs.initial_moving_transform_com = True
    normalization.inputs.metric = ['MI', 'MI', 'CC']
    normalization.inputs.metric_weight = [1.0] * 3
    normalization.inputs.number_of_iterations = [[1000, 500, 250, 100],
                                                 [1000, 500, 250, 100],
                                                 [100, 70, 50, 20]]
    normalization.inputs.num_threads = ants_threads
    normalization.inputs.output_transform_prefix = 'anat2template'
    normalization.inputs.output_inverse_warped_image = True
    normalization.inputs.output_warped_image = True
    normalization.inputs.radius_or_number_of_bins = [32, 32, 4]
    normalization.inputs.sampling_percentage = [0.25, 0.25, 1]
    normalization.inputs.sampling_strategy = ['Regular', 'Regular', 'None']
    normalization.inputs.shrink_factors = [[8, 4, 2, 1]] * 3
    normalization.inputs.sigma_units = ['vox'] * 3
    normalization.inputs.smoothing_sigmas = [[3, 2, 1, 0]] * 3
    normalization.inputs.transforms = ['Rigid', 'Affine', 'SyN']
    normalization.inputs.transform_parameters = [(0.1, ), (0.1, ),
                                                 (0.1, 3.0, 0.0)]
    normalization.inputs.use_histogram_matching = True
    normalization.inputs.winsorize_lower_quantile = 0.005
    normalization.inputs.winsorize_upper_quantile = 0.995
    normalization.inputs.write_composite_transform = True

    # NEW SETTINGS (need to be adjusted; specifically shink_factors and smoothing_sigmas need to be the same length)
    # normalization = Node(Registration(), name='normalization')
    # normalization.inputs.float = False
    # normalization.inputs.collapse_output_transforms = True
    # normalization.inputs.convergence_threshold = [1e-06, 1e-06, 1e-07]
    # normalization.inputs.convergence_window_size = [10]
    # normalization.inputs.dimension = 3
    # normalization.inputs.fixed_image = MNItemplate
    # normalization.inputs.initial_moving_transform_com = True
    # normalization.inputs.metric = ['MI', 'MI', 'CC']
    # normalization.inputs.metric_weight = [1.0]*3
    # normalization.inputs.number_of_iterations = [[1000, 500, 250, 100],
    #                                              [1000, 500, 250, 100],
    #                                              [100, 70, 50, 20]]
    # normalization.inputs.num_threads = ants_threads
    # normalization.inputs.output_transform_prefix = 'anat2template'
    # normalization.inputs.output_inverse_warped_image = True
    # normalization.inputs.output_warped_image = True
    # normalization.inputs.radius_or_number_of_bins = [32, 32, 4]
    # normalization.inputs.sampling_percentage = [0.25, 0.25, 1]
    # normalization.inputs.sampling_strategy = ['Regular',
    #                                           'Regular',
    #                                           'None']
    # normalization.inputs.shrink_factors = [[4, 3, 2, 1]]*3
    # normalization.inputs.sigma_units = ['vox']*3
    # normalization.inputs.smoothing_sigmas = [[2, 1], [2, 1], [3, 2, 1, 0]]
    # normalization.inputs.transforms = ['Rigid', 'Affine', 'SyN']
    # normalization.inputs.transform_parameters = [(0.1,),
    #                                              (0.1,),
    #                                              (0.1, 3.0, 0.0)]
    # normalization.inputs.use_histogram_matching = True
    # normalization.inputs.winsorize_lower_quantile = 0.005
    # normalization.inputs.winsorize_upper_quantile = 0.995
    # normalization.inputs.write_composite_transform = True

    ###################################
    ### APPLY TRANSFORMS AND SMOOTH ###
    ###################################
    merge_transforms = Node(Merge(2),
                            iterfield=['in2'],
                            name='merge_transforms')

    # Used for epi -> mni, via (coreg + norm)
    apply_transforms = Node(ApplyTransforms(),
                            iterfield=['input_image'],
                            name='apply_transforms')
    apply_transforms.inputs.input_image_type = 3
    apply_transforms.inputs.float = False
    apply_transforms.inputs.num_threads = 12
    apply_transforms.inputs.environ = {}
    apply_transforms.inputs.interpolation = 'BSpline'
    apply_transforms.inputs.invert_transform_flags = [False, False]
    apply_transforms.inputs.reference_image = MNItemplate

    # Used for t1 segmented -> mni, via (norm)
    apply_transform_seg = Node(ApplyTransforms(), name='apply_transform_seg')
    apply_transform_seg.inputs.input_image_type = 3
    apply_transform_seg.inputs.float = False
    apply_transform_seg.inputs.num_threads = 12
    apply_transform_seg.inputs.environ = {}
    apply_transform_seg.inputs.interpolation = 'MultiLabel'
    apply_transform_seg.inputs.invert_transform_flags = [False]
    apply_transform_seg.inputs.reference_image = MNItemplate

    ###################################
    ### PLOTS ###
    ###################################
    plot_realign = Node(Plot_Realignment_Parameters(), name="plot_realign")
    plot_qa = Node(Plot_Quality_Control(), name="plot_qa")
    plot_normalization_check = Node(Plot_Coregistration_Montage(),
                                    name="plot_normalization_check")
    plot_normalization_check.inputs.canonical_img = MNItemplatehasskull

    ############################################
    ### FILTER, SMOOTH, DOWNSAMPLE PRECISION ###
    ############################################
    # Use cosanlab_preproc for down sampling
    down_samp = Node(Down_Sample_Precision(), name="down_samp")

    # Use FSL for smoothing
    if apply_smooth:
        smooth = Node(Smooth(), name='smooth')
        if isinstance(apply_smooth, list):
            smooth.iterables = ("fwhm", apply_smooth)
        elif isinstance(apply_smooth, int) or isinstance(apply_smooth, float):
            smooth.inputs.fwhm = apply_smooth
        else:
            raise ValueError("apply_smooth must be a list or int/float")

    # Use cosanlab_preproc for low-pass filtering
    if apply_filter:
        lp_filter = Node(Filter_In_Mask(), name='lp_filter')
        lp_filter.inputs.mask = MNImask
        lp_filter.inputs.sampling_rate = tr_length
        lp_filter.inputs.high_pass_cutoff = 0
        if isinstance(apply_filter, list):
            lp_filter.iterables = ("low_pass_cutoff", apply_filter)
        elif isinstance(apply_filter, int) or isinstance(apply_filter, float):
            lp_filter.inputs.low_pass_cutoff = apply_filter
        else:
            raise ValueError("apply_filter must be a list or int/float")

    ###################
    ### OUTPUT NODE ###
    ###################
    # Collect all final outputs in the output dir and get rid of file name additions
    datasink = Node(DataSink(), name='datasink')
    if session:
        datasink.inputs.base_directory = os.path.join(output_final_dir,
                                                      subject_id)
        datasink.inputs.container = 'ses-' + session
    else:
        datasink.inputs.base_directory = output_final_dir
        datasink.inputs.container = subject_id

    # Remove substitutions
    data_dir_parts = data_dir.split('/')[1:]
    if session:
        prefix = ['_scan_'] + data_dir_parts + [subject_id] + [
            'ses-' + session
        ] + ['func']
    else:
        prefix = ['_scan_'] + data_dir_parts + [subject_id] + ['func']
    func_scan_names = [os.path.split(elem)[-1] for elem in funcs]
    to_replace = []
    for elem in func_scan_names:
        bold_name = elem.split(subject_id + '_')[-1]
        bold_name = bold_name.split('.nii.gz')[0]
        to_replace.append(('..'.join(prefix + [elem]), bold_name))
    datasink.inputs.substitutions = to_replace

    #####################
    ### INIT WORKFLOW ###
    #####################
    # If we have sessions provide the full path to the subject's intermediate directory
    # and only rely on workflow init to create the session container *within* that directory
    # Otherwise just point to the intermediate directory and let the workflow init create the subject container within the intermediate directory
    if session:
        workflow = Workflow(name='ses_' + session)
        workflow.base_dir = os.path.join(output_interm_dir, subId)
    else:
        workflow = Workflow(name=subId)
        workflow.base_dir = output_interm_dir

    ############################
    ######### PART (1a) #########
    # func -> discorr -> trim -> realign
    # OR
    # func -> trim -> realign
    # OR
    # func -> discorr -> realign
    # OR
    # func -> realign
    ############################
    if apply_dist_corr:
        workflow.connect([(encoding_file_writer, topup, [('encoding_file',
                                                          'encoding_file')]),
                          (encoding_file_writer, apply_topup,
                           [('encoding_file', 'encoding_file')]),
                          (merger, topup, [('merged_file', 'in_file')]),
                          (func_scans, apply_topup, [('scan', 'in_files')]),
                          (topup, apply_topup,
                           [('out_fieldcoef', 'in_topup_fieldcoef'),
                            ('out_movpar', 'in_topup_movpar')])])
        if apply_trim:
            # Dist Corr + Trim
            workflow.connect([(apply_topup, trim, [('out_corrected', 'in_file')
                                                   ]),
                              (trim, realign_fsl, [('out_file', 'in_file')])])
        else:
            # Dist Corr + No Trim
            workflow.connect([(apply_topup, realign_fsl, [('out_corrected',
                                                           'in_file')])])
    else:
        if apply_trim:
            # No Dist Corr + Trim
            workflow.connect([(func_scans, trim, [('scan', 'in_file')]),
                              (trim, realign_fsl, [('out_file', 'in_file')])])
        else:
            # No Dist Corr + No Trim
            workflow.connect([
                (func_scans, realign_fsl, [('scan', 'in_file')]),
            ])

    ############################
    ######### PART (1n) #########
    # anat -> N4 -> bet
    # OR
    # anat -> bet
    ############################
    if apply_n4:
        workflow.connect([(n4_correction, brain_extraction_ants,
                           [('output_image', 'anatomical_image')])])
    else:
        brain_extraction_ants.inputs.anatomical_image = anat

    ##########################################
    ############### PART (2) #################
    # realign -> coreg -> mni (via t1)
    # t1 -> mni
    # covariate creation
    # plot creation
    ###########################################

    workflow.connect([
        (realign_fsl, plot_realign, [('par_file', 'realignment_parameters')]),
        (realign_fsl, plot_qa, [('out_file', 'dat_img')]),
        (realign_fsl, art, [('out_file', 'realigned_files'),
                            ('par_file', 'realignment_parameters')]),
        (realign_fsl, mean_epi, [('out_file', 'in_file')]),
        (realign_fsl, make_cov, [('par_file', 'realignment_parameters')]),
        (mean_epi, compute_mask, [('out_file', 'mean_volume')]),
        (compute_mask, art, [('brain_mask', 'mask_file')]),
        (art, make_cov, [('outlier_files', 'spike_id')]),
        (art, plot_realign, [('outlier_files', 'outliers')]),
        (plot_qa, make_cov, [('fd_outliers', 'fd_outliers')]),
        (brain_extraction_ants, coregistration, [('BrainExtractionBrain',
                                                  'fixed_image')]),
        (mean_epi, coregistration, [('out_file', 'moving_image')]),
        (brain_extraction_ants, normalization, [('BrainExtractionBrain',
                                                 'moving_image')]),
        (coregistration, merge_transforms, [('composite_transform', 'in2')]),
        (normalization, merge_transforms, [('composite_transform', 'in1')]),
        (merge_transforms, apply_transforms, [('out', 'transforms')]),
        (realign_fsl, apply_transforms, [('out_file', 'input_image')]),
        (apply_transforms, mean_norm_epi, [('output_image', 'in_file')]),
        (normalization, apply_transform_seg, [('composite_transform',
                                               'transforms')]),
        (brain_extraction_ants, apply_transform_seg,
         [('BrainExtractionSegmentation', 'input_image')]),
        (mean_norm_epi, plot_normalization_check, [('out_file', 'wra_img')])
    ])

    ##################################################
    ################### PART (3) #####################
    # epi (in mni) -> filter -> smooth -> down sample
    # OR
    # epi (in mni) -> filter -> down sample
    # OR
    # epi (in mni) -> smooth -> down sample
    # OR
    # epi (in mni) -> down sample
    ###################################################

    if apply_filter:
        workflow.connect([(apply_transforms, lp_filter, [('output_image',
                                                          'in_file')])])

        if apply_smooth:
            # Filtering + Smoothing
            workflow.connect([(lp_filter, smooth, [('out_file', 'in_file')]),
                              (smooth, down_samp, [('smoothed_file', 'in_file')
                                                   ])])
        else:
            # Filtering + No Smoothing
            workflow.connect([(lp_filter, down_samp, [('out_file', 'in_file')])
                              ])
    else:
        if apply_smooth:
            # No Filtering + Smoothing
            workflow.connect([
                (apply_transforms, smooth, [('output_image', 'in_file')]),
                (smooth, down_samp, [('smoothed_file', 'in_file')])
            ])
        else:
            # No Filtering + No Smoothing
            workflow.connect([(apply_transforms, down_samp, [('output_image',
                                                              'in_file')])])

    ##########################################
    ############### PART (4) #################
    # down sample -> save
    # plots -> save
    # covs -> save
    # t1 (in mni) -> save
    # t1 segmented masks (in mni) -> save
    # realignment parms -> save
    ##########################################

    workflow.connect([
        (down_samp, datasink, [('out_file', 'functional.@down_samp')]),
        (plot_realign, datasink, [('plot', 'functional.@plot_realign')]),
        (plot_qa, datasink, [('plot', 'functional.@plot_qa')]),
        (plot_normalization_check, datasink,
         [('plot', 'functional.@plot_normalization')]),
        (make_cov, datasink, [('covariates', 'functional.@covariates')]),
        (normalization, datasink, [('warped_image', 'structural.@normanat')]),
        (apply_transform_seg, datasink, [('output_image',
                                          'structural.@normanatseg')]),
        (realign_fsl, datasink, [('par_file', 'functional.@motionparams')])
    ])

    if not os.path.exists(os.path.join(output_dir, 'pipeline.png')):
        workflow.write_graph(dotfilename=os.path.join(output_dir, 'pipeline'),
                             format='png')

    print(f"Creating workflow for subject: {subject_id}")
    if ants_threads != 8:
        print(
            f"ANTs will utilize the user-requested {ants_threads} threads for parallel processing."
        )
    return workflow
Пример #14
0
# directories
working_dir = '/home/julia/projects/real_data/working_dir/'
data_dir = '/home/julia/projects/real_data/mouse_visual/%s/' % dataset
out_dir = '/home/julia/projects/real_data/mouse_visual/%s/processed/func/' % dataset

# main workflow
preproc_func = Workflow(name='preproc_func')
preproc_func.base_dir = working_dir
preproc_func.config['execution'][
    'crashdump_dir'] = preproc_func.base_dir + "/crash_files"

# iterate over scans
scan_infosource = Node(util.IdentityInterface(fields=['scan']),
                       name='scan_infosource')
scan_infosource.iterables = [('scan', scans)]

# iterate over recons
recon_infosource = Node(util.IdentityInterface(fields=['recon']),
                        name='recon_infosource')
recon_infosource.iterables = [('recon', recons)]

# select files
templates = {
    'func': 'processed/func/{scan}/data_{recon}.nii.gz',
    'mask': 'processed/func/{scan}/func_mask.nii.gz',
    'struct': 'processed/struct/struct_masked.nii.gz'
}
selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                   name="selectfiles")
preproc_func.connect([(recon_infosource, selectfiles, [('recon', 'recon')]),
Пример #15
0
no_runs = 3

proc_2nd_level = Workflow(name='proc_2nd_level')
proc_2nd_level.base_dir = opj(experiment_dir, working_dir)

#==========================================================================================================================================================
# In[3]:
#to prevent nipype from iterating over the anat image with each func run-, you need seperate
#nodes to select the files
#and this will solve the problem I have for almost 6 months
#but notice that in the sessions, you have to iterate also over subject_id to get the {subject_id} var

# Infosource - a function free node to iterate over the list of subject names

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

#==========================================================================================================================================================
# In[4]:
# sub-001_task-MGT_run--02_bold.nii.gz, sub-001_task-MGT_run--02_sbref.nii.gz
#/preproc_img/run--04sub-119/smoothed_all_maths_filt_maths.nii.gz
#functional run-s

out_1st = '/home/in/aeed/poldrack_gabmling/output_MGT_poldrack_proc_1st_level'
out_pre = '/home/in/aeed/poldrack_gabmling/output_MGT_poldrack_preproc_preproc'
standard_brain = '/home/in/aeed/fsl/fsl/data/standard/MNI152_T1_1mm_brain.nii.gz'
standard_mask = '/home/in/aeed/fsl/fsl/data/standard/MNI152_T1_1mm_brain_mask.nii.gz'

templates = {
    'anat_brain':
    '/home/in/aeed/poldrack_gabmling/workingdir_MGT_poldrack_preproc_preproc/preproc/_subject_id_{subject_id}/brain_extraction_anat/{subject_id}_T1w_brain.nii.gz',
def learning_prepare_data_wf(working_dir,
                             ds_dir,
                             template_lookup_dict,
                             behav_file,
                             qc_file,
                             in_data_name_list,
                             data_lookup_dict,
                             use_n_procs,
                             plugin_name):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    from prepare_data_utils import vectorize_and_aggregate
    from itertools import chain

    # ensure in_data_name_list is list of lists
    in_data_name_list = [i if type(i) == list else [i] for i in in_data_name_list]
    in_data_name_list_unique = list(set(chain.from_iterable(in_data_name_list)))


    #####################################
    # GENERAL SETTINGS
    #####################################
    wf = Workflow(name='learning_prepare_data_wf')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': False,
                                                                       'remove_unnecessary_outputs': False,
                                                                       'job_finished_timeout': 120,
                                                                       'hash_method': 'timestamp'})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(), name='ds')
    ds.inputs.base_directory = os.path.join(ds_dir, 'group_learning_prepare_data')

    ds.inputs.regexp_substitutions = [
        # ('subject_id_', ''),
        ('_parcellation_', ''),
        ('_bp_freqs_', 'bp_'),
        ('_extraction_method_', ''),
        ('_subject_id_[A0-9]*/', '')
    ]

    ds_X = Node(nio.DataSink(), name='ds_X')
    ds_X.inputs.base_directory = os.path.join(ds_dir, 'vectorized_aggregated_data')

    ds_pdf = Node(nio.DataSink(), name='ds_pdf')
    ds_pdf.inputs.base_directory = os.path.join(ds_dir, 'pdfs')
    ds_pdf.inputs.parameterization = False


    #####################################
    # SET ITERATORS
    #####################################
    # SUBJECTS ITERATOR
    in_data_name_infosource = Node(util.IdentityInterface(fields=['in_data_name']), name='in_data_name_infosource')
    in_data_name_infosource.iterables = ('in_data_name', in_data_name_list_unique)

    mulitmodal_in_data_name_infosource = Node(util.IdentityInterface(fields=['multimodal_in_data_name']),
                                              name='mulitmodal_in_data_name_infosource')
    mulitmodal_in_data_name_infosource.iterables = ('multimodal_in_data_name', in_data_name_list)



    ###############################################################################################################
    # GET SUBJECTS INFO
    # create subjects list based on selection criteria

    def create_df_fct(behav_file, qc_file):
        import pandas as pd
        import os
        df = pd.read_pickle(behav_file)
        qc = pd.read_pickle(qc_file)
        df_all = qc.join(df, how='inner')

        assert df_all.index.is_unique, 'duplicates in df index. fix before cont.'

        df_all_subjects_pickle_file = os.path.abspath('df_all.pkl')
        df_all.to_pickle(df_all_subjects_pickle_file)

        full_subjects_list = df_all.index.values

        return df_all_subjects_pickle_file, full_subjects_list

    create_df = Node(util.Function(input_names=['behav_file', 'qc_file'],
                                   output_names=['df_all_subjects_pickle_file', 'full_subjects_list'],
                                   function=create_df_fct),
                     name='create_df')
    create_df.inputs.behav_file = behav_file
    create_df.inputs.qc_file = qc_file


    ###############################################################################################################
    # CREAE FILE LIST
    # of files that will be aggregted

    def create_file_list_fct(subjects_list, in_data_name, data_lookup_dict, template_lookup_dict):
        file_list = []
        for s in subjects_list:
            file_list.append(data_lookup_dict[in_data_name]['path_str'].format(subject_id=s))

        if 'matrix_name' in data_lookup_dict[in_data_name].keys():
            matrix_name = data_lookup_dict[in_data_name]['matrix_name']
        else:
            matrix_name = None

        if 'parcellation_path' in data_lookup_dict[in_data_name].keys():
            parcellation_path = data_lookup_dict[in_data_name]['parcellation_path']
        else:
            parcellation_path = None

        if 'fwhm' in data_lookup_dict[in_data_name].keys():
            fwhm = data_lookup_dict[in_data_name]['fwhm']
            if fwhm == 0:
                fwhm = None
        else:
            fwhm = None

        if 'mask_name' in data_lookup_dict[in_data_name].keys():
            mask_path = template_lookup_dict[data_lookup_dict[in_data_name]['mask_name']]
        else:
            mask_path = None

        if 'use_diagonal' in data_lookup_dict[in_data_name].keys():
            use_diagonal = data_lookup_dict[in_data_name]['use_diagonal']
        else:
            use_diagonal = False

        if 'use_fishers_z' in data_lookup_dict[in_data_name].keys():
            use_fishers_z = data_lookup_dict[in_data_name]['use_fishers_z']
        else:
            use_fishers_z = False

        if 'df_col_names' in data_lookup_dict[in_data_name].keys():
            df_col_names = data_lookup_dict[in_data_name]['df_col_names']
        else:
            df_col_names = None

        return file_list, matrix_name, parcellation_path, fwhm, mask_path, use_diagonal, use_fishers_z, df_col_names

    create_file_list = Node(util.Function(input_names=['subjects_list',
                                                       'in_data_name',
                                                       'data_lookup_dict',
                                                       'template_lookup_dict',
                                                       ],
                                          output_names=['file_list',
                                                        'matrix_name',
                                                        'parcellation_path',
                                                        'fwhm',
                                                        'mask_path',
                                                        'use_diagonal',
                                                        'use_fishers_z',
                                                        'df_col_names'],
                                          function=create_file_list_fct),
                            name='create_file_list')
    wf.connect(create_df, 'full_subjects_list', create_file_list, 'subjects_list')
    wf.connect(in_data_name_infosource, 'in_data_name', create_file_list, 'in_data_name')
    create_file_list.inputs.data_lookup_dict = data_lookup_dict
    create_file_list.inputs.template_lookup_dict = template_lookup_dict




    ###############################################################################################################
    # VECTORIZE AND AGGREGATE SUBJECTS
    # stack single subject np arrays vertically
    vectorize_aggregate_subjects = Node(util.Function(input_names=['in_data_file_list',
                                                                   'mask_file',
                                                                   'matrix_name',
                                                                   'parcellation_path',
                                                                   'fwhm',
                                                                   'use_diagonal',
                                                                   'use_fishers_z',
                                                                   'df_file',
                                                                   'df_col_names'],
                                                      output_names=['vectorized_aggregated_file',
                                                                    'unimodal_backprojection_info_file'],
                                                      function=vectorize_and_aggregate),
                                        name='vectorize_aggregate_subjects')
    wf.connect(create_file_list, 'file_list', vectorize_aggregate_subjects, 'in_data_file_list')
    wf.connect(create_file_list, 'mask_path', vectorize_aggregate_subjects, 'mask_file')
    wf.connect(create_file_list, 'matrix_name', vectorize_aggregate_subjects, 'matrix_name')
    wf.connect(create_file_list, 'parcellation_path', vectorize_aggregate_subjects, 'parcellation_path')
    wf.connect(create_file_list, 'fwhm', vectorize_aggregate_subjects, 'fwhm')
    wf.connect(create_file_list, 'use_diagonal', vectorize_aggregate_subjects, 'use_diagonal')
    wf.connect(create_file_list, 'use_fishers_z', vectorize_aggregate_subjects, 'use_fishers_z')
    wf.connect(create_df, 'df_all_subjects_pickle_file', vectorize_aggregate_subjects, 'df_file')
    wf.connect(create_file_list, 'df_col_names', vectorize_aggregate_subjects, 'df_col_names')

    wf.connect(create_df, 'df_all_subjects_pickle_file', ds_X, 'df_all_subjects_pickle_file')
    wf.connect(vectorize_aggregate_subjects, 'vectorized_aggregated_file', ds_X, 'X_file')
    wf.connect(vectorize_aggregate_subjects, 'unimodal_backprojection_info_file', ds_X, 'unimodal_backprojection_info_file')



    #####################################
    # RUN WF
    #####################################
    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
    def make_neuromet_fs_workflow(self):

        # Infosource: Iterate through subject names
        infosource = Node(interface=IdentityInterface(fields=['subject_id']),
                          name="infosource")
        infosource.iterables = ('subject_id', self.subject_list)

        mask_source = Node(interface=GetMaskValue(csv_file=self.mask_file),
                           name='get_mask')

        split_sub_str = Node(Function(['subject_str'],
                                      ['subject_id', 'session_id'],
                                      self.split_subject_ses),
                             name='split_sub_str')

        # Datasource: Build subjects' filenames from IDs
        info = dict(mask=[[
            'subject_id', 'session_id', 'anat', 'subject_id', 'session_id',
            'mask', 'ro_brain_bin.nii.gz'
        ]],
                    uni_bias_corr=[[
                        'subject_id', 'session_id', 'anat', 'subject_id',
                        'session_id', 'UNI', 'ro_bfcorr.nii'
                    ]],
                    den_ro=[[
                        'subject_id', 'session_id', 'anat', 'subject_id',
                        'session_id', 'UNIDEN', 'ro_bfcorr.nii'
                    ]])

        datasource = Node(interface=DataGrabber(
            infields=['subject_id', 'session_id', 'mask'],
            outfields=['mask', 'uni_bias_corr', 'den_ro']),
                          name='datasource')
        datasource.inputs.base_directory = self.derivatives_dir
        datasource.inputs.template = 'sub-NeuroMET%s/ses-0%s/%s/sub-NeuroMET%s_ses-0%s_desc-%s_%s'
        datasource.inputs.template_args = info
        datasource.inputs.sort_filelist = False

        sink = self.make_sink()

        comb_imgs = self.make_comb_imgs()

        freesurfer = self.make_freesurfer()

        neuromet_fs = Workflow(name='NeuroMET', base_dir=self.temp_dir)
        neuromet_fs.connect(infosource, 'subject_id', split_sub_str,
                            'subject_str')
        neuromet_fs.connect(split_sub_str, 'subject_id', datasource,
                            'subject_id')
        neuromet_fs.connect(split_sub_str, 'session_id', datasource,
                            'session_id')
        neuromet_fs.connect(infosource, 'subject_id', mask_source,
                            'subject_id')
        neuromet_fs.connect(mask_source, 'mask_value', datasource, 'mask')
        neuromet_fs.connect(datasource, 'uni_bias_corr', comb_imgs,
                            'mask_uni_bias.in_file')
        neuromet_fs.connect(datasource, 'mask', comb_imgs,
                            'mask_uni_bias.mask_file')
        neuromet_fs.connect(datasource, 'den_ro', comb_imgs,
                            'uni_brain_den_surr_mas.in_file')

        neuromet_fs.connect(comb_imgs, 'uni_brain_den_surr_add.out_file',
                            freesurfer, 'fs_recon1.T1_files')
        neuromet_fs.connect(datasource, 'mask', freesurfer,
                            'fs_mriconv.in_file')

        out_dir_source = Node(interface=IdentityInterface(
            fields=['out_dir'], mandatory_inputs=True),
                              name='out_dir_source')
        out_dir_source.inputs.out_dir = self.bids_root
        make_list_str = Node(interface=Merge(2), name='make_list_of_paths')
        merge_strs = Node(interface=OsPathJoin(), name='merge_sub_id_dir')

        neuromet_fs.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', sink,
                            '@img')
        #neuromet_fs.connect(infosource, 'subject_id', copy_freesurfer_dir, 'sub_id')
        #neuromet_fs.connect(freesurfer, 'segment_hp.subjects_dir', copy_freesurfer_dir, 'in_dir')
        neuromet_fs.connect(freesurfer, 'segment_hp.subjects_dir',
                            make_list_str, 'in1')
        neuromet_fs.connect(freesurfer, 'segment_hp.subject_id', make_list_str,
                            'in2')
        neuromet_fs.connect(make_list_str, 'out', merge_strs, 'str_list')
        neuromet_fs.connect(merge_strs, 'out_path', sink, '@recon_all')
        #neuromet_fs.connect(out_dir_source, 'out_dir', copy_freesurfer_dir, 'out_dir')

        #ToDo:
        # 04.12.2020 QDec + Adjust volumes. It hangs if qdec is in a workflow, works a single interface
        #neuromet_fs.connect(freesurfer, 'segment_hp.subject_id', qdec, 'devnull')
        #neuromet_fs.connect(datasource, 'base_directory', qdec, 'basedir')
        #neuromet_fs.connect(qdec, 'stats_directory', adj_vol, 'stats_directory')
        #neuromet_fs.connect(qdec, 'stats_directory', sink, '@stat_dir')
        #neuromet_fs.connect(adj_vol, 'adjusted_stats', sink, '@adj_stats')

        return neuromet_fs
def create_preproc_func_pipeline(data_dir=None, subject_id=None, task_list=None):

	###############################
	## Set up Nodes
	###############################

	ds = Node(nio.DataGrabber(infields=['subject_id', 'task_id'], outfields=['func', 'struc']),name='datasource')
	ds.inputs.base_directory = os.path.abspath(data_dir + '/' + subject_id)
	ds.inputs.template = '*'
	ds.inputs.sort_filelist = True
	ds.inputs.template_args = {'func': [['task_id']], 'struc':[]}
	ds.inputs.field_template = {'func': 'Functional/Raw/%s/func.nii','struc': 'Structural/SPGR/spgr.nii'}
	ds.inputs.subject_id = subject_id
	ds.inputs.task_id = task_list
	ds.iterables = ('task_id',task_list)
	# ds.run().outputs #show datafiles

	# #Setup Data Sinker for writing output files
	# datasink = Node(nio.DataSink(), name='sinker')
	# datasink.inputs.base_directory = '/path/to/output'
	# workflow.connect(realigner, 'realignment_parameters', datasink, 'motion.@par')
	# datasink.inputs.substitutions = [('_variable', 'variable'),('file_subject_', '')]

	#Get Timing Acquisition for slice timing
	tr = 2
	ta = Node(interface=util.Function(input_names=['tr', 'n_slices'], output_names=['ta'],  function = get_ta), name="ta")
	ta.inputs.tr=tr

	#Slice Timing: sequential ascending 
	slice_timing = Node(interface=spm.SliceTiming(), name="slice_timing")
	slice_timing.inputs.time_repetition = tr
	slice_timing.inputs.ref_slice = 1

	#Realignment - 6 parameters - realign to first image of very first series.
	realign = Node(interface=spm.Realign(), name="realign")
	realign.inputs.register_to_mean = True

	#Plot Realignment
	plot_realign = Node(interface=PlotRealignmentParameters(), name="plot_realign")

	#Artifact Detection
	art = Node(interface=ra.ArtifactDetect(), name="art")
	art.inputs.use_differences      = [True,False]
	art.inputs.use_norm             = True
	art.inputs.norm_threshold       = 1
	art.inputs.zintensity_threshold = 3
	art.inputs.mask_type            = 'file'
	art.inputs.parameter_source     = 'SPM'

	#Coregister - 12 parameters, cost function = 'nmi', fwhm 7, interpolate, don't mask
	#anatomical to functional mean across all available data.
	coregister = Node(interface=spm.Coregister(), name="coregister")
	coregister.inputs.jobtype = 'estimate'

	# Segment structural, gray/white/csf,mni, 
	segment = Node(interface=spm.Segment(), name="segment")
	segment.inputs.save_bias_corrected = True

	#Normalize - structural to MNI - then apply this to the coregistered functionals
	normalize = Node(interface=spm.Normalize(), name = "normalize")
	normalize.inputs.template = os.path.abspath(t1_template_file)

	#Plot normalization Check
	plot_normalization_check = Node(interface=Plot_Coregistration_Montage(), name="plot_normalization_check")
	plot_normalization_check.inputs.canonical_img = canonical_file

	#Create Mask
	compute_mask = Node(interface=ComputeMask(), name="compute_mask")
	#remove lower 5% of histogram of mean image
	compute_mask.inputs.m = .05

	#Smooth
	#implicit masking (.im) = 0, dtype = 0
	smooth = Node(interface=spm.Smooth(), name = "smooth")
	fwhmlist = [8]
	smooth.iterables = ('fwhm',fwhmlist)

	#Create Covariate matrix
	make_covariates = Node(interface=Create_Covariates(), name="make_covariates")

	###############################
	## Create Pipeline
	###############################

	Preprocessed = Workflow(name="Preprocessed")
	Preprocessed.base_dir = os.path.abspath(data_dir + '/' + subject_id + '/Functional')

	Preprocessed.connect([(ds, ta, [(('func', get_n_slices), "n_slices")]),
						(ta, slice_timing, [("ta", "time_acquisition")]),
						(ds, slice_timing, [('func', 'in_files'),
											(('func', get_n_slices), "num_slices"),
											(('func', get_slice_order), "slice_order"),
											]),
						(slice_timing, realign, [('timecorrected_files', 'in_files')]),
						(realign, compute_mask, [('mean_image','mean_volume')]),
						(realign,coregister, [('mean_image', 'target')]),
						(ds,coregister, [('struc', 'source')]),
						(coregister,segment, [('coregistered_source', 'data')]),
						(segment, normalize, [('transformation_mat','parameter_file'),
											('bias_corrected_image', 'source'),]),
						(realign,normalize, [('realigned_files', 'apply_to_files'),
											(('realigned_files', get_vox_dims), 'write_voxel_sizes')]),
						(normalize, smooth, [('normalized_files', 'in_files')]),
						(compute_mask,art,[('brain_mask','mask_file')]),
						(realign,art,[('realignment_parameters','realignment_parameters')]),
						(realign,art,[('realigned_files','realigned_files')]),
						(realign,plot_realign, [('realignment_parameters', 'realignment_parameters')]),
						(normalize, plot_normalization_check, [('normalized_files', 'wra_img')]),
						(realign, make_covariates, [('realignment_parameters', 'realignment_parameters')]),
						(art, make_covariates, [('outlier_files', 'spike_id')]),
						])
	return Preprocessed
def run_workflow(session=None, csv_file=None):
    from nipype import config
    #config.enable_debug_mode()

    method = 'fs'  # freesurfer's mri_convert is faster
    if method == 'fs':
        import nipype.interfaces.freesurfer as fs  # freesurfer
    else:
        assert method == 'fsl'
        import nipype.interfaces.fsl as fsl  # fsl

    # ------------------ Specify variables
    ds_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

    data_dir = ds_root
    output_dir = 'derivatives/resampled-isotropic-06mm'
    working_dir = 'workingdirs'

    # ------------------ Input Files
    infosource = Node(IdentityInterface(fields=[
        'subject_id',
        'session_id',
        'datatype',
    ]),
                      name="infosource")

    if csv_file is not None:
        # Read csv and use pandas to set-up image and ev-processing
        df = pd.read_csv(csv_file)
        # init lists
        sub_img = []
        ses_img = []
        dt_img = []

        # fill lists to iterate mapnodes
        for index, row in df.iterrows():
            for dt in row.datatype.strip("[]").split(" "):
                if dt in ['anat']:  # only for anatomicals
                    sub_img.append(row.subject)
                    ses_img.append(row.session)
                    dt_img.append(dt)

        # check if the file definitions are ok
        if len(dt_img) > 0:
            print('There are images to process. Will continue.')
        else:
            print('No images specified. Check your csv-file.')

        infosource.iterables = [('session_id', ses_img),
                                ('subject_id', sub_img), ('datatype', dt_img)]
        infosource.synchronize = True
    else:
        print('No csv-file specified. Cannot continue.')

    # SelectFiles
    templates = {
        'image':
        'sub-{subject_id}/ses-{session_id}/{datatype}/'
        'sub-{subject_id}_ses-{session_id}_*.nii.gz',
    }
    inputfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                      name="input_files")

    # ------------------ Output Files
    # Datasink
    outputfiles = Node(nio.DataSink(base_directory=ds_root,
                                    container=output_dir,
                                    parameterization=True),
                       name="output_files")

    # Use the following DataSink output substitutions
    outputfiles.inputs.substitutions = [
        ('subject_id_', 'sub-'),
        ('session_id_', 'ses-'),
        # BIDS Extension Proposal: BEP003
        ('_resample.nii.gz', '_res-06x06x06_preproc.nii.gz'),
        # remove subdirectories:
        ('resampled-isotropic-06mm/isoxfm-06mm', 'resampled-isotropic-06mm'),
        ('resampled-isotropic-06mm/mriconv-06mm', 'resampled-isotropic-06mm'),
    ]
    # Put result into a BIDS-like format
    outputfiles.inputs.regexp_substitutions = [
        # this works only if datatype is specified in input
        (r'_datatype_([a-z]*)_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)',
         r'sub-\3/ses-\2/\1'),
        (r'_fs_iso06mm[0-9]*/', r''),
        (r'/_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)', r'/sub-\2/ses-\1/'),
        # stupid hacks for when datatype is not specified
        (r'//(sub-[^/]*_bold_res-.*)', r'/func/\1'),
        (r'//(sub-[^/]*_phasediff_res-.*.nii.gz)', r'/fmap/\1'),
        (r'//(sub-[^/]*_magnitude1_res-.*.nii.gz)', r'/fmap/\1'),
        (r'//(sub-[^/]*_epi_res-.*.nii.gz)', r'/fmap/\1'),
        (r'//(sub-[^/]*_T1w_res-.*.nii.gz)', r'/anat/\1'),
        (r'//(sub-[^/]*_T2w_res-.*.nii.gz)', r'/anat/\1'),
        (r'//(sub-[^/]*_dwi_res-.*.nii.gz)', r'/dwi/\1'),
    ]

    # -------------------------------------------- Create Pipeline
    isotropic_flow = Workflow(name='resample_isotropic06mm',
                              base_dir=os.path.join(ds_root, working_dir))

    isotropic_flow.connect([(infosource, inputfiles, [
        ('subject_id', 'subject_id'),
        ('session_id', 'session_id'),
        ('datatype', 'datatype'),
    ])])

    # --- Convert to 1m isotropic voxels

    if method == 'fs':
        fs_iso06mm = MapNode(
            fs.Resample(
                voxel_size=(0.6, 0.6, 0.6),
                # suffix is not accepted by fs.Resample
                # suffix='_res-1x1x1_preproc',
                # BIDS Extension Proposal: BEP003
            ),
            name='fs_iso06mm',
            iterfield=['in_file'],
        )

        isotropic_flow.connect(inputfiles, 'image', fs_iso06mm, 'in_file')
        isotropic_flow.connect(fs_iso06mm, 'resampled_file', outputfiles,
                               'mriconv-06mm')
    elif method == 'fsl':
        # in_file --> out_file
        isoxfm = Node(fsl.FLIRT(apply_isoxfm=0.6, ), name='isoxfm')

        isotropic_flow.connect(inputfiles, 'image', isoxfm, 'in_file')
        isotropic_flow.connect(inputfiles, 'image', isoxfm, 'reference')
        isotropic_flow.connect(isoxfm, 'out_file', outputfiles, 'isoxfm-06mm')

    isotropic_flow.stop_on_first_crash = False  # True
    isotropic_flow.keep_inputs = True
    isotropic_flow.remove_unnecessary_outputs = False
    isotropic_flow.write_graph()
    outgraph = isotropic_flow.run()
Пример #20
0
# ======================================================================
# time of repetition, in seconds:
time_repetition = 1.25
# total number of runs:
num_runs = 8
# smoothing kernel, in mm:
fwhm = 4
# number of dummy variables to remove from each run:
num_dummy = 0
# ======================================================================
# DEFINE NODE: INFOSOURCE
# ======================================================================
# define the infosource node that collects the data:
infosource = Node(IdentityInterface(fields=['subject_id']), name='infosource')
# let the node iterate (paralellize) over all subjects:
infosource.iterables = [('subject_id', sub_list)]
# ======================================================================
# DEFINE SELECTFILES NODE
# ======================================================================
path_confounds = glob.glob(
    opj(path_root, 'fmriprep', 'fmriprep', '*', '*', 'func',
        '*highspeed*confounds_regressors.tsv'))
path_events = glob.glob(opj(path_root, 'bids', '*', '*', 'func',
                            '*events.tsv'))
path_func = glob.glob(
    opj(path_root, 'fmriprep', 'fmriprep', '*', '*', 'func',
        '*highspeed*space-T1w*preproc_bold.nii.gz'))
path_anat = glob.glob(
    opj(path_root, 'fmriprep', 'fmriprep', '*', 'anat',
        '*_desc-preproc_T1w.nii.gz'))
path_wholemask = glob.glob(
Пример #21
0
#     if s.endswith('_roi.mat'):
#         mat_to_nii(s)
#         s = s.replace('_roi.mat', '.nii')

# Nuisance variables
nuisance_masks = ['/data/mridata/SeeleyToolbox/SeeleyFirstLevel/proc/csf_ant_post_bilateral.nii',
                  '/data/mridata/SeeleyToolbox/SeeleyFirstLevel/proc/avg152T1_white_mask.nii']

# TR
TR = 2.0

## CREATE NODES
# For distributing subject paths
infosource = Node(IdentityInterface(fields=['subject_path', 'seed']),
                  name="infosource")
infosource.iterables = [('subject_path', subjdir), ('seed', all_seeds)]

info = dict(func = [['subject_path', '/processedfmri_TRCNnSFmDI/images/swua_filteredf*.nii']],
            motion = [['subject_path', '/processedfmri_TRCNnSFmDI/motion_params_filtered.txt']])

selectfiles = Node(DataGrabber(infields = ['subject_path'],
                              outfields = ['func', 'motion'],
                              base_directory = '/',
                              template = '%s/%s',
                              template_args = info,
                              sort_filelist = True),
                  name = 'selectfiles')

# For merging seed and nuisance mask paths and then distributing them downstream
seed_plus_nuisance = Node(utilMerge(2), name = 'seed_plus_nuisance')
seed_plus_nuisance.inputs.in2 = nuisance_masks
Пример #22
0
def extract_values_mask(working_dir, data_dir, out_dir, preproc_dir,
                            subject_id, mask_list, scan_group_list):
                        
                              
    afni.base.AFNICommand.set_default_output_type('NIFTI_GZ')
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')

    ########################
    ### SPECIFY WORKFLOW ###
    ########################

    # Create a local_metrics workflow
    extract_vals_wf = Workflow(name='extract_vals_wf')
    extract_vals_wf.base_dir =  working_dir
    extract_vals_wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')
    
    
    #####################
    ### SPECIFY NODES ###
    #####################
    
    ### INPUT ###
    
    # Infosource - a function free node to iterate over the list scans 
    scan_group_infosource = Node(util.IdentityInterface(fields=['scan_group']), 
                               name='scan_group_infosource')
    scan_group_infosource.iterables= [('scan_group', scan_group_list)]             
                                    
                          
    # select Z maps, 2 versions of func (bpf: band pass filtered; no_bpf:no temporal filtering)
    templates={'z_map_le_amy': 'MRI/' + subject_id + '/analysis/sca/nilearn/{scan_group}/left_amygdala/fwhm_6/corr_map_le_amy_z.nii.gz',
               'z_map_ri_amy': 'MRI/' + subject_id + '/analysis/sca/nilearn/{scan_group}/right_amygdala/fwhm_6/corr_map_ri_amy_z.nii.gz',
               }
    select_zmaps = Node(nio.SelectFiles(templates,
                                       base_directory = data_dir),
                       name="select_zmaps")
    extract_vals_wf.connect(scan_group_infosource, 'scan_group', select_zmaps, 'scan_group')
        
    
#    roi_infosource = Node(util.IdentityInterface(fields=['epi_mask']), 
#                               name='roi_infosource')
#    roi_infosource.iterables= [('epi_mask',roi_list)]                                  
    
    
#    # select files, 2 versions of func (bpf: band pass filtered; no_bpf:no temporal filtering)
#    templates={'epi_mask' : 'templates/harvard_oxford/{epi_mask}'
#               }
#    selectmasks = Node(nio.SelectFiles(templates,
#                                       base_directory = project_dir),
#                       name="selectmasks")
                     

    
    ### ANALYSIS NODES ###
    
    def get_vals(le_amy_nii):
                   
        from nipype.interfaces.afni import ROIStats
        import numpy as np
        import os        
           #from nipype.interfaces.fsl import ImageMeants        
            #from nilearn.input_data import NiftiMasker, NiftiMapsMasker
            #import numpy as np
            #import os
            
        ROIStats(mask = '/scr/nil3/reinelt/NECOS/templates/interaction_masks/mask_intact_bl2vs1_str_vs_con_le_amy.nii.gz',
                 quiet = True)
        mean_le_amy = ROIStats.run(le_amy_nii)
                                  
                                  
            # initialize  an empty file & "fill" it with the calculated value, necessary becaus nipype need file types or so... aehm hmm 
        mean_le_amy_file = os.path.abspath('mean_le_amy.txt')
        np.savetxt(mean_le_amy_file, np.atleast_1d(mean_le_amy))         
                      
        return mean_le_amy_file
                              
 

    vals_inside_mask = Node(util.Function(input_names = ['le_amy_nii'],
                                           output_names = ['mean_le_amy_file'],      
                                           function = get_vals),
                    name='sca_prob_seeds')                      
    extract_vals_wf.connect(select_zmaps, 'z_map_le_amy', vals_inside_mask, 'le_amy_nii')     
                        
    
      
#    vals_inside_mask = Node(afni.ROIStats(),
#                            name = 'vals_inside_mask')
#    vals_inside_mask.inputs.mask = '/scr/nil3/reinelt/NECOS/templates/interaction_masks/mask_intact_bl2vs1_str_vs_con_le_amy.nii.gz'
#                                 
#    extract_vals_wf.connect(select_zmaps, 'z_map_le_amy', vals_inside_mask, 'in_file')     
  
    ### OUTPUT ###
        
    # Node to sink data (function DataSink from nipype.interfaces.io)
    datasink = Node(nio.DataSink(base_directory = out_dir,
                                 substitutions=[('_scan_id_', ''),
                                                ('_epi_mask_',''),
                                                ('rest_preprocessed2mni_2mm_maths.nii.gz','temporal_std_2mni_2mm.nii.gz')    
                                                 ]),
                      name="datasink")    
    extract_vals_wf.connect(vals_inside_mask, 'mean_le_amy_file', datasink, 'mean_le_amy')

    
  
                   
    ####################
    ### RUN WORKFLOW ###
    ####################    
    
    #extract_vals_wf.write_graph(dotfilename='sca', graph2use='flat', format='pdf')
    #extract_vals_wf.run()rest_preprocessed2mn
    #extract_vals_wf.run(plugin='CondorDAGMan')    
    extract_vals_wf.run(plugin='MultiProc', plugin_args={'n_procs' : 30})
Пример #23
0
def learning_prepare_data_wf(working_dir,
                             ds_dir,
                             template_dir,
                             df_file,
                             in_data_name_list,
                             data_lookup_dict,
                             use_n_procs,
                             plugin_name):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow, MapNode, JoinNode
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    from nipype.interfaces.freesurfer.utils import ImageInfo
    from utils import aggregate_data, vectorize_data
    from itertools import chain




    # ensure in_data_name_list is list of lists
    in_data_name_list = [i if type(i) == list else [i] for i in in_data_name_list]
    in_data_name_list_unique = list(set(chain.from_iterable(in_data_name_list)))

    #####################################
    # GENERAL SETTINGS
    #####################################
    wf = Workflow(name='learning_prepare_data_wf')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True,
                                                                       'remove_unnecessary_outputs': False,
                                                                       'job_finished_timeout': 120})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(), name='ds')
    ds.inputs.base_directory = os.path.join(ds_dir, 'group_learning_prepare_data')

    ds.inputs.regexp_substitutions = [
        # ('subject_id_', ''),
        ('_parcellation_', ''),
        ('_bp_freqs_', 'bp_'),
        ('_extraction_method_', ''),
        ('_subject_id_[A0-9]*/', '')
    ]
    ds_pdf = Node(nio.DataSink(), name='ds_pdf')
    ds_pdf.inputs.base_directory = os.path.join(ds_dir, 'pdfs')
    ds_pdf.inputs.parameterization = False

    # get atlas data
    templates_atlases = {'GM_mask_MNI_2mm': 'SPM_GM/SPM_GM_mask_2mm.nii.gz',
                         'GM_mask_MNI_3mm': 'SPM_GM/SPM_GM_mask_3mm.nii.gz',
                         'brain_mask_MNI_3mm': 'cpac_image_resources/MNI_3mm/MNI152_T1_3mm_brain_mask.nii.gz',
                         'brain_template_MNI_3mm': 'cpac_image_resources/MNI_3mm/MNI152_T1_3mm.nii.gz'
                         }

    selectfiles_anat_templates = Node(nio.SelectFiles(templates_atlases,
                                                      base_directory=template_dir),
                                      name="selectfiles_anat_templates")

    #####################################
    # SET ITERATORS
    #####################################
    # SUBJECTS ITERATOR
    in_data_name_infosource = Node(util.IdentityInterface(fields=['in_data_name']), name='in_data_name_infosource')
    in_data_name_infosource.iterables = ('in_data_name', in_data_name_list_unique)

    mulitmodal_in_data_name_infosource = Node(util.IdentityInterface(fields=['multimodal_in_data_name']),
                                              name='mulitmodal_in_data_name_infosource')
    mulitmodal_in_data_name_infosource.iterables = ('multimodal_in_data_name', in_data_name_list)

    subjects_selection_crit_dict = {}
    subjects_selection_crit_dict['adult_healthy_F'] = ["df[df.sex == \'F\']", 'df[df.no_axis_1]', 'df[df.age >= 18]']
    subjects_selection_crit_dict['adult_F'] = ["df[df.sex == \'F\']", 'df[df.age >= 18]']
    subjects_selection_crit_dict['F'] = ["df[df.sex == \'F\']"]

    subjects_selection_crit_dict['adult_healthy_M'] = ["df[df.sex == \'M\']", 'df[df.no_axis_1]', 'df[df.age >= 18]']
    subjects_selection_crit_dict['adult_M'] = ["df[df.sex == \'M\']", 'df[df.age >= 18]']
    subjects_selection_crit_dict['adult'] = ['df[df.age >= 18]']
    # subjects_selection_crit_names_list = subjects_selection_crit_dict.keys()
    subjects_selection_crit_names_list = ['adult_F']

    subject_selection_infosource = Node(util.IdentityInterface(fields=['selection_criterium']),
                                        name='subject_selection_infosource')
    subject_selection_infosource.iterables = ('selection_criterium', subjects_selection_crit_names_list)

    def out_name_str_fct(selection_criterium, in_data_name):
        return selection_criterium + '_' + in_data_name

    out_name_str = Node(util.Function(input_names=['selection_criterium', 'in_data_name'],
                                      output_names=['out_name_str'],
                                      function=out_name_str_fct),
                        name='out_name_str')
    wf.connect(in_data_name_infosource, 'in_data_name', out_name_str, 'in_data_name')
    wf.connect(subject_selection_infosource, 'selection_criterium', out_name_str, 'selection_criterium')

    def get_subjects_info_fct(df_file, subjects_selection_crit_dict, selection_criterium):
        import pandas as pd
        import os
        import numpy as np

        df = pd.read_pickle(df_file)

        #   EXCLUSION HERE:
        for eval_str in subjects_selection_crit_dict[selection_criterium]:
            df = eval(eval_str)

        df_out_file = os.path.join(os.getcwd(), 'df_use.csv')
        df.to_csv(df_out_file)
        subjects_list = df.leica_id.values

        age = df.age.values
        age_file = os.path.join(os.getcwd(), 'age.npy')
        np.save(age_file, age)
        return (age_file, df_out_file, subjects_list)

    get_subjects_info = Node(
        util.Function(input_names=['df_file', 'subjects_selection_crit_dict', 'selection_criterium'],
                      output_names=['age_file', 'df_out_file', 'subjects_list'],
                      function=get_subjects_info_fct),
        name='get_subjects_info')
    get_subjects_info.inputs.df_file = df_file
    get_subjects_info.inputs.subjects_selection_crit_dict = subjects_selection_crit_dict
    wf.connect(subject_selection_infosource, 'selection_criterium', get_subjects_info, 'selection_criterium')
    wf.connect(get_subjects_info, 'df_out_file', ds, 'test')
    wf.connect(get_subjects_info, 'age_file', ds, 'test_age_file')

    def create_file_list_fct(subjects_list, in_data_name, data_lookup_dict, brain_mask_path, gm_mask_path):
        file_list = []
        for s in subjects_list:
            file_list.append(data_lookup_dict[in_data_name]['path_str'].format(subject_id=s))

        if 'matrix_name' in data_lookup_dict[in_data_name].keys():
            matrix_name = data_lookup_dict[in_data_name]['matrix_name']
        else:
            matrix_name = None

        if 'parcellation_path' in data_lookup_dict[in_data_name].keys():
            parcellation_path = data_lookup_dict[in_data_name]['parcellation_path']
        else:
            parcellation_path = None

        if 'fwhm' in data_lookup_dict[in_data_name].keys():
            fwhm = data_lookup_dict[in_data_name]['fwhm']
        else:
            fwhm = None

        mask_path = brain_mask_path
        if 'use_gm_mask' in data_lookup_dict[in_data_name].keys():
            if data_lookup_dict[in_data_name]['use_gm_mask']:
                mask_path = gm_mask_path

        return file_list, matrix_name, parcellation_path, fwhm, mask_path

    create_file_list = Node(util.Function(input_names=['subjects_list',
                                                       'in_data_name',
                                                       'data_lookup_dict',
                                                       'brain_mask_path',
                                                       'gm_mask_path'],
                                          output_names=['file_list',
                                                        'matrix_name',
                                                        'parcellation_path',
                                                        'fwhm',
                                                        'mask_path'],
                                          function=create_file_list_fct),
                            name='create_file_list')
    wf.connect(get_subjects_info, 'subjects_list', create_file_list, 'subjects_list')
    wf.connect(in_data_name_infosource, 'in_data_name', create_file_list, 'in_data_name')
    create_file_list.inputs.data_lookup_dict = data_lookup_dict
    wf.connect(selectfiles_anat_templates, 'brain_mask_MNI_3mm', create_file_list, 'brain_mask_path')
    wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', create_file_list, 'gm_mask_path')

    aggregate_subjects = Node(util.Function(input_names=['file_list'],
                                            output_names=['merged_file'],
                                            function=aggregate_data),
                              name='aggregate_subjects')
    wf.connect(create_file_list, 'file_list', aggregate_subjects, 'file_list')

    vectorized_data = Node(
        util.Function(input_names=['in_data_file', 'mask_file', 'matrix_name', 'parcellation_path', 'fwhm'],
                      output_names=['vectorized_data', 'vectorized_data_file'],
                      function=vectorize_data),
        name='vectorized_data')
    wf.connect(aggregate_subjects, 'merged_file', vectorized_data, 'in_data_file')
    wf.connect(create_file_list, 'mask_path', vectorized_data, 'mask_file')
    wf.connect(create_file_list, 'matrix_name', vectorized_data, 'matrix_name')
    wf.connect(create_file_list, 'parcellation_path', vectorized_data, 'parcellation_path')
    wf.connect(create_file_list, 'fwhm', vectorized_data, 'fwhm')

    def aggregate_multimodal_metrics_fct(multimodal_list, vectorized_data_file, vectorized_data_names,
                                         selection_criterium):
        import numpy as np
        import os

        metrics_index_list = [vectorized_data_names.index(m) for m in multimodal_list]
        X = None
        for i in metrics_index_list:
            X_file = vectorized_data_file[i]
            X_single = np.load(X_file)
            if X is None:
                X = X_single
            else:
                X = np.hstack((X, X_single))

        multimodal_in_name = '_'.join(multimodal_list)
        multimodal_out_name = selection_criterium + '_' + multimodal_in_name
        X_file = os.path.join(os.getcwd(), multimodal_in_name + '.npy')
        np.save(X_file, X)
        return multimodal_in_name, multimodal_out_name, X_file

    aggregate_multimodal_metrics = JoinNode(util.Function(input_names=['multimodal_list',
                                                                       'vectorized_data_file',
                                                                       'vectorized_data_names',
                                                                       'selection_criterium'],
                                                          output_names=['multimodal_in_name', 'multimodal_out_name',
                                                                        'X_file'],
                                                          function=aggregate_multimodal_metrics_fct),
                                            joinfield='vectorized_data_file',
                                            joinsource=in_data_name_infosource,
                                            name='aggregate_multimodal_metrics')

    wf.connect(mulitmodal_in_data_name_infosource, 'multimodal_in_data_name', aggregate_multimodal_metrics,
               'multimodal_list')
    wf.connect(vectorized_data, 'vectorized_data_file', aggregate_multimodal_metrics, 'vectorized_data_file')
    wf.connect(subject_selection_infosource, 'selection_criterium', aggregate_multimodal_metrics, 'selection_criterium')
    wf.connect(aggregate_multimodal_metrics, 'X_file', ds, 'multimodal_test')
    aggregate_multimodal_metrics.inputs.vectorized_data_names = in_data_name_list_unique

    def run_prediction(reg_model, X_file, y_file, data_str):
        def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name):
            import os
            import pylab as plt
            from matplotlib.backends.backend_pdf import PdfPages

            plt.scatter(y_test, y_test_predicted)
            plt.plot([10, 80], [10, 80], 'k')
            plt.xlabel('real')
            plt.ylabel('predicted')
            ax = plt.gca()
            ax.set_aspect('equal')
            plt.title(title_str)
            plt.tight_layout()
            scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf')
            pp = PdfPages(scatter_file)
            pp.savefig()
            pp.close()
            return scatter_file

        import os, pickle
        import numpy as np
        from sklearn.svm import SVR
        from sklearn.cross_validation import cross_val_score, cross_val_predict
        from sklearn.feature_selection import VarianceThreshold
        from sklearn.preprocessing import MinMaxScaler
        from sklearn.preprocessing import Imputer
        from sklearn.pipeline import Pipeline
        from sklearn.metrics import r2_score, mean_absolute_error

        X = np.load(X_file)
        y = np.load(y_file)


        # fixme pipe
        fill_missing = Imputer()
        # X = fill_missing.fit_transform(X)

        # fixme? pipe
        # remove low variance features
        var_thr = VarianceThreshold()
        # X = var_thr.fit_transform(X)

        # fixme pipe normalize
        normalize = MinMaxScaler()
        # X = normalize.fit_transform(X)

        regression_model = reg_model  # SVR(kernel='linear')

        pipe = Pipeline([
            ('fill_missing', fill_missing),
            ('var_thr', var_thr),
            ('normalize', normalize),
            ('regression_model', regression_model),
        ])
        # cv_scores = cross_val_score(pipe, X, y, cv=5, n_jobs=5,
        #                             scoring='mean_absolute_error')
        # cv_scores_r2 = cross_val_score(pipe, X, y, cv=5, n_jobs=5,
        #                                scoring='r2')

        y_predicted = cross_val_predict(pipe, X, y, cv=5, n_jobs=5)

        cv_scores = mean_absolute_error(y, y_predicted)
        cv_scores_r2 = r2_score(y, y_predicted)
        title_str = '{}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}'.format(
            data_str,
            cv_scores.mean(), cv_scores.std(), cv_scores.min(), cv_scores.max(),
            cv_scores_r2.mean(), cv_scores_r2.std(), cv_scores_r2.min(), cv_scores_r2.max())

        scatter_file = _pred_real_scatter(y, y_predicted, title_str, data_str)

        out_file = os.path.join(os.getcwd(), 'cv_scores.pkl')
        with open(out_file, 'w') as f:
            pickle.dump(cv_scores, f)

        y_pred_file = os.path.join(os.getcwd(), 'y_pred.npy')
        np.save(y_pred_file, y_predicted)

        return out_file, regression_model, scatter_file, y_pred_file

    #
    from sklearn.svm import SVR
    from sklearn.linear_model import (LassoCV, ElasticNetCV)

    prediction = Node(util.Function(input_names=['reg_model', 'X_file', 'y_file', 'data_str'],
                                    output_names=['out_file', 'regression_model', 'scatter_file', 'y_pred_file'],
                                    function=run_prediction),
                      name='prediction')
    # prediction.inputs.reg_model = SVR(kernel='linear')
    # wf.connect(aggregate_multimodal_metrics, 'X_file', prediction, 'X_file')
    # # wf.connect(vectorized_data, 'vectorized_data_file', prediction, 'X_file')
    # wf.connect(get_subjects_info, 'age_file', prediction, 'y_file')
    # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction, 'data_str')
    # wf.connect(prediction, 'out_file', ds, 'test_naiv_cv_score')
    # wf.connect(prediction, 'scatter_file', ds_pdf, 'test_naive_scatter_svr')
    # wf.connect(prediction, 'y_pred_file', ds_pdf, 'test_naive_predicted_svr')
    #

    # prediction_lasso = prediction.clone('prediction_lasso')
    # prediction_lasso.inputs.reg_model = LassoCV(n_jobs=5)
    # wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_lasso, 'X_file')
    # wf.connect(get_subjects_info, 'age_file', prediction_lasso, 'y_file')
    # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_lasso, 'data_str')
    # wf.connect(prediction_lasso, 'out_file', ds, 'test_cv_score_lasso')
    # wf.connect(prediction_lasso, 'scatter_file', ds_pdf, 'test_naive_scatter_lasso')
    #
    def run_prediction_split(reg_model, X_file, y_file, data_str):
        def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name):
            import os
            import pylab as plt
            from matplotlib.backends.backend_pdf import PdfPages

            plt.scatter(y_test, y_test_predicted)
            plt.plot([10, 80], [10, 80], 'k')
            plt.xlabel('real')
            plt.ylabel('predicted')
            ax = plt.gca()
            ax.set_aspect('equal')
            plt.title(title_str)
            plt.tight_layout()
            scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf')
            pp = PdfPages(scatter_file)
            pp.savefig()
            pp.close()
            return scatter_file

        import os, pickle
        import numpy as np
        from sklearn.svm import SVR
        from sklearn.cross_validation import cross_val_score, cross_val_predict
        from sklearn.feature_selection import VarianceThreshold
        from sklearn.preprocessing import MinMaxScaler
        from sklearn.preprocessing import Imputer
        from sklearn.pipeline import Pipeline
        from sklearn.metrics import r2_score, mean_absolute_error
        from sklearn.cross_validation import train_test_split

        X = np.load(X_file)
        y = np.load(y_file)
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

        fill_missing = Imputer()
        var_thr = VarianceThreshold()
        normalize = MinMaxScaler()

        regression_model = reg_model  # SVR(kernel='linear')

        pipe = Pipeline([
            ('fill_missing', fill_missing),
            ('var_thr', var_thr),
            ('normalize', normalize),
            ('regression_model', regression_model),
        ])

        pipe.fit(X_train, y_train)

        fitted_enet_model = pipe.steps[3][1]
        results_str = 'n_iter: %s. l1_r: %s. alpha: %s' % (
            fitted_enet_model.n_iter_, fitted_enet_model.l1_ratio_, fitted_enet_model.alpha_)

        y_predicted = pipe.predict(X_test)

        cv_scores = mean_absolute_error(y_test, y_predicted)
        cv_scores_r2 = r2_score(y_test, y_predicted)
        title_str = '{}\n{}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}'.format(
            data_str,
            results_str,
            cv_scores.mean(), cv_scores.std(), cv_scores.min(), cv_scores.max(),
            cv_scores_r2.mean(), cv_scores_r2.std(), cv_scores_r2.min(), cv_scores_r2.max())

        scatter_file = _pred_real_scatter(y_test, y_predicted, title_str, data_str)

        out_file = os.path.join(os.getcwd(), 'cv_scores.pkl')
        with open(out_file, 'w') as f:
            pickle.dump(cv_scores, f)

        model_out_file = os.path.join(os.getcwd(), 'trained_model.pkl')
        with open(model_out_file, 'w') as f:
            pickle.dump(pipe, f)

        y_pred_file = os.path.join(os.getcwd(), 'y_pred.npy')
        np.save(y_pred_file, y_predicted)

        return out_file, regression_model, scatter_file, y_pred_file, model_out_file, fitted_enet_model

    prediction_enet = Node(util.Function(input_names=['reg_model', 'X_file', 'y_file', 'data_str'],
                                         output_names=['out_file', 'regression_model', 'scatter_file',
                                                       'y_pred_file', 'model_out_file', 'fitted_enet_model'],
                                         function=run_prediction_split),
                           name='prediction_enet')

    # fixme n_jobs
    prediction_enet.inputs.reg_model = ElasticNetCV(cv=5, n_jobs=10, selection='random', max_iter=2000,
                                                    l1_ratio=[0, .01, .05, .1, .5, .7, .9, .95, .99, 1])
    wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_enet, 'X_file')
    wf.connect(get_subjects_info, 'age_file', prediction_enet, 'y_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_enet, 'data_str')
    wf.connect(prediction_enet, 'out_file', ds, 'test_split_cv_score_enet')
    wf.connect(prediction_enet, 'model_out_file', ds, 'test_split_trained_model_enet')
    wf.connect(prediction_enet, 'scatter_file', ds_pdf, 'test_split_scatter_enet')
    wf.connect(prediction_enet, 'y_pred_file', ds_pdf, 'test_split_predicted_enet')



    # prediction_enet = prediction.clone('prediction_enet')
    # prediction_enet.inputs.reg_model = ElasticNetCV(cv=5, n_jobs=7, selection='random', max_iter=2000,
    #                                                 l1_ratio=[.1, .5, .7, .9, .95, .99, 1])
    # wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_enet, 'X_file')
    # wf.connect(get_subjects_info, 'age_file', prediction_enet, 'y_file')
    # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_enet, 'data_str')
    # wf.connect(prediction_enet, 'out_file', ds, 'test_cv_score_enet')
    # wf.connect(prediction_enet, 'scatter_file', ds_pdf, 'test_naive_scatter_enet')
    # wf.connect(prediction_enet, 'y_pred_file', ds_pdf, 'test_naive_predicted_enet')


    # # # # # # # # # # # # # #
    # GS
    # # # # # # # # # # # # # #
    def run_prediction_gs(X_file, y_file, data_str):
        # fixme copied function
        def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name):
            import os
            import pylab as plt
            from matplotlib.backends.backend_pdf import PdfPages

            plt.scatter(y_test, y_test_predicted)
            plt.plot([10, 80], [10, 80], 'k')
            plt.xlabel('real')
            plt.ylabel('predicted')
            ax = plt.gca()
            ax.set_aspect('equal')
            plt.title(title_str)
            plt.tight_layout()
            scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf')
            pp = PdfPages(scatter_file)
            pp.savefig()
            pp.close()
            return scatter_file

        import os, pickle
        import numpy as np
        from sklearn.svm import SVR
        from sklearn.cross_validation import cross_val_score, cross_val_predict
        from sklearn.feature_selection import VarianceThreshold
        from sklearn.grid_search import GridSearchCV
        from sklearn.preprocessing import MinMaxScaler
        from sklearn.preprocessing import Imputer

        X = np.load(X_file)
        y = np.load(y_file)

        # fixme pipe
        imp = Imputer()
        X = imp.fit_transform(X)

        # fixme? pipe
        # remove low variance features
        var_thr = VarianceThreshold()
        X = var_thr.fit_transform(X)


        # fixme pipe normalize
        normalize = MinMaxScaler()
        X = normalize.fit_transform(X)

        # fixme?
        # remove low variance features
        var_thr = VarianceThreshold()
        X = var_thr.fit_transform(X)

        regression_model = SVR(kernel='linear')

        # GRID SEARCH
        params = {
            'C': [.0001, .001, .01, .1, 1, 10, 20, 30],
            'epsilon': [.0001, .001, .01, .1, 1],
        }
        gs = GridSearchCV(regression_model, params, cv=5, scoring='mean_absolute_error', n_jobs=10)
        gs.fit(X, y)

        sorted_grid_score = sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True)
        score_str = [str(n) + ': ' + str(g) for n, g in enumerate(sorted_grid_score)]

        gs_file = os.path.join(os.getcwd(), 'gs_' + data_str + '.txt')
        with open(gs_file, 'w') as f:
            f.write('\n'.join(score_str))

        # GS WITH NESTED CV
        gs_cv = GridSearchCV(regression_model, params, cv=5, scoring='mean_absolute_error', n_jobs=5)
        cv_scores = cross_val_score(regression_model, X, y, cv=5, scoring='mean_absolute_error')
        cv_scores_r2 = cross_val_score(regression_model, X, y, cv=5, scoring='r2')
        cv_prediction = cross_val_predict(regression_model, X, y, cv=5)

        title_str = '{}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}\n mean: {:.3f}, sd: {:.3f}, min: {:.3f}, max: {:.3f}'.format(
            data_str,
            cv_scores.mean(), cv_scores.std(), cv_scores.min(), cv_scores.max(),
            cv_scores_r2.mean(), cv_scores_r2.std(), cv_scores_r2.min(), cv_scores_r2.max())

        cv_scatter_file = _pred_real_scatter(y, cv_prediction, title_str, data_str + '_cv_pred')

        ## #  # # # # # # #
        # BEST PARAMETERS


        best_params = sorted_grid_score[0].parameters
        regression_model = SVR(kernel='linear', **best_params)

        y_predicted = cross_val_predict(regression_model, X, y, cv=5, n_jobs=5)

        best_params_scatter_file = _pred_real_scatter(y, y_predicted, data_str, data_str)

        return regression_model, gs_file, best_params_scatter_file, cv_scatter_file

    gs = Node(util.Function(input_names=['X_file', 'y_file', 'data_str'],
                            output_names=['regression_model', 'gs_file', 'best_params_scatter_file', 'cv_scatter_file'],
                            function=run_prediction_gs),
              name='gs')


    # wf.connect(aggregate_multimodal_metrics, 'X_file', gs, 'X_file')
    # wf.connect(get_subjects_info, 'age_file', gs, 'y_file')
    # wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', gs, 'data_str')
    # wf.connect(gs, 'gs_file', ds_pdf, 'test_gs')
    # wf.connect(gs, 'best_params_scatter_file', ds_pdf, 'test_gs_best_params_scatters')
    # wf.connect(gs, 'cv_scatter_file', ds_pdf, 'test_gs_cv_scatters')


    # # # # # # # # # # # # # #
    # PIPELINE
    # # # # # # # # # # # # # #
    def run_prediction_gs_split(X_file, y_file, data_str):
        # fixme copied function
        def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name):
            import os
            import pylab as plt
            from matplotlib.backends.backend_pdf import PdfPages

            plt.scatter(y_test, y_test_predicted)
            plt.plot([10, 80], [10, 80], 'k')
            plt.xlabel('real')
            plt.ylabel('predicted')
            ax = plt.gca()
            ax.set_aspect('equal')
            plt.title(title_str)
            plt.tight_layout()

            scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf')
            pp = PdfPages(scatter_file)
            pp.savefig()
            pp.close()
            return scatter_file

        import os, pickle
        import numpy as np
        from sklearn.svm import SVR
        from sklearn.cross_validation import cross_val_score, cross_val_predict, train_test_split
        from sklearn.grid_search import GridSearchCV
        from sklearn.pipeline import Pipeline
        from sklearn.feature_selection import VarianceThreshold
        from sklearn.preprocessing import MinMaxScaler, StandardScaler
        from sklearn.preprocessing import Imputer
        from sklearn.feature_selection import SelectPercentile, f_regression
        from sklearn.metrics import mean_absolute_error, r2_score
        from sklearn.svm import LinearSVR
        from sklearn.decomposition import PCA

        X = np.load(X_file)
        y = np.load(y_file)

        # fixme add squared values to X
        # X = np.hstack([X, np.square(X)])

        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

        # remove low variance features
        fill_missing = Imputer()
        var_thr = VarianceThreshold()
        normalize = StandardScaler()  # MinMaxScaler()
        selection = SelectPercentile(f_regression)

        # regression_model = LinearSVR() #SVR(kernel='linear')
        from sklearn.svm import NuSVR
        regression_model = LinearSVR()  # NuSVR(kernel='linear') #SVR(kernel='linear')

        pipe = Pipeline([
            ('fill_missing', fill_missing),
            ('var_thr', var_thr),
            ('normalize', normalize),
            ('selection', selection),
            ('regression_model', regression_model),
        ])

        # GRID SEARCH
        params = {
            'selection__percentile': [70, 75, 80, 85, 90, 95, 99, 100],
            'regression_model__C': [1, 98, 106, 110, 130, 150, 170, 200, 14450],
            # [.0001, .001, .01, .1, 1, 10, 20, 30],
            'regression_model__epsilon': [0, .005, .01, .05, .1, 1, 5, 10],
            'regression_model__loss': ['epsilon_insensitive', 'squared_epsilon_insensitive'],
            # 'regression_model__nu': [0.01, .25, .5, .75, .8, .85, .9, .95, .99],
        }


        # fixme njobs
        gs = GridSearchCV(pipe, params, cv=5, scoring='mean_absolute_error', n_jobs=30)
        gs.fit(X_train, y_train)

        best_estimator = gs.best_estimator_

        grid_scores = gs.grid_scores_
        gs_file = os.path.join(os.getcwd(), 'gs_' + data_str + '.pkl')
        with open(gs_file, 'w') as f:
            pickle.dump(grid_scores, f)

        sorted_grid_score = sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True)
        score_str = [str(n) + ': ' + str(g) for n, g in enumerate(sorted_grid_score)]

        gs_text_file = os.path.join(os.getcwd(), 'gs_txt_' + data_str + '.txt')
        with open(gs_text_file, 'w') as f:
            f.write('\n'.join(score_str))

        # fitted_model = gs.steps[-1][1]

        model_out_file = os.path.join(os.getcwd(), 'trained_model.pkl')
        with open(model_out_file, 'w') as f:
            pickle.dump(gs, f)

        y_predicted = gs.predict(X_test)
        cv_scores = mean_absolute_error(y_test, y_predicted)
        cv_scores_r2 = r2_score(y_test, y_predicted)

        title_str = '{}\n mae: {:.3f}\n r2: {:.3f}'.format(
            data_str,
            cv_scores,
            cv_scores_r2)

        scatter_file = _pred_real_scatter(y_test, y_predicted, title_str, data_str)

        return model_out_file, scatter_file, gs_text_file, gs_file, best_estimator

    prediction_gs_split = Node(util.Function(input_names=['X_file', 'y_file', 'data_str'],
                                             output_names=['model_out_file', 'scatter_file', 'gs_text_file', 'gs_file',
                                                           'best_estimator'],
                                             function=run_prediction_gs_split),
                               name='prediction_gs_split')

    wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_gs_split, 'X_file')
    wf.connect(get_subjects_info, 'age_file', prediction_gs_split, 'y_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_gs_split, 'data_str')
    wf.connect(prediction_gs_split, 'scatter_file', ds_pdf, 'test_gs_split_scatter')
    wf.connect(prediction_gs_split, 'model_out_file', ds, 'test_gs_split_trained_model')
    wf.connect(prediction_gs_split, 'gs_text_file', ds_pdf, 'test_gs_split_gs_params')
    wf.connect(prediction_gs_split, 'gs_file', ds_pdf, 'grid_scores')



    # RANDOM CV
    def run_prediction_random_gs_split(X_file, y_file, data_str):
        # fixme copied function
        def _pred_real_scatter(y_test, y_test_predicted, title_str, in_data_name):
            import os
            import pylab as plt
            from matplotlib.backends.backend_pdf import PdfPages

            plt.scatter(y_test, y_test_predicted)
            plt.plot([10, 80], [10, 80], 'k')
            plt.xlabel('real')
            plt.ylabel('predicted')
            ax = plt.gca()
            ax.set_aspect('equal')
            plt.title(title_str)
            plt.tight_layout()

            scatter_file = os.path.join(os.getcwd(), 'scatter_' + in_data_name + '.pdf')
            pp = PdfPages(scatter_file)
            pp.savefig()
            pp.close()
            return scatter_file

        import os, pickle
        import numpy as np
        from sklearn.svm import SVR
        from sklearn.cross_validation import cross_val_score, cross_val_predict, train_test_split
        from sklearn.grid_search import RandomizedSearchCV
        from sklearn.pipeline import Pipeline
        from sklearn.feature_selection import VarianceThreshold
        from sklearn.preprocessing import MinMaxScaler, StandardScaler
        from sklearn.preprocessing import Imputer
        from sklearn.feature_selection import SelectPercentile, f_regression
        from sklearn.metrics import mean_absolute_error, r2_score
        from sklearn.svm import LinearSVR
        from sklearn.decomposition import PCA
        from scipy.stats import randint as sp_randint
        from scipy.stats import expon

        X = np.load(X_file)
        y = np.load(y_file)

        # fixme add squared values to X
        # X = np.hstack([X, np.square(X)])

        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

        # remove low variance features
        fill_missing = Imputer()
        var_thr = VarianceThreshold()
        normalize = StandardScaler()  # MinMaxScaler()
        selection = SelectPercentile(f_regression)

        # regression_model = LinearSVR() #SVR(kernel='linear')
        from sklearn.svm import NuSVR
        regression_model = LinearSVR()  # NuSVR(kernel='linear') #SVR(kernel='linear')

        pipe = Pipeline([
            ('fill_missing', fill_missing),
            ('var_thr', var_thr),
            ('normalize', normalize),
            ('selection', selection),
            ('regression_model', regression_model),
        ])


        param_dist = {
            'selection__percentile': sp_randint(10, 100),
            'regression_model__C': expon(scale=100), # sp_randint(.001, 14450),
            'regression_model__epsilon': sp_randint(0, 100),
            'regression_model__loss': ['epsilon_insensitive', 'squared_epsilon_insensitive'],
        }


        # fixme njobs
        n_iter_search = 400
        gs = RandomizedSearchCV(pipe, param_distributions=param_dist, cv=5, scoring='mean_absolute_error', n_jobs=15, n_iter=n_iter_search)
        gs.fit(X_train, y_train)

        best_estimator = gs.best_estimator_

        grid_scores = gs.grid_scores_
        gs_file = os.path.join(os.getcwd(), 'gs_' + data_str + '.pkl')
        with open(gs_file, 'w') as f:
            pickle.dump(grid_scores, f)

        sorted_grid_score = sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True)
        score_str = [str(n) + ': ' + str(g) for n, g in enumerate(sorted_grid_score)]

        gs_text_file = os.path.join(os.getcwd(), 'gs_txt_' + data_str + '.txt')
        with open(gs_text_file, 'w') as f:
            f.write('\n'.join(score_str))

        # fitted_model = gs.steps[-1][1]

        # fixme pickle crashes
        model_out_file = ''
        # model_out_file = os.path.join(os.getcwd(), 'trained_model.pkl')
        # with open(model_out_file, 'w') as f:
        #     pickle.dump(gs, f)

        y_predicted = gs.predict(X_test)
        cv_scores = mean_absolute_error(y_test, y_predicted)
        cv_scores_r2 = r2_score(y_test, y_predicted)

        title_str = '{}\n mae: {:.3f}\n r2: {:.3f}'.format(
            data_str,
            cv_scores,
            cv_scores_r2)

        scatter_file = _pred_real_scatter(y_test, y_predicted, title_str, data_str)

        return model_out_file, scatter_file, gs_text_file, gs_file, best_estimator

    prediction_random_gs_split = Node(util.Function(input_names=['X_file', 'y_file', 'data_str'],
                                             output_names=['model_out_file', 'scatter_file', 'gs_text_file', 'gs_file',
                                                           'best_estimator'],
                                             function=run_prediction_random_gs_split),
                               name='prediction_random_gs_split')

    wf.connect(aggregate_multimodal_metrics, 'X_file', prediction_random_gs_split, 'X_file')
    wf.connect(get_subjects_info, 'age_file', prediction_random_gs_split, 'y_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', prediction_random_gs_split, 'data_str')
    wf.connect(prediction_random_gs_split, 'scatter_file', ds_pdf, 'test_random_gs_split_scatter')
    #wf.connect(prediction_random_gs_split, 'model_out_file', ds, 'test_random_gs_split_trained_model')
    wf.connect(prediction_random_gs_split, 'gs_text_file', ds_pdf, 'test_random_gs_split_gs_params')
    wf.connect(prediction_random_gs_split, 'gs_file', ds_pdf, 'random_grid_scores')



    from learning_curve import learning_curve_fct
    learning_curve_svr = Node(util.Function(input_names=['X_file', 'y_file', 'out_name', 'best_estimator'],
                                            output_names=['curve_file'],
                                            function=learning_curve_fct),
                              name='learning_curve_svr')

    wf.connect(aggregate_multimodal_metrics, 'X_file', learning_curve_svr, 'X_file')
    wf.connect(get_subjects_info, 'age_file', learning_curve_svr, 'y_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', learning_curve_svr, 'out_name')
    wf.connect(prediction_gs_split, 'best_estimator', learning_curve_svr, 'best_estimator')
    # wf.connect(prediction_gs_split, 'model_out_file', learning_curve_svr, 'fitted_model_file')
    wf.connect(learning_curve_svr, 'curve_file', ds_pdf, 'learning_curve_svr')

    def _create_best_enet(fitted_enet):
        from sklearn.linear_model import ElasticNet
        best_estimator = ElasticNet(selection='random', max_iter=2000,
                                    alpha=fitted_enet.alpha_,
                                    l1_ratio=fitted_enet.l1_ratio_)
        return best_estimator

    best_estimator_enet = Node(util.Function(input_names=['fitted_enet'],
                                             output_names=['best_estimator'], function=_create_best_enet),
                               name='best_estimator_enet')
    wf.connect(prediction_enet, 'fitted_enet_model', best_estimator_enet, 'fitted_enet')

    learning_curve_enet = Node(util.Function(input_names=['X_file', 'y_file', 'out_name', 'best_estimator'],
                                             output_names=['curve_file'],
                                             function=learning_curve_fct),
                               name='learning_curve_enet')

    wf.connect(aggregate_multimodal_metrics, 'X_file', learning_curve_enet, 'X_file')
    wf.connect(get_subjects_info, 'age_file', learning_curve_enet, 'y_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', learning_curve_enet, 'out_name')
    wf.connect(best_estimator_enet, 'best_estimator', learning_curve_enet, 'best_estimator')
    wf.connect(learning_curve_enet, 'curve_file', ds_pdf, 'learning_curve_enet')

    def plot_grid_scores_fct(gs_file, data_str):
        import pylab as plt
        import pickle, os
        import pandas as pd
        import numpy as np

        with open(gs_file) as fi:
            gs = pickle.load(fi)

        # build data frame
        names_params = gs[0].parameters.keys()
        c_names = names_params + ['m', 'sd']
        df = pd.DataFrame([], columns=c_names)

        for g in gs:
            data_params = [g.parameters[n] for n in names_params]
            data_m = [np.abs(g.mean_validation_score), g.cv_validation_scores.std()]
            data = data_params + data_m
            df.loc[len(df)] = data

        # plot
        plt.figure(figsize=(5, 4 * len(names_params)))
        for i, p in enumerate(names_params):
            plt.subplot(len(names_params), 1, i + 1)
            x = df[p].values
            y = df['m'].values
            if type(x[0]) is str:
                rep_dict = {}
                for i, o in enumerate(np.unique(x)):
                    rep_dict[o] = i
                x = np.array([rep_dict[o] for o in x])
                x_ticks = rep_dict.keys()
                x_vals = map(rep_dict.get, x_ticks)
                plt.xticks(x_vals, x_ticks, rotation='vertical')
                u_x = x_vals
                u_y = [np.mean(df['m'][df[p] == v]) for v in rep_dict.keys()]
            else:
                u_x = np.unique(x)
                u_y = [np.mean(df['m'][df[p] == v]) for v in u_x]
            plt.scatter(x, y, color='black')
            plt.plot(u_x, u_y)
            plt.scatter(u_x, u_y, marker='+')
            plt.title(p)
            plt.tight_layout()

        fig_file = os.path.join(os.getcwd(), 'gs_plot_' + data_str + '.pdf')
        plt.savefig(fig_file)

        return fig_file

    plot_grid_scores = Node(util.Function(input_names=['gs_file', 'data_str'],
                                          output_names=['fig_file'],
                                          function=plot_grid_scores_fct),
                            name='plot_grid_scores')

    wf.connect(prediction_gs_split, 'gs_file', plot_grid_scores, 'gs_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', plot_grid_scores, 'data_str')
    wf.connect(plot_grid_scores, 'fig_file', ds_pdf, 'gs_grid_score_plots')


    plot_random_grid_scores = Node(util.Function(input_names=['gs_file', 'data_str'],
                                          output_names=['fig_file'],
                                          function=plot_grid_scores_fct),
                            name='plot_random_grid_scores')

    wf.connect(prediction_random_gs_split, 'gs_file', plot_random_grid_scores, 'gs_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', plot_random_grid_scores, 'data_str')
    wf.connect(plot_random_grid_scores, 'fig_file', ds_pdf, 'gs_random_grid_score_plots')


    def plot_validation_curve_fct(X_file, y_file, best_estimator, data_str):
        import pylab as plt
        import pickle, os
        import pandas as pd
        import numpy as np
        from sklearn.learning_curve import validation_curve
        from matplotlib.backends.backend_pdf import PdfPages

        X = np.load(X_file)
        y = np.load(y_file)

        params = {
            'selection__percentile': [70, 75, 80, 85, 90, 95, 99, 100],
            'regression_model__C': [1, 98, 106, 110, 130, 150, 170, 200, 1000, 10000, 14450],
            # [.0001, .001, .01, .1, 1, 10, 20, 30],
            'regression_model__epsilon': [0, .005, .01, .05, .1, 1, 5, 10],
            'regression_model__loss': ['epsilon_insensitive', 'squared_epsilon_insensitive'],
            # 'regression_model__nu': [0.01, .25, .5, .75, .8, .85, .9, .95, .99],
        }

        fig_file = os.path.abspath('validation_curve_' + data_str + '.pdf')
        fig_file_log = os.path.abspath('validation_curve_log' + data_str + '.pdf')

        with PdfPages(fig_file, 'w') as pdf:
            with PdfPages(fig_file_log, 'w') as pdf_log:
                for p in sorted(params.keys()):
                    param_range = params[p]

                    if type(param_range[0]) is not str:
                        train_scores, test_scores = validation_curve(best_estimator, X, y, param_name=p,
                                                                     param_range=param_range,
                                                                     cv=5, n_jobs=5)
                        train_scores_mean = np.mean(train_scores, axis=1)
                        train_scores_std = np.std(train_scores, axis=1)
                        test_scores_mean = np.mean(test_scores, axis=1)
                        test_scores_std = np.std(test_scores, axis=1)
                        # LINEAR AXIS
                        plt.title('Validation Curve')
                        plt.xlabel(p)
                        plt.ylim(0.0, 1.1)
                        plt.plot(param_range, train_scores_mean, label='Training score', color='r')
                        plt.fill_between(param_range, train_scores_mean - train_scores_std,
                                         train_scores_mean + train_scores_std,
                                         alpha=0.2, color='r')
                        plt.plot(param_range, test_scores_mean, label='Cross-validation score', color='g')
                        plt.fill_between(param_range, test_scores_mean - test_scores_std,
                                         test_scores_mean + test_scores_std,
                                         alpha=0.2, color='g')
                        plt.legend(loc='best')
                        pdf.savefig()
                        plt.close()

                        # LOG AXIS
                        plt.title('Validation Curve')
                        plt.xlabel(p)
                        plt.ylim(0.0, 1.1)
                        plt.semilogx(param_range, train_scores_mean, label='Training score', color='r')
                        plt.fill_between(param_range, train_scores_mean - train_scores_std,
                                         train_scores_mean + train_scores_std,
                                         alpha=0.2, color='r')
                        plt.semilogx(param_range, test_scores_mean, label='Cross-validation score', color='g')
                        plt.fill_between(param_range, test_scores_mean - test_scores_std,
                                         test_scores_mean + test_scores_std,
                                         alpha=0.2, color='g')
                        plt.legend(loc='best')
                        pdf_log.savefig()
                        plt.close()

        return fig_file, fig_file_log

    plot_validation_curve = Node(util.Function(input_names=['X_file', 'y_file', 'best_estimator', 'data_str'],
                                               output_names=['fig_file', 'fig_file_log'],
                                               function=plot_validation_curve_fct),
                                 name='plot_validation_curve')
    wf.connect(aggregate_multimodal_metrics, 'X_file', plot_validation_curve, 'X_file')
    wf.connect(get_subjects_info, 'age_file', plot_validation_curve, 'y_file')
    wf.connect(prediction_gs_split, 'best_estimator', plot_validation_curve, 'best_estimator')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', plot_validation_curve, 'data_str')
    wf.connect(plot_validation_curve, 'fig_file', ds_pdf, 'validation_curve.@lin')
    wf.connect(plot_validation_curve, 'fig_file_log', ds_pdf, 'validation_curve.@log')

    def run_pca_fct(X_file, data_str):
        from sklearn.decomposition import PCA
        import numpy as np
        import pylab as plt
        import os

        from sklearn.feature_selection import VarianceThreshold
        from sklearn.grid_search import GridSearchCV
        from sklearn.preprocessing import MinMaxScaler
        from sklearn.preprocessing import Imputer

        X = np.load(X_file)

        # fixme pipe
        imp = Imputer()
        X = imp.fit_transform(X)

        # fixme? pipe
        # remove low variance features
        var_thr = VarianceThreshold()
        X = var_thr.fit_transform(X)


        # fixme pipe normalize
        normalize = MinMaxScaler()
        X = normalize.fit_transform(X)

        # fixme?
        # remove low variance features
        var_thr = VarianceThreshold()
        X = var_thr.fit_transform(X)

        pca = PCA()
        p = pca.fit_transform(X)
        explained_var = sum(pca.explained_variance_ratio_)
        plt.plot(range(1, len(pca.explained_variance_ratio_) + 1), np.cumsum(pca.explained_variance_ratio_))
        plt.title('explained var: %s' % explained_var)
        plt.xlabel('n_components')
        plt.tight_layout()
        out_fig = os.path.join(os.getcwd(), 'pca_var_%s.pdf' % data_str)
        plt.savefig(out_fig)
        return out_fig

    run_pca = Node(util.Function(input_names=['X_file', 'data_str'],
                                 output_names=['out_fig'],
                                 function=run_pca_fct),
                   name='run_pca')

    wf.connect(aggregate_multimodal_metrics, 'X_file', run_pca, 'X_file')
    wf.connect(aggregate_multimodal_metrics, 'multimodal_out_name', run_pca, 'data_str')
    wf.connect(run_pca, 'out_fig', ds_pdf, 'pca')


    #####################################
    # RUN WF
    #####################################
    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def preprocessing_pipeline(cfg):
    import os

    from nipype import config
    from nipype.pipeline.engine import Node, Workflow, JoinNode
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.freesurfer as freesurfer

    # LeiCA modules
    from utils import zip_and_save_running_scripts
    from preprocessing.rsfMRI_preprocessing import create_rsfMRI_preproc_pipeline
    from preprocessing.converter import create_converter_structural_pipeline, create_converter_functional_pipeline, \
        create_converter_diffusion_pipeline
    from sca import create_sca_pipeline

    # INPUT PARAMETERS
    dicom_dir = cfg['dicom_dir']
    working_dir = cfg['working_dir']
    freesurfer_dir = cfg['freesurfer_dir']
    template_dir = cfg['template_dir']
    script_dir = cfg['script_dir']
    ds_dir = cfg['ds_dir']

    subject_id = cfg['subject_id']
    TR_list = cfg['TR_list']

    vols_to_drop = cfg['vols_to_drop']
    rois_list = cfg['rois_list']
    lp_cutoff_freq = cfg['lp_cutoff_freq']
    hp_cutoff_freq = cfg['hp_cutoff_freq']
    use_fs_brainmask = cfg['use_fs_brainmask']

    use_n_procs = cfg['use_n_procs']
    plugin_name = cfg['plugin_name']


    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir)

    wf = Workflow(name='LeiCA_resting')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level = 'DEBUG'), execution={'stop_on_first_crash': True,
                                                                  'remove_unnecessary_outputs': True,
                                                                  'job_finished_timeout': 120})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')


    #####################################
    # SET ITERATORS
    #####################################
    # GET SCAN TR_ID ITERATOR
    scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource')
    scan_infosource.iterables = ('TR_id', TR_list)




    #####################################
    # FETCH MRI DATA
    #####################################
    # GET LATERAL VENTRICLE MASK
    templates_atlases = {'lat_ventricle_mask_MNI': 'cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz'}
    selectfiles_templates = Node(nio.SelectFiles(templates_atlases,
                                                 base_directory=template_dir),
                                 name="selectfiles_templates")

    if not subject_id.startswith('A000'): # releases 1-6 with 01... format subject_id
        # GET FUNCTIONAL DATA
        templates_funct = {'funct_dicom': '{subject_id}/session_1/RfMRI_*_{TR_id}'}

        selectfiles_funct = Node(nio.SelectFiles(templates_funct,
                                                 base_directory=dicom_dir),
                                 name="selectfiles_funct")
        selectfiles_funct.inputs.subject_id = subject_id

        wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id')


        # GET STRUCTURAL DATA
        templates_struct = {'t1w_dicom': '{subject_id}/anat',
                            'dMRI_dicom': '{subject_id}/session_1/DTI_mx_137/*.dcm'} # *.dcm for dMRI as Dcm2nii requires this

        selectfiles_struct = Node(nio.SelectFiles(templates_struct,
                                                  base_directory=dicom_dir),
                                  name="selectfiles_struct")
        selectfiles_struct.inputs.subject_id = subject_id



    else: #startin with release 6 new folder structure
        templates_funct = {'funct_dicom': '*/{subject_id}/*_V2/REST_{TR_id}*/*.dcm'}

        selectfiles_funct = Node(nio.SelectFiles(templates_funct,
                                                 base_directory=dicom_dir),
                                 name="selectfiles_funct")
        selectfiles_funct.inputs.subject_id = subject_id

        wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id')


        # GET STRUCTURAL DATA
        templates_struct = {'t1w_dicom': '*/{subject_id}/*_V2/MPRAGE_SIEMENS_DEFACED*/*.dcm',
                            'dMRI_dicom': '*/{subject_id}/*_V2/DIFF_137_AP*/*.dcm'} # *.dcm for dMRI as Dcm2nii requires this

        selectfiles_struct = Node(nio.SelectFiles(templates_struct,
                                                  base_directory=dicom_dir),
                                  name="selectfiles_struct")
        selectfiles_struct.inputs.subject_id = subject_id



    #####################################
    # COPY RUNNING SCRIPTS
    #####################################
    copy_scripts = Node(util.Function(input_names=['subject_id', 'script_dir'], output_names=['zip_file'], function=zip_and_save_running_scripts), name='copy_scripts')
    copy_scripts.inputs.script_dir = script_dir
    copy_scripts.inputs.subject_id = subject_id
    wf.connect(copy_scripts, 'zip_file', ds, 'scripts')



    #####################################
    # CONVERT DICOMs
    #####################################
    # CONVERT STRUCT 2 NIFTI
    converter_struct = create_converter_structural_pipeline(working_dir, ds_dir, 'converter_struct')
    wf.connect(selectfiles_struct, 't1w_dicom', converter_struct, 'inputnode.t1w_dicom')

    # CONVERT dMRI 2 NIFTI
    converter_dMRI = create_converter_diffusion_pipeline(working_dir, ds_dir, 'converter_dMRI')
    wf.connect(selectfiles_struct, 'dMRI_dicom', converter_dMRI, 'inputnode.dMRI_dicom')


    # CONVERT FUNCT 2 NIFTI
    converter_funct = create_converter_functional_pipeline(working_dir, ds_dir, 'converter_funct')
    wf.connect(selectfiles_funct, 'funct_dicom', converter_funct, 'inputnode.epi_dicom')
    wf.connect(scan_infosource, 'TR_id', converter_funct, 'inputnode.out_format')


    #####################################
    # START RSFMRI PREPROCESSING ANALYSIS
    #####################################
    # rsfMRI PREPROCESSING
    rsfMRI_preproc = create_rsfMRI_preproc_pipeline(working_dir,freesurfer_dir, ds_dir, use_fs_brainmask, 'rsfMRI_preprocessing')
    rsfMRI_preproc.inputs.inputnode.vols_to_drop = vols_to_drop
    rsfMRI_preproc.inputs.inputnode.lp_cutoff_freq = lp_cutoff_freq
    rsfMRI_preproc.inputs.inputnode.hp_cutoff_freq = hp_cutoff_freq
    rsfMRI_preproc.inputs.inputnode.subject_id = subject_id

    wf.connect(converter_struct, 'outputnode.t1w', rsfMRI_preproc, 'inputnode.t1w')
    wf.connect(converter_funct, 'outputnode.epi', rsfMRI_preproc, 'inputnode.epi')
    wf.connect(converter_funct, 'outputnode.TR_ms', rsfMRI_preproc, 'inputnode.TR_ms')
    #wf.connect(subjects_infosource, 'subject_id', rsfMRI_preproc, 'inputnode.subject_id')
    wf.connect(selectfiles_templates, 'lat_ventricle_mask_MNI', rsfMRI_preproc, 'inputnode.lat_ventricle_mask_MNI')





    #####################################
    # SCA
    #####################################

    # sca = create_sca_pipeline(working_dir, rois_list, ds_dir, name='sca')
    # wf.connect(rsfMRI_preproc, 'outputnode.rs_preprocessed', sca, 'inputnode.rs_preprocessed')
    # wf.connect(rsfMRI_preproc, 'outputnode.epi_2_MNI_warp', sca, 'inputnode.epi_2_MNI_warp')

    # if len(subjects_list)>1:
    #     def test_fct(in_files):
    #         print('cxcxcx')
    #         print in_files
    #         out_files = in_files
    #         return out_files
    #
    #     collect_files = JoinNode(util.Function(input_names=['in_files'],
    #                                   output_names=['out_files'],
    #                                   function=test_fct),
    #                            joinsource='subjects_infosource', #'selectfiles_funct',
    #                            joinfield='in_files',
    #                     name='collect_files')
    #     wf.connect(sca, 'outputnode.seed_based_z', collect_files, 'in_files')
    #
    #
    #     collect_sca = Node(fsl.Merge(dimension='t', merged_file='concat_corr_z.nii.gz'),
    #                            joinsource='subjects_infosource', #'selectfiles_funct',
    #                            joinfield='in_files',
    #                            name='collect_sca')
    #     wf.connect(collect_files, 'out_files', collect_sca, 'in_files')
    #
    #     mean_sca = Node(fsl.MeanImage(), name='mean_sca')
    #     wf.connect(collect_sca, 'merged_file', mean_sca, 'in_file')



    #####################################
    # RUN WF
    #####################################
    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
def create_lsd_resting(subject, working_dir, out_dir, freesurfer_dir, data_dir, 
                    echo_space, te_diff, vol_to_remove, scans, epi_resolution,
                    TR, highpass, lowpass):
    
    # main workflow
    func_preproc = Workflow(name='lsd_resting')
    func_preproc.base_dir = working_dir
    func_preproc.config['execution']['crashdump_dir'] = func_preproc.base_dir + "/crash_files"
    
    
    # set fsl output type to nii.gz
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    
    # infosource to iterate over scans
    scan_infosource = Node(util.IdentityInterface(fields=['scan_id']), 
                      name='scan_infosource')
    scan_infosource.iterables=('scan_id', scans)
    
    # function node to get fieldmap information
    def fmap_info(scan_id):
        if scan_id=='rest1a':
            fmap_id='fmap1'
            pe_dir='y-'
        elif scan_id=='rest1b':
            fmap_id='fmap1'
            pe_dir='y'
        elif scan_id=='rest2a':
            fmap_id='fmap2'
            pe_dir='y-'
        elif scan_id=='rest2b':
            fmap_id='fmap2'
            pe_dir='y'
        return fmap_id, pe_dir
    
    fmap_infosource=Node(util.Function(input_names=['scan_id'],
                                       output_names=['fmap_id', 'pe_dir'],
                                       function=fmap_info),
                          name='fmap_infosource')
            
    # select files
    templates={'func': 'nifti/lsd_resting/{scan_id}.nii.gz',
               'fmap_phase' : 'nifti/lsd_resting/{fmap_id}_phase.nii.gz',
               'fmap_mag' : 'nifti/lsd_resting/{fmap_id}_mag.nii.gz',
               'anat_head' : 'preprocessed/anat/T1.nii.gz',
               'anat_brain' : 'preprocessed/anat/T1_brain.nii.gz',
               'func_mask' : 'preprocessed/anat/func_mask.nii.gz',
               }
    selectfiles = Node(nio.SelectFiles(templates,
                                       base_directory=data_dir),
                       name="selectfiles")
    
    
    # node to strip rois
    remove_vol = Node(util.Function(input_names=['in_file','t_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')
    remove_vol.inputs.t_min = vol_to_remove
    
    
    # workflow for motion correction
    moco=create_moco_pipeline()
    
    # workflow for fieldmap correction and coregistration
    fmap_coreg=create_fmap_coreg_pipeline()
    fmap_coreg.inputs.inputnode.fs_subjects_dir=freesurfer_dir
    fmap_coreg.inputs.inputnode.fs_subject_id=subject
    fmap_coreg.inputs.inputnode.echo_space=echo_space
    fmap_coreg.inputs.inputnode.te_diff=te_diff
    
    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()
    transform_ts.inputs.inputnode.resolution=epi_resolution
    
    # workflow to denoise timeseries
    denoise = create_denoise_pipeline()
    denoise.inputs.inputnode.highpass_sigma= 1./(2*TR*highpass)
    denoise.inputs.inputnode.lowpass_sigma= 1./(2*TR*lowpass)
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1205&L=FSL&P=R57592&1=FSL&9=A&I=-3&J=on&d=No+Match%3BMatch%3BMatches&z=4 
    denoise.inputs.inputnode.tr = TR
    
    #sink to store files of single scans
    sink = Node(nio.DataSink(parameterization=False,
                             base_directory=out_dir,
                             substitutions=[('fmap1_phase_fslprepared', 'fieldmap'),
                                            ('fmap2_phase_fslprepared', 'fieldmap'),
                                            ('fieldmap_fslprepared_fieldmap_unmasked_vsm', 'shiftmap'),
                                            ('plot.rest_coregistered', 'outlier_plot'),
                                            ('filter_motion_comp_norm_compcor_art_dmotion', 'nuissance_matrix'),
                                            ('rest_realigned.nii.gz_abs.rms', 'rest_realigned_abs.rms'),
                                            ('rest_realigned.nii.gz.par','rest_realigned.par'),
                                            ('rest_realigned.nii.gz_rel.rms', 'rest_realigned_rel.rms'),
                                            ('rest_realigned.nii.gz_abs_disp', 'abs_displacement_plot'),
                                            ('rest_realigned.nii.gz_rel_disp', 'rel_displacment_plot'),
                                            ('art.rest_coregistered_outliers', 'outliers'),
                                            ('global_intensity.rest_coregistered', 'global_intensity'),
                                            ('norm.rest_coregistered', 'composite_norm'),
                                            ('stats.rest_coregistered', 'stats'),
                                            ('rest_denoised_bandpassed_norm.nii.gz', 'rest_preprocessed.nii.gz')
                                            ]),
                 name='sink')
    
    # connections
    func_preproc.connect([(scan_infosource, selectfiles, [('scan_id', 'scan_id')]),
                          (scan_infosource, fmap_infosource, [('scan_id', 'scan_id')]),
                          (fmap_infosource, selectfiles, [('fmap_id', 'fmap_id')]),
                          (fmap_infosource, fmap_coreg, [('pe_dir', 'inputnode.pe_dir')]),
                          (scan_infosource, sink, [('scan_id', 'container')]),
                          (selectfiles, remove_vol, [('func', 'in_file')]),
                          (remove_vol, moco, [('out_file', 'inputnode.epi')]),
                          (selectfiles, fmap_coreg, [('fmap_phase', 'inputnode.phase'),
                                                     ('fmap_mag', 'inputnode.mag'),
                                                     ('anat_head', 'inputnode.anat_head'),
                                                     ('anat_brain', 'inputnode.anat_brain')
                                                     ]),
                          (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),
                          (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
                          (selectfiles, transform_ts, [('anat_head', 'inputnode.anat_head')]),
                          (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
                          (fmap_coreg, transform_ts, [('outputnode.fmap_fullwarp', 'inputnode.fullwarp')]),
                          (selectfiles, denoise, [('func_mask', 'inputnode.brain_mask'),
                                                  ('anat_brain', 'inputnode.anat_brain')]),
                          (fmap_coreg, denoise, [('outputnode.epi2anat_dat', 'inputnode.epi2anat_dat'),
                                                 ('outputnode.unwarped_mean_epi2fmap', 'inputnode.unwarped_mean')]),
                          (moco, denoise, [('outputnode.par_moco', 'inputnode.moco_par')]),
                          (transform_ts, denoise, [('outputnode.trans_ts','inputnode.epi_coreg')]),
                          (moco, sink, [#('outputnode.epi_moco', 'realign.@realigned_ts'),
                                        ('outputnode.par_moco', 'realign.@par'),
                                        ('outputnode.rms_moco', 'realign.@rms'),
                                        ('outputnode.mat_moco', 'realign.MAT.@mat'),
                                        ('outputnode.epi_mean', 'realign.@mean'),
                                        ('outputnode.rotplot', 'realign.plots.@rotplot'),
                                        ('outputnode.transplot', 'realign.plots.@transplot'),
                                        ('outputnode.dispplots', 'realign.plots.@dispplots'),
                                        ('outputnode.tsnr_file', 'realign.@tsnr')]),
                          (fmap_coreg, sink, [('outputnode.fmap','coregister.transforms2anat.@fmap'),
                                              #('outputnode.unwarpfield_epi2fmap', 'coregister.@unwarpfield_epi2fmap'),
                                              ('outputnode.unwarped_mean_epi2fmap', 'coregister.@unwarped_mean_epi2fmap'),
                                              ('outputnode.epi2fmap', 'coregister.@epi2fmap'),
                                              #('outputnode.shiftmap', 'coregister.@shiftmap'),
                                              ('outputnode.fmap_fullwarp', 'coregister.transforms2anat.@fmap_fullwarp'),
                                              ('outputnode.epi2anat', 'coregister.@epi2anat'),
                                              ('outputnode.epi2anat_mat', 'coregister.transforms2anat.@epi2anat_mat'),
                                              ('outputnode.epi2anat_dat', 'coregister.transforms2anat.@epi2anat_dat'),
                                              ('outputnode.epi2anat_mincost', 'coregister.@epi2anat_mincost')
                                              ]),
                          (transform_ts, sink, [#('outputnode.trans_ts', 'coregister.@full_transform_ts'),
                                                ('outputnode.trans_ts_mean', 'coregister.@full_transform_mean'),
                                                ('outputnode.resamp_brain', 'coregister.@resamp_brain')]),
                          (denoise, sink, [('outputnode.wmcsf_mask', 'denoise.mask.@wmcsf_masks'),
                                           ('outputnode.combined_motion','denoise.artefact.@combined_motion'),
                                           ('outputnode.outlier_files','denoise.artefact.@outlier'),
                                           ('outputnode.intensity_files','denoise.artefact.@intensity'),
                                           ('outputnode.outlier_stats','denoise.artefact.@outlierstats'),
                                           ('outputnode.outlier_plots','denoise.artefact.@outlierplots'),
                                           ('outputnode.mc_regressor', 'denoise.regress.@mc_regressor'),
                                           ('outputnode.comp_regressor', 'denoise.regress.@comp_regressor'),
                                           ('outputnode.mc_F', 'denoise.regress.@mc_F'),
                                           ('outputnode.mc_pF', 'denoise.regress.@mc_pF'),
                                           ('outputnode.comp_F', 'denoise.regress.@comp_F'),
                                           ('outputnode.comp_pF', 'denoise.regress.@comp_pF'),
                                           ('outputnode.brain_mask_resamp', 'denoise.mask.@brain_resamp'),
                                           ('outputnode.brain_mask2epi', 'denoise.mask.@brain_mask2epi'),
                                           ('outputnode.normalized_file', '@normalized')
                                           ])
                          ])
    
    #joinnode for concatenation
#     concatenate=JoinNode(fsl.Merge(dimension='t',
#                                    merged_file='rest_preprocessed_concat.nii.gz'),
#                                joinsource='scan_infosource',
#                                joinfield='in_files',
#                                name='concatenate')
#     #concatenate.plugin_args={'submit_specs': 'request_memory = 20000'}
#        
#     concat_sink=Node(nio.DataSink(parameterization=False,
#                                   base_directory=out_dir),
#                      name='concat_sink')
#        
#        
#     func_preproc.connect([(denoise, concatenate, [('outputnode.normalized_file', 'in_files')]),
#                           (concatenate, concat_sink, [('merged_file', '@rest_concat')])
#                           ])
        
    
    #func_preproc.write_graph(dotfilename='func_preproc.dot', graph2use='colored', format='pdf', simple_form=True)
    func_preproc.run()
    #func_preproc.run(plugin='CondorDAGMan')
    #func_preproc.run(plugin='MultiProc')
Пример #26
0
working_dir = "/scr/ilz3/myelinconnect/working_dir/mappings_fixhdr/"
data_dir = "/scr/ilz3/myelinconnect/"
out_dir = "/scr/ilz3/myelinconnect/transformations/"

# set fsl output type to nii.gz
fsl.FSLCommand.set_default_output_type("NIFTI_GZ")


# main workflow
mappings = Workflow(name="mappings")
mappings.base_dir = working_dir
mappings.config["execution"]["crashdump_dir"] = mappings.base_dir + "/crash_files"

# iterate over subjects
subject_infosource = Node(util.IdentityInterface(fields=["subject"]), name="subject_infosource")
subject_infosource.iterables = [("subject", subjects_db)]

# iterate over sessions
session_infosource = Node(util.IdentityInterface(fields=["session"]), name="session_infosource")
session_infosource.iterables = [("session", sessions)]

# select files
templates = {
    "median": "resting/preprocessed/{subject}/{session}/realignment/corr_{subject}_{session}_roi_detrended_median_corrected.nii.gz",
    "median_mapping": "mappings/rest/fixed_hdr/corr_{subject}_{session}_*mapping_fixed.nii.gz",
    #'t1_mapping': 'mappings/t1/{subject}*T1_Images_merged_mapping.nii.gz',
    "t1_highres": "struct/t1/{subject}*T1_Images_merged.nii.gz",
    "epi2highres_lin_itk": "resting/preprocessed/{subject}/{session}/registration/epi2highres_lin.txt",
    "epi2highres_warp": "resting/preprocessed/{subject}/{session}/registration/transform0Warp.nii.gz",
    "epi2highres_invwarp": "resting/preprocessed/{subject}/{session}/registration/transform0InverseWarp.nii.gz",
    #'t1_prep_rh' : 'struct/surf_rh/prep_t1/smooth_1.5/{subject}_rh_mid_T1_avg_smoothdata_data.nii.gz',
Пример #27
0
background = Node(JistIntensityMp2rageMasking(outMasked=True,
                                        outMasked2=True,
                                        outSignal2=True), 
                  name='background')

# skullstrip
strip = Node(MedicAlgorithmSPECTRE2010(outStripped=True,
                                       outMask=True,
                                       outOriginal=True,
                                       inOutput='true',
                                       inFind='true',
                                       #maxMemoryUsage = 6000,
                                       #inMMC=4
                                       ), 
             name='strip')
strip.iterables=('inMMC',[2,4])

# connections
mp2rage.connect([(inputnode, background, [('inv2', 'inSecond'),
                                          ('t1map', 'inQuantitative'),
                                          ('uni', 'inT1weighted')]),
                 (background, strip, [('outMasked2','inInput')]),
                 (background, outputnode, [('outMasked2','uni_masked'),
                                           ('outMasked','t1map_masked'),
                                           ('outSignal2','background_mask')]),
                 (strip, outputnode, [('outStripped','uni_stripped'),
                                      ('outMask', 'skullstrip_mask'),
                                      ('outOriginal','uni_reoriented')])
                 ])

Пример #28
0
def preprocessing_pipeline(cfg):
    import os

    from nipype import config
    from nipype.pipeline.engine import Node, Workflow
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.freesurfer as freesurfer

    # LeiCA modules
    from utils import zip_and_save_running_scripts
    from preprocessing.rsfMRI_preprocessing import create_rsfMRI_preproc_pipeline
    from preprocessing.converter import create_converter_structural_pipeline, create_converter_functional_pipeline, \
        create_converter_diffusion_pipeline

    # INPUT PARAMETERS
    dicom_dir = cfg['dicom_dir']
    working_dir = cfg['working_dir']
    freesurfer_dir = cfg['freesurfer_dir']
    template_dir = cfg['template_dir']
    script_dir = cfg['script_dir']
    ds_dir = cfg['ds_dir']

    subject_id = cfg['subject_id']
    TR_list = cfg['TR_list']

    vols_to_drop = cfg['vols_to_drop']
    lp_cutoff_freq = cfg['lp_cutoff_freq']
    hp_cutoff_freq = cfg['hp_cutoff_freq']
    use_fs_brainmask = cfg['use_fs_brainmask']

    use_n_procs = cfg['use_n_procs']
    plugin_name = cfg['plugin_name']

    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir)

    wf = Workflow(name='LeiCA_resting')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'),
                      execution={
                          'stop_on_first_crash': True,
                          'remove_unnecessary_outputs': True,
                          'job_finished_timeout': 120
                      })
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(
        working_dir, 'crash')

    ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')

    #####################################
    # SET ITERATORS
    #####################################
    # GET SCAN TR_ID ITERATOR
    scan_infosource = Node(util.IdentityInterface(fields=['TR_id']),
                           name='scan_infosource')
    scan_infosource.iterables = ('TR_id', TR_list)

    #####################################
    # FETCH MRI DATA
    #####################################
    # GET LATERAL VENTRICLE MASK
    templates_atlases = {
        'lat_ventricle_mask_MNI':
        'cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz'
    }
    selectfiles_templates = Node(nio.SelectFiles(templates_atlases,
                                                 base_directory=template_dir),
                                 name="selectfiles_templates")

    if not True:  # releases 1-6 with 01... format subject_id
        # GET FUNCTIONAL DATA
        templates_funct = {
            'funct_dicom': '{subject_id}/session_1/RfMRI_*_{TR_id}'
        }

        selectfiles_funct = Node(nio.SelectFiles(templates_funct,
                                                 base_directory=dicom_dir),
                                 name="selectfiles_funct")
        selectfiles_funct.inputs.subject_id = subject_id

        wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id')

        # GET STRUCTURAL DATA
        templates_struct = {
            't1w_dicom': '{subject_id}/anat',
            'dMRI_dicom': '{subject_id}/session_1/DTI_mx_137/*.dcm'
        }  # *.dcm for dMRI as Dcm2nii requires this

        selectfiles_struct = Node(nio.SelectFiles(templates_struct,
                                                  base_directory=dicom_dir),
                                  name="selectfiles_struct")
        selectfiles_struct.inputs.subject_id = subject_id

    else:  #startin with release 6 new folder structure
        templates_funct = {
            'funct_dicom': '*/{subject_id}/*_V2/REST_{TR_id}*/*.dcm'
        }

        selectfiles_funct = Node(nio.SelectFiles(templates_funct,
                                                 base_directory=dicom_dir),
                                 name="selectfiles_funct")
        selectfiles_funct.inputs.subject_id = subject_id

        wf.connect(scan_infosource, 'TR_id', selectfiles_funct, 'TR_id')

        # GET STRUCTURAL DATA
        templates_struct = {
            't1w_dicom': '*/{subject_id}/*_V2/MPRAGE_SIEMENS_DEFACED*/*.dcm',
            'dMRI_dicom': '*/{subject_id}/*_V2/DIFF_137_AP*/*.dcm'
        }  # *.dcm for dMRI as Dcm2nii requires this

        selectfiles_struct = Node(nio.SelectFiles(templates_struct,
                                                  base_directory=dicom_dir),
                                  name="selectfiles_struct")
        selectfiles_struct.inputs.subject_id = subject_id

    #####################################
    # COPY RUNNING SCRIPTS
    #####################################
    copy_scripts = Node(util.Function(input_names=['subject_id', 'script_dir'],
                                      output_names=['zip_file'],
                                      function=zip_and_save_running_scripts),
                        name='copy_scripts')
    copy_scripts.inputs.script_dir = script_dir
    copy_scripts.inputs.subject_id = subject_id
    wf.connect(copy_scripts, 'zip_file', ds, 'scripts')

    #####################################
    # CONVERT DICOMs
    #####################################
    # CONVERT STRUCT 2 NIFTI
    converter_struct = create_converter_structural_pipeline(
        working_dir, ds_dir, 'converter_struct')
    wf.connect(selectfiles_struct, 't1w_dicom', converter_struct,
               'inputnode.t1w_dicom')

    # CONVERT dMRI 2 NIFTI
    converter_dMRI = create_converter_diffusion_pipeline(
        working_dir, ds_dir, 'converter_dMRI')
    wf.connect(selectfiles_struct, 'dMRI_dicom', converter_dMRI,
               'inputnode.dMRI_dicom')

    # CONVERT FUNCT 2 NIFTI
    converter_funct = create_converter_functional_pipeline(
        working_dir, ds_dir, 'converter_funct')
    wf.connect(selectfiles_funct, 'funct_dicom', converter_funct,
               'inputnode.epi_dicom')
    wf.connect(scan_infosource, 'TR_id', converter_funct,
               'inputnode.out_format')

    #####################################
    # START RSFMRI PREPROCESSING ANALYSIS
    #####################################
    # rsfMRI PREPROCESSING
    rsfMRI_preproc = create_rsfMRI_preproc_pipeline(working_dir,
                                                    freesurfer_dir, ds_dir,
                                                    use_fs_brainmask,
                                                    'rsfMRI_preprocessing')
    rsfMRI_preproc.inputs.inputnode.vols_to_drop = vols_to_drop
    rsfMRI_preproc.inputs.inputnode.lp_cutoff_freq = lp_cutoff_freq
    rsfMRI_preproc.inputs.inputnode.hp_cutoff_freq = hp_cutoff_freq
    rsfMRI_preproc.inputs.inputnode.subject_id = subject_id

    wf.connect(converter_struct, 'outputnode.t1w', rsfMRI_preproc,
               'inputnode.t1w')
    wf.connect(converter_funct, 'outputnode.epi', rsfMRI_preproc,
               'inputnode.epi')
    wf.connect(converter_funct, 'outputnode.TR_ms', rsfMRI_preproc,
               'inputnode.TR_ms')
    wf.connect(selectfiles_templates, 'lat_ventricle_mask_MNI', rsfMRI_preproc,
               'inputnode.lat_ventricle_mask_MNI')

    #####################################
    # RUN WF
    #####################################
    wf.write_graph(dotfilename=wf.name, graph2use='colored',
                   format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
Пример #29
0
def calc_local_metrics(cfg):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow, MapNode
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.freesurfer as freesurfer

    import CPAC.alff.alff as cpac_alff
    import CPAC.reho.reho as cpac_reho
    import CPAC.utils.utils as cpac_utils
    import CPAC.vmhc.vmhc as cpac_vmhc
    import CPAC.registration.registration as cpac_registration
    import CPAC.network_centrality.z_score as cpac_centrality_z_score

    import utils as calc_metrics_utils


    # INPUT PARAMETERS
    dicom_dir = cfg['dicom_dir']
    preprocessed_data_dir = cfg['preprocessed_data_dir']

    working_dir = cfg['working_dir']
    freesurfer_dir = cfg['freesurfer_dir']
    template_dir = cfg['template_dir']
    script_dir = cfg['script_dir']
    ds_dir = cfg['ds_dir']

    subject_id = cfg['subject_id']
    TR_list = cfg['TR_list']

    vols_to_drop = cfg['vols_to_drop']
    rois_list = cfg['rois_list']
    lp_cutoff_freq = cfg['lp_cutoff_freq']
    hp_cutoff_freq = cfg['hp_cutoff_freq']
    use_fs_brainmask = cfg['use_fs_brainmask']

    use_n_procs = cfg['use_n_procs']
    plugin_name = cfg['plugin_name']



    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir)

    wf = Workflow(name='LeiCA_metrics')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True,
                                                                       'remove_unnecessary_outputs': True,
                                                                       'job_finished_timeout': 120})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')
    ds.inputs.substitutions = [('_TR_id_', 'TR_')]
    ds.inputs.regexp_substitutions = [('_variabilty_MNIspace_3mm[0-9]*/', ''), ('_z_score[0-9]*/', '')]


    #####################################
    # SET ITERATORS
    #####################################
    # GET SCAN TR_ID ITERATOR
    scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource')
    scan_infosource.iterables = ('TR_id', TR_list)



    # get atlas data
    templates_atlases = {  # 'GM_mask_MNI_2mm': 'SPM_GM/SPM_GM_mask_2mm.nii.gz',
                           # 'GM_mask_MNI_3mm': 'SPM_GM/SPM_GM_mask_3mm.nii.gz',
                           'FSL_MNI_3mm_template': 'MNI152_T1_3mm_brain.nii.gz',
                           'vmhc_symm_brain': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_symmetric.nii.gz',
                           'vmhc_symm_brain_3mm': 'cpac_image_resources/symmetric/MNI152_T1_3mm_brain_symmetric.nii.gz',
                           'vmhc_symm_skull': 'cpac_image_resources/symmetric/MNI152_T1_2mm_symmetric.nii.gz',
                           'vmhc_symm_brain_mask_dil': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz',
                           'vmhc_config_file_2mm': 'cpac_image_resources/symmetric/T1_2_MNI152_2mm_symmetric.cnf'
                           }

    selectfiles_anat_templates = Node(nio.SelectFiles(templates_atlases,
                                                      base_directory=template_dir),
                                      name="selectfiles_anat_templates")


    # GET SUBJECT SPECIFIC FUNCTIONAL AND STRUCTURAL DATA
    selectfiles_templates = {
        'epi_2_MNI_warp': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_MNI_warp/TR_{TR_id}/*.nii.gz',
        'epi_mask': '{subject_id}/rsfMRI_preprocessing/masks/brain_mask_epiSpace/TR_{TR_id}/*.nii.gz',
        'preproc_epi_full_spectrum': '{subject_id}/rsfMRI_preprocessing/epis/01_denoised/TR_{TR_id}/*.nii.gz',
        'preproc_epi_bp': '{subject_id}/rsfMRI_preprocessing/epis/02_denoised_BP/TR_{TR_id}/*.nii.gz',
        'preproc_epi_bp_tNorm': '{subject_id}/rsfMRI_preprocessing/epis/03_denoised_BP_tNorm/TR_{TR_id}/*.nii.gz',
        'epi_2_struct_mat': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_struct_mat/TR_{TR_id}/*.mat',
        't1w': '{subject_id}/raw_niftis/sMRI/t1w_reoriented.nii.gz',
        't1w_brain': '{subject_id}/rsfMRI_preprocessing/struct_prep/t1w_brain/t1w_reoriented_maths.nii.gz',
    }

    selectfiles = Node(nio.SelectFiles(selectfiles_templates,
                                       base_directory=preprocessed_data_dir),
                       name="selectfiles")
    wf.connect(scan_infosource, 'TR_id', selectfiles, 'TR_id')
    selectfiles.inputs.subject_id = subject_id



    # CREATE TRANSFORMATIONS
    # creat MNI 2 epi warp
    MNI_2_epi_warp = Node(fsl.InvWarp(), name='MNI_2_epi_warp')
    MNI_2_epi_warp.inputs.reference = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz')
    wf.connect(selectfiles, 'epi_mask', MNI_2_epi_warp, 'reference')
    wf.connect(selectfiles, 'epi_2_MNI_warp', MNI_2_epi_warp, 'warp')


    # # CREATE GM MASK IN EPI SPACE
    # GM_mask_epiSpace = Node(fsl.ApplyWarp(), name='GM_mask_epiSpace')
    # GM_mask_epiSpace.inputs.out_file = 'GM_mask_epiSpace.nii.gz'
    #
    # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_2mm', GM_mask_epiSpace, 'in_file')
    # wf.connect(selectfiles, 'epi_mask', GM_mask_epiSpace, 'ref_file')
    # wf.connect(MNI_2_epi_warp, 'inverse_warp', GM_mask_epiSpace, 'field_file')
    # wf.connect(GM_mask_epiSpace, 'out_file', ds, 'GM_mask_epiSpace')



    # fixme
    # # CREATE TS IN MNI SPACE
    # # is it ok to apply the 2mm warpfield to the 3mm template?
    # # seems ok: https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind0904&L=FSL&P=R14011&1=FSL&9=A&J=on&d=No+Match%3BMatch%3BMatches&z=4
    # epi_bp_MNIspace_3mm = Node(fsl.ApplyWarp(), name='epi_bp_MNIspace_3mm')
    # epi_bp_MNIspace_3mm.inputs.interp = 'spline'
    # epi_bp_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'}
    # wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', epi_bp_MNIspace_3mm, 'ref_file')
    # wf.connect(selectfiles, 'preproc_epi_bp', epi_bp_MNIspace_3mm, 'in_file')
    # wf.connect(selectfiles, 'epi_2_MNI_warp', epi_bp_MNIspace_3mm, 'field_file')


    # CREATE EPI MASK IN MNI SPACE
    epi_mask_MNIspace_3mm = Node(fsl.ApplyWarp(), name='epi_mask_MNIspace_3mm')
    epi_mask_MNIspace_3mm.inputs.interp = 'nn'
    epi_mask_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'}
    wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', epi_mask_MNIspace_3mm, 'ref_file')
    wf.connect(selectfiles, 'epi_mask', epi_mask_MNIspace_3mm, 'in_file')
    wf.connect(selectfiles, 'epi_2_MNI_warp', epi_mask_MNIspace_3mm, 'field_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', ds, 'epi_mask_MNIspace_3mm')


    #####################
    # CALCULATE METRICS
    #####################

    # f/ALFF
    alff = cpac_alff.create_alff('alff')
    alff.inputs.hp_input.hp = 0.01
    alff.inputs.lp_input.lp = 0.1
    wf.connect(selectfiles, 'preproc_epi_full_spectrum', alff, 'inputspec.rest_res')
    # wf.connect(GM_mask_epiSpace, 'out_file', alff, 'inputspec.rest_mask')
    wf.connect(selectfiles, 'epi_mask', alff, 'inputspec.rest_mask')
    wf.connect(alff, 'outputspec.alff_img', ds, 'alff.alff')
    wf.connect(alff, 'outputspec.falff_img', ds, 'alff.falff')



    # f/ALFF 2 MNI
    # fixme spline or default?
    alff_MNIspace_3mm = Node(fsl.ApplyWarp(), name='alff_MNIspace_3mm')
    alff_MNIspace_3mm.inputs.interp = 'spline'
    alff_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'}
    wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', alff_MNIspace_3mm, 'ref_file')
    wf.connect(alff, 'outputspec.alff_img', alff_MNIspace_3mm, 'in_file')
    wf.connect(selectfiles, 'epi_2_MNI_warp', alff_MNIspace_3mm, 'field_file')
    wf.connect(alff_MNIspace_3mm, 'out_file', ds, 'alff.alff_MNI_3mm')

    falff_MNIspace_3mm = Node(fsl.ApplyWarp(), name='falff_MNIspace_3mm')
    falff_MNIspace_3mm.inputs.interp = 'spline'
    falff_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'}
    wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', falff_MNIspace_3mm, 'ref_file')
    wf.connect(alff, 'outputspec.falff_img', falff_MNIspace_3mm, 'in_file')
    wf.connect(selectfiles, 'epi_2_MNI_warp', falff_MNIspace_3mm, 'field_file')
    wf.connect(falff_MNIspace_3mm, 'out_file', ds, 'alff.falff_MNI_3mm')



    # f/ALFF_MNI Z-SCORE
    alff_MNIspace_3mm_Z = cpac_utils.get_zscore(input_name='alff_MNIspace_3mm', wf_name='alff_MNIspace_3mm_Z')
    wf.connect(alff_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_Z, 'inputspec.input_file')
    # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', alff_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(alff_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'alff.alff_MNI_3mm_Z')

    falff_MNIspace_3mm_Z = cpac_utils.get_zscore(input_name='falff_MNIspace_3mm', wf_name='falff_MNIspace_3mm_Z')
    wf.connect(falff_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_Z, 'inputspec.input_file')
    # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', falff_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(falff_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'alff.falff_MNI_3mm_Z')


    # f/ALFF_MNI STANDARDIZE BY MEAN
    alff_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean(
        wf_name='alff_MNIspace_3mm_standardized_mean')
    wf.connect(alff_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_standardized_mean, 'inputnode.in_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', alff_MNIspace_3mm_standardized_mean, 'inputnode.mask_file')
    wf.connect(alff_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'alff.alff_MNI_3mm_standardized_mean')

    falff_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean(
        wf_name='falff_MNIspace_3mm_standardized_mean')
    wf.connect(falff_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_standardized_mean, 'inputnode.in_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', falff_MNIspace_3mm_standardized_mean, 'inputnode.mask_file')
    wf.connect(falff_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'alff.falff_MNI_3mm_standardized_mean')





    # REHO
    reho = cpac_reho.create_reho()
    reho.inputs.inputspec.cluster_size = 27
    wf.connect(selectfiles, 'preproc_epi_bp', reho, 'inputspec.rest_res_filt')
    # wf.connect(GM_mask_epiSpace, 'out_file', reho, 'inputspec.rest_mask')
    wf.connect(selectfiles, 'epi_mask', reho, 'inputspec.rest_mask')
    wf.connect(reho, 'outputspec.raw_reho_map', ds, 'reho.reho')



    # REHO 2 MNI
    # fixme spline or default?
    reho_MNIspace_3mm = Node(fsl.ApplyWarp(), name='reho_MNIspace_3mm')
    reho_MNIspace_3mm.inputs.interp = 'spline'
    reho_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'}
    wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', reho_MNIspace_3mm, 'ref_file')
    wf.connect(reho, 'outputspec.raw_reho_map', reho_MNIspace_3mm, 'in_file')
    wf.connect(selectfiles, 'epi_2_MNI_warp', reho_MNIspace_3mm, 'field_file')
    wf.connect(reho_MNIspace_3mm, 'out_file', ds, 'reho.reho_MNI_3mm')



    # REHO_MNI Z-SCORE
    reho_MNIspace_3mm_Z = cpac_utils.get_zscore(input_name='reho_MNIspace_3mm', wf_name='reho_MNIspace_3mm_Z')
    wf.connect(alff_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_Z, 'inputspec.input_file')
    # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', reho_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(reho_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'reho.reho_MNI_3mm_Z')



    # REHO_MNI STANDARDIZE BY MEAN
    reho_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean(
        wf_name='reho_MNIspace_3mm_standardized_mean')
    wf.connect(reho_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_standardized_mean, 'inputnode.in_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', reho_MNIspace_3mm_standardized_mean, 'inputnode.mask_file')
    wf.connect(reho_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds, 'reho.reho_MNI_3mm_standardized_mean')



    # VMHC
    # create registration to symmetrical MNI template
    struct_2_MNI_symm = cpac_registration.create_nonlinear_register(name='struct_2_MNI_symm')
    wf.connect(selectfiles_anat_templates, 'vmhc_config_file_2mm', struct_2_MNI_symm, 'inputspec.fnirt_config')
    wf.connect(selectfiles_anat_templates, 'vmhc_symm_brain', struct_2_MNI_symm, 'inputspec.reference_brain')
    wf.connect(selectfiles_anat_templates, 'vmhc_symm_skull', struct_2_MNI_symm, 'inputspec.reference_skull')
    wf.connect(selectfiles_anat_templates, 'vmhc_symm_brain_mask_dil', struct_2_MNI_symm, 'inputspec.ref_mask')
    wf.connect(selectfiles, 't1w', struct_2_MNI_symm, 'inputspec.input_skull')
    wf.connect(selectfiles, 't1w_brain', struct_2_MNI_symm, 'inputspec.input_brain')

    wf.connect(struct_2_MNI_symm, 'outputspec.output_brain', ds, 'vmhc.symm_reg.@output_brain')
    wf.connect(struct_2_MNI_symm, 'outputspec.linear_xfm', ds, 'vmhc.symm_reg.@linear_xfm')
    wf.connect(struct_2_MNI_symm, 'outputspec.invlinear_xfm', ds, 'vmhc.symm_reg.@invlinear_xfm')
    wf.connect(struct_2_MNI_symm, 'outputspec.nonlinear_xfm', ds, 'vmhc.symm_reg.@nonlinear_xfm')



    # fixme
    vmhc = cpac_vmhc.create_vmhc(use_ants=False, name='vmhc')
    vmhc.inputs.fwhm_input.fwhm = 4
    wf.connect(selectfiles_anat_templates, 'vmhc_symm_brain_3mm', vmhc, 'inputspec.standard_for_func')
    wf.connect(selectfiles, 'preproc_epi_bp_tNorm', vmhc, 'inputspec.rest_res')
    wf.connect(selectfiles, 'epi_2_struct_mat', vmhc, 'inputspec.example_func2highres_mat')
    wf.connect(struct_2_MNI_symm, 'outputspec.nonlinear_xfm', vmhc, 'inputspec.fnirt_nonlinear_warp')
    # wf.connect(GM_mask_epiSpace, 'out_file', vmhc, 'inputspec.rest_mask')
    wf.connect(selectfiles, 'epi_mask', vmhc, 'inputspec.rest_mask')

    wf.connect(vmhc, 'outputspec.rest_res_2symmstandard', ds, 'vmhc.rest_res_2symmstandard')
    wf.connect(vmhc, 'outputspec.VMHC_FWHM_img', ds, 'vmhc.VMHC_FWHM_img')
    wf.connect(vmhc, 'outputspec.VMHC_Z_FWHM_img', ds, 'vmhc.VMHC_Z_FWHM_img')
    wf.connect(vmhc, 'outputspec.VMHC_Z_stat_FWHM_img', ds, 'vmhc.VMHC_Z_stat_FWHM_img')



    # VARIABILITY SCORES
    variability = Node(util.Function(input_names=['in_file'],
                                     output_names=['out_file_list'],
                                     function=calc_metrics_utils.calc_variability),
                       name='variability')
    wf.connect(selectfiles, 'preproc_epi_bp', variability, 'in_file')
    wf.connect(variability, 'out_file_list', ds, 'variability.subjectSpace.@out_files')


    # #fixme spline?
    variabilty_MNIspace_3mm = MapNode(fsl.ApplyWarp(), iterfield=['in_file'], name='variabilty_MNIspace_3mm')
    variabilty_MNIspace_3mm.inputs.interp = 'spline'
    variabilty_MNIspace_3mm.plugin_args = {'submit_specs': 'request_memory = 4000'}
    wf.connect(selectfiles_anat_templates, 'FSL_MNI_3mm_template', variabilty_MNIspace_3mm, 'ref_file')
    wf.connect(selectfiles, 'epi_2_MNI_warp', variabilty_MNIspace_3mm, 'field_file')
    wf.connect(variability, 'out_file_list', variabilty_MNIspace_3mm, 'in_file')
    wf.connect(variabilty_MNIspace_3mm, 'out_file', ds, 'variability.MNI_3mm.@out_file')


    # CALC Z SCORE
    variabilty_MNIspace_3mm_Z = cpac_centrality_z_score.get_cent_zscore(wf_name='variabilty_MNIspace_3mm_Z')
    wf.connect(variabilty_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_Z, 'inputspec.input_file')
    # wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', variabilty_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_Z, 'inputspec.mask_file')
    wf.connect(variabilty_MNIspace_3mm_Z, 'outputspec.z_score_img', ds, 'variability.MNI_3mm_Z.@out_file')



    # STANDARDIZE BY MEAN
    variabilty_MNIspace_3mm_standardized_mean = calc_metrics_utils.standardize_divide_by_mean(
        wf_name='variabilty_MNIspace_3mm_standardized_mean')
    wf.connect(variabilty_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_standardized_mean, 'inputnode.in_file')
    wf.connect(epi_mask_MNIspace_3mm, 'out_file', variabilty_MNIspace_3mm_standardized_mean, 'inputnode.mask_file')
    wf.connect(variabilty_MNIspace_3mm_standardized_mean, 'outputnode.out_file', ds,
               'variability.MNI_3mm_standardized_mean.@out_file')

    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
Пример #30
0
from variables_AFNI import data_dir, work_dir, subject_list, plugin, plugin_args

import nibabel as nb



Afni_workflow = Workflow(name="Afni_volreg_workflow")

Afni_workflow.base_dir = work_dir


from nipype import SelectFiles
templates = dict(epi="*_{subject_id}_*/rfMRI_REST_{pe_dir}_BIC_v2/*_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), ("pe_dir", ["LR", "RL"])]



from nipype.interfaces.afni import Volreg
volreg_motion = MapNode(Volreg(), name="Afni_Motion_Correction", iterfield="in_file")
volreg_motion.inputs.args = '-Fourier -twopass'
volreg_motion.inputs.zpad = 1
#volreg_motion.inputs.basefile = "in_file"
volreg_motion.inputs.outputtype = "NIFTI_GZ"
volreg_motion.inputs.verbose = True
volreg_motion.inputs.out_file = "afni_test"
volreg_motion.inputs.oned_file = "S0799AAW_P126317_6_7_00001"
volreg_motion.inputs.oned_matrix_save = "S0799AAW_P126317_6_7_00001"

Пример #31
0
    def create(self):  # , **kwargs):
        """ Create the nodes and connections for the workflow """

        # Preamble
        csvReader = CSVReader()
        csvReader.inputs.in_file = self.csv_file.default_value
        csvReader.inputs.header = self.hasHeader.default_value
        csvOut = csvReader.run()

        print(("=" * 80))
        print((csvOut.outputs.__dict__))
        print(("=" * 80))

        iters = OrderedDict()
        label = list(csvOut.outputs.__dict__.keys())[0]
        result = eval("csvOut.outputs.{0}".format(label))
        iters["tests"], iters["trains"] = sample_crossvalidation_set(
            result, self.sample_size.default_value
        )
        # Main event
        out_fields = ["T1", "T2", "Label", "trainindex", "testindex"]
        inputsND = Node(
            interface=IdentityInterface(fields=out_fields),
            run_without_submitting=True,
            name="inputs",
        )
        inputsND.iterables = [
            ("trainindex", iters["trains"]),
            ("testindex", iters["tests"]),
        ]
        if not self.hasHeader.default_value:
            inputsND.inputs.T1 = csvOut.outputs.column_0
            inputsND.inputs.Label = csvOut.outputs.column_1
            inputsND.inputs.T2 = csvOut.outputs.column_2
        else:
            inputsND.inputs.T1 = csvOut.outputs.__dict__["t1"]
            inputsND.inputs.Label = csvOut.outputs.__dict__["label"]
            inputsND.inputs.T2 = csvOut.outputs.__dict__["t2"]
            pass  # TODO
        metaflow = Workflow(name="metaflow")
        metaflow.config["execution"] = {
            "plugin": "Linear",
            "stop_on_first_crash": "false",
            "stop_on_first_rerun": "false",
            # This stops at first attempt to rerun, before running, and before deleting previous results.
            "hash_method": "timestamp",
            "single_thread_matlab": "true",  # Multi-core 2011a  multi-core for matrix multiplication.
            "remove_unnecessary_outputs": "true",
            "use_relative_paths": "false",  # relative paths should be on, require hash update when changed.
            "remove_node_directories": "false",  # Experimental
            "local_hash_check": "false",
        }

        metaflow.add_nodes([inputsND])
        """import pdb; pdb.set_trace()"""
        fusionflow = FusionLabelWorkflow()
        self.connect(
            [
                (
                    metaflow,
                    fusionflow,
                    [
                        ("inputs.trainindex", "trainT1s.index"),
                        ("inputs.T1", "trainT1s.inlist"),
                    ],
                ),
                (
                    metaflow,
                    fusionflow,
                    [
                        ("inputs.trainindex", "trainLabels.index"),
                        ("inputs.Label", "trainLabels.inlist"),
                    ],
                ),
                (
                    metaflow,
                    fusionflow,
                    [
                        ("inputs.testindex", "testT1s.index"),
                        ("inputs.T1", "testT1s.inlist"),
                    ],
                ),
            ]
        )
Пример #32
0
def calc_local_metrics(brain_mask,
                       preprocessed_data_dir,
                       subject_id,
                       parcellations_dict,
                       bp_freq_list,
                       TR,
                       selectfiles_templates,
                       working_dir,
                       ds_dir,
                       use_n_procs,
                       plugin_name):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow, MapNode
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl
    from nipype.interfaces.freesurfer.preprocess import MRIConvert

    import CPAC.alff.alff as cpac_alff
    import CPAC.reho.reho as cpac_reho
    import CPAC.utils.utils as cpac_utils

    import utils as calc_metrics_utils
    from motion import calculate_FD_P, calculate_FD_J





    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')

    wf = Workflow(name='LeiCA_LIFE_metrics')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True,
                                                                       'remove_unnecessary_outputs': True,
                                                                       'job_finished_timeout': 15})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')
    ds.inputs.regexp_substitutions = [('MNI_resampled_brain_mask_calc.nii.gz', 'falff.nii.gz'),
                                      ('residual_filtered_3dT.nii.gz', 'alff.nii.gz'),
                                      ('_parcellation_', ''),
                                      ('_bp_freqs_', 'bp_'),
                                      ]



    #####################
    # ITERATORS
    #####################
    # PARCELLATION ITERATOR
    parcellation_infosource = Node(util.IdentityInterface(fields=['parcellation']), name='parcellation_infosource')
    parcellation_infosource.iterables = ('parcellation', parcellations_dict.keys())

    # BP FILTER ITERATOR
    bp_filter_infosource = Node(util.IdentityInterface(fields=['bp_freqs']), name='bp_filter_infosource')
    bp_filter_infosource.iterables = ('bp_freqs', bp_freq_list)

    selectfiles = Node(nio.SelectFiles(selectfiles_templates,
                                       base_directory=preprocessed_data_dir),
                       name='selectfiles')
    selectfiles.inputs.subject_id = subject_id

    # #####################
    # # FIX TR IN HEADER
    # #####################
    # tr_msec = int(TR * 1000)
    # tr_str = '-tr %s' % tr_msec
    #
    # fixed_tr_bp = Node(MRIConvert(out_type='niigz', args=tr_str), name='fixed_tr_bp')
    # wf.connect(selectfiles, 'epi_MNI_bp', fixed_tr_bp, 'in_file')
    #
    # fixed_tr_fullspectrum = Node(MRIConvert(out_type='niigz', args=tr_str), name='fixed_tr_fullspectrum')
    # wf.connect(selectfiles, 'epi_MNI_fullspectrum', fixed_tr_fullspectrum, 'in_file')

    #####################
    # calc FD
    #####################
    FD_P = Node(util.Function(input_names=['in_file'],
                              output_names=['FD_ts_file', 'mean_FD_file', 'max_FD_file'],
                              function=calculate_FD_P),
                name='FD_P')
    wf.connect(selectfiles, 'moco_parms_file', FD_P, 'in_file')
    wf.connect(FD_P, 'FD_ts_file', ds, 'QC.@FD')
    wf.connect(FD_P, 'mean_FD_file', ds, 'QC.@mean_FD')
    wf.connect(FD_P, 'max_FD_file', ds, 'QC.@max_FD')

    FD_J = Node(util.Function(input_names=['in_file'],
                              output_names=['FD_ts_file', 'mean_FD_file', 'max_FD_file'],
                              function=calculate_FD_J),
                name='FD_J')
    wf.connect(selectfiles, 'jenkinson_file', FD_J, 'in_file')
    wf.connect(FD_J, 'FD_ts_file', ds, 'QC.@FD_J')
    wf.connect(FD_J, 'mean_FD_file', ds, 'QC.@mean_FD_J')
    wf.connect(FD_J, 'max_FD_file', ds, 'QC.@max_FD_J')

    wf.connect(selectfiles, 'rest2anat_cost_file', ds, 'QC.@cost_file')


    #####################
    # CALCULATE METRICS
    #####################

    # f/ALFF
    alff = cpac_alff.create_alff('alff')
    alff.inputs.hp_input.hp = 0.01
    alff.inputs.lp_input.lp = 0.1
    alff.inputs.inputspec.rest_mask = brain_mask
    #wf.connect(fixed_tr_fullspectrum, 'out_file', alff, 'inputspec.rest_res')
    wf.connect(selectfiles, 'epi_MNI_fullspectrum', alff, 'inputspec.rest_res')
    wf.connect(alff, 'outputspec.alff_img', ds, 'alff.@alff')
    wf.connect(alff, 'outputspec.falff_img', ds, 'alff.@falff')

    # f/ALFF_MNI Z-SCORE
    alff_z = cpac_utils.get_zscore(input_name='alff', wf_name='alff_z')
    alff_z.inputs.inputspec.mask_file = brain_mask
    wf.connect(alff, 'outputspec.alff_img', alff_z, 'inputspec.input_file')
    wf.connect(alff_z, 'outputspec.z_score_img', ds, 'alff_z.@alff')

    falff_z = cpac_utils.get_zscore(input_name='falff', wf_name='falff_z')
    falff_z.inputs.inputspec.mask_file = brain_mask
    wf.connect(alff, 'outputspec.falff_img', falff_z, 'inputspec.input_file')
    wf.connect(falff_z, 'outputspec.z_score_img', ds, 'alff_z.@falff')


    # REHO
    reho = cpac_reho.create_reho()
    reho.inputs.inputspec.cluster_size = 27
    reho.inputs.inputspec.rest_mask = brain_mask
    #wf.connect(fixed_tr_bp, 'out_file', reho, 'inputspec.rest_res_filt')
    wf.connect(selectfiles, 'epi_MNI_BP', reho, 'inputspec.rest_res_filt')
    wf.connect(reho, 'outputspec.raw_reho_map', ds, 'reho.@reho')


    # VARIABILITY SCORES
    variability = Node(util.Function(input_names=['in_file'],
                                     output_names=['out_file'],
                                     function=calc_metrics_utils.calc_variability),
                       name='variability')
    #wf.connect(fixed_tr_bp, 'out_file', variability, 'in_file')
    wf.connect(selectfiles, 'epi_MNI_BP', variability, 'in_file')
    wf.connect(variability, 'out_file', ds, 'variability.@SD')

    variability_z = cpac_utils.get_zscore(input_name='ts_std', wf_name='variability_z')
    variability_z.inputs.inputspec.mask_file = brain_mask
    wf.connect(variability, 'out_file', variability_z, 'inputspec.input_file')
    wf.connect(variability_z, 'outputspec.z_score_img', ds, 'variability_z.@variability_z')



    ##############
    ## CON MATS
    ##############
    ##############
    ## extract ts
    ##############
    parcellated_ts = Node(
        util.Function(input_names=['in_data', 'parcellation_name', 'parcellations_dict', 'bp_freqs', 'tr'],
                      output_names=['parcellation_time_series', 'parcellation_time_series_file', 'masker_file'],
                      function=calc_metrics_utils.extract_parcellation_time_series),
        name='parcellated_ts')

    parcellated_ts.inputs.parcellations_dict = parcellations_dict
    parcellated_ts.inputs.tr = TR
    #wf.connect(fixed_tr_fullspectrum, 'out_file', parcellated_ts, 'in_data')
    wf.connect(selectfiles, 'epi_MNI_fullspectrum', parcellated_ts, 'in_data')
    wf.connect(parcellation_infosource, 'parcellation', parcellated_ts, 'parcellation_name')
    wf.connect(bp_filter_infosource, 'bp_freqs', parcellated_ts, 'bp_freqs')



    ##############
    ## get conmat
    ##############
    con_mat = Node(util.Function(input_names=['in_data', 'extraction_method'],
                                 output_names=['matrix', 'matrix_file'],
                                 function=calc_metrics_utils.calculate_connectivity_matrix),
                   name='con_mat')
    con_mat.inputs.extraction_method = 'correlation'
    wf.connect(parcellated_ts, 'parcellation_time_series', con_mat, 'in_data')


    ##############
    ## ds
    ##############

    wf.connect(parcellated_ts, 'parcellation_time_series_file', ds, 'con_mat.parcellated_time_series.@parc_ts')
    wf.connect(parcellated_ts, 'masker_file', ds, 'con_mat.parcellated_time_series.@masker')
    wf.connect(con_mat, 'matrix_file', ds, 'con_mat.matrix.@mat')

    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name, plugin_args={'initial_specs': 'request_memory = 1500'})
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
Пример #33
0
def calc_centrality_metrics(cfg):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.freesurfer as freesurfer

    import CPAC.network_centrality.resting_state_centrality as cpac_centrality
    import CPAC.network_centrality.z_score as cpac_centrality_z_score


    # INPUT PARAMETERS
    dicom_dir = cfg['dicom_dir']
    preprocessed_data_dir = cfg['preprocessed_data_dir']

    working_dir = cfg['working_dir']
    freesurfer_dir = cfg['freesurfer_dir']
    template_dir = cfg['template_dir']
    script_dir = cfg['script_dir']
    ds_dir = cfg['ds_dir']

    subjects_list = cfg['subjects_list']
    TR_list = cfg['TR_list']

    use_n_procs = cfg['use_n_procs']
    plugin_name = cfg['plugin_name']



    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir)

    wf = Workflow(name='LeiCA_metrics')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': False,
                                                                       'remove_unnecessary_outputs': True,
                                                                       'job_finished_timeout': 120})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(), name='ds')
    ds.inputs.substitutions = [('_TR_id_', 'TR_')]
    ds.inputs.regexp_substitutions = [('_subject_id_[A0-9]*/', ''), (
    '_z_score[0-9]*/', '')]  # , #('dc/_TR_id_[0-9]*/', ''), ('evc/_TR_id_[0-9]*/','')]

    #####################################
    # SET ITERATORS
    #####################################
    # GET SCAN TR_ID ITERATOR
    scan_infosource = Node(util.IdentityInterface(fields=['TR_id']), name='scan_infosource')
    scan_infosource.iterables = ('TR_id', TR_list)

    subjects_infosource = Node(util.IdentityInterface(fields=['subject_id']), name='subjects_infosource')
    subjects_infosource.iterables = ('subject_id', subjects_list)

    def add_subject_id_to_ds_dir_fct(subject_id, ds_path):
        import os
        out_path = os.path.join(ds_path, subject_id)
        return out_path

    add_subject_id_to_ds_dir = Node(util.Function(input_names=['subject_id', 'ds_path'],
                                                  output_names=['out_path'],
                                                  function=add_subject_id_to_ds_dir_fct),
                                    name='add_subject_id_to_ds_dir')
    wf.connect(subjects_infosource, 'subject_id', add_subject_id_to_ds_dir, 'subject_id')
    add_subject_id_to_ds_dir.inputs.ds_path = ds_dir

    wf.connect(add_subject_id_to_ds_dir, 'out_path', ds, 'base_directory')


    # get atlas data
    templates_atlases = {'GM_mask_MNI_2mm': 'SPM_GM/SPM_GM_mask_2mm.nii.gz',
                         'GM_mask_MNI_3mm': 'SPM_GM/SPM_GM_mask_3mm.nii.gz',
                         'FSL_MNI_3mm_template': 'MNI152_T1_3mm_brain.nii.gz',
                         'vmhc_symm_brain': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_symmetric.nii.gz',
                         'vmhc_symm_brain_3mm': 'cpac_image_resources/symmetric/MNI152_T1_3mm_brain_symmetric.nii.gz',
                         'vmhc_symm_skull': 'cpac_image_resources/symmetric/MNI152_T1_2mm_symmetric.nii.gz',
                         'vmhc_symm_brain_mask_dil': 'cpac_image_resources/symmetric/MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz',
                         'vmhc_config_file_2mm': 'cpac_image_resources/symmetric/T1_2_MNI152_2mm_symmetric.cnf'
                         }

    selectfiles_anat_templates = Node(nio.SelectFiles(templates_atlases,
                                                      base_directory=template_dir),
                                      name="selectfiles_anat_templates")


    # GET SUBJECT SPECIFIC FUNCTIONAL AND STRUCTURAL DATA
    selectfiles_templates = {
        'epi_2_MNI_warp': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_MNI_warp/TR_{TR_id}/*.nii.gz',
        'epi_mask': '{subject_id}/rsfMRI_preprocessing/masks/brain_mask_epiSpace/TR_{TR_id}/*.nii.gz',
        'preproc_epi_full_spectrum': '{subject_id}/rsfMRI_preprocessing/epis/01_denoised/TR_{TR_id}/*.nii.gz',
        'preproc_epi_bp': '{subject_id}/rsfMRI_preprocessing/epis/02_denoised_BP/TR_{TR_id}/*.nii.gz',
        'preproc_epi_bp_tNorm': '{subject_id}/rsfMRI_preprocessing/epis/03_denoised_BP_tNorm/TR_{TR_id}/*.nii.gz',
        'epi_2_struct_mat': '{subject_id}/rsfMRI_preprocessing/registration/epi_2_struct_mat/TR_{TR_id}/*.mat',
        't1w': '{subject_id}/raw_niftis/sMRI/t1w_reoriented.nii.gz',
        't1w_brain': '{subject_id}/rsfMRI_preprocessing/struct_prep/t1w_brain/t1w_reoriented_maths.nii.gz',
        'epi_bp_tNorm_MNIspace_3mm': '{subject_id}/rsfMRI_preprocessing/epis_MNI_3mm/03_denoised_BP_tNorm/TR_645/residual_filt_norm_warp.nii.gz'
    }

    selectfiles = Node(nio.SelectFiles(selectfiles_templates,
                                       base_directory=preprocessed_data_dir),
                       name="selectfiles")
    wf.connect(scan_infosource, 'TR_id', selectfiles, 'TR_id')
    wf.connect(subjects_infosource, 'subject_id', selectfiles, 'subject_id')
    # selectfiles.inputs.subject_id = subject_id

    # CREATE TRANSFORMATIONS
    # creat MNI 2 epi warp
    MNI_2_epi_warp = Node(fsl.InvWarp(), name='MNI_2_epi_warp')
    MNI_2_epi_warp.inputs.reference = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz')
    wf.connect(selectfiles, 'epi_mask', MNI_2_epi_warp, 'reference')
    wf.connect(selectfiles, 'epi_2_MNI_warp', MNI_2_epi_warp, 'warp')

    #####################
    # CALCULATE METRICS
    #####################

    # DEGREE
    # fixme
    # a_mem = 5
    # fixme
    a_mem = 20
    dc = cpac_centrality.create_resting_state_graphs(allocated_memory=a_mem,
                                                     wf_name='dc')  # allocated_memory = a_mem, wf_name = 'dc')
    # dc.plugin_args = {'submit_specs': 'request_memory = 6000'}
    # fixme
    dc.plugin_args = {'submit_specs': 'request_memory = 20000'}

    dc.inputs.inputspec.method_option = 0  # 0 for degree centrality, 1 for eigenvector centrality, 2 for lFCD
    dc.inputs.inputspec.threshold_option = 0  # 0 for probability p_value, 1 for sparsity threshold, any other for threshold value
    dc.inputs.inputspec.threshold = 0.0001
    dc.inputs.inputspec.weight_options = [True,
                                          True]  # list of two booleans for binarize and weighted options respectively
    wf.connect(selectfiles, 'epi_bp_tNorm_MNIspace_3mm', dc, 'inputspec.subject')
    wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', dc, 'inputspec.template')
    wf.connect(dc, 'outputspec.centrality_outputs', ds, 'metrics.centrality.dc.@centrality_outputs')
    wf.connect(dc, 'outputspec.correlation_matrix', ds, 'metrics.centrality.dc.@correlation_matrix')
    wf.connect(dc, 'outputspec.graph_outputs', ds, 'metrics.centrality.dc.@graph_outputs')

    # DC Z-SCORE
    dc_Z = cpac_centrality_z_score.get_cent_zscore(wf_name='dc_Z')
    wf.connect(dc, 'outputspec.centrality_outputs', dc_Z, 'inputspec.input_file')
    wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', dc_Z, 'inputspec.mask_file')
    wf.connect(dc_Z, 'outputspec.z_score_img', ds, 'metrics.centrality.dc_z.@output')

    a_mem = 20
    evc = cpac_centrality.create_resting_state_graphs(allocated_memory=a_mem, wf_name='evc')
    evc.plugin_args = {'submit_specs': 'request_memory = 20000'}

    evc.inputs.inputspec.method_option = 1  # 0 for degree centrality, 1 for eigenvector centrality, 2 for lFCD
    evc.inputs.inputspec.threshold_option = 0  # 0 for probability p_value, 1 for sparsity threshold, any other for threshold value
    evc.inputs.inputspec.threshold = 0.0001
    evc.inputs.inputspec.weight_options = [True,
                                           True]  # list of two booleans for binarize and weighted options respectively
    wf.connect(selectfiles, 'epi_bp_tNorm_MNIspace_3mm', evc, 'inputspec.subject')
    wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', evc, 'inputspec.template')
    wf.connect(evc, 'outputspec.centrality_outputs', ds, 'metrics.centrality.evc.@centrality_outputs')
    wf.connect(evc, 'outputspec.correlation_matrix', ds, 'metrics.centrality.evc.@correlation_matrix')
    wf.connect(evc, 'outputspec.graph_outputs', ds, 'metrics.centrality.evc.@graph_outputs')

    # EVC Z-SCORE
    evc_Z = cpac_centrality_z_score.get_cent_zscore(wf_name='evc_Z')
    wf.connect(evc, 'outputspec.centrality_outputs', evc_Z, 'inputspec.input_file')
    wf.connect(selectfiles_anat_templates, 'GM_mask_MNI_3mm', evc_Z, 'inputspec.mask_file')
    wf.connect(evc_Z, 'outputspec.z_score_img', ds, 'metrics.centrality.evc_z.@output')

    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
                    (level2estimate, level2conestimate, [('spm_mat_file',
                                                          'spm_mat_file'),
                                                         ('beta_images',
                                                          'beta_images'),
                                                         ('residual_image',
                                                          'residual_image')]),
                    ])


###
# Input & Output Stream

# Infosource - a function free node to iterate over the list of subject names
infosource = Node(IdentityInterface(fields=['contrast_id']),
                  name="infosource")
infosource.iterables = [('contrast_id', contrast_list)]

# SelectFiles - to grab the data (alternative to DataGrabber)
con_file = opj(input_dir_norm, 'warp_complete', 'sub*', 'warpall*',
               '{contrast_id}_trans.nii')
templates = {'cons': con_file}
selectfiles = Node(SelectFiles(templates,
                               base_directory=experiment_dir),
                   name="selectfiles")

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

# Use the following DataSink output substitutions
    def make_neuromet1_workflow(self):

        # Infosource: Iterate through subject names
        infosource = Node(interface=IdentityInterface(fields=['subject_id']),
                          name="infosource")
        infosource.iterables = ('subject_id', self.subject_list)

        #unidensource, return for every subject uni and den
        unidensource = Node(interface=IdentityInterface(
            fields=['uniden_prefix', 'uniden_suffix']),
                            name="unidensource")
        unidensource.iterables = [
            ('uniden_prefix', ['', 'derivatives/Siemens/']),
            ('uniden_suffix', ['T1w', 'desc-UNIDEN_MP2RAGE'])
        ]
        unidensource.synchronize = True

        split_sub_str = Node(Function(['subject_str'],
                                      ['subject_id', 'session_id'],
                                      self.split_subject_ses),
                             name='split_sub_str')

        info = dict(T1w=[[
            'uniden_prefix', 'subject_id', 'session_id', 'anat', 'subject_id',
            'session_id', 'uniden_suffix'
        ]])

        datasource = Node(interface=DataGrabber(infields=[
            'subject_id', 'session_id', 'uniden_prefix', 'uniden_suffix'
        ],
                                                outfields=['T1w']),
                          name='datasource')
        datasource.inputs.base_directory = self.bids_root
        datasource.inputs.template = '%ssub-NeuroMET%s/ses-0%s/%s/sub-NeuroMET%s_ses-0%s_%s.nii.gz'
        datasource.inputs.template_args = info
        datasource.inputs.sort_filelist = False

        sink = self.make_sink()
        segment = self.make_segment()
        mask = self.make_mask()

        neuromet = Workflow(name='NeuroMET', base_dir=self.temp_dir)
        neuromet.connect(infosource, 'subject_id', split_sub_str,
                         'subject_str')
        neuromet.connect(split_sub_str, 'subject_id', datasource, 'subject_id')
        neuromet.connect(split_sub_str, 'session_id', datasource, 'session_id')
        neuromet.connect(unidensource, 'uniden_prefix', datasource,
                         'uniden_prefix')
        neuromet.connect(unidensource, 'uniden_suffix', datasource,
                         'uniden_suffix')
        neuromet.connect(datasource, 'T1w', segment, 'ro.in_file')

        # neuromet.connect()
        neuromet.connect(segment, 'spm_tissues_split.gm', mask,
                         'sum_tissues1.in_file')
        neuromet.connect(segment, 'spm_tissues_split.wm', mask,
                         'sum_tissues1.operand_files')
        neuromet.connect(segment, 'spm_tissues_split.csf', mask,
                         'sum_tissues2.operand_files')
        neuromet.connect(segment, 'spm_tissues_split.gm', sink, '@gm')
        neuromet.connect(segment, 'spm_tissues_split.wm', sink, '@wm')
        neuromet.connect(segment, 'spm_tissues_split.csf', sink, '@csf')
        neuromet.connect(segment, 'seg.bias_corrected_images', sink,
                         '@biascorr')
        # neuromet.connect(comb_imgs, 'uni_brain_den_surr_add.out_file', sink, '@img')
        neuromet.connect(mask, 'gen_mask.out_file', sink, '@mask')
        neuromet.connect(segment, 'ro.out_file', sink, '@ro')

        return neuromet
Пример #36
0
wf.base_dir = os.path.join(wd_dir)
nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True,
                                                                   'remove_unnecessary_outputs': True,
                                                                   'job_finished_timeout': 120})
config.update_config(nipype_cfg)
wf.config['execution']['crashdump_dir'] = os.path.join(wd_dir, 'crash')

ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')



######################
# GET DATA
######################
age_infosource = Node(util.IdentityInterface(fields=['age_switch']), name='age_infosource')
age_infosource.iterables = ('age_switch', ['full_range', 'adults_only', 'under_18'])


def get_subjects_list_and_age_fct(age_switch, df):
    import os

    df = df[df.no_axis_1]

    if age_switch == 'adults_only':
        df = df[df.AGE_04 >= 18]
    elif age_switch == 'under_18':
        df = df[df.AGE_04 < 18]
    subjects_list = df.leica_id.values
    age = df.AGE_04.values

    df_used = os.path.join(os.getcwd(), 'df_used.csv')
Пример #37
0
def learning_predict_data_2samp_wf(working_dir,
                                   ds_dir,
                                   in_data_name_list,
                                   subjects_selection_crit_dict,
                                   subjects_selection_crit_names_list,
                                   aggregated_subjects_dir,
                                   target_list,
                                   use_n_procs,
                                   plugin_name,
                                   confound_regression=[False, True],
                                   run_cv=False,
                                   n_jobs_cv=1,
                                   run_tuning=False,
                                   run_2sample_training=False,
                                   aggregated_subjects_dir_nki=None,
                                   subjects_selection_crit_dict_nki=None,
                                   subjects_selection_crit_name_nki=None,
                                   reverse_split=False,
                                   random_state_nki=666,
                                   run_learning_curve=False,
                                   life_test_size=0.5):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    from itertools import chain
    from learning_utils import aggregate_multimodal_metrics_fct, run_prediction_split_fct, \
        backproject_and_split_weights_fct, select_subjects_fct, select_multimodal_X_fct, learning_curve_plot
    import pandas as pd



    ###############################################################################################################
    # GENERAL SETTINGS

    wf = Workflow(name='learning_predict_data_2samp_wf')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'),
                      execution={'stop_on_first_crash': False,
                                 'remove_unnecessary_outputs': False,
                                 'job_finished_timeout': 120})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(), name='ds')
    ds.inputs.base_directory = os.path.join(ds_dir, 'group_learning_prepare_data')

    ds.inputs.regexp_substitutions = [
        # ('subject_id_', ''),
        ('_parcellation_', ''),
        ('_bp_freqs_', 'bp_'),
        ('_extraction_method_', ''),
        ('_subject_id_[A0-9]*/', '')
    ]
    ds_pdf = Node(nio.DataSink(), name='ds_pdf')
    ds_pdf.inputs.base_directory = os.path.join(ds_dir, 'pdfs')
    ds_pdf.inputs.parameterization = False



    ###############################################################################################################
    # ensure in_data_name_list is list of lists
    in_data_name_list = [i if type(i) == list else [i] for i in in_data_name_list]
    in_data_name_list_unique = list(set(chain.from_iterable(in_data_name_list)))



    ###############################################################################################################
    # SET ITERATORS

    in_data_name_infosource = Node(util.IdentityInterface(fields=['in_data_name']), name='in_data_name_infosource')
    in_data_name_infosource.iterables = ('in_data_name', in_data_name_list_unique)

    multimodal_in_data_name_infosource = Node(util.IdentityInterface(fields=['multimodal_in_data_name']),
                                              name='multimodal_in_data_name_infosource')
    multimodal_in_data_name_infosource.iterables = ('multimodal_in_data_name', in_data_name_list)

    subject_selection_infosource = Node(util.IdentityInterface(fields=['selection_criterium']),
                                        name='subject_selection_infosource')
    subject_selection_infosource.iterables = ('selection_criterium', subjects_selection_crit_names_list)

    target_infosource = Node(util.IdentityInterface(fields=['target_name']), name='target_infosource')
    target_infosource.iterables = ('target_name', target_list)



    ###############################################################################################################
    # COMPILE LIFE DATA
    ###############################################################################################################

    ###############################################################################################################
    # GET INFO AND SELECT FILES
    df_all_subjects_pickle_file = os.path.join(aggregated_subjects_dir, 'df_all_subjects_pickle_file/df_all.pkl')
    df = pd.read_pickle(df_all_subjects_pickle_file)

    # build lookup dict for unimodal data
    X_file_template = 'X_file/_in_data_name_{in_data_name}/vectorized_aggregated_data.npy'
    info_file_template = 'unimodal_backprojection_info_file/_in_data_name_{in_data_name}/unimodal_backprojection_info.pkl'
    unimodal_lookup_dict = {}
    for k in in_data_name_list_unique:
        unimodal_lookup_dict[k] = {'X_file': os.path.join(aggregated_subjects_dir, X_file_template.format(
            in_data_name=k)),
                                   'unimodal_backprojection_info_file': os.path.join(aggregated_subjects_dir,
                                                                                     info_file_template.format(
                                                                                         in_data_name=k))
                                   }



    ###############################################################################################################
    # AGGREGATE MULTIMODAL METRICS
    # stack single modality arrays horizontally
    aggregate_multimodal_metrics = Node(util.Function(input_names=['multimodal_list', 'unimodal_lookup_dict'],
                                                      output_names=['X_multimodal_file',
                                                                    'multimodal_backprojection_info',
                                                                    'multimodal_name'],
                                                      function=aggregate_multimodal_metrics_fct),
                                        name='aggregate_multimodal_metrics')
    wf.connect(multimodal_in_data_name_infosource, 'multimodal_in_data_name', aggregate_multimodal_metrics,
               'multimodal_list')
    aggregate_multimodal_metrics.inputs.unimodal_lookup_dict = unimodal_lookup_dict



    ###############################################################################################################
    # GET INDEXER FOR SUBJECTS OF INTEREST (as defined by selection criterium)
    select_subjects = Node(util.Function(input_names=['df_all_subjects_pickle_file',
                                                      'subjects_selection_crit_dict',
                                                      'selection_criterium'],
                                         output_names=['df_use_file',
                                                       'df_use_pickle_file',
                                                       'subjects_selection_index'],
                                         function=select_subjects_fct),
                           name='select_subjects')

    select_subjects.inputs.df_all_subjects_pickle_file = df_all_subjects_pickle_file
    select_subjects.inputs.subjects_selection_crit_dict = subjects_selection_crit_dict
    wf.connect(subject_selection_infosource, 'selection_criterium', select_subjects, 'selection_criterium')



    ###############################################################################################################
    # SELECT MULITMODAL X
    # select subjects (rows) from multimodal X according indexer
    select_multimodal_X = Node(util.Function(input_names=['X_multimodal_file', 'subjects_selection_index',
                                                          'selection_criterium'],
                                             output_names=['X_multimodal_selected_file'],
                                             function=select_multimodal_X_fct),
                               name='select_multimodal_X')
    wf.connect(aggregate_multimodal_metrics, 'X_multimodal_file', select_multimodal_X, 'X_multimodal_file')
    wf.connect(select_subjects, 'subjects_selection_index', select_multimodal_X, 'subjects_selection_index')






    ###############################################################################################################
    # COMPILE NKI DATA
    ###############################################################################################################
    if run_2sample_training:

        ###############################################################################################################
        # GET INFO AND SELECT FILES
        df_all_subjects_pickle_file_nki = os.path.join(aggregated_subjects_dir_nki,
                                                       'df_all_subjects_pickle_file/df_all.pkl')
        df_nki = pd.read_pickle(df_all_subjects_pickle_file_nki)

        # build lookup dict for unimodal data
        X_file_template = 'X_file/_in_data_name_{in_data_name}/vectorized_aggregated_data.npy'
        info_file_template = 'unimodal_backprojection_info_file/_in_data_name_{in_data_name}/unimodal_backprojection_info.pkl'
        unimodal_lookup_dict_nki = {}
        for k in in_data_name_list_unique:
            unimodal_lookup_dict_nki[k] = {'X_file': os.path.join(aggregated_subjects_dir_nki, X_file_template.format(
                in_data_name=k)),
                                           'unimodal_backprojection_info_file': os.path.join(
                                               aggregated_subjects_dir_nki,
                                               info_file_template.format(
                                                   in_data_name=k))
                                           }



        ###############################################################################################################
        # AGGREGATE MULTIMODAL METRICS
        # stack single modality arrays horizontally
        aggregate_multimodal_metrics_nki = Node(util.Function(input_names=['multimodal_list', 'unimodal_lookup_dict'],
                                                              output_names=['X_multimodal_file',
                                                                            'multimodal_backprojection_info',
                                                                            'multimodal_name'],
                                                              function=aggregate_multimodal_metrics_fct),
                                                name='aggregate_multimodal_metrics_nki')
        wf.connect(multimodal_in_data_name_infosource, 'multimodal_in_data_name', aggregate_multimodal_metrics_nki,
                   'multimodal_list')
        aggregate_multimodal_metrics_nki.inputs.unimodal_lookup_dict = unimodal_lookup_dict_nki



        ###############################################################################################################
        # GET INDEXER FOR SUBJECTS OF INTEREST (as defined by selection criterium)
        select_subjects_nki = Node(util.Function(input_names=['df_all_subjects_pickle_file',
                                                              'subjects_selection_crit_dict',
                                                              'selection_criterium'],
                                                 output_names=['df_use_file',
                                                               'df_use_pickle_file',
                                                               'subjects_selection_index'],
                                                 function=select_subjects_fct),
                                   name='select_subjects_nki')

        select_subjects_nki.inputs.df_all_subjects_pickle_file = df_all_subjects_pickle_file_nki
        select_subjects_nki.inputs.subjects_selection_crit_dict = subjects_selection_crit_dict_nki
        select_subjects_nki.inputs.selection_criterium = subjects_selection_crit_name_nki



        ###############################################################################################################
        # SELECT MULITMODAL X
        # select subjects (rows) from multimodal X according indexer
        select_multimodal_X_nki = Node(util.Function(input_names=['X_multimodal_file', 'subjects_selection_index',
                                                                  'selection_criterium'],
                                                     output_names=['X_multimodal_selected_file'],
                                                     function=select_multimodal_X_fct),
                                       name='select_multimodal_X_nki')
        wf.connect(aggregate_multimodal_metrics_nki, 'X_multimodal_file', select_multimodal_X_nki, 'X_multimodal_file')
        wf.connect(select_subjects_nki, 'subjects_selection_index', select_multimodal_X_nki, 'subjects_selection_index')





    ###############################################################################################################
    # RUN PREDICTION
    #
    prediction_node_dict = {}
    backprojection_node_dict = {}

    prediction_split = Node(util.Function(input_names=['X_file',
                                                       'target_name',
                                                       'selection_criterium',
                                                       'df_file',
                                                       'data_str',
                                                       'regress_confounds',
                                                       'run_cv',
                                                       'n_jobs_cv',
                                                       'run_tuning',
                                                       'X_file_nki',
                                                       'df_file_nki',
                                                       'reverse_split',
                                                       'random_state_nki',
                                                       'run_learning_curve',
                                                       'life_test_size'],
                                          output_names=['scatter_file',
                                                        'brain_age_scatter_file',
                                                        'df_life_out_file',
                                                        'df_nki_out_file',
                                                        'df_big_out_file',
                                                        'model_out_file',
                                                        'df_res_out_file',
                                                        'tuning_curve_file',
                                                        'scatter_file_cv',
                                                        'learning_curve_plot_file',
                                                        'learning_curve_df_file'],
                                          function=run_prediction_split_fct),
                            name='prediction_split')

    backproject_and_split_weights = Node(util.Function(input_names=['trained_model_file',
                                                                    'multimodal_backprojection_info',
                                                                    'data_str',
                                                                    'target_name'],
                                                       output_names=['out_file_list',
                                                                     'out_file_render_list'],
                                                       function=backproject_and_split_weights_fct),
                                         name='backproject_and_split_weights')

    i = 0

    for reg in confound_regression:
        the_out_node_str = 'single_source_model_reg_%s_' % (reg)
        prediction_node_dict[i] = prediction_split.clone(the_out_node_str)
        the_in_node = prediction_node_dict[i]
        the_in_node.inputs.regress_confounds = reg
        the_in_node.inputs.run_cv = run_cv
        the_in_node.inputs.n_jobs_cv = n_jobs_cv
        the_in_node.inputs.run_tuning = run_tuning
        the_in_node.inputs.reverse_split = reverse_split
        the_in_node.inputs.random_state_nki = random_state_nki
        the_in_node.inputs.run_learning_curve = run_learning_curve
        the_in_node.inputs.life_test_size = life_test_size

        wf.connect(select_multimodal_X, 'X_multimodal_selected_file', the_in_node, 'X_file')
        wf.connect(target_infosource, 'target_name', the_in_node, 'target_name')
        wf.connect(subject_selection_infosource, 'selection_criterium', the_in_node, 'selection_criterium')
        wf.connect(select_subjects, 'df_use_pickle_file', the_in_node, 'df_file')
        wf.connect(aggregate_multimodal_metrics, 'multimodal_name', the_in_node, 'data_str')

        wf.connect(the_in_node, 'model_out_file', ds, the_out_node_str + 'trained_model')
        wf.connect(the_in_node, 'scatter_file', ds_pdf, the_out_node_str + 'scatter')
        wf.connect(the_in_node, 'brain_age_scatter_file', ds_pdf, the_out_node_str + 'brain_age_scatter')
        wf.connect(the_in_node, 'df_life_out_file', ds_pdf, the_out_node_str + 'predicted_life')
        wf.connect(the_in_node, 'df_nki_out_file', ds_pdf, the_out_node_str + 'predicted_nki')
        wf.connect(the_in_node, 'df_big_out_file', ds_pdf, the_out_node_str + 'predicted')

        wf.connect(the_in_node, 'df_res_out_file', ds_pdf, the_out_node_str + 'results_error')
        wf.connect(the_in_node, 'tuning_curve_file', ds_pdf, the_out_node_str + 'tuning_curve')
        wf.connect(the_in_node, 'scatter_file_cv', ds_pdf, the_out_node_str + 'scatter_cv')
        wf.connect(the_in_node, 'learning_curve_plot_file', ds_pdf, the_out_node_str + 'learning_curve_plot_file.@plot')
        wf.connect(the_in_node, 'learning_curve_df_file', ds_pdf, the_out_node_str + 'learning_curve_df_file.@df')

        # NKI
        if run_2sample_training:
            wf.connect(select_multimodal_X_nki, 'X_multimodal_selected_file', the_in_node, 'X_file_nki')
            wf.connect(select_subjects_nki, 'df_use_pickle_file', the_in_node, 'df_file_nki')

        else:
            the_in_node.inputs.df_file_nki = None
            the_in_node.inputs.X_file_nki = None

        # BACKPROJECT PREDICTION WEIGHTS
        # map weights back to single modality original format (e.g., nifti or matrix)
        the_out_node_str = 'backprojection_single_source_model_reg_%s_' % (reg)
        backprojection_node_dict[i] = backproject_and_split_weights.clone(the_out_node_str)
        the_from_node = prediction_node_dict[i]
        the_in_node = backprojection_node_dict[i]
        wf.connect(the_from_node, 'model_out_file', the_in_node, 'trained_model_file')
        wf.connect(aggregate_multimodal_metrics, 'multimodal_backprojection_info', the_in_node,
                   'multimodal_backprojection_info')
        wf.connect(aggregate_multimodal_metrics, 'multimodal_name', the_in_node, 'data_str')
        wf.connect(target_infosource, 'target_name', the_in_node, 'target_name')

        wf.connect(the_in_node, 'out_file_list', ds_pdf, the_out_node_str + '.@weights')
        wf.connect(the_in_node, 'out_file_render_list', ds_pdf, the_out_node_str + 'renders.@renders')

        i += 1



    ###############################################################################################################
    # #  RUN WF
    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
# in and out
similarity.base_dir = "/scr/kansas1/huntenburg/"
similarity.config["execution"] = {"remove_unnecessary_outputs": "False"}
out_dir = "/scr/jessica2/Schaare/LEMON/preprocessed/"
data_dir = "/scr/jessica2/Schaare/LEMON/preprocessed/"
# subjects=['LEMON001']
subjects = []
f = open("/scr/jessica2/Schaare/LEMON/done_freesurfer.txt", "r")
for line in f:
    subjects.append(line.strip())
subjects.remove("LEMON027")


# create inforsource to iterate over subjects
infosource = Node(util.IdentityInterface(fields=["subject_id"]), name="infosource")
infosource.iterables = ("subject_id", subjects)


# select files
templates = {
    "anat_brain": "{subject_id}/freesurfer_anatomy/brain_out.nii.gz",
    "lin_mean_coreg": "{subject_id}/coreg/lin_mean_coreg.nii.gz",
    "nonlin_mean_coreg": "{subject_id}/nonlin_coreg/nonlin_mean_coreg.nii.gz",
    "fmap_mean_coreg": "{subject_id}/fieldmap_coreg/fmap_mean_coreg.nii.gz",
    "topup_mean_coreg": "{subject_id}/topup_coreg/topup_mean_coreg.nii.gz",
}


selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles")

Пример #39
0
preproc.connect(remove_noise, "out_file", bandpass_filter, "in_file")
preproc.connect(bandpass_filter, "out_file", outputnode, "filtered_file")


###################################################################################################################################
# in and out
preproc.base_dir = "/scr/kansas1/huntenburg/"
preproc.config["execution"] = {"remove_unnecessary_outputs": "False"}
out_dir = "/scr/"
data_dir = "/scr/"
subjects = ["LEMON006"]  # ,'LEMON001','LEMON087','LEMON030','LEMON044','LEMON071']


# infosource to iterate over subjects
subject_infosource = Node(util.IdentityInterface(fields=["subject_id"]), name="subject_infosource")
subject_infosource.iterables = ("subject_id", subjects)


# infosource to iterate over coregistration methods
cor_method_infosource = Node(util.IdentityInterface(fields=["cor_method"]), name="cor_method_infosource")
cor_method_infosource.iterables = ("cor_method", ["lin_ts"])  # , 'lin_ts', 'nonlin_ts', 'fmap_ts', 'topup_ts'])


# select files
templates = {
    "timeseries": "kansas1/huntenburg/*_timeseries/_subject_id_{subject_id}/*apply*/{cor_method}.nii.gz",
    #'par_file':'jessica2/Schaare/LEMON/preprocessed/{subject_id}/motion_correction/rest_moco.nii.gz.par'
}

selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir), name="selectfiles")
Пример #40
0
sessions = ['d0']

# directories
working_dir = '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/working_dir'
out_dir = '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/final/'

# main workflow
preproc_nuisance_regress = Workflow(name='func_preproc_nuisance_regress')
preproc_nuisance_regress.base_dir = working_dir
preproc_nuisance_regress.config['execution'][
    'crashdump_dir'] = preproc_nuisance_regress.base_dir + "/crash_files"

# iterate over subjects
subject_infosource = Node(util.IdentityInterface(fields=['subjectlist']),
                          name='subject_infosource')
subject_infosource.iterables = [('subjectlist', subjects)]

# iterate over sessions
session_infosource = Node(util.IdentityInterface(fields=['session']),
                          name='session_infosource')
session_infosource.iterables = [('session', sessions)]

# select files

templates = {
    'unwarped_file':
    '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/working_dir/func_preproc/_session_{session}/_subjectlist_{proband}.{subject}/fugue/corr_{subject}_{session}_S3_RS_ep2d_SMS6_TR1p1_TE22_FA40_1p2_FatSat_Echo_0_Te22_roi_unwarped.nii.gz',
    #'unwarped_file' : '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/{subject}/fugue/corr_{subject}_{session}_S3_RS_ep2d_SMS6_TR1p1_TE22_FA40_1p2_FatSat_Echo_0_Te22_roi_unwarped.nii.gz',
    'slicemoco_par_file':
    '/nobackup/eminem2/schmidt/MMPIRS/preprocessing/working_dir/func_preproc/_session_{session}/_subjectlist_{proband}.{subject}/spacetime_realign/{subject}_{session}_S3_RS_ep2d_SMS6_TR1p1_TE22_FA40_1p2_FatSat_Echo_0_Te22_roi.nii.gz.par',
    # need brain mask, csf and wm mask in functional space - from cbstools coreg pipeline
Пример #41
0
fs_skullstrip_wf = create_freesurfer_skullstrip_workflow()
fs_skullstrip_wf.inputs.inputspec.subjects_dir = fs_projdir

sids = [
    'sub-01', 'sub-02', 'sub-03', 'sub-04', 'sub-05', 'sub-06', 'sub-07',
    'sub-09', 'sub-10', 'sub-11', 'sub-12', 'sub-13', 'sub-14', 'sub-15'
]

# Set up the FreeSurfer skull stripper work flow
antsreg_wf = Workflow(name='antsreg_wf')
antsreg_wf.base_dir = workingdir

subjID_infosource = Node(
    IdentityInterface(fields=['subject_id', 'subjects_dir']),
    name='subjID_infosource')
subjID_infosource.iterables = ('subject_id', sids)

antsreg_wf.connect(subjID_infosource, 'subject_id', fs_skullstrip_wf,
                   'inputspec.subject_id')

# Use a JoinNode to aggregrate all of the outputs from the fs_skullstrip_wf
reg = Node(ants.Registration(), name='antsRegister')
reg.inputs.fixed_image = '/scratch/PSB6351_2017/ds008_R2.0.0/template/T1_template/study_template.nii.gz'
reg.inputs.output_transform_prefix = "output_"
reg.inputs.transforms = ['Rigid', 'Affine', 'SyN']
reg.inputs.transform_parameters = [(0.1, ), (0.1, ), (0.2, 3.0, 0.0)]
reg.inputs.number_of_iterations = [[10000, 11110, 11110]] * 2 + [[
    100, 100, 50
]]
reg.inputs.dimension = 3
reg.inputs.write_composite_transform = True
Пример #42
0
                  name='apply2mean')

# Initiation of the ANTS normalization workflow
normflow = Workflow(name='normflow')
normflow.base_dir = opj(experiment_dir, working_dir)

# Connect up ANTS normalization components
normflow.connect([(antsreg, apply2con, [('composite_transform', 'transforms')]),
                  (antsreg, apply2mean, [('composite_transform',
                                          'transforms')])
                  ])

# Infosource - a function free node to iterate over the list of subject names
infosource = Node(IdentityInterface(fields=['subject_id']),
                  name="infosource")
infosource.iterables = [('subject_id', subject_list)]

# SelectFiles - to grab the data (alternativ to DataGrabber)
anat_file = opj('freesurfer', '{subject_id}', 'mri/brain.mgz')
func_file = opj(input_dir_1st, 'contrasts', '{subject_id}',
                '_mriconvert*/*_out.nii.gz')
func_orig_file = opj(input_dir_1st, 'contrasts', '{subject_id}', '[ce]*.nii')
mean_file = opj(input_dir_1st, 'preprocout', '{subject_id}', 'mean*.nii')

templates = {'anat': anat_file,
             'func': func_file,
             'func_orig': func_orig_file,
             'mean': mean_file,
             }

selectfiles = Node(SelectFiles(templates,
subject_list = ['003','005','008','011','018','019','020', '059', '060','062','063','066']
session_list = ['run001', 'run002', 'run003']

                
output_dir  = '10Hz_10s_Task_Based_OutputDir'
working_dir = '10Hz_10s_Task_Based_WorkingDir'

preproc_task = Workflow(name = 'preproc_task')
preproc_task.base_dir = opj(experiment_dir, working_dir)

#-----------------------------------------------------------------------------------------------------
# In[20]:
# Infosource - a function free node to iterate over the list of subject names
infosource = Node(IdentityInterface(fields=['subject_id','session_id']),
                  name="infosource")
infosource.iterables = [('subject_id', subject_list),
                        ('session_id', session_list)]

#-----------------------------------------------------------------------------------------------------
# In[21]:

templates = {

 'Anat_Bias' : '/media/amr/HDD/Work/Stimulation/Registration_Stimulation_WorkingDir/Registration_Stimulation/_subject_id_{subject_id}/BiasFieldCorrection/Anat_{subject_id}_bet_corrected.nii.gz',
 'Anat_Mask' : 'Data/{subject_id}/Anat_{subject_id}_Mask.nii.gz',
 'Highres2Temp_Transformations' : '/media/amr/HDD/Work/Stimulation/Registration_Stimulation_WorkingDir/Registration_Stimulation/_subject_id_{subject_id}/HighresToTemplate/transformComposite.h5',


 'Stim_10Hz_10s' : 'Data/{subject_id}/Stim_{subject_id}_??_10Hz_10s_{session_id}.nii.gz',
 'EPI_Mask'  : 'Data/{subject_id}/EPI_{subject_id}_Mask.nii.gz'
             }
fmapepi.base_dir='/scr/kansas1/huntenburg/lemon_missing/working_dir/'
#fmapepi.config['execution']={'remove_unnecessary_outputs': 'False'}
data_dir = '/scr/jessica2/Schaare/LEMON/'
fs_subjects_dir='/scr/jessica2/Schaare/LEMON/freesurfer/'
out_dir = '/scr/jessica2/Schaare/LEMON/preprocessed/'
#subjects=['LEMON001']
subjects=[]
f = open('/scr/jessica2/Schaare/LEMON/missing_subjects.txt','r')
for line in f:
    subjects.append(line.strip())

# create inforsource to iterate over subjects
infosource = Node(util.IdentityInterface(fields=['subject_id','fs_subjects_dir']), 
                  name='infosource')
infosource.inputs.fs_subjects_dir=fs_subjects_dir
infosource.iterables=('subject_id', subjects)

# define templates and select files
templates={'epi_mean':'preprocessed/{subject_id}/motion_correction/rest_moco_mean.nii.gz',
           'mag': 'raw/{subject_id}/rest/fmap_mag_1.nii.gz',
           'phase': 'raw/{subject_id}/rest/fmap_phase.nii.gz',
           'anat_head': 'preprocessed/{subject_id}/freesurfer_anatomy/T1_out.nii.gz',
           'anat_brain': 'preprocessed/{subject_id}/freesurfer_anatomy/brain_out.nii.gz',
           'wmseg':'preprocessed/{subject_id}/freesurfer_anatomy/brain_out_wmseg.nii.gz'}

selectfiles = Node(nio.SelectFiles(templates,
                                   base_directory=data_dir),
                   name="selectfiles")

#sink to store files
sink = Node(nio.DataSink(base_directory=out_dir,
Пример #45
0
working_dir = 'Stimulation_Preproc_WorkingDir_CA3'

stimulation_preproc = Workflow(name='stimulation_preproc_CA3')
stimulation_preproc.base_dir = opj(experiment_dir, working_dir)

# =====================================================================================================
# In[3]:
# to prevent nipype from iterating over the anat image with each func run, you need seperate
# nodes to select the files
# and this will solve the problem I have for almost 6 months
# but notice that in the sessions, you have to iterate also over subject_id to get the {subject_id} var

# Infosource - a function free node to iterate over the list of subject names
infosource_anat = Node(IdentityInterface(fields=['subject_id']),
                       name="infosource_anat")
infosource_anat.iterables = [('subject_id', subject_list)]

infosource_func = Node(
    IdentityInterface(fields=['subject_id', 'session_id', 'frequency_id']),
    name="infosource_func")
infosource_func.iterables = [('subject_id', subject_list),
                             ('session_id', session_list),
                             ('frequency_id', frequency_list)]

# ========================================================================================================
# In[4]:
# /home/in/aeed/poldrack_gabmling/ds000005/sub-01/anat/sub-01_T1w.nii.gz
# anatomical images
templates_anat = {
    'anat':
    '/media/amr/Amr_4TB/Work/stimulation/Data_CA3/{subject_id}/Anat_{subject_id}_bet.nii.gz'
Пример #46
0
def mean_con_mat_wf(subjects_list,
                    preprocessed_data_dir,
                    working_dir,
                    ds_dir,
                    parcellations_list,
                    extraction_methods_list,
                    bp_freq_list,
                    use_n_procs,
                    plugin_name):

    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow, MapNode, JoinNode
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    from nipype.interfaces.freesurfer.utils import ImageInfo
    from utils import aggregate_data


    #####################################
    # GENERAL SETTINGS
    #####################################
    wf = Workflow(name='mean_con_mats')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True,
                                                                       'remove_unnecessary_outputs': True,
                                                                       'job_finished_timeout': 120})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(), name='ds')
    ds.inputs.base_directory = os.path.join(ds_dir, 'group_conmats_test')

    ds.inputs.regexp_substitutions = [
        # ('subject_id_', ''),
        ('_parcellation_', ''),
        ('_bp_freqs_', 'bp_'),
        ('_extraction_method_', ''),
        ('_subject_id_[A0-9]*/', '')
    ]



    #####################################
    # SET ITERATORS
    #####################################
    # SUBJECTS ITERATOR
    subjects_infosource = Node(util.IdentityInterface(fields=['subject_id']), name='subjects_infosource')
    subjects_infosource.iterables = ('subject_id', subjects_list)

    # PARCELLATION ITERATOR
    parcellation_infosource = Node(util.IdentityInterface(fields=['parcellation']), name='parcellation_infosource')
    parcellation_infosource.iterables = ('parcellation', parcellations_list)

    # BP FILTER ITERATOR
    bp_filter_infosource = Node(util.IdentityInterface(fields=['bp_freqs']), name='bp_filter_infosource')
    bp_filter_infosource.iterables = ('bp_freqs', bp_freq_list)

    # EXTRACTION METHOD ITERATOR
    extraction_method_infosource = Node(util.IdentityInterface(fields=['extraction_method']),
                                        name='extraction_method_infosource')
    extraction_method_infosource.iterables = ('extraction_method', extraction_methods_list)



    def create_file_list_fct(subjects_list, base_path, parcellation, bp_freqs, extraction_method):
        import os

        file_list = []
        for s in subjects_list:
            file_list.append(os.path.join(base_path, s, 'metrics/con_mat/matrix',
                                                       'bp_%s.%s'%(bp_freqs),
                            parcellation, extraction_method, 'matrix.pkl'))
        return file_list

    create_file_list = Node(util.Function(input_names=['subjects_list', 'base_path', 'parcellation', 'bp_freqs', 'extraction_method'],
                                       output_names=['file_list'],
                                       function=create_file_list_fct),
                         name='create_file_list')
    create_file_list.inputs.subjects_list = subjects_list
    create_file_list.inputs.base_path = preprocessed_data_dir
    wf.connect(parcellation_infosource, 'parcellation', create_file_list, 'parcellation')
    wf.connect(bp_filter_infosource, 'bp_freqs', create_file_list, 'bp_freqs')
    wf.connect(extraction_method_infosource, 'extraction_method', create_file_list, 'extraction_method')




    aggregate = Node(util.Function(input_names=['file_list'],
                                       output_names=['merged_file'],
                                       function=aggregate_data),
                         name='aggregate')
    wf.connect(create_file_list, 'file_list', aggregate, 'file_list')



    def plot_matrix_fct(in_file):
        import pickle, os
        import pylab as plt
        import numpy as np


        with open(in_file, 'r') as f:
            matrix_dict = pickle.load(f)

        out_file_list = []
        for m_type in matrix_dict.keys():
            mean_matrix = np.mean(matrix_dict[m_type], axis=0)
            fig = plt.imshow(mean_matrix, interpolation='nearest')
            plt.title(in_file)

            out_file = os.path.join(os.getcwd(), m_type+'.png')
            out_file_list.append(out_file)
            plt.savefig(out_file)

        return out_file_list

    plot_matrix = Node(util.Function(input_names=['in_file'],
                                       output_names=['out_file_list'],
                                       function=plot_matrix_fct),
                         name='plot_matrix')
    wf.connect(aggregate, 'merged_file', plot_matrix, 'in_file')
    wf.connect(plot_matrix, 'out_file_list', ds, 'group_mats.@groupmats')


    #####################################
    # RUN WF
    #####################################
    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})
output_dir = 'DTI_TBSS_Wax'
working_dir = 'DTI_TBSS_workingdir_Wax_Template'

DTI_TBSS_Wax = Workflow(name='DTI_TBSS_Wax')
DTI_TBSS_Wax.base_dir = opj(experiment_dir, working_dir)

#-----------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------
# In[3]:

# Infosource - a function free node to iterate over the list of subject names
infosource = Node(IdentityInterface(fields=['map_id']), name="infosource")
infosource.iterables = [('map_id', map_list)]

#-----------------------------------------------------------------------------------------------------
# In[4]:

templates = {
    'all_skeleton': 'Waxholm_Template/*/{map_id}/All_*_skeletonised.nii.gz',
    'skeleton_mask':
    'Waxholm_Template/*/{map_id}/mean_FA_skeleton_mask.nii.gz',
    'all_image': 'Waxholm_Template/*/{map_id}/All_{map_id}_WAX.nii.gz',
    'mean_FA': 'Waxholm_Template/*/{map_id}/mean_FA.nii.gz',
}

selectfiles = Node(SelectFiles(templates, base_directory=experiment_dir),
                   name="selectfiles")
#-----------------------------------------------------------------------------------------------------
                 (realign, art, [('realigned_files', 'realigned_files'),
                                 ('mean_image', 'mask_file'),
                                 ('realignment_parameters',
                                  'realignment_parameters')]),
                 (realign, smooth, [('realigned_files', 'in_files')]),
                 ])


###
# Input & Output Stream

# Infosource - a function free node to iterate over the list of subject names
infosource = Node(IdentityInterface(fields=['subject_id',
                                            'session_id']),
                  name="infosource")
infosource.iterables = [('subject_id', subject_list),
                        ('session_id', session_list)]

# SelectFiles
templates = {'func': 'data/{subject_id}/{session_id}.nii.gz'}
selectfiles = Node(SelectFiles(templates,
                               base_directory=experiment_dir),
                   name="selectfiles")

# Datasink
datasink = Node(DataSink(base_directory=experiment_dir,
                         container=output_dir),
                name="datasink")

# Use the following DataSink output substitutions
substitutions = [('_subject_id', ''),
                 ('_session_id_', '')]
Пример #49
0
def run_workflow(undist):
    # ------------------ Specify variables
    ds_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

    data_dir = ds_root
    output_dir = 'motion-correction'
    working_dir = 'workingdirs/motion-correction'

    # ------------------ Input Files
    infosource = Node(IdentityInterface(fields=[
        'subject_id',
        'session_id',
        'use_contours',
        'smooth',
        'dof',
        'mcflirt_stages',
    ]), name="infosource")

    infosource.iterables = [
        ('session_id', session_list),
        ('subject_id', subject_list),
        ('smooth', [1.0]),
        # ('dof', [6]),
        # ('mcflirt_stages', [3]),
    ]
    
    if undist:
        ud_flag = 'preproc_undist_PLUS'
    else:
        ud_flag = 'preproc' 
    
    # SelectFiles
    templates = {
        'funcs':
        'resampled-isotropic-1mm/sub-{subject_id}/ses-{session_id}/func/'
            'sub-{subject_id}_ses-{session_id}_'
            'task-*run-01*_bold_res-1x1x1_' + ud_flag + '.nii.gz',

        'manualweights':
        'manual-masks/sub-eddy/ses-20170511/func/'
            'sub-eddy_ses-20170511_task-curvetracing_run-01_frame-50_bold_'
            'res-1x1x1_manualweights.nii.gz',

    }
    inputfiles = Node(
        nio.SelectFiles(templates,
                        base_directory=data_dir), name="input_files")

    # ------------------ Output Files
    # Datasink
    outputfiles = Node(nio.DataSink(
        base_directory=ds_root,
        container=output_dir,
        parameterization=True),
        name="output_files")

    # Use the following DataSink output substitutions
    outputfiles.inputs.substitutions = [
        ('subject_id_', 'sub-'),
        ('session_id_', 'ses-'),
        ('/motioncorrected/', '/'),
        ('_mcf.nii.gz', '.nii.gz')
        # BIDS Extension Proposal: BEP003
        # ('_resample.nii.gz', '_res-1x1x1_preproc.nii.gz'),
        # remove subdirectories:
        # ('resampled-isotropic-1mm/isoxfm-1mm', 'resampled-isotropic-1mm'),
        # ('resampled-isotropic-1mm/mriconv-1mm', 'resampled-isotropic-1mm'),
    ]
    # Put result into a BIDS-like format
    outputfiles.inputs.regexp_substitutions = [
        (r'_ses-([a-zA-Z0-9]*)_sub-([a-zA-Z0-9]*)', r'sub-\2/ses-\1'),
        (r'_mcflirt[0-9]+/', r'func/'),
    ]

    # -------------------------------------------- Create Pipeline
    workflow = Workflow(
        name='motion_correction',
        base_dir=os.path.join(ds_root, working_dir))

    workflow.connect([(infosource, inputfiles,
                      [('subject_id', 'subject_id'),
                       ('session_id', 'session_id'),
                       ('use_contours', 'use_contours'),
                       ('mcflirt_stages', 'stages'),
                       ('smooth', 'smooth'),
                       ('dof', 'dof'),
                       ])])

    mc = create_workflow_afni()

    workflow.connect(inputfiles, 'funcs',
                     mc, 'in.funcs')
    workflow.connect(inputfiles, 'manualweights',
                     mc, 'in.manualweights')
    workflow.connect(inputfiles, 'manualweights_func_ref',
                     mc, 'in.manualweights_func_ref')
    workflow.connect(mc, 'mc.out_file',
                     outputfiles, 'motioncorrected')

    workflow.stop_on_first_crash = True
    workflow.keep_inputs = True
    workflow.remove_unnecessary_outputs = False
    workflow.write_graph()
    workflow.run()
Пример #50
0
# directories
working_dir = '/scr/ilz3/myelinconnect/working_dir/' 
data_dir= '/scr/ilz3/myelinconnect/struct/'
out_dir = '/scr/ilz3/myelinconnect/struct/medial_wall'
# set fsl output type to nii.gz
fsl.FSLCommand.set_default_output_type('NIFTI_GZ')

# main workflow
medwall = Workflow(name='medwall')
medwall.base_dir = working_dir
medwall.config['execution']['crashdump_dir'] = medwall.base_dir + "/crash_files"

# iterate over subjects
subject_infosource = Node(util.IdentityInterface(fields=['subject']), 
                  name='subject_infosource')
subject_infosource.iterables=[('subject', subjects_db)]

# select files
templates={'sub_gm': 'medial_wall/input/{subject}*_sub_gm.nii.gz',
           'sub_csf': 'medial_wall/input/{subject}*_sub_csf.nii.gz',
           'thickness_rh' : 'thickness/{subject}*right_cortex_thick.nii.gz',
           'thickness_lh' : 'thickness/{subject}*left_cortex_thick.nii.gz',}

selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                   name="selectfiles")

medwall.connect([(subject_infosource, selectfiles, [('subject', 'subject')])
                 ])

addmasks= Node(fsl.BinaryMaths(operation='add'),
               name='addmasks')
Пример #51
0
working_dir = '/scr/ilz3/myelinconnect/working_dir/' 
data_dir= '/scr/ilz3/myelinconnect/'
out_dir = '/scr/ilz3/myelinconnect/final_struct_space/rest1_1_trans'

# set fsl output type to nii.gz
fsl.FSLCommand.set_default_output_type('NIFTI_GZ')

# main workflow
smooth = Workflow(name='smooth')
smooth.base_dir = working_dir
smooth.config['execution']['crashdump_dir'] = smooth.base_dir + "/crash_files"

# iterate over subjects
subject_infosource = Node(util.IdentityInterface(fields=['subject']), 
                  name='subject_infosource')
subject_infosource.iterables=[('subject', subjects_db)]

# iterate over sessions
session_infosource = Node(util.IdentityInterface(fields=['session']), 
                  name='session_infosource')
session_infosource.iterables=[('session', sessions)]

# select files
templates={'rest': 'final_struct_space/rest1_1_trans/{subject}_{session}_denoised_trans.nii.gz'
           }    
selectfiles = Node(nio.SelectFiles(templates, base_directory=data_dir),
                   name="selectfiles")

smooth.connect([(subject_infosource, selectfiles, [('subject', 'subject')]),
                 (session_infosource, selectfiles, [('session', 'session')])
                 ])
Пример #52
0
def calc_local_metrics(
    preprocessed_data_dir,
    subject_id,
    parcellations_dict,
    bp_freq_list,
    fd_thresh,
    working_dir,
    ds_dir,
    use_n_procs,
    plugin_name,
):
    import os
    from nipype import config
    from nipype.pipeline.engine import Node, Workflow, MapNode
    import nipype.interfaces.utility as util
    import nipype.interfaces.io as nio
    import nipype.interfaces.fsl as fsl
    import utils as calc_metrics_utils

    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type("NIFTI_GZ")

    wf = Workflow(name="LeiCA_LIFE_metrics")
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(
        logging=dict(workflow_level="DEBUG"),
        execution={"stop_on_first_crash": True, "remove_unnecessary_outputs": True, "job_finished_timeout": 15},
    )
    config.update_config(nipype_cfg)
    wf.config["execution"]["crashdump_dir"] = os.path.join(working_dir, "crash")

    ds = Node(nio.DataSink(base_directory=ds_dir), name="ds")
    ds.inputs.regexp_substitutions = [
        ("MNI_resampled_brain_mask_calc.nii.gz", "falff.nii.gz"),
        ("residual_filtered_3dT.nii.gz", "alff.nii.gz"),
        ("_parcellation_", ""),
        ("_bp_freqs_", "bp_"),
    ]

    #####################
    # ITERATORS
    #####################
    # PARCELLATION ITERATOR
    parcellation_infosource = Node(util.IdentityInterface(fields=["parcellation"]), name="parcellation_infosource")
    parcellation_infosource.iterables = ("parcellation", parcellations_dict.keys())

    bp_filter_infosource = Node(util.IdentityInterface(fields=["bp_freqs"]), name="bp_filter_infosource")
    bp_filter_infosource.iterables = ("bp_freqs", bp_freq_list)

    selectfiles = Node(
        nio.SelectFiles(
            {
                "parcellation_time_series": "{subject_id}/con_mat/parcellated_time_series/bp_{bp_freqs}/{parcellation}/parcellation_time_series.npy"
            },
            base_directory=preprocessed_data_dir,
        ),
        name="selectfiles",
    )
    selectfiles.inputs.subject_id = subject_id
    wf.connect(parcellation_infosource, "parcellation", selectfiles, "parcellation")
    wf.connect(bp_filter_infosource, "bp_freqs", selectfiles, "bp_freqs")

    fd_file = Node(
        nio.SelectFiles({"fd_p": "{subject_id}/QC/FD_P_ts"}, base_directory=preprocessed_data_dir), name="fd_file"
    )
    fd_file.inputs.subject_id = subject_id

    ##############
    ## CON MATS
    ##############
    ##############
    ## extract ts
    ##############

    get_good_trs = Node(
        util.Function(
            input_names=["fd_file", "fd_thresh"],
            output_names=["good_trs", "fd_scrubbed_file"],
            function=calc_metrics_utils.get_good_trs,
        ),
        name="get_good_trs",
    )
    wf.connect(fd_file, "fd_p", get_good_trs, "fd_file")
    get_good_trs.inputs.fd_thresh = fd_thresh

    parcellated_ts_scrubbed = Node(
        util.Function(
            input_names=["parcellation_time_series_file", "good_trs"],
            output_names=["parcellation_time_series_scrubbed"],
            function=calc_metrics_utils.parcellation_time_series_scrubbing,
        ),
        name="parcellated_ts_scrubbed",
    )

    wf.connect(selectfiles, "parcellation_time_series", parcellated_ts_scrubbed, "parcellation_time_series_file")
    wf.connect(get_good_trs, "good_trs", parcellated_ts_scrubbed, "good_trs")

    ##############
    ## get conmat
    ##############
    con_mat = Node(
        util.Function(
            input_names=["in_data", "extraction_method"],
            output_names=["matrix", "matrix_file"],
            function=calc_metrics_utils.calculate_connectivity_matrix,
        ),
        name="con_mat",
    )
    con_mat.inputs.extraction_method = "correlation"
    wf.connect(parcellated_ts_scrubbed, "parcellation_time_series_scrubbed", con_mat, "in_data")

    ##############
    ## ds
    ##############

    wf.connect(get_good_trs, "fd_scrubbed_file", ds, "QC.@fd_scrubbed_file")
    fd_str = ("%.1f" % fd_thresh).replace(".", "_")
    wf.connect(con_mat, "matrix_file", ds, "con_mat.matrix_scrubbed_%s.@mat" % fd_str)

    # wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    # wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    # wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == "CondorDAGMan":
        wf.run(plugin=plugin_name, plugin_args={"initial_specs": "request_memory = 1500"})
    if plugin_name == "MultiProc":
        wf.run(plugin=plugin_name, plugin_args={"n_procs": use_n_procs})
Пример #53
0
Created on Tue Aug 25 11:39:05 2015

@author: craigmoodie
"""

from nipype.pipeline.engine import Workflow, Node, MapNode
from variables import data_dir, work_dir, subject_list, plugin, plugin_args


surface_workflow = Workflow(name="qc_workflow")

surface_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)]


from nipype.interfaces.freesurfer import ReconAll
reconall = Node(ReconAll(), name = "Recon_All")
reconall.inputs.subject_id = "subject_id"
reconall.inputs.directive = 'all'
reconall.inputs.subjects_dir = data_dir
#reconall.inputs.T1_files = "T1"
#reconall.run()

surface_workflow.connect(file_list,"T1", reconall, "T1_files")
surface_workflow.run(plugin=plugin, plugin_args=plugin_args)
Пример #54
0
def main():

    #######################
    # Commandline Arguments
    #######################
    # list of subject identifiers
    task_name = "Training" if training else "Test"
    print(project_folder, subject_list, task_name, nb_prc)

    #############################################################
    # Extracting fMRI Params (Only works with Kamitani's Dataset)
    #############################################################
    TR = 3.0
    voxel_size = (3, 3, 3)
    number_of_slices = 50
    json_file1 = opj(project_folder,
                     "dataset/ds001246-download/task-imagery_bold.json")
    json_file2 = opj(project_folder,
                     "dataset/ds001246-download/task-perception_bold.json")

    file = open(json_file1)
    data = json.load(file)
    slice_timing1 = data['SliceTiming']
    file.close()

    file = open(json_file2)
    data = json.load(file)
    slice_timing2 = data['SliceTiming']
    file.close()

    sorted1 = np.argsort(slice_timing1)
    sorted2 = np.argsort(slice_timing2)
    print(np.all(sorted1 == sorted2))

    slice_order = list(sorted1 + 1)
    print("Slice order:", slice_order)

    ##########################
    # Creating essential nodes
    ##########################
    # Model Spec
    modelspec_node = Node(SpecifySPMModel(concatenate_runs=True,
                                          input_units='secs',
                                          output_units='secs',
                                          time_repetition=TR,
                                          high_pass_filter_cutoff=128),
                          name='modelspec')

    # Level1Design - Generates a SPM design matrix
    level1design_node = Node(Level1Design(bases={'hrf': {
        'derivs': [0, 0]
    }},
                                          timing_units='secs',
                                          interscan_interval=TR,
                                          model_serial_correlations='AR(1)',
                                          mask_threshold='-Inf'),
                             name="level1design")

    # EstimateModel - estimate the parameters of the model (GLM)
    level1estimate_node = Node(
        EstimateModel(estimation_method={'Classical': 1}),
        name="level1estimate")

    # Infosource - a function free node to iterate over the list of subject names
    infosrc_subjects = Node(IdentityInterface(fields=['subject_id']),
                            name="infosrc_subjects")
    infosrc_subjects.iterables = [('subject_id', subject_list)]

    # SelectFiles - it select files based on template matching
    tsv_file = opj('dataset', 'ds001246-download', '{subject_id}',
                   'ses-p*' + task_name + '*', 'func',
                   '{subject_id}_ses-p*' + task_name + '*_task-*_events.tsv')
    reg_file = opj('preprocess', '_subject_id_{subject_id}',
                   '_session_id_ses-p*' + task_name + '*', 'Realign',
                   'rp_a{subject_id}_ses-p*' + task_name + '*_task-*_bold.txt')
    func_file = opj(
        'preprocess', '_subject_id_{subject_id}',
        '_session_id_ses-p*' + task_name + '*', 'Coregister',
        'rara{subject_id}_ses-p*' + task_name + '*_task-*_bold.nii')
    mask_file = opj('datasink', 'preprocessed_masks', '{subject_id}',
                    '{subject_id}_full_mask.nii')

    templates = {
        'tsv': tsv_file,
        'reg': reg_file,
        'func': func_file,
        'mask': mask_file
    }

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

    # Subject Info
    subject_info_node = Node(Function(
        input_names=['tsv_files'],
        output_names=['subject_info'],
        function=read_tsv_train if training else read_tsv_test),
                             name='subject_info')

    # Datasink - creates output folder for important outputs
    datasink_node = Node(DataSink(base_directory=project_folder,
                                  container='datasink'),
                         name="datasink")

    substitutions = [('_subject_id_', '')]
    datasink_node.inputs.substitutions = substitutions

    #####################
    # Create the workflow
    #####################
    wf_name = 'glm_train_nomod' if training else 'glm_test'
    glm = Workflow(name=wf_name)
    glm.base_dir = project_folder

    # connect infosource to selectfile
    glm.connect([(infosrc_subjects, selectfiles, [('subject_id', 'subject_id')
                                                  ])])
    glm.connect([(selectfiles, subject_info_node, [('tsv', 'tsv_files')])])

    # connect infos to modelspec
    glm.connect([(subject_info_node, modelspec_node, [('subject_info',
                                                       'subject_info')])])
    glm.connect([(selectfiles, modelspec_node, [('reg',
                                                 'realignment_parameters')])])
    glm.connect([(selectfiles, modelspec_node, [('func', 'functional_runs')])])

    # connect modelspec to level1design
    glm.connect([(modelspec_node, level1design_node, [('session_info',
                                                       'session_info')])])
    glm.connect([(selectfiles, level1design_node, [('mask', 'mask_image')])])

    # connect design to estimate
    glm.connect([(level1design_node, level1estimate_node, [('spm_mat_file',
                                                            'spm_mat_file')])])

    # keeping estimate files params
    glm.connect([(level1estimate_node, datasink_node,
                  [('mask_image', f'{wf_name}.@mask_img')])])
    glm.connect([(level1estimate_node, datasink_node,
                  [('beta_images', f'{wf_name}.@beta_imgs')])])
    glm.connect([(level1estimate_node, datasink_node,
                  [('residual_image', f'{wf_name}.@res_img')])])
    glm.connect([(level1estimate_node, datasink_node,
                  [('RPVimage', f'{wf_name}.@rpv_img')])])
    glm.connect([(level1estimate_node, datasink_node,
                  [('spm_mat_file', f'{wf_name}.@spm_mat_file')])])

    glm.write_graph(graph2use='flat', format='png', simple_form=True)
    #     from IPython.display import Image
    #     Image(filename=opj(glm.base_dir, {wf_name}, 'graph_detailed.png'))

    ##################
    # Run the workflow
    ##################
    glm.run('MultiProc', plugin_args={'n_procs': nb_prc})
Пример #55
0
def create_volatlas_workflow(wf_name, wf_base_dir, subject_list, cnxn_names,
                             fstr_dict, ref_file, agg_cnxn_names_dict):

    from nipype.pipeline import engine as pe
    from nipype.pipeline.engine import Node, JoinNode, MapNode, Workflow

    from nipype.pipeline.engine.utils import IdentityInterface
    from nipype.interfaces import Function

    from nipype.interfaces.io import DataSink
    """
  Variables
  """

    dpy_fstr = fstr_dict['dpy']
    warp_fstr = fstr_dict['warp']
    parc_fstr = fstr_dict['parc']
    cnxn_mapping_fstr = fstr_dict['cnxn_mapping']
    """
  Node: Infosource
  """

    # (iterates over subjects)
    def mirror(subject_id):
        return subject_id

    mirror_npfunc = Function(['subject_id'], ['subject_id'], mirror)

    node__infosource = Node(interface=mirror_npfunc, name="infosource")
    node__infosource.iterables = [("subject_id", subject_list)]
    """
  Node: Get data
  """

    # (also iterates over cnxn ids)

    def get_sub_files_func(subject_id, cnxn_name, dpy_fstr, warp_fstr,
                           parc_fstr, cnxn_mapping_fstr):
        dpy_file = dpy_fstr % subject_id
        cnxn_mapping_file = cnxn_mapping_fstr % subject_id
        parc_file = parc_fstr % subject_id
        warp_file = warp_fstr % subject_id

        return dpy_file, parc_file, warp_file, cnxn_mapping_file, cnxn_name, subject_id

    get_sub_files_npfunc = Function([
        'subject_id', 'cnxn_name', 'dpy_fstr', 'warp_fstr', 'parc_fstr',
        'cnxn_mapping_fstr'
    ], [
        'dpy_file', 'parc_file', 'warp_file', 'cnxn_mapping_file', 'cnxn_name',
        'subject_id'
    ], get_sub_files_func)

    node__datasource = Node(interface=get_sub_files_npfunc, name='datasource')
    node__datasource.inputs.dpy_fstr = dpy_fstr
    node__datasource.inputs.parc_fstr = parc_fstr
    node__datasource.inputs.warp_fstr = warp_fstr
    node__datasource.inputs.cnxn_mapping_fstr = cnxn_mapping_fstr
    node__datasource.iterables = [('cnxn_name', cnxn_names)]
    """
  Node: Make sub cnxn visitation map
  """

    make_sub_vismap_npfunc = Function([
        'sub', 'dpy_file', 'parc_file', 'warp_file', 'ref_file',
        'cnxn_inds_file', 'cnxn_name', 'vismap_fstr'
    ], ['sub_vismap_file'], make_sub_cnxn_visitation_map)

    node__makesubvismap = Node(interface=make_sub_vismap_npfunc,
                               name="make_sub_vismap")

    node__makesubvismap.inputs.ref_file = ref_file
    node__makesubvismap.inputs.vismap_fstr = 'temp_vismap_%s.nii.gz'
    #node__makesubvismap.inputs.overwrite=True
    """
  Node: make grp cnxn visitation map
  """

    make_grp_vismap_npfunc = Function(
        ['cnxn_name', 'sub_vismaps', 'grp_vismap_fstr', 'subs_list'],
        ['grp_vismap_fpath', 'grp_vismap_norm_fpath', 'subs_list_file'],
        make_group_cnxn_visitation_map)

    node__makegrpvismap = JoinNode(interface=make_grp_vismap_npfunc,
                                   name='make_grp_vismap',
                                   joinsource="infosource",
                                   joinfield=["sub_vismaps",
                                              'subs_list'])  #subject_id")

    node__makegrpvismap.inputs.grp_vismap_fstr = 'grp_vismap_%s.nii.gz'  # this needs to be changed to come from previous node in wf
    """
  Node: aggregate group cnxn visitation map
  """
    # (to do...)

    agg_grp_vismap_npfunc = Function(['in_files', 'cnxn_names', 'outfname'],
                                     ['agg_image_file', 'agg_list_file'],
                                     aggregate_grp_vismap,
                                     imports=['import os'])

    node__agggrpvismap = JoinNode(interface=agg_grp_vismap_npfunc,
                                  name='agg_grp_vismap',
                                  joinsource="datasource",
                                  joinfield=["in_files"])

    node__agggrpvismap.iterables = [("cnxn_names",
                                     agg_cnxn_names_dict.values()),
                                    ("outfname", agg_cnxn_names_dict.keys())]
    node__agggrpvismap.synchronize = True
    """
  Node: datasink
  """
    # I want to use a mapnode for this, but can't get it to work
    # so have to settle with this followed by a command line copy...

    # (if you don't have a mapnode, just get same result as outputs of agggrpvismap node...)
    node__datasink = Node(DataSink(), name='datasink')
    node__datasink.inputs.base_directory = wf_base_dir

    #node__datasinkniifile = MapNode(DataSink(infields=['agg_image_file']),name='ds_nii', iterfield=['agg_image_file'])
    #node__datasinkniifile.inputs.base_directory=wf_base_dir
    #node__datasinktxtfile = MapNode(DataSink(infields=['agg_list_file']),name='ds_txt', iterfield=['agg_list_file'])
    #node__datasinktxtfile.inputs.base_directory=wf_base_dir
    """
  Workflow: put it all together
  """

    wf = pe.Workflow(name=wf_name)
    wf.base_dir = wf_base_dir

    wf.connect(node__infosource, 'subject_id', node__datasource, 'subject_id')
    wf.connect(node__datasource, 'subject_id', node__makesubvismap, 'sub')
    wf.connect(node__datasource, 'dpy_file', node__makesubvismap, 'dpy_file')
    wf.connect(node__datasource, 'parc_file', node__makesubvismap, 'parc_file')
    wf.connect(node__datasource, 'warp_file', node__makesubvismap, 'warp_file')
    wf.connect(node__datasource, 'cnxn_mapping_file', node__makesubvismap,
               'cnxn_inds_file')
    wf.connect(node__datasource, 'cnxn_name', node__makesubvismap, 'cnxn_name')
    wf.connect(node__makesubvismap, 'sub_vismap_file', node__makegrpvismap,
               'sub_vismaps')
    wf.connect(node__datasource, 'cnxn_name', node__makegrpvismap, 'cnxn_name')
    wf.connect(node__datasource, 'subject_id', node__makegrpvismap,
               'subs_list')

    wf.connect(node__makegrpvismap, 'grp_vismap_norm_fpath',
               node__agggrpvismap, 'in_files')

    wf.connect(node__agggrpvismap, 'agg_image_file', node__datasink,
               '@agg_image_file')
    wf.connect(node__agggrpvismap, 'agg_list_file', node__datasink,
               '@agg_list_file')

    #wf.connect(node__agggrpvismap, 'agg_image_file', node__datasinkniifile, '@agg_image_file')
    #wf.connect(node__agggrpvismap, 'agg_list_file',  node__datasinktxtfile, '@agg_list_file')

    return wf
Пример #56
0
def Lesion_extractor(
    name='Lesion_Extractor',
    wf_name='Test',
    base_dir='/homes_unix/alaurent/',
    input_dir=None,
    subjects=None,
    main=None,
    acc=None,
    atlas='/homes_unix/alaurent/cbstools-public-master/atlases/brain-segmentation-prior3.0/brain-atlas-quant-3.0.8.txt'
):

    wf = Workflow(wf_name)
    wf.base_dir = base_dir

    #file = open(subjects,"r")
    #subjects = file.read().split("\n")
    #file.close()

    # Subject List
    subjectList = Node(IdentityInterface(fields=['subject_id'],
                                         mandatory_inputs=True),
                       name="subList")
    subjectList.iterables = ('subject_id', [
        sub for sub in subjects if sub != '' and sub != '\n'
    ])

    # T1w and FLAIR
    scanList = Node(DataGrabber(infields=['subject_id'],
                                outfields=['T1', 'FLAIR']),
                    name="scanList")
    scanList.inputs.base_directory = input_dir
    scanList.inputs.ignore_exception = False
    scanList.inputs.raise_on_empty = True
    scanList.inputs.sort_filelist = True
    #scanList.inputs.template = '%s/%s.nii'
    #scanList.inputs.template_args = {'T1': [['subject_id','T1*']],
    #                                 'FLAIR': [['subject_id','FLAIR*']]}
    scanList.inputs.template = '%s/anat/%s'
    scanList.inputs.template_args = {
        'T1': [['subject_id', '*_T1w.nii.gz']],
        'FLAIR': [['subject_id', '*_FLAIR.nii.gz']]
    }
    wf.connect(subjectList, "subject_id", scanList, "subject_id")

    #     # T1w and FLAIR
    #     dg = Node(DataGrabber(outfields=['T1', 'FLAIR']), name="T1wFLAIR")
    #     dg.inputs.base_directory = "/homes_unix/alaurent/LesionPipeline"
    #     dg.inputs.template = "%s/NIFTI/*.nii.gz"
    #     dg.inputs.template_args['T1']=[['7']]
    #     dg.inputs.template_args['FLAIR']=[['9']]
    #     dg.inputs.sort_filelist=True

    # Reorient Volume
    T1Conv = Node(Reorient2Std(), name="ReorientVolume")
    T1Conv.inputs.ignore_exception = False
    T1Conv.inputs.terminal_output = 'none'
    T1Conv.inputs.out_file = "T1_reoriented.nii.gz"
    wf.connect(scanList, "T1", T1Conv, "in_file")

    # Reorient Volume (2)
    T2flairConv = Node(Reorient2Std(), name="ReorientVolume2")
    T2flairConv.inputs.ignore_exception = False
    T2flairConv.inputs.terminal_output = 'none'
    T2flairConv.inputs.out_file = "FLAIR_reoriented.nii.gz"
    wf.connect(scanList, "FLAIR", T2flairConv, "in_file")

    # N3 Correction
    T1NUC = Node(N4BiasFieldCorrection(), name="N3Correction")
    T1NUC.inputs.dimension = 3
    T1NUC.inputs.environ = {'NSLOTS': '1'}
    T1NUC.inputs.ignore_exception = False
    T1NUC.inputs.num_threads = 1
    T1NUC.inputs.save_bias = False
    T1NUC.inputs.terminal_output = 'none'
    wf.connect(T1Conv, "out_file", T1NUC, "input_image")

    # N3 Correction (2)
    T2flairNUC = Node(N4BiasFieldCorrection(), name="N3Correction2")
    T2flairNUC.inputs.dimension = 3
    T2flairNUC.inputs.environ = {'NSLOTS': '1'}
    T2flairNUC.inputs.ignore_exception = False
    T2flairNUC.inputs.num_threads = 1
    T2flairNUC.inputs.save_bias = False
    T2flairNUC.inputs.terminal_output = 'none'
    wf.connect(T2flairConv, "out_file", T2flairNUC, "input_image")
    '''
    #####################
    ### PRE-NORMALIZE ###
    #####################
    To make sure there's no outlier values (negative, or really high) to offset the initialization steps
    '''

    # Intensity Range Normalization
    getMaxT1NUC = Node(ImageStats(op_string='-r'), name="getMaxT1NUC")
    wf.connect(T1NUC, 'output_image', getMaxT1NUC, 'in_file')

    T1NUCirn = Node(AbcImageMaths(), name="IntensityNormalization")
    T1NUCirn.inputs.op_string = "-div"
    T1NUCirn.inputs.out_file = "normT1.nii.gz"
    wf.connect(T1NUC, 'output_image', T1NUCirn, 'in_file')
    wf.connect(getMaxT1NUC, ('out_stat', getElementFromList, 1), T1NUCirn,
               "op_value")

    # Intensity Range Normalization (2)
    getMaxT2NUC = Node(ImageStats(op_string='-r'), name="getMaxT2")
    wf.connect(T2flairNUC, 'output_image', getMaxT2NUC, 'in_file')

    T2NUCirn = Node(AbcImageMaths(), name="IntensityNormalization2")
    T2NUCirn.inputs.op_string = "-div"
    T2NUCirn.inputs.out_file = "normT2.nii.gz"
    wf.connect(T2flairNUC, 'output_image', T2NUCirn, 'in_file')
    wf.connect(getMaxT2NUC, ('out_stat', getElementFromList, 1), T2NUCirn,
               "op_value")
    '''
    ########################
    #### COREGISTRATION ####
    ########################
    '''

    # Optimized Automated Registration
    T2flairCoreg = Node(FLIRT(), name="OptimizedAutomatedRegistration")
    T2flairCoreg.inputs.output_type = 'NIFTI_GZ'
    wf.connect(T2NUCirn, "out_file", T2flairCoreg, "in_file")
    wf.connect(T1NUCirn, "out_file", T2flairCoreg, "reference")
    '''    
    #########################
    #### SKULL-STRIPPING ####
    #########################
    '''

    # SPECTRE
    T1ss = Node(BET(), name="SPECTRE")
    T1ss.inputs.frac = 0.45  #0.4
    T1ss.inputs.mask = True
    T1ss.inputs.outline = True
    T1ss.inputs.robust = True
    wf.connect(T1NUCirn, "out_file", T1ss, "in_file")

    # Image Calculator
    T2ss = Node(ApplyMask(), name="ImageCalculator")
    wf.connect(T1ss, "mask_file", T2ss, "mask_file")
    wf.connect(T2flairCoreg, "out_file", T2ss, "in_file")
    '''
    ####################################
    #### 2nd LAYER OF N3 CORRECTION ####
    ####################################
    This time without the skull: there were some significant amounts of inhomogeneities leftover.
    '''

    # N3 Correction (3)
    T1ssNUC = Node(N4BiasFieldCorrection(), name="N3Correction3")
    T1ssNUC.inputs.dimension = 3
    T1ssNUC.inputs.environ = {'NSLOTS': '1'}
    T1ssNUC.inputs.ignore_exception = False
    T1ssNUC.inputs.num_threads = 1
    T1ssNUC.inputs.save_bias = False
    T1ssNUC.inputs.terminal_output = 'none'
    wf.connect(T1ss, "out_file", T1ssNUC, "input_image")

    # N3 Correction (4)
    T2ssNUC = Node(N4BiasFieldCorrection(), name="N3Correction4")
    T2ssNUC.inputs.dimension = 3
    T2ssNUC.inputs.environ = {'NSLOTS': '1'}
    T2ssNUC.inputs.ignore_exception = False
    T2ssNUC.inputs.num_threads = 1
    T2ssNUC.inputs.save_bias = False
    T2ssNUC.inputs.terminal_output = 'none'
    wf.connect(T2ss, "out_file", T2ssNUC, "input_image")
    '''
    ####################################
    ####    NORMALIZE FOR MGDM      ####
    ####################################
    This normalization is a bit aggressive: only useful to have a 
    cropped dynamic range into MGDM, but possibly harmful to further 
    processing, so the unprocessed images are passed to the subsequent steps.
    '''

    # Intensity Range Normalization
    getMaxT1ssNUC = Node(ImageStats(op_string='-r'), name="getMaxT1ssNUC")
    wf.connect(T1ssNUC, 'output_image', getMaxT1ssNUC, 'in_file')

    T1ssNUCirn = Node(AbcImageMaths(), name="IntensityNormalization3")
    T1ssNUCirn.inputs.op_string = "-div"
    T1ssNUCirn.inputs.out_file = "normT1ss.nii.gz"
    wf.connect(T1ssNUC, 'output_image', T1ssNUCirn, 'in_file')
    wf.connect(getMaxT1ssNUC, ('out_stat', getElementFromList, 1), T1ssNUCirn,
               "op_value")

    # Intensity Range Normalization (2)
    getMaxT2ssNUC = Node(ImageStats(op_string='-r'), name="getMaxT2ssNUC")
    wf.connect(T2ssNUC, 'output_image', getMaxT2ssNUC, 'in_file')

    T2ssNUCirn = Node(AbcImageMaths(), name="IntensityNormalization4")
    T2ssNUCirn.inputs.op_string = "-div"
    T2ssNUCirn.inputs.out_file = "normT2ss.nii.gz"
    wf.connect(T2ssNUC, 'output_image', T2ssNUCirn, 'in_file')
    wf.connect(getMaxT2ssNUC, ('out_stat', getElementFromList, 1), T2ssNUCirn,
               "op_value")
    '''
    ####################################
    ####      ESTIMATE CSF PV       ####
    ####################################
    Here we try to get a better handle on CSF voxels to help the segmentation step
    '''

    # Recursive Ridge Diffusion
    CSF_pv = Node(RecursiveRidgeDiffusion(), name='estimate_CSF_pv')
    CSF_pv.plugin_args = {'sbatch_args': '--mem 6000'}
    CSF_pv.inputs.ridge_intensities = "dark"
    CSF_pv.inputs.ridge_filter = "2D"
    CSF_pv.inputs.orientation = "undefined"
    CSF_pv.inputs.ang_factor = 1.0
    CSF_pv.inputs.min_scale = 0
    CSF_pv.inputs.max_scale = 3
    CSF_pv.inputs.propagation_model = "diffusion"
    CSF_pv.inputs.diffusion_factor = 0.5
    CSF_pv.inputs.similarity_scale = 0.1
    CSF_pv.inputs.neighborhood_size = 4
    CSF_pv.inputs.max_iter = 100
    CSF_pv.inputs.max_diff = 0.001
    CSF_pv.inputs.save_data = True
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, CSF_pv.name),
        CSF_pv, 'output_dir')
    wf.connect(T1ssNUCirn, 'out_file', CSF_pv, 'input_image')
    '''
    ####################################
    ####            MGDM            ####
    ####################################
    '''

    # Multi-contrast Brain Segmentation
    MGDM = Node(MGDMSegmentation(), name='MGDM')
    MGDM.plugin_args = {'sbatch_args': '--mem 7000'}
    MGDM.inputs.contrast_type1 = "Mprage3T"
    MGDM.inputs.contrast_type2 = "FLAIR3T"
    MGDM.inputs.contrast_type3 = "PVDURA"
    MGDM.inputs.save_data = True
    MGDM.inputs.atlas_file = atlas
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, MGDM.name), MGDM,
        'output_dir')
    wf.connect(T1ssNUCirn, 'out_file', MGDM, 'contrast_image1')
    wf.connect(T2ssNUCirn, 'out_file', MGDM, 'contrast_image2')
    wf.connect(CSF_pv, 'ridge_pv', MGDM, 'contrast_image3')

    # Enhance Region Contrast
    ERC = Node(EnhanceRegionContrast(), name='ERC')
    ERC.plugin_args = {'sbatch_args': '--mem 7000'}
    ERC.inputs.enhanced_region = "crwm"
    ERC.inputs.contrast_background = "crgm"
    ERC.inputs.partial_voluming_distance = 2.0
    ERC.inputs.save_data = True
    ERC.inputs.atlas_file = atlas
    wf.connect(subjectList,
               ('subject_id', createOutputDir, wf.base_dir, wf.name, ERC.name),
               ERC, 'output_dir')
    wf.connect(T1ssNUC, 'output_image', ERC, 'intensity_image')
    wf.connect(MGDM, 'segmentation', ERC, 'segmentation_image')
    wf.connect(MGDM, 'distance', ERC, 'levelset_boundary_image')

    # Enhance Region Contrast (2)
    ERC2 = Node(EnhanceRegionContrast(), name='ERC2')
    ERC2.plugin_args = {'sbatch_args': '--mem 7000'}
    ERC2.inputs.enhanced_region = "crwm"
    ERC2.inputs.contrast_background = "crgm"
    ERC2.inputs.partial_voluming_distance = 2.0
    ERC2.inputs.save_data = True
    ERC2.inputs.atlas_file = atlas
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, ERC2.name), ERC2,
        'output_dir')
    wf.connect(T2ssNUC, 'output_image', ERC2, 'intensity_image')
    wf.connect(MGDM, 'segmentation', ERC2, 'segmentation_image')
    wf.connect(MGDM, 'distance', ERC2, 'levelset_boundary_image')

    # Define Multi-Region Priors
    DMRP = Node(DefineMultiRegionPriors(), name='DefineMultRegPriors')
    DMRP.plugin_args = {'sbatch_args': '--mem 6000'}
    #DMRP.inputs.defined_region = "ventricle-horns"
    #DMRP.inputs.definition_method = "closest-distance"
    DMRP.inputs.distance_offset = 3.0
    DMRP.inputs.save_data = True
    DMRP.inputs.atlas_file = atlas
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, DMRP.name), DMRP,
        'output_dir')
    wf.connect(MGDM, 'segmentation', DMRP, 'segmentation_image')
    wf.connect(MGDM, 'distance', DMRP, 'levelset_boundary_image')
    '''
    ###############################################
    ####      REMOVE VENTRICLE POSTERIOR       ####
    ###############################################
    Due to topology constraints, the ventricles are often not fully segmented:
    here add back all ventricle voxels from the posterior probability (without the topology constraints)
    '''

    # Posterior label
    PostLabel = Node(Split(), name='PosteriorLabel')
    PostLabel.inputs.dimension = "t"
    wf.connect(MGDM, 'labels', PostLabel, 'in_file')

    # Posterior proba
    PostProba = Node(Split(), name='PosteriorProba')
    PostProba.inputs.dimension = "t"
    wf.connect(MGDM, 'memberships', PostProba, 'in_file')

    # Threshold binary mask : ventricle label part 1
    VentLabel1 = Node(Threshold(), name="VentricleLabel1")
    VentLabel1.inputs.thresh = 10.5
    VentLabel1.inputs.direction = "below"
    wf.connect(PostLabel, ("out_files", getFirstElement), VentLabel1,
               "in_file")

    # Threshold binary mask : ventricle label part 2
    VentLabel2 = Node(Threshold(), name="VentricleLabel2")
    VentLabel2.inputs.thresh = 13.5
    VentLabel2.inputs.direction = "above"
    wf.connect(VentLabel1, "out_file", VentLabel2, "in_file")

    # Image calculator : ventricle proba
    VentProba = Node(ImageMaths(), name="VentricleProba")
    VentProba.inputs.op_string = "-mul"
    VentProba.inputs.out_file = "ventproba.nii.gz"
    wf.connect(PostProba, ("out_files", getFirstElement), VentProba, "in_file")
    wf.connect(VentLabel2, "out_file", VentProba, "in_file2")

    # Image calculator : remove inter ventricles
    RmInterVent = Node(ImageMaths(), name="RemoveInterVent")
    RmInterVent.inputs.op_string = "-sub"
    RmInterVent.inputs.out_file = "rmintervent.nii.gz"
    wf.connect(ERC, "region_pv", RmInterVent, "in_file")
    wf.connect(DMRP, "inter_ventricular_pv", RmInterVent, "in_file2")

    # Image calculator : add horns
    AddHorns = Node(ImageMaths(), name="AddHorns")
    AddHorns.inputs.op_string = "-add"
    AddHorns.inputs.out_file = "rmvent.nii.gz"
    wf.connect(RmInterVent, "out_file", AddHorns, "in_file")
    wf.connect(DMRP, "ventricular_horns_pv", AddHorns, "in_file2")

    # Image calculator : remove ventricles
    RmVent = Node(ImageMaths(), name="RemoveVentricles")
    RmVent.inputs.op_string = "-sub"
    RmVent.inputs.out_file = "rmvent.nii.gz"
    wf.connect(AddHorns, "out_file", RmVent, "in_file")
    wf.connect(VentProba, "out_file", RmVent, "in_file2")

    # Image calculator : remove internal capsule
    RmIC = Node(ImageMaths(), name="RemoveInternalCap")
    RmIC.inputs.op_string = "-sub"
    RmIC.inputs.out_file = "rmic.nii.gz"
    wf.connect(RmVent, "out_file", RmIC, "in_file")
    wf.connect(DMRP, "internal_capsule_pv", RmIC, "in_file2")

    # Intensity Range Normalization (3)
    getMaxRmIC = Node(ImageStats(op_string='-r'), name="getMaxRmIC")
    wf.connect(RmIC, 'out_file', getMaxRmIC, 'in_file')

    RmICirn = Node(AbcImageMaths(), name="IntensityNormalization5")
    RmICirn.inputs.op_string = "-div"
    RmICirn.inputs.out_file = "normRmIC.nii.gz"
    wf.connect(RmIC, 'out_file', RmICirn, 'in_file')
    wf.connect(getMaxRmIC, ('out_stat', getElementFromList, 1), RmICirn,
               "op_value")

    # Probability To Levelset : WM orientation
    WM_Orient = Node(ProbabilityToLevelset(), name='WM_Orientation')
    WM_Orient.plugin_args = {'sbatch_args': '--mem 6000'}
    WM_Orient.inputs.save_data = True
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, WM_Orient.name),
        WM_Orient, 'output_dir')
    wf.connect(RmICirn, 'out_file', WM_Orient, 'probability_image')

    # Recursive Ridge Diffusion : PVS in WM only
    WM_pvs = Node(RecursiveRidgeDiffusion(), name='PVS_in_WM')
    WM_pvs.plugin_args = {'sbatch_args': '--mem 6000'}
    WM_pvs.inputs.ridge_intensities = "bright"
    WM_pvs.inputs.ridge_filter = "1D"
    WM_pvs.inputs.orientation = "orthogonal"
    WM_pvs.inputs.ang_factor = 1.0
    WM_pvs.inputs.min_scale = 0
    WM_pvs.inputs.max_scale = 3
    WM_pvs.inputs.propagation_model = "diffusion"
    WM_pvs.inputs.diffusion_factor = 1.0
    WM_pvs.inputs.similarity_scale = 1.0
    WM_pvs.inputs.neighborhood_size = 2
    WM_pvs.inputs.max_iter = 100
    WM_pvs.inputs.max_diff = 0.001
    WM_pvs.inputs.save_data = True
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, WM_pvs.name),
        WM_pvs, 'output_dir')
    wf.connect(ERC, 'background_proba', WM_pvs, 'input_image')
    wf.connect(WM_Orient, 'levelset', WM_pvs, 'surface_levelset')
    wf.connect(RmICirn, 'out_file', WM_pvs, 'loc_prior')

    # Extract Lesions : extract WM PVS
    extract_WM_pvs = Node(LesionExtraction(), name='ExtractPVSfromWM')
    extract_WM_pvs.plugin_args = {'sbatch_args': '--mem 6000'}
    extract_WM_pvs.inputs.gm_boundary_partial_vol_dist = 1.0
    extract_WM_pvs.inputs.csf_boundary_partial_vol_dist = 3.0
    extract_WM_pvs.inputs.lesion_clust_dist = 1.0
    extract_WM_pvs.inputs.prob_min_thresh = 0.1
    extract_WM_pvs.inputs.prob_max_thresh = 0.33
    extract_WM_pvs.inputs.small_lesion_size = 4.0
    extract_WM_pvs.inputs.save_data = True
    extract_WM_pvs.inputs.atlas_file = atlas
    wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir,
                             wf.name, extract_WM_pvs.name), extract_WM_pvs,
               'output_dir')
    wf.connect(WM_pvs, 'propagation', extract_WM_pvs, 'probability_image')
    wf.connect(MGDM, 'segmentation', extract_WM_pvs, 'segmentation_image')
    wf.connect(MGDM, 'distance', extract_WM_pvs, 'levelset_boundary_image')
    wf.connect(RmICirn, 'out_file', extract_WM_pvs, 'location_prior_image')
    '''
    2nd branch
    '''

    # Image calculator : internal capsule witout ventricules
    ICwoVent = Node(ImageMaths(), name="ICWithoutVentricules")
    ICwoVent.inputs.op_string = "-sub"
    ICwoVent.inputs.out_file = "icwovent.nii.gz"
    wf.connect(DMRP, "internal_capsule_pv", ICwoVent, "in_file")
    wf.connect(DMRP, "inter_ventricular_pv", ICwoVent, "in_file2")

    # Image calculator : remove ventricles IC
    RmVentIC = Node(ImageMaths(), name="RmVentIC")
    RmVentIC.inputs.op_string = "-sub"
    RmVentIC.inputs.out_file = "RmVentIC.nii.gz"
    wf.connect(ICwoVent, "out_file", RmVentIC, "in_file")
    wf.connect(VentProba, "out_file", RmVentIC, "in_file2")

    # Intensity Range Normalization (4)
    getMaxRmVentIC = Node(ImageStats(op_string='-r'), name="getMaxRmVentIC")
    wf.connect(RmVentIC, 'out_file', getMaxRmVentIC, 'in_file')

    RmVentICirn = Node(AbcImageMaths(), name="IntensityNormalization6")
    RmVentICirn.inputs.op_string = "-div"
    RmVentICirn.inputs.out_file = "normRmVentIC.nii.gz"
    wf.connect(RmVentIC, 'out_file', RmVentICirn, 'in_file')
    wf.connect(getMaxRmVentIC, ('out_stat', getElementFromList, 1),
               RmVentICirn, "op_value")

    # Probability To Levelset : IC orientation
    IC_Orient = Node(ProbabilityToLevelset(), name='IC_Orientation')
    IC_Orient.plugin_args = {'sbatch_args': '--mem 6000'}
    IC_Orient.inputs.save_data = True
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, IC_Orient.name),
        IC_Orient, 'output_dir')
    wf.connect(RmVentICirn, 'out_file', IC_Orient, 'probability_image')

    # Recursive Ridge Diffusion : PVS in IC only
    IC_pvs = Node(RecursiveRidgeDiffusion(), name='RecursiveRidgeDiffusion2')
    IC_pvs.plugin_args = {'sbatch_args': '--mem 6000'}
    IC_pvs.inputs.ridge_intensities = "bright"
    IC_pvs.inputs.ridge_filter = "1D"
    IC_pvs.inputs.orientation = "undefined"
    IC_pvs.inputs.ang_factor = 1.0
    IC_pvs.inputs.min_scale = 0
    IC_pvs.inputs.max_scale = 3
    IC_pvs.inputs.propagation_model = "diffusion"
    IC_pvs.inputs.diffusion_factor = 1.0
    IC_pvs.inputs.similarity_scale = 1.0
    IC_pvs.inputs.neighborhood_size = 2
    IC_pvs.inputs.max_iter = 100
    IC_pvs.inputs.max_diff = 0.001
    IC_pvs.inputs.save_data = True
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, IC_pvs.name),
        IC_pvs, 'output_dir')
    wf.connect(ERC, 'background_proba', IC_pvs, 'input_image')
    wf.connect(IC_Orient, 'levelset', IC_pvs, 'surface_levelset')
    wf.connect(RmVentICirn, 'out_file', IC_pvs, 'loc_prior')

    # Extract Lesions : extract IC PVS
    extract_IC_pvs = Node(LesionExtraction(), name='ExtractPVSfromIC')
    extract_IC_pvs.plugin_args = {'sbatch_args': '--mem 6000'}
    extract_IC_pvs.inputs.gm_boundary_partial_vol_dist = 1.0
    extract_IC_pvs.inputs.csf_boundary_partial_vol_dist = 4.0
    extract_IC_pvs.inputs.lesion_clust_dist = 1.0
    extract_IC_pvs.inputs.prob_min_thresh = 0.25
    extract_IC_pvs.inputs.prob_max_thresh = 0.5
    extract_IC_pvs.inputs.small_lesion_size = 4.0
    extract_IC_pvs.inputs.save_data = True
    extract_IC_pvs.inputs.atlas_file = atlas
    wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir,
                             wf.name, extract_IC_pvs.name), extract_IC_pvs,
               'output_dir')
    wf.connect(IC_pvs, 'propagation', extract_IC_pvs, 'probability_image')
    wf.connect(MGDM, 'segmentation', extract_IC_pvs, 'segmentation_image')
    wf.connect(MGDM, 'distance', extract_IC_pvs, 'levelset_boundary_image')
    wf.connect(RmVentICirn, 'out_file', extract_IC_pvs, 'location_prior_image')
    '''
    3rd branch
    '''

    # Image calculator :
    RmInter = Node(ImageMaths(), name="RemoveInterVentricules")
    RmInter.inputs.op_string = "-sub"
    RmInter.inputs.out_file = "rminter.nii.gz"
    wf.connect(ERC2, 'region_pv', RmInter, "in_file")
    wf.connect(DMRP, "inter_ventricular_pv", RmInter, "in_file2")

    # Image calculator :
    AddVentHorns = Node(ImageMaths(), name="AddVentHorns")
    AddVentHorns.inputs.op_string = "-add"
    AddVentHorns.inputs.out_file = "rminter.nii.gz"
    wf.connect(RmInter, 'out_file', AddVentHorns, "in_file")
    wf.connect(DMRP, "ventricular_horns_pv", AddVentHorns, "in_file2")

    # Intensity Range Normalization (5)
    getMaxAddVentHorns = Node(ImageStats(op_string='-r'),
                              name="getMaxAddVentHorns")
    wf.connect(AddVentHorns, 'out_file', getMaxAddVentHorns, 'in_file')

    AddVentHornsirn = Node(AbcImageMaths(), name="IntensityNormalization7")
    AddVentHornsirn.inputs.op_string = "-div"
    AddVentHornsirn.inputs.out_file = "normAddVentHorns.nii.gz"
    wf.connect(AddVentHorns, 'out_file', AddVentHornsirn, 'in_file')
    wf.connect(getMaxAddVentHorns, ('out_stat', getElementFromList, 1),
               AddVentHornsirn, "op_value")

    # Extract Lesions : extract White Matter Hyperintensities
    extract_WMH = Node(LesionExtraction(), name='Extract_WMH')
    extract_WMH.plugin_args = {'sbatch_args': '--mem 6000'}
    extract_WMH.inputs.gm_boundary_partial_vol_dist = 1.0
    extract_WMH.inputs.csf_boundary_partial_vol_dist = 2.0
    extract_WMH.inputs.lesion_clust_dist = 1.0
    extract_WMH.inputs.prob_min_thresh = 0.84
    extract_WMH.inputs.prob_max_thresh = 0.84
    extract_WMH.inputs.small_lesion_size = 4.0
    extract_WMH.inputs.save_data = True
    extract_WMH.inputs.atlas_file = atlas
    wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir,
                             wf.name, extract_WMH.name), extract_WMH,
               'output_dir')
    wf.connect(ERC2, 'background_proba', extract_WMH, 'probability_image')
    wf.connect(MGDM, 'segmentation', extract_WMH, 'segmentation_image')
    wf.connect(MGDM, 'distance', extract_WMH, 'levelset_boundary_image')
    wf.connect(AddVentHornsirn, 'out_file', extract_WMH,
               'location_prior_image')

    #===========================================================================
    # extract_WMH2 = extract_WMH.clone(name='Extract_WMH2')
    # extract_WMH2.inputs.gm_boundary_partial_vol_dist = 2.0
    # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_WMH2.name),extract_WMH2,'output_dir')
    # wf.connect(ERC2,'background_proba',extract_WMH2,'probability_image')
    # wf.connect(MGDM,'segmentation',extract_WMH2,'segmentation_image')
    # wf.connect(MGDM,'distance',extract_WMH2,'levelset_boundary_image')
    # wf.connect(AddVentHornsirn,'out_file',extract_WMH2,'location_prior_image')
    #
    # extract_WMH3 = extract_WMH.clone(name='Extract_WMH3')
    # extract_WMH3.inputs.gm_boundary_partial_vol_dist = 3.0
    # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_WMH3.name),extract_WMH3,'output_dir')
    # wf.connect(ERC2,'background_proba',extract_WMH3,'probability_image')
    # wf.connect(MGDM,'segmentation',extract_WMH3,'segmentation_image')
    # wf.connect(MGDM,'distance',extract_WMH3,'levelset_boundary_image')
    # wf.connect(AddVentHornsirn,'out_file',extract_WMH3,'location_prior_image')
    #===========================================================================
    '''
    ####################################
    ####     FINDING SMALL WMHs     ####
    ####################################
    Small round WMHs near the cortex are often missed by the main algorithm, 
    so we're adding this one that takes care of them.
    '''

    # Recursive Ridge Diffusion : round WMH detection
    round_WMH = Node(RecursiveRidgeDiffusion(), name='round_WMH')
    round_WMH.plugin_args = {'sbatch_args': '--mem 6000'}
    round_WMH.inputs.ridge_intensities = "bright"
    round_WMH.inputs.ridge_filter = "0D"
    round_WMH.inputs.orientation = "undefined"
    round_WMH.inputs.ang_factor = 1.0
    round_WMH.inputs.min_scale = 1
    round_WMH.inputs.max_scale = 4
    round_WMH.inputs.propagation_model = "none"
    round_WMH.inputs.diffusion_factor = 1.0
    round_WMH.inputs.similarity_scale = 0.1
    round_WMH.inputs.neighborhood_size = 4
    round_WMH.inputs.max_iter = 100
    round_WMH.inputs.max_diff = 0.001
    round_WMH.inputs.save_data = True
    wf.connect(
        subjectList,
        ('subject_id', createOutputDir, wf.base_dir, wf.name, round_WMH.name),
        round_WMH, 'output_dir')
    wf.connect(ERC2, 'background_proba', round_WMH, 'input_image')
    wf.connect(AddVentHornsirn, 'out_file', round_WMH, 'loc_prior')

    # Extract Lesions : extract round WMH
    extract_round_WMH = Node(LesionExtraction(), name='Extract_round_WMH')
    extract_round_WMH.plugin_args = {'sbatch_args': '--mem 6000'}
    extract_round_WMH.inputs.gm_boundary_partial_vol_dist = 1.0
    extract_round_WMH.inputs.csf_boundary_partial_vol_dist = 2.0
    extract_round_WMH.inputs.lesion_clust_dist = 1.0
    extract_round_WMH.inputs.prob_min_thresh = 0.33
    extract_round_WMH.inputs.prob_max_thresh = 0.33
    extract_round_WMH.inputs.small_lesion_size = 6.0
    extract_round_WMH.inputs.save_data = True
    extract_round_WMH.inputs.atlas_file = atlas
    wf.connect(subjectList, ('subject_id', createOutputDir, wf.base_dir,
                             wf.name, extract_round_WMH.name),
               extract_round_WMH, 'output_dir')
    wf.connect(round_WMH, 'ridge_pv', extract_round_WMH, 'probability_image')
    wf.connect(MGDM, 'segmentation', extract_round_WMH, 'segmentation_image')
    wf.connect(MGDM, 'distance', extract_round_WMH, 'levelset_boundary_image')
    wf.connect(AddVentHornsirn, 'out_file', extract_round_WMH,
               'location_prior_image')

    #===========================================================================
    # extract_round_WMH2 = extract_round_WMH.clone(name='Extract_round_WMH2')
    # extract_round_WMH2.inputs.gm_boundary_partial_vol_dist = 2.0
    # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_round_WMH2.name),extract_round_WMH2,'output_dir')
    # wf.connect(round_WMH,'ridge_pv',extract_round_WMH2,'probability_image')
    # wf.connect(MGDM,'segmentation',extract_round_WMH2,'segmentation_image')
    # wf.connect(MGDM,'distance',extract_round_WMH2,'levelset_boundary_image')
    # wf.connect(AddVentHornsirn,'out_file',extract_round_WMH2,'location_prior_image')
    #
    # extract_round_WMH3 = extract_round_WMH.clone(name='Extract_round_WMH3')
    # extract_round_WMH3.inputs.gm_boundary_partial_vol_dist = 2.0
    # wf.connect(subjectList,('subject_id',createOutputDir,wf.base_dir,wf.name,extract_round_WMH3.name),extract_round_WMH3,'output_dir')
    # wf.connect(round_WMH,'ridge_pv',extract_round_WMH3,'probability_image')
    # wf.connect(MGDM,'segmentation',extract_round_WMH3,'segmentation_image')
    # wf.connect(MGDM,'distance',extract_round_WMH3,'levelset_boundary_image')
    # wf.connect(AddVentHornsirn,'out_file',extract_round_WMH3,'location_prior_image')
    #===========================================================================
    '''
    ####################################
    ####     COMBINE BOTH TYPES     ####
    ####################################
    Small round WMHs and regular WMH together before thresholding
    +
    PVS from white matter and internal capsule
    '''

    # Image calculator : WM + IC DVRS
    DVRS = Node(ImageMaths(), name="DVRS")
    DVRS.inputs.op_string = "-max"
    DVRS.inputs.out_file = "DVRS_map.nii.gz"
    wf.connect(extract_WM_pvs, 'lesion_score', DVRS, "in_file")
    wf.connect(extract_IC_pvs, "lesion_score", DVRS, "in_file2")

    # Image calculator : WMH + round
    WMH = Node(ImageMaths(), name="WMH")
    WMH.inputs.op_string = "-max"
    WMH.inputs.out_file = "WMH_map.nii.gz"
    wf.connect(extract_WMH, 'lesion_score', WMH, "in_file")
    wf.connect(extract_round_WMH, "lesion_score", WMH, "in_file2")

    #===========================================================================
    # WMH2 = Node(ImageMaths(), name="WMH2")
    # WMH2.inputs.op_string = "-max"
    # WMH2.inputs.out_file = "WMH2_map.nii.gz"
    # wf.connect(extract_WMH2,'lesion_score',WMH2,"in_file")
    # wf.connect(extract_round_WMH2,"lesion_score", WMH2, "in_file2")
    #
    # WMH3 = Node(ImageMaths(), name="WMH3")
    # WMH3.inputs.op_string = "-max"
    # WMH3.inputs.out_file = "WMH3_map.nii.gz"
    # wf.connect(extract_WMH3,'lesion_score',WMH3,"in_file")
    # wf.connect(extract_round_WMH3,"lesion_score", WMH3, "in_file2")
    #===========================================================================

    # Image calculator : multiply by boundnary partial volume
    WMH_mul = Node(ImageMaths(), name="WMH_mul")
    WMH_mul.inputs.op_string = "-mul"
    WMH_mul.inputs.out_file = "final_mask.nii.gz"
    wf.connect(WMH, "out_file", WMH_mul, "in_file")
    wf.connect(MGDM, "distance", WMH_mul, "in_file2")

    #===========================================================================
    # WMH2_mul = Node(ImageMaths(), name="WMH2_mul")
    # WMH2_mul.inputs.op_string = "-mul"
    # WMH2_mul.inputs.out_file = "final_mask.nii.gz"
    # wf.connect(WMH2,"out_file", WMH2_mul,"in_file")
    # wf.connect(MGDM,"distance", WMH2_mul, "in_file2")
    #
    # WMH3_mul = Node(ImageMaths(), name="WMH3_mul")
    # WMH3_mul.inputs.op_string = "-mul"
    # WMH3_mul.inputs.out_file = "final_mask.nii.gz"
    # wf.connect(WMH3,"out_file", WMH3_mul,"in_file")
    # wf.connect(MGDM,"distance", WMH3_mul, "in_file2")
    #===========================================================================
    '''
    ##########################################
    ####      SEGMENTATION THRESHOLD      ####
    ##########################################
    A threshold of 0.5 is very conservative, because the final lesion score is the product of two probabilities.
    This needs to be optimized to a value between 0.25 and 0.5 to balance false negatives 
    (dominant at 0.5) and false positives (dominant at low values).
    '''

    # Threshold binary mask :
    DVRS_mask = Node(Threshold(), name="DVRS_mask")
    DVRS_mask.inputs.thresh = 0.25
    DVRS_mask.inputs.direction = "below"
    wf.connect(DVRS, "out_file", DVRS_mask, "in_file")

    # Threshold binary mask : 025
    WMH1_025 = Node(Threshold(), name="WMH1_025")
    WMH1_025.inputs.thresh = 0.25
    WMH1_025.inputs.direction = "below"
    wf.connect(WMH_mul, "out_file", WMH1_025, "in_file")

    #===========================================================================
    # WMH2_025 = Node(Threshold(), name="WMH2_025")
    # WMH2_025.inputs.thresh = 0.25
    # WMH2_025.inputs.direction = "below"
    # wf.connect(WMH2_mul,"out_file", WMH2_025, "in_file")
    #
    # WMH3_025 = Node(Threshold(), name="WMH3_025")
    # WMH3_025.inputs.thresh = 0.25
    # WMH3_025.inputs.direction = "below"
    # wf.connect(WMH3_mul,"out_file", WMH3_025, "in_file")
    #===========================================================================

    # Threshold binary mask : 050
    WMH1_050 = Node(Threshold(), name="WMH1_050")
    WMH1_050.inputs.thresh = 0.50
    WMH1_050.inputs.direction = "below"
    wf.connect(WMH_mul, "out_file", WMH1_050, "in_file")

    #===========================================================================
    # WMH2_050 = Node(Threshold(), name="WMH2_050")
    # WMH2_050.inputs.thresh = 0.50
    # WMH2_050.inputs.direction = "below"
    # wf.connect(WMH2_mul,"out_file", WMH2_050, "in_file")
    #
    # WMH3_050 = Node(Threshold(), name="WMH3_050")
    # WMH3_050.inputs.thresh = 0.50
    # WMH3_050.inputs.direction = "below"
    # wf.connect(WMH3_mul,"out_file", WMH3_050, "in_file")
    #===========================================================================

    # Threshold binary mask : 075
    WMH1_075 = Node(Threshold(), name="WMH1_075")
    WMH1_075.inputs.thresh = 0.75
    WMH1_075.inputs.direction = "below"
    wf.connect(WMH_mul, "out_file", WMH1_075, "in_file")

    #===========================================================================
    # WMH2_075 = Node(Threshold(), name="WMH2_075")
    # WMH2_075.inputs.thresh = 0.75
    # WMH2_075.inputs.direction = "below"
    # wf.connect(WMH2_mul,"out_file", WMH2_075, "in_file")
    #
    # WMH3_075 = Node(Threshold(), name="WMH3_075")
    # WMH3_075.inputs.thresh = 0.75
    # WMH3_075.inputs.direction = "below"
    # wf.connect(WMH3_mul,"out_file", WMH3_075, "in_file")
    #===========================================================================

    ## Outputs

    DVRS_Output = Node(IdentityInterface(fields=[
        'mask', 'region', 'lesion_size', 'lesion_proba', 'boundary', 'label',
        'score'
    ]),
                       name='DVRS_Output')
    wf.connect(DVRS_mask, 'out_file', DVRS_Output, 'mask')

    WMH_output = Node(IdentityInterface(fields=[
        'mask1025', 'mask1050', 'mask1075', 'mask2025', 'mask2050', 'mask2075',
        'mask3025', 'mask3050', 'mask3075'
    ]),
                      name='WMH_output')
    wf.connect(WMH1_025, 'out_file', WMH_output, 'mask1025')
    #wf.connect(WMH2_025,'out_file',WMH_output,'mask2025')
    #wf.connect(WMH3_025,'out_file',WMH_output,'mask3025')
    wf.connect(WMH1_050, 'out_file', WMH_output, 'mask1050')
    #wf.connect(WMH2_050,'out_file',WMH_output,'mask2050')
    #wf.connect(WMH3_050,'out_file',WMH_output,'mask3050')
    wf.connect(WMH1_075, 'out_file', WMH_output, 'mask1075')
    #wf.connect(WMH2_075,'out_file',WMH_output,'mask2070')
    #wf.connect(WMH3_075,'out_file',WMH_output,'mask3075')

    return wf
Пример #57
0
out_dir = os.path.abspath(
    '/data/pt_nmc002/other/narps/derivatives/second_lev_equal_range/')
deriv_dir = os.path.join(data_dir, 'first_lev/equalRange')
fwhm = [5]
mask = '/data/pt_nmc002/other/narps/derivatives/fmriprep/gr_mask_tmax.nii'
#template_image = '/data/pt_neunmc024/SpeechInNoise_Dyslexia_Study/MRI_Data_BIDS/derivatives/mni_template/mni1mm.nii'

# list of contrast identifiers
contrasts = ['con_0001', 'con_0002', 'con_0003']

# collect all the con images for each contrast.
contrast_ids = list(range(1, len(contrasts) + 1))

# Infosource - a function free node to iterate over the list of subject names
infosource = Node(IdentityInterface(fields=['contrast_id']), name="infosource")
infosource.iterables = [('contrast_id', contrasts)]

# Select files from derivatives.

templates = {
    'cons':
    '/data/pt_nmc002/other/narps/derivatives/first_lev/tmp/equalRange/*/contraste_estimate/{contrast_id}.nii'
}
selectderivs = Node(SelectFiles(templates, sort_filelist=True),
                    name='selectderivs')
#selectderivs.inputs.sub_id = subs

# One Sample T-Test Design - creates one sample T-Test Design
onesamplettestdes = Node(
    OneSampleTTestDesign(),
    #overwrite=True,
Пример #58
0
def downsampel_surfs(subject_id,
                     working_dir,
                     freesurfer_dir,
                     ds_dir,
                     plugin_name,
                     use_n_procs):
    '''
    Workflow resamples e.g. native thickness maps to fsaverage5 space
    '''

    #####################################
    # GENERAL SETTINGS
    #####################################
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    fs.FSCommand.set_default_subjects_dir(freesurfer_dir)

    wf = Workflow(name='freesurfer_downsample')
    wf.base_dir = os.path.join(working_dir)

    nipype_cfg = dict(logging=dict(workflow_level='DEBUG'), execution={'stop_on_first_crash': True,
                                                                       'remove_unnecessary_outputs': True,
                                                                       'job_finished_timeout': 15})
    config.update_config(nipype_cfg)
    wf.config['execution']['crashdump_dir'] = os.path.join(working_dir, 'crash')

    ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')
    ds.inputs.parameterization = False



    #####################
    # ITERATORS
    #####################
    # PARCELLATION ITERATOR
    infosource = Node(util.IdentityInterface(fields=['hemi', 'surf_measure', 'fwhm', 'target']), name='infosource')
    infosource.iterables = [('hemi', ['lh', 'rh']),
                            ('surf_measure', ['thickness', 'area']),
                            ('fwhm', [0, 5, 10, 20]),
                            ('target', ['fsaverage3', 'fsaverage4', 'fsaverage5']),
                            ]

    downsample = Node(fs.model.MRISPreproc(), name='downsample')
    downsample.inputs.subjects = [subject_id]
    wf.connect(infosource, 'target', downsample, 'target')
    wf.connect(infosource, 'hemi', downsample, 'hemi')
    wf.connect(infosource, 'surf_measure', downsample, 'surf_measure')
    wf.connect(infosource, 'fwhm', downsample, 'fwhm_source')

    rename = Node(util.Rename(format_string='%(hemi)s.%(surf_measure)s.%(target)s.%(fwhm)smm'), name='rename')
    rename.inputs.keep_ext = True
    wf.connect(infosource, 'target', rename, 'target')
    wf.connect(infosource, 'hemi', rename, 'hemi')
    wf.connect(infosource, 'surf_measure', rename, 'surf_measure')
    wf.connect(infosource, 'fwhm', rename, 'fwhm')
    wf.connect(downsample, 'out_file', rename, 'in_file')

    wf.connect(rename, 'out_file', ds, 'surfs.@surfs')





    #
    wf.write_graph(dotfilename=wf.name, graph2use='colored', format='pdf')  # 'hierarchical')
    wf.write_graph(dotfilename=wf.name, graph2use='orig', format='pdf')
    wf.write_graph(dotfilename=wf.name, graph2use='flat', format='pdf')

    if plugin_name == 'CondorDAGMan':
        wf.run(plugin=plugin_name)
    if plugin_name == 'MultiProc':
        wf.run(plugin=plugin_name, plugin_args={'n_procs': use_n_procs})