Skip to content

Commit 85dc10e

Browse files
committed
antsCorticalThickness template + test files + merged upstream
1 parent ba986a9 commit 85dc10e

9 files changed

+219
-0
lines changed

nipype/interfaces/ants/segmentation.py

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

nipype/testing/data/BrainSegmentationPrior01.nii.gz

Whitespace-only changes.

nipype/testing/data/BrainSegmentationPrior02.nii.gz

Whitespace-only changes.

nipype/testing/data/BrainSegmentationPrior03.nii.gz

Whitespace-only changes.

nipype/testing/data/BrainSegmentationPrior04.nii.gz

Whitespace-only changes.

nipype/testing/data/ProbabilityMaskOfStudyTemplate.nii.gz

Whitespace-only changes.

nipype/testing/data/T1.nii.gz

Whitespace-only changes.

nipype/testing/data/brain_study_template.nii.gz

Whitespace-only changes.

nipype/testing/data/study_template.nii.gz

Whitespace-only changes.

0 commit comments

Comments
 (0)