Skip to content

Commit 3ea71cc

Browse files
committed
Updated documentation
1 parent c20e1d9 commit 3ea71cc

File tree

1 file changed

+118
-13
lines changed

1 file changed

+118
-13
lines changed

nipype/interfaces/ants/registration.py

Lines changed: 118 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -219,37 +219,51 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
219219
dimension = traits.Enum(3, 2, argstr='--dimensionality %d',
220220
usedefault=True, desc='image dimension (2 or 3)')
221221
fixed_image = InputMultiPath(File(exists=True), mandatory=True,
222-
desc='image to apply transformation to (generally a coregistered functional)')
222+
desc='Image to which the moving_image should be transformed'
223+
'(usually a structural image)')
223224
fixed_image_mask = File(
224225
exists=True, argstr='%s', max_ver='2.1.0', xor=['fixed_image_masks'],
225-
desc='mask used to limit metric sampling region of the fixed image')
226+
desc='Mask used to limit metric sampling region of the fixed image'
227+
'in all stages')
226228
fixed_image_masks = InputMultiPath(
227229
traits.Either('NULL', File(exists=True)), min_ver='2.2.0', xor=['fixed_image_mask'],
228-
desc='mask used to limit metric sampling region of the fixed image '
230+
desc='Masks used to limit metric sampling region of the fixed image, defined per registration stage'
229231
'(Use "NULL" to omit a mask at a given stage)')
230232
moving_image = InputMultiPath(File(exists=True), mandatory=True,
231-
desc='image to apply transformation to (generally a coregistered functional)')
233+
desc='Image that will be registered to the space of fixed_image. This is the'
234+
'image on which the transformations will be applied to')
232235
moving_image_mask = File(
233236
exists=True, requires=['fixed_image_mask'], max_ver='2.1.0', xor=['moving_image_masks'],
234-
desc='mask used to limit metric sampling region of the moving image')
237+
desc='mask used to limit metric sampling region of the moving image'
238+
'in all stages')
235239
moving_image_masks = InputMultiPath(
236240
traits.Either('NULL', File(exists=True)), min_ver='2.2.0', xor=['moving_image_mask'],
237-
desc='mask used to limit metric sampling region of the moving image '
241+
desc='Masks used to limit metric sampling region of the moving image, defined per registration stage'
238242
'(Use "NULL" to omit a mask at a given stage)')
239243

240244
save_state = File(argstr='--save-state %s', exists=False,
241245
desc='Filename for saving the internal restorable state of the registration')
242246
restore_state = File(argstr='--restore-state %s', exists=True,
243247
desc='Filename for restoring the internal restorable state of the registration')
244248

