3
XdB                @   s@  d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZmZmZ G d	d
 d
eZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd  d eZG d!d" d"eZG d#d$ d$eZG d%d& d&eZdS )'zQThe ants module provides basic functions for interfacing with ants
   functions.
    N   )ensure_list   )TraitedSpecFileStrtraitsInputMultiPath	isdefined   )ANTSCommandANTSCommandInputSpecLOCAL_DEFAULT_NUMBER_OF_THREADSc            
   @   s  e Zd ZejddddddZeedddd	d
ZeeddddddZ	ej
ejdddddddddd
Zej
ej dgddgdddZej
ej dgdddZeddddddZejdd d!d"d#ddddZejd$gdd%Zejd&gdd%Zejd'gdd%Zejd(gdd%Zejdddd)Zej
ej d*d+d,Zej
ej d-d+d,Zej
ej d.d+d,Zej
ej dd/Zej
ej d0d+d,Zejd1d2ddd3Zejd4gdd%Zejd4gdd%Z ej
ej d5d+d,Z!d6S )7ANTSInputSpecr   r   z%dr   zimage dimension (2 or 3))argstrpositiondescT)existsz)image to which the moving image is warped)	mandatoryr   z%szEimage to apply transformation to (generally a coregisteredfunctional))r   r   r   CCMISMIPRSSDMSQPSE g      ?metriczIthe metric weight(s) for each stage. The weights must sum to 1 per stage.)value
usedefaultrequiresr   r   znradius of the region (i.e. number of layers around a voxel/pixel) that is used for computing cross correlation)r    r   r   outz--output-naming %s)r   r   r   r   ZDiffZElastZExpz
Greedy ExpSyNtransformation_model)r    r   gradient_step_lengthnumber_of_time_steps
delta_time)r   default_valuer   z--number-of-iterations %sx)r   sepz--gaussian-smoothing-sigmas %sz--subsampling-factors %s)r   z--MI-option %sZGaussZDMFFD)r   r   regularizationz --number-of-affine-iterations %sN)"__name__
__module____qualname__r   Enum	dimensionr	   r   fixed_imagemoving_imageListr   Floatmetric_weightIntradiusr   output_transform_prefixr#   r$   r%   r&   symmetry_typeBooluse_histogram_matchingnumber_of_iterationssmoothing_sigmasZsubsampling_factorsaffine_gradient_descent_optionZ	mi_optionr*   #regularization_gradient_field_sigma&regularization_deformation_field_sigmaZnumber_of_affine_iterations r@   r@   U/var/www/html/virt/lib/python3.6/site-packages/nipype/interfaces/ants/registration.pyr      sv   r   c               @   sH   e Zd ZedddZedddZedddZedddZedddZdS )	ANTSOutputSpecTzAffine transform file)r   r   zWarping deformation fieldz!Inverse warping deformation fieldzVTK metaheader .mhd filezVTK metaheader .raw fileN)	r+   r,   r-   r   affine_transformwarp_transforminverse_warp_transformZ
metaheaderZmetaheader_rawr@   r@   r@   rA   rB   y   s
   rB   c                   sT   e Zd ZdZd ZeZeZdd Z	dd Z
dd Zdd	 Z fd
dZdd Z  ZS )ANTSa  ANTS wrapper for registration of images
    (old, use Registration instead)

    Examples
    --------

    >>> from nipype.interfaces.ants import ANTS
    >>> ants = ANTS()
    >>> ants.inputs.dimension = 3
    >>> ants.inputs.output_transform_prefix = 'MY'
    >>> ants.inputs.metric = ['CC']
    >>> ants.inputs.fixed_image = ['T1.nii']
    >>> ants.inputs.moving_image = ['resting.nii']
    >>> ants.inputs.metric_weight = [1.0]
    >>> ants.inputs.radius = [5]
    >>> ants.inputs.transformation_model = 'SyN'
    >>> ants.inputs.gradient_step_length = 0.25
    >>> ants.inputs.number_of_iterations = [50, 35, 15]
    >>> ants.inputs.use_histogram_matching = True
    >>> ants.inputs.mi_option = [32, 16000]
    >>> ants.inputs.regularization = 'Gauss'
    >>> ants.inputs.regularization_gradient_field_sigma = 3
    >>> ants.inputs.regularization_deformation_field_sigma = 0
    >>> ants.inputs.number_of_affine_iterations = [10000,10000,10000,10000,10000]
    >>> ants.cmdline
    'ANTS 3 --MI-option 32x16000 --image-metric CC[ T1.nii, resting.nii, 1, 5 ] --number-of-affine-iterations 10000x10000x10000x10000x10000 --number-of-iterations 50x35x15 --output-naming MY --regularization Gauss[3.0,0.0] --transformation-model SyN[0.25] --use-Histogram-Matching 1'
    c          	   C   s   g }ddddddg}ddg}xzt t| jjD ]f}| jj| |kr|jd	| jj| | jj| | jj| | jj| | jj| f  q.| jj| |kr.q.W d
j	|S )Nr   r   r   r   r   r   r   ZJTBz#--image-metric %s[ %s, %s, %g, %d ] )
rangeleninputsr1   r   appendr0   r4   r6   join)selfretvalZintensity_basedZpoint_set_basediir@   r@   rA   _image_metric_constructor   s    



zANTS._image_metric_constructorc       	      C   s   | j j}| j j}| j j}| j j}| j j}d| g}g }x,||||fD ]}|tjk	rD|jd|  qDW t	|dkrt	|dkrdj
|}n
dj
|}|jd|  dj
|S )Nz--transformation-model %sz%#.2gr   r   ,r   z[%s])rJ   r#   r$   r%   r&   r8   r   	UndefinedrK   rI   rL   )	rM   modelZstep_lengthZ	time_stepr&   r8   rN   
parameterselemr@   r@   rA   _transformation_constructor   s     


