Beispiel #1
0
def init_tsnr_wf(name="tsnr"):
    """
    create a workflow to calculate the temporal signal-to-noise
    ratio of a functional image

    :param name: workflow name (Default value = "tsnr")

    """
    workflow = pe.Workflow(name=name)

    # only input is the bold image
    inputnode = pe.Node(niu.IdentityInterface(fields=["bold_file"]),
                        name="inputnode")

    # output is an image file for display in the qualitycheck web page
    outputnode = pe.Node(niu.IdentityInterface(fields=["report_file"]),
                         name="outputnode")

    # actually calculate the tsnr image
    tsnr = pe.Node(interface=nac.TSNR(), name="compute_tsnr")

    # plot the resulting image as a mosaic
    mosaic_stddev = pe.Node(interface=viz.PlotMosaic(
        out_file="plot_func_stddev_mosaic2_stddev.svg", cmap="viridis"),
                            name="plot_mosaic")

    workflow.connect([(inputnode, tsnr, [("bold_file", "in_file")]),
                      (tsnr, mosaic_stddev, [("tsnr_file", "in_file")]),
                      (mosaic_stddev, outputnode, [("out_file", "report_file")
                                                   ])])

    return workflow
def create_moco_pipeline(name='motion_correction'):
    # initiate workflow
    moco = Workflow(name='motion_correction')
    # set fsl output
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    # inputnode
    inputnode = Node(util.IdentityInterface(fields=['epi']), name='inputnode')
    # outputnode
    outputnode = Node(util.IdentityInterface(fields=[
        'epi_moco', 'par_moco', 'mat_moco', 'rms_moco', 'epi_mean', 'rotplot',
        'transplot', 'dispplots', 'tsnr_file'
    ]),
                      name='outputnode')
    # mcflirt motion correction to 1st volume
    mcflirt = Node(fsl.MCFLIRT(save_mats=True,
                               save_plots=True,
                               save_rms=True,
                               ref_vol=1,
                               out_file='rest_realigned.nii.gz'),
                   name='mcflirt')
    # plot motion parameters
    rotplotter = Node(fsl.PlotMotionParams(in_source='fsl',
                                           plot_type='rotations',
                                           out_file='rotation_plot.png'),
                      name='rotplotter')
    transplotter = Node(fsl.PlotMotionParams(in_source='fsl',
                                             plot_type='translations',
                                             out_file='translation_plot.png'),
                        name='transplotter')
    dispplotter = MapNode(interface=fsl.PlotMotionParams(
        in_source='fsl',
        plot_type='displacement',
    ),
                          name='dispplotter',
                          iterfield=['in_file'])
    dispplotter.iterables = ('plot_type', ['displacement'])
    # calculate tmean
    tmean = Node(fsl.maths.MeanImage(dimension='T',
                                     out_file='rest_realigned_mean.nii.gz'),
                 name='tmean')
    # calculate tsnr
    tsnr = Node(confounds.TSNR(), name='tsnr')
    # create connections
    moco.connect([(inputnode, mcflirt, [('epi', 'in_file')]),
                  (mcflirt, tmean, [('out_file', 'in_file')]),
                  (mcflirt, rotplotter, [('par_file', 'in_file')]),
                  (mcflirt, transplotter, [('par_file', 'in_file')]),
                  (mcflirt, dispplotter, [('rms_files', 'in_file')]),
                  (tmean, outputnode, [('out_file', 'epi_mean')]),
                  (mcflirt, outputnode, [('out_file', 'epi_moco'),
                                         ('par_file', 'par_moco'),
                                         ('mat_file', 'mat_moco'),
                                         ('rms_files', 'rms_moco')]),
                  (rotplotter, outputnode, [('out_file', 'rotplot')]),
                  (transplotter, outputnode, [('out_file', 'transplot')]),
                  (dispplotter, outputnode, [('out_file', 'dispplots')]),
                  (mcflirt, tsnr, [('out_file', 'in_file')]),
                  (tsnr, outputnode, [('tsnr_file', 'tsnr_file')])])
    return moco
