def mean_functional_workflow(workflow, resource_pool, config): # resource pool should have: # func_motion_correct ''' this version does NOT remove background noise ''' 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, "func_motion_correct") #check_input_resources(resource_pool, "functional_brain_mask") if "func_motion_correct" not in resource_pool.keys(): from functional_preproc import func_motion_correct_workflow workflow, resource_pool = \ func_motion_correct_workflow(workflow, resource_pool, config) func_mean_skullstrip = pe.Node(interface=preprocess.TStat(), name='func_mean_skullstrip') func_mean_skullstrip.inputs.options = '-mean' func_mean_skullstrip.inputs.outputtype = 'NIFTI_GZ' if len(resource_pool["func_motion_correct"]) == 2: node, out_file = resource_pool["func_motion_correct"] workflow.connect(node, out_file, func_mean_skullstrip, 'in_file')#func_edge_detect, 'in_file_a') else: func_mean_skullstrip.inputs.in_file = \ resource_pool["func_motion_correct"] resource_pool["mean_functional"] = (func_mean_skullstrip, 'out_file') return workflow, resource_pool
def mean_functional_workflow(workflow, resource_pool, config): # resource pool should have: # func_motion_correct ''' this version does NOT remove background noise ''' 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, "func_motion_correct") #check_input_resources(resource_pool, "functional_brain_mask") if "func_motion_correct" not in resource_pool.keys(): from functional_preproc import func_motion_correct_workflow workflow, resource_pool = \ func_motion_correct_workflow(workflow, resource_pool, config) func_mean_skullstrip = pe.Node(interface=preprocess.TStat(), name='func_mean_skullstrip') func_mean_skullstrip.inputs.options = '-mean' func_mean_skullstrip.inputs.outputtype = 'NIFTI_GZ' if len(resource_pool["func_motion_correct"]) == 2: node, out_file = resource_pool["func_motion_correct"] workflow.connect(node, out_file, func_mean_skullstrip, 'in_file') #func_edge_detect, 'in_file_a') else: func_mean_skullstrip.inputs.in_file = \ resource_pool["func_motion_correct"] resource_pool["mean_functional"] = (func_mean_skullstrip, 'out_file') return workflow, resource_pool
def functional_brain_mask_workflow(workflow, resource_pool, config): # resource pool should have: # func_motion_correct 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 as fsl from nipype.interfaces.afni import preprocess #check_input_resources(resource_pool, "func_motion_correct") if "use_bet" not in config.keys(): config["use_bet"] = False if "func_motion_correct" not in resource_pool.keys(): from functional_preproc import func_motion_correct_workflow workflow, resource_pool = \ func_motion_correct_workflow(workflow, resource_pool, config) if config["use_bet"] == False: func_get_brain_mask = pe.Node(interface=preprocess.Automask(), name='func_get_brain_mask') func_get_brain_mask.inputs.outputtype = 'NIFTI_GZ' else: func_get_brain_mask = pe.Node(interface=fsl.BET(), name='func_get_brain_mask_BET') func_get_brain_mask.inputs.mask = True func_get_brain_mask.inputs.functional = True erode_one_voxel = pe.Node(interface=fsl.ErodeImage(), name='erode_one_voxel') erode_one_voxel.inputs.kernel_shape = 'box' erode_one_voxel.inputs.kernel_size = 1.0 #if isinstance(tuple, resource_pool["func_motion_correct"]): if len(resource_pool["func_motion_correct"]) == 2: node, out_file = resource_pool["func_motion_correct"] workflow.connect(node, out_file, func_get_brain_mask, 'in_file') else: func_get_brain_mask.inputs.in_file = \ resource_pool["func_motion_correct"] if config["use_bet"] == False: resource_pool["functional_brain_mask"] = (func_get_brain_mask, \ 'out_file') else: workflow.connect(func_get_brain_mask, 'mask_file', erode_one_voxel, 'in_file') resource_pool["functional_brain_mask"] = (erode_one_voxel, 'out_file') return workflow, resource_pool
def run_func_motion_correct(functional_scan, start_idx, stop_idx, slice_timing_correction=False, run=True): # stand-alone runner for functional motion correct workflow import os import sys import glob import nipype.interfaces.io as nio import nipype.pipeline.engine as pe workflow = pe.Workflow(name='func_motion_correct_workflow') current_dir = os.getcwd() workflow_dir = os.path.join(current_dir, "func_motion_correct") workflow.base_dir = workflow_dir resource_pool = {} config = {} num_cores_per_subject = 1 resource_pool["functional_scan"] = functional_scan config["start_idx"] = start_idx config["stop_idx"] = stop_idx config["slice_timing_correction"] = slice_timing_correction workflow, resource_pool = \ func_motion_correct_workflow(workflow, resource_pool, config) ds = pe.Node(nio.DataSink(), name='datasink_func_motion_correct') ds.inputs.base_directory = workflow_dir node, out_file = resource_pool["func_motion_correct"] workflow.connect(node, out_file, ds, 'func_motion_correct') ds = pe.Node(nio.DataSink(), name='datasink_coordinate_transformation') ds.inputs.base_directory = workflow_dir node, out_file = resource_pool["coordinate_transformation"] workflow.connect(node, out_file, ds, 'coordinate_transformation') if run == True: workflow.run(plugin='MultiProc', plugin_args= \ {'n_procs': num_cores_per_subject}) outpath = glob.glob(os.path.join(workflow_dir, "func_motion_correct",\ "*"))[0] return outpath else: return workflow, workflow.base_dir
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 util from qap_workflows_utils import qap_functional_temporal, write_to_csv """ 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) temporal = pe.Node( util.Function( input_names=[ "func_motion_correct", "func_brain_mask", "coord_xfm_matrix", "subject_id", "session_id", "scan_id", "site_name", ], output_names=["qc"], function=qap_functional_temporal, ), name="qap_functional_temporal", ) temporal_to_csv = pe.Node( util.Function(input_names=["sub_qap_dict"], output_names=["outfile"], function=write_to_csv), name="qap_functional_temporal_to_csv", ) if len(resource_pool["func_motion_correct"]) == 2: node, out_file = resource_pool["func_motion_correct"] workflow.connect(node, out_file, temporal, "func_motion_correct") else: temporal.inputs.func_motion_correct = resource_pool["func_motion_correct"] 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"] if "mcflirt_rel_rms" in resource_pool.keys(): temporal.inputs.coord_xfm_matrix = 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, temporal, "coord_xfm_matrix") else: temporal.inputs.coord_xfm_matrix = resource_pool["coordinate_transformation"] # Subject infos temporal.inputs.subject_id = config["subject_id"] temporal.inputs.session_id = config["session_id"] temporal.inputs.scan_id = config["scan_id"] if "site_name" in config.keys(): temporal.inputs.site_name = config["site_name"] workflow.connect(temporal, "qc", temporal_to_csv, "sub_qap_dict") resource_pool["qap_functional_temporal"] = (temporal_to_csv, "outfile") 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