Skip to content

Commit 27d78ce

Browse files
author
David Ellis
committed
Adds recon-all workflows to nipype
1 parent 3ec3ae2 commit 27d78ce

File tree

10 files changed

+3305
-0
lines changed

10 files changed

+3305
-0
lines changed
4.91 KB

Using Nipype Recon-All Workflow

Overview

This program runs FreeSurfer's recon-all (based on 6.0 beta) as a nipype workflow. This allows for better parallel processing and for easier experimenting with new and/or improved processing steps.

You will need

Setup FreeSurfer

Before running the workflow, the FreeSurfer environment must be setup. Setup FreeSurfer

export FREESURFER_HOME=/user/home/freesurfer/6.0-beta
source $FREESURFER_HOME/SetUpFreeSurfer.sh  

Usage

python recon-all.py --T1 <infile1> --subject <name> --subjects_dir <dir> [--T1 <infile2>... --T2 <inT2> --FLAIR <inFLAIR> --qcache --cw256 --openmp <numthreads>]

Required inputs

Flag Argument Description
-i or --T1 in_file(s) Input T1 image. Multiple T1 images may be used as inputs each requiring its own input flag.
-s or --subject name Subject ID or name of the subject being processed. The workflow will output results to a folder with this name in the subjects directory.
--subjects_dir dir Input subjects directory defines where to run workflow and output results.

Optional inputs

Flag Argument Description
--T2 inT2 Input T2 image. T2 images are not used for processing, but the image will be converted to .mgz format.
--FLAIR inFLAIR Input FLAIR image. FLAIR images are not used for processing, but the image will be converted to .mgz format.
--plugin plugin Plugin to use when running workflow.
-q or --queue queue Queue to submit as a qsub argument (requires 'SGE' or 'SGEGraph' plugin).
--qcache Make qcache.
--cw256 Include this flag if images have a FOV > 256. The flag causes mri_convert to conform the image to dimensions of 256^3.
--openmp numthreads OpenMP parallelization (CentOS 6 distribution only!). To enable this feature, add the flag -openmp numthreads to recon-all, where numthreads is the number of threads you would like to run.
For questions or bug fixes email:

David Ellis david-ellis@uiowa.edu University of Iowa

nipype/workflows/smri/freesurfer/autorecon1.py

Lines changed: 424 additions & 0 deletions
Large diffs are not rendered by default.

nipype/workflows/smri/freesurfer/autorecon2.py

Lines changed: 725 additions & 0 deletions
Large diffs are not rendered by default.

nipype/workflows/smri/freesurfer/autorecon3.py