Beispiel #3
0
def init_atlasbasedconnectivity_wf(
        workdir: str | Path,
        feature=None,
        atlas_files=None,
        atlas_spaces=None,
        memcalc=MemoryCalculator.default(),
):
    """
    create workflow for brainatlas

    """
    if feature is not None:
        name = f"{format_workflow(feature.name)}_wf"
    else:
        name = "atlasbasedconnectivity_wf"
    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(
        niu.IdentityInterface(fields=[
            "tags",
            "vals",
            "metadata",
            "bold",
            "mask",
            "repetition_time",
            "atlas_names",
            "atlas_files",
            "atlas_spaces",
        ]),
        name="inputnode",
    )
    outputnode = pe.Node(niu.IdentityInterface(fields=["resultdicts"]),
                         name="outputnode")

    min_region_coverage = 1
    if feature is not None:
        inputnode.inputs.atlas_names = feature.atlases
        if hasattr(feature, "min_region_coverage"):
            min_region_coverage = feature.min_region_coverage

    if atlas_files is not None:
        inputnode.inputs.atlas_files = atlas_files

    if atlas_spaces is not None:
        inputnode.inputs.atlas_spaces = atlas_spaces

    #
    make_resultdicts = pe.Node(
        MakeResultdicts(
            tagkeys=["feature", "atlas"],
            imagekeys=[
                "timeseries", "covariance_matrix", "correlation_matrix"
            ],
            metadatakeys=[
                "sources",
                "sampling_frequency",
                "mean_atlas_tsnr",
                "coverage",
            ],
            nobroadcastkeys=["mean_atlas_tsnr", "coverage"],
        ),
        name="make_resultdicts",
    )
    if feature is not None:
        make_resultdicts.inputs.feature = feature.name
    workflow.connect(inputnode, "tags", make_resultdicts, "tags")
    workflow.connect(inputnode, "vals", make_resultdicts, "vals")
    workflow.connect(inputnode, "metadata", make_resultdicts, "metadata")
    workflow.connect(inputnode, "atlas_names", make_resultdicts, "atlas")
    workflow.connect(inputnode, "repetition_time", make_resultdicts,
                     "sampling_frequency")

    workflow.connect(make_resultdicts, "resultdicts", outputnode,
                     "resultdicts")

    #
    resultdict_datasink = pe.Node(ResultdictDatasink(base_directory=workdir),
                                  name="resultdict_datasink")
    workflow.connect(make_resultdicts, "resultdicts", resultdict_datasink,
                     "indicts")

    #
    reference_dict = dict(reference_space=constants.reference_space,
                          reference_res=constants.reference_res)
    resample = pe.MapNode(
        Resample(interpolation="MultiLabel", **reference_dict),
        name="resample",
        iterfield=["input_image", "input_space"],
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "atlas_files", resample, "input_image")
    workflow.connect(inputnode, "atlas_spaces", resample, "input_space")

    #
    connectivitymeasure = pe.MapNode(
        ConnectivityMeasure(background_label=0,
                            min_region_coverage=min_region_coverage),
        name="connectivitymeasure",
        iterfield=["atlas_file"],
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "bold", connectivitymeasure, "in_file")
    workflow.connect(inputnode, "mask", connectivitymeasure, "mask_file")
    workflow.connect(resample, "output_image", connectivitymeasure,
                     "atlas_file")

    workflow.connect(connectivitymeasure, "time_series", make_resultdicts,
                     "timeseries")
    workflow.connect(connectivitymeasure, "covariance", make_resultdicts,
                     "covariance_matrix")
    workflow.connect(connectivitymeasure, "correlation", make_resultdicts,
                     "correlation_matrix")
    workflow.connect(connectivitymeasure, "region_coverage", make_resultdicts,
                     "coverage")

    #
    tsnr = pe.Node(interface=nac.TSNR(),
                   name="tsnr",
                   mem_gb=memcalc.series_std_gb)
    workflow.connect(inputnode, "bold", tsnr, "in_file")

    calcmean = pe.MapNode(
        CalcMean(),
        iterfield="parcellation",
        name="calcmean",
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(resample, "output_image", calcmean, "parcellation")
    workflow.connect(inputnode, "mask", calcmean, "mask")
    workflow.connect(tsnr, "tsnr_file", calcmean, "in_file")

    workflow.connect(calcmean, "mean", make_resultdicts, "mean_atlas_tsnr")

    return workflow
Beispiel #4
0
def init_dualregression_wf(workdir=None,
                           feature=None,
                           map_files=None,
                           map_spaces=None,
                           memcalc=MemoryCalculator()):
    """
    create a workflow to calculate dual regression for ICA seeds
    """
    if feature is not None:
        name = f"{formatlikebids(feature.name)}_wf"
    else:
        name = "dualregression_wf"
    workflow = pe.Workflow(name=name)

    # input
    inputnode = pe.Node(
        niu.IdentityInterface(fields=[
            "tags",
            "vals",
            "metadata",
            "bold",
            "mask",
            "confounds_selected",
            "map_names",
            "map_files",
            "map_spaces",
        ]),
        name="inputnode",
    )
    outputnode = pe.Node(niu.IdentityInterface(fields=["resultdicts"]),
                         name="outputnode")

    if feature is not None:
        inputnode.inputs.map_names = feature.maps

    if map_files is not None:
        inputnode.inputs.map_files = map_files

    if map_spaces is not None:
        inputnode.inputs.map_spaces = map_spaces

    #
    statmaps = ["effect", "variance", "z", "dof", "mask"]
    make_resultdicts_a = pe.Node(
        MakeResultdicts(tagkeys=["feature", "map"],
                        imagekeys=["design_matrix", "contrast_matrix"]),
        name="make_resultdicts_a",
    )
    if feature is not None:
        make_resultdicts_a.inputs.feature = feature.name
    workflow.connect(inputnode, "tags", make_resultdicts_a, "tags")
    workflow.connect(inputnode, "vals", make_resultdicts_a, "vals")
    workflow.connect(inputnode, "metadata", make_resultdicts_a, "metadata")
    workflow.connect(inputnode, "map_names", make_resultdicts_a, "map")
    make_resultdicts_b = pe.Node(
        MakeResultdicts(
            tagkeys=["feature", "map", "component"],
            imagekeys=statmaps,
            metadatakeys=["sources", "mean_t_s_n_r"],
        ),
        name="make_resultdicts_b",
    )
    if feature is not None:
        make_resultdicts_b.inputs.feature = feature.name
    workflow.connect(inputnode, "tags", make_resultdicts_b, "tags")
    workflow.connect(inputnode, "vals", make_resultdicts_b, "vals")
    workflow.connect(inputnode, "metadata", make_resultdicts_b, "metadata")
    workflow.connect(inputnode, "map_names", make_resultdicts_b, "map")
    workflow.connect(inputnode, "mask", make_resultdicts_b, "mask")

    workflow.connect(make_resultdicts_b, "resultdicts", outputnode,
                     "resultdicts")

    #
    merge_resultdicts = pe.Node(niu.Merge(2), name="merge_resultdicts")
    workflow.connect(make_resultdicts_a, "resultdicts", merge_resultdicts,
                     "in1")
    workflow.connect(make_resultdicts_b, "resultdicts", merge_resultdicts,
                     "in2")
    resultdict_datasink = pe.Node(ResultdictDatasink(base_directory=workdir),
                                  name="resultdict_datasink")
    workflow.connect(merge_resultdicts, "out", resultdict_datasink, "indicts")

    #
    reference_dict = dict(reference_space=constants.reference_space,
                          reference_res=constants.reference_res)
    resample = pe.MapNode(
        Resample(interpolation="LanczosWindowedSinc", **reference_dict),
        name="resample",
        iterfield=["input_image", "input_space"],
        n_procs=config.nipype.omp_nthreads,
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "map_files", resample, "input_image")
    workflow.connect(inputnode, "map_spaces", resample, "input_space")

    # Delete zero voxels for the maps
    applymask = pe.MapNode(
        fsl.ApplyMask(),
        name="applymask",
        iterfield="in_file",
        mem_gb=memcalc.volume_std_gb,
    )
    workflow.connect(inputnode, "mask", applymask, "mask_file")
    workflow.connect(resample, "output_image", applymask, "in_file")

    # first step, calculate spatial regression of ICA components on to the
    # bold file
    spatialglm = pe.MapNode(
        fsl.GLM(out_file="beta", demean=True),
        name="spatialglm",
        iterfield="design",
        mem_gb=memcalc.series_std_gb * 5,
    )
    workflow.connect(applymask, "out_file", spatialglm, "design")
    workflow.connect(inputnode, "bold", spatialglm, "in_file")
    workflow.connect(inputnode, "mask", spatialglm, "mask")

    # second step, calculate the temporal regression of the time series
    # from the first step on to the bold file
    contrasts = pe.MapNode(
        niu.Function(
            input_names=["map_timeseries_file", "confounds_file"],
            output_names=[
                "out_with_header", "out_no_header", "map_component_names"
            ],
            function=_contrasts,
        ),
        iterfield="map_timeseries_file",
        name="contrasts",
    )
    workflow.connect(spatialglm, "out_file", contrasts, "map_timeseries_file")
    workflow.connect(inputnode, "confounds_selected", contrasts,
                     "confounds_file")

    workflow.connect(contrasts, "out_with_header", make_resultdicts_a,
                     "contrast_matrix")
    workflow.connect(contrasts, "map_component_names", make_resultdicts_b,
                     "component")

    design = pe.MapNode(MergeColumns(2),
                        iterfield=["in1", "column_names1"],
                        name="design")
    workflow.connect(spatialglm, "out_file", design, "in1")
    workflow.connect(contrasts, "map_component_names", design, "column_names1")
    workflow.connect(inputnode, "confounds_selected", design, "in2")

    workflow.connect(design, "out_with_header", make_resultdicts_a,
                     "design_matrix")

    fillna = pe.MapNode(FillNA(), iterfield="in_tsv", name="fillna")
    workflow.connect(design, "out_no_header", fillna, "in_tsv")

    temporalglm = pe.MapNode(
        fsl.GLM(
            out_file="beta.nii.gz",
            out_cope="cope.nii.gz",
            out_varcb_name="varcope.nii.gz",
            out_z_name="zstat.nii.gz",
            demean=True,
        ),
        name="temporalglm",
        iterfield=["design", "contrasts"],
        mem_gb=memcalc.series_std_gb * 5,
    )
    workflow.connect(inputnode, "bold", temporalglm, "in_file")
    workflow.connect(inputnode, "mask", temporalglm, "mask")
    workflow.connect(fillna, "out_no_header", temporalglm, "design")
    workflow.connect(contrasts, "out_no_header", temporalglm, "contrasts")

    # make dof volume
    makedofvolume = pe.MapNode(
        MakeDofVolume(),
        iterfield=["design"],
        name="makedofvolume",
    )
    workflow.connect(inputnode, "bold", makedofvolume, "bold_file")
    workflow.connect(fillna, "out_no_header", makedofvolume, "design")

    for glmattr, resultattr in (("cope", "effect"), ("varcb", "variance"),
                                ("z", "z")):
        split = pe.MapNode(fsl.Split(dimension="t"),
                           iterfield="in_file",
                           name=f"split{resultattr}images")
        workflow.connect(temporalglm, f"out_{glmattr}", split, "in_file")
        workflow.connect(split, "out_files", make_resultdicts_b, resultattr)
    workflow.connect(makedofvolume, "out_file", make_resultdicts_b, "dof")

    #
    tsnr = pe.Node(nac.TSNR(), name="tsnr", mem_gb=memcalc.series_std_gb)
    workflow.connect(inputnode, "bold", tsnr, "in_file")

    maxintensity = pe.MapNode(MaxIntensity(),
                              iterfield="in_file",
                              name="maxintensity",
                              mem_gb=memcalc.series_std_gb)
    workflow.connect(resample, "output_image", maxintensity, "in_file")

    calcmean = pe.MapNode(CalcMean(),
                          iterfield="parcellation",
                          name="calcmean",
                          mem_gb=memcalc.series_std_gb)
    workflow.connect(maxintensity, "out_file", calcmean, "parcellation")
    workflow.connect(tsnr, "tsnr_file", calcmean, "in_file")

    workflow.connect(calcmean, "mean", make_resultdicts_b, "mean_t_s_n_r")

    return workflow
Beispiel #5
0
def fmri_qc_workflow(name='fMRIQC', settings=None):
    """ The fMRI qc workflow """

    if settings is None:
        settings = {}

    workflow = pe.Workflow(name=name)
    deriv_dir = op.abspath(op.join(settings['output_dir'], 'derivatives'))

    if not op.exists(deriv_dir):
        os.makedirs(deriv_dir)

    # Read FD radius, or default it
    fd_radius = settings.get('fd_radius', 50.)

    # Define workflow, inputs and outputs
    inputnode = pe.Node(niu.IdentityInterface(fields=[
        'bids_dir', 'subject_id', 'session_id', 'run_id', 'site_name',
        'start_idx', 'stop_idx'
    ]),
                        name='inputnode')
    get_idx = pe.Node(niu.Function(
        input_names=['in_file', 'start_idx', 'stop_idx'],
        function=fmri_getidx,
        output_names=['start_idx', 'stop_idx']),
                      name='get_idx')

    outputnode = pe.Node(niu.IdentityInterface(fields=[
        'qc', 'mosaic', 'out_group', 'out_movpar', 'out_dvars', 'out_fd'
    ]),
                         name='outputnode')

    # 0. Get data
    datasource = pe.Node(niu.Function(input_names=[
        'bids_dir', 'data_type', 'subject_id', 'session_id', 'run_id'
    ],
                                      output_names=['out_file'],
                                      function=bids_getfile),
                         name='datasource')
    datasource.inputs.data_type = 'func'

    # Workflow --------------------------------------------------------
    # 1. HMC: head motion correct
    hmcwf = hmc_mcflirt()
    if settings.get('hmc_afni', False):
        hmcwf = hmc_afni(
            st_correct=settings.get('correct_slice_timing', False))
    hmcwf.inputs.inputnode.fd_radius = fd_radius

    mean = pe.Node(
        afp.TStat(  # 2. Compute mean fmri
            options='-mean', outputtype='NIFTI_GZ'),
        name='mean')
    bmw = fmri_bmsk_workflow(  # 3. Compute brain mask
        use_bet=settings.get('use_bet', False))

    # Compute TSNR using nipype implementation
    tsnr = pe.Node(nac.TSNR(), name='compute_tsnr')

    # Compute DVARS
    dvnode = pe.Node(nac.ComputeDVARS(remove_zerovariance=True,
                                      save_plot=True,
                                      save_all=True,
                                      figdpi=200,
                                      figformat='pdf'),
                     name='ComputeDVARS')
    fdnode = pe.Node(nac.FramewiseDisplacement(normalize=True,
                                               save_plot=True,
                                               radius=fd_radius,
                                               figdpi=200),
                     name='ComputeFD')

    # AFNI quality measures
    fwhm = pe.Node(afp.FWHMx(combine=True, detrend=True), name='smoothness')
    # fwhm.inputs.acf = True  # add when AFNI >= 16
    outliers = pe.Node(afp.OutlierCount(fraction=True, out_file='ouliers.out'),
                       name='outliers')
    quality = pe.Node(afp.QualityIndex(automask=True),
                      out_file='quality.out',
                      name='quality')

    measures = pe.Node(FunctionalQC(), name='measures')

    # Link images that should be reported
    dsreport = pe.Node(nio.DataSink(base_directory=settings['report_dir'],
                                    parameterization=True),
                       name='dsreport')
    dsreport.inputs.container = 'func'
    dsreport.inputs.substitutions = [
        ('_data', ''), ('fd_power_2012', 'plot_fd'),
        ('tsnr.nii.gz', 'mosaic_TSNR.nii.gz'),
        ('mean.nii.gz', 'mosaic_TSNR_mean.nii.gz'),
        ('stdev.nii.gz', 'mosaic_TSNR_stdev.nii.gz')
    ]
    dsreport.inputs.regexp_substitutions = [
        ('_u?(sub-[\\w\\d]*)\\.([\\w\\d_]*)(?:\\.([\\w\\d_-]*))+',
         '\\1_ses-\\2_\\3'), ('sub-[^/.]*_dvars_std', 'plot_dvars'),
        ('sub-[^/.]*_mask', 'mask'),
        ('sub-[^/.]*_mcf_tstat', 'mosaic_epi_mean')
    ]

    workflow.connect([
        (inputnode, datasource, [('bids_dir', 'bids_dir'),
                                 ('subject_id', 'subject_id'),
                                 ('session_id', 'session_id'),
                                 ('run_id', 'run_id')]),
        (inputnode, get_idx, [('start_idx', 'start_idx'),
                              ('stop_idx', 'stop_idx')]),
        (datasource, get_idx, [('out_file', 'in_file')]),
        (datasource, hmcwf, [('out_file', 'inputnode.in_file')]),
        (get_idx, hmcwf, [('start_idx', 'inputnode.start_idx'),
                          ('stop_idx', 'inputnode.stop_idx')]),
        (hmcwf, bmw, [('outputnode.out_file', 'inputnode.in_file')]),
        (hmcwf, mean, [('outputnode.out_file', 'in_file')]),
        (hmcwf, tsnr, [('outputnode.out_file', 'in_file')]),
        (hmcwf, fdnode, [('outputnode.out_movpar', 'in_plots')]),
        (mean, fwhm, [('out_file', 'in_file')]),
        (bmw, fwhm, [('outputnode.out_file', 'mask')]),
        (hmcwf, outliers, [('outputnode.out_file', 'in_file')]),
        (bmw, outliers, [('outputnode.out_file', 'mask')]),
        (hmcwf, quality, [('outputnode.out_file', 'in_file')]),
        (hmcwf, dvnode, [('outputnode.out_file', 'in_file')]),
        (bmw, dvnode, [('outputnode.out_file', 'in_mask')]),
        (mean, measures, [('out_file', 'in_epi')]),
        (hmcwf, measures, [('outputnode.out_file', 'in_hmc')]),
        (bmw, measures, [('outputnode.out_file', 'in_mask')]),
        (tsnr, measures, [('tsnr_file', 'in_tsnr')]),
        (dvnode, measures, [('out_all', 'in_dvars')]),
        (fdnode, measures, [('out_file', 'in_fd')]),
        (fdnode, outputnode, [('out_file', 'out_fd')]),
        (dvnode, outputnode, [('out_all', 'out_dvars')]),
        (hmcwf, outputnode, [('outputnode.out_movpar', 'out_movpar')]),
        (mean, dsreport, [('out_file', '@meanepi')]),
        (tsnr, dsreport, [('tsnr_file', '@tsnr'), ('stddev_file', '@tsnr_std'),
                          ('mean_file', '@tsnr_mean')]),
        (bmw, dsreport, [('outputnode.out_file', '@mask')]),
        (fdnode, dsreport, [('out_figure', '@fdplot')]),
        (dvnode, dsreport, [('fig_std', '@dvars')]),
    ])

    # Format name
    out_name = pe.Node(niu.Function(
        input_names=['subid', 'sesid', 'runid', 'prefix', 'out_path'],
        output_names=['out_file'],
        function=bids_path),
                       name='FormatName')
    out_name.inputs.out_path = deriv_dir
    out_name.inputs.prefix = 'func'

    # Save to JSON file
    datasink = pe.Node(nio.JSONFileSink(), name='datasink')
    datasink.inputs.qc_type = 'func'

    workflow.connect([
        (inputnode, out_name, [('subject_id', 'subid'),
                               ('session_id', 'sesid'), ('run_id', 'runid')]),
        (inputnode, datasink, [('subject_id', 'subject_id'),
                               ('session_id', 'session_id'),
                               ('run_id', 'run_id')]),
        (fwhm, datasink, [(('fwhm', fwhm_dict), 'fwhm')]),
        (outliers, datasink, [(('out_file', _parse_tout), 'outlier')]),
        (quality, datasink, [(('out_file', _parse_tqual), 'quality')]),
        (measures, datasink, [('summary', 'summary'), ('spacing', 'spacing'),
                              ('size', 'size'), ('fber', 'fber'),
                              ('efc', 'efc'), ('snr', 'snr'), ('gsr', 'gsr'),
                              ('m_tsnr', 'm_tsnr'), ('fd', 'fd'),
                              ('dvars', 'dvars'), ('gcor', 'gcor')]),
        (out_name, datasink, [('out_file', 'out_file')]),
        (datasink, outputnode, [('out_file', 'out_file')])
    ])

    return workflow
def init_seedbasedconnectivity_wf(workdir=None,
                                  feature=None,
                                  seed_files=None,
                                  seed_spaces=None,
                                  memcalc=MemoryCalculator()):
    """
    create workflow to calculate seed connectivity maps
    """
    if feature is not None:
        name = f"{formatlikebids(feature.name)}_wf"
    else:
        name = "seedbasedconnectivity_wf"
    workflow = pe.Workflow(name=name)

    # input
    inputnode = pe.Node(
        niu.IdentityInterface(fields=[
            "tags",
            "vals",
            "metadata",
            "bold",
            "mask",
            "confounds_selected",
            "seed_names",
            "seed_files",
            "seed_spaces",
        ]),
        name="inputnode",
    )
    outputnode = pe.Node(niu.IdentityInterface(fields=["resultdicts"]),
                         name="outputnode")

    min_seed_coverage = 1
    if feature is not None:
        inputnode.inputs.seed_names = feature.seeds
        if hasattr(feature, "min_seed_coverage"):
            min_seed_coverage = feature.min_seed_coverage

    if seed_files is not None:
        inputnode.inputs.seed_files = seed_files

    if seed_spaces is not None:
        inputnode.inputs.seed_spaces = seed_spaces

    #
    statmaps = ["effect", "variance", "z", "dof", "mask"]
    make_resultdicts = pe.Node(
        MakeResultdicts(
            tagkeys=["feature", "seed"],
            imagekeys=[*statmaps, "design_matrix", "contrast_matrix"],
            metadatakeys=["mean_t_s_n_r", "coverage"],
        ),
        name="make_resultdicts",
    )
    if feature is not None:
        make_resultdicts.inputs.feature = feature.name
    workflow.connect(inputnode, "tags", make_resultdicts, "tags")
    workflow.connect(inputnode, "vals", make_resultdicts, "vals")
    workflow.connect(inputnode, "metadata", make_resultdicts, "metadata")
    workflow.connect(inputnode, "mask", make_resultdicts, "mask")

    workflow.connect(make_resultdicts, "resultdicts", outputnode,
                     "resultdicts")

    #
    resultdict_datasink = pe.Node(ResultdictDatasink(base_directory=workdir),
                                  name="resultdict_datasink")
    workflow.connect(make_resultdicts, "resultdicts", resultdict_datasink,
                     "indicts")

    #
    reference_dict = dict(reference_space=constants.reference_space,
                          reference_res=constants.reference_res)
    resample = pe.MapNode(
        Resample(interpolation="MultiLabel", **reference_dict),
        name="resample",
        iterfield=["input_image", "input_space"],
        n_procs=config.nipype.omp_nthreads,
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "seed_files", resample, "input_image")
    workflow.connect(inputnode, "seed_spaces", resample, "input_space")

    # Delete zero voxels for the seeds
    maskseeds = pe.Node(
        MaskCoverage(keys=["names"], min_coverage=min_seed_coverage),
        name="maskseeds",
        mem_gb=memcalc.volume_std_gb,
    )
    workflow.connect(inputnode, "mask", maskseeds, "mask_file")

    workflow.connect(inputnode, "seed_names", maskseeds, "names")
    workflow.connect(resample, "output_image", maskseeds, "in_files")

    workflow.connect(maskseeds, "names", make_resultdicts, "seed")
    workflow.connect(maskseeds, "coverage", make_resultdicts, "coverage")

    # calculate the mean time series of the region defined by each mask
    meants = pe.MapNode(
        fsl.ImageMeants(),
        name="meants",
        iterfield="mask",
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "bold", meants, "in_file")
    workflow.connect(maskseeds, "out_files", meants, "mask")

    #
    design = pe.MapNode(MergeColumns(2),
                        iterfield=["in1", "column_names1"],
                        name="design")
    workflow.connect(meants, "out_file", design, "in1")
    workflow.connect(maskseeds, "names", design, "column_names1")
    workflow.connect(inputnode, "confounds_selected", design, "in2")

    workflow.connect(design, "out_with_header", make_resultdicts,
                     "design_matrix")

    contrasts = pe.MapNode(
        niu.Function(
            input_names=["design_file"],
            output_names=["out_with_header", "out_no_header"],
            function=_contrasts,
        ),
        iterfield="design_file",
        name="contrasts",
    )
    workflow.connect(design, "out_with_header", contrasts, "design_file")

    workflow.connect(contrasts, "out_with_header", make_resultdicts,
                     "contrast_matrix")

    fillna = pe.MapNode(FillNA(), iterfield="in_tsv", name="fillna")
    workflow.connect(design, "out_no_header", fillna, "in_tsv")

    # calculate the regression of the mean time series
    # onto the functional image.
    # the result is the seed connectivity map
    glm = pe.MapNode(
        fsl.GLM(
            out_file="beta.nii.gz",
            out_cope="cope.nii.gz",
            out_varcb_name="varcope.nii.gz",
            out_z_name="zstat.nii.gz",
            demean=True,
        ),
        name="glm",
        iterfield=["design", "contrasts"],
        mem_gb=memcalc.series_std_gb * 5,
    )
    workflow.connect(inputnode, "bold", glm, "in_file")
    workflow.connect(inputnode, "mask", glm, "mask")
    workflow.connect(fillna, "out_no_header", glm, "design")
    workflow.connect(contrasts, "out_no_header", glm, "contrasts")

    # make dof volume
    makedofvolume = pe.MapNode(MakeDofVolume(),
                               iterfield=["design"],
                               name="makedofvolume")
    workflow.connect(inputnode, "bold", makedofvolume, "bold_file")
    workflow.connect(fillna, "out_no_header", makedofvolume, "design")

    workflow.connect(glm, "out_cope", make_resultdicts, "effect")
    workflow.connect(glm, "out_varcb", make_resultdicts, "variance")
    workflow.connect(glm, "out_z", make_resultdicts, "z")
    workflow.connect(makedofvolume, "out_file", make_resultdicts, "dof")

    #
    tsnr = pe.Node(nac.TSNR(), name="tsnr", mem_gb=memcalc.series_std_gb)
    workflow.connect(inputnode, "bold", tsnr, "in_file")

    calcmean = pe.MapNode(CalcMean(),
                          iterfield="mask",
                          name="calcmean",
                          mem_gb=memcalc.series_std_gb)
    workflow.connect(maskseeds, "out_files", calcmean, "mask")
    workflow.connect(tsnr, "tsnr_file", calcmean, "in_file")

    workflow.connect(calcmean, "mean", make_resultdicts, "mean_t_s_n_r")

    return workflow
Beispiel #7
0
def fmri_qc_workflow(dataset, settings, name='funcMRIQC'):
    """
    The fMRI qc workflow

    .. workflow::

      import os.path as op
      from mriqc.workflows.functional import fmri_qc_workflow
      datadir = op.abspath('data')
      wf = fmri_qc_workflow([op.join(datadir, 'sub-001/func/sub-001_task-rest_bold.nii.gz')],
                            settings={'bids_dir': datadir,
                                      'output_dir': op.abspath('out'),
                                      'no_sub': True})


    """

    workflow = pe.Workflow(name=name)

    biggest_file_gb = settings.get("biggest_file_size_gb", 1)

    # Define workflow, inputs and outputs
    # 0. Get data, put it in RAS orientation
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']), name='inputnode')
    WFLOGGER.info('Building fMRI QC workflow, datasets list: %s',
                  [str(Path(d).relative_to(settings['bids_dir']))
                   for d in sorted(dataset)])
    inputnode.iterables = [('in_file', dataset)]

    outputnode = pe.Node(niu.IdentityInterface(
        fields=['qc', 'mosaic', 'out_group', 'out_dvars',
                'out_fd']), name='outputnode')

    non_steady_state_detector = pe.Node(nac.NonSteadyStateDetector(),
                                        name="non_steady_state_detector")

    sanitize = pe.Node(niutils.SanitizeImage(), name="sanitize",
                       mem_gb=biggest_file_gb * 4.0)
    sanitize.inputs.max_32bit = settings.get("float32", DEFAULTS['float32'])

    # Workflow --------------------------------------------------------

    # 1. HMC: head motion correct
    if settings.get('hmc_fsl', False):
        hmcwf = hmc_mcflirt(settings)
    else:
        hmcwf = hmc_afni(settings,
                         st_correct=settings.get('correct_slice_timing', False),
                         despike=settings.get('despike', False),
                         deoblique=settings.get('deoblique', False),
                         start_idx=settings.get('start_idx', None),
                         stop_idx=settings.get('stop_idx', None))

    # Set HMC settings
    hmcwf.inputs.inputnode.fd_radius = settings.get('fd_radius', DEFAULT_FD_RADIUS)

    mean = pe.Node(afni.TStat(                   # 2. Compute mean fmri
        options='-mean', outputtype='NIFTI_GZ'), name='mean',
        mem_gb=biggest_file_gb * 1.5)
    skullstrip_epi = fmri_bmsk_workflow(use_bet=True)

    # EPI to MNI registration
    ema = epi_mni_align(settings)

    # Compute TSNR using nipype implementation
    tsnr = pe.Node(nac.TSNR(), name='compute_tsnr', mem_gb=biggest_file_gb * 2.5)

    # 7. Compute IQMs
    iqmswf = compute_iqms(settings)
    # Reports
    repwf = individual_reports(settings)

    workflow.connect([
        (inputnode, iqmswf, [('in_file', 'inputnode.in_file')]),
        (inputnode, sanitize, [('in_file', 'in_file')]),
        (inputnode, non_steady_state_detector, [('in_file', 'in_file')]),
        (non_steady_state_detector, sanitize, [('n_volumes_to_discard', 'n_volumes_to_discard')]),
        (sanitize, hmcwf, [('out_file', 'inputnode.in_file')]),
        (mean, skullstrip_epi, [('out_file', 'inputnode.in_file')]),
        (hmcwf, mean, [('outputnode.out_file', 'in_file')]),
        (hmcwf, tsnr, [('outputnode.out_file', 'in_file')]),
        (mean, ema, [('out_file', 'inputnode.epi_mean')]),
        (skullstrip_epi, ema, [('outputnode.out_file', 'inputnode.epi_mask')]),
        (sanitize, iqmswf, [('out_file', 'inputnode.in_ras')]),
        (mean, iqmswf, [('out_file', 'inputnode.epi_mean')]),
        (hmcwf, iqmswf, [('outputnode.out_file', 'inputnode.hmc_epi'),
                         ('outputnode.out_fd', 'inputnode.hmc_fd')]),
        (skullstrip_epi, iqmswf, [('outputnode.out_file', 'inputnode.brainmask')]),
        (tsnr, iqmswf, [('tsnr_file', 'inputnode.in_tsnr')]),
        (sanitize, repwf, [('out_file', 'inputnode.in_ras')]),
        (mean, repwf, [('out_file', 'inputnode.epi_mean')]),
        (tsnr, repwf, [('stddev_file', 'inputnode.in_stddev')]),
        (skullstrip_epi, repwf, [('outputnode.out_file', 'inputnode.brainmask')]),
        (hmcwf, repwf, [('outputnode.out_fd', 'inputnode.hmc_fd'),
                        ('outputnode.out_file', 'inputnode.hmc_epi')]),
        (ema, repwf, [('outputnode.epi_parc', 'inputnode.epi_parc'),
                      ('outputnode.report', 'inputnode.mni_report')]),
        (non_steady_state_detector, iqmswf, [('n_volumes_to_discard', 'inputnode.exclude_index')]),
        (iqmswf, repwf, [('outputnode.out_file', 'inputnode.in_iqms'),
                         ('outputnode.out_dvars', 'inputnode.in_dvars'),
                         ('outputnode.outliers', 'inputnode.outliers')]),
        (hmcwf, outputnode, [('outputnode.out_fd', 'out_fd')]),
    ])

    if settings.get('fft_spikes_detector', False):
        workflow.connect([
            (iqmswf, repwf, [('outputnode.out_spikes', 'inputnode.in_spikes'),
                             ('outputnode.out_fft', 'inputnode.in_fft')]),
        ])

    if settings.get('ica', False):
        melodic = pe.Node(nws.MELODICRPT(no_bet=True,
                                         no_mask=True,
                                         no_mm=True,
                                         compress_report=False,
                                         generate_report=True),
                          name="ICA", mem_gb=max(biggest_file_gb * 5, 8))
        workflow.connect([
            (sanitize, melodic, [('out_file', 'in_files')]),
            (skullstrip_epi, melodic, [('outputnode.out_file', 'report_mask')]),
            (melodic, repwf, [('out_report', 'inputnode.ica_report')])
        ])

    # Upload metrics
    if not settings.get('no_sub', False):
        from ..interfaces.webapi import UploadIQMs
        upldwf = pe.Node(UploadIQMs(), name='UploadMetrics')
        upldwf.inputs.url = settings.get('webapi_url')
        if settings.get('webapi_port'):
            upldwf.inputs.port = settings.get('webapi_port')
        upldwf.inputs.email = settings.get('email')
        upldwf.inputs.strict = settings.get('upload_strict', False)

        workflow.connect([
            (iqmswf, upldwf, [('outputnode.out_file', 'in_iqms')]),
        ])

    return workflow
Beispiel #8
0
def create_resting_preproc(name='restpreproc', base_dir=None):
    """Create a "resting" time series preprocessing workflow

    The noise removal is based on Behzadi et al. (2007)

    Parameters
    ----------

    name : name of workflow (default: restpreproc)

    Inputs::

        inputspec.func : functional run (filename or list of filenames)

    Outputs::

        outputspec.noise_mask_file : voxels used for PCA to derive noise
                                     components
        outputspec.filtered_file : bandpass filtered and noise-reduced time
                                   series

    Example
    -------

    >>> TR = 3.0
    >>> wf = create_resting_preproc()
    >>> wf.inputs.inputspec.func = 'f3.nii'
    >>> wf.inputs.inputspec.num_noise_components = 6
    >>> wf.inputs.inputspec.highpass_sigma = 100/(2*TR)
    >>> wf.inputs.inputspec.lowpass_sigma = 12.5/(2*TR)
    >>> wf.run() # doctest: +SKIP

    """

    restpreproc = pe.Workflow(name=name, base_dir=base_dir)

    # Define nodes
    inputnode = pe.Node(interface=util.IdentityInterface(fields=[
        'func', 'num_noise_components', 'highpass_sigma', 'lowpass_sigma'
    ]),
                        name='inputspec')
    outputnode = pe.Node(interface=util.IdentityInterface(fields=[
        'noise_mask_file',
        'filtered_file',
    ]),
                         name='outputspec')
    slicetimer = pe.Node(fsl.SliceTimer(), name='slicetimer')
    realigner = create_realign_flow()
    tsnr = pe.Node(confounds.TSNR(regress_poly=2), name='tsnr')
    getthresh = pe.Node(interface=fsl.ImageStats(op_string='-p 98'),
                        name='getthreshold')
    threshold_stddev = pe.Node(fsl.Threshold(), name='threshold')
    compcor = pe.Node(confounds.ACompCor(
        components_file="noise_components.txt", pre_filter=False),
                      name='compcor')
    remove_noise = pe.Node(fsl.FilterRegressor(filter_all=True),
                           name='remove_noise')
    bandpass_filter = pe.Node(fsl.TemporalFilter(), name='bandpass_filter')

    # Define connections
    restpreproc.connect(inputnode, 'func', slicetimer, 'in_file')
    restpreproc.connect(slicetimer, 'slice_time_corrected_file', realigner,
                        'inputspec.func')
    restpreproc.connect(realigner, 'outputspec.realigned_file', tsnr,
                        'in_file')
    restpreproc.connect(tsnr, 'stddev_file', threshold_stddev, 'in_file')
    restpreproc.connect(tsnr, 'stddev_file', getthresh, 'in_file')
    restpreproc.connect(getthresh, 'out_stat', threshold_stddev, 'thresh')
    restpreproc.connect(realigner, 'outputspec.realigned_file', compcor,
                        'realigned_file')
    restpreproc.connect(threshold_stddev, 'out_file', compcor, 'mask_files')
    restpreproc.connect(inputnode, 'num_noise_components', compcor,
                        'num_components')
    restpreproc.connect(tsnr, 'detrended_file', remove_noise, 'in_file')
    restpreproc.connect(compcor, 'components_file', remove_noise,
                        'design_file')
    restpreproc.connect(inputnode, 'highpass_sigma', bandpass_filter,
                        'highpass_sigma')
    restpreproc.connect(inputnode, 'lowpass_sigma', bandpass_filter,
                        'lowpass_sigma')
    restpreproc.connect(remove_noise, 'out_file', bandpass_filter, 'in_file')
    restpreproc.connect(threshold_stddev, 'out_file', outputnode,
                        'noise_mask_file')
    restpreproc.connect(bandpass_filter, 'out_file', outputnode,
                        'filtered_file')
    return restpreproc
Beispiel #9
0
                       'in_file2')
    preproc_wf.connect(maskfunc2, 'out_file', outputspec,
                       'susan_sm{0}_files'.format(kernel))

    # Temporal smoothing for SUSAN-smoothed data
    # FSL bandpass
    fsl_bandpass = pe.MapNode(fsl.ImageMaths(suffix='_tempfilt'),
                              iterfield=['in_file'],
                              name='fsl_bp_susan_sm{0}_'.format(kernel))
    preproc_wf.connect(determine_bp_sigmas, ('out_sigmas', highpass_operand),
                       fsl_bandpass, 'op_string')
    preproc_wf.connect(maskfunc2, 'out_file', fsl_bandpass, 'in_file')
    preproc_wf.connect(fsl_bandpass, 'out_file', outputspec,
                       'fsl_bp_susan_sm{0}_files'.format(kernel))

    tsnr = pe.MapNode(conf.TSNR(),
                      iterfield=['in_file'],
                      name='fsl_bp_susan_sm{0}_tsnr_'.format(kernel))
    preproc_wf.connect(fsl_bandpass, 'out_file', tsnr, 'in_file')
    preproc_wf.connect(tsnr, 'tsnr_file', outputspec,
                       'fsl_bp_susan_sm{0}_tsnr_files'.format(kernel))

    # AFNI bandpass
    afni_detrend = pe.MapNode(afni.Detrend(outputtype='NIFTI_GZ',
                                           args='-polort 4'),
                              iterfield=['in_file'],
                              name='afni_bp_susan_sm{0}_'.format(kernel))
    preproc_wf.connect(maskfunc2, 'out_file', afni_detrend, 'in_file')
    preproc_wf.connect(afni_detrend, 'out_file', outputspec,
                       'afni_bp_susan_sm{0}_files'.format(kernel))
