def init_fmriprep_wf(): """ Build *fMRIPrep*'s pipeline. This workflow organizes the execution of FMRIPREP, with a sub-workflow for each subject. If FreeSurfer's ``recon-all`` is to be run, a corresponding folder is created and populated with any needed template subjects under the derivatives folder. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes from fmriprep.workflows.tests import mock_config from fmriprep.workflows.base import init_fmriprep_wf with mock_config(): wf = init_fmriprep_wf() """ from niworkflows.engine.workflows import LiterateWorkflow as Workflow from niworkflows.interfaces.bids import BIDSFreeSurferDir fmriprep_wf = Workflow(name='fmriprep_wf') fmriprep_wf.base_dir = config.execution.work_dir freesurfer = config.workflow.run_reconall if freesurfer: fsdir = pe.Node( BIDSFreeSurferDir(derivatives=config.execution.output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=config.workflow.spaces.get_fs_spaces()), name='fsdir_run_%s' % config.execution.run_uuid.replace('-', '_'), run_without_submitting=True) if config.execution.fs_subjects_dir is not None: fsdir.inputs.subjects_dir = str( config.execution.fs_subjects_dir.absolute()) for subject_id in config.execution.participant_label: single_subject_wf = init_single_subject_wf(subject_id) single_subject_wf.config['execution']['crashdump_dir'] = str( config.execution.output_dir / "fmriprep" / "-".join( ("sub", subject_id)) / "log" / config.execution.run_uuid) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: fmriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: fmriprep_wf.add_nodes([single_subject_wf]) # Dump a copy of the config file into the log directory log_dir = config.execution.output_dir / 'fmriprep' / 'sub-{}'.format(subject_id) \ / 'log' / config.execution.run_uuid log_dir.mkdir(exist_ok=True, parents=True) config.to_filename(log_dir / 'fmriprep.toml') return fmriprep_wf
def init_dmriprep_wf(): """ Create the base workflow. This workflow organizes the execution of *dMRIPrep*, with a sub-workflow for each subject. If FreeSurfer's recon-all is to be run, a FreeSurfer derivatives folder is created and populated with any needed template subjects. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes from dmriprep.config.testing import mock_config from dmriprep.workflows.base import init_dmriprep_wf with mock_config(): wf = init_dmriprep_wf() """ dmriprep_wf = Workflow(name="dmriprep_wf") dmriprep_wf.base_dir = config.execution.work_dir freesurfer = config.workflow.run_reconall if freesurfer: fsdir = pe.Node( BIDSFreeSurferDir( derivatives=config.execution.output_dir, freesurfer_home=os.getenv("FREESURFER_HOME"), spaces=config.workflow.spaces.get_fs_spaces(), ), name=f"fsdir_run_{config.execution.run_uuid.replace('-', '_')}", run_without_submitting=True, ) if config.execution.fs_subjects_dir is not None: fsdir.inputs.subjects_dir = str( config.execution.fs_subjects_dir.absolute()) for subject_id in config.execution.participant_label: single_subject_wf = init_single_subject_wf(subject_id) single_subject_wf.config["execution"]["crashdump_dir"] = str( config.execution.output_dir / "dmriprep" / f"sub-{subject_id}" / "log" / config.execution.run_uuid) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: dmriprep_wf.connect(fsdir, "subjects_dir", single_subject_wf, "fsinputnode.subjects_dir") else: dmriprep_wf.add_nodes([single_subject_wf]) # Dump a copy of the config file into the log directory log_dir = (config.execution.output_dir / "dmriprep" / f"sub-{subject_id}" / "log" / config.execution.run_uuid) log_dir.mkdir(exist_ok=True, parents=True) config.to_filename(log_dir / "dmriprep.toml") return dmriprep_wf
def init_fmriprep_wf(): """ Build *fMRIPrep*'s pipeline. This workflow organizes the execution of FMRIPREP, with a sub-workflow for each subject. If FreeSurfer's ``recon-all`` is to be run, a corresponding folder is created and populated with any needed template subjects under the derivatives folder. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes from fprodents.workflows.tests import mock_config from fprodents.workflows.base import init_fmriprep_wf with mock_config(): wf = init_fmriprep_wf() """ from niworkflows.engine.workflows import LiterateWorkflow as Workflow fmriprep_wf = Workflow(name="fmriprep_wf") fmriprep_wf.base_dir = config.execution.work_dir for subject_id in config.execution.participant_label: single_subject_wf = init_single_subject_wf(subject_id) # Dump a copy of the config file into the log directory log_dir = (config.execution.output_dir / "fmriprep" / f"sub-{subject_id}" / "log" / config.execution.run_uuid) log_dir.mkdir(exist_ok=True, parents=True) config.to_filename(log_dir / "fmriprep.toml") single_subject_wf.config["execution"]["crashdump_dir"] = str(log_dir) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) fmriprep_wf.add_nodes([single_subject_wf]) return fmriprep_wf
def init_fmriprep_wf(layout, subject_list, task_id, echo_idx, run_uuid, work_dir, output_dir, ignore, debug, low_mem, anat_only, longitudinal, t2s_coreg, omp_nthreads, skull_strip_template, skull_strip_fixed_seed, freesurfer, output_spaces, template, medial_surface_nan, cifti_output, hires, use_bbr, bold2t1w_dof, fmap_bspline, fmap_demean, use_syn, force_syn, use_aroma, err_on_aroma_warn, aroma_melodic_dim, template_out_grid): """ This workflow organizes the execution of FMRIPREP, with a sub-workflow for each subject. If FreeSurfer's recon-all is to be run, a FreeSurfer derivatives folder is created and populated with any needed template subjects. .. workflow:: :graph2use: orig :simple_form: yes import os from collections import namedtuple BIDSLayout = namedtuple('BIDSLayout', ['root'], defaults='.') from fmriprep.workflows.base import init_fmriprep_wf os.environ['FREESURFER_HOME'] = os.getcwd() wf = init_fmriprep_wf(layout=BIDSLayout(), subject_list=['fmripreptest'], task_id='', echo_idx=None, run_uuid='X', work_dir='.', output_dir='.', ignore=[], debug=False, low_mem=False, anat_only=False, longitudinal=False, t2s_coreg=False, omp_nthreads=1, skull_strip_template='OASIS30ANTs', skull_strip_fixed_seed=False, freesurfer=True, output_spaces=['T1w', 'fsnative', 'template', 'fsaverage5'], template='MNI152NLin2009cAsym', medial_surface_nan=False, cifti_output=False, hires=True, use_bbr=True, bold2t1w_dof=9, fmap_bspline=False, fmap_demean=True, use_syn=True, force_syn=True, use_aroma=False, err_on_aroma_warn=False, aroma_melodic_dim=-200, template_out_grid='native') Parameters layout : BIDSLayout object BIDS dataset layout subject_list : list List of subject labels task_id : str or None Task ID of BOLD series to preprocess, or ``None`` to preprocess all echo_idx : int or None Index of echo to preprocess in multiecho BOLD series, or ``None`` to preprocess all run_uuid : str Unique identifier for execution instance work_dir : str Directory in which to store workflow execution state and temporary files output_dir : str Directory in which to save derivatives ignore : list Preprocessing steps to skip (may include "slicetiming", "fieldmaps") debug : bool Enable debugging outputs low_mem : bool Write uncompressed .nii files in some cases to reduce memory usage anat_only : bool Disable functional workflows longitudinal : bool Treat multiple sessions as longitudinal (may increase runtime) See sub-workflows for specific differences t2s_coreg : bool For multi-echo EPI, use the calculated T2*-map for T2*-driven coregistration omp_nthreads : int Maximum number of threads an individual process may use skull_strip_template : str Name of ANTs skull-stripping template ('OASIS30ANTs' or 'NKI') skull_strip_fixed_seed : bool Do not use a random seed for skull-stripping - will ensure run-to-run replicability when used with --omp-nthreads 1 freesurfer : bool Enable FreeSurfer surface reconstruction (may increase runtime) output_spaces : list List of output spaces functional images are to be resampled to. Some parts of pipeline will only be instantiated for some output spaces. Valid spaces: - T1w - template - fsnative - fsaverage (or other pre-existing FreeSurfer templates) template : str Name of template targeted by ``template`` output space medial_surface_nan : bool Replace medial wall values with NaNs on functional GIFTI files cifti_output : bool Generate bold CIFTI file in output spaces hires : bool Enable sub-millimeter preprocessing in FreeSurfer use_bbr : bool or None Enable/disable boundary-based registration refinement. If ``None``, test BBR result for distortion before accepting. bold2t1w_dof : 6, 9 or 12 Degrees-of-freedom for BOLD-T1w registration fmap_bspline : bool **Experimental**: Fit B-Spline field using least-squares fmap_demean : bool Demean voxel-shift map during unwarp use_syn : bool **Experimental**: Enable ANTs SyN-based susceptibility distortion correction (SDC). If fieldmaps are present and enabled, this is not run, by default. force_syn : bool **Temporary**: Always run SyN-based SDC use_aroma : bool Perform ICA-AROMA on MNI-resampled functional series err_on_aroma_warn : bool Do not fail on ICA-AROMA errors template_out_grid : str Keyword ('native', '1mm' or '2mm') or path of custom reference image for normalization """ fmriprep_wf = Workflow(name='fmriprep_wf') fmriprep_wf.base_dir = work_dir if freesurfer: fsdir = pe.Node(BIDSFreeSurferDir( derivatives=output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=output_spaces), name='fsdir_run_' + run_uuid.replace('-', '_'), run_without_submitting=True) reportlets_dir = os.path.join(work_dir, 'reportlets') for subject_id in subject_list: single_subject_wf = init_single_subject_wf( layout=layout, subject_id=subject_id, task_id=task_id, echo_idx=echo_idx, name="single_subject_" + subject_id + "_wf", reportlets_dir=reportlets_dir, output_dir=output_dir, ignore=ignore, debug=debug, low_mem=low_mem, anat_only=anat_only, longitudinal=longitudinal, t2s_coreg=t2s_coreg, omp_nthreads=omp_nthreads, skull_strip_template=skull_strip_template, skull_strip_fixed_seed=skull_strip_fixed_seed, freesurfer=freesurfer, output_spaces=output_spaces, template=template, medial_surface_nan=medial_surface_nan, cifti_output=cifti_output, hires=hires, use_bbr=use_bbr, bold2t1w_dof=bold2t1w_dof, fmap_bspline=fmap_bspline, fmap_demean=fmap_demean, use_syn=use_syn, force_syn=force_syn, template_out_grid=template_out_grid, use_aroma=use_aroma, aroma_melodic_dim=aroma_melodic_dim, err_on_aroma_warn=err_on_aroma_warn, ) single_subject_wf.config['execution']['crashdump_dir'] = (os.path.join( output_dir, "fmriprep", "sub-" + subject_id, 'log', run_uuid)) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: fmriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: fmriprep_wf.add_nodes([single_subject_wf]) return fmriprep_wf
def init_smriprep_wf( debug, fast_track, freesurfer, fs_subjects_dir, hires, layout, longitudinal, low_mem, omp_nthreads, output_dir, run_uuid, skull_strip_mode, skull_strip_fixed_seed, skull_strip_template, spaces, subject_list, work_dir, bids_filters, ): """ Create the execution graph of *sMRIPrep*, with a sub-workflow for each subject. If FreeSurfer's ``recon-all`` is to be run, a FreeSurfer derivatives folder is created and populated with any needed template subjects. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes import os from collections import namedtuple BIDSLayout = namedtuple('BIDSLayout', ['root']) os.environ['FREESURFER_HOME'] = os.getcwd() from smriprep.workflows.base import init_smriprep_wf from niworkflows.utils.spaces import SpatialReferences, Reference wf = init_smriprep_wf( debug=False, fast_track=False, freesurfer=True, fs_subjects_dir=None, hires=True, layout=BIDSLayout('.'), longitudinal=False, low_mem=False, omp_nthreads=1, output_dir='.', run_uuid='testrun', skull_strip_fixed_seed=False, skull_strip_mode='force', skull_strip_template=Reference('OASIS30ANTs'), spaces=SpatialReferences(spaces=['MNI152NLin2009cAsym', 'fsaverage5']), subject_list=['smripreptest'], work_dir='.', bids_filters=None, ) Parameters ---------- debug : :obj:`bool` Enable debugging outputs fast_track : :obj:`bool` Fast-track the workflow by searching for existing derivatives. freesurfer : :obj:`bool` Enable FreeSurfer surface reconstruction (may increase runtime) fs_subjects_dir : os.PathLike or None Use existing FreeSurfer subjects directory if provided hires : :obj:`bool` Enable sub-millimeter preprocessing in FreeSurfer layout : BIDSLayout object BIDS dataset layout longitudinal : :obj:`bool` Treat multiple sessions as longitudinal (may increase runtime) See sub-workflows for specific differences low_mem : :obj:`bool` Write uncompressed .nii files in some cases to reduce memory usage omp_nthreads : :obj:`int` Maximum number of threads an individual process may use output_dir : :obj:`str` Directory in which to save derivatives run_uuid : :obj:`str` Unique identifier for execution instance skull_strip_fixed_seed : :obj:`bool` Do not use a random seed for skull-stripping - will ensure run-to-run replicability when used with --omp-nthreads 1 skull_strip_mode : :obj:`str` Determiner for T1-weighted skull stripping (`force` ensures skull stripping, `skip` ignores skull stripping, and `auto` automatically ignores skull stripping if pre-stripped brains are detected). skull_strip_template : :py:class:`~niworkflows.utils.spaces.Reference` Spatial reference to use in atlas-based brain extraction. spaces : :py:class:`~niworkflows.utils.spaces.SpatialReferences` Object containing standard and nonstandard space specifications. subject_list : :obj:`list` List of subject labels work_dir : :obj:`str` Directory in which to store workflow execution state and temporary files bids_filters : dict Provides finer specification of the pipeline input files through pybids entities filters. A dict with the following structure {<suffix>:{<entity>:<filter>,...},...} """ smriprep_wf = Workflow(name='smriprep_wf') smriprep_wf.base_dir = work_dir if freesurfer: fsdir = pe.Node(BIDSFreeSurferDir( derivatives=output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=spaces.get_fs_spaces()), name='fsdir_run_%s' % run_uuid.replace('-', '_'), run_without_submitting=True) if fs_subjects_dir is not None: fsdir.inputs.subjects_dir = str(fs_subjects_dir.absolute()) for subject_id in subject_list: single_subject_wf = init_single_subject_wf( debug=debug, freesurfer=freesurfer, fast_track=fast_track, hires=hires, layout=layout, longitudinal=longitudinal, low_mem=low_mem, name="single_subject_%s_wf" % subject_id, omp_nthreads=omp_nthreads, output_dir=output_dir, skull_strip_fixed_seed=skull_strip_fixed_seed, skull_strip_mode=skull_strip_mode, skull_strip_template=skull_strip_template, spaces=spaces, subject_id=subject_id, bids_filters=bids_filters, ) single_subject_wf.config['execution']['crashdump_dir'] = (os.path.join( output_dir, "smriprep", "sub-" + subject_id, 'log', run_uuid)) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: smriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: smriprep_wf.add_nodes([single_subject_wf]) return smriprep_wf
def init_fmriprep_wf( anat_only, aroma_melodic_dim, bold2t1w_dof, cifti_output, debug, dummy_scans, echo_idx, err_on_aroma_warn, fmap_bspline, fmap_demean, force_syn, freesurfer, fs_subjects_dir, hires, ignore, layout, longitudinal, low_mem, medial_surface_nan, omp_nthreads, output_dir, regressors_all_comps, regressors_dvars_th, regressors_fd_th, run_uuid, skull_strip_fixed_seed, skull_strip_template, spaces, subject_list, t2s_coreg, task_id, use_aroma, use_bbr, use_syn, work_dir, ): """ Build *fMRIPrep*'s pipeline. This workflow organizes the execution of FMRIPREP, with a sub-workflow for each subject. If FreeSurfer's ``recon-all`` is to be run, a corresponding folder is created and populated with any needed template subjects under the derivatives folder. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes import os from collections import namedtuple, OrderedDict BIDSLayout = namedtuple('BIDSLayout', ['root']) from fmriprep.workflows.base import init_fmriprep_wf from niworkflows.utils.spaces import Reference, SpatialReferences os.environ['FREESURFER_HOME'] = os.getcwd() wf = init_fmriprep_wf( anat_only=False, aroma_melodic_dim=-200, bold2t1w_dof=9, cifti_output=False, debug=False, dummy_scans=None, echo_idx=None, err_on_aroma_warn=False, fmap_bspline=False, fmap_demean=True, force_syn=True, freesurfer=True, fs_subjects_dir=None, hires=True, ignore=[], layout=BIDSLayout('.'), longitudinal=False, low_mem=False, medial_surface_nan=False, omp_nthreads=1, output_dir='.', regressors_all_comps=False, regressors_dvars_th=1.5, regressors_fd_th=0.5, run_uuid='X', skull_strip_fixed_seed=False, skull_strip_template=Reference('OASIS30ANTs'), spaces=SpatialReferences( spaces=['MNI152Lin', ('fsaverage', {'density': '10k'}), 'T1w', 'fsnative'], checkpoint=True), subject_list=['fmripreptest'], t2s_coreg=False, task_id='', use_aroma=False, use_bbr=True, use_syn=True, work_dir='.', ) Parameters ---------- anat_only : bool Disable functional workflows bold2t1w_dof : 6, 9 or 12 Degrees-of-freedom for BOLD-T1w registration cifti_output : bool Generate bold CIFTI file in output spaces debug : bool Enable debugging outputs dummy_scans : int or None Number of volumes to consider as non steady state echo_idx : int or None Index of echo to preprocess in multiecho BOLD series, or ``None`` to preprocess all err_on_aroma_warn : bool Do not fail on ICA-AROMA errors fmap_bspline : bool **Experimental**: Fit B-Spline field using least-squares fmap_demean : bool Demean voxel-shift map during unwarp force_syn : bool **Temporary**: Always run SyN-based SDC freesurfer : bool Enable FreeSurfer surface reconstruction (may increase runtime) hires : bool Enable sub-millimeter preprocessing in FreeSurfer ignore : list Preprocessing steps to skip (may include "slicetiming", "fieldmaps") layout : BIDSLayout object BIDS dataset layout longitudinal : bool Treat multiple sessions as longitudinal (may increase runtime) See sub-workflows for specific differences low_mem : bool Write uncompressed .nii files in some cases to reduce memory usage medial_surface_nan : bool Replace medial wall values with NaNs on functional GIFTI files omp_nthreads : int Maximum number of threads an individual process may use output_dir : str Directory in which to save derivatives regressors_all_comps Return all CompCor component time series instead of the top fraction regressors_dvars_th Criterion for flagging DVARS outliers regressors_fd_th Criterion for flagging framewise displacement outliers run_uuid : str Unique identifier for execution instance skull_strip_template : tuple Name of target template for brain extraction with ANTs' ``antsBrainExtraction``, and corresponding dictionary of output-space modifiers. skull_strip_fixed_seed : bool Do not use a random seed for skull-stripping - will ensure run-to-run replicability when used with --omp-nthreads 1 spaces : :py:class:`~niworkflows.utils.spaces.SpatialReferences` A container for storing, organizing, and parsing spatial normalizations. Composed of :py:class:`~niworkflows.utils.spaces.Reference` objects representing spatial references. Each ``Reference`` contains a space, which is a string of either TemplateFlow template IDs (e.g., ``MNI152Lin``, ``MNI152NLin6Asym``, ``MNIPediatricAsym``), nonstandard references (e.g., ``T1w`` or ``anat``, ``sbref``, ``run``, etc.), or a custom template located in the TemplateFlow root directory. Each ``Reference`` may also contain a spec, which is a dictionary with template specifications (e.g., a specification of ``{'resolution': 2}`` would lead to resampling on a 2mm resolution of the space). subject_list : list List of subject labels t2s_coreg : bool For multi-echo EPI, use the calculated T2*-map for T2*-driven coregistration task_id : str or None Task ID of BOLD series to preprocess, or ``None`` to preprocess all use_aroma : bool Perform ICA-AROMA on MNI-resampled functional series use_bbr : bool or None Enable/disable boundary-based registration refinement. If ``None``, test BBR result for distortion before accepting. use_syn : bool **Experimental**: Enable ANTs SyN-based susceptibility distortion correction (SDC). If fieldmaps are present and enabled, this is not run, by default. work_dir : str Directory in which to store workflow execution state and temporary files """ fmriprep_wf = Workflow(name='fmriprep_wf') fmriprep_wf.base_dir = work_dir if freesurfer: fsdir = pe.Node( BIDSFreeSurferDir( derivatives=output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=spaces.get_fs_spaces()), name='fsdir_run_' + run_uuid.replace('-', '_'), run_without_submitting=True) if fs_subjects_dir is not None: fsdir.inputs.subjects_dir = str(fs_subjects_dir.absolute()) reportlets_dir = os.path.join(work_dir, 'reportlets') for subject_id in subject_list: single_subject_wf = init_single_subject_wf( anat_only=anat_only, aroma_melodic_dim=aroma_melodic_dim, bold2t1w_dof=bold2t1w_dof, cifti_output=cifti_output, debug=debug, dummy_scans=dummy_scans, echo_idx=echo_idx, err_on_aroma_warn=err_on_aroma_warn, fmap_bspline=fmap_bspline, fmap_demean=fmap_demean, force_syn=force_syn, freesurfer=freesurfer, hires=hires, ignore=ignore, layout=layout, longitudinal=longitudinal, low_mem=low_mem, medial_surface_nan=medial_surface_nan, name="single_subject_" + subject_id + "_wf", omp_nthreads=omp_nthreads, output_dir=output_dir, regressors_all_comps=regressors_all_comps, regressors_dvars_th=regressors_dvars_th, regressors_fd_th=regressors_fd_th, reportlets_dir=reportlets_dir, skull_strip_fixed_seed=skull_strip_fixed_seed, skull_strip_template=skull_strip_template, spaces=spaces, subject_id=subject_id, t2s_coreg=t2s_coreg, task_id=task_id, use_aroma=use_aroma, use_bbr=use_bbr, use_syn=use_syn, ) single_subject_wf.config['execution']['crashdump_dir'] = ( os.path.join(output_dir, "fmriprep", "sub-" + subject_id, 'log', run_uuid) ) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: fmriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: fmriprep_wf.add_nodes([single_subject_wf]) return fmriprep_wf
def init_dmriprep_wf( anat_only, debug, force_syn, freesurfer, hires, ignore, layout, longitudinal, low_mem, omp_nthreads, output_dir, output_spaces, run_uuid, skull_strip_fixed_seed, skull_strip_template, subject_list, use_syn, work_dir, ): """ Create the base workflow. This workflow organizes the execution of *dMRIPrep*, with a sub-workflow for each subject. If FreeSurfer's recon-all is to be run, a FreeSurfer derivatives folder is created and populated with any needed template subjects. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes import os from collections import namedtuple, OrderedDict BIDSLayout = namedtuple('BIDSLayout', ['root']) from dmriprep.workflows.base import init_dmriprep_wf os.environ['FREESURFER_HOME'] = os.getcwd() wf = init_dmriprep_wf( anat_only=False, debug=False, force_syn=True, freesurfer=True, hires=True, ignore=[], layout=BIDSLayout('.'), longitudinal=False, low_mem=False, omp_nthreads=1, output_dir='.', output_spaces=OrderedDict([ ('MNI152Lin', {}), ('fsaverage', {'density': '10k'}), ('T1w', {}), ('fsnative', {})]), run_uuid='X', skull_strip_fixed_seed=False, skull_strip_template=('OASIS30ANTs', {}), subject_list=['dmripreptest'], use_syn=True, work_dir='.', ) Parameters ---------- anat_only : bool Disable diffusion MRI workflows debug : bool Enable debugging outputs force_syn : bool **Temporary**: Always run SyN-based SDC freesurfer : bool Enable FreeSurfer surface reconstruction (may increase runtime) hires : bool Enable sub-millimeter preprocessing in FreeSurfer ignore : list Preprocessing steps to skip (may include "slicetiming", "fieldmaps") layout : BIDSLayout object BIDS dataset layout longitudinal : bool Treat multiple sessions as longitudinal (may increase runtime) See sub-workflows for specific differences low_mem : bool Write uncompressed .nii files in some cases to reduce memory usage omp_nthreads : int Maximum number of threads an individual process may use output_dir : str Directory in which to save derivatives output_spaces : OrderedDict Ordered dictionary where keys are TemplateFlow ID strings (e.g., ``MNI152Lin``, ``MNI152NLin6Asym``, ``MNI152NLin2009cAsym``, or ``fsLR``) strings designating nonstandard references (e.g., ``T1w`` or ``anat``, ``sbref``, ``run``, etc.), or paths pointing to custom templates organized in a TemplateFlow-like structure. Values of the dictionary aggregate modifiers (e.g., the value for the key ``MNI152Lin`` could be ``{'resolution': 2}`` if one wants the resampling to be done on the 2mm resolution version of the selected template). run_uuid : str Unique identifier for execution instance skull_strip_template : tuple Name of target template for brain extraction with ANTs' ``antsBrainExtraction``, and corresponding dictionary of output-space modifiers. skull_strip_fixed_seed : bool Do not use a random seed for skull-stripping - will ensure run-to-run replicability when used with --omp-nthreads 1 subject_list : list List of subject labels use_syn : bool **Experimental**: Enable ANTs SyN-based susceptibility distortion correction (SDC). If fieldmaps are present and enabled, this is not run, by default. work_dir : str Directory in which to store workflow execution state and temporary files """ dmriprep_wf = Workflow(name='dmriprep_wf') dmriprep_wf.base_dir = work_dir if freesurfer: fsdir = pe.Node(BIDSFreeSurferDir( derivatives=output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=[ s for s in output_spaces.keys() if s.startswith('fsaverage') ] + ['fsnative'] * ('fsnative' in output_spaces)), name='fsdir_run_' + run_uuid.replace('-', '_'), run_without_submitting=True) reportlets_dir = os.path.join(work_dir, 'reportlets') for subject_id in subject_list: single_subject_wf = init_single_subject_wf( anat_only=anat_only, debug=debug, force_syn=force_syn, freesurfer=freesurfer, hires=hires, ignore=ignore, layout=layout, longitudinal=longitudinal, low_mem=low_mem, name="single_subject_" + subject_id + "_wf", omp_nthreads=omp_nthreads, output_dir=output_dir, output_spaces=output_spaces, reportlets_dir=reportlets_dir, skull_strip_fixed_seed=skull_strip_fixed_seed, skull_strip_template=skull_strip_template, subject_id=subject_id, use_syn=use_syn, ) single_subject_wf.config['execution']['crashdump_dir'] = (os.path.join( output_dir, "dmriprep", "sub-" + subject_id, 'log', run_uuid)) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: dmriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: dmriprep_wf.add_nodes([single_subject_wf]) return dmriprep_wf
def init_smriprep_wf( debug, freesurfer, hires, layout, longitudinal, low_mem, omp_nthreads, output_dir, output_spaces, run_uuid, skull_strip_fixed_seed, skull_strip_template, subject_list, work_dir, ): """ Create the execution graph of *sMRIPrep*, with a sub-workflow for each subject. If FreeSurfer's recon-all is to be run, a FreeSurfer derivatives folder is created and populated with any needed template subjects. .. workflow:: :graph2use: orig :simple_form: yes import os from collections import OrderedDict, namedtuple BIDSLayout = namedtuple('BIDSLayout', ['root']) os.environ['FREESURFER_HOME'] = os.getcwd() from smriprep.workflows.base import init_smriprep_wf wf = init_smriprep_wf( debug=False, freesurfer=True, hires=True, layout=BIDSLayout('.'), longitudinal=False, low_mem=False, omp_nthreads=1, output_dir='.', output_spaces=OrderedDict([('MNI152NLin2009cAsym', {}), ('fsaverage5', {})]), run_uuid='testrun', skull_strip_fixed_seed=False, skull_strip_template=('OASIS30ANTs', {}), subject_list=['smripreptest'], work_dir='.', ) **Parameters** debug : bool Enable debugging outputs freesurfer : bool Enable FreeSurfer surface reconstruction (may increase runtime) hires : bool Enable sub-millimeter preprocessing in FreeSurfer layout : BIDSLayout object BIDS dataset layout longitudinal : bool Treat multiple sessions as longitudinal (may increase runtime) See sub-workflows for specific differences low_mem : bool Write uncompressed .nii files in some cases to reduce memory usage omp_nthreads : int Maximum number of threads an individual process may use output_dir : str Directory in which to save derivatives output_spaces : OrderedDict List of spatial normalization targets. Some parts of pipeline will only be instantiated for some output spaces. Valid spaces: - Any template identifier from TemplateFlow - Path to a template folder organized following TemplateFlow's conventions run_uuid : str Unique identifier for execution instance skull_strip_fixed_seed : bool Do not use a random seed for skull-stripping - will ensure run-to-run replicability when used with --omp-nthreads 1 skull_strip_template : tuple Name of ANTs skull-stripping template ('OASIS30ANTs' or 'NKI'), and dictionary with template specifications (e.g., {'res': '2'}) subject_list : list List of subject labels work_dir : str Directory in which to store workflow execution state and temporary files """ smriprep_wf = Workflow(name='smriprep_wf') smriprep_wf.base_dir = work_dir if freesurfer: fsdir = pe.Node(BIDSFreeSurferDir( derivatives=output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=[ s for s in output_spaces.keys() if s.startswith('fsaverage') ] + ['fsnative'] * ('fsnative' in output_spaces)), name='fsdir_run_%s' % run_uuid.replace('-', '_'), run_without_submitting=True) reportlets_dir = os.path.join(work_dir, 'reportlets') for subject_id in subject_list: single_subject_wf = init_single_subject_wf( debug=debug, freesurfer=freesurfer, hires=hires, layout=layout, longitudinal=longitudinal, low_mem=low_mem, name="single_subject_%s_wf" % subject_id, omp_nthreads=omp_nthreads, output_dir=output_dir, output_spaces=output_spaces, reportlets_dir=reportlets_dir, skull_strip_fixed_seed=skull_strip_fixed_seed, skull_strip_template=skull_strip_template, subject_id=subject_id, ) single_subject_wf.config['execution']['crashdump_dir'] = (os.path.join( output_dir, "smriprep", "sub-" + subject_id, 'log', run_uuid)) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: smriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: smriprep_wf.add_nodes([single_subject_wf]) return smriprep_wf
def init_fmriprep_wf(subject_list, task_id, echo_idx, run_uuid, work_dir, output_dir, bids_dir, ignore, debug, low_mem, anat_only, longitudinal, t2s_coreg, omp_nthreads, skull_strip_template, skull_strip_fixed_seed, freesurfer, output_spaces, template, medial_surface_nan, cifti_output, hires, use_bbr, bold2t1w_dof, fmap_bspline, fmap_demean, use_syn, force_syn, use_aroma, ignore_aroma_err, aroma_melodic_dim, template_out_grid): """ This workflow organizes the execution of FMRIPREP, with a sub-workflow for each subject. If FreeSurfer's recon-all is to be run, a FreeSurfer derivatives folder is created and populated with any needed template subjects. .. workflow:: :graph2use: orig :simple_form: yes import os os.environ['FREESURFER_HOME'] = os.getcwd() from fmriprep.workflows.base import init_fmriprep_wf wf = init_fmriprep_wf(subject_list=['fmripreptest'], task_id='', echo_idx=None, run_uuid='X', work_dir='.', output_dir='.', bids_dir='.', ignore=[], debug=False, low_mem=False, anat_only=False, longitudinal=False, t2s_coreg=False, omp_nthreads=1, skull_strip_template='OASIS', skull_strip_fixed_seed=False, freesurfer=True, output_spaces=['T1w', 'fsnative', 'template', 'fsaverage5'], template='MNI152NLin2009cAsym', medial_surface_nan=False, cifti_output=False, hires=True, use_bbr=True, bold2t1w_dof=9, fmap_bspline=False, fmap_demean=True, use_syn=True, force_syn=True, use_aroma=False, ignore_aroma_err=False, aroma_melodic_dim=-200, template_out_grid='native') Parameters subject_list : list List of subject labels task_id : str or None Task ID of BOLD series to preprocess, or ``None`` to preprocess all echo_idx : int or None Index of echo to preprocess in multiecho BOLD series, or ``None`` to preprocess all run_uuid : str Unique identifier for execution instance work_dir : str Directory in which to store workflow execution state and temporary files output_dir : str Directory in which to save derivatives bids_dir : str Root directory of BIDS dataset ignore : list Preprocessing steps to skip (may include "slicetiming", "fieldmaps") debug : bool Enable debugging outputs low_mem : bool Write uncompressed .nii files in some cases to reduce memory usage anat_only : bool Disable functional workflows longitudinal : bool Treat multiple sessions as longitudinal (may increase runtime) See sub-workflows for specific differences t2s_coreg : bool For multi-echo EPI, use the calculated T2*-map for T2*-driven coregistration omp_nthreads : int Maximum number of threads an individual process may use skull_strip_template : str Name of ANTs skull-stripping template ('OASIS' or 'NKI') skull_strip_fixed_seed : bool Do not use a random seed for skull-stripping - will ensure run-to-run replicability when used with --omp-nthreads 1 freesurfer : bool Enable FreeSurfer surface reconstruction (may increase runtime) output_spaces : list List of output spaces functional images are to be resampled to. Some parts of pipeline will only be instantiated for some output spaces. Valid spaces: - T1w - template - fsnative - fsaverage (or other pre-existing FreeSurfer templates) template : str Name of template targeted by ``template`` output space medial_surface_nan : bool Replace medial wall values with NaNs on functional GIFTI files cifti_output : bool Generate bold CIFTI file in output spaces hires : bool Enable sub-millimeter preprocessing in FreeSurfer use_bbr : bool or None Enable/disable boundary-based registration refinement. If ``None``, test BBR result for distortion before accepting. bold2t1w_dof : 6, 9 or 12 Degrees-of-freedom for BOLD-T1w registration fmap_bspline : bool **Experimental**: Fit B-Spline field using least-squares fmap_demean : bool Demean voxel-shift map during unwarp use_syn : bool **Experimental**: Enable ANTs SyN-based susceptibility distortion correction (SDC). If fieldmaps are present and enabled, this is not run, by default. force_syn : bool **Temporary**: Always run SyN-based SDC use_aroma : bool Perform ICA-AROMA on MNI-resampled functional series ignore_aroma_err : bool Do not fail on ICA-AROMA errors template_out_grid : str Keyword ('native', '1mm' or '2mm') or path of custom reference image for normalization """ fmriprep_wf = Workflow(name='fmriprep_wf') fmriprep_wf.base_dir = work_dir if freesurfer: fsdir = pe.Node( BIDSFreeSurferDir( derivatives=output_dir, freesurfer_home=os.getenv('FREESURFER_HOME'), spaces=output_spaces), name='fsdir_run_' + run_uuid.replace('-', '_'), run_without_submitting=True) reportlets_dir = os.path.join(work_dir, 'reportlets') for subject_id in subject_list: single_subject_wf = init_single_subject_wf( subject_id=subject_id, task_id=task_id, echo_idx=echo_idx, name="single_subject_" + subject_id + "_wf", reportlets_dir=reportlets_dir, output_dir=output_dir, bids_dir=bids_dir, ignore=ignore, debug=debug, low_mem=low_mem, anat_only=anat_only, longitudinal=longitudinal, t2s_coreg=t2s_coreg, omp_nthreads=omp_nthreads, skull_strip_template=skull_strip_template, skull_strip_fixed_seed=skull_strip_fixed_seed, freesurfer=freesurfer, output_spaces=output_spaces, template=template, medial_surface_nan=medial_surface_nan, cifti_output=cifti_output, hires=hires, use_bbr=use_bbr, bold2t1w_dof=bold2t1w_dof, fmap_bspline=fmap_bspline, fmap_demean=fmap_demean, use_syn=use_syn, force_syn=force_syn, template_out_grid=template_out_grid, use_aroma=use_aroma, aroma_melodic_dim=aroma_melodic_dim, ignore_aroma_err=ignore_aroma_err, ) single_subject_wf.config['execution']['crashdump_dir'] = ( os.path.join(output_dir, "fmriprep", "sub-" + subject_id, 'log', run_uuid) ) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: fmriprep_wf.connect(fsdir, 'subjects_dir', single_subject_wf, 'inputnode.subjects_dir') else: fmriprep_wf.add_nodes([single_subject_wf]) return fmriprep_wf
def init_nibabies_wf(): """ Build *NiBabies*'s pipeline. This workflow organizes the execution of NiBabies, with a sub-workflow for each subject. If FreeSurfer's ``infant_recon_all`` is to be run, a corresponding folder is created and populated with any needed template subjects under the derivatives folder. Workflow Graph .. workflow:: :graph2use: orig :simple_form: yes from nibabies.workflows.tests import mock_config from nibabies.workflows.base import init_nibabies_wf with mock_config(): wf = init_nibabies_wf() """ from niworkflows.engine.workflows import LiterateWorkflow as Workflow from niworkflows.interfaces.bids import BIDSFreeSurferDir nibabies_wf = Workflow(name="nibabies_wf") nibabies_wf.base_dir = config.execution.work_dir freesurfer = config.workflow.run_reconall if freesurfer: fsdir = pe.Node( BIDSFreeSurferDir( derivatives=config.execution.output_dir, freesurfer_home=os.getenv("FREESURFER_HOME"), spaces=config.workflow.spaces.get_fs_spaces(), ), name=f"fsdir_run_{config.execution.run_uuid.replace('-', '_')}", run_without_submitting=True, ) if config.execution.fs_subjects_dir is not None: fsdir.inputs.subjects_dir = str( config.execution.fs_subjects_dir.absolute()) for subject_id in config.execution.participant_label: single_subject_wf = init_single_subject_wf(subject_id) single_subject_wf.config["execution"]["crashdump_dir"] = str( config.execution.fmriprep_dir / f"sub-{subject_id}" / "log" / config.execution.run_uuid) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) if freesurfer: nibabies_wf.connect(fsdir, "subjects_dir", single_subject_wf, "inputnode.subjects_dir") else: nibabies_wf.add_nodes([single_subject_wf]) # Dump a copy of the config file into the log directory log_dir = (config.execution.fmriprep_dir / f"sub-{subject_id}" / "log" / config.execution.run_uuid) log_dir.mkdir(exist_ok=True, parents=True) config.to_filename(log_dir / "nibabies.toml") return nibabies_wf
def init_nibetaseries_participant_wf( estimator, atlas_img, atlas_lut, bids_dir, database_path, derivatives_pipeline_dir, exclude_description_label, fir_delays, hrf_model, high_pass, norm_betas, output_dir, return_residuals, run_label, selected_confounds, session_label, signal_scaling, smoothing_kernel, space_label, subject_list, task_label, description_label, work_dir, ): """ This workflow organizes the execution of NiBetaSeries, with a sub-workflow for each subject. Parameters ---------- atlas_img : str Path to input atlas nifti atlas_lut : str Path to input atlas lookup table (tsv) bids_dir : str Root directory of BIDS dataset database_path : str Path to a BIDS database derivatives_pipeline_dir : str Root directory of the derivatives pipeline exclude_description_label : str or None Exclude bold series containing this description label fir_delays : list or None FIR delays (in scans) hrf_model : str The model that represents the shape of the hemodynamic response function high_pass : float High pass filter to apply to bold (in Hertz). Reminder - frequencies _higher_ than this number are kept. norm_betas : Bool If True, beta estimates are divided by the square root of their variance output_dir : str Directory where derivatives are saved return_residuals : bool Output the residuals from the betaseries model into the derivatives directory run_label : str or None Include bold series containing this run label selected_confounds : list List of confounds to be included in regression signal_scaling : False or 0 Whether (0) or not (False) to scale each voxel's timeseries session_label : str or None Include bold series containing this session label smoothing_kernel : float or None The smoothing kernel to be applied to the bold series before beta estimation space_label : str or None Include bold series containing this space label subject_list : list List of subject labels task_label : str or None Include bold series containing this task label description_label : str or None Include bold series containing this description label work_dir : str Directory in which to store workflow execution state and temporary files """ # setup workflow nibetaseries_participant_wf = Workflow(name='nibetaseries_participant_wf') nibetaseries_participant_wf.base_dir = os.path.join( work_dir, 'NiBetaSeries_work') os.makedirs(nibetaseries_participant_wf.base_dir, exist_ok=True) nibetaseries_participant_wf.__desc__ = """ Results included in this manuscript come from modeling performed using *NiBetaSeries* {nibs_ver} [@Kent2018], which is based on *Nipype* {nipype_ver} [@Gorgolewski2011; @Gorgolewski2018]. """.format(nibs_ver=get_versions()['version'], nipype_ver=nipype_ver) nibetaseries_participant_wf.__postdesc__ = """ ### Software Dependencies Additional libraries used in the NiBetaSeries workflow include *Pybids* {pybids_ver} [@Yarkoni2019], *Niworkflows* {niworkflows_ver}, *Nibabel* {nibabel_ver}, *Pandas* {pandas_ver} [@McKinney2010], and *Numpy* {numpy_ver} [@VanDerWalt2011; @Oliphant2006]. ### Copyright Waiver The above boilerplate text was automatically generated by NiBetaSeries with the express intention that users should copy and paste this text into their manuscripts *unchanged*. It is released under the [CC0]\ (https://creativecommons.org/publicdomain/zero/1.0/) license. ### References """.format(pybids_ver=pybids_ver, niworkflows_ver=niworkflows_ver, nibabel_ver=nibabel_ver, pandas_ver=pandas_ver, numpy_ver=numpy_ver) # Go ahead and initialize the layout database if database_path is None: database_path = os.path.join(work_dir, 'dbcache') reset_database = True else: reset_database = False # reading in derivatives and bids inputs as queryable database like objects layout = BIDSLayout(bids_dir, derivatives=derivatives_pipeline_dir, index_metadata=False, database_file=database_path, reset_database=reset_database) # only index bold file metadata if reset_database: indexer = BIDSLayoutIndexerPatch(layout) metadata_filter = { 'extension': ['nii', 'nii.gz', 'json'], 'suffix': 'bold', } indexer.index_metadata(**metadata_filter) for subject_label in subject_list: # collect the necessary inputs for both collect data subject_data = collect_data(layout, subject_label, task=task_label, run=run_label, ses=session_label, space=space_label, description=description_label) # collect files to be associated with each preproc brainmask_list = [d['brainmask'] for d in subject_data] confound_tsv_list = [d['confounds'] for d in subject_data] events_tsv_list = [d['events'] for d in subject_data] preproc_img_list = [d['preproc'] for d in subject_data] bold_metadata_list = [d['metadata'] for d in subject_data] single_subject_wf = init_single_subject_wf( estimator=estimator, atlas_img=atlas_img, atlas_lut=atlas_lut, bold_metadata_list=bold_metadata_list, brainmask_list=brainmask_list, confound_tsv_list=confound_tsv_list, events_tsv_list=events_tsv_list, fir_delays=fir_delays, hrf_model=hrf_model, high_pass=high_pass, name='single_subject' + subject_label + '_wf', norm_betas=norm_betas, output_dir=output_dir, preproc_img_list=preproc_img_list, return_residuals=return_residuals, selected_confounds=selected_confounds, signal_scaling=signal_scaling, smoothing_kernel=smoothing_kernel, ) single_subject_wf.config['execution']['crashdump_dir'] = (os.path.join( output_dir, "sub-" + subject_label, 'log')) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) nibetaseries_participant_wf.add_nodes([single_subject_wf]) return nibetaseries_participant_wf
def init_fmap_estimation_wf( epi_targets, debug=False, generate_report=True, name="fmap_estimation_wf", ): """ Setup a fieldmap estimation strategy and write results to derivatives folder. Parameters ---------- participant_label : :obj:`str` The particular subject for which the BIDS layout will be queried. epi_targets : :obj:`list` of :obj:`os.pathlike` A list of :abbr:`EPI (echo planar imaging)` scans that will be corrected for susceptibility distortions with the estimated fieldmaps. omp_nthreads : :obj:`int` Number of CPUs available to individual processes for multithreaded execution. debug : :obj:`bool` Whether fast (and less accurate) execution parameters should be used whenever available. name : :obj:`str` A unique workflow name to build Nipype's workflow hierarchy. """ layout = config.execution.layout wf = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=["dwi_reference", "dwi_mask"]), name="inputnode") wf.add_nodes([inputnode]) # TODO: remove when fully implemented # Create one outputnode with a port for each potential EPI target # outputnode = pe.Node(niu.IdentityInterface(fields=[_fname2outname(p) for p in epi_targets]), # name="outputnode") # Return identity transforms for all if fieldmaps are ignored if "fieldmaps" in config.workflow.ignore: return wf # Set-up PEPOLAR estimators only with EPIs under fmap/ # fmap_epi = {f: layout.get_metadata(f) # for f in layout.get( # subject=participant_label, datatype="fmap", # suffix="epi", extension=("nii", "nii.gz"))} metadata = [layout.get_metadata(p) for p in epi_targets] if any("TotalReadoutTime" not in m for m in metadata): return wf pedirs = [m.get("PhaseEncodingDirection", "unknown") for m in metadata] if len(set(pedirs) - set(("unknown",))) > 1: if "unknown" in pedirs or len(set(pe[0] for pe in set(pedirs))) > 1: raise NotImplementedError # Get EPI polarities and their metadata sdc_estimate_wf = init_pepolar_estimate_wf(debug=debug) sdc_estimate_wf.inputs.inputnode.metadata = metadata wf.connect([ (inputnode, sdc_estimate_wf, [("dwi_reference", "inputnode.in_data")]), ]) if generate_report: from sdcflows.interfaces.reportlets import FieldmapReportlet pepolar_report = pe.Node(FieldmapReportlet(reference_label="SDC'd B0"), name="pepolar_report") ds_report_pepolar = pe.Node(DerivativesDataSink( base_directory=str(config.execution.output_dir), datatype="figures", suffix="fieldmap", desc="pepolar", dismiss_entities=("acquisition", "dir")), name="ds_report_pepolar") ds_report_pepolar.inputs.source_file = epi_targets[0] wf.connect([ (sdc_estimate_wf, pepolar_report, [ ("outputnode.fieldmap", "fieldmap"), ("outputnode.corrected", "reference"), ("outputnode.corrected_mask", "mask")]), (pepolar_report, ds_report_pepolar, [("out_report", "in_file")]), ]) return wf
def init_funcworks_subject_wf( model, bids_dir, output_dir, work_dir, database_path, subject_id, analysis_level, smoothing_fwhm, smoothing_level, smoothing_type, use_rapidart, detrend_poly, align_volumes, smooth_autocorrelations, despike, name, ): """Produce single subject workflow for a subject given a model spec.""" workflow = Workflow(name=name) stage = None pre_level = None for step in model["Steps"]: level = step["Level"] if level == "run": model = fsl_run_level_wf( model=model, step=step, bids_dir=bids_dir, output_dir=output_dir, work_dir=work_dir, database_path=database_path, subject_id=subject_id, smoothing_fwhm=smoothing_fwhm, smoothing_level=smoothing_level, smoothing_type=smoothing_type, use_rapidart=use_rapidart, detrend_poly=detrend_poly, align_volumes=align_volumes, smooth_autocorrelations=smooth_autocorrelations, despike=despike, name=f"fsl_{level}_level_wf", ) workflow.add_nodes([model]) else: model = fsl_higher_level_wf( step=step, output_dir=output_dir, work_dir=work_dir, database_path=database_path, # smoothing_fwhm=smoothing_fwhm, smoothing_level=smoothing_level, # smoothing_type=smoothing_type, align_volumes=align_volumes, name=f"fsl_{level}_level_wf", ) workflow.connect([( stage, model, [ ( f"wrangle_{pre_level}_outputs.contrast_maps", f"wrangle_{level}_inputs.contrast_maps", ), ( f"wrangle_{pre_level}_outputs.contrast_metadata", f"wrangle_{level}_inputs.contrast_metadata", ), ], )]) stage = model pre_level = level if level == analysis_level: break return workflow
def init_funcworks_wf( model_file, bids_dir, output_dir, work_dir, database_path, participants, analysis_level, smoothing, runtime_uuid, use_rapidart, detrend_poly, align_volumes, smooth_autocorrelations, despike, ): """Initialize funcworks single subject workflow for all subjects.""" with open(model_file, "r") as read_mdl: model = json.load(read_mdl) funcworks_wf = Workflow(name="funcworks_wf") (work_dir / model["Name"]).mkdir(exist_ok=True, parents=True) funcworks_wf.base_dir = work_dir / model["Name"] if smoothing: smoothing_params = smoothing.split(":") if len(smoothing_params) == 1: smoothing_params.extend(("l1", "iso")) elif len(smoothing_params) == 2: smoothing_params.append("iso") smoothing_fwhm, smoothing_level, smoothing_type = smoothing_params smoothing_fwhm = int(smoothing_fwhm) if smoothing_level.lower().startswith("l"): if int(smoothing_level[1:]) > len(model["Steps"]): raise ValueError(f"Invalid smoothing level {smoothing_level}") else: smoothing_fwhm = None smoothing_level = None smoothing_type = None for subject_id in participants: single_subject_wf = init_funcworks_subject_wf( model=model, bids_dir=bids_dir, output_dir=(output_dir / "funcworks" / model["Name"]), work_dir=work_dir, database_path=database_path, subject_id=subject_id, analysis_level=analysis_level, smoothing_fwhm=smoothing_fwhm, smoothing_level=smoothing_level, smoothing_type=smoothing_type, use_rapidart=use_rapidart, detrend_poly=detrend_poly, align_volumes=align_volumes, smooth_autocorrelations=smooth_autocorrelations, despike=despike, name=f"single_subject_{subject_id}_wf", ) crash_dir = (Path(output_dir) / "funcworks" / model["Name"] / f"sub-{subject_id}" / "log" / runtime_uuid) crash_dir.mkdir(exist_ok=True, parents=True) single_subject_wf.config["execution"]["crashdump_dir"] = str(crash_dir) for node in single_subject_wf._get_all_nodes(): node.config = deepcopy(single_subject_wf.config) funcworks_wf.add_nodes([single_subject_wf]) return funcworks_wf