245-
initial_moving_transform = InputMultiPath(argstr='%s', exists=True, desc='',
249+
initial_moving_transform = InputMultiPath(argstr='%s',
250+
exists=True,
251+
desc='A transform or a list of transforms that should be applied'
252+
'before the registration begins. Note that, when a list is given,'
253+
'the transformations are applied in reverse order.',
246254
xor=['initial_moving_transform_com'])
247-
invert_initial_moving_transform= InputMultiPath(traits.Bool(), requires=["initial_moving_transform"],
248-
desc='', xor=['initial_moving_transform_com'])
255+
invert_initial_moving_transform= InputMultiPath(traits.Bool(),
256+
requires=["initial_moving_transform"],
257+
desc='One boolean or a list of booleans that indicate'
258+
'whether the inverse(s) of the transform(s) defined'
259+
'in initial_moving_transform should be used.',
260+
xor=['initial_moving_transform_com'])
249261

250262
initial_moving_transform_com = traits.Enum(0, 1, 2, argstr='%s',
251263
default=0, xor=['initial_moving_transform'],
252-
desc="Use center of mass for moving transform")
264+
desc="Align the moving_image nad fixed_image befor registration using"
265+
"the geometric center of the images (=0), the image intensities (=1),"
266+
"or the origin of the images (=2)")
253267
metric_item_trait = traits.Enum("CC", "MeanSquares", "Demons", "GC", "MI",
254268
"Mattes")
255269
metric_stage_trait = traits.Either(
@@ -291,7 +305,8 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
291305
use_estimate_learning_rate_once = traits.List(traits.Bool(), desc='')
292306
use_histogram_matching = traits.Either(
293307
traits.Bool, traits.List(traits.Bool(argstr='%s')),
294-
default=True, usedefault=True)
308+
default=True, usedefault=True,
309+
desc='Histogram match the images before registration.')
295310
interpolation = traits.Enum(
296311
'Linear', 'NearestNeighbor', 'CosineWindowedSinc', 'WelchWindowedSinc',
297312
'HammingWindowedSinc', 'LanczosWindowedSinc', 'BSpline', 'MultiLabel', 'Gaussian',
@@ -421,8 +436,57 @@ class RegistrationOutputSpec(TraitedSpec):
421436
class Registration(ANTSCommand):
422437

423438
"""
439+
`antsRegister <http://stnava.github.io/ANTs/>`_ registers a 'moving_image' to a 'fixed_image',
440+
using a predefined (sequence of) cost function(s) and transformation operattions.
441+
The cost function is defined using one or more 'metrics', specifically
442+
local cross-correlation ('CC'), Mean Squares ('MeanSquares'), Demons ('Demons'),
443+
global correlation ('GC'), or Mutual Information ('Mattes' or 'MI').
444+
445+
ANTS can use both linear ('Translation, 'Rigid', 'Affine', 'CompositeAffine',
446+
or 'Translation') and non-linear transformations ('BSpline', 'GaussianDisplacementField',
447+
'TimeVaryingVelocityField', 'TimeVaryingBSplineVelocityField', 'SyN', 'BSplineSyN',
448+
'Exponential', or 'BSplineExponential'). Usually, registration is done in multiple
449+
*stages*. For example first an Affine, then a Rigid, and ultimately a non-linear
450+
(Syn)-transformation.
451+
452+
antsRegistration can be initialized using one ore more transforms from moving_image
453+
to fixed_image with the 'initial_moving_transform'-input. For example, when you
454+
already have a warpfield that corrects for geometrical distortions in an EPI (functional) image,
455+
that you want to apply before an Affine registration to a structural image.
456+
You could put this transform into 'intial_moving_transform'.
457+
458+
The Registration-interface can output the resulting transform(s) that map moving_image to
459+
fixed_image in a single file as a 'composite_transform' (if write_composite_transform
460+
is set to True), or a list of transforms as 'forwards_transforms'. It can also output
461+
inverse transforms (from fixed_image to moving_image) in a similar fashion using
462+
inverse_composite_transform. Note that the order of forward_transforms is in 'natural'
463+
order: the first element should be applied first, the last element should be applied last.
464+
465+
Note, however, that ANTS tools always apply lists of transformations in reverse order (the last
466+
transformation in the list is applied first). Therefore, if the output forward_transforms
467+
is a list, one can not directly feed it into, for example, ants.ApplyTransforms. To
468+
make ants.ApplyTransforms apply the transformations in the same order as ants.Registration,
469+
you have to provide the list of transformations in reverse order from forward_transforms.
470+
reverse_forward_transforms outputs forward_transforms in reverse order and can be used for t
471+
this purpose. Note also that, because composite_transform is always only a single file, this
472+
output is preferred for most use-cases.
473+
474+
More information can be found in the `ANTS
475+
manual<https://sourceforge.net/projects/advants/files/Documentation/ants.pdf/download>`.
476+
477+
See below for some useful examples.
478+
424479
Examples
425480
--------
481+
482+
Set up a Registation node with some default settings. This Node registers
483+
'fixed1.nii' to 'moving1.nii' by first fitting a linear 'Affine' transformation, and
484+
then a non-linear 'SyN' transformation, both using the Mutual Information-cost
485+
metric.
486+
487+
The registration is initailized by first applying the (linear) transform
488+
trans.mat.
489+
426490
>>> import copy, pprint
427491
>>> from nipype.interfaces.ants import Registration
428492
>>> reg = Registration()
@@ -461,6 +525,8 @@ class Registration(ANTSCommand):
461525
--use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
462526
>>> reg.run() # doctest: +SKIP
463527
528+
Same as reg1, but first invert the initial transform ('trans.mat') before applying it.
529+
464530
>>> reg.inputs.invert_initial_moving_transform = True
465531
>>> reg1 = copy.deepcopy(reg)
466532
>>> reg1.inputs.winsorize_lower_quantile = 0.025
@@ -475,6 +541,9 @@ class Registration(ANTSCommand):
475541
--use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ] --write-composite-transform 1'
476542
>>> reg1.run() # doctest: +SKIP
477543
544+
Clip extremely high intensity data points using winsorize_upper_quantile. All data points
545+
higher than the 0.975 quantile are set to the value of the 0.975 quantile.
546+
478547
>>> reg2 = copy.deepcopy(reg)
479548
>>> reg2.inputs.winsorize_upper_quantile = 0.975
480549
>>> reg2.cmdline # doctest: +ALLOW_UNICODE
@@ -487,6 +556,10 @@ class Registration(ANTSCommand):
487556
--smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 \
488557
--use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ] --write-composite-transform 1'
489558
559+
Clip extremely low intensity data points using winsorize_lower_quantile. All data points
560+
lower than the 0.025 quantile are set to the original value at the 0.025 quantile.
561+
562+
490563
>>> reg3 = copy.deepcopy(reg)
491564
>>> reg3.inputs.winsorize_lower_quantile = 0.025
492565
>>> reg3.inputs.winsorize_upper_quantile = 0.975
@@ -500,6 +573,8 @@ class Registration(ANTSCommand):
500573
--smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 \
501574
--use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ] --write-composite-transform 1'
502575
576+
Use float instead of double for computations (saves memory usage)
577+
503578
>>> reg3a = copy.deepcopy(reg)
504579
>>> reg3a.inputs.float = True
505580
>>> reg3a.cmdline # doctest: +ALLOW_UNICODE
@@ -513,6 +588,8 @@ class Registration(ANTSCommand):
513588
--use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] \
514589
--write-composite-transform 1'
515590
591+
Force to use double instead of float for computations (more precision and memory usage).
592+
516593
>>> reg3b = copy.deepcopy(reg)
517594
>>> reg3b.inputs.float = False
518595
>>> reg3b.cmdline # doctest: +ALLOW_UNICODE
@@ -526,6 +603,9 @@ class Registration(ANTSCommand):
526603
--use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] \
527604
--write-composite-transform 1'
528605
606+
'collapse_output_transforms' can be used to put all transformation in a single 'composite_transform'-
607+
file. Note that forward_transforms will now be an empty list.
608+
529609
>>> # Test collapse transforms flag
530610
>>> reg4 = copy.deepcopy(reg)
531611
>>> reg4.inputs.save_state = 'trans.mat'
@@ -554,6 +634,7 @@ class Registration(ANTSCommand):
554634
--use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] \
555635
--write-composite-transform 1'
556636
637+
557638
>>> # Test collapse transforms flag
558639
>>> reg4b = copy.deepcopy(reg4)
559640
>>> reg4b.inputs.write_composite_transform = False
@@ -567,7 +648,7 @@ class Registration(ANTSCommand):
567648
'inverse_warped_image': <undefined>,
568649
'reverse_invert_flags': [True, False],
569650
'reverse_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', \
570-
'.../nipype/testing/data/output_1InverseWarp.nii.gz'],
651+
'.../nipype/testing/data/output_1InverseWarp.nii.gz'],
571652
'save_state': '.../nipype/testing/data/trans.mat',
572653
'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz'}
573654
>>> reg4b.aggregate_outputs() # doctest: +SKIP
@@ -582,6 +663,14 @@ class Registration(ANTSCommand):
582663
--use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] \
583664
--write-composite-transform 0'
584665
666+
One can use multiple similarity metrics in a single registration stage.The Node below first
667+
performs a linear registation using only the Mutual Information ('Mattes')-metric.
668+
In a second stage, it performs a non-linear registration ('Syn') using both a
669+
Mutual Information and a local cross-correlation ('CC')-metric. Both metrics are weighted
670+
equally ('metric_weight' is .5 for both). The Mutual Information- metric uses 32 bins.
671+
The local cross-correlations (correlations between every voxel's neighborhoods) is computed
672+
with a radius of 4.
673+
585674
>>> # Test multiple metrics per stage
586675
>>> reg5 = copy.deepcopy(reg)
587676
>>> reg5.inputs.fixed_image = 'fixed1.nii'
@@ -602,7 +691,13 @@ class Registration(ANTSCommand):
602691
--smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 \
603692
--use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
604693
605-
>>> # Test multiple inputs
694+
ANTS Registration can also use multiple modalities to perform the registration. Here it is assumed
695+
that fixed1.nii and fixed2.nii are in the same space, and so are moving1.nii and
696+
moving2.nii. First, a linear registration is performed matching fixed1.nii to moving1.nii,
697+
then a non-linear registration is performed to match fixed2.nii to moving2.nii, starting from
698+
the transformation of the first step.
699+
700+
>>> # Test multiple inputS
606701
>>> reg6 = copy.deepcopy(reg5)
607702
>>> reg6.inputs.fixed_image = ['fixed1.nii', 'fixed2.nii']
608703
>>> reg6.inputs.moving_image = ['moving1.nii', 'moving2.nii']
@@ -617,6 +712,8 @@ class Registration(ANTSCommand):
617712
--smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 \
618713
--use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
619714
715+
Different methods can be used for the interpolation when applying transformations.
716+
620717
>>> # Test Interpolation Parameters (BSpline)
621718
>>> reg7a = copy.deepcopy(reg)
622719
>>> reg7a.inputs.interpolation = 'BSpline'
@@ -646,6 +743,8 @@ class Registration(ANTSCommand):
646743
--use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] \
647744
--write-composite-transform 1'
648745
746+
BSplineSyN non-linear registration with custom parameters.
747+
649748
>>> # Test Extended Transform Parameters
650749
>>> reg8 = copy.deepcopy(reg)
651750
>>> reg8.inputs.transforms = ['Affine', 'BSplineSyN']
@@ -660,6 +759,8 @@ class Registration(ANTSCommand):
660759
--smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 \
661760
--use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
662761
762+
Mask the fixed image in the second stage of the registration (but not the first).
763+
663764
>>> # Test masking
664765
>>> reg9 = copy.deepcopy(reg)
665766
>>> reg9.inputs.fixed_image_masks = ['NULL', 'fixed1.nii']
@@ -674,6 +775,10 @@ class Registration(ANTSCommand):
674775
--use-estimate-learning-rate-once 1 --use-histogram-matching 1 --masks [ fixed1.nii, NULL ] \
675776
--winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
676777
778+
Here we use both a warpfield and a linear transformation, before registration commences. Note that
779+
the first transformation that needs to be applied ('ants_Warp.nii.gz') is last in the list of
780+
'initial_moving_transform'.
781+
677782
>>> # Test initialization with multiple transforms matrices (e.g., unwarp and affine transform)
678783
>>> reg10 = copy.deepcopy(reg)
679784
>>> reg10.inputs.initial_moving_transform = ['func_to_struct.mat', 'ants_Warp.nii.gz']

0 commit comments

Comments
 (0)