def anatomical_reorient_workflow(workflow, resource_pool, config): # resource pool should have: # anatomical_scan import os import sys import nipype.interfaces.io as nio import nipype.pipeline.engine as pe import nipype.interfaces.utility as util import nipype.interfaces.fsl.maths as fsl from nipype.interfaces.afni import preprocess from workflow_utils import check_input_resources check_input_resources(resource_pool, "anatomical_scan") anat_deoblique = pe.Node(interface=preprocess.Refit(), name="anat_deoblique") anat_deoblique.inputs.in_file = resource_pool["anatomical_scan"] anat_deoblique.inputs.deoblique = True anat_reorient = pe.Node(interface=preprocess.Resample(), name="anat_reorient") anat_reorient.inputs.orientation = "RPI" anat_reorient.inputs.outputtype = "NIFTI_GZ" workflow.connect(anat_deoblique, "out_file", anat_reorient, "in_file") resource_pool["anatomical_reorient"] = (anat_reorient, "out_file") return workflow, resource_pool
def anatomical_reorient_workflow(workflow, resource_pool, config): # resource pool should have: # anatomical_scan import os import sys import nipype.interfaces.io as nio import nipype.pipeline.engine as pe import nipype.interfaces.utility as util import nipype.interfaces.fsl.maths as fsl from nipype.interfaces.afni import preprocess from workflow_utils import check_input_resources check_input_resources(resource_pool, "anatomical_scan") anat_deoblique = pe.Node(interface=preprocess.Refit(), name='anat_deoblique') anat_deoblique.inputs.in_file = resource_pool["anatomical_scan"] anat_deoblique.inputs.deoblique = True anat_reorient = pe.Node(interface=preprocess.Resample(), name='anat_reorient') anat_reorient.inputs.orientation = 'RPI' anat_reorient.inputs.outputtype = 'NIFTI_GZ' workflow.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file') resource_pool["anatomical_reorient"] = (anat_reorient, 'out_file') return workflow, resource_pool
def func_motion_correct_workflow(workflow, resource_pool, config): # resource pool should have: # functional_scan import os import sys import nipype.interfaces.io as nio import nipype.pipeline.engine as pe import nipype.interfaces.utility as util import nipype.interfaces.fsl.maths as fsl from nipype.interfaces.afni import preprocess from workflow_utils import check_input_resources, \ check_config_settings check_input_resources(resource_pool, "functional_scan") check_config_settings(config, "start_idx") check_config_settings(config, "stop_idx") check_config_settings(config, "slice_timing_correction") func_get_idx = pe.Node(util.Function( input_names=['in_files', 'stop_idx', 'start_idx'], output_names=['stopidx', 'startidx'], function=get_idx), name='func_get_idx') func_get_idx.inputs.in_files = resource_pool["functional_scan"] func_get_idx.inputs.start_idx = config["start_idx"] func_get_idx.inputs.stop_idx = config["stop_idx"] func_drop_trs = pe.Node(interface=preprocess.Calc(), name='func_drop_trs') func_drop_trs.inputs.in_file_a = resource_pool["functional_scan"] func_drop_trs.inputs.expr = 'a' func_drop_trs.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_get_idx, 'startidx', func_drop_trs, 'start_idx') workflow.connect(func_get_idx, 'stopidx', func_drop_trs, 'stop_idx') #workflow.connect(func_drop_trs, 'out_file', # outputNode, 'drop_tr') func_slice_timing_correction = pe.Node(interface=preprocess.TShift(), name='func_slice_time_correction') func_slice_timing_correction.inputs.outputtype = 'NIFTI_GZ' func_deoblique = pe.Node(interface=preprocess.Refit(), name='func_deoblique') func_deoblique.inputs.deoblique = True if config["slice_timing_correction"] == True: workflow.connect(func_drop_trs, 'out_file', func_slice_timing_correction, 'in_file') workflow.connect(func_slice_timing_correction, 'out_file', func_deoblique, 'in_file') else: workflow.connect(func_drop_trs, 'out_file', func_deoblique, 'in_file') func_reorient = pe.Node(interface=preprocess.Resample(), name='func_reorient') func_reorient.inputs.orientation = 'RPI' func_reorient.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_deoblique, 'out_file', func_reorient, 'in_file') func_get_mean_RPI = pe.Node(interface=preprocess.TStat(), name='func_get_mean_RPI') func_get_mean_RPI.inputs.options = '-mean' func_get_mean_RPI.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_reorient, 'out_file', func_get_mean_RPI, 'in_file') # calculate motion parameters func_motion_correct = pe.Node(interface=preprocess.Volreg(), name='func_motion_correct') func_motion_correct.inputs.args = '-Fourier -twopass' func_motion_correct.inputs.zpad = 4 func_motion_correct.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_reorient, 'out_file', func_motion_correct, 'in_file') workflow.connect(func_get_mean_RPI, 'out_file', func_motion_correct, 'basefile') func_get_mean_motion = func_get_mean_RPI.clone('func_get_mean_motion') workflow.connect(func_motion_correct, 'out_file', func_get_mean_motion, 'in_file') func_motion_correct_A = func_motion_correct.clone('func_motion_correct_A') func_motion_correct_A.inputs.md1d_file = 'max_displacement.1D' workflow.connect(func_reorient, 'out_file', func_motion_correct_A, 'in_file') workflow.connect(func_get_mean_motion, 'out_file', func_motion_correct_A, 'basefile') resource_pool["func_motion_correct"] = (func_motion_correct_A, 'out_file') resource_pool["coordinate_transformation"] = \ (func_motion_correct_A, 'oned_matrix_save') return workflow, resource_pool
def qap_functional_temporal_workflow(workflow, resource_pool, config): # resource pool should have: # functional_brain_mask # func_motion_correct # coordinate_transformation import os import sys import nipype.interfaces.io as nio import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu import nipype.algorithms.misc as nam from qap_workflows_utils import qap_functional_temporal from temporal_qc import fd_jenkinson from qap.viz.interfaces import PlotMosaic, PlotFD def _getfirst(inlist): if isinstance(inlist, list): return inlist[0] return inlist # if 'mean_functional' not in resource_pool.keys(): # from functional_preproc import mean_functional_workflow # workflow, resource_pool = \ # mean_functional_workflow(workflow, resource_pool, config) if "functional_brain_mask" not in resource_pool.keys(): from functional_preproc import functional_brain_mask_workflow workflow, resource_pool = functional_brain_mask_workflow(workflow, resource_pool, config) if ("func_motion_correct" not in resource_pool.keys()) or ( "coordinate_transformation" not in resource_pool.keys() and "mcflirt_rel_rms" not in resource_pool.keys() ): from functional_preproc import func_motion_correct_workflow workflow, resource_pool = func_motion_correct_workflow(workflow, resource_pool, config) fd = pe.Node( niu.Function(input_names=["in_file"], output_names=["out_file"], function=fd_jenkinson), name="generate_FD_file" ) if "mcflirt_rel_rms" in resource_pool.keys(): fd.inputs.in_file = resource_pool["mcflirt_rel_rms"] else: if len(resource_pool["coordinate_transformation"]) == 2: node, out_file = resource_pool["coordinate_transformation"] workflow.connect(node, out_file, fd, "in_file") else: fd.inputs.in_file = resource_pool["coordinate_transformation"] temporal = pe.Node( niu.Function( input_names=[ "func_motion_correct", "func_brain_mask", "tsnr_volume", "fd_file", "subject_id", "session_id", "scan_id", "site_name", ], output_names=["qc"], function=qap_functional_temporal, ), name="qap_functional_temporal", ) temporal.inputs.subject_id = config["subject_id"] temporal.inputs.session_id = config["session_id"] temporal.inputs.scan_id = config["scan_id"] workflow.connect(fd, "out_file", temporal, "fd_file") if "site_name" in config.keys(): temporal.inputs.site_name = config["site_name"] tsnr = pe.Node(nam.TSNR(), name="compute_tsnr") if len(resource_pool["func_motion_correct"]) == 2: node, out_file = resource_pool["func_motion_correct"] workflow.connect(node, out_file, tsnr, "in_file") workflow.connect(node, out_file, temporal, "func_motion_correct") else: from workflow_utils import check_input_resources check_input_resources(resource_pool, "func_motion_correct") input_file = resource_pool["func_motion_correct"] tsnr.inputs.in_file = input_file temporal.inputs.func_motion_correct = input_file if len(resource_pool["functional_brain_mask"]) == 2: node, out_file = resource_pool["functional_brain_mask"] workflow.connect(node, out_file, temporal, "func_brain_mask") else: temporal.inputs.func_brain_mask = resource_pool["functional_brain_mask"] # Write mosaic and FD plot if config.get("write_report", False): plot = pe.Node(PlotMosaic(), name="plot_mosaic") plot.inputs.subject = config["subject_id"] metadata = [config["session_id"], config["scan_id"]] if "site_name" in config.keys(): metadata.append(config["site_name"]) plot.inputs.metadata = metadata plot.inputs.title = "tSNR volume" workflow.connect(tsnr, "tsnr_file", plot, "in_file") # Enable this if we want masks # if len(resource_pool['functional_brain_mask']) == 2: # node, out_file = resource_pool['functional_brain_mask'] # workflow.connect(node, out_file, plot, 'in_mask') # else: # plot.inputs.in_mask = resource_pool['functional_brain_mask'] resource_pool["qap_mosaic"] = (plot, "out_file") fdplot = pe.Node(PlotFD(), name="plot_fd") fdplot.inputs.subject = config["subject_id"] fdplot.inputs.metadata = metadata workflow.connect(fd, "out_file", fdplot, "in_file") resource_pool["qap_fd"] = (fdplot, "out_file") out_csv = op.join(config["output_directory"], "qap_functional_temporal.csv") temporal_to_csv = pe.Node(nam.AddCSVRow(in_file=out_csv), name="qap_functional_temporal_to_csv") workflow.connect(tsnr, "tsnr_file", temporal, "tsnr_volume") workflow.connect(temporal, "qc", temporal_to_csv, "_outputs") resource_pool["qap_functional_temporal"] = (temporal_to_csv, "csv_file") return workflow, resource_pool
def qap_functional_temporal_workflow(workflow, resource_pool, config): # resource pool should have: # functional_brain_mask # func_motion_correct # coordinate_transformation import os import sys import nipype.interfaces.io as nio import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu import nipype.algorithms.misc as nam from qap_workflows_utils import qap_functional_temporal from temporal_qc import fd_jenkinson from qap.viz.interfaces import PlotMosaic, PlotFD def _getfirst(inlist): if isinstance(inlist, list): return inlist[0] return inlist # if 'mean_functional' not in resource_pool.keys(): # from functional_preproc import mean_functional_workflow # workflow, resource_pool = \ # mean_functional_workflow(workflow, resource_pool, config) if 'functional_brain_mask' not in resource_pool.keys(): from functional_preproc import functional_brain_mask_workflow workflow, resource_pool = \ functional_brain_mask_workflow(workflow, resource_pool, config) if ('func_motion_correct' not in resource_pool.keys()) or \ ('coordinate_transformation' not in resource_pool.keys() and 'mcflirt_rel_rms' not in resource_pool.keys()): from functional_preproc import func_motion_correct_workflow workflow, resource_pool = \ func_motion_correct_workflow(workflow, resource_pool, config) fd = pe.Node(niu.Function(input_names=['in_file'], output_names=['out_file'], function=fd_jenkinson), name='generate_FD_file') if 'mcflirt_rel_rms' in resource_pool.keys(): fd.inputs.in_file = resource_pool['mcflirt_rel_rms'] else: if len(resource_pool['coordinate_transformation']) == 2: node, out_file = resource_pool['coordinate_transformation'] workflow.connect(node, out_file, fd, 'in_file') else: fd.inputs.in_file = resource_pool['coordinate_transformation'] temporal = pe.Node(niu.Function(input_names=[ 'func_motion_correct', 'func_brain_mask', 'tsnr_volume', 'fd_file', 'subject_id', 'session_id', 'scan_id', 'site_name' ], output_names=['qc'], function=qap_functional_temporal), name='qap_functional_temporal') temporal.inputs.subject_id = config['subject_id'] temporal.inputs.session_id = config['session_id'] temporal.inputs.scan_id = config['scan_id'] workflow.connect(fd, 'out_file', temporal, 'fd_file') if 'site_name' in config.keys(): temporal.inputs.site_name = config['site_name'] tsnr = pe.Node(nam.TSNR(), name='compute_tsnr') if len(resource_pool['func_motion_correct']) == 2: node, out_file = resource_pool['func_motion_correct'] workflow.connect(node, out_file, tsnr, 'in_file') workflow.connect(node, out_file, temporal, 'func_motion_correct') else: from workflow_utils import check_input_resources check_input_resources(resource_pool, 'func_motion_correct') input_file = resource_pool['func_motion_correct'] tsnr.inputs.in_file = input_file temporal.inputs.func_motion_correct = input_file if len(resource_pool['functional_brain_mask']) == 2: node, out_file = resource_pool['functional_brain_mask'] workflow.connect(node, out_file, temporal, 'func_brain_mask') else: temporal.inputs.func_brain_mask = \ resource_pool['functional_brain_mask'] # Write mosaic and FD plot if config.get('write_report', False): plot = pe.Node(PlotMosaic(), name='plot_mosaic') plot.inputs.subject = config['subject_id'] metadata = [config['session_id'], config['scan_id']] if 'site_name' in config.keys(): metadata.append(config['site_name']) plot.inputs.metadata = metadata plot.inputs.title = 'tSNR volume' workflow.connect(tsnr, 'tsnr_file', plot, 'in_file') # Enable this if we want masks # if len(resource_pool['functional_brain_mask']) == 2: # node, out_file = resource_pool['functional_brain_mask'] # workflow.connect(node, out_file, plot, 'in_mask') # else: # plot.inputs.in_mask = resource_pool['functional_brain_mask'] resource_pool['qap_mosaic'] = (plot, 'out_file') fdplot = pe.Node(PlotFD(), name='plot_fd') fdplot.inputs.subject = config['subject_id'] fdplot.inputs.metadata = metadata workflow.connect(fd, 'out_file', fdplot, 'in_file') resource_pool['qap_fd'] = (fdplot, 'out_file') out_csv = op.join(config['output_directory'], 'qap_functional_temporal.csv') temporal_to_csv = pe.Node(nam.AddCSVRow(in_file=out_csv), name='qap_functional_temporal_to_csv') workflow.connect(tsnr, 'tsnr_file', temporal, 'tsnr_volume') workflow.connect(temporal, 'qc', temporal_to_csv, '_outputs') resource_pool['qap_functional_temporal'] = (temporal_to_csv, 'csv_file') return workflow, resource_pool
def func_motion_correct_workflow(workflow, resource_pool, config): # resource pool should have: # functional_scan import os import sys import nipype.interfaces.io as nio import nipype.pipeline.engine as pe import nipype.interfaces.utility as util import nipype.interfaces.fsl.maths as fsl from nipype.interfaces.afni import preprocess from workflow_utils import check_input_resources, \ check_config_settings check_input_resources(resource_pool, "functional_scan") check_config_settings(config, "start_idx") check_config_settings(config, "stop_idx") check_config_settings(config, "slice_timing_correction") func_get_idx = pe.Node(util.Function(input_names=['in_files', 'stop_idx', 'start_idx'], output_names=['stopidx', 'startidx'], function=get_idx), name='func_get_idx') func_get_idx.inputs.in_files = resource_pool["functional_scan"] func_get_idx.inputs.start_idx = config["start_idx"] func_get_idx.inputs.stop_idx = config["stop_idx"] func_drop_trs = pe.Node(interface=preprocess.Calc(), name='func_drop_trs') func_drop_trs.inputs.in_file_a = resource_pool["functional_scan"] func_drop_trs.inputs.expr = 'a' func_drop_trs.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_get_idx, 'startidx', func_drop_trs, 'start_idx') workflow.connect(func_get_idx, 'stopidx', func_drop_trs, 'stop_idx') #workflow.connect(func_drop_trs, 'out_file', # outputNode, 'drop_tr') func_slice_timing_correction = pe.Node(interface=preprocess.TShift(), name='func_slice_time_correction') func_slice_timing_correction.inputs.outputtype = 'NIFTI_GZ' func_deoblique = pe.Node(interface=preprocess.Refit(), name='func_deoblique') func_deoblique.inputs.deoblique = True if config["slice_timing_correction"] == True: workflow.connect(func_drop_trs, 'out_file', func_slice_timing_correction,'in_file') workflow.connect(func_slice_timing_correction, 'out_file', func_deoblique, 'in_file') else: workflow.connect(func_drop_trs, 'out_file', func_deoblique, 'in_file') func_reorient = pe.Node(interface=preprocess.Resample(), name='func_reorient') func_reorient.inputs.orientation = 'RPI' func_reorient.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_deoblique, 'out_file', func_reorient, 'in_file') func_get_mean_RPI = pe.Node(interface=preprocess.TStat(), name='func_get_mean_RPI') func_get_mean_RPI.inputs.options = '-mean' func_get_mean_RPI.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_reorient, 'out_file', func_get_mean_RPI, 'in_file') # calculate motion parameters func_motion_correct = pe.Node(interface=preprocess.Volreg(), name='func_motion_correct') func_motion_correct.inputs.args = '-Fourier -twopass' func_motion_correct.inputs.zpad = 4 func_motion_correct.inputs.outputtype = 'NIFTI_GZ' workflow.connect(func_reorient, 'out_file', func_motion_correct, 'in_file') workflow.connect(func_get_mean_RPI, 'out_file', func_motion_correct, 'basefile') func_get_mean_motion = func_get_mean_RPI.clone('func_get_mean_motion') workflow.connect(func_motion_correct, 'out_file', func_get_mean_motion, 'in_file') func_motion_correct_A = func_motion_correct.clone('func_motion_correct_A') func_motion_correct_A.inputs.md1d_file = 'max_displacement.1D' workflow.connect(func_reorient, 'out_file', func_motion_correct_A, 'in_file') workflow.connect(func_get_mean_motion, 'out_file', func_motion_correct_A, 'basefile') resource_pool["func_motion_correct"] = (func_motion_correct_A, 'out_file') resource_pool["coordinate_transformation"] = \ (func_motion_correct_A, 'oned_matrix_save') return workflow, resource_pool