despike=Node(afni.Despike(),name='despike')
despike.inputs.outputtype='NIFTI'
#Outputs: out_file

#Slice timing corrected (gets timing from header)
st_corr=Node(spm.SliceTiming(),name='slicetiming_correction')
st_corr.inputs.ref_slice=1
#Outputs: timecorrected_files

#Realignment using SPM <--- Maybe just estimate and apply all transforms at the end?
realign=Node(spm.Realign(),name='realign')
realign.inputs.register_to_mean=False
realign.inputs.quality=1.0
#Outputs: realignment_parameters, reliced epi images (motion corrected)

tsnr = Node(confounds.TSNR(),name = 'tsnr')
tsnr.inputs.regress_poly = 2 #Note: This removes linear + constant drifts from the epi time series. Compcor removes from the wm / csf
tsnr.inputs.mean_file = 'mean.nii'
tsnr.inputs.stddev_file = 'stdev.nii'
tsnr.inputs.tsnr_file = 'tsnr.nii'
#Outputs: detrended_file, mean_file, stddev_file, tsnr_file


smooth=Node(spm.Smooth(),name='smooth')
smooth.inputs.fwhm=fwhm


####Anatomical preprocessing####


#dcmstack - Convert dicoms to nii (with embeded metadata)
Beispiel #11
0
def init_func_report_wf(workdir=None,
                        name="func_report_wf",
                        memcalc=MemoryCalculator()):
    """

    """
    workflow = pe.Workflow(name=name)

    # only input is the bold image
    inputnode = pe.Node(
        niu.IdentityInterface(fields=[
            *func_in_attrs_from_anat_preproc_wf,
            *in_attrs_from_func_preproc_wf,
            *in_attrs_from_filt_wf,
            "metadata",
        ]),
        name="inputnode",
    )

    # output is an image file for display in the qualitycheck web page
    outputnode = pe.Node(niu.IdentityInterface(fields=["metadata"]),
                         name="outputnode")

    # EPI->mni
    epi_norm_rpt = pe.Node(
        PlotRegistration(template=config.workflow.spaces.get_spaces()[0]),
        name="epi_norm_rpt",
        mem_gb=0.1,
    )
    workflow.connect([(
        inputnode,
        epi_norm_rpt,
        [("bold_std_ref", "in_file"), ("bold_mask_std", "mask_file")],
    )])

    # calculate the tsnr image
    tsnr = pe.Node(interface=nac.TSNR(),
                   name="compute_tsnr",
                   mem_gb=memcalc.series_std_gb)
    workflow.connect([(inputnode, tsnr, [("bold_std", "in_file")])])

    # plot the tsnr image
    tsnr_rpt = pe.Node(interface=PlotEpi(),
                       name="tsnr_rpt",
                       mem_gb=memcalc.min_gb)
    workflow.connect([
        (inputnode, tsnr_rpt, [("bold_mask_std", "mask_file")]),
        (tsnr, tsnr_rpt, [("tsnr_file", "in_file")]),
    ])

    # reportnode
    mergereport = pe.Node(
        interface=niu.Merge(2),
        name="mergereport",
        run_without_submitting=True,
    )
    workflow.connect(epi_norm_rpt, "out_report", mergereport, "in1")
    workflow.connect(tsnr_rpt, "out_report", mergereport, "in2")

    reportnode = pe.Node(interface=MakeResultdicts(keys=["desc", "report"]),
                         name="reportnode")
    reportnode.inputs.desc = ["epi_norm_rpt", "tsnr_rpt"]
    workflow.connect(inputnode, "metadata", reportnode, "basedict")
    workflow.connect(mergereport, "out", reportnode, "report")

    # metrics
    resampleifneeded = pe.Node(
        interface=ResampleIfNeeded(method="nearest"),
        name="resampleifneeded",
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "std_dseg", resampleifneeded, "in_file")
    workflow.connect(inputnode, "bold_std", resampleifneeded, "ref_file")
    reportmetadata = pe.Node(interface=BoldFileReportMetadata(),
                             name="reportmetadata",
                             mem_gb=memcalc.series_std_gb)
    workflow.connect(inputnode, "metadata", reportmetadata, "basedict")
    workflow.connect(inputnode, "out3", reportmetadata, "confounds")
    workflow.connect(tsnr, "tsnr_file", reportmetadata, "tsnr_file")
    workflow.connect(inputnode, "aroma_metadata", reportmetadata,
                     "aroma_metadata")
    workflow.connect(resampleifneeded, "out_file", reportmetadata, "dseg")
    workflow.connect(reportmetadata, "outdict", outputnode, "metadata")

    assert workdir is not None
    make_reportnode_datasink(workflow, workdir)

    return workflow
