@@ -79,17 +79,32 @@ def link_masks(subjects_dir, subject_id):
7979 wf .connect (autorecon_resume , "subject_id" , outputnode , "subject_id" )
8080 return wf
8181
82- def create_reconall_workflow (name = "ReconAll" , plugin_args = None ):
82+ def create_reconall_workflow (name = "ReconAll" , plugin_args = None ,
83+ recoding_file = None ):
8384 """Creates the ReconAll workflow in nipype.
85+
86+ Example
87+ -------
88+ >>> from nipype.workflows.smri.freesurfer import create_skullstripped_recon_flow
89+ >>> import nipype.interfaces.freesurfer as fs
90+ >>> recon_all = create_skullstripped_recon_flow()
91+ >>> recon_all.inputs.inputspec.subject_id = 'subj1'
92+ >>> recon_all.inputs.inputspec.subjects_dir = '.'
93+ >>> recon_all.inputs.inputspec.T1_files = 'T1.nii.gz'
94+ >>> recon_flow.run() # doctest: +SKIP
95+
8496
8597 Inputs::
98+ inputspec.subjects_dir : subjects directory (mandatory)
99+ inputspec.subject_id : name of subject (mandatory)
86100 inputspec.T1_files : T1 files (mandatory)
87101 inputspec.T2_file : T2 file (optional)
88102 inputspec.FLAIR_file : FLAIR file (optional)
89103 inputspec.cw256 : Conform inputs to 256 FOV (optional)
90104 inputspec.num_threads: Number of threads on nodes that utilize OpenMP (default=1)
91105 plugin_args : Dictionary of plugin args to set to nodes that utilize OpenMP (optional)
92106 Outpus::
107+ postdatasink_outputspec.subject_id : name of the datasinked output folder in the subjects directory
93108
94109 """
95110 reconall = pe .Workflow (name = name )
@@ -115,66 +130,122 @@ def create_reconall_workflow(name="ReconAll", plugin_args=None):
115130 'wm_lookup_table' ,
116131 'src_subject_id' ,
117132 'src_subject_dir' ,
118- 'color_table' ]),
133+ 'color_table' ,
134+ 'awk_file' ]),
119135 run_without_submitting = True ,
120136 name = 'inputspec' )
121137
122- # get the default configurations
123- defaultconfig = getdefaultconfig ()
124-
125- # set the default template and classifier files
126- inputspec .inputs .reg_template = defaultconfig ['registration_template' ]
127- inputspec .inputs .reg_template_withskull = defaultconfig ['registration_template_withskull' ]
128- inputspec .inputs .lh_atlas = defaultconfig ['lh_atlas' ]
129- inputspec .inputs .rh_atlas = defaultconfig ['rh_atlas' ]
130- inputspec .inputs .lh_classifier1 = defaultconfig ['lh_classifier' ]
131- inputspec .inputs .rh_classifier1 = defaultconfig ['rh_classifier' ]
132- inputspec .inputs .lh_classifier2 = defaultconfig ['lh_classifier2' ]
133- inputspec .inputs .rh_classifier2 = defaultconfig ['rh_classifier2' ]
134- inputspec .inputs .lh_classifier3 = defaultconfig ['lh_classifier3' ]
135- inputspec .inputs .rh_classifier3 = defaultconfig ['rh_classifier3' ]
136- inputspec .inputs .src_subject_id = defaultconfig ['src_subject_id' ]
137- inputspec .inputs .src_subject_dir = defaultconfig ['src_subject_dir' ]
138- inputspec .inputs .color_table = defaultconfig ['AvgColorTable' ]
139- inputspec .inputs .lookup_table = defaultconfig ['LookUpTable' ]
140- inputspec .inputs .wm_lookup_table = defaultconfig ['WMLookUpTable' ]
138+ def setconfig (reg_template = None ,
139+ reg_template_withskull = None ,
140+ lh_atlas = None ,
141+ rh_atlas = None ,
142+ lh_classifier1 = None ,
143+ rh_classifier1 = None ,
144+ lh_classifier2 = None ,
145+ rh_classifier2 = None ,
146+ lh_classifier3 = None ,
147+ rh_classifier3 = None ,
148+ src_subject_id = None ,
149+ src_subject_dir = None ,
150+ color_table = None ,
151+ lookup_table = None ,
152+ wm_lookup_table = None ,
153+ awk_file = None ):
154+ """Set optional configurations to the default"""
155+ from nipype .workflows .smri .freesurfer .utils import getdefaultconfig
156+ def checkarg (arg , default ):
157+ """Returns the value if defined; otherwise default"""
158+ if arg :
159+ return arg
160+ else :
161+ return default
162+ # set the default template and classifier files
163+ reg_template = checkarg (reg_template , defaultconfig ['registration_template' ])
164+ reg_template_withskull = checkarg (reg_template_withskull ,
165+ defaultconfig ['registration_template_withskull' ])
166+ lh_atlas = checkarg (lh_atlas , defaultconfig ['lh_atlas' ])
167+ rh_atlas = checkarg (rh_atlas , defaultconfig ['rh_atlas' ])
168+ lh_classifier1 = checkarg (lh_classifier1 , defaultconfig ['lh_classifier' ])
169+ rh_classifier1 = checkarg (rh_classifier1 , defaultconfig ['rh_classifier' ])
170+ lh_classifier2 = checkarg (lh_classifier2 , defaultconfig ['lh_classifier2' ])
171+ rh_classifier2 = checkarg (rh_classifier2 , defaultconfig ['rh_classifier2' ])
172+ lh_classifier3 = checkarg (lh_classifier3 , defaultconfig ['lh_classifier3' ])
173+ rh_classifier3 = checkarg (rh_classifier3 , defaultconfig ['rh_classifier3' ])
174+ src_subject_id = checkarg (src_subject_id , defaultconfig ['src_subject_id' ])
175+ src_subject_dir = checkarg (src_subject_dir , defaultconfig ['src_subject_dir' ])
176+ color_table = checkarg (color_table , defaultconfig ['AvgColorTable' ])
177+ lookup_table = checkarg (lookup_table , defaultconfig ['LookUpTable' ])
178+ wm_lookup_table = checkarg (wm_lookup_table , defaultconfig ['WMLookUpTable' ])
179+ awk_file = checkarg (awk_file , defaultconfig ['awk_file' ])
180+ return reg_template , reg_template_withskull , lh_atlas , rh_atlas , \
181+ lh_classifier1 , rh_classifier1 , lh_classifier2 , rh_classifier2 , \
182+ lh_classifier3 , rh_classifier3 , src_subject_id , src_subject_dir , \
183+ color_table , lookup_table , wm_lookup_table , awk_file
184+
185+ # list of params to check
186+ params = ['reg_template' ,
187+ 'reg_template_withskull' ,
188+ 'lh_atlas' ,
189+ 'rh_atlas' ,
190+ 'lh_classifier1' ,
191+ 'rh_classifier1' ,
192+ 'lh_classifier2' ,
193+ 'rh_classifier2' ,
194+ 'lh_classifier3' ,
195+ 'rh_classifier3' ,
196+ 'lookup_table' ,
197+ 'wm_lookup_table' ,
198+ 'src_subject_id' ,
199+ 'src_subject_dir' ,
200+ 'color_table' ,
201+ 'awk_file' ]
202+
203+ config_node = pe .Node (niu .Function (params ,
204+ params ,
205+ setconfig ),
206+ name = "config" )
207+
208+ for param in params :
209+ reconall .connect (inputspec , param , config_node , param )
141210
142211 # create AutoRecon1
143- ar1_wf , ar1_outputs = create_AutoRecon1 (plugin_args = plugin_args ,
144- awk_file = defaultconfig ['awk_file' ])
212+ ar1_wf , ar1_outputs = create_AutoRecon1 (plugin_args = plugin_args )
145213 # connect inputs for AutoRecon1
146214 reconall .connect ([(inputspec , ar1_wf , [('T1_files' , 'inputspec.T1_files' ),
147215 ('T2_file' , 'inputspec.T2_file' ),
148216 ('FLAIR_file' , 'inputspec.FLAIR_file' ),
149217 ('num_threads' , 'inputspec.num_threads' ),
150- ('cw256' , 'inputspec.cw256' ),
151- ('reg_template_withskull' , 'inputspec.reg_template_withskull' )])])
218+ ('cw256' , 'inputspec.cw256' )]),
219+ (config_node , ar1_wf , [('reg_template_withskull' ,
220+ 'inputspec.reg_template_withskull' ),
221+ ('awk_file' , 'inputspec.awk_file' )])])
152222
153223 # create AutoRecon2
154224 ar2_wf , ar2_outputs = create_AutoRecon2 (plugin_args = plugin_args )
155225 # connect inputs for AutoRecon2
156- reconall .connect ([(inputspec , ar2_wf , [('num_threads' , 'inputspec.num_threads' ),
157- ('reg_template' , 'inputspec.reg_template' ),
158- ('reg_template_withskull' , 'inputspec.reg_template_withskull' )]),
226+ reconall .connect ([(inputspec , ar2_wf , [('num_threads' , 'inputspec.num_threads' )]),
227+ (config_node , ar2_wf , [('reg_template_withskull' ,
228+ 'inputspec.reg_template_withskull' ),
229+ ('reg_template' , 'inputspec.reg_template' )]),
159230 (ar1_wf , ar2_wf , [('outputspec.brainmask' , 'inputspec.brainmask' ),
160231 ('outputspec.talairach' , 'inputspec.transform' ),
161232 ('outputspec.orig' , 'inputspec.orig' )])])
162233 # create AutoRecon3
163- ar3_wf , ar3_outputs = create_AutoRecon3 (plugin_args = plugin_args , th3 = defaultconfig [ 'th3' ] )
234+ ar3_wf , ar3_outputs = create_AutoRecon3 (plugin_args = plugin_args , th3 = True )
164235 # connect inputs for AutoRecon3
165- reconall .connect ([(inputspec , ar3_wf , [('lh_atlas' , 'inputspec.lh_atlas' ),
166- ('rh_atlas' , 'inputspec.rh_atlas' ),
167- ('lh_classifier1' , 'inputspec.lh_classifier1' ),
168- ('rh_classifier1' , 'inputspec.rh_classifier1' ),
169- ('lh_classifier2' , 'inputspec.lh_classifier2' ),
170- ('rh_classifier2' , 'inputspec.rh_classifier2' ),
171- ('lh_classifier3' , 'inputspec.lh_classifier3' ),
172- ('rh_classifier3' , 'inputspec.rh_classifier3' ),
173- ('lookup_table' , 'inputspec.lookup_table' ),
174- ('wm_lookup_table' , 'inputspec.wm_lookup_table' ),
175- ('src_subject_dir' , 'inputspec.src_subject_dir' ),
176- ('src_subject_id' , 'inputspec.src_subject_id' ),
177- ('color_table' , 'inputspec.color_table' )]),
236+ reconall .connect ([(config_node , ar3_wf , [('lh_atlas' , 'inputspec.lh_atlas' ),
237+ ('rh_atlas' , 'inputspec.rh_atlas' ),
238+ ('lh_classifier1' , 'inputspec.lh_classifier1' ),
239+ ('rh_classifier1' , 'inputspec.rh_classifier1' ),
240+ ('lh_classifier2' , 'inputspec.lh_classifier2' ),
241+ ('rh_classifier2' , 'inputspec.rh_classifier2' ),
242+ ('lh_classifier3' , 'inputspec.lh_classifier3' ),
243+ ('rh_classifier3' , 'inputspec.rh_classifier3' ),
244+ ('lookup_table' , 'inputspec.lookup_table' ),
245+ ('wm_lookup_table' , 'inputspec.wm_lookup_table' ),
246+ ('src_subject_dir' , 'inputspec.src_subject_dir' ),
247+ ('src_subject_id' , 'inputspec.src_subject_id' ),
248+ ('color_table' , 'inputspec.color_table' )]),
178249 (ar1_wf , ar3_wf , [('outputspec.brainmask' , 'inputspec.brainmask' ),
179250 ('outputspec.talairach' , 'inputspec.transform' ),
180251 ('outputspec.orig' , 'inputspec.orig_mgz' ),
@@ -209,7 +280,7 @@ def create_reconall_workflow(name="ReconAll", plugin_args=None):
209280 'inputspec.{0}_white_K' .format (hemi ))])])
210281
211282
212- # Add more outputs to outputspec
283+ # Add more outputs to outputspec
213284 outputs = ar1_outputs + ar2_outputs + ar3_outputs
214285 outputspec = pe .Node (niu .IdentityInterface (fields = outputs , mandatory_inputs = True ),
215286 name = "outputspec" )
@@ -401,14 +472,48 @@ def getDSTransformPath(subjects_dir, subject_id):
401472 ('rh_table' , 'label.@rh_table' ),
402473 ('rh_color' , 'label.@rh_color' ),
403474 ('rh_thresh_table' , 'label.@rh_thresh_table' ),
404- ('rh_thresh_color' , 'label.@rh_thresh_color' )
475+ ('rh_thresh_color' , 'label.@rh_thresh_color' ),
476+ ('lh_BAMaps_labels' , 'label.@lh_BAMaps_labels' ),
477+ ('lh_thresh_BAMaps_labels' , 'label.@lh_thresh_BAMaps_labels' ),
478+ ('rh_BAMaps_labels' , 'label.@rh_BAMaps_labels' ),
479+ ('rh_thresh_BAMaps_labels' , 'label.@rh_thresh_BAMaps_labels' ),
480+ ('lh_BAMaps_annotation' ,
481+ 'label.@lh_BAMaps_annotation' ),
482+ ('lh_thresh_BAMaps_annotation' ,
483+ 'label.@lh_thresh_BAMaps_annotation' ),
484+ ('rh_BAMaps_annotation' ,
485+ 'label.@rh_BAMaps_annotation' ),
486+ ('rh_thresh_BAMaps_annotation' ,
487+ 'label.@rh_thresh_BAMaps_annotation' ),
405488 ]),
406489 ])
407490
491+ # compeltion node
492+ # since recon-all outputs so many files a completion node is added
493+ # that will output the subject_id once the workflow has completed
494+ def completemethod (datasinked_files , subject_id ):
495+ print ("recon-all has finished executing for subject: {0}" .format (subject_id ))
496+ return subject_id
497+
498+ completion = pe .Node (niu .Function (['datasinked_files' , 'subject_id' ],
499+ ['subject_id' ],
500+ completemethod ),
501+ name = "Completion" )
502+
503+ # create a special identity interface for outputing the subject_id
504+
505+ postds_outputspec = pe .Node (niu .IdentityInterface (['subject_id' ]),
506+ name = "postdatasink_outputspec" )
507+
508+ reconall .connect ([(datasink , completion , [('out_file' , 'datasinked_files' )]),
509+ (inputspec , completion , [('subject_id' , 'subject_id' )]),
510+ (completion , postds_outputspec , [('subject_id' , 'subject_id' )])])
511+
512+
408513 #### Workflow additions go here
409- if defaultconfig [ ' recoding_file' ] :
514+ if recoding_file :
410515 from utils import create_recoding_wf
411- recode = create_recoding_wf (defaultconfig [ ' recoding_file' ] )
516+ recode = create_recoding_wf (recoding_file )
412517 reconall .connect ([(ar3_wf , recode , [('outputspec.aseg' , 'inputspec.labelmap' )]),
413518 (recode , outputspec , [('outputspec.recodedlabelmap' , 'recoded_labelmap' )])])
414519
0 commit comments