z ANTS._transformation_constructorc             C   s   dj | jj| jj| jjS )Nz--regularization {0}[{1},{2}])formatrJ   r*   r>   r?   )rM   r@   r@   rA   _regularization_constructor   s    z ANTS._regularization_constructorc                s   | j j}ddddg x<tt D ],}y||  |< W q" tk
rL   P Y q"X q"W | j fddtdD }d|g}dj|S )	Ng?g      ?g-C6?c                s   g | ]}d  |  qS )z%gr@   ).0index)defaultsr@   rA   
<listcomp>   s    zDANTS._affine_gradient_descent_option_constructor.<locals>.<listcomp>   z --affine-gradient-descent-optionrG   )rJ   r=   rH   rI   
IndexError_format_xarrayrL   )rM   valuesrO   rT   rN   r@   )r[   rA   +_affine_gradient_descent_option_constructor   s    z0ANTS._affine_gradient_descent_option_constructorc                sl   |dkr| j  S |dkr | j S |dkr0| j S |dkr@| j S |dkrX| jjrTdS dS tt| j|||S )Nr1   r#   r*   r=   r:   z--use-Histogram-Matching 1z--use-Histogram-Matching 0)	rP   rV   rX   ra   rJ   r:   superrF   _format_arg)rM   optspecval)	__class__r@   rA   rc      s    zANTS._format_argc             C   sX   | j  j }tjj| jjd |d< tjj| jjd |d< tjj| jjd |d< |S )Nz
Affine.txtrC   zWarp.nii.gzrD   zInverseWarp.nii.gzrE   )_outputsgetospathabspathrJ   r7   )rM   outputsr@   r@   rA   _list_outputs   s    zANTS._list_outputs)r+   r,   r-   __doc___cmdr   
input_specrB   output_specrP   rV   rX   ra   rc   rn   __classcell__r@   r@   )rg   rA   rF      s   rF   c               @   s  e Zd ZejddddddZeeddddd	Zedd
ddgddZ	eej
deddddgddZeeddddd	ZeddgddgddZeej
deddddgddZeddddZeddddZeeddd
d d!gd"Zeej d#gd$d!gd%Zejd&d'dd
d#gd(d)Zejd*d+d,d-d.d/Zej
eejeZejedd0d	Zejd1dd2Zej
eejeZejed1gdd3gdd4d5Zejd6dd2Zej
eejeZejed6gdd7gd8d9Z ejd:d;d<d=Z!ej
e!eje!Z"eje"d7gd>d?Z#ej
ej$d@d1dAd=Z%ej
e%eje%Z&eje&dBgdCd?Z'ejej dDdEZ(ej
ejejejd
dFdddGdHZ)ejdIdJdKdLdMdNdOdPdQdRd
ddSZ*ej
ej+ej ej+ej ej ej+ej, Z-ejdTdddDdUZ.ejdVdddWdUZ/ejdXdddYdUZ0ejdZdd[d\Z1ejejd]d^d_d`dadOdbdcdddedfdgdhd
ddiZ2ejej
ej+ej ej+ej ej ej ej+ej ej ej ej ej+ej ej ej ej ej ej ej+ej ej ej ej ej+ej ej ej ej ej Z3ejejej$d@d1dAdjdEZ4ejejej Z5ejejej ddkZ6ejejdldmdngdodpZ7ejejej ddkZ8ejej dqgd'drgddsZ9ejej dtgd'dugddsZ:e,dvdd
dDdwZ;ej
eje ddDdxZ<ej
eje ddygdDdzZ=ej$d@d1d1d
dd{d|Z>ej$d@d1d@d
dd}d|Z?ejd~ddddZ@d=S )RegistrationInputSpecr   r   z--dimensionality %dTzimage dimension (2 or 3))r   r   r   )r   zQImage to which the moving_image should be transformed(usually a structural image))r   r   z%sz2.1.0fixed_image_maskszIMask used to limit metric sampling region of the fixed imagein all stages)r   r   max_verxorr   NULLz2.2.0fixed_image_maskzMasks used to limit metric sampling region of the fixed image, defined per registration stage(Use "NULL" to omit a mask at a given stage))Zmin_verrw   r   z{Image that will be registered to the space of fixed_image. This is theimage on which the transformations will be applied tomoving_image_maskszJmask used to limit metric sampling region of the moving imagein all stages)r   r    rv   rw   r   moving_image_maskzMasks used to limit metric sampling region of the moving image, defined per registration stage(Use "NULL" to omit a mask at a given stage)z--save-state %sFzEFilename for saving the internal restorable state of the registration)r   r   r   z--restore-state %szHFilename for restoring the internal restorable state of the registrationzA transform or a list of transforms that should be applied before the registration begins. Note that, when a list is given, the transformations are applied in reverse order.initial_moving_transform_com)r   r   rw   initial_moving_transformzOne boolean or a list of booleans that indicatewhether the inverse(s) of the transform(s) definedin initial_moving_transform should be used.)r    r   rw   r   r   zAlign the moving_image and fixed_image before registration using the geometric center of the images (=0), the image intensities (=1), or the origin of the images (=2).)r   rw   r   r   MeanSquaresDemonsGCr   Matteszvthe metric(s) to use for each stage. Note that multiple metrics per stage are not supported in ANTS 1.9.1 and earlier.g      ?)r   r   zIthe metric weight(s) for each stage. The weights must sum to 1 per stage.)r   r   r    r   r      r4   z[the number of bins in each stage for the MI and Mattes metric, the radius for other metrics)r   r   r    r   NoneRegularRandomNz8the metric sampling strategy (strategies) for each stage)traitr    r   g        )lowhighsampling_strategyz7the metric sampling percentage(s) to use for each stager   )r   )r   z/Histogram match the images before registration.)defaultr   r   ZLinearZNearestNeighborZCosineWindowedSincZWelchWindowedSincZHammingWindowedSincZLanczosWindowedSincBSpline
MultiLabelGaussianGenericLabel)r   r   z--write-composite-transform %d)r   r'   r   r   z--collapse-output-transforms %dzCollapse output transforms. Specifically, enabling this option combines all adjacent linear transforms and composes all adjacent displacement field transforms before writing the results to disk.z$--initialize-transforms-per-stage %dab  Initialize linear transforms from the previous stage. By enabling this option, the current linear stage transform is directly intialized from the previous stages linear transform; this allows multiple linear stages to be run where each stage directly updates the estimated linear transform from the previous stage. (e.g. Translation -> Rigid -> Affine). z
--float %dz-Use float instead of double for computations.)r   r'   r   RigidAffineCompositeAffine
SimilarityTranslationZGaussianDisplacementFieldZTimeVaryingVelocityFieldZTimeVaryingBSplineVelocityFieldr"   Z
BSplineSyNZExponentialZBSplineExponential)r   r   a  This option allows the user to restrict the optimization of the displacement field, translation, rigid or affine transform on a per-component basis. For example, if one wants to limit the deformation or rotation of 3-D volume to the  first two dimensions, this is possible by specifying a weight vector of '1x1x0' for a deformation field or '1x1x0x1x1x0' for a rigid transformation.  Low-dimensional restriction only works if there are no preceding transformations.)r   mmZvoxr<   zunits for smoothing sigmas)r    r   gư>r;   )r   r   Zminlenr    r   
   convergence_threshold	transform)r   r   r   )
hash_filesr   output_warped_image)r   r    r   z'The Upper quantile to clip image ranges)r   r   r   r   r   r   z'The Lower quantile to clip image rangesz-v)r   r'   r   Znohash)Ar+   r,   r-   r   r.   r/   r	   r   r0   ry   Eitherru   r1   r{   rz   
save_stateZrestore_stater}   r9   invert_initial_moving_transformr|   Zmetric_item_traitr2   Zmetric_stage_traitr   r3   Zmetric_weight_item_traitZmetric_weight_stage_traitr4   r5   Zradius_bins_item_traitZradius_bins_stage_traitradius_or_number_of_binsZsampling_strategy_item_traitZsampling_strategy_stage_traitr   RangeZsampling_percentage_item_traitZsampling_percentage_stage_traitsampling_percentageuse_estimate_learning_rate_oncer:   interpolationTupler   interpolation_parameterswrite_composite_transformcollapse_output_transformsZinitialize_transforms_per_stagefloat
transformstransform_parametersrestrict_deformationr;   r<   sigma_unitsshrink_factorsr   convergence_window_sizer7   r   output_inverse_warped_imagewinsorize_upper_quantilewinsorize_lower_quantileverboser@   r@   r@   rA   rt     s  

	
rt   c               @   s   e Zd ZejeddddZejeddddZejeddddZejej	 ddZ
ejej	 ddZejej	 d	dZedd
dZeddZeddZeddZeddZejddZejddZdS )RegistrationOutputSpecT)r   z2List of output transforms for forward registration)r   zRList of output transforms for forward registration reversed for antsApplyTransformz2List of output transforms for reverse registrationz5List of flags corresponding to the forward transformszUList of flags corresponding to the forward transforms reversed for antsApplyTransformz5List of flags corresponding to the reverse transformszComposite transform file)r   r   z Inverse composite transform filezOutputs warped imagez'Outputs the inverse of the warped imagez+The saved registration state to be restoredzthe final value of metricz*the total elapsed time as reported by ANTsN)r+   r,   r-   r   r2   r   forward_transformsreverse_forward_transformsreverse_transformsr9   forward_invert_flagsreverse_forward_invert_flagsreverse_invert_flagscomposite_transforminverse_composite_transformwarped_imageinverse_warped_imager   r3   metric_valueelapsed_timer@   r@   r@   rA   r   R  s*   



r   c                   s   e Zd ZdZdZdZeZeZ	dZ
ddddd	gZ fd
dZd& fdd	Zdd Zedd Zdd Zdd Zd'ddZdd Zdd Zdd Z fdd Zd(d!d"Zd#d$ Z  ZS ))Registrationa\  ANTs Registration command for registration of images

    `antsRegistration <http://stnava.github.io/ANTs/>`_ registers a ``moving_image`` to a ``fixed_image``,
    using a predefined (sequence of) cost function(s) and transformation operations.
    The cost function is defined using one or more 'metrics', specifically
    local cross-correlation (``CC``), Mean Squares (``MeanSquares``), Demons (``Demons``),
    global correlation (``GC``), or Mutual Information (``Mattes`` or ``MI``).

    ANTS can use both linear (``Translation``, ``Rigid``, ``Affine``, ``CompositeAffine``,
    or ``Translation``) and non-linear transformations (``BSpline``, ``GaussianDisplacementField``,
    ``TimeVaryingVelocityField``, ``TimeVaryingBSplineVelocityField``, ``SyN``, ``BSplineSyN``,
    ``Exponential``, or ``BSplineExponential``). Usually, registration is done in multiple
    *stages*. For example first an Affine, then a Rigid, and ultimately a non-linear
    (Syn)-transformation.

    antsRegistration can be initialized using one ore more transforms from moving_image
    to fixed_image with the ``initial_moving_transform``-input. For example, when you
    already have a warpfield that corrects for geometrical distortions in an EPI (functional) image,
    that you want to apply before an Affine registration to a structural image.
    You could put this transform into 'intial_moving_transform'.

    The Registration-interface can output the resulting transform(s) that map moving_image to
    fixed_image in a single file as a ``composite_transform`` (if ``write_composite_transform``
    is set to ``True``), or a list of transforms as ``forwards_transforms``. It can also output
    inverse transforms (from ``fixed_image`` to ``moving_image``) in a similar fashion using
    ``inverse_composite_transform``. Note that the order of ``forward_transforms`` is in 'natural'
    order: the first element should be applied first, the last element should be applied last.

    Note, however, that ANTS tools always apply lists of transformations in reverse order (the last
    transformation in the list is applied first). Therefore, if the output forward_transforms
    is a list, one can not directly feed it into, for example, ``ants.ApplyTransforms``. To
    make ``ants.ApplyTransforms`` apply the transformations in the same order as ``ants.Registration``,
    you have to provide the list of transformations in reverse order from ``forward_transforms``.
    ``reverse_forward_transforms`` outputs ``forward_transforms`` in reverse order and can be used for
    this purpose. Note also that, because ``composite_transform`` is always a single file, this
    output is preferred for  most use-cases.

    More information can be found in the `ANTS
    manual <https://sourceforge.net/projects/advants/files/Documentation/ants.pdf/download>`_.

    See below for some useful examples.

    Examples
    --------

    Set up a Registration node with some default settings. This Node registers
    'fixed1.nii' to 'moving1.nii' by first fitting a linear 'Affine' transformation, and
    then a non-linear 'SyN' transformation, both using the Mutual Information-cost
    metric.

    The registration is initialized by first applying the (linear) transform
    trans.mat.

    >>> import copy, pprint
    >>> from nipype.interfaces.ants import Registration
    >>> reg = Registration()
    >>> reg.inputs.fixed_image = 'fixed1.nii'
    >>> reg.inputs.moving_image = 'moving1.nii'
    >>> reg.inputs.output_transform_prefix = "output_"
    >>> reg.inputs.initial_moving_transform = 'trans.mat'
    >>> reg.inputs.transforms = ['Affine', 'SyN']
    >>> reg.inputs.transform_parameters = [(2.0,), (0.25, 3.0, 0.0)]
    >>> reg.inputs.number_of_iterations = [[1500, 200], [100, 50, 30]]
    >>> reg.inputs.dimension = 3
    >>> reg.inputs.write_composite_transform = True
    >>> reg.inputs.collapse_output_transforms = False
    >>> reg.inputs.initialize_transforms_per_stage = False
    >>> reg.inputs.metric = ['Mattes']*2
    >>> reg.inputs.metric_weight = [1]*2 # Default (value ignored currently by ANTs)
    >>> reg.inputs.radius_or_number_of_bins = [32]*2
    >>> reg.inputs.sampling_strategy = ['Random', None]
    >>> reg.inputs.sampling_percentage = [0.05, None]
    >>> reg.inputs.convergence_threshold = [1.e-8, 1.e-9]
    >>> reg.inputs.convergence_window_size = [20]*2
    >>> reg.inputs.smoothing_sigmas = [[1,0], [2,1,0]]
    >>> reg.inputs.sigma_units = ['vox'] * 2
    >>> reg.inputs.shrink_factors = [[2,1], [3,2,1]]
    >>> reg.inputs.use_estimate_learning_rate_once = [True, True]
    >>> reg.inputs.use_histogram_matching = [True, True] # This is the default
    >>> reg.inputs.output_warped_image = 'output_warped_image.nii.gz'
    >>> reg.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 0 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'
    >>> reg.run()  # doctest: +SKIP

    Same as reg1, but first invert the initial transform ('trans.mat') before applying it.

    >>> reg.inputs.invert_initial_moving_transform = True
    >>> reg1 = copy.deepcopy(reg)
    >>> reg1.inputs.winsorize_lower_quantile = 0.025
    >>> reg1.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ]  --write-composite-transform 1'
    >>> reg1.run()  # doctest: +SKIP

    Clip extremely high intensity data points using winsorize_upper_quantile. All data points
    higher than the 0.975 quantile are set to the value of the 0.975 quantile.

    >>> reg2 = copy.deepcopy(reg)
    >>> reg2.inputs.winsorize_upper_quantile = 0.975
    >>> reg2.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ]  --write-composite-transform 1'

    Clip extremely low intensity data points using winsorize_lower_quantile. All data points
    lower than the 0.025 quantile are set to the original value at the 0.025 quantile.


    >>> reg3 = copy.deepcopy(reg)
    >>> reg3.inputs.winsorize_lower_quantile = 0.025
    >>> reg3.inputs.winsorize_upper_quantile = 0.975
    >>> reg3.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ]  --write-composite-transform 1'

    Use float instead of double for computations (saves memory usage)

    >>> reg3a = copy.deepcopy(reg)
    >>> reg3a.inputs.float = True
    >>> reg3a.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --float 1 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    Force to use double instead of float for computations (more precision and memory usage).

    >>> reg3b = copy.deepcopy(reg)
    >>> reg3b.inputs.float = False
    >>> reg3b.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --float 0 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    'collapse_output_transforms' can be used to put all transformation in a single 'composite_transform'-
    file. Note that forward_transforms will now be an empty list.

    >>> # Test collapse transforms flag
    >>> reg4 = copy.deepcopy(reg)
    >>> reg4.inputs.save_state = 'trans.mat'
    >>> reg4.inputs.restore_state = 'trans.mat'
    >>> reg4.inputs.initialize_transforms_per_stage = True
    >>> reg4.inputs.collapse_output_transforms = True
    >>> outputs = reg4._list_outputs()
    >>> pprint.pprint(outputs)  # doctest: +ELLIPSIS,
    {'composite_transform': '...data/output_Composite.h5',
     'elapsed_time': <undefined>,
     'forward_invert_flags': [],
     'forward_transforms': [],
     'inverse_composite_transform': '...data/output_InverseComposite.h5',
     'inverse_warped_image': <undefined>,
     'metric_value': <undefined>,
     'reverse_forward_invert_flags': [],
     'reverse_forward_transforms': [],
     'reverse_invert_flags': [],
     'reverse_transforms': [],
     'save_state': '...data/trans.mat',
     'warped_image': '...data/output_warped_image.nii.gz'}
    >>> reg4.cmdline
    'antsRegistration --collapse-output-transforms 1 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 1 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'


    >>> # Test collapse transforms flag
    >>> reg4b = copy.deepcopy(reg4)
    >>> reg4b.inputs.write_composite_transform = False
    >>> outputs = reg4b._list_outputs()
    >>> pprint.pprint(outputs)  # doctest: +ELLIPSIS,
    {'composite_transform': <undefined>,
     'elapsed_time': <undefined>,
     'forward_invert_flags': [False, False],
     'forward_transforms': ['...data/output_0GenericAffine.mat',
     '...data/output_1Warp.nii.gz'],
     'inverse_composite_transform': <undefined>,
     'inverse_warped_image': <undefined>,
     'metric_value': <undefined>,
     'reverse_forward_invert_flags': [False, False],
     'reverse_forward_transforms': ['...data/output_1Warp.nii.gz',
     '...data/output_0GenericAffine.mat'],
     'reverse_invert_flags': [True, False],
     'reverse_transforms': ['...data/output_0GenericAffine.mat',     '...data/output_1InverseWarp.nii.gz'],
     'save_state': '...data/trans.mat',
     'warped_image': '...data/output_warped_image.nii.gz'}
    >>> reg4b.aggregate_outputs()  # doctest: +SKIP
    >>> reg4b.cmdline
    'antsRegistration --collapse-output-transforms 1 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 1 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 0'

    One can use multiple similarity metrics in a single registration stage.The Node below first
    performs a linear registation using only the Mutual Information ('Mattes')-metric.
    In a second stage, it performs a non-linear registration ('Syn') using both a
    Mutual Information and a local cross-correlation ('CC')-metric. Both metrics are weighted
    equally ('metric_weight' is .5 for both). The Mutual Information- metric uses 32 bins.
    The local cross-correlations (correlations between every voxel's neighborhoods) is computed
    with a radius of 4.

    >>> # Test multiple metrics per stage
    >>> reg5 = copy.deepcopy(reg)
    >>> reg5.inputs.fixed_image = 'fixed1.nii'
    >>> reg5.inputs.moving_image = 'moving1.nii'
    >>> reg5.inputs.metric = ['Mattes', ['Mattes', 'CC']]
    >>> reg5.inputs.metric_weight = [1, [.5,.5]]
    >>> reg5.inputs.radius_or_number_of_bins = [32, [32, 4] ]
    >>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage
    >>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]]
    >>> reg5.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 4, None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    ANTS Registration can also use multiple modalities to perform the registration. Here it is assumed
    that fixed1.nii and fixed2.nii are in the same space, and so are moving1.nii and
    moving2.nii. First, a linear registration is performed matching fixed1.nii to moving1.nii,
    then a non-linear registration is performed to match fixed2.nii to moving2.nii, starting from
    the transformation of the first step.

    >>> # Test multiple inputS
    >>> reg6 = copy.deepcopy(reg5)
    >>> reg6.inputs.fixed_image = ['fixed1.nii', 'fixed2.nii']
    >>> reg6.inputs.moving_image = ['moving1.nii', 'moving2.nii']
    >>> reg6.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric CC[ fixed2.nii, moving2.nii, 0.5, 4, None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    Different methods can be used for the interpolation when applying transformations.

    >>> # Test Interpolation Parameters (BSpline)
    >>> reg7a = copy.deepcopy(reg)
    >>> reg7a.inputs.interpolation = 'BSpline'
    >>> reg7a.inputs.interpolation_parameters = (3,)
    >>> reg7a.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation BSpline[ 3 ] --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    >>> # Test Interpolation Parameters (MultiLabel/Gaussian)
    >>> reg7b = copy.deepcopy(reg)
    >>> reg7b.inputs.interpolation = 'Gaussian'
    >>> reg7b.inputs.interpolation_parameters = (1.0, 1.0)
    >>> reg7b.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Gaussian[ 1.0, 1.0 ] --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    BSplineSyN non-linear registration with custom parameters.

    >>> # Test Extended Transform Parameters
    >>> reg8 = copy.deepcopy(reg)
    >>> reg8.inputs.transforms = ['Affine', 'BSplineSyN']
    >>> reg8.inputs.transform_parameters = [(2.0,), (0.25, 26, 0, 3)]
    >>> reg8.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform BSplineSyN[ 0.25, 26, 0, 3 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    Mask the fixed image in the second stage of the registration (but not the first).

    >>> # Test masking
    >>> reg9 = copy.deepcopy(reg)
    >>> reg9.inputs.fixed_image_masks = ['NULL', 'fixed1.nii']
    >>> reg9.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --masks [ NULL, NULL ] --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --masks [ fixed1.nii, NULL ] --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'

    Here we use both a warpfield and a linear transformation, before registration commences.  Note that
    the first transformation that needs to be applied ('ants_Warp.nii.gz') is last in the list of
    'initial_moving_transform'.

    >>> # Test initialization with multiple transforms matrices (e.g., unwarp and affine transform)
    >>> reg10 = copy.deepcopy(reg)
    >>> reg10.inputs.initial_moving_transform = ['func_to_struct.mat', 'ants_Warp.nii.gz']
    >>> reg10.inputs.invert_initial_moving_transform = [False, False]
    >>> reg10.cmdline
    'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ func_to_struct.mat, 0 ] [ ants_Warp.nii.gz, 0 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ]  --write-composite-transform 1'
    r   ZantsRegistrationFr   r   r   r   r   c                s"   t t| jf | d | _d | _d S )N)rb   r   __init___elapsed_time_metric_value)rM   rJ   )rg   r@   rA   r     s    zRegistration.__init__r   c                s   t t| j|}|jp|j}|r|jd}xZ|d d d	 D ]H}|j jdrdt|j j	dd| _
q:d|kr:t|jdd | _P q:W |S )
N
r   zTotal elapsed time:zTotal elapsed time: r   Z
DIAGNOSTICrQ   r   )rb   r   _run_interfacestdoutmergedsplitstrip
startswithr   replacer   r   )rM   runtimeZcorrect_return_codesoutputlinesl)rg   r@   rA   r     s    
zRegistration._run_interfacec       
         s  j j| }tj jd j jd |j j| j j| j j| d}tj jrtj jrtj j| }|rt||d< tj j	rj j	rj j	| }|r||d< t