Beispiel #12
0
def generate_plots(tedana_dir, out_dir=None):
    # TEDPCA
    comptable_file = op.join(tedana_dir, 'comp_table_pca.txt')
    comptable = pd.read_csv(comptable_file, sep='\t')
    fig, ax = plot_spectra(comptable)
    fig.savefig(op.join(out_dir, 'tedpca_metrics.png'), dpi=400)

    # TEDICA
    comptable_file = op.join(tedana_dir, 'comp_table_ica.txt')
    comptable = pd.read_csv(comptable_file, sep='\t')
    fig, ax = plot_spectra(comptable)
    fig.savefig(op.join(out_dir, 'tedica_metrics.png'), dpi=400)

    # T2*
    f = op.join(tedana_dir, 't2sv.nii')
    m = compute_epi_mask(f).get_data()
    fig, ax = plot_image(f, vmin=0, vmax=100)
    fig.savefig(op.join(out_dir, 't2s.png'), dpi=400)

    # S0
    f = op.join(tedana_dir, 's0v.nii')
    fig, ax = plot_image(f)
    fig.savefig(op.join(out_dir, 's0.png'), dpi=400)

    # OC
    f = op.join(tedana_dir, 'ts_OC.nii')

    # OC TSNR
    tsnr = nac.TSNR()
    tsnr.inputs.in_file = f
    res = tsnr.run()
    fig, ax = plot_image(res.outputs.tsnr_file)
    fig.savefig(op.join(out_dir, 'optcom_tsnr.png'), dpi=400)

    # OC Carpet
    fig, ax = plt.subplots(figsize=(16, 6))
    plots.plot_carpet(f, m, subplot=ax)
    fig.savefig(op.join(out_dir, 'optcom_carpet.png'), dpi=400)

    # MEDN
    f = op.join(tedana_dir, 'dn_ts_OC.nii')
    img = nib.load(f)

    # MEDN TSNR
    tsnr = nac.TSNR()
    tsnr.inputs.in_file = f
    res = tsnr.run()
    fig, ax = plot_image(res.outputs.tsnr_file)
    fig.savefig(op.join(out_dir, 'medn_tsnr.png'), dpi=400)

    # MEDN STD
    data = img.get_data()
    data = np.std(data, axis=-1)
    img2 = nib.Nifti1Image(data, img.affine)
    fig, ax = plot_image(img2)
    fig.savefig(op.join(out_dir, 'medn_std.png'), dpi=400)

    # MEDN Mean
    data = img.get_data()
    data = np.mean(data, axis=-1)
    img2 = nib.Nifti1Image(data, img.affine)
    fig, ax = plot_anatomical(img2)
    fig.savefig(op.join(out_dir, 'medn_mean.png'), dpi=400)

    # MEDN Carpet
    fig, ax = plt.subplots(figsize=(16, 6))
    plots.plot_carpet(f, m, subplot=ax)
    fig.savefig(op.join(out_dir, 'medn_carpet.png'), dpi=400)

    # Cleanup
    remove(res.outputs.mean_file)
    remove(res.outputs.stddev_file)
    remove(res.outputs.tsnr_file)
