27 from lsst.pex.config 
import Config, ListField, makeRegistry, \
 
   28     ConfigDictField, ConfigurableField
 
   29 from .transformFactory 
import makeTransform, makeIdentityTransform, \
 
   32 __all__ = [
"transformRegistry", 
"OneTransformConfig", 
"TransformConfig",
 
   33            "IdentityTransformConfig", 
"AffineTransformConfig", 
"RadialTransformConfig",
 
   34            "MultiTransformConfig"]
 
   37     """"A registry of ``Transform`` factories 
   39     A ``Transform`` factory is a function that obeys these rules: 
   40     - has an attribute ``ConfigClass`` 
   41     - takes one argument, ``config`` (an instance of ``ConfigClass``) by name 
   42     - returns a ``Transform`` 
   48     """A Config representing a ``Transform`` that does nothing. 
   52     lsst.afw.geom.makeIdentityTransform 
   58     """Make an identity ``Transform`` 
   63 identityFactory.ConfigClass = IdentityTransformConfig
 
   64 transformRegistry.register(
"identity", identityFactory)
 
   68     """A Config representing a single ``Transform`` in a compound ``Transform``. 
   72     lsst.afw.geom.MultiTransformConfig 
   74     transform = ConfigurableField(
 
   75         doc=
"Transform factory",
 
   76         target=identityFactory,
 
   81     """Invert a ``Transform`` specified by config. 
   83     return config.transform.apply().inverted()
 
   86 invertingFactory.ConfigClass = OneTransformConfig
 
   87 transformRegistry.register(
"inverted", invertingFactory)
 
   91     """A Config representing an affine ``Transform``. 
   95     lsst.afw.geom.makeTransform 
   98         doc=
"2x2 linear matrix in the usual numpy order; " 
   99             "to rotate a vector by theta use: cos(theta), sin(theta), " 
  100             "-sin(theta), cos(theta)",
 
  103         default=(1, 0, 0, 1),
 
  105     translation = ListField(
 
  106         doc=
"x, y translation vector",
 
  114     """Make an affine ``Transform`` 
  116     linear = numpy.array(config.linear)
 
  117     linear.shape = (2, 2)
 
  118     translation = numpy.array(config.translation)
 
  122 affineFactory.ConfigClass = AffineTransformConfig
 
  123 transformRegistry.register(
"affine", affineFactory)
 
  127     """A Config representing a radially symmetric ``Transform``. 
  131     lsst.afw.geom.makeRadialTransform 
  134         doc=
"Coefficients for the radial polynomial; coeff[0] must be 0",
 
  145                 f
"invalid radial transform coeffs {self.coeffs}: " 
  146                 "need len(coeffs)=0 or len(coeffs)>1, coeffs[0]==0, " 
  151     """Make a radial ``Transform`` 
  156 radialFactory.ConfigClass = RadialTransformConfig
 
  157 transformRegistry.register(
"radial", radialFactory)
 
  161     """A Config representing a chain of consecutive ``Transforms``. 
  163     transformDict = ConfigDictField(
 
  164         doc=
"Dict of index: OneTransformConfig (a transform wrapper); " 
  165             "key order is transform order",
 
  167         itemtype=OneTransformConfig,
 
  172     """Concatenate multiple ``Transforms`` 
  174     transformKeys = sorted(config.transformDict.keys())
 
  175     transformList = [config.transformDict[key].transform.apply()
 
  176                      for key 
in transformKeys]
 
  179     def concat(transform1, transform2):
 
  180         return transform1.then(transform2)
 
  182     return functools.reduce(concat, transformList)
 
  185 multiFactory.ConfigClass = MultiTransformConfig
 
  186 transformRegistry.register(
"multi", multiFactory)
 
  190     """Config that identifies ``Transforms`` by keyword. 
  195         `IdentityTransformConfig` 
  199         `AffineTransformConfig` 
  201         `RadialTransformConfig` 
  203         `MultiTransformConfig` 
  205     transform = transformRegistry.makeField(
 
  206         doc=
"a Transform from the registry"