|trht|j }ttdt|}t }x|D ] t fdd|D }	tj jdkrj jd |	d< nj j  |	d< tj jdkrHj jd |	d	< nj j  |	d	< |j|	 qW n|g}fd
d|D S )z
        Format the antsRegistration -m metric argument(s).

        Parameters
        ----------
        index: the stage index
        r   )r0   r1   r   weightradius_or_binsoptionalr   r   c                s   g | ]\}}||  fqS r@   r@   )rY   kv)ir@   rA   r\   5  s    z/Registration._format_metric.<locals>.<listcomp>r   r0   r1   c                s   g | ]} j f |qS r@   )_format_metric_argument)rY   re   )rM   r@   rA   r\   F  s    )rJ   r   dictr0   r1   r4   r   r
   r   r   
isinstancelistitemsrH   rI   rK   )
rM   rZ   Z
name_inputZstage_inputsr   r   r   Zindexesspecstempr@   )r   rM   rA   _format_metric
  s@    	




zRegistration._format_metricc              K   s   d| d | d | d | d | d f }d| kr8| d }nd| krHt j}nd }|rt|d	| 7 }d| krt|d
| d  7 }|d7 }|S )Nz%s[ %s, %s, %g, %dr   r0   r1   r   r   r   r   z, %sz, %gz ])r   DEF_SAMPLING_STRATEGY)kwargsrN   r   r@   r@   rA   r   H  s"    
z$Registration._format_metric_argumentc             C   sX   g }|j d| jj|   djdd | jj| D }|j d|  |j d dj|S )Nz%s[ z, c             S   s   g | ]}t |qS r@   )str)rY   elementr@   r@   rA   r\   i  s    z2Registration._format_transform.<locals>.<listcomp>z%sz ]r   )rK   rJ   r   rL   r   )rM   rZ   rN   rT   r@   r@   rA   _format_transforme  s    
zRegistration._format_transformc       	      C   s  g }xt t| jjD ]}|jd| j|  x | j|D ]}|jd|  q>W |jd| j|  t| jj	r|jd| j
| jj| | jj	| f  n|jd| j
| jj|   |jd| j
| jj|   t| jjr|jd| jj|   t| jjr:t| jjtr | jj}n| jj| }|jd|  t| jjrd|jd	| j
| jj|   tt| jjt| jjfrt| jjrt| jj}|t|d
kr|nd }nd}t| jjrt| jj}|t|d
kr|nd }nd}|jd||f  qW dj|S )Nz--transform %sz--metric %sz--convergence %sz--smoothing-sigmas %s%sz--smoothing-sigmas %sz--shrink-factors %sz$--use-estimate-learning-rate-once %dz--use-histogram-matching %dz--restrict-deformation %sr   r   rx   z--masks [ %s, %s ]rG   )rH   rI   rJ   r   rK   r   r   _format_convergencer
   r   r_   r<   r   r   r:   r   boolr   anyru   rz   r   rL   )	rM   rN   rO   r   ZhistvalZfixed_masksZ