Beispiel #13
0
#Generic datagrabber module that wraps around glob in an
io_S3DataGrabber = pe.Node(io.S3DataGrabber(outfields=["outfiles"]),
                           name='io_S3DataGrabber')
io_S3DataGrabber.inputs.bucket = 'openneuro'
io_S3DataGrabber.inputs.sort_filelist = True
io_S3DataGrabber.inputs.template = 'sub-01/func/sub-01_task-simon_run-1_bold.nii.gz'
io_S3DataGrabber.inputs.anon = True
io_S3DataGrabber.inputs.bucket_path = 'ds000101/ds000101_R2.0.0/uncompressed/'
io_S3DataGrabber.inputs.local_directory = '/tmp'

#Wraps command **slicetimer**
fsl_SliceTimer = pe.Node(interface=fsl.SliceTimer(), name='fsl_SliceTimer')

#Computes the time-course SNR for a time series
confounds_TSNR = pe.Node(interface=confounds.TSNR(), name='confounds_TSNR')
confounds_TSNR.inputs.regress_poly = 3

#Wraps command **fslstats**
fsl_ImageStats = pe.Node(interface=fsl.ImageStats(), name='fsl_ImageStats')
fsl_ImageStats.inputs.op_string = '-p 98'

#Wraps command **fslmaths**
fsl_Threshold = pe.Node(interface=fsl.Threshold(), name='fsl_Threshold')
fsl_Threshold.inputs.args = '-bin'