Lines changed: 897 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import os
2+
import nipype
3+
from nipype.interfaces.utility import Function,IdentityInterface
4+
import nipype.pipeline.engine as pe # pypeline engine
5+
from nipype.interfaces.freesurfer import *
6+
from nipype.interfaces.io import DataGrabber
7+
from nipype.interfaces.utility import Merge
8+
9+
def create_ba_maps_wf(config):
10+
# Brodmann Area Maps (BA Maps) and Hinds V1 Atlas
11+
inputs = ['lh_sphere_reg',
12+
'rh_sphere_reg',
13+
'lh_white',
14+
'rh_white',
15+
'lh_pial',
16+
'rh_pial',
17+
'lh_orig',
18+
'rh_orig',
19+
'transform',
20+
'lh_thickness',
21+
'rh_thickness',
22+
'brainmask',
23+
'aseg',
24+
'ribbon',
25+
'wm']
26+
27+
inputSpec = pe.Node(IdentityInterface(fields=inputs),
28+
name="inputspec")
29+
30+
ba_WF = pe.Workflow(name="Brodmann_Area_Maps")
31+
32+
outputSpec = pe.Node(IdentityInterface(fields=['lh_table',
33+
'lh_color',
34+
'lh_thresh_table',
35+
'lh_thresh_color',
36+
'rh_table',
37+
'rh_color',
38+
'rh_thresh_table',
39+
'rh_thresh_color']),
40+
name="outputspec")
41+
42+
labels = ["BA1", "BA2", "BA3a", "BA3b", "BA4a", "BA4p", "BA6",
43+
"BA44", "BA45", "V1", "V2", "MT", "entorhinal", "perirhinal"]
44+
for hemisphere in ['lh', 'rh']:
45+
for threshold in [True, False]:
46+
field_template = dict(sphere_reg='surf/{0}.sphere.reg'.format(hemisphere),
47+
white='surf/{0}.white'.format(hemisphere))
48+
49+
out_files = list()
50+
if threshold:
51+
for label in labels:
52+
out_file = '{0}.{1}_exvivo.thresh.label'.format(hemisphere, label)
53+
out_files.append(out_file)
54+
field_template[label] = 'label/' + out_file
55+
node_name = 'BA_Maps_' + hemisphere + '_Tresh'
56+
else:
57+
for label in labels:
58+
out_file = '{0}.{1}_exvivo.label'.format(hemisphere, label)
59+
out_files.append(out_file)
60+
field_template[label] = 'label/' + out_file
61+
node_name = 'BA_Maps_' + hemisphere
62+
63+
source_fields = labels + ['sphere_reg', 'white']
64+
source_subject = pe.Node(DataGrabber(outfields=source_fields),
65+
name=node_name + "_srcsubject")
66+
source_subject.inputs.base_directory = config['source_subject']
67+
source_subject.inputs.template = '*'
68+
source_subject.inputs.sort_filelist = False
69+
source_subject.inputs.field_template = field_template
70+
71+
merge_labels = pe.Node(Merge(len(labels)),
72+
name=node_name + "_Merge")
73+
for i,label in enumerate(labels):
74+
ba_WF.connect([(source_subject, merge_labels, [(label, 'in{0}'.format(i+1))])])
75+
76+
node = pe.MapNode(Label2Label(), name=node_name,
77+
iterfield=['source_label', 'out_file'])
78+
node.inputs.hemisphere = hemisphere
79+
node.inputs.out_file = out_files
80+
node.inputs.source_subject = config['src_subject_id']
81+
node.inputs.copy_inputs = True
82+
83+
ba_WF.connect([(merge_labels, node, [('out', 'source_label')]),
84+
(source_subject, node, [('sphere_reg', 'source_sphere_reg'),
85+
('white', 'source_white')])])
86+
87+
label2annot = pe.Node(Label2Annot(), name=node_name + '_2_Annot')
88+
label2annot.inputs.hemisphere = hemisphere
89+
label2annot.inputs.color_table = os.path.join(
90+
config['fs_home'], 'average', 'colortable_BA.txt')
91+
label2annot.inputs.verbose_off = True
92+
label2annot.inputs.keep_max = True
93+
label2annot.inputs.copy_inputs = True
94+
95+
stats_node = pe.Node(ParcellationStats(), name=node_name + '_Stats')
96+
stats_node.inputs.hemisphere = hemisphere
97+
stats_node.inputs.mgz = True
98+
stats_node.inputs.surface = 'white'
99+
stats_node.inputs.tabular_output = True
100+
stats_node.inputs.copy_inputs = True
101+
102+
if threshold:
103+
label2annot.inputs.out_annot = "BA_exvivo.thresh"
104+
ba_WF.connect([(stats_node, outputSpec, [('out_color',
105+
'{0}_thresh_color'.format(hemisphere)),
106+
('out_table',
107+
'{0}_thresh_table'.format(hemisphere))])])
108+
else:
109+
label2annot.inputs.out_annot = "BA_exvivo"
110+
ba_WF.connect([(stats_node, outputSpec, [('out_color',
111+
'{0}_color'.format(hemisphere)),
112+
('out_table',
113+
'{0}_table'.format(hemisphere))])])
114+
115+
116+
ba_WF.connect([(inputSpec, node, [('{0}_sphere_reg'.format(hemisphere),
117+
'sphere_reg'),
118+
('{0}_white'.format(hemisphere), 'white'),
119+
]),
120+
(node, label2annot, [('out_file', 'in_labels')]),
121+
(inputSpec, label2annot, [('{0}_orig'.format(hemisphere), 'orig')]),
122+
(label2annot, stats_node,
123+
[('out_file', 'in_annotation')]),
124+
(inputSpec, stats_node, [('{0}_thickness'.format(hemisphere),
125+
'thickness'),
126+
('lh_white', 'lh_white'),
127+
('rh_white', 'rh_white'),
128+
('lh_pial', 'lh_pial'),
129+
('rh_pial', 'rh_pial'),
130+
('transform', 'transform'),
131+
('brainmask', 'brainmask'),
132+
('aseg', 'aseg'),
133+
('wm', 'wm'),
134+
('ribbon', 'ribbon')])])
135+
136+
137+
return ba_WF

0 commit comments

Comments
 (0)