fixed_maskZmoving_masksZmoving_maskr@   r@   rA   _format_registrationo  sV    

z!Registration._format_registrationc             C   sx   d }|s>t | jjr:| jjr:| jj}t|tr:d| jj }|S d }t | jjrt| jjrt| jj}t|trtd| jj }|S )Nz%s_Warped.nii.gzz%s_InverseWarped.nii.gz)r
   rJ   r   r   r   r7   r   )rM   inverseZoutput_filenameZinv_output_filenamer@   r@   rA   _get_outputfilenames  s    

z!Registration._get_outputfilenamesc             C   st   | j | jj| }t| jj|kr0| jj| }n| jjd }t| jj|krZ| jj| }n| jjd }d|||f S )Nr   z[ %s, %g, %d ])r_   rJ   r;   rI   r   r   )rM   rO   Zconvergence_iterZconvergence_valueZconvergence_wsr@   r@   rA   r     s    z Registration._format_convergencec             C   sB   | j j| j jks(td| j j| j jf d| _d| j j| j jf S )Nz2Upper bound MUST be more than lower bound: %g > %gTz(--winsorize-image-intensities [ %s, %s ])rJ   r   r   RuntimeError_quantilesDone)rM   r@   r@   rA   #_format_winsorize_image_intensities  s    
z0Registration._format_winsorize_image_intensitiesc             C   sj   t | jj}dg| }t| jjrBt | jj|kr:td| jj}dd t| jj|D }djdg| S )Nr   zcInputs "initial_moving_transform" and "invert_initial_moving_transform"should have the same length.c             S   s    g | ]\}}d |t |f qS )z
[ %s, %d ])int)rY   Zxfmflagr@   r@   rA   r\     s   zARegistration._get_initial_transform_filenames.<locals>.<listcomp>rG   z--initial-moving-transform)rI   rJ   r}   r
   r   	ExceptionziprL   )rM   Zn_transformsZinvert_flagsrN   r@   r@   rA    _get_initial_transform_filenames  s    