#Anatomical compcor: for inputs and outputs, see CompCor.
confounds_ACompCor = pe.Node(interface=confounds.ACompCor(),
                             name='confounds_ACompCor')
confounds_ACompCor.inputs.num_components = 2
Beispiel #14
0
epi_s1_stack = Node(dcmstack.DcmStack(), name='epi_s1_stack')
epi_s1_stack.inputs.embed_meta = True
epi_s1_stack.inputs.out_format = 'epi1'
epi_s1_stack.inputs.out_ext = '.nii'

epi_s2_stack = Node(dcmstack.DcmStack(), name='epi_s2_stack')
epi_s2_stack.inputs.embed_meta = True
epi_s2_stack.inputs.out_format = 'epi2'
epi_s2_stack.inputs.out_ext = '.nii'

st_corr = Node(spm.SliceTiming(), name='slicetiming_correction')

realign = Node(spm.Realign(), name='realign')
realign.inputs.register_to_mean = True

tsnr = MapNode(confounds.TSNR(), iterfield='in_file', name='tsnr')
tsnr.inputs.mean_file = 'mean.nii'
tsnr.inputs.stddev_file = 'stddev.nii'
tsnr.inputs.tsnr_file = 'tsnr.nii'

despike = MapNode(afni.Despike(), iterfield='in_file', name='despike')
despike.inputs.outputtype = 'NIFTI'

seg = Node(spm.Segment(), name='seg')
seg.inputs.csf_output_type = [False, False, True]  #Output native CSF seg
seg.inputs.gm_output_type = [False, False, True]  #Output native gm seg
seg.inputs.wm_output_type = [False, False, True]  #Output native wm seg

coreg2epi = MapNode(spm.Coregister(), iterfield='target', name='coreg2epi')

#Warps to MNI space using a 3mm template image
Beispiel #15
0
    struct='%s/anatomy/highres001_brain.nii.gz')
DataFromOpenNeuro.inputs.template_args = dict(func=[['subj_id', 'run_num']],
                                              struct=[['subj_id']])

#Wraps command **slicetimer**
SliceTimer = pe.MapNode(interface=fsl.SliceTimer(),
                        name='SliceTimer',
                        iterfield=['in_file'])

#Wraps command **mcflirt**
MotionCorrection = pe.MapNode(interface=fsl.MCFLIRT(),
                              name='MotionCorrection',
                              iterfield=['in_file'])

#Computes the time-course SNR for a time series
TSNR = pe.MapNode(interface=confounds.TSNR(),
                  name='TSNR',
                  iterfield=['in_file'])
TSNR.inputs.regress_poly = 3

#Wraps command **fslstats**
ComputeLowTsnr = pe.MapNode(interface=fsl.ImageStats(),
                            name='ComputeLowTsnr',
                            iterfield=['in_file'])
ComputeLowTsnr.inputs.op_string = '-p 98'

#Wraps command **fslmaths**
Threshold = pe.MapNode(interface=fsl.Threshold(),
                       name='Threshold',
                       iterfield=['thresh', 'in_file'])
