Skip to content

Commit 4b97b0b

Browse files
committed
New interface for antsCorticalThickness.sh script
1 parent ba986a9 commit 4b97b0b

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

nipype/interfaces/ants/segmentation.py

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,220 @@ def _list_outputs(self):
290290
outputs = self._outputs().get()
291291
outputs['output_image'] = os.path.abspath(self._gen_filename('output_image'))
292292
return outputs
293+
294+
class antsCorticalThicknessInputSpec(ANTSCommandInputSpec):
295+
dimension=traits.Enum(3, 2, argstr= '-d %d', usedefault=True,
296+
desc='image dimension (2 or 3)')
297+
anatomical_image=File(exists=True,
298+
argstr='-a %s',
299+
desc='Structural *intensity* image, typically T1.'
300+
'If more than one anatomical image is specified,'
301+
'subsequently specified images are used during the'
302+
'segmentation process. However, only the first'
303+
'image is used in the registration of priors.'
304+
'Our suggestion would be to specify the T1'
305+
'as the first image.',
306+
mandatory=True)
307+
brain_template=File(exists=True,
308+
argstr='-e %s',
309+
desc='Anatomical *intensity* template (possibly created using a'
310+
'population data set with buildtemplateparallel.sh in ANTs).'
311+
'This template is *not* skull-stripped.')
312+
brain_probability_mask=File(exists=True,
313+
argstr='-m %s', desc='brain probability mask in template space',
314+
mandatory=True, copyfile=False)
315+
segmentation_priors = InputMultiPath(File(exists=True),
316+
argstr='-p %s')
317+
out_prefix = traits.Str('antsCT_', argstr='-o %s', usedefault=True,
318+
desc=('Prefix that is prepended to all output'
319+
' files (default = antsCT_)'))
320+
image_suffix=traits.Str('nii.gz', desc=('any of standard ITK formats,'
321+
' nii.gz is default'), mandatory = False, argstr='-s %s',
322+
usedefault=True)
323+
t1_registration_template = File(exists=True,
324+
desc = ('Anatomical *intensity* template'
325+
'(assumed to be skull-stripped). A common'
326+
'case would be where this would be the same'
327+
'template as specified in the -e option which'
328+
'is not skull stripped.'),
329+
mandatory=True, argstr='-t %s')
330+
extraction_registration_mask=File(exists=True, argstr='-f %s',
331+
mandatory=False, desc='Mask (defined in the template'
332+
'space) used during registration for brain extraction.')
333+
keep_temporary_files=traits.Int(argstrr='-k %d',
334+
desc='Keep brain extraction/segmentation'
335+
'warps, etc (default = 0).', mandatory=False)
336+
max_iterations=traits.Int(argstr='-i %d',
337+
desc='ANTS registration max iterations'
338+
'(default = 100x100x70x20)', mandatory=False)
339+
prior_segmentation_weight=traits.Float(mandatory=False, argstr='-w %f',
340+
desc='Atropos spatial prior *probability* weight for'
341+
'the segmentation')
342+
segmentation_iterations=traits.Int(argstr='-n %d', mandatory=False,
343+
desc='N4 -> Atropos -> N4 iterations during segmentation'
344+
'(default = 3)')
345+
posterior_formulation=traits.Str(argstr='-b %s', mandatory=False,
346+
desc=('Atropos posterior formulation and whether or not'
347+
'to use mixture model proportions.'
348+
'''e.g 'Socrates[1]' (default) or 'Aristotle[1]'.'''
349+
'Choose the latter if you'
350+
'want use the distance priors (see also the -l option'
351+
'for label propagation control).'))
352+
use_floatingpoint_precision=traits.Enum(0, 1, argstr='-j %d',
353+
mandatory=False,
354+
desc='Use floating point precision in registrations (default = 0)')
355+
use_random_seeding=traits.Enum(0, 1, argstr='-u %d', mandatory=False,
356+
desc='Use random number generated from system clock in Atropos'
357+
'(default = 1)')
358+
b_spline_smoothing=traits.Bool(argst='-v', mandatory=False,
359+
desc='Use B-spline SyN for registrations and B-spline'
360+
'exponential mapping in DiReCT.')
361+
cortical_label_image=File(exists=True, mandatory=False,
362+
desc='Cortical ROI labels to use as a prior for ATITH.')
363+
label_propagation=traits.Str(argstr='-l %s', mandatory=False,
364+
desc='Incorporate a distance prior one the posterior formulation. Should be'
365+
'''of the form 'label[lambda,boundaryProbability]' where label'''
366+
'is a value of 1,2,3,... denoting label ID. The label'
367+
'probability for anything outside the current label'
368+
' = boundaryProbability * exp( -lambda * distanceFromBoundary )'
369+
'Intuitively, smaller lambda values will increase the spatial capture'
370+
'range of the distance prior. To apply to all label values, simply omit'
371+
'specifying the label, i.e. -l [lambda,boundaryProbability].')
372+
quick_registration=traits.Bool(argstr='-q 1', mandatory=False,
373+
desc='If = 1, use antsRegistrationSyNQuick.sh as the basis for registration'
374+
'during brain extraction, brain segmentation, and'
375+
'(optional) normalization to a template.'
376+
'Otherwise use antsRegistrationSyN.sh (default = 0).')
377+
debug=traits.Bool(argstr='-z 1', mandatory=False,
378+
desc='If > 0, runs a faster version of the script.'
379+
'Only for testing. Implies -u 0.'
380+
'Requires single thread computation for complete reproducibility.')
381+
382+
class antsCorticalThicknessoutputSpec(TraitedSpec):
383+
BrainExtractionMask=File(exists=True,
384+
desc= 'brain extraction mask')
385+
BrainSegmentation=File(exists=True,
386+
desc='brain segmentaion image')
387+
BrainSegmentationN4=File(exists=True,
388+
desc='N4 corrected image')
389+
BrainSegmentationPosteriorsCSF=File(exists=True,
390+
desc='CSF posterior probability image')
391+
BrainSegmentationPosteriorsGM=File(exists=True,
392+
desc='GM posterior probability image')
393+
BrainSegmentationPosteriorsWM=File(exists=True,
394+
desc='WM posterior probability image')
395+
BrainSegmentationPosteriorsDGM=File(exists=True,
396+
desc='DGM posterior probability image')
397+
CorticalThickness=File(exists=True,
398+
desc='cortical thickness file')
399+
TemplateToSubject1GenericAffine=File(exists=True,
400+
desc='Template to subject affine')
401+
TemplateToSubject0Warp=File(exists=True,
402+
desc='Template to subject warp')
403+
SubjectToTemplate1Warp=File(exists=True,
404+
desc='Template to subject inverse warp')
405+
SubjectToTemplate0GenericAffine=File(exists=True,
406+
desc='Template to subject inverse affine')
407+
TemplateToSubjectLogJacobian=File(exists=True,
408+
desc='Template to subject log jacobian')
409+
410+
class antsCorticalThickness(ANTSCommand):
411+
"""
412+
Examples
413+
--------
414+
>>> from nipype.interfaces.ants.segmentation import antsCorticalThickness
415+
>>> corticalthickness = anstCorticalThickness()
416+
>>> corticalthickness.inputs.dimension = 3
417+
>>> corticalthickness.inputs.anatomical_image ='T1.nii.gz'
418+
>>> corticalthickness.inputs.brain_template = 'study_template.nii.gz'
419+
>>> corticalthickness.inputs.brain_probability_mask ='ProbabilityMaskOfStudyTemplate.nii.gz'
420+
>>> corticalthickness.inputs.segmentation_priors =['CSF.nii.gz','WM.nii.gz','GM.nii.gz','DEEP_GM.nii.gz']
421+
>>> corticalthickness.inputs.t1_registration_template = 'brain_study_template.nii.gz'
422+
>>> corticalthickness.cmdline
423+
'antsCorticalThickness.sh -d 3 -a T1.nii.gz -m ProbabilityMaskOfStudyTemplate.nii.gz -e study_template.nii.gz -o antsCT_ -p BrainSegmentationPrior%0d.nii.gz -t brain_study_template.nii.gz'
424+
"""
425+
426+
input_spec = antsCorticalThicknessInputSpec
427+
output_spec = antsCorticalThicknessoutputSpec
428+
_cmd = 'antsCorticalThickness.sh'
429+
def _format_arg(self, opt, spec, val):
430+
if opt == 'anatomical_image':
431+
retval = '-a %s' %(val)
432+
return retval
433+
if opt == 'brain_template':
434+
retval = '-e %s' %(val)
435+
return retval
436+
if opt == 'brain_probability_mask':
437+
retval = '-m %s' %(val)
438+
return retval
439+
if opt == 'out_prefix':
440+
retval = '-o %s' %(val)
441+
return retval
442+
if opt == 't1_registration_template':
443+
retval = '-t %s' %(val)
444+
return retval
445+
if opt == 'segmentation_priors':
446+
_, _, ext = split_filename(self.inputs.segmentation_priors[0])
447+
retval = "-p priors/BrainSegmentationPrior%02d"
448+
retval += ext
449+
return retval
450+
return super(ANTSCommand, self)._format_arg(opt, spec, val)
451+
def _run_interface(self, runtime):
452+
priors_directory = os.path.join(os.getcwd(), "priors")
453+
if not os.path.exists(priors_directory):
454+
os.makedirs(priors_directory)
455+
_, _, ext = split_filename(self.inputs.segmentation_priors[0])
456+
for i, f in enumerate(self.inputs.segmentation_priors):
457+
target = os.path.join(priors_directory,
458+
'BrainSegmentationPrior%02d' % (i + 1) + ext)
459+
if not (os.path.exists(target) and os.path.realpath(target) == os.path.abspath(f)):
460+
copyfile(os.path.abspath(f), os.path.join(priors_directory,
461+
'BrainSegmentationPrior%02d' % (i + 1) + ext))
462+
runtime = super(antsCorticalThickness, self)._run_interface(runtime)
463+
return runtime
464+
465+
def _list_outputs(self):
466+
outputs = self._outputs().get()
467+
outputs['BrainExtractionMask'] = os.path.join(os.getcwd(),
468+
self.inputs.out_prefix +
469+
'BrainExtractionMask.'+
470+
self.inputs.image_suffix)
471+
outputs['BrainSegmentation'] = os.path.join(os.getcwd(),
472+
self.inputs.out_prefix +
473+
'BrainSegmentation.' +
474+
self.inputs.image_suffix)
475+
outputs['BrainSegmentationN4'] = os.path.join(os.getcwd(),
476+
self.inputs.out_prefix +
477+
'BrainSegmentation0N4.' +
478+
self.inputs.image_suffix)
479+
outputs['BrainSegmentationPosteriorsCSF'] = os.path.join(os.getcwd(),
480+
self.inputs.out_prefix +
481+
'BrainSegmentationPosteriors01.' +
482+
self.inputs.image_suffix)
483+
outputs['BrainSegmentationPosteriorsGM'] = os.path.join(os.getcwd(),
484+
'BrainSegmentationPosteriors02.' +
485+
self.inputs.image_suffix)
486+
outputs['BrainSegmentationPosteriorsWM'] = os.path.join(os.getcwd(),
487+
'BrainSegmentationPosteriors03.' +
488+
self.inputs.image_suffix)
489+
outputs['BrainSegmentationPosteriorsDGM'] = os.path.join(os.getcwd(),
490+
'BrainSegmentationPosteriors04.' +
491+
self.inputs.image_suffix)
492+
outputs['CorticalThickness'] = os.path.join(os.getcwd(),
493+
self.inputs.out_prefix + 'CorticalThickness.' +
494+
self.inputs.image_suffix)
495+
outputs['TemplateToSubject1GenericAffine'] = os.path.join(
496+
os.getcwd(),
497+
'TemplateToSubject1GenericAffine.mat')
498+
outputs['TemplateToSubject0Warp'] = os.path.join(os.getcwd(),
499+
self.inputs.out_prefix + 'TemplateToSubject0Warp.'+
500+
self.inputs.image_suffix)
501+
outputs['SubjectToTemplate1Warp'] = os.path.join(os.getcwd(),
502+
self.inputs.out_prefix + 'SubjectToTemplate1Warp' +
503+
self.inputs.image_suffix)
504+
outputs['SubjectToTemplate0GenericAffine'] = os.path.join(os.getcwd(),
505+
self.inputs.out_prefix + 'SubjectToTemplate0GenericAffine.mat')
506+
outputs['TemplateToSubjectLogJacobian'] = os.path.join(os.getcwd(),
507+
self.inputs.out_prefix + 'subjectToTemplateLogJacobian.'+
508+
self.inputs.image_suffix)
509+
return outputs

0 commit comments

Comments
 (0)