z-Registration._get_initial_transform_filenamesc                s  |dkr8t | jjr(d| jj| jjf S d| jj S nB|dkrH| j S |dkrX| j S |dkrt | jjrt| jjnd}d| jjd | jjd |f S |d	kr| jj	dkrt | jj
rd| jj	djdd | jj
D f S d| jj	 S n|dkrL| jdd}| jdd}|r(|r(d| jj||f S |r>d| jj|f S d| jj S n.|dks`|dkrz| jsp| j S d| _dS tt| j|||S )Nry   z--masks [ %s, %s ]z
--masks %sr   r}   r|   r   z)--initial-moving-transform [ %s, %s, %d ]r   r   r   r   r   z--interpolation %s[ %s ]z, c             S   s   g | ]}t |qS r@   )r   )rY   paramr@   r@   rA   r\     s    z,Registration._format_arg.<locals>.<listcomp>z--interpolation %sr7   F)r   Tz--output [ %s, %s, %s ]z--output [ %s, %s ]z--output %sr   r   r   )r   r   r   r   )r
   rJ   r{   ry   r   r   r|   r0   r1   r   r   rL   r   r7   r   r   rb   r   rc   )rM   rd   re   rf   Zdo_center_of_mass_initout_filenameinv_out_filename)rg   r@   rA   rc     s`    

   
zRegistration._format_argc          	   C   s^   ddddddddd| _ |t| j j kr:| j | }|}nd	}|rHd
}nd}d|||f |fS )Nz	Rigid.matz
Affine.matzGenericAffine.matzSimilarity.matzTranslation.matzBSpline.txtz#DerivedInitialMovingTranslation.mat)r   r   GenericAffiner   r   r   r   InitialFzInverseWarp.nii.gzzWarp.nii.gzz%s%d%s)Zlow_dimensional_transform_mapr   keys)rM   prefixcountr   r   suffixZinverse_moder@   r@   rA   _output_filenames9  s     

