def test_applymask(): masker = fs.ApplyMask() filelist, testdir, origdir = create_files_in_directory() # Test underlying command yield assert_equal, masker.cmd, "mri_mask" # Test exception with mandatory args absent yield assert_raises, ValueError, masker.run for input in ["in_file", "mask_file"]: indict = {input: filelist[0]} willbreak = fs.ApplyMask(**indict) yield assert_raises, ValueError, willbreak.run # Now test a basic command line masker.inputs.in_file = filelist[0] masker.inputs.mask_file = filelist[1] outfile = os.path.join(testdir, "a_masked.nii") yield assert_equal, masker.cmdline, "mri_mask a.nii b.nii %s" % outfile # Now test that optional inputs get formatted properly masker.inputs.mask_thresh = 2 yield assert_equal, masker.cmdline, "mri_mask -T 2.0000 a.nii b.nii %s" % outfile masker.inputs.use_abs = True yield assert_equal, masker.cmdline, "mri_mask -T 2.0000 -abs a.nii b.nii %s" % outfile # Now clean up clean_directory(testdir, origdir)
def mrtrix_dti(name='MRTrix_DTI'): """ A workflow for DTI reconstruction using the tensor fitting included with MRTrix. :inputs: * in_dwi: the input dMRI volume to be reconstructed * in_bvec: b-vectors file in FSL format * in_bval: b-values file in FSL format * in_mask: input whole-brain mask (dwi space) """ from nipype.pipeline import engine as pe from nipype.interfaces import utility as niu from nipype.interfaces import mrtrix as mrt from nipype.interfaces import freesurfer as fs inputnode = pe.Node(niu.IdentityInterface( fields=['in_bvec', 'in_bval', 'in_dwi', 'in_mask']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['fa', 'md']), name='outputnode') fsl2mrtrix = pe.Node(mrt.FSL2MRTrix(), name='fsl2mrtrix') dwi2tsr = pe.Node(mrt.DWI2Tensor(), name='DWI2Tensor') tsr2fa = pe.Node(mrt.Tensor2FractionalAnisotropy(), name='ComputeFA') fa2nii = pe.Node(mrt.MRConvert(extension='nii'), 'FA2Nifti') msk_fa = pe.Node(fs.ApplyMask(), name='MaskFA') tsr2adc = pe.Node(mrt.Tensor2ApparentDiffusion(), name='ComputeADC') adc2nii = pe.Node(mrt.MRConvert(extension='nii'), 'ADC2Nifti') msk_adc = pe.Node(fs.ApplyMask(), name='MaskADC') wf = pe.Workflow(name=name) wf.connect([ (inputnode, fsl2mrtrix, [('in_bvec', 'bvec_file'), ('in_bval', 'bval_file')]), (inputnode, dwi2tsr, [('in_dwi', 'in_file')]), (inputnode, msk_fa, [('in_mask', 'mask_file')]), (inputnode, msk_adc, [('in_mask', 'mask_file')]), (fsl2mrtrix, dwi2tsr, [('encoding_file', 'encoding_file')]), (dwi2tsr, tsr2fa, [('tensor', 'in_file')]), (tsr2fa, fa2nii, [('FA', 'in_file')]), (fa2nii, msk_fa, [('converted', 'in_file')]), (dwi2tsr, tsr2adc, [('tensor', 'in_file')]), (tsr2adc, adc2nii, [('ADC', 'in_file')]), (adc2nii, msk_adc, [('converted', 'in_file')]), (msk_fa, outputnode, [('out_file', 'fa')]), (msk_adc, outputnode, [('out_file', 'md')]) ]) return wf
def make_freesurfer(self): # Ref: http://nipype.readthedocs.io/en/1.0.4/interfaces/generated/interfaces.freesurfer/preprocess.html#reconall fs_recon1 = Node(interface=fs.ReconAll(directive='autorecon1', mris_inflate='-n 15', hires=True, mprage=True, openmp=self.omp_nthreads), name='fs_recon1', n_procs=self.omp_nthreads) fs_mriconv = Node(interface=fs.MRIConvert(out_type='mgz'), name='fs_mriconv') fs_vol2vol = Node(interface=fs.ApplyVolTransform(mni_152_reg=True), name='fs_vol2vol') fs_mrimask = Node(interface=fs.ApplyMask(), name='fs_mrimask') fs_recon2 = Node(interface=fs.ReconAll(directive='autorecon2', hires=True, mprage=True, hippocampal_subfields_T1=False, openmp=self.omp_nthreads), name='fs_recon2', n_procs=self.omp_nthreads) fs_recon3 = Node(interface=fs.ReconAll(directive='autorecon3', hires=True, mprage=True, hippocampal_subfields_T1=False, openmp=self.omp_nthreads), name='fs_recon3', n_procs=self.omp_nthreads) copy_brainmask = Node(Function(['in_file', 'fs_dir'], ['fs_dir'], self.copy_mask), name='copy_brainmask') segment_hp = Node(interface=SegmentHA_T1(), name='segment_hp') freesurfer = Workflow(name='freesurfer', base_dir=self.temp_dir) freesurfer.connect(fs_recon1, 'T1', fs_vol2vol, 'target_file') freesurfer.connect(fs_mriconv, 'out_file', fs_vol2vol, 'source_file') freesurfer.connect(fs_recon1, 'T1', fs_mrimask, 'in_file') freesurfer.connect(fs_vol2vol, 'transformed_file', fs_mrimask, 'mask_file') freesurfer.connect(fs_mrimask, 'out_file', copy_brainmask, 'in_file') freesurfer.connect(fs_recon1, 'subjects_dir', copy_brainmask, 'fs_dir') freesurfer.connect(copy_brainmask, 'fs_dir', fs_recon2, 'subjects_dir') freesurfer.connect(fs_recon2, 'subjects_dir', fs_recon3, 'subjects_dir') freesurfer.connect(fs_recon3, 'subjects_dir', segment_hp, 'subjects_dir') return freesurfer
def ants_getmask(name): import nipype.interfaces.fsl as fsl import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu import nipype.interfaces.ants as ants import nipype.interfaces.freesurfer as fs wf = pe.Workflow(name=name) inputspec = pe.Node( niu.IdentityInterface(fields=['functional', 'structural']), name='inputspec') bet = pe.Node(fsl.BET(mask=True, remove_eyes=True), name='bet') applymask = pe.Node(fs.ApplyMask(), name='applymask') #flirt = pe.Node(fsl.FLIRT(),name='flirt') #applyxfm_mask = pe.Node(fsl.ApplyXfm(interp='nearestneighbour',apply_xfm=True),name='applyxfm_mask') #applyxfm_seg = pe.MapNode(fsl.ApplyXfm(interp='nearestneighbour',apply_xfm=True),name='applyxfm_seg',iterfield=['in_file']) dilate = pe.Node(fsl.DilateImage(operation='mean'), name='dilate') atropos = pe.Node(ants.Atropos(initialization='KMeans', number_of_tissue_classes=3, dimension=3), name='atropos') n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='n4corrections') outputspec = pe.Node(niu.IdentityInterface( fields=['mask', 'reg_file', 'segments', 'warped_struct']), name='outputspec') #create brain mask wf.connect(inputspec, "structural", bet, "in_file") #dilate bets mask a bit for atropos wf.connect(bet, "mask_file", dilate, "in_file") # apply dilated mask to img wf.connect(dilate, 'out_file', applymask, 'mask_file') wf.connect(inputspec, 'structural', applymask, 'in_file') #N4 bias correction wf.connect(applymask, "out_file", n4, 'input_image') # atropos it wf.connect(n4, "output_image", atropos, 'intensity_images') wf.connect(dilate, 'out_file', atropos, 'mask_image') return wf
def create_custom_template(c): import nipype.pipeline.engine as pe #from nipype.interfaces.ants import BuildTemplate import nipype.interfaces.io as nio import nipype.interfaces.utility as niu import nipype.interfaces.freesurfer as fs wf = pe.Workflow(name='create_fs_masked_brains') #temp = pe.Node(BuildTemplate(parallelization=1), name='create_template') fssource = pe.Node(nio.FreeSurferSource(subjects_dir=c.surf_dir), name='fssource') infosource = pe.Node(niu.IdentityInterface(fields=["subject_id"]), name="subject_names") infosource.iterables = ("subject_id", c.subjects) wf.connect(infosource, "subject_id", fssource, "subject_id") sink = pe.Node(nio.DataSink(base_directory=c.sink_dir), name='sinker') applymask = pe.Node(fs.ApplyMask(mask_thresh=0.5), name='applymask') binarize = pe.Node(fs.Binarize(dilate=1, min=0.5, subjects_dir=c.surf_dir), name='binarize') convert = pe.Node(fs.MRIConvert(out_type='niigz'), name='convert') wf.connect(fssource, 'orig', applymask, 'in_file') wf.connect(fssource, ('aparc_aseg', pickaparc), binarize, 'in_file') wf.connect(binarize, 'binary_file', applymask, 'mask_file') wf.connect(applymask, 'out_file', convert, 'in_file') wf.connect(convert, "out_file", sink, "masked_images") def getsubs(subject_id): subs = [] subs.append(('_subject_id_%s/' % subject_id, '%s_' % subject_id)) return subs wf.connect(infosource, ("subject_id", getsubs), sink, "substitutions") #wf.connect(convert,'out_file',temp,'in_files') #wf.connect(temp,'final_template_file',sink,'custom_template.final_template_file') #wf.connect(temp,'subject_outfiles',sink,'custom_template.subject_outfiles') #wf.connect(temp,'template_files',sink,'template_files') return wf
def create_skullstrip_workflow(name="skullstrip"): """Remove non-brain voxels from the timeseries.""" # Define the workflow inputs inputnode = Node( IdentityInterface(["subject_id", "timeseries", "reg_file"]), "inputs") # Mean the timeseries across the fourth dimension origmean = MapNode(fsl.MeanImage(), "in_file", "origmean") # Grab the Freesurfer aparc+aseg file as an anatomical brain mask getaseg = Node( io.SelectFiles({"aseg": "{subject_id}/mri/aparc+aseg.mgz"}, base_directory=os.environ["SUBJECTS_DIR"]), "getaseg") # Threshold the aseg volume to get a boolean mask makemask = Node(fs.Binarize(dilate=4, min=0.5), "makemask") # Transform the brain mask into functional space transform = MapNode(fs.ApplyVolTransform(inverse=True, interp="nearest"), ["reg_file", "source_file"], "transform") # Convert the mask to nifti and rename convertmask = MapNode(fs.MRIConvert(out_file="functional_mask.nii.gz"), "in_file", "convertmask") # Use the mask to skullstrip the timeseries stripts = MapNode(fs.ApplyMask(), ["in_file", "mask_file"], "stripts") # Use the mask to skullstrip the mean image stripmean = MapNode(fs.ApplyMask(), ["in_file", "mask_file"], "stripmean") # Generate images summarizing the skullstrip and resulting data reportmask = MapNode(MaskReport(), ["mask_file", "orig_file", "mean_file"], "reportmask") # Define the workflow outputs outputnode = Node( IdentityInterface(["timeseries", "mean_file", "mask_file", "report"]), "outputs") # Define and connect the workflow skullstrip = Workflow(name) skullstrip.connect([ (inputnode, origmean, [("timeseries", "in_file")]), (inputnode, getaseg, [("subject_id", "subject_id")]), (origmean, transform, [("out_file", "source_file")]), (getaseg, makemask, [("aseg", "in_file")]), (makemask, transform, [("binary_file", "target_file")]), (inputnode, transform, [("reg_file", "reg_file")]), (transform, stripts, [("transformed_file", "mask_file")]), (transform, stripmean, [("transformed_file", "mask_file")]), (inputnode, stripts, [("timeseries", "in_file")]), (origmean, stripmean, [("out_file", "in_file")]), (stripmean, reportmask, [("out_file", "mean_file")]), (origmean, reportmask, [("out_file", "orig_file")]), (transform, reportmask, [("transformed_file", "mask_file")]), (transform, convertmask, [("transformed_file", "in_file")]), (stripts, outputnode, [("out_file", "timeseries")]), (stripmean, outputnode, [("out_file", "mean_file")]), (convertmask, outputnode, [("out_file", "mask_file")]), (reportmask, outputnode, [("out_files", "report")]), ]) return skullstrip
def define_template_workflow(info, subjects, qc=True): # --- Workflow parameterization subject_source = Node(IdentityInterface(["subject"]), name="subject_source", iterables=("subject", subjects)) # Data input template_input = Node(TemplateInput(data_dir=info.data_dir), "template_input") # --- Definition of functional template space crop_image = Node(fs.ApplyMask(args="-bb 4"), "crop_image") zoom_image = Node(fs.MRIConvert(resample_type="cubic", out_type="niigz", vox_size=info.voxel_size, ), "zoom_image") reorient_image = Node(fsl.Reorient2Std(out_file="anat.nii.gz"), "reorient_image") generate_reg = Node(fs.Tkregister2(fsl_out="anat2func.mat", reg_file="anat2func.dat", reg_header=True), "generate_reg") invert_reg = Node(fs.Tkregister2(reg_file="func2anat.dat", reg_header=True), "invert_reg") # --- Identification of surface vertices hemi_source = Node(IdentityInterface(["hemi"]), "hemi_source", iterables=("hemi", ["lh", "rh"])) tag_surf = Node(fs.Surface2VolTransform(surf_name="graymid", transformed_file="ribbon.nii.gz", vertexvol_file="vertices.nii.gz", mkmask=True), "tag_surf") mask_cortex = Node(MaskWithLabel(fill_value=-1), "mask_cortex") combine_hemis = JoinNode(fsl.Merge(dimension="t", merged_file="surf.nii.gz"), name="combine_hemis", joinsource="hemi_source", joinfield="in_files") make_ribbon = Node(MakeRibbon(), "make_ribbon") # --- Segementation of anatomical tissue in functional space transform_wmparc = Node(fs.ApplyVolTransform(inverse=True, interp="nearest", args="--keep-precision"), "transform_wmparc") anat_segment = Node(AnatomicalSegmentation(), "anat_segment") # --- Template QC template_qc = Node(TemplateReport(), "template_qc") # --- Workflow ouptut save_info = Node(SaveInfo(info_dict=info.trait_get()), "save_info") template_output = Node(DataSink(base_directory=info.proc_dir, parameterization=False), "template_output") # === Assemble pipeline workflow = Workflow(name="template", base_dir=info.cache_dir) processing_edges = [ (subject_source, template_input, [("subject", "subject")]), (template_input, crop_image, [("norm_file", "in_file"), ("wmparc_file", "mask_file")]), (crop_image, zoom_image, [("out_file", "in_file")]), (zoom_image, reorient_image, [("out_file", "in_file")]), (subject_source, generate_reg, [("subject", "subject_id")]), (template_input, generate_reg, [("norm_file", "moving_image")]), (reorient_image, generate_reg, [("out_file", "target_image")]), (subject_source, invert_reg, [("subject", "subject_id")]), (template_input, invert_reg, [("norm_file", "target_image")]), (reorient_image, invert_reg, [("out_file", "moving_image")]), (hemi_source, tag_surf, [("hemi", "hemi")]), (invert_reg, tag_surf, [("reg_file", "reg_file")]), (reorient_image, tag_surf, [("out_file", "template_file")]), (template_input, mask_cortex, [("label_files", "label_files")]), (hemi_source, mask_cortex, [("hemi", "hemi")]), (tag_surf, mask_cortex, [("vertexvol_file", "in_file")]), (mask_cortex, combine_hemis, [("out_file", "in_files")]), (combine_hemis, make_ribbon, [("merged_file", "in_file")]), (reorient_image, transform_wmparc, [("out_file", "source_file")]), (template_input, transform_wmparc, [("wmparc_file", "target_file")]), (invert_reg, transform_wmparc, [("reg_file", "reg_file")]), (reorient_image, anat_segment, [("out_file", "anat_file")]), (transform_wmparc, anat_segment, [("transformed_file", "wmparc_file")]), (combine_hemis, anat_segment, [("merged_file", "surf_file")]), (template_input, template_output, [("output_path", "container")]), (reorient_image, template_output, [("out_file", "@anat")]), (generate_reg, template_output, [("fsl_file", "@anat2func")]), (anat_segment, template_output, [("seg_file", "@seg"), ("lut_file", "@lut"), ("edge_file", "@edge"), ("mask_file", "@mask")]), (combine_hemis, template_output, [("merged_file", "@surf")]), (make_ribbon, template_output, [("out_file", "@ribon")]), ] workflow.connect(processing_edges) # Optionally connect QC nodes qc_edges = [ (reorient_image, template_qc, [("out_file", "anat_file")]), (combine_hemis, template_qc, [("merged_file", "surf_file")]), (anat_segment, template_qc, [("lut_file", "lut_file"), ("seg_file", "seg_file"), ("edge_file", "edge_file"), ("mask_file", "mask_file")]), (subject_source, save_info, [("subject", "parameterization")]), (save_info, template_output, [("info_file", "qc.@info_json")]), (template_qc, template_output, [("seg_plot", "qc.@seg_plot"), ("mask_plot", "qc.@mask_plot"), ("edge_plot", "qc.@edge_plot"), ("surf_plot", "qc.@surf_plot"), ("anat_plot", "qc.@anat_plot")]), ] if qc: workflow.connect(qc_edges) return workflow
def localizer(name='localizer'): import nipype.interfaces.freesurfer as fs import nipype.interfaces.fsl as fsl import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu import nipype.interfaces.io as nio wf = pe.Workflow(name=name) inputspec = pe.Node(niu.IdentityInterface(fields=["subject_id", "subjects_dir", "overlay", 'reg', 'mean', 'thresh', 'roi', "mask_overlay", "use_mask_overlay","uthresh"]),name='inputspec') surf_label = pe.MapNode(niu.Function(input_names=['vertex', 'hemi', 'subject', 'overlay', 'reg', 'sd', 'thresh'], output_names=['filename','labels'], function=get_surface_label), name='get_surface_label', iterfield=['hemi','vertex']) surf_label.inputs.hemi=['lh','rh'] #surf_label.inputs.vertex = [61091, 60437] #surf_label.inputs.thresh = 1.5 masker = pe.Node(niu.Function(input_names=['mask', 'overlay', 'use_mask_overlay', 'thresh'], output_names=['outfile'],function=mask_overlay), name='mask_overlay') bg = pe.Node(niu.Function(input_names=['overlay','uthresh'],output_names=['outfile'],function=background),name='background') wf.connect(inputspec,'overlay',bg,'overlay') wf.connect(inputspec,'uthresh',bg,'uthresh') wf.connect(inputspec,'overlay',masker,'overlay') wf.connect(inputspec,'mask_overlay',masker,'mask') wf.connect(inputspec,'use_mask_overlay',masker,'use_mask_overlay') wf.connect(inputspec,'thresh',masker,'thresh') wf.connect(masker,'outfile',surf_label,'overlay') wf.connect(inputspec,"subject_id",surf_label,"subject") wf.connect(inputspec,"subjects_dir",surf_label,"sd") #wf.connect(inputspec,"overlay",surf_label,"overlay") wf.connect(inputspec,"reg",surf_label,"reg") label2vol = pe.Node(fs.Label2Vol(),name='labels2vol') wf.connect(inputspec,'subjects_dir',label2vol,'subjects_dir') wf.connect(inputspec,'mean',label2vol,'template_file') wf.connect(inputspec,'reg',label2vol,'reg_file') wf.connect(surf_label,'filename',label2vol,'label_file') verts = pe.MapNode(niu.Function(input_names=['sub', 'sd', 'overlay', 'reg', 'mean', 'hemi', 'roi', 'thresh'], output_names=['vertex'], function=get_vertices), name='get_verts',iterfield=['hemi']) verts.inputs.hemi = ['lh','rh'] wf.connect(inputspec,'subject_id',verts,'sub') wf.connect(inputspec,'subjects_dir',verts,'sd') #wf.connect(inputspec,'overlay',verts,'overlay') wf.connect(masker,'outfile',verts,'overlay') wf.connect(inputspec,'reg',verts,'reg') wf.connect(inputspec,'mean',verts,'mean') wf.connect(inputspec,'thresh',verts,'thresh') wf.connect(inputspec,'roi',verts,'roi') wf.connect(verts,'vertex',surf_label,'vertex') wf.connect(inputspec,'thresh',surf_label,'thresh') from ...smri.freesurfer_brain_masks import pickaparc fssource = pe.Node(nio.FreeSurferSource(),name='fssource') wf.connect(inputspec,"subjects_dir",fssource,"subjects_dir") wf.connect(inputspec,"subject_id", fssource,"subject_id") bg_mask = pe.Node(fs.Binarize(wm_ven_csf=True, erode=2),name="bg_mask") wf.connect(fssource,("aparc_aseg",pickaparc),bg_mask,"in_file") warp_mask = pe.Node(fs.ApplyVolTransform(inverse=True,interp='nearest'),name="warp_to_func") wf.connect(inputspec,"mean",warp_mask,"source_file") wf.connect(bg_mask,"binary_file",warp_mask,"target_file") wf.connect(inputspec,"reg", warp_mask,"reg_file") do_bg_mask = pe.Node(fs.ApplyMask(),name="do_bg_mask") wf.connect(warp_mask,"transformed_file",do_bg_mask,"mask_file") studyref = pe.Node(niu.Function(input_names=['mean'],output_names=['study_ref'], function=study_ref),name='studyref') wf.connect(inputspec,'mean',studyref,'mean') outputspec = pe.Node(niu.IdentityInterface(fields=['rois','reference','study_ref','labels']),name='outputspec') wf.connect(studyref,'study_ref', outputspec, 'study_ref') bin = pe.Node(fsl.ImageMaths(op_string = '-bin'),name="binarize_roi") changetype = pe.Node(fsl.ChangeDataType(output_datatype='short'),name='to_short') wf.connect(bg,'outfile',do_bg_mask,"in_file") wf.connect(do_bg_mask,("out_file",shorty), outputspec,'reference') wf.connect(label2vol,'vol_label_file',bin,'in_file') wf.connect(bin,'out_file', changetype, 'in_file') wf.connect(changetype, 'out_file', outputspec, 'rois') wf.connect(surf_label,'labels',outputspec,'labels') return wf
def sdc_t2b(name='SDC_T2B', icorr=True, num_threads=1): """ The T2w-registration based method (T2B) implements an SDC by nonlinear registration of the anatomically correct *T2w* image to the *b0* image of the *dMRI* dataset. The implementation here tries to reproduce the one included in ExploreDTI `(Leemans et al., 2009) <http://www.exploredti.com/ref/ExploreDTI_ISMRM_2009.pdf>`_, which is also used by `(Irfanoglu et al., 2012) <http://dx.doi.org/10.1016/j.neuroimage.2012.02.054>`_. :param str name: a unique name for the workflow. :inputs: * in_t2w: the reference T2w image :outputs: * outputnode.corrected_image: the dMRI image after correction Example:: >>> t2b = sdc_t2b() >>> t2b.inputs.inputnode.in_dwi = 'dwi_brain.nii' >>> t2b.inputs.inputnode.in_bval = 'dwi.bval' >>> t2b.inputs.inputnode.in_mask = 'b0_mask.nii' >>> t2b.inputs.inputnode.in_t2w = 't2w_brain.nii' >>> t2b.inputs.inputnode.in_param = 'parameters.txt' >>> t2b.run() # doctest: +SKIP """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_dwi', 'in_bval', 'in_t2w', 'dwi_mask', 't2w_mask', 'in_param', 'in_surf']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['dwi', 'dwi_mask', 'out_surf']), name='outputnode') avg_b0 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='AverageB0') n4_b0 = pe.Node(N4BiasFieldCorrection(dimension=3), name='BiasB0') n4_t2 = pe.Node(N4BiasFieldCorrection(dimension=3), name='BiasT2') getparam = pe.Node(nio.JSONFileGrabber(defaults={'enc_dir': 'y'}), name='GetEncDir') reg = pe.Node(nex.Registration(num_threads=1), name='Elastix') tfx_b0 = pe.Node(nex.EditTransform(), name='tfm_b0') split_dwi = pe.Node(fsl.utils.Split(dimension='t'), name='split_dwi') warp = pe.MapNode(nex.ApplyWarp(), iterfield=['moving_image'], name='UnwarpDWIs') warp_prop = pe.Node(nex.AnalyzeWarp(), name='DisplFieldAnalysis') warpbuff = pe.Node(niu.IdentityInterface(fields=['unwarped']), name='UnwarpedCache') mskdwis = pe.MapNode(fs.ApplyMask(), iterfield='in_file', name='MaskDWIs') thres = pe.MapNode(Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegs') merge_dwi = pe.Node(fsl.utils.Merge(dimension='t'), name='merge_dwis') tfx_msk = pe.Node(nex.EditTransform( interpolation='nearest', output_type='unsigned char'), name='MSKInterpolator') corr_msk = pe.Node(nex.ApplyWarp(), name='UnwarpMsk') closmsk = pe.Node(fsl.maths.MathsCommand( nan2zeros=True, args='-kernel sphere 3 -dilM -kernel sphere 2 -ero'), name='MaskClosing') swarp = pe.MapNode(nex.PointsWarp(), iterfield=['points_file'], name='UnwarpSurfs') wf = pe.Workflow(name=name) wf.connect([ (inputnode, avg_b0, [('in_dwi', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, getparam, [('in_param', 'in_file')]), (inputnode, split_dwi, [('in_dwi', 'in_file')]), (inputnode, corr_msk, [('dwi_mask', 'moving_image')]), (inputnode, swarp, [('in_surf', 'points_file')]), (inputnode, reg, [('t2w_mask', 'fixed_mask'), ('dwi_mask', 'moving_mask')]), (inputnode, n4_t2, [('in_t2w', 'input_image'), ('t2w_mask', 'mask_image')]), (inputnode, n4_b0, [('dwi_mask', 'mask_image')]), (avg_b0, n4_b0, [('out_file', 'input_image')]), (getparam, reg, [ (('enc_dir', _default_params), 'parameters')]), (n4_t2, reg, [('output_image', 'fixed_image')]), (n4_b0, reg, [('output_image', 'moving_image')]), (reg, tfx_b0, [ (('transform', _get_last), 'transform_file')]), (avg_b0, tfx_b0, [('out_file', 'reference_image')]), (tfx_b0, warp_prop, [('output_file', 'transform_file')]), (tfx_b0, warp, [('output_file', 'transform_file')]), (split_dwi, warp, [('out_files', 'moving_image')]), (warpbuff, mskdwis, [('unwarped', 'in_file')]), (closmsk, mskdwis, [('out_file', 'mask_file')]), (mskdwis, thres, [('out_file', 'in_file')]), (thres, merge_dwi, [('out_file', 'in_files')]), (reg, tfx_msk, [ (('transform', _get_last), 'transform_file')]), (tfx_b0, swarp, [('output_file', 'transform_file')]), (avg_b0, tfx_msk, [('out_file', 'reference_image')]), (tfx_msk, corr_msk, [('output_file', 'transform_file')]), (corr_msk, closmsk, [('warped_file', 'in_file')]), (merge_dwi, outputnode, [('merged_file', 'dwi')]), (closmsk, outputnode, [('out_file', 'dwi_mask')]), (warp_prop, outputnode, [('jacdet_map', 'jacobian')]), (swarp, outputnode, [('warped_file', 'out_surf')]) ]) if icorr: jac_mask = pe.Node(fs.ApplyMask(), name='mask_jac') mult = pe.MapNode(MultiImageMaths(op_string='-mul %s'), iterfield=['in_file'], name='ModulateDWIs') wf.connect([ (closmsk, jac_mask, [('out_file', 'mask_file')]), (warp_prop, jac_mask, [('jacdet_map', 'in_file')]), (warp, mult, [('warped_file', 'in_file')]), (jac_mask, mult, [('out_file', 'operand_files')]), (mult, warpbuff, [('out_file', 'unwarped')]) ]) else: wf.connect([ (warp, warpbuff, [('warped_file', 'unwarped')]) ]) return wf
def apply_dfm(name='ApplyDFM', interp='spline', icorr=True, closemask=False): """ A workflow to warp images using DFMs (displacements field maps) computed with FSL. """ in_fields = ['in_files', 'in_mask', 'dfm', 'jac'] inputnode = pe.Node(niu.IdentityInterface(fields=in_fields), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_files', 'out_mask']), name='outputnode') warpmsk = pe.Node(fsl.ApplyWarp(interp='nn', relwarp=True), name='ResampleMask') cachemsk = pe.Node(niu.IdentityInterface(fields=['mask']), name='CacheMask') dwi_ref = pe.Node(niu.Select(index=[0]), name='FirstInput') warp = pe.MapNode(fsl.ApplyWarp(relwarp=True, interp=interp), iterfield=['in_file'], name='ResampleImages') wf = pe.Workflow(name=name) wf.connect([ (inputnode, warpmsk, [('dfm', 'field_file'), ('in_mask', 'in_file'), ('in_mask', 'ref_file')]), (inputnode, dwi_ref, [('in_files', 'inlist')]), (inputnode, warp, [('dfm', 'field_file')]), (dwi_ref, warp, [('out', 'ref_file')]), (inputnode, warp, [('in_files', 'in_file')]), (cachemsk, outputnode, [('mask', 'out_mask')]) ]) if closemask: closmsk = pe.Node(fsl.maths.MathsCommand( args='-kernel sphere 3 -dilM -kernel sphere 2 -ero'), name='MaskClosing') wf.connect([ (warpmsk, closmsk, [('out_file', 'in_file')]), (closmsk, cachemsk, [('out_file', 'mask')]) ]) else: wf.connect([ (warpmsk, cachemsk, [('out_file', 'mask')]) ]) if icorr: jacmask = pe.Node(fs.ApplyMask(), name='JacobianMask') jacmult = pe.MapNode(fsl.MultiImageMaths(op_string='-mul %s'), iterfield=['in_file'], name='ModulateDWIs') wf.connect([ (inputnode, jacmask, [('jac', 'in_file')]), (cachemsk, jacmask, [('mask', 'mask_file')]), (jacmask, jacmult, [('out_file', 'operand_files')]), (warp, jacmult, [('out_file', 'in_file')]), (jacmult, outputnode, [('out_file', 'out_files')]) ]) else: mskdwis = pe.MapNode(fs.ApplyMask(), iterfield=['in_file'], name='MaskWarped') wf.connect([ (cachemsk, mskdwis, [('mask', 'mask_file')]), (warp, mskdwis, [('out_file', 'in_file')]), (mskdwis, outputnode, [('out_file', 'out_files')]) ]) return wf
def vsm_fmb(name='VSM_FMB', phase_unwrap=True, fmb_params={}): """ Workflow that uses `FUGUE <http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE>`_ to compute the voxel-shift map (VSM) from the corresponding B-fieldmap in EPI data. """ wf = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'in_bmap', 'in_mask', 'echospacing', 'delta_te', 'acc_factor', 'enc_dir' ]), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['vsm', 'dfm', 'dfm_inv', 'jac', 'jac_inv']), name='outputnode') selmag = pe.Node(niu.Select(index=0), name='SelectMag') selpha = pe.Node(niu.Select(index=1), name='SelectPha') magmsk = pe.Node(fs.ApplyMask(), name='mask_mag') eff_es = pe.Node(niu.Function(input_names=['echospacing', 'acc_factor'], function=_eff_es_seg, output_names=['echospacing']), name='GetEffEcho') phcache = pe.Node(niu.IdentityInterface(fields=['pha_unwrapped']), name='PhCache') rad2rsec = pe.Node(niu.Function(input_names=['in_file', 'delta_te'], output_names=['out_file'], function=nwu.rads2radsec), name='ToRadSec') pre_fugue = pe.Node(fsl.FUGUE(save_unmasked_fmap=True), name='PreliminaryFugue') demean = pe.Node(niu.Function(function=nwu.demean_image, input_names=['in_file', 'in_mask'], output_names=['out_file']), name='DemeanFmap') cleanup = nwu.cleanup_edge_pipeline() addvol = pe.Node(niu.Function(function=nwu.add_empty_vol, input_names=['in_file'], output_names=['out_file']), name='AddEmptyVol') vsm = pe.Node(fsl.FUGUE(save_unmasked_shift=True, **fmb_params), name="Compute_VSM") dfm = process_vsm() dfm.inputs.inputnode.scaling = 1.0 wf.connect([(inputnode, selmag, [('in_bmap', 'inlist')]), (inputnode, selpha, [('in_bmap', 'inlist')]), (inputnode, magmsk, [('in_mask', 'mask_file')]), (inputnode, eff_es, [('echospacing', 'echospacing'), ('acc_factor', 'acc_factor')]), (selmag, magmsk, [('out', 'in_file')]), (phcache, rad2rsec, [('pha_unwrapped', 'in_file')]), (inputnode, rad2rsec, [('delta_te', 'delta_te')]), (rad2rsec, pre_fugue, [('out_file', 'fmap_in_file')]), (inputnode, pre_fugue, [('in_mask', 'mask_file')]), (pre_fugue, demean, [('fmap_out_file', 'in_file')]), (inputnode, demean, [('in_mask', 'in_mask')]), (demean, cleanup, [('out_file', 'inputnode.in_file')]), (inputnode, cleanup, [('in_mask', 'inputnode.in_mask')]), (cleanup, addvol, [('outputnode.out_file', 'in_file')]), (addvol, vsm, [('out_file', 'fmap_in_file')]), (eff_es, vsm, [('echospacing', 'dwell_time')]), (inputnode, vsm, [('in_mask', 'mask_file'), ('delta_te', 'asym_se_time')]), (vsm, outputnode, [('shift_out_file', 'vsm')]), (vsm, dfm, [('shift_out_file', 'inputnode.vsm')]), (inputnode, dfm, [('in_mask', 'inputnode.reference'), ('enc_dir', 'inputnode.enc_dir')]), (dfm, outputnode, [('outputnode.dfm', 'dfm'), ('outputnode.jacobian', 'jac'), ('outputnode.inv_dfm', 'dfm_inv'), ('outputnode.inv_jacobian', 'jac_inv')])]) if phase_unwrap: prelude = pe.Node(fsl.PRELUDE(process3d=True), name='PhaseUnwrap') wf.connect([(selmag, prelude, [('out', 'magnitude_file')]), (selpha, prelude, [('out', 'phase_file')]), (magmsk, prelude, [('out_file', 'mask_file')]), (prelude, phcache, [('unwrapped_phase_file', 'pha_unwrapped')])]) else: wf.connect(selpha, 'out', phcache, 'pha_unwrapped') return wf