Threshold.inputs.args = '-bin'
Beispiel #16
0
def fmri_qc_workflow(dataset, settings, name='funcMRIQC'):
    """
    The fMRI qc workflow

    .. workflow::

      import os.path as op
      from mriqc.workflows.functional import fmri_qc_workflow
      datadir = op.abspath('data')
      wf = fmri_qc_workflow([op.join(datadir, 'sub-001/func/sub-001_task-rest_bold.nii.gz')],
                            settings={'bids_dir': datadir,
                                      'output_dir': op.abspath('out')})


    """

    workflow = pe.Workflow(name=name)

    biggest_file_gb = settings.get("biggest_file_size_gb", 1)

    # Define workflow, inputs and outputs
    # 0. Get data, put it in RAS orientation
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']),
                        name='inputnode')
    WFLOGGER.info(
        'Building fMRI QC workflow, datasets list: %s',
        sorted([d.replace(settings['bids_dir'] + '/', '') for d in dataset]))
    inputnode.iterables = [('in_file', dataset)]

    meta = pe.Node(ReadSidecarJSON(), name='metadata')

    outputnode = pe.Node(niu.IdentityInterface(
        fields=['qc', 'mosaic', 'out_group', 'out_dvars', 'out_fd']),
                         name='outputnode')

    reorient_and_discard = pe.Node(niu.Function(
        input_names=['in_file', 'float32'],
        output_names=['exclude_index', 'out_file'],
        function=reorient_and_discard_non_steady),
                                   name='reorient_and_discard')

    reorient_and_discard.inputs.float32 = settings.get("float32",
                                                       DEFAULTS['float32'])
    reorient_and_discard.interface.estimated_memory_gb = 4.0 * biggest_file_gb

    # Workflow --------------------------------------------------------

    # 1. HMC: head motion correct
    if settings.get('hmc_fsl', False):
        hmcwf = hmc_mcflirt(settings)
    else:
        hmcwf = hmc_afni(settings,
                         st_correct=settings.get('correct_slice_timing',
                                                 False),
                         despike=settings.get('despike', False),
                         deoblique=settings.get('deoblique', False),
                         start_idx=settings.get('start_idx', None),
                         stop_idx=settings.get('stop_idx', None))

    # Set HMC settings
    hmcwf.inputs.inputnode.fd_radius = settings.get('fd_radius',
                                                    DEFAULT_FD_RADIUS)

    mean = pe.Node(
        afni.TStat(  # 2. Compute mean fmri
            options='-mean', outputtype='NIFTI_GZ'),
        name='mean')
    mean.interface.estimated_memory_gb = biggest_file_gb * 1.5
    skullstrip_epi = fmri_bmsk_workflow(use_bet=True)

    # EPI to MNI registration
    ema = epi_mni_align(settings)

    # Compute TSNR using nipype implementation
    tsnr = pe.Node(nac.TSNR(), name='compute_tsnr')
    tsnr.interface.estimated_memory_gb = biggest_file_gb * 4.5

    # 7. Compute IQMs
    iqmswf = compute_iqms(settings)
    # Reports
    repwf = individual_reports(settings)
    # Upload metrics
    upldwf = upload_wf(settings)

    workflow.connect([
        (inputnode, meta, [('in_file', 'in_file')]),
        (inputnode, reorient_and_discard, [('in_file', 'in_file')]),
        (reorient_and_discard, hmcwf, [('out_file', 'inputnode.in_file')]),
        (mean, skullstrip_epi, [('out_file', 'inputnode.in_file')]),
        (hmcwf, mean, [('outputnode.out_file', 'in_file')]),
        (hmcwf, tsnr, [('outputnode.out_file', 'in_file')]),
        (mean, ema, [('out_file', 'inputnode.epi_mean')]),
        (skullstrip_epi, ema, [('outputnode.out_file', 'inputnode.epi_mask')]),
        (meta, iqmswf, [('subject_id', 'inputnode.subject_id'),
                        ('session_id', 'inputnode.session_id'),
                        ('task_id', 'inputnode.task_id'),
                        ('acq_id', 'inputnode.acq_id'),
                        ('rec_id', 'inputnode.rec_id'),
                        ('run_id', 'inputnode.run_id'),
                        ('out_dict', 'inputnode.metadata')]),
        (reorient_and_discard, iqmswf, [('out_file', 'inputnode.orig')]),
        (mean, iqmswf, [('out_file', 'inputnode.epi_mean')]),
        (hmcwf, iqmswf, [('outputnode.out_file', 'inputnode.hmc_epi'),
                         ('outputnode.out_fd', 'inputnode.hmc_fd')]),
        (skullstrip_epi, iqmswf, [('outputnode.out_file',
                                   'inputnode.brainmask')]),
        (tsnr, iqmswf, [('tsnr_file', 'inputnode.in_tsnr')]),
        (reorient_and_discard, repwf, [('out_file', 'inputnode.orig')]),
        (mean, repwf, [('out_file', 'inputnode.epi_mean')]),
        (tsnr, repwf, [('stddev_file', 'inputnode.in_stddev')]),
        (skullstrip_epi, repwf, [('outputnode.out_file', 'inputnode.brainmask')
                                 ]),
        (hmcwf, repwf, [('outputnode.out_fd', 'inputnode.hmc_fd'),
                        ('outputnode.out_file', 'inputnode.hmc_epi')]),
        (ema, repwf, [('outputnode.epi_parc', 'inputnode.epi_parc'),
                      ('outputnode.report', 'inputnode.mni_report')]),
        (reorient_and_discard, repwf, [('exclude_index',
                                        'inputnode.exclude_index')]),
        (iqmswf, repwf, [('outputnode.out_file', 'inputnode.in_iqms'),
                         ('outputnode.out_dvars', 'inputnode.in_dvars'),
                         ('outputnode.outliers', 'inputnode.outliers')]),
        (iqmswf, upldwf, [('outputnode.out_file', 'inputnode.in_iqms')]),
        (hmcwf, outputnode, [('outputnode.out_fd', 'out_fd')]),
    ])

    if settings.get('fft_spikes_detector', False):
        workflow.connect([
            (iqmswf, repwf, [('outputnode.out_spikes', 'inputnode.in_spikes'),
                             ('outputnode.out_fft', 'inputnode.in_fft')]),
        ])

    if settings.get('ica', False):
        melodic = pe.Node(nws.MELODICRPT(no_bet=True,
                                         no_mask=True,
                                         no_mm=True,
                                         generate_report=True),
                          name="ICA")
        melodic.interface.estimated_memory_gb = biggest_file_gb * 5
        workflow.connect([
            (reorient_and_discard, melodic, [('out_file', 'in_files')]),
            (skullstrip_epi, melodic, [('outputnode.out_file', 'report_mask')
                                       ]),
            (melodic, repwf, [('out_report', 'inputnode.ica_report')])
        ])

    return workflow
Beispiel #17
0
                           name='NodeName_30f69e0')
NodeHash_30f69e0.inputs.bucket = 'openneuro'
NodeHash_30f69e0.inputs.sort_filelist = True
NodeHash_30f69e0.inputs.template = 'sub-01/func/sub-01_task-simon_run-1_bold.nii.gz'
NodeHash_30f69e0.inputs.anon = True
NodeHash_30f69e0.inputs.bucket_path = 'ds000101/ds000101_R2.0.0/uncompressed/'
NodeHash_30f69e0.inputs.local_directory = '/tmp'

#Wraps command **slicetimer**
NodeHash_1d000c0 = pe.Node(interface=fsl.SliceTimer(), name='NodeName_1d000c0')

#Wraps command **mcflirt**
NodeHash_22f2e80 = pe.Node(interface=fsl.MCFLIRT(), name='NodeName_22f2e80')

#Computes the time-course SNR for a time series
NodeHash_50c02c0 = pe.Node(interface=confounds.TSNR(), name='NodeName_50c02c0')
NodeHash_50c02c0.inputs.regress_poly = 3

#Wraps command **fslstats**
NodeHash_3ac27f0 = pe.Node(interface=fsl.ImageStats(), name='NodeName_3ac27f0')
NodeHash_3ac27f0.inputs.op_string = '-p 98'

#Wraps command **fslmaths**
NodeHash_30f6760 = pe.Node(interface=fsl.Threshold(), name='NodeName_30f6760')
NodeHash_30f6760.inputs.args = '-bin'

#Anatomical compcor: for inputs and outputs, see CompCor.
NodeHash_325da10 = pe.Node(interface=confounds.ACompCor(),
                           name='NodeName_325da10')
NodeHash_325da10.inputs.num_components = 2
Beispiel #18
0
my_io_S3DataGrabber.inputs.anon = True
my_io_S3DataGrabber.inputs.bucket_path = 'ds000101/ds000101_R2.0.0/uncompressed/'
my_io_S3DataGrabber.inputs.local_directory = '/tmp'

#Wraps command **slicetimer**
my_fsl_SliceTimer = pe.Node(interface=fsl.SliceTimer(),
                            name='my_fsl_SliceTimer',
                            iterfield=[''])

#Wraps command **mcflirt**
my_fsl_MCFLIRT = pe.Node(interface=fsl.MCFLIRT(),
                         name='my_fsl_MCFLIRT',
                         iterfield=[''])

#Computes the time-course SNR for a time series
my_confounds_TSNR = pe.Node(interface=confounds.TSNR(),
                            name='my_confounds_TSNR',
                            iterfield=[''])
my_confounds_TSNR.inputs.regress_poly = 3

#Wraps command **fslstats**
my_fsl_ImageStats = pe.Node(interface=fsl.ImageStats(),
                            name='my_fsl_ImageStats',
                            iterfield=[''])
my_fsl_ImageStats.inputs.op_string = '-p 98'

#Wraps command **fslmaths**
my_fsl_Threshold = pe.Node(interface=fsl.Threshold(),
                           name='my_fsl_Threshold',
                           iterfield=[''])