zRegistration._output_filenamesc                s   j  j }g |d< g |d< g |d< g |d< dgt jj }t jjrR jj} jjr jjd }t	j
j||d<  jjd }t	j
j||d	< nĈ jjsXd
}t jjr|d   jj7  < |d  |7  <  jj|d  |d< dd |D |d  |d< |t jj7 }nt jjr j jj|d\}} j jj|dd\}}|d jt	j
j| |d jd |d jd
t	j
j| |d jd
d |d7 }xtt jjD ]}	 j jj| jj|	 \}} j jj| jj|	 d\}}|d jt	j
j| |d j| |d jd
t	j
j| |d jd
| |d7 }qW nd
} fdd jjD }
g }t jjst jjr|
jd
d t|
r|jd t|
s|jd x|D ]} j jj||dd\}} j jj||dd\}}|d jt	j
j| |d j| |d jt	j
j| |d j| |d7 }qW  jdd} jdd}|rt	j
j||d< |rt	j
j||d< t jjrt	j
j jj|d<  jr҈ j|d<  jr j|d< |d d d d |d< |d d d d |d< |S )Nr   r   r   r   FzComposite.h5r   zInverseComposite.h5r   r   c             S   s   g | ]
}| qS r@   r@   )rY   er@   r@   rA   r\   s  s    z.Registration._list_outputs.<locals>.<listcomp>r   Tr   c                s   g | ]}| j kqS r@   )_linear_transform_names)rY   t)rM   r@   rA   r\     s    r   r"   )r   r   r   r   r   r   r   r   r   r   )rh   ri   rI   rJ   r}   r
   r   r   r7   rj   rk   rl   r   r|   r   rK   insertrH   r   r   allr   r   r   r   )rM   rm   r   filenameZtransform_countZforward_filenameZforward_inversemodeZreverse_filenameZreverse_inversemoder   Z	is_linearZcollapse_listr   r   r   r@   )rM   rA   rn   O  s    










