def airmsk_wf(name='AirMaskWorkflow'): """Implements the Step 1 of [Mortamet2009]_.""" workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'in_file', 'in_mask', 'head_mask', 'reverse_transforms', 'reverse_invert_flags' ]), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['out_file', 'artifact_msk']), name='outputnode') invt = pe.Node(ants.ApplyTransforms(dimension=3, default_value=0, interpolation='NearestNeighbor'), name='invert_xfm') invt.inputs.input_image = op.join(get_mni_icbm152_nlin_asym_09c(), '1mm_headmask.nii.gz') qi1 = pe.Node(ArtifactMask(), name='ArtifactMask') workflow.connect([(inputnode, qi1, [('in_file', 'in_file'), ('head_mask', 'head_mask')]), (inputnode, invt, [('in_mask', 'reference_image'), ('reverse_transforms', 'transforms'), ('reverse_invert_flags', 'invert_transform_flags')]), (invt, qi1, [('output_image', 'nasion_post_mask')]), (qi1, outputnode, [('out_air_msk', 'out_file'), ('out_art_msk', 'artifact_msk')])]) return workflow
def airmsk_wf(name='AirMaskWorkflow'): """Implements the Step 1 of [Mortamet2009]_.""" import pkg_resources as pkgr workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_mask', 'head_mask', 'reverse_transforms', 'reverse_invert_flags']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'artifact_msk']), name='outputnode') invt = pe.Node(ants.ApplyTransforms( dimension=3, default_value=0, interpolation='NearestNeighbor'), name='invert_xfm') invt.inputs.input_image = op.join(get_mni_icbm152_nlin_asym_09c(), '1mm_headmask.nii.gz') qi1 = pe.Node(ArtifactMask(), name='ArtifactMask') workflow.connect([ (inputnode, qi1, [('in_file', 'in_file'), ('head_mask', 'head_mask')]), (inputnode, invt, [('in_mask', 'reference_image'), ('reverse_transforms', 'transforms'), ('reverse_invert_flags', 'invert_transform_flags')]), (invt, qi1, [('output_image', 'nasion_post_mask')]), (qi1, outputnode, [('out_air_msk', 'out_file'), ('out_art_msk', 'artifact_msk')]) ]) return workflow
def airmsk_wf(name='AirMaskWorkflow'): """ Implements the Step 1 of [Mortamet2009]_. .. workflow:: from mriqc.workflows.anatomical import airmsk_wf wf = airmsk_wf() """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'in_file', 'in_mask', 'head_mask', 'inverse_composite_transform' ]), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['hat_mask', 'air_mask', 'art_mask', 'rot_mask']), name='outputnode') rotmsk = pe.Node(RotationMask(), name='RotationMask') invt = pe.Node(ants.ApplyTransforms(dimension=3, default_value=0, interpolation='Linear', float=True), name='invert_xfm') invt.inputs.input_image = str( Path(get_mni_icbm152_nlin_asym_09c()) / '1mm_headmask.nii.gz') binarize = pe.Node(niu.Function(function=_binarize), name='Binarize') qi1 = pe.Node(ArtifactMask(), name='ArtifactMask') workflow.connect([(inputnode, rotmsk, [('in_file', 'in_file')]), (inputnode, qi1, [('in_file', 'in_file'), ('head_mask', 'head_mask')]), (rotmsk, qi1, [('out_file', 'rot_mask')]), (inputnode, invt, [('in_mask', 'reference_image'), ('inverse_composite_transform', 'transforms')]), (invt, binarize, [('output_image', 'in_file')]), (binarize, qi1, [('out', 'nasion_post_mask')]), (qi1, outputnode, [('out_hat_msk', 'hat_mask'), ('out_air_msk', 'air_mask'), ('out_art_msk', 'art_mask')]), (rotmsk, outputnode, [('out_file', 'rot_mask')])]) return workflow
def airmsk_wf(name='AirMaskWorkflow'): """ Implements the Step 1 of [Mortamet2009]_. .. workflow:: from mriqc.workflows.anatomical import airmsk_wf wf = airmsk_wf() """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_mask', 'head_mask', 'inverse_composite_transform']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'artifact_msk', 'rot_mask']), name='outputnode') rotmsk = pe.Node(RotationMask(), name='RotationMask') invt = pe.Node(ants.ApplyTransforms(dimension=3, default_value=0, interpolation='Linear', float=True), name='invert_xfm') invt.inputs.input_image = op.join(get_mni_icbm152_nlin_asym_09c(), '1mm_headmask.nii.gz') binarize = pe.Node(niu.Function(function=_binarize), name='Binarize') qi1 = pe.Node(ArtifactMask(), name='ArtifactMask') workflow.connect([ (inputnode, rotmsk, [('in_file', 'in_file')]), (inputnode, qi1, [('in_file', 'in_file'), ('head_mask', 'head_mask')]), (rotmsk, qi1, [('out_file', 'rot_mask')]), (inputnode, invt, [('in_mask', 'reference_image'), ('inverse_composite_transform', 'transforms')]), (invt, binarize, [('output_image', 'in_file')]), (binarize, qi1, [('out', 'nasion_post_mask')]), (qi1, outputnode, [('out_air_msk', 'out_file'), ('out_art_msk', 'artifact_msk')]), (rotmsk, outputnode, [('out_file', 'rot_mask')]) ]) return workflow
def compute_iqms(settings, name='ComputeIQMs'): """Workflow that actually computes the IQMs""" workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'subject_id', 'session_id', 'run_id', 'orig', 'brainmask', 'airmask', 'artmask', 'headmask', 'segmentation', 'inu_corrected', 'in_inu', 'pvms', 'metadata', 'reverse_transforms', 'reverse_invert_flags' ]), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['out_file', 'out_noisefit']), name='outputnode') deriv_dir = check_folder( op.abspath(op.join(settings['output_dir'], 'derivatives'))) # AFNI check smoothing fwhm = pe.Node(afni.FWHMx(combine=True, detrend=True), name='smoothness') # fwhm.inputs.acf = True # add when AFNI >= 16 # Mortamet's QI2 getqi2 = pe.Node(ComputeQI2(erodemsk=settings.get('testing', False)), name='ComputeQI2') # Compute python-coded measures measures = pe.Node(StructuralQC(), 'measures') # Project MNI segmentation to T1 space invt = pe.MapNode(ants.ApplyTransforms(dimension=3, default_value=0, interpolation='NearestNeighbor'), iterfield=['input_image'], name='MNItpms2t1') invt.inputs.input_image = [ op.join(get_mni_icbm152_nlin_asym_09c(), fname + '.nii.gz') for fname in ['1mm_tpm_csf', '1mm_tpm_gm', '1mm_tpm_wm'] ] datasink = pe.Node(IQMFileSink(modality='T1w', out_dir=deriv_dir), name='datasink') workflow.connect([(inputnode, datasink, [('subject_id', 'subject_id'), ('session_id', 'session_id'), ('run_id', 'run_id'), ('metadata', 'metadata')]), (inputnode, getqi2, [('orig', 'in_file'), ('airmask', 'air_msk')]), (inputnode, measures, [('inu_corrected', 'in_noinu'), ('in_inu', 'in_bias'), ('orig', 'in_file'), ('airmask', 'air_msk'), ('headmask', 'head_msk'), ('artmask', 'artifact_msk'), ('segmentation', 'in_segm'), ('pvms', 'in_pvms')]), (inputnode, fwhm, [('orig', 'in_file'), ('brainmask', 'mask')]), (inputnode, invt, [('orig', 'reference_image'), ('reverse_transforms', 'transforms'), ('reverse_invert_flags', 'invert_transform_flags')]), (invt, measures, [('output_image', 'mni_tpms')]), (measures, datasink, [('out_qc', 'root')]), (getqi2, datasink, [('qi2', 'qi_2')]), (fwhm, datasink, [(('fwhm', fwhm_dict), 'root0')]), (getqi2, outputnode, [('out_file', 'out_noisefit')]), (datasink, outputnode, [('out_file', 'out_file')])]) return workflow
def t1w_preprocessing(name='t1w_preprocessing', settings=None): """T1w images preprocessing pipeline""" if settings is None: raise RuntimeError('Workflow settings are missing') workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=['t1w']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['t1_seg', 't1_tpms', 'bias_corrected_t1', 't1_brain', 't1_mask', 't1_2_mni', 't1_2_mni_forward_transform', 't1_2_mni_reverse_transform']), name='outputnode') # 0. Align and merge if several T1w images are provided t1wmrg = pe.Node(IntraModalMerge(), name='MergeT1s') # 1. Reorient T1 arw = pe.Node(niu.Function(input_names=['in_file'], output_names=['out_file'], function=reorient), name='Reorient') # 2. T1 Bias Field Correction inu_n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='CorrectINU') # 3. Skull-stripping asw = skullstrip_wf() if settings.get('skull_strip_ants', False): asw = skullstrip_ants(settings=settings) # 4. Segmentation t1_seg = pe.Node(FASTRPT(generate_report=True, segments=True, no_bias=True, probability_maps=True), name='Segmentation') # 5. Spatial normalization (T1w to MNI registration) t1_2_mni = pe.Node( RobustMNINormalizationRPT( generate_report=True, num_threads=settings['ants_nthreads'], testing=settings.get('debug', False), template='mni_icbm152_nlin_asym_09c' ), name='T1_2_MNI_Registration' ) # should not be necesssary byt does not hurt - make sure the multiproc # scheduler knows the resource limits t1_2_mni.interface.num_threads = settings['ants_nthreads'] # Resample the brain mask and the tissue probability maps into mni space bmask_mni = pe.Node( ants.ApplyTransforms(dimension=3, default_value=0, interpolation='NearestNeighbor'), name='brain_mni_warp' ) bmask_mni.inputs.reference_image = op.join(get_mni_icbm152_nlin_asym_09c(), '1mm_T1.nii.gz') tpms_mni = pe.MapNode( ants.ApplyTransforms(dimension=3, default_value=0, interpolation='Linear'), iterfield=['input_image'], name='tpms_mni_warp' ) tpms_mni.inputs.reference_image = op.join(get_mni_icbm152_nlin_asym_09c(), '1mm_T1.nii.gz') ds_t1_seg_report = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='t1_seg', out_path_base='reports'), name='DS_T1_Seg_Report' ) ds_t1_2_mni_report = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='t1_2_mni', out_path_base='reports'), name='DS_T1_2_MNI_Report' ) workflow.connect([ (inputnode, t1wmrg, [('t1w', 'in_files')]), (t1wmrg, arw, [('out_avg', 'in_file')]), (arw, inu_n4, [('out_file', 'input_image')]), (inu_n4, asw, [('output_image', 'inputnode.in_file')]), (asw, t1_seg, [('outputnode.out_file', 'in_files')]), (inu_n4, t1_2_mni, [('output_image', 'moving_image')]), (asw, t1_2_mni, [('outputnode.out_mask', 'moving_mask')]), (t1_seg, outputnode, [('tissue_class_map', 't1_seg')]), (inu_n4, outputnode, [('output_image', 'bias_corrected_t1')]), (t1_seg, outputnode, [('probability_maps', 't1_tpms')]), (t1_2_mni, outputnode, [ ('warped_image', 't1_2_mni'), ('forward_transforms', 't1_2_mni_forward_transform'), ('reverse_transforms', 't1_2_mni_reverse_transform') ]), (asw, bmask_mni, [('outputnode.out_mask', 'input_image')]), (t1_2_mni, bmask_mni, [('forward_transforms', 'transforms'), ('forward_invert_flags', 'invert_transform_flags')]), (t1_seg, tpms_mni, [('probability_maps', 'input_image')]), (t1_2_mni, tpms_mni, [('forward_transforms', 'transforms'), ('forward_invert_flags', 'invert_transform_flags')]), (asw, outputnode, [('outputnode.out_file', 't1_brain'), ('outputnode.out_mask', 't1_mask')]), (inputnode, ds_t1_seg_report, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (t1_seg, ds_t1_seg_report, [('out_report', 'in_file')]), (inputnode, ds_t1_2_mni_report, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (t1_2_mni, ds_t1_2_mni_report, [('out_report', 'in_file')]) ]) if settings.get('skull_strip_ants', False): ds_t1_skull_strip_report = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='t1_skull_strip', out_path_base='reports'), name='DS_Report' ) workflow.connect([ (inputnode, ds_t1_skull_strip_report, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (asw, ds_t1_skull_strip_report, [('outputnode.out_report', 'in_file')]) ]) # Write corrected file in the designated output dir ds_t1_bias = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='preproc'), name='DerivT1_inu' ) ds_t1_seg = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='dtissue'), name='DerivT1_seg' ) ds_mask = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='brainmask'), name='DerivT1_mask' ) ds_t1_mni = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='space-MNI152NLin2009cAsym_preproc'), name='DerivT1w_MNI' ) ds_t1_mni_aff = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='target-MNI152NLin2009cAsym_affine'), name='DerivT1w_MNI_affine' ) ds_bmask_mni = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='space-MNI152NLin2009cAsym_brainmask'), name='DerivT1_Mask_MNI' ) ds_tpms_mni = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='space-MNI152NLin2009cAsym_class-{extra_value}_probtissue'), name='DerivT1_TPMs_MNI' ) ds_tpms_mni.inputs.extra_values = ['CSF', 'GM', 'WM'] if settings.get('debug', False): workflow.connect([ (t1_2_mni, ds_t1_mni_aff, [('forward_transforms', 'in_file')]) ]) else: ds_t1_mni_warp = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='target-MNI152NLin2009cAsym_warp'), name='mni_warp') def _get_aff(inlist): return inlist[:-1] def _get_warp(inlist): return inlist[-1] workflow.connect([ (inputnode, ds_t1_mni_warp, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (t1_2_mni, ds_t1_mni_aff, [ (('forward_transforms', _get_aff), 'in_file')]), (t1_2_mni, ds_t1_mni_warp, [ (('forward_transforms', _get_warp), 'in_file')]) ]) workflow.connect([ (inputnode, ds_t1_bias, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inputnode, ds_t1_seg, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inputnode, ds_mask, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inputnode, ds_t1_mni, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inputnode, ds_t1_mni_aff, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inputnode, ds_bmask_mni, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inputnode, ds_tpms_mni, [(('t1w', fix_multi_T1w_source_name), 'source_file')]), (inu_n4, ds_t1_bias, [('output_image', 'in_file')]), (t1_seg, ds_t1_seg, [('tissue_class_map', 'in_file')]), (asw, ds_mask, [('outputnode.out_mask', 'in_file')]), (t1_2_mni, ds_t1_mni, [('warped_image', 'in_file')]), (bmask_mni, ds_bmask_mni, [('output_image', 'in_file')]), (tpms_mni, ds_tpms_mni, [('output_image', 'in_file')]) ]) return workflow
def compute_iqms(settings, modality='T1w', name='ComputeIQMs'): """ Workflow that actually computes the IQMs .. workflow:: from mriqc.workflows.anatomical import compute_iqms wf = compute_iqms(settings={'output_dir': 'out'}) """ from .utils import _tofloat from ..interfaces.anatomical import Harmonize workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'in_file', 'in_ras', 'brainmask', 'airmask', 'artmask', 'headmask', 'rotmask', 'segmentation', 'inu_corrected', 'in_inu', 'pvms', 'metadata', 'inverse_composite_transform']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_noisefit']), name='outputnode') deriv_dir = check_folder(op.abspath(op.join(settings['output_dir'], 'derivatives'))) # Extract metadata meta = pe.Node(ReadSidecarJSON(), name='metadata') # Add provenance addprov = pe.Node(niu.Function(function=_add_provenance), name='provenance') addprov.inputs.settings = { 'testing': settings.get('testing', False), 'webapi_url': settings.get('webapi_url'), 'webapi_port': settings.get('webapi_port') } # AFNI check smoothing fwhm_interface = get_fwhmx() fwhm = pe.Node(fwhm_interface, name='smoothness') # Harmonize homog = pe.Node(Harmonize(), name='harmonize') # Mortamet's QI2 getqi2 = pe.Node(ComputeQI2(erodemsk=settings.get('testing', False)), name='ComputeQI2') # Compute python-coded measures measures = pe.Node(StructuralQC(), 'measures') # Project MNI segmentation to T1 space invt = pe.MapNode(ants.ApplyTransforms( dimension=3, default_value=0, interpolation='Linear', float=True), iterfield=['input_image'], name='MNItpms2t1') invt.inputs.input_image = [op.join(get_mni_icbm152_nlin_asym_09c(), fname + '.nii.gz') for fname in ['1mm_tpm_csf', '1mm_tpm_gm', '1mm_tpm_wm']] datasink = pe.Node(IQMFileSink(modality=modality, out_dir=deriv_dir), name='datasink') datasink.inputs.modality = modality def _getwm(inlist): return inlist[-1] workflow.connect([ (inputnode, meta, [('in_file', 'in_file')]), (meta, datasink, [('subject_id', 'subject_id'), ('session_id', 'session_id'), ('acq_id', 'acq_id'), ('rec_id', 'rec_id'), ('run_id', 'run_id'), ('out_dict', 'metadata')]), (inputnode, addprov, [('in_file', 'in_file'), ('airmask', 'air_msk'), ('rotmask', 'rot_msk')]), (inputnode, getqi2, [('in_ras', 'in_file'), ('airmask', 'air_msk')]), (inputnode, homog, [('inu_corrected', 'in_file'), (('pvms', _getwm), 'wm_mask')]), (inputnode, measures, [('in_inu', 'in_bias'), ('in_ras', 'in_file'), ('airmask', 'air_msk'), ('headmask', 'head_msk'), ('artmask', 'artifact_msk'), ('rotmask', 'rot_msk'), ('segmentation', 'in_segm'), ('pvms', 'in_pvms')]), (inputnode, fwhm, [('in_ras', 'in_file'), ('brainmask', 'mask')]), (inputnode, invt, [('in_ras', 'reference_image'), ('inverse_composite_transform', 'transforms')]), (homog, measures, [('out_file', 'in_noinu')]), (invt, measures, [('output_image', 'mni_tpms')]), (fwhm, measures, [(('fwhm', _tofloat), 'in_fwhm')]), (measures, datasink, [('out_qc', 'root')]), (addprov, datasink, [('out', 'provenance')]), (getqi2, datasink, [('qi2', 'qi_2')]), (getqi2, outputnode, [('out_file', 'out_noisefit')]), (datasink, outputnode, [('out_file', 'out_file')]), ]) return workflow
def init_carpetplot_wf(mem_gb, metadata, name="bold_carpet_wf"): """ Resamples the MNI parcellation (ad-hoc parcellation derived from the Harvard-Oxford template and others). **Parameters** mem_gb : float Size of BOLD file in GB - please note that this size should be calculated after resamplings that may extend the FoV metadata : dict BIDS metadata for BOLD file name : str Name of workflow (default: ``bold_carpet_wf``) **Inputs** bold BOLD image, after the prescribed corrections (STC, HMC and SDC) when available. bold_mask BOLD series mask confounds_file TSV of all aggregated confounds t1_bold_xform Affine matrix that maps the T1w space into alignment with the native BOLD space t1_2_mni_reverse_transform ANTs-compatible affine-and-warp transform file **Outputs** out_carpetplot Path of the generated SVG file """ inputnode = pe.Node(niu.IdentityInterface( fields=['bold', 'bold_mask', 'confounds_file', 't1_bold_xform', 't1_2_mni_reverse_transform']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_carpetplot']), name='outputnode') # List transforms mrg_xfms = pe.Node(niu.Merge(2), name='mrg_xfms') # Warp segmentation into EPI space resample_parc = pe.Node(ApplyTransforms( float=True, input_image=os.path.join( get_mni_icbm152_nlin_asym_09c(), '1mm_parc.nii.gz'), dimension=3, default_value=0, interpolation='MultiLabel'), name='resample_parc') # Carpetplot and confounds plot conf_plot = pe.Node(FMRISummary( tr=metadata['RepetitionTime'], confounds_list=[ ('GlobalSignal', None, 'GS'), ('CSF', None, 'GSCSF'), ('WhiteMatter', None, 'GSWM'), ('stdDVARS', None, 'DVARS'), ('FramewiseDisplacement', 'mm', 'FD')]), name='conf_plot', mem_gb=mem_gb) ds_report_bold_conf = pe.Node( DerivativesDataSink(suffix='carpetplot'), name='ds_report_bold_conf', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow = pe.Workflow(name=name) workflow.connect([ (inputnode, mrg_xfms, [('t1_bold_xform', 'in1'), ('t1_2_mni_reverse_transform', 'in2')]), (inputnode, resample_parc, [('bold_mask', 'reference_image')]), (mrg_xfms, resample_parc, [('out', 'transforms')]), # Carpetplot (inputnode, conf_plot, [ ('bold', 'in_func'), ('bold_mask', 'in_mask'), ('confounds_file', 'confounds_file')]), (resample_parc, conf_plot, [('output_image', 'in_segm')]), (conf_plot, ds_report_bold_conf, [('out_file', 'in_file')]), (conf_plot, outputnode, [('out_file', 'out_carpetplot')]), ]) return workflow
def init_carpetplot_wf(mem_gb, metadata, name="bold_carpet_wf"): """ Resamples the MNI parcellation (ad-hoc parcellation derived from the Harvard-Oxford template and others). **Parameters** mem_gb : float Size of BOLD file in GB - please note that this size should be calculated after resamplings that may extend the FoV metadata : dict BIDS metadata for BOLD file name : str Name of workflow (default: ``bold_carpet_wf``) **Inputs** bold BOLD image, after the prescribed corrections (STC, HMC and SDC) when available. bold_mask BOLD series mask confounds_file TSV of all aggregated confounds t1_bold_xform Affine matrix that maps the T1w space into alignment with the native BOLD space t1_2_mni_reverse_transform ANTs-compatible affine-and-warp transform file **Outputs** out_carpetplot Path of the generated SVG file """ inputnode = pe.Node(niu.IdentityInterface( fields=['bold', 'bold_mask', 'confounds_file', 't1_bold_xform', 't1_2_mni_reverse_transform']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_carpetplot']), name='outputnode') # List transforms mrg_xfms = pe.Node(niu.Merge(2), name='mrg_xfms') # Warp segmentation into EPI space resample_parc = pe.Node(ApplyTransforms( float=True, input_image=os.path.join( get_mni_icbm152_nlin_asym_09c(), '1mm_parc.nii.gz'), dimension=3, default_value=0, interpolation='MultiLabel'), name='resample_parc') # Carpetplot and confounds plot conf_plot = pe.Node(FMRISummary( tr=metadata['RepetitionTime'], confounds_list=[ ('global_signal', None, 'GS'), ('csf', None, 'GSCSF'), ('white_matter', None, 'GSWM'), ('std_dvars', None, 'DVARS'), ('framewise_displacement', 'mm', 'FD')]), name='conf_plot', mem_gb=mem_gb) ds_report_bold_conf = pe.Node( DerivativesDataSink(suffix='carpetplot'), name='ds_report_bold_conf', run_without_submitting=True, mem_gb=DEFAULT_MEMORY_MIN_GB) workflow = Workflow(name=name) workflow.connect([ (inputnode, mrg_xfms, [('t1_bold_xform', 'in1'), ('t1_2_mni_reverse_transform', 'in2')]), (inputnode, resample_parc, [('bold_mask', 'reference_image')]), (mrg_xfms, resample_parc, [('out', 'transforms')]), # Carpetplot (inputnode, conf_plot, [ ('bold', 'in_func'), ('bold_mask', 'in_mask'), ('confounds_file', 'confounds_file')]), (resample_parc, conf_plot, [('output_image', 'in_segm')]), (conf_plot, ds_report_bold_conf, [('out_file', 'in_file')]), (conf_plot, outputnode, [('out_file', 'out_carpetplot')]), ]) return workflow
def epi_mni_transformation(name='EPIMNITransformation', settings=None): workflow = pe.Workflow(name=name) inputnode = pe.Node( niu.IdentityInterface(fields=[ 'itk_epi_to_t1', 't1_2_mni_forward_transform', 'epi', 'epi_mask', 't1', 'hmc_xforms' ]), name='inputnode' ) def _aslist(in_value): if isinstance(in_value, list): return in_value return [in_value] gen_ref = pe.Node(niu.Function( input_names=['fixed_image', 'moving_image'], output_names=['out_file'], function=_gen_reference), name='GenNewMNIReference') gen_ref.inputs.fixed_image = op.join(get_mni_icbm152_nlin_asym_09c(), '1mm_T1.nii.gz') split = pe.Node(fsl.Split(dimension='t'), name='SplitEPI') split.interface.estimated_memory_gb = settings["biggest_epi_file_size_gb"] * 3 merge_transforms = pe.MapNode(niu.Merge(3), iterfield=['in3'], name='MergeTransforms') epi_to_mni_transform = pe.MapNode( ants.ApplyTransforms(), iterfield=['input_image', 'transforms'], name='EPIToMNITransform') epi_to_mni_transform.terminal_output = 'file' merge = pe.Node(niu.Function(input_names=["in_files"], output_names=["merged_file"], function=nii_concat), name='MergeEPI') merge.interface.estimated_memory_gb = settings[ "biggest_epi_file_size_gb"] * 3 mask_merge_tfms = pe.Node(niu.Merge(2), name='MaskMergeTfms') mask_mni_tfm = pe.Node( ants.ApplyTransforms(interpolation='NearestNeighbor'), name='MaskToMNI' ) # Write corrected file in the designated output dir ds_mni = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='space-MNI152NLin2009cAsym_preproc'), name='DerivativesHMCMNI' ) ds_mni_mask = pe.Node( DerivativesDataSink(base_directory=settings['output_dir'], suffix='space-MNI152NLin2009cAsym_brainmask'), name='DerivativesHMCMNImask' ) workflow.connect([ (inputnode, ds_mni, [('epi', 'source_file')]), (inputnode, ds_mni_mask, [('epi', 'source_file')]), (inputnode, gen_ref, [('epi_mask', 'moving_image')]), (inputnode, merge_transforms, [('t1_2_mni_forward_transform', 'in1'), (('itk_epi_to_t1', _aslist), 'in2'), ('hmc_xforms', 'in3')]), (inputnode, mask_merge_tfms, [('t1_2_mni_forward_transform', 'in1'), (('itk_epi_to_t1', _aslist), 'in2')]), (inputnode, split, [('epi', 'in_file')]), (split, epi_to_mni_transform, [('out_files', 'input_image')]), (merge_transforms, epi_to_mni_transform, [('out', 'transforms')]), (gen_ref, epi_to_mni_transform, [('out_file', 'reference_image')]), (epi_to_mni_transform, merge, [('output_image', 'in_files')]), (merge, ds_mni, [('merged_file', 'in_file')]), (mask_merge_tfms, mask_mni_tfm, [('out', 'transforms')]), (gen_ref, mask_mni_tfm, [('out_file', 'reference_image')]), (inputnode, mask_mni_tfm, [('epi_mask', 'input_image')]), (mask_mni_tfm, ds_mni_mask, [('output_image', 'in_file')]) ]) return workflow
def compute_iqms(settings, modality='T1w', name='ComputeIQMs'): """ Workflow that actually computes the IQMs .. workflow:: from mriqc.workflows.anatomical import compute_iqms wf = compute_iqms(settings={'output_dir': 'out'}) """ from .utils import _tofloat from ..interfaces.anatomical import Harmonize workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'in_file', 'in_ras', 'brainmask', 'airmask', 'artmask', 'headmask', 'rotmask', 'segmentation', 'inu_corrected', 'in_inu', 'pvms', 'metadata', 'inverse_composite_transform']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_noisefit']), name='outputnode') deriv_dir = check_folder(op.abspath(op.join(settings['output_dir'], 'derivatives'))) # Extract metadata meta = pe.Node(ReadSidecarJSON(), name='metadata') # Add provenance addprov = pe.Node(niu.Function(function=_add_provenance), name='provenance') addprov.inputs.settings = { 'testing': settings.get('testing', False) } # AFNI check smoothing fwhm = pe.Node(afni.FWHMx(combine=True, detrend=True), name='smoothness') # fwhm.inputs.acf = True # add when AFNI >= 16 # Harmonize homog = pe.Node(Harmonize(), name='harmonize') # Mortamet's QI2 getqi2 = pe.Node(ComputeQI2(erodemsk=settings.get('testing', False)), name='ComputeQI2') # Compute python-coded measures measures = pe.Node(StructuralQC(), 'measures') # Project MNI segmentation to T1 space invt = pe.MapNode(ants.ApplyTransforms( dimension=3, default_value=0, interpolation='Linear', float=True), iterfield=['input_image'], name='MNItpms2t1') invt.inputs.input_image = [op.join(get_mni_icbm152_nlin_asym_09c(), fname + '.nii.gz') for fname in ['1mm_tpm_csf', '1mm_tpm_gm', '1mm_tpm_wm']] datasink = pe.Node(IQMFileSink(modality=modality, out_dir=deriv_dir), name='datasink') datasink.inputs.modality = modality def _getwm(inlist): return inlist[-1] workflow.connect([ (inputnode, meta, [('in_file', 'in_file')]), (meta, datasink, [('subject_id', 'subject_id'), ('session_id', 'session_id'), ('acq_id', 'acq_id'), ('rec_id', 'rec_id'), ('run_id', 'run_id'), ('out_dict', 'metadata')]), (inputnode, addprov, [('in_file', 'in_file'), ('airmask', 'air_msk'), ('rotmask', 'rot_msk')]), (inputnode, getqi2, [('in_ras', 'in_file'), ('airmask', 'air_msk')]), (inputnode, homog, [('inu_corrected', 'in_file'), (('pvms', _getwm), 'wm_mask')]), (inputnode, measures, [('in_inu', 'in_bias'), ('in_ras', 'in_file'), ('airmask', 'air_msk'), ('headmask', 'head_msk'), ('artmask', 'artifact_msk'), ('rotmask', 'rot_msk'), ('segmentation', 'in_segm'), ('pvms', 'in_pvms')]), (inputnode, fwhm, [('in_ras', 'in_file'), ('brainmask', 'mask')]), (inputnode, invt, [('in_ras', 'reference_image'), ('inverse_composite_transform', 'transforms')]), (homog, measures, [('out_file', 'in_noinu')]), (invt, measures, [('output_image', 'mni_tpms')]), (fwhm, measures, [(('fwhm', _tofloat), 'in_fwhm')]), (measures, datasink, [('out_qc', 'root')]), (addprov, datasink, [('out', 'provenance')]), (getqi2, datasink, [('qi2', 'qi_2')]), (getqi2, outputnode, [('out_file', 'out_noisefit')]), (datasink, outputnode, [('out_file', 'out_file')]), ]) return workflow
def compute_iqms(settings, name='ComputeIQMs'): """Workflow that actually computes the IQMs""" workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'subject_id', 'session_id', 'run_id', 'orig', 'brainmask', 'airmask', 'artmask', 'headmask', 'segmentation', 'inu_corrected', 'in_inu', 'pvms', 'metadata', 'reverse_transforms', 'reverse_invert_flags']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_noisefit']), name='outputnode') deriv_dir = check_folder(op.abspath(op.join(settings['output_dir'], 'derivatives'))) # AFNI check smoothing fwhm = pe.Node(afni.FWHMx(combine=True, detrend=True), name='smoothness') # fwhm.inputs.acf = True # add when AFNI >= 16 # Compute python-coded measures measures = pe.Node(StructuralQC(testing=settings.get('testing', False)), 'measures') # Project MNI segmentation to T1 space invt = pe.MapNode(ants.ApplyTransforms( dimension=3, default_value=0, interpolation='NearestNeighbor'), iterfield=['input_image'], name='MNItpms2t1') invt.inputs.input_image = [op.join(get_mni_icbm152_nlin_asym_09c(), fname + '.nii.gz') for fname in ['1mm_tpm_csf', '1mm_tpm_gm', '1mm_tpm_wm']] # Link images that should be reported dsreport = pe.Node(nio.DataSink( base_directory=settings['report_dir'], parameterization=True), name='dsreport') dsreport.inputs.container = 'anat' dsreport.inputs.substitutions = [ ('_data', ''), ('background_fit', 'plot_bgfit') ] dsreport.inputs.regexp_substitutions = [ ('_u?(sub-[\\w\\d]*)\\.([\\w\\d_]*)(?:\\.([\\w\\d_-]*))+', '\\1_ses-\\2_\\3'), ('anatomical_bgplotsub-[^/.]*_dvars_std', 'plot_dvars'), ('sub-[^/.]*_T1w_out_calc_thresh', 'mask'), ] # 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 = 'anat' # Save to JSON file jfs_if = nio.JSONFileSink() setattr(jfs_if, '_always_run', settings.get('force_run', False)) datasink = pe.Node(jfs_if, name='datasink') datasink.inputs.qc_type = 'anat' 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'), ('metadata', 'metadata')]), (inputnode, measures, [('inu_corrected', 'in_noinu'), ('in_inu', 'in_bias'), ('orig', 'in_file'), ('airmask', 'air_msk'), ('headmask', 'head_msk'), ('artmask', 'artifact_msk'), ('segmentation', 'in_segm'), ('pvms', 'in_pvms')]), (inputnode, fwhm, [('orig', 'in_file'), ('brainmask', 'mask')]), (inputnode, invt, [('orig', 'reference_image'), ('reverse_transforms', 'transforms'), ('reverse_invert_flags', 'invert_transform_flags')]), (invt, measures, [('output_image', 'mni_tpms')]), (fwhm, datasink, [(('fwhm', fwhm_dict), 'fwhm')]), (measures, datasink, [('summary', 'summary'), ('spacing', 'spacing'), ('size', 'size'), ('icvs', 'icvs'), ('rpve', 'rpve'), ('inu', 'inu'), ('snr', 'snr'), ('cnr', 'cnr'), ('fber', 'fber'), ('efc', 'efc'), ('qi1', 'qi1'), ('qi2', 'qi2'), ('cjv', 'cjv'), ('wm2max', 'wm2max'), ('tpm_overlap', 'tpm_overlap')]), (out_name, datasink, [('out_file', 'out_file')]), (measures, outputnode, [('out_noisefit', 'out_noisefit')]), (datasink, outputnode, [('out_file', 'out_file')]) ]) return workflow