my_fsl_Threshold.inputs.args = '-bin'
Beispiel #19
0
def fmri_qc_workflow(dataset, settings, name='funcMRIQC'):
    """ The fMRI qc workflow """

    workflow = pe.Workflow(name=name)

    # Define workflow, inputs and outputs
    # 0. Get data, put it in RAS orientation
    inputnode = pe.Node(niu.IdentityInterface(fields=['in_file']), name='inputnode')
    WFLOGGER.info('Building fMRI QC workflow, datasets list: %s',
                  sorted([d.replace(settings['bids_dir'] + '/', '') for d in dataset]))
    inputnode.iterables = [('in_file', dataset)]


    meta = pe.Node(ReadSidecarJSON(), name='metadata')

    outputnode = pe.Node(niu.IdentityInterface(
        fields=['qc', 'mosaic', 'out_group', 'out_dvars',
                'out_fd']), name='outputnode')


    reorient_and_discard = pe.Node(niu.Function(input_names=['in_file'],
                                                output_names=['exclude_index',
                                                              'out_file'],
                                                function=reorient_and_discard_non_steady),
                                   name='reorient_and_discard')

    # Workflow --------------------------------------------------------

    # 1. HMC: head motion correct
    hmcwf = hmc_mcflirt()
    if settings.get('hmc_afni', False):
        hmcwf = hmc_afni(st_correct=settings.get('correct_slice_timing', False),
                         despike=settings.get('despike', False),
                         deoblique=settings.get('deoblique', False))

    # Set HMC settings
    hmcwf.inputs.inputnode.fd_radius = settings.get('fd_radius', DEFAULT_FD_RADIUS)
    if settings.get('start_idx'):
        hmcwf.inputs.inputnode.start_idx = settings['start_idx']
    if settings.get('stop_idx'):
        hmcwf.inputs.inputnode.stop_idx = settings['stop_idx']


    mean = pe.Node(afni.TStat(                   # 2. Compute mean fmri
        options='-mean', outputtype='NIFTI_GZ'), name='mean')
    bmw = fmri_bmsk_workflow(                   # 3. Compute brain mask
        use_bet=settings.get('use_bet', False))

    # EPI to MNI registration
    ema = epi_mni_align(ants_nthreads=settings['ants_nthreads'],
                        testing=settings.get('testing', False))

    # Compute TSNR using nipype implementation
    tsnr = pe.Node(nac.TSNR(), name='compute_tsnr')

    # 7. Compute IQMs
    iqmswf = compute_iqms(settings)
    # Reports
    repwf = individual_reports(settings)

    workflow.connect([
        (inputnode, meta, [('in_file', 'in_file')]),
        (inputnode, reorient_and_discard, [('in_file', 'in_file')]),
        (reorient_and_discard, hmcwf, [('out_file', 'inputnode.in_file')]),
        (hmcwf, bmw, [('outputnode.out_file', 'inputnode.in_file')]),
        (hmcwf, mean, [('outputnode.out_file', 'in_file')]),
        (hmcwf, tsnr, [('outputnode.out_file', 'in_file')]),
        (mean, ema, [('out_file', 'inputnode.epi_mean')]),
        (bmw, ema, [('outputnode.out_file', 'inputnode.epi_mask')]),
        (meta, iqmswf, [('subject_id', 'inputnode.subject_id'),
                        ('session_id', 'inputnode.session_id'),
                        ('task_id', 'inputnode.task_id'),
                        ('run_id', 'inputnode.run_id'),
                        ('out_dict', 'inputnode.metadata')]),
        (reorient_and_discard, iqmswf, [('out_file', 'inputnode.orig')]),
        (mean, iqmswf, [('out_file', 'inputnode.epi_mean')]),
        (hmcwf, iqmswf, [('outputnode.out_file', 'inputnode.hmc_epi'),
                         ('outputnode.out_fd', 'inputnode.hmc_fd')]),
        (bmw, iqmswf, [('outputnode.out_file', 'inputnode.brainmask')]),
        (tsnr, iqmswf, [('tsnr_file', 'inputnode.in_tsnr')]),
        (reorient_and_discard, repwf, [('out_file', 'inputnode.orig')]),
        (mean, repwf, [('out_file', 'inputnode.epi_mean')]),
        (tsnr, repwf, [('stddev_file', 'inputnode.in_stddev')]),
        (bmw, repwf, [('outputnode.out_file', 'inputnode.brainmask')]),
        (hmcwf, repwf, [('outputnode.out_fd', 'inputnode.hmc_fd')]),
        (ema, repwf, [('outputnode.epi_parc', 'inputnode.epi_parc'),
                      ('outputnode.report', 'inputnode.mni_report')]),
        (reorient_and_discard, repwf, [('exclude_index', 'inputnode.exclude_index')]),
        (iqmswf, repwf, [('outputnode.out_file', 'inputnode.in_iqms'),
                         ('outputnode.out_dvars', 'inputnode.in_dvars'),
                         ('outputnode.out_spikes', 'inputnode.in_spikes'),
                         ('outputnode.outliers', 'inputnode.outliers')]),
        (hmcwf, outputnode, [('outputnode.out_fd', 'out_fd')]),
    ])

    return workflow
Beispiel #20
0
def init_func_report_wf(workdir=None, fd_thres=None, name="func_report_wf", memcalc=MemoryCalculator()):
    """

    """
    workflow = pe.Workflow(name=name)

    #
    fmriprepreports = ["bold_conf", "reg", "bold_rois", "compcor", "conf_corr", "sdc"]
    fmriprepreportdatasinks = [f"ds_report_{fr}" for fr in fmriprepreports]
    strfields = [
        "bold_std",
        "bold_std_ref",
        "bold_mask_std",
        "movpar_file",
        "skip_vols",
        "confounds",
        "std_dseg",
        "method",
        *fmriprepreportdatasinks,
    ]
    inputnode = pe.Node(
        Exec(
            fieldtpls=[
                ("tags", None),
                *[(field, "firststr") for field in strfields],
                ("fd_thres", None)
            ]
        ),
        name="inputnode",
    )
    outputnode = pe.Node(niu.IdentityInterface(fields=["vals"]), name="outputnode")

    #
    make_resultdicts = pe.Node(
        MakeResultdicts(
            reportkeys=["epi_norm_rpt", "tsnr_rpt", "carpetplot", *fmriprepreports],
            valkeys=["dummy", "sdc_method"]
        ),
        name="make_resultdicts",
    )
    workflow.connect(inputnode, "tags", make_resultdicts, "tags")
    workflow.connect(inputnode, "skip_vols", make_resultdicts, "dummy")
    workflow.connect(inputnode, "method", make_resultdicts, "sdc_method")

    #
    resultdict_datasink = pe.Node(
        ResultdictDatasink(base_directory=workdir), name="resultdict_datasink"
    )
    workflow.connect(make_resultdicts, "resultdicts", resultdict_datasink, "indicts")

    #
    for fr, frd in zip(fmriprepreports, fmriprepreportdatasinks):
        workflow.connect(inputnode, frd, make_resultdicts, fr)

    # EPI -> mni
    epi_norm_rpt = pe.Node(
        PlotRegistration(template=config.workflow.spaces.get_spaces()[0]),
        name="epi_norm_rpt",
        mem_gb=0.1,
    )
    workflow.connect(inputnode, "bold_std_ref", epi_norm_rpt, "in_file")
    workflow.connect(inputnode, "bold_mask_std", epi_norm_rpt, "mask_file")
    workflow.connect(epi_norm_rpt, "out_report", make_resultdicts, "epi_norm_rpt")

    # plot the tsnr image
    tsnr = pe.Node(nac.TSNR(), name="compute_tsnr", mem_gb=memcalc.series_std_gb)
    workflow.connect(inputnode, "bold_std", tsnr, "in_file")

    tsnr_rpt = pe.Node(PlotEpi(), name="tsnr_rpt", mem_gb=memcalc.min_gb)
    workflow.connect(tsnr, "tsnr_file", tsnr_rpt, "in_file")
    workflow.connect(inputnode, "bold_mask_std", tsnr_rpt, "mask_file")
    workflow.connect(tsnr_rpt, "out_report", make_resultdicts, "tsnr_rpt")

    #
    reference_dict = dict(reference_space=constants.reference_space, reference_res=constants.reference_res)
    reference_dict["input_space"] = reference_dict["reference_space"]
    resample = pe.Node(
        Resample(interpolation="MultiLabel", **reference_dict),
        name="resample",
        mem_gb=memcalc.series_std_gb,
    )
    workflow.connect(inputnode, "std_dseg", resample, "input_image")

    # vals
    confvals = pe.Node(
        Vals(), name="vals", mem_gb=memcalc.series_std_gb
    )
    workflow.connect(inputnode, "fd_thres", confvals, "fd_thres")
    workflow.connect(inputnode, "confounds", confvals, "confounds")

    calcmean = pe.Node(
        CalcMean(key="mean_gm_tsnr"), name="calcmean", mem_gb=memcalc.series_std_gb
    )
    workflow.connect(confvals, "vals", calcmean, "vals")  # base dict to update
    workflow.connect(tsnr, "tsnr_file", calcmean, "in_file")
    workflow.connect(resample, "output_image", calcmean, "dseg")

    workflow.connect(calcmean, "vals", make_resultdicts, "vals")
    workflow.connect(make_resultdicts, "vals", outputnode, "vals")

    return workflow