zRegistration._list_outputsr   )r   )F)F)r+   r,   r-   ro   r   rp   rt   rq   r   rr   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   rc   r   rn   rs   r@   r@   )rg   rA   r   p  s4     s>
>
B
r   c            
   @   s   e Zd ZejdddddddZeddd	d
Zedddd
ZejdddddddddZ	ej
dgddddZejdgdddZejddddgdddZejejddd dgdd!dZeddd"d#Zedd$gd%d&Zd'S )(MeasureImageSimilarityInputSpecr   r   r]   z--dimensionality %dr   z-Dimensionality of the fixed/moving image pair)r   r   r   Tz)Image to which the moving image is warped)r   r   r   zFImage to apply transformation to (generally a coregistered functional)r   r   r   r~   r   r   z%s)r   r   r   g      ?z(The "metricWeight" variable is not used.)r    r'   r   r   z^The number of bins in each stage for the MI and Mattes metric, or the radius for other metrics)r    r   r   r   r   r   zManner of choosing point set over which to optimize the metric. Defaults to "None" (i.e. a dense sampling of one sample per voxel).)r    r   r   g        )r   r   z[Percentage of points accessible to the sampling strategy over which to optimize the metric.z<mask used to limit metric sampling region of the fixed image)r   r   r   ry   z=mask used to limit metric sampling region of the moving image)r   r    r   N)r+   r,   r-   r   r.   r/   r   r0   r1   r   r3   r4   r5   r   r   r   r   r   ry   r{   r@   r@   r@   rA   r    sX   r  c               @   s   e Zd Zej ZdS ) MeasureImageSimilarityOutputSpecN)r+   r,   r-   r   r3   
similarityr@   r@   r@   rA   r    s   r  c                   sF   e Zd ZdZd ZeZeZdd Z	dd Z
 fddZdd	d
Z  ZS )MeasureImageSimilaritya  


    Examples
    --------

    >>> from nipype.interfaces.ants import MeasureImageSimilarity
    >>> sim = MeasureImageSimilarity()
    >>> sim.inputs.dimension = 3
    >>> sim.inputs.metric = 'MI'
    >>> sim.inputs.fixed_image = 'T1.nii'
    >>> sim.inputs.moving_image = 'resting.nii'
    >>> sim.inputs.metric_weight = 1.0
    >>> sim.inputs.radius_or_number_of_bins = 5
    >>> sim.inputs.sampling_strategy = 'Regular'
    >>> sim.inputs.sampling_percentage = 1.0
    >>> sim.inputs.fixed_image_mask = 'mask.nii'
    >>> sim.inputs.moving_image_mask = 'mask.nii.gz'
    >>> sim.cmdline
    'MeasureImageSimilarity --dimensionality 3 --masks ["mask.nii","mask.nii.gz"] --metric MI["T1.nii","resting.nii",1.0,5,Regular,1.0]'
    c          	   C   s8   dj | jj| jj| jj| jj| jj| jj| jjd}|S )Nz--metric {metric}["{fixed_image}","{moving_image}",{metric_weight},{radius_or_number_of_bins},{sampling_strategy},{sampling_percentage}])r   r0   r1   r4   r   r   r   )	rW   rJ   r   r0   r1   r4   r   r   r   )rM   rN   r@   r@   rA   _metric_constructor9  s    z*MeasureImageSimilarity._metric_constructorc             C   s4   | j jr dj| j j| j jd}ndj| j jd}|S )Nz4--masks ["{fixed_image_mask}","{moving_image_mask}"])ry   r{   z--masks "{fixed_image_mask}")ry   )rJ   r{   rW   ry   )rM   rN   r@   r@   rA   _mask_constructorH  s    z(MeasureImageSimilarity._mask_constructorc                s4   |dkr| j  S |dkr | j S tt| j|||S )Nr   ry   )r  r  rb   r  rc   )rM   rd   re   rf   )rg   r@   rA   rc   T  s
    z"MeasureImageSimilarity._format_argNc             C   s&   | j  }|jjd}t|d |_|S )Nr   r   )rh   r   r   r   r  )rM   r   Zneeded_outputsrm   r   r@   r@   rA   aggregate_outputs[  s    z(MeasureImageSimilarity.aggregate_outputs)NN)r+   r,   r-   ro   rp   r  rq   r  rr   r  r  rc   r  rs   r@   r@   )rg   rA   r    s   r  c               @   s   e Zd ZejddddddZeeddddd	d
Zeedddddd
Z	e
dddddZejeddddZejddddddddddd
Zejddd d!Zejd"dd#d$d%Zejd&dd'd(d%Zejd)d*d+d,ddZd-S ).RegistrationSynQuickInputSpecr   r   z-d %dTzimage dimension (2 or 3))r   r   r   )r   z-f %s...z.Fixed image or source image or reference image)r   r   r   z-m %s...zMoving image or target imager   z-o %sz.A prefix that is prepended to all output files)r   r   r   zNumber of threads (default = 1)z-n %d)r'   r   r   r   sr   rasrbbrz-t %szTransform type

  * t:  translation
  * r:  rigid
  * a:  rigid + affine
  * s:  rigid + affine + deformable syn (default)
  * sr: rigid + deformable syn
  * b:  rigid + affine + deformable b-spline syn
  * br: rigid + deformable b-spline syn

)r   r   r   Fz-j %dzuse histogram matching)r   r       z-r %dzbhistogram bins for mutual information in SyN stage                                  (default = 32))r'   r   r   r      z-s %dzespline distance for deformable B-spline SyN transform                                  (default = 26)doubler   z-p %sz!precision type (default = double)N)r+   r,   r-   r   r.   r/   r	   r   r0   r1   r   output_prefixr5   r   num_threadstransform_typer9   r:   Zhistogram_binsZspline_distanceprecision_typer@   r@   r@   rA   r	  b  sf   r	  c               @   sH   e Zd ZedddZedddZedddZedddZedddZdS )	RegistrationSynQuickOutputSpecTzWarped image)r   r   zInverse warped imagezAffine matrixzForward warp fieldzInverse warp fieldN)	r+   r,   r-   r   r   r   
out_matrixforward_warp_fieldinverse_warp_fieldr@   r@   r@   rA   r    s
   r  c                   s<   e Zd ZdZdZeZeZdd Z	 fddZ
