def init_enhance_and_skullstrip_bold_wf( name='enhance_and_skullstrip_bold_wf', pre_mask=False, omp_nthreads=1): """ This workflow takes in a :abbr:`BOLD (blood-oxygen level-dependant)` :abbr:`fMRI (functional MRI)` average/summary (e.g. a reference image averaging non-steady-state timepoints), and sharpens the histogram with the application of the N4 algorithm for removing the :abbr:`INU (intensity non-uniformity)` bias field and calculates a signal mask. Steps of this workflow are: 1. Calculate a tentative mask by registering (9-parameters) to *fMRIPrep*'s :abbr:`EPI (echo-planar imaging)` -*boldref* template, which is in MNI space. The tentative mask is obtained by resampling the MNI template's brainmask into *boldref*-space. 2. Binary dilation of the tentative mask with a sphere of 3mm diameter. 3. Run ANTs' ``N4BiasFieldCorrection`` on the input :abbr:`BOLD (blood-oxygen level-dependant)` average, using the mask generated in 1) instead of the internal Otsu thresholding. 4. Calculate a loose mask using FSL's ``bet``, with one mathematical morphology dilation of one iteration and a sphere of 6mm as structuring element. 5. Mask the :abbr:`INU (intensity non-uniformity)`-corrected image with the latest mask calculated in 3), then use AFNI's ``3dUnifize`` to *standardize* the T2* contrast distribution. 6. Calculate a mask using AFNI's ``3dAutomask`` after the contrast enhancement of 4). 7. Calculate a final mask as the intersection of 4) and 6). 8. Apply final mask on the enhanced reference. Step 1 can be skipped if the ``pre_mask`` argument is set to ``True`` and a tentative mask is passed in to the workflow throught the ``pre_mask`` Nipype input. .. workflow :: :graph2use: orig :simple_form: yes from fmriprep.workflows.bold.util import init_enhance_and_skullstrip_bold_wf wf = init_enhance_and_skullstrip_bold_wf(omp_nthreads=1) **Parameters** name : str Name of workflow (default: ``enhance_and_skullstrip_bold_wf``) pre_mask : bool Indicates whether the ``pre_mask`` input will be set (and thus, step 1 should be skipped). omp_nthreads : int number of threads available to parallel nodes **Inputs** in_file BOLD image (single volume) pre_mask : bool A tentative brain mask to initialize the workflow (requires ``pre_mask`` parameter set ``True``). **Outputs** bias_corrected_file the ``in_file`` after `N4BiasFieldCorrection`_ skull_stripped_file the ``bias_corrected_file`` after skull-stripping mask_file mask of the skull-stripped input file out_report reportlet for the skull-stripping .. _N4BiasFieldCorrection: https://hdl.handle.net/10380/3053 """ workflow = Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'pre_mask']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=[ 'mask_file', 'skull_stripped_file', 'bias_corrected_file']), name='outputnode') # Dilate pre_mask pre_dilate = pe.Node(fsl.DilateImage( operation='max', kernel_shape='sphere', kernel_size=3.0, internal_datatype='char'), name='pre_mask_dilate') # Ensure mask's header matches reference's check_hdr = pe.Node(MatchHeader(), name='check_hdr', run_without_submitting=True) # Run N4 normally, force num_threads=1 for stability (images are small, no need for >1) n4_correct = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True), name='n4_correct', n_procs=1) # Create a generous BET mask out of the bias-corrected EPI skullstrip_first_pass = pe.Node(fsl.BET(frac=0.2, mask=True), name='skullstrip_first_pass') bet_dilate = pe.Node(fsl.DilateImage( operation='max', kernel_shape='sphere', kernel_size=6.0, internal_datatype='char'), name='skullstrip_first_dilate') bet_mask = pe.Node(fsl.ApplyMask(), name='skullstrip_first_mask') # Use AFNI's unifize for T2 constrast & fix header unifize = pe.Node(afni.Unifize( t2=True, outputtype='NIFTI_GZ', # Default -clfrac is 0.1, 0.4 was too conservative # -rbt because I'm a Jedi AFNI Master (see 3dUnifize's documentation) args='-clfrac 0.2 -rbt 18.3 65.0 90.0', out_file="uni.nii.gz"), name='unifize') fixhdr_unifize = pe.Node(CopyXForm(), name='fixhdr_unifize', mem_gb=0.1) # Run ANFI's 3dAutomask to extract a refined brain mask skullstrip_second_pass = pe.Node(afni.Automask(dilate=1, outputtype='NIFTI_GZ'), name='skullstrip_second_pass') fixhdr_skullstrip2 = pe.Node(CopyXForm(), name='fixhdr_skullstrip2', mem_gb=0.1) # Take intersection of both masks combine_masks = pe.Node(fsl.BinaryMaths(operation='mul'), name='combine_masks') # Compute masked brain apply_mask = pe.Node(fsl.ApplyMask(), name='apply_mask') if not pre_mask: bold_template = get_template('MNI152NLin2009cAsym', 'res-02_desc-fMRIPrep_boldref.nii.gz') brain_mask = get_template('MNI152NLin2009cAsym', 'res-02_desc-brain_mask.nii.gz') # Initialize transforms with antsAI init_aff = pe.Node(AI( fixed_image=str(bold_template), fixed_image_mask=str(brain_mask), metric=('Mattes', 32, 'Regular', 0.2), transform=('Affine', 0.1), search_factor=(20, 0.12), principal_axes=False, convergence=(10, 1e-6, 10), verbose=True), name='init_aff', n_procs=omp_nthreads) # Registration().version may be None if parseversion(Registration().version or '0.0.0') > Version('2.2.0'): init_aff.inputs.search_grid = (40, (0, 40, 40)) # Set up spatial normalization norm = pe.Node(Registration( from_file=pkgr_fn( 'fmriprep.data', 'epi_atlasbased_brainmask.json')), name='norm', n_procs=omp_nthreads) norm.inputs.fixed_image = str(bold_template) map_brainmask = pe.Node( ApplyTransforms(interpolation='MultiLabel', float=True, input_image=str(brain_mask)), name='map_brainmask' ) workflow.connect([ (inputnode, init_aff, [('in_file', 'moving_image')]), (inputnode, map_brainmask, [('in_file', 'reference_image')]), (inputnode, norm, [('in_file', 'moving_image')]), (init_aff, norm, [('output_transform', 'initial_moving_transform')]), (norm, map_brainmask, [ ('reverse_invert_flags', 'invert_transform_flags'), ('reverse_transforms', 'transforms')]), (map_brainmask, pre_dilate, [('output_image', 'in_file')]), ]) else: workflow.connect([ (inputnode, pre_dilate, [('pre_mask', 'in_file')]), ]) workflow.connect([ (inputnode, check_hdr, [('in_file', 'reference')]), (pre_dilate, check_hdr, [('out_file', 'in_file')]), (check_hdr, n4_correct, [('out_file', 'mask_image')]), (inputnode, n4_correct, [('in_file', 'input_image')]), (inputnode, fixhdr_unifize, [('in_file', 'hdr_file')]), (inputnode, fixhdr_skullstrip2, [('in_file', 'hdr_file')]), (n4_correct, skullstrip_first_pass, [('output_image', 'in_file')]), (skullstrip_first_pass, bet_dilate, [('mask_file', 'in_file')]), (bet_dilate, bet_mask, [('out_file', 'mask_file')]), (skullstrip_first_pass, bet_mask, [('out_file', 'in_file')]), (bet_mask, unifize, [('out_file', 'in_file')]), (unifize, fixhdr_unifize, [('out_file', 'in_file')]), (fixhdr_unifize, skullstrip_second_pass, [('out_file', 'in_file')]), (skullstrip_first_pass, combine_masks, [('mask_file', 'in_file')]), (skullstrip_second_pass, fixhdr_skullstrip2, [('out_file', 'in_file')]), (fixhdr_skullstrip2, combine_masks, [('out_file', 'operand_file')]), (fixhdr_unifize, apply_mask, [('out_file', 'in_file')]), (combine_masks, apply_mask, [('out_file', 'mask_file')]), (combine_masks, outputnode, [('out_file', 'mask_file')]), (apply_mask, outputnode, [('out_file', 'skull_stripped_file')]), (n4_correct, outputnode, [('output_image', 'bias_corrected_file')]), ]) return workflow
def init_templateflow_wf( bids_dir, output_dir, participant_label, mov_template, ref_template='MNI152NLin2009cAsym', use_float=True, omp_nthreads=None, mem_gb=3.0, modality='T1w', normalization_quality='precise', name='templateflow_wf', fs_subjects_dir=None, ): """ A Nipype workflow to perform image registration between two templates *R* and *M*. *R* is the *reference template*, selected by a templateflow identifier such as ``MNI152NLin2009cAsym``, and *M* is the *moving template* (e.g., ``MNI152Lin``). This workflows maps data defined on template-*M* space onto template-*R* space. 1. Run the subrogate images through ``antsBrainExtraction``. 2. Recompute :abbr:`INU (intensity non-uniformity)` correction using the mask obtained in 1). 3. Independently, run spatial normalization of every :abbr:`INU (intensity non-uniformity)` corrected image (supplied via ``in_files``) to both templates. 4. Calculate an initialization between both templates, using them directly. 5. Run multi-channel image registration of the images resulting from 3). Both sets of images (one registered to *R* and another to *M*) are then used as reference and moving images in the registration framework. **Parameters** in_files: list of files a list of paths pointing to the images that will be used as surrogates mov_template: str a templateflow identifier for template-*M* ref_template: str a templateflow identifier for template-*R* (default: ``MNI152NLin2009cAsym``). """ # number of participants ninputs = len(participant_label) ants_env = { 'NSLOTS': '%d' % omp_nthreads, 'ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS': '%d' % omp_nthreads, 'OMP_NUM_THREADS': '%d' % omp_nthreads, } # Get path to templates tpl_ref = str( get_template(ref_template, suffix=modality, desc=None, resolution=1)) tpl_ref_mask = str( get_template(ref_template, suffix='mask', desc='brain', resolution=1)) tpl_mov = str( get_template(mov_template, suffix=modality, desc=None, resolution=1)) tpl_mov_mask = str( get_template(mov_template, suffix='mask', desc='brain', resolution=1)) wf = pe.Workflow(name) inputnode = pe.Node(niu.IdentityInterface(fields=['participant_label']), name='inputnode') inputnode.iterables = ('participant_label', sorted(list(participant_label))) pick_file = pe.Node(niu.Function(function=_bids_pick), name='pick_file', run_without_submitting=True) pick_file.inputs.bids_root = bids_dir ref_bex = init_brain_extraction_wf( in_template=ref_template, omp_nthreads=omp_nthreads, mem_gb=mem_gb, bids_suffix=modality, name='reference_bex', ) mov_bex = init_brain_extraction_wf( in_template=mov_template, omp_nthreads=omp_nthreads, mem_gb=mem_gb, bids_suffix=modality, name='moving_bex', ) ref_norm = pe.Node(Registration(from_file=pkgr.resource_filename( 'niworkflows.data', 't1w-mni_registration_%s_000.json' % normalization_quality)), name='ref_norm', n_procs=omp_nthreads) ref_norm.inputs.fixed_image = tpl_ref ref_norm.inputs.fixed_image_masks = tpl_ref_mask ref_norm.inputs.environ = ants_env # Register the INU-corrected image to the other template mov_norm = pe.Node(Registration(from_file=pkgr.resource_filename( 'niworkflows.data', 't1w-mni_registration_%s_000.json' % normalization_quality)), name='mov_norm', n_procs=omp_nthreads) mov_norm.inputs.fixed_image = tpl_mov mov_norm.inputs.fixed_image_masks = tpl_mov_mask mov_norm.inputs.environ = ants_env # Initialize between-templates transform with antsAI init_aff = pe.Node(AI( metric=('Mattes', 32, 'Regular', 0.2), transform=('Affine', 0.1), search_factor=(20, 0.12), principal_axes=False, convergence=(10, 1e-6, 10), verbose=True, fixed_image=tpl_ref, fixed_image_mask=tpl_ref_mask, moving_image=tpl_mov, moving_image_mask=tpl_mov_mask, environ=ants_env, ), name='init_aff', n_procs=omp_nthreads) ref_buffer = pe.JoinNode(niu.IdentityInterface(fields=['fixed_image']), joinsource='inputnode', joinfield='fixed_image', name='ref_buffer') mov_buffer = pe.JoinNode(niu.IdentityInterface(fields=['moving_image']), joinsource='inputnode', joinfield='moving_image', name='mov_buffer') flow = pe.Node( Registration(from_file=pkgr.resource_filename( 'niworkflows.data', 't1w-mni_registration_%s_000.json' % normalization_quality)), name='flow_norm', n_procs=omp_nthreads, ) flow.inputs.fixed_image_masks = tpl_ref_mask flow.inputs.moving_image_masks = tpl_mov_mask flow.inputs.metric = [[v] * ninputs for v in flow.inputs.metric] flow.inputs.metric_weight = [[1 / ninputs] * ninputs for _ in flow.inputs.metric_weight] flow.inputs.radius_or_number_of_bins = [ [v] * ninputs for v in flow.inputs.radius_or_number_of_bins ] flow.inputs.sampling_percentage = [[v] * ninputs for v in flow.inputs.sampling_percentage ] flow.inputs.sampling_strategy = [[v] * ninputs for v in flow.inputs.sampling_strategy] flow.inputs.environ = ants_env # Datasinking ref_norm_ds = pe.Node(DerivativesDataSink(base_directory=str( output_dir.parent), out_path_base=output_dir.name, space=ref_template, desc='preproc', keep_dtype=True), name='ref_norm_ds', run_without_submitting=True) mov_norm_ds = pe.Node(DerivativesDataSink(base_directory=str( output_dir.parent), out_path_base=output_dir.name, space=mov_template, desc='preproc', keep_dtype=True), name='mov_norm_ds', run_without_submitting=True) xfm_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, allowed_entities=['from', 'mode'], mode='image', suffix='xfm', source_file='group/tpl-{0}_T1w.nii.gz'.format(ref_template), **{'from': mov_template}), name='xfm_ds', run_without_submitting=True) wf.connect([ (inputnode, pick_file, [('participant_label', 'participant_label')]), (pick_file, ref_bex, [('out', 'inputnode.in_files')]), (pick_file, mov_bex, [('out', 'inputnode.in_files')]), (ref_bex, ref_norm, [('outputnode.bias_corrected', 'moving_image'), ('outputnode.out_mask', 'moving_image_masks'), ('norm.forward_transforms', 'initial_moving_transform')]), (ref_bex, mov_norm, [('outputnode.bias_corrected', 'moving_image')]), (mov_bex, mov_norm, [('outputnode.out_mask', 'moving_image_masks'), ('norm.forward_transforms', 'initial_moving_transform')]), (init_aff, flow, [('output_transform', 'initial_moving_transform')]), (ref_norm, ref_buffer, [('warped_image', 'fixed_image')]), (mov_norm, mov_buffer, [('warped_image', 'moving_image')]), (ref_buffer, flow, [('fixed_image', 'fixed_image')]), (mov_buffer, flow, [('moving_image', 'moving_image')]), (pick_file, ref_norm_ds, [('out', 'source_file')]), (ref_norm, ref_norm_ds, [('warped_image', 'in_file')]), (pick_file, mov_norm_ds, [('out', 'source_file')]), (mov_norm, mov_norm_ds, [('warped_image', 'in_file')]), (flow, xfm_ds, [('composite_transform', 'in_file')]), ]) if fs_subjects_dir: fssource = pe.Node(FreeSurferSource(subjects_dir=str(fs_subjects_dir)), name='fssource', run_without_submitting=True) tonative = pe.Node(fs.Label2Vol(subjects_dir=str(fs_subjects_dir)), name='tonative') tonii = pe.Node(fs.MRIConvert(out_type='niigz', resample_type='nearest'), name='tonii') ref_aparc = pe.Node(ApplyTransforms(interpolation='MultiLabel', float=True, reference_image=tpl_ref, environ=ants_env), name='ref_aparc', mem_gb=1, n_procs=omp_nthreads) mov_aparc = pe.Node(ApplyTransforms(interpolation='MultiLabel', float=True, reference_image=tpl_mov, environ=ants_env), name='mov_aparc', mem_gb=1, n_procs=omp_nthreads) ref_aparc_buffer = pe.JoinNode(niu.IdentityInterface(fields=['aparc']), joinsource='inputnode', joinfield='aparc', name='ref_aparc_buffer') ref_join_labels = pe.Node(AntsJointFusion( target_image=[tpl_ref], out_label_fusion='merged_aparc.nii.gz', out_intensity_fusion_name_format='merged_aparc_intensity_%d.nii.gz', out_label_post_prob_name_format='merged_aparc_posterior_%d.nii.gz', out_atlas_voting_weight_name_format='merged_aparc_weight_%d.nii.gz', environ=ants_env, ), name='ref_join_labels', n_procs=omp_nthreads) ref_join_labels_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, suffix='dtissue', desc='aparc', keep_dtype=False, source_file='group/tpl-{0}_T1w.nii.gz'.format(ref_template)), name='ref_join_labels_ds', run_without_submitting=True) ref_join_probs_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, suffix='probtissue', desc='aparc', keep_dtype=False, source_file='group/tpl-{0}_T1w.nii.gz'.format(ref_template)), name='ref_join_probs_ds', run_without_submitting=True) # ref_join_voting_ds = pe.Node( # DerivativesDataSink( # base_directory=str(output_dir.parent), # out_path_base=output_dir.name, space=ref_template, # suffix='probtissue', desc='aparcvoting', keep_dtype=False, # source_file='group/tpl-{0}_T1w.nii.gz'.format(ref_template)), # name='ref_join_voting_ds', run_without_submitting=True) mov_aparc_buffer = pe.JoinNode(niu.IdentityInterface(fields=['aparc']), joinsource='inputnode', joinfield='aparc', name='mov_aparc_buffer') mov_join_labels = pe.Node(AntsJointFusion( target_image=[tpl_mov], out_label_fusion='merged_aparc.nii.gz', out_intensity_fusion_name_format='merged_aparc_intensity_%d.nii.gz', out_label_post_prob_name_format='merged_aparc_posterior_%d.nii.gz', out_atlas_voting_weight_name_format='merged_aparc_weight_%d.nii.gz', environ=ants_env, ), name='mov_join_labels', n_procs=omp_nthreads) mov_join_labels_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, suffix='dtissue', desc='aparc', keep_dtype=False, source_file='group/tpl-{0}_T1w.nii.gz'.format(mov_template)), name='mov_join_labels_ds', run_without_submitting=True) mov_join_probs_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, suffix='probtissue', desc='aparc', keep_dtype=False, source_file='group/tpl-{0}_T1w.nii.gz'.format(mov_template)), name='mov_join_probs_ds', run_without_submitting=True) ref_aparc_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, space=ref_template, suffix='dtissue', desc='aparc', keep_dtype=False), name='ref_aparc_ds', run_without_submitting=True) mov_aparc_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, space=mov_template, suffix='dtissue', desc='aparc', keep_dtype=False), name='mov_aparc_ds', run_without_submitting=True) # Extract surfaces cifti_wf = init_gifti_surface_wf(name='cifti_surfaces', subjects_dir=str(fs_subjects_dir)) # Move surfaces to template spaces gii2csv = pe.MapNode(GiftiToCSV(itk_lps=True), iterfield=['in_file'], name='gii2csv') ref_map_surf = pe.MapNode(ApplyTransformsToPoints(dimension=3, environ=ants_env), n_procs=omp_nthreads, name='ref_map_surf', iterfield=['input_file']) ref_csv2gii = pe.MapNode(CSVToGifti(itk_lps=True), name='ref_csv2gii', iterfield=['in_file', 'gii_file']) ref_surfs_buffer = pe.JoinNode( niu.IdentityInterface(fields=['surfaces']), joinsource='inputnode', joinfield='surfaces', name='ref_surfs_buffer') ref_surfs_unzip = pe.Node(UnzipJoinedSurfaces(), name='ref_surfs_unzip', run_without_submitting=True) ref_ply = pe.MapNode(SurfacesToPointCloud(), name='ref_ply', iterfield=['in_files']) ref_recon = pe.MapNode(PoissonRecon(), name='ref_recon', iterfield=['in_file']) ref_avggii = pe.MapNode(PLYtoGifti(), name='ref_avggii', iterfield=['in_file', 'surf_key']) ref_smooth = pe.MapNode(fs.SmoothTessellation(), name='ref_smooth', iterfield=['in_file']) ref_surfs_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, space=ref_template, keep_dtype=False, compress=False), name='ref_surfs_ds', run_without_submitting=True) ref_avg_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, space=ref_template, keep_dtype=False, compress=False, source_file='group/tpl-{0}_T1w.nii.gz'.format(ref_template)), name='ref_avg_ds', run_without_submitting=True) mov_map_surf = pe.MapNode(ApplyTransformsToPoints(dimension=3, environ=ants_env), n_procs=omp_nthreads, name='mov_map_surf', iterfield=['input_file']) mov_csv2gii = pe.MapNode(CSVToGifti(itk_lps=True), name='mov_csv2gii', iterfield=['in_file', 'gii_file']) mov_surfs_buffer = pe.JoinNode( niu.IdentityInterface(fields=['surfaces']), joinsource='inputnode', joinfield='surfaces', name='mov_surfs_buffer') mov_surfs_unzip = pe.Node(UnzipJoinedSurfaces(), name='mov_surfs_unzip', run_without_submitting=True) mov_ply = pe.MapNode(SurfacesToPointCloud(), name='mov_ply', iterfield=['in_files']) mov_recon = pe.MapNode(PoissonRecon(), name='mov_recon', iterfield=['in_file']) mov_avggii = pe.MapNode(PLYtoGifti(), name='mov_avggii', iterfield=['in_file', 'surf_key']) mov_smooth = pe.MapNode(fs.SmoothTessellation(), name='mov_smooth', iterfield=['in_file']) mov_surfs_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, space=mov_template, keep_dtype=False, compress=False), name='mov_surfs_ds', run_without_submitting=True) mov_avg_ds = pe.Node(DerivativesDataSink( base_directory=str(output_dir.parent), out_path_base=output_dir.name, space=mov_template, keep_dtype=False, compress=False, source_file='group/tpl-{0}_T1w.nii.gz'.format(mov_template)), name='mov_avg_ds', run_without_submitting=True) wf.connect([ (inputnode, fssource, [(('participant_label', _sub_decorate), 'subject_id')]), (inputnode, cifti_wf, [(('participant_label', _sub_decorate), 'inputnode.subject_id')]), (pick_file, cifti_wf, [('out', 'inputnode.in_t1w')]), (pick_file, tonii, [('out', 'reslice_like')]), # Select DKT aparc (fssource, tonative, [(('aparc_aseg', _last), 'seg_file'), ('rawavg', 'template_file'), ('aseg', 'reg_header')]), (tonative, tonii, [('vol_label_file', 'in_file')]), (tonii, ref_aparc, [('out_file', 'input_image')]), (tonii, mov_aparc, [('out_file', 'input_image')]), (ref_norm, ref_aparc, [('composite_transform', 'transforms')]), (mov_norm, mov_aparc, [('composite_transform', 'transforms')]), (ref_buffer, ref_join_labels, [('fixed_image', 'atlas_image')]), (ref_aparc, ref_aparc_buffer, [('output_image', 'aparc')]), (ref_aparc_buffer, ref_join_labels, [('aparc', 'atlas_segmentation_image')]), (mov_buffer, mov_join_labels, [('moving_image', 'atlas_image')]), (mov_aparc, mov_aparc_buffer, [('output_image', 'aparc')]), (mov_aparc_buffer, mov_join_labels, [('aparc', 'atlas_segmentation_image')]), # Datasinks (ref_join_labels, ref_join_labels_ds, [('out_label_fusion', 'in_file')]), (ref_join_labels, ref_join_probs_ds, [('out_label_post_prob', 'in_file'), (('out_label_post_prob', _get_extra), 'extra_values')]), # (ref_join_labels, ref_join_voting_ds, [ # ('out_atlas_voting_weight_name_format', 'in_file')]), (mov_join_labels, mov_join_labels_ds, [('out_label_fusion', 'in_file')]), (mov_join_labels, mov_join_probs_ds, [('out_label_post_prob', 'in_file'), (('out_label_post_prob', _get_extra), 'extra_values')]), (pick_file, ref_aparc_ds, [('out', 'source_file')]), (ref_aparc, ref_aparc_ds, [('output_image', 'in_file')]), (pick_file, mov_aparc_ds, [('out', 'source_file')]), (mov_aparc, mov_aparc_ds, [('output_image', 'in_file')]), # Mapping ref surfaces (cifti_wf, gii2csv, [(('outputnode.surf_norm', _discard_inflated), 'in_file')]), (gii2csv, ref_map_surf, [('out_file', 'input_file')]), (ref_norm, ref_map_surf, [(('inverse_composite_transform', _ensure_list), 'transforms')]), (ref_map_surf, ref_csv2gii, [('output_file', 'in_file')]), (cifti_wf, ref_csv2gii, [(('outputnode.surf_norm', _discard_inflated), 'gii_file')]), (pick_file, ref_surfs_ds, [('out', 'source_file')]), (ref_csv2gii, ref_surfs_ds, [('out_file', 'in_file'), (('out_file', _get_surf_extra), 'extra_values')]), (ref_csv2gii, ref_surfs_buffer, [('out_file', 'surfaces')]), (ref_surfs_buffer, ref_surfs_unzip, [('surfaces', 'in_files')]), (ref_surfs_unzip, ref_ply, [('out_files', 'in_files')]), (ref_ply, ref_recon, [('out_file', 'in_file')]), (ref_recon, ref_avggii, [('out_file', 'in_file')]), (ref_surfs_unzip, ref_avggii, [('surf_keys', 'surf_key')]), (ref_avggii, ref_smooth, [('out_file', 'in_file')]), (ref_smooth, ref_avg_ds, [('surface', 'in_file'), (('surface', _get_surf_extra), 'extra_values')]), # Mapping mov surfaces (gii2csv, mov_map_surf, [('out_file', 'input_file')]), (mov_norm, mov_map_surf, [(('inverse_composite_transform', _ensure_list), 'transforms')]), (mov_map_surf, mov_csv2gii, [('output_file', 'in_file')]), (cifti_wf, mov_csv2gii, [(('outputnode.surf_norm', _discard_inflated), 'gii_file')]), (pick_file, mov_surfs_ds, [('out', 'source_file')]), (mov_csv2gii, mov_surfs_ds, [('out_file', 'in_file'), (('out_file', _get_surf_extra), 'extra_values')]), (mov_csv2gii, mov_surfs_buffer, [('out_file', 'surfaces')]), (mov_surfs_buffer, mov_surfs_unzip, [('surfaces', 'in_files')]), (mov_surfs_unzip, mov_ply, [('out_files', 'in_files')]), (mov_ply, mov_recon, [('out_file', 'in_file')]), (mov_recon, mov_avggii, [('out_file', 'in_file')]), (mov_surfs_unzip, mov_avggii, [('surf_keys', 'surf_key')]), (mov_avggii, mov_smooth, [('out_file', 'in_file')]), (mov_smooth, mov_avg_ds, [('surface', 'in_file'), (('surface', _get_surf_extra), 'extra_values')]), ]) return wf