Source code for PUMI.pipelines.multimodal.image_manipulation

from PUMI.engine import NestedNode as Node, QcPipeline
from PUMI.engine import FuncPipeline


# To extract voxels 10 to 12 inclusive you would specify 10 and 3 (not 10 and 12).

[docs]@FuncPipeline(inputspec_fields=['in_file'], outputspec_fields=['out_file']) def pick_volume(wf, volume='middle', **kwargs): """ Sub-Workflow that deals with extracting a 3D-volume choosen by the user from a functional 4D-Sequence Parameters: wf(str): Name of the workflow. volume(str): The volume specified by the user. - Possible Values : (first | middle | last | mean | arbitrary number). - In case no value was given, the first volume will be returned. - In case of a non-valid value, a ValueException will be thrown. Returns: wf(Workflow): The sub-workflow itself. """ from nipype.interfaces.fsl import ImageMaths from PUMI.engine import Node import nipype.interfaces.fsl as fsl from nipype import Function # Basic interface which get the start index, from which the slicing begins img_4d_info = Node(Function(input_names=['in_file', 'volume'], output_names=['start_idx'], function=get_info), name='img_4d_info') img_4d_info.inputs.volume = volume mean = False fslroi = None img_mean = None if volume == 'mean': img_mean = Node(ImageMaths(op_string='-Tmean'), name='img_mean_node') mean = True else: fslroi = Node(fsl.ExtractROI(), name='fslroi') fslroi.inputs.t_size = 1 if mean: wf.connect('inputspec', 'in_file', img_mean, 'in_file') wf.connect(img_mean, 'out_file', 'sinker', 'out_file') wf.connect(img_mean, 'out_file', 'outputspec', 'out_file') else: wf.connect('inputspec', 'in_file', img_4d_info, 'in_file') wf.connect('inputspec', 'in_file', fslroi, 'in_file') wf.connect(img_4d_info, 'start_idx', fslroi, 't_min') wf.connect(fslroi, 'roi_file', 'sinker', 'out_file') wf.connect(fslroi, 'roi_file', 'outputspec', 'out_file')
[docs]def get_info(in_file, volume='first'): """ Adapted from C-PAC (https://github.com/FCP-INDI/C-PAC) Function to get the right index, from which the slicing requested by the user, starts. - In case no value was given, the first volume will be returned. - In case of a non-valid value, a ValueException will be thrown. - Beaware : This function will be called only if the volume != 'mean' Parameters: in_file(str): Path to input functional run. volume(str): The volume specified by the user. Possible Values: (first | middle | last | mean | arbitrary number) Returns: start_idx (integer): The index in the 4d-sequence, from which we start slicing. """ from nibabel import load from nipype import Function from nipype.interfaces import fsl # Init variables img = load(in_file) shape = img.shape # Check to make sure the input file is 4-dimensional if len(shape) != 4: print('Warning: NOT A 3D VOLUME!') return 0 # Grab the maximum number of volumes in the 4d-img vol_count = img.shape[3] # check which volume the user want start_idx = 0 if volume == 'first': return start_idx elif volume == 'middle': start_idx = round(vol_count / 2) elif volume == 'last': start_idx = vol_count - 1 # User wants a specific volume elif volume.isdigit() and vol_count > int(volume) > 0: start_idx = int(volume) - 1 else: raise ValueError('{} is a non-valid value for the Parameter volume \nPossible values : first / middle / last ' '/ mean / arbitrary number'.format(volume)) return start_idx
[docs]@QcPipeline(inputspec_fields=['bg_image', 'overlay_image'], outputspec_fields=['out_file']) def vol2png(wf, overlay=True, **kwargs): """ # Todo Docs """ from nipype.interfaces import fsl slicer = Node(interface=fsl.Slicer(), name='slicer') slicer.inputs.image_width = 2000 slicer.inputs.sample_axial = 5 # set output all axial slices into one picture wf.connect('inputspec', 'bg_image', slicer, 'in_file') if overlay: wf.connect('inputspec', 'overlay_image', slicer, 'image_edges') wf.connect(slicer, 'out_file', 'outputspec', 'out_file')
[docs]@QcPipeline(inputspec_fields=['func', 'mask', 'x', 'y', 'z'], outputspec_fields=['out_file']) def timecourse2png(wf, plot_type='all', sink=True, **kwargs): """ plot_type: 'all': nothing to specify, will input everything greater than zero 'vox': use 'x', 'y', 'z' fields for voxel then 'roi': use 'mask' for roi """ from PUMI.engine import Node import nipype.pipeline as pe import nipype.interfaces.fsl as fsl from nipype import Function if plot_type == 'all': vox_roi = Node(fsl.ImageMaths(), name='vox_roi') def set_inputs(x, y, z): return '-roi '\ + str(x) + ' 1 '\ + str(y) + ' 1 '\ + str(z) + ' 1 0 -1 -bin' voxroi_args = pe.Node( Function( input_names=['x', 'y', 'z'], output_names=['args'], function=set_inputs), name="voxroi_args") elif plot_type == 'all': vox_roi = Node(fsl.ImageMaths(op_string= '-bin'), name='vox_roi') mean_ts = Node(fsl.ImageMeants(), name='mean_ts') plottimeser = Node(fsl.PlotTimeSeries(), name='plottimeser') if plot_type == 'vox': wf.connect('inputspec', 'func', vox_roi, 'in_file') wf.connect('inputspec', 'x', voxroi_args, 'x') wf.connect('inputspec', 'y', voxroi_args, 'y') wf.connect('inputspec', 'z', voxroi_args, 'z') wf.connect(voxroi_args, 'args', vox_roi, 'args') wf.connect(vox_roi, 'out_file', mean_ts, 'mask') elif plot_type == 'all': wf.connect('inputspec', 'func', vox_roi, 'in_file') wf.connect(vox_roi, 'out_file', mean_ts, 'mask') elif plot_type == 'roi': wf.connect('inputspec', 'mask', mean_ts, 'mask') wf.connect('inputspec', 'func', mean_ts, 'in_file') wf.connect(mean_ts, 'out_file', plottimeser, 'in_file') wf.connect(plottimeser, 'out_file', 'outputspec', 'out_file')