dd Z  ZS )	RegistrationSynQuickaL  
    Registration using a symmetric image normalization method (SyN).
    You can read more in Avants et al.; Med Image Anal., 2008
    (https://www.ncbi.nlm.nih.gov/pubmed/17659998).

    Examples
    --------

    >>> from nipype.interfaces.ants import RegistrationSynQuick
    >>> reg = RegistrationSynQuick()
    >>> reg.inputs.fixed_image = 'fixed1.nii'
    >>> reg.inputs.moving_image = 'moving1.nii'
    >>> reg.inputs.num_threads = 2
    >>> reg.cmdline
    'antsRegistrationSyNQuick.sh -d 3 -f fixed1.nii -r 32 -m moving1.nii -n 2 -o transform -p d -s 26 -t s'
    >>> reg.run()  # doctest: +SKIP

    example for multiple images

    >>> from nipype.interfaces.ants import RegistrationSynQuick
    >>> reg = RegistrationSynQuick()
    >>> reg.inputs.fixed_image = ['fixed1.nii', 'fixed2.nii']
    >>> reg.inputs.moving_image = ['moving1.nii', 'moving2.nii']
    >>> reg.inputs.num_threads = 2
    >>> reg.cmdline
    'antsRegistrationSyNQuick.sh -d 3 -f fixed1.nii -f fixed2.nii -r 32 -m moving1.nii -m moving2.nii -n 2 -o transform -p d -s 26 -t s'
    >>> reg.run()  # doctest: +SKIP
    zantsRegistrationSyNQuick.shc             C   s   dS )z
        antsRegistrationSyNQuick.sh ignores environment variables,
        so override environment update from ANTSCommand class
        Nr@   )rM   r@   r@   rA   _num_threads_update  s    z(RegistrationSynQuick._num_threads_updatec                s*   |dkr|j |d  S tt| j|||S )Nr  r   )r   rb   r  rc   )rM   namere   r   )rg   r@   rA   rc     s    z RegistrationSynQuick._format_argc             C   sh   | j  j }tjj| jj}|d |d< |d |d< |d |d< | jjdkrd|d
 |d< |d |d< |S )NzWarped.nii.gzr   zInverseWarped.nii.gzr   z0GenericAffine.matr  r   r  r  z1Warp.nii.gzr  z1InverseWarp.nii.gzr  )r   r  r  )rr   ri   rj   rk   rl   rJ   r  r  )rM   rm   Zout_baser@   r@   rA   rn     s    z"RegistrationSynQuick._list_outputs)r+   r,   r-   ro   rp   r	  rq   r  rr   r  rc   rn   rs   r@   r@   )rg   rA   r    s   r  c               @   s\   e Zd ZejdddddddZedd	d
ddZeedddddddZ	e
ddd	dddZdS )CompositeTransformUtilInputSpecassembledisassemblez--%sr   Tz>What to do with the transform inputs (assemble or disassemble))r   r   r   r   Fz%sr   z-Output file path (only used for disassembly).)r   r   r   r   )r   z%s...r   zInput transform file(s))r   r   r   r   r   r]   zHA prefix that is prepended to all output files (only used for assembly).)r   r   r   r   N)r+   r,   r-   r   r.   processr   out_filer	   in_filer   r  r@   r@   r@   rA   r    s0   r  c               @   s*   e Zd ZeddZeddZeddZdS ) CompositeTransformUtilOutputSpeczAffine transform component)r   zDisplacement field componentzCompound transformation fileN)r+   r,   r-   r   rC   displacement_fieldr"  r@   r@   r@   rA   r$    s   

r$  c                   s<   e Zd ZdZd ZeZeZdd Z	 fddZ
dd Z  ZS )CompositeTransformUtila  
    ANTs utility which can combine or break apart transform files into their individual
    constituent components.

    Examples
    --------

    >>> from nipype.interfaces.ants import CompositeTransformUtil
    >>> tran = CompositeTransformUtil()
    >>> tran.inputs.process = 'disassemble'
    >>> tran.inputs.in_file = 'output_Composite.h5'
    >>> tran.cmdline
    'CompositeTransformUtil --disassemble output_Composite.h5 transform'
    >>> tran.run()  # doctest: +SKIP

    example for assembling transformation files

    >>> from nipype.interfaces.ants import CompositeTransformUtil
    >>> tran = CompositeTransformUtil()
    >>> tran.inputs.process = 'assemble'
    >>> tran.inputs.out_file = 'my.h5'
    >>> tran.inputs.in_file = ['AffineTransform.mat', 'DisplacementFieldTransform.nii.gz']
    >>> tran.cmdline
    'CompositeTransformUtil --assemble my.h5 AffineTransform.mat DisplacementFieldTransform.nii.gz '
    >>> tran.run()  # doctest: +SKIP
    c             C   s   dS )z
        CompositeTransformUtil ignores environment variables,
        so override environment update from ANTSCommand class
        Nr@   )rM   r@   r@   rA   r  :  s    z*CompositeTransformUtil._num_threads_updatec                sD   |dkr| j jdkrdS |dkr0| j jdkr0dS tt| j|||S )Nr  r  r   r"  r   )rJ   r!  rb   r&  rc   )rM   r  re   r   )rg   r@   rA   rc   A  s
    z"CompositeTransformUtil._format_argc             C   sp   | j  j }| jjdkrLtjjdj| jj|d< tjjdj| jj|d< | jjdkrltjj| jj	|d< |S )Nr   z00_{}_AffineTransform.matrC   z'01_{}_DisplacementFieldTransform.nii.gzr%  r  r"  )
rr   ri   rJ   r!  rj   rk   rl   rW   r  r"  )rM   rm   r@   r@   rA   rn   H  s    z$CompositeTransformUtil._list_outputs)r+   r,   r-   ro   rp   r  rq   r$  rr   r  rc   rn   rs   r@   r@   )rg   rA   r&    s   r&  )ro   rj   Zutils.filemanipr   baser   r   r   r   r	   r
   r   r   r   r   rB   rF   rt   r   r   r  r  r  r	  r  r  r  r$  r&  r@   r@   r@   rA   <module>   s8    m   R      s<EO<