Skip to content

Commit f838f64

Browse files
author
David Ellis
committed
ENH: improves preprocessing of T1s to check for FOV and to run as a node.
1 parent 27d78ce commit f838f64

File tree

1 file changed

+57
-43
lines changed

1 file changed

+57
-43
lines changed

nipype/workflows/smri/freesurfer/autorecon1.py

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,38 @@
66
from nipype.interfaces.freesurfer import *
77
from utils import copy_file, copy_files, awkfile
88

9-
def VerifyInputs(T1sList):
10-
##TODO Make this its own node
11-
##TODO Convert .mgz files to .nii.gz
12-
##TODO Check the FOV
9+
def checkT1s(T1_files, cw256=False):
1310
"""Verify size outside of pipeline processing"""
14-
print "Verifying input T1 size"
15-
try:
16-
import SimpleITK as sitk
17-
T1Length = len(T1sList)
18-
extension = None
19-
for i_extension in ['.mgz', '.nii', 'nii.gz']:
20-
if T1sList[0].endswith(i_extension):
21-
extension = i_extension
22-
if T1Length == 0:
23-
print("ERROR: No T1's Given")
24-
sys.exit(-1)
25-
elif T1Length > 1 and extension in ['.nii', '.nii.gz']:
26-
firstSize = sitk.ReadImage(T1sList[0]).GetSize()
27-
for otherFilename in T1sList[1:]:
28-
if firstSize != sitk.ReadImage(otherFilename).GetSize():
29-
print("ERROR: T1s not the same size can not process {0} {1} together".format(
30-
T1sList[0], otherFilename))
31-
sys.exit(-1)
32-
elif extension == None:
33-
print "ERROR: Input files must be have '.mgz', '.nii', or '.nii.gz' extension"
34-
sys.exit(-1)
35-
except OSError as exc: # Python >2.5
36-
print "ERROR: Could not verify input file sizes using SimpleITK"
37-
print exc
11+
print("Verifying input T1 size")
12+
import SimpleITK as sitk
13+
import os
14+
if len(T1_files) == 0:
15+
print("ERROR: No T1's Given")
3816
sys.exit(-1)
39-
return T1sList
17+
for i, t1 in enumerate(T1_files):
18+
if t1.endswith(".mgz"):
19+
# convert input fs files to NIFTI
20+
convert = MRIConvert()
21+
convert.inputs.in_file = t1
22+
convert.inputs.out_file = os.path.abspath(os.path.basename(t1).replace('.mgz', '.nii.gz'))
23+
convert.run()
24+
T1_files[i] = convert.inputs.out_file
25+
size = None
26+
for t1 in T1_files:
27+
img = sitk.ReadImage(t1)
28+
if not size:
29+
size = img.GetSize()
30+
elif size != img.GetSize():
31+
print("ERROR: T1s not the same size. Cannot process {0} {1} together".format(T1_files[0],
32+
otherFilename))
33+
sys.exit(-1)
34+
# check if cw256 is set to crop the images
35+
if not cw256:
36+
for dim in size:
37+
if dim > 256:
38+
print("Setting MRI Convert to crop images to 256 FOV")
39+
40+
return T1_files, cw256
4041

4142
def create_preproc_filenames(in_T1s):
4243
# Create output filenames
@@ -53,18 +54,31 @@ def create_preproc_filenames(in_T1s):
5354
inputvols.append(file_num + '.mgz')
5455
return inputvols, iscaleout, ltaout
5556

56-
def create_AutoRecon1(config):
57-
# AutoRecon1
58-
# Workflow
59-
ar1_wf = pe.Workflow(name='AutoRecon1')
57+
def create_AutoRecon1(name="AutoRecon1", longitudinal=False, use_T2=False, use_FLAIR=False, config):
58+
"""Creates the AutoRecon1 workflow in nipype.
6059
61-
if not config['longitudinal']:
60+
Inputs::
61+
inputspec.T1_files : T1 files (mandatory)
62+
inputspec.T2_file : T2 file (optional)
63+
inputspec.FLAIR_file : FLAIR file (optional)
64+
65+
Outpus::
66+
67+
"""
68+
ar1_wf = pe.Workflow(name=name)
69+
70+
if not longitudinal:
6271
# single session processing
6372
inputSpec = pe.Node(interface=IdentityInterface(
64-
fields=['in_t1s', 'in_t2', 'in_flair']),
73+
fields=['T1_files', 'T2_file', 'in_flair']),
6574
run_without_submitting=True,
6675
name='inputspec')
67-
inputSpec.inputs.in_t1s = VerifyInputs(config['in_T1s'])
76+
77+
verify_inputs = pe.Node(Function(infields=["T1_files"],
78+
outfields=["T1_files"],
79+
checkT1s)
80+
name="Check_T1s"),
81+
6882

6983
origvols, iscaleout, ltaout = create_preproc_filenames(config['in_T1s'])
7084

@@ -75,22 +89,22 @@ def create_AutoRecon1(config):
7589
name="T1_prep")
7690
T1_image_preparation.inputs.out_file = origvols
7791

78-
ar1_wf.connect([(inputSpec, T1_image_preparation, [('in_t1s', 'in_file')]),
92+
ar1_wf.connect([(inputSpec, T1_image_preparation, [('T1_files', 'in_file')]),
7993
])
8094

8195
# T2 image preparation
82-
if config['in_T2'] != None:
96+
if use_T2:
8397
# Create T2raw.mgz
8498
# mri_convert
85-
inputSpec.inputs.in_t2 = config['in_T2']
99+
inputSpec.inputs.T2_file = config['in_T2']
86100
T2_convert = pe.Node(MRIConvert(), name="T2_convert")
87101
T2_convert.inputs.out_file = 'T2raw.mgz'
88102
T2_convert.inputs.no_scale = True
89-
ar1_wf.connect([(inputSpec, T2_convert, [('in_t2', 'in_file')]),
103+
ar1_wf.connect([(inputSpec, T2_convert, [('T2_file', 'in_file')]),
90104
])
91105

92106
# FLAIR image preparation
93-
if config['in_FLAIR'] != None:
107+
if use_FLAIR:
94108
# Create FLAIRraw.mgz
95109
# mri_convert
96110
inputSpec.inputs.in_flair = config['in_FLAIR']
@@ -102,7 +116,7 @@ def create_AutoRecon1(config):
102116
else:
103117
# longitudinal inputs
104118
inputSpec = pe.Node(interface=IdentityInterface(
105-
fields=['in_t1s',
119+
fields=['T1_files',
106120
'iscales',
107121
'ltas',
108122
'subj_to_template_lta',
@@ -168,7 +182,7 @@ def create_AutoRecon1(config):
168182
if config['longitudinal']:
169183
# if running longitudinally
170184
ar1_wf.connect([(concatenate_lta, create_template, [('out_file', 'initial_transforms')]),
171-
(inputSpec, create_template, [('in_t1s', 'in_files')]),
185+
(inputSpec, create_template, [('T1_files', 'in_files')]),
172186
(copy_iscales, create_template, [('out_file','in_intensity_scales')]),
173187
])
174188
else:

0 commit comments

Comments
 (0)