import os
import logging
import envoy
from .ants_error import ANTSError

def warp(moving, fixed, metric):
    """
    Warps to the given moving image to fit the fixed image. The result is a new image
    named by the moving image name without extension followed by 'Registered.nii.gz',
    e.g. 'image0004Registered.nii.gz'.
    
    :param moving: the file name of the image to transform
    :param fixed: the file name of the reference image
    :parm metric: the similarity metric
    :return: the name of the new image file
    """
    return WarpTransform(moving, fixed, metric).apply()

class WarpTransform:
    """An ANTS WarpTransform applies a deformation field and affine transform to an image."""
    
    def __init__(self, moving, fixed, metric):
        """
        :param moving: the file name of the image to transform
        :param fixed: the file name of the reference image
        :parm metric: the similarity metric
        :return: the new transform
        :rtype: WarpTransform
        """
        MAP = "ANTS 2 -m {metric} -i 100x100x10 -r Gauss[0,3] -t SyN[0.25] -o {output}"
        FIELD = "{output}Warp.nii.gz"
        AFFINE = "{output}Affine.txt"

        self.moving = moving
        self.fixed = fixed
        mstr = metric.format(fixed=fixed, moving=moving)
        name = os.path.splitext(moving)[0]
        cmd = MAP.format(metric=mstr, output=name)
        logging.info("Building the %(moving)s -> %(fixed)s warp transform with the following command:" % {'moving': moving, 'fixed': fixed})
        logging.info(cmd)
        r = envoy.run(cmd)
        if r.status_code:
            logging.error("Build transform failed with error code %d" % r.status_code)
            logging.error(r.std_err)
            raise ANTSError("Build transform unsuccessful; see the log for details")
        self.field = FIELD.format(output=name)
        self.affine = AFFINE.format(output=name)
        logging.info("The %(moving)s -> %(fixed)s deformation field is %(field)s" % {'moving': moving, 'fixed': fixed, 'field': self.field})
        logging.info("The %(moving)s -> %(fixed)s affine transform is %(affine)s" % {'moving': moving, 'fixed': fixed, 'affine': self.affine})
    
    def apply(self):
        """
        Applies this transform to the given moving image. The result is a new image named by
        the moving image name without extension followed by 'Registered.nii.gz', e.g.
        'image0004Registered.nii.gz'.
        
        :return: the name of the new image file
        """
        TARGET = "{output}Registered.nii.gz"
        REG = "WarpImageMultiTransform 2 {moving} {target} -R {fixed} {field} {affine}"
        
        target = TARGET.format(output=os.path.splitext(self.moving)[0])
        cmd = REG.format(fixed=self.fixed, moving=self.moving, target=target, field=self.field, affine=self.affine)
        logging.info("Applying the %(moving)s -> %(fixed)s warp transform with the following command:" % {'moving': self.moving, 'fixed': self.fixed})
        logging.info(cmd)
        r = envoy.run(cmd)
        if r.status_code:
            logging.error("Apply warp transform failed with error code %d" % r.status_code)
            logging.error(r.std_err)
            raise ANTSError("Apply warp transform unsuccessful; see the log for details")
        logging.info("Applied the %(moving)s -> %(fixed)s warp transform with result %(target)s" % {'moving': self.moving, 'fixed': self.fixed, 'target': target})
        return target
@@ -31,16 +31,50 @@
 t envoy%0A
+from .similarity_metrics import *%0A
 from .an
@@ -126,24 +126,29 @@
 ixed, metric
+=None
 ):%0A    %22%22%22%0A 
@@ -156,19 +156,16 @@
   Warps 
-to 
 the give
@@ -508,24 +508,52 @@
 arity metric
+ (default cross-correlation)
 %0A    :return
@@ -814,16 +814,46 @@
 , metric
+=None, iterations=%5B100,100,10%5D
 ):%0A     
@@ -985,32 +985,33 @@
 age%0A        :par
+a
 m metric: the si
@@ -1025,16 +1025,115 @@
 y metric
+ (default cross-correlation)%0A        :param iterations: the number of iterations in each resolution
 %0A       
@@ -1243,18 +1243,20 @@
  -i 
-100x100x10
+%7Biterations%7D
  -r 
@@ -1265,11 +1265,11 @@
 uss%5B
-0,3
+3,0
 %5D -t
@@ -1425,16 +1425,65 @@
 = fixed%0A
+        if not metric:%0A            metric = CC()%0A
         
@@ -1615,32 +1615,65 @@
 str, output=name
+, iterations='x'.join(iterations)
 )%0A        loggin

Add iterations option.