22 __all__ = [
"Warper", 
"WarperConfig"]
 
   24 import lsst.pex.config 
as pexConfig
 
   31     """Compute the bounding box of a warped image. 
   33     The bounding box includes all warped pixels and it may be a bit oversize. 
   37     destWcs : `lsst.afw.geom.SkyWcs` 
   38         WCS of warped exposure 
   39     srcBBox : `lsst.geom.Box2I` 
   40         parent bounding box of unwarped image 
   41     srcWcs : `lsst.afw.geom.SkyWcs` 
   46     destBBox: `lsst.geom.Box2I` 
   47         bounding box of warped exposure 
   51     for inX 
in (srcPosBox.getMinX(), srcPosBox.getMaxX()):
 
   52         for inY 
in (srcPosBox.getMinY(), srcPosBox.getMaxY()):
 
   53             destPos = destWcs.skyToPixel(srcWcs.pixelToSky(inX, inY))
 
   54             destPosBox.include(destPos)
 
   59 _DefaultInterpLength = 10
 
   60 _DefaultCacheSize = 1000000
 
   64     warpingKernelName = pexConfig.ChoiceField(
 
   69             "bilinear": 
"bilinear interpolation",
 
   70             "lanczos3": 
"Lanczos kernel of order 3",
 
   71             "lanczos4": 
"Lanczos kernel of order 4",
 
   72             "lanczos5": 
"Lanczos kernel of order 5",
 
   75     maskWarpingKernelName = pexConfig.ChoiceField(
 
   77         doc=
"Warping kernel for mask (use ``warpingKernelName`` if '')",
 
   80             "": 
"use the regular warping kernel for the mask plane, as well as the image and variance planes",
 
   81             "bilinear": 
"bilinear interpolation",
 
   82             "lanczos3": 
"Lanczos kernel of order 3",
 
   83             "lanczos4": 
"Lanczos kernel of order 4",
 
   84             "lanczos5": 
"Lanczos kernel of order 5",
 
   87     interpLength = pexConfig.Field(
 
   89         doc=
"``interpLength`` argument to `lsst.afw.math.warpExposure`",
 
   90         default=_DefaultInterpLength,
 
   92     cacheSize = pexConfig.Field(
 
   94         doc=
"``cacheSize`` argument to `lsst.afw.math.SeparableKernel.computeCache`",
 
   95         default=_DefaultCacheSize,
 
   97     growFullMask = pexConfig.Field(
 
   99         doc=
"mask bits to grow to full width of image/variance kernel,",
 
  100         default=afwImage.Mask.getPlaneBitMask(
"EDGE"),
 
  109     warpingKernelName : `str` 
  110         see `WarperConfig.warpingKernelName` 
  111     interpLength : `int`, optional 
  112         ``interpLength`` argument to `lsst.afw.math.warpExposure` 
  113     cacheSize : `int`, optional 
  115     maskWarpingKernelName : `str`, optional 
  116         name of mask warping kernel (if ``""`` then use ``warpingKernelName``); 
  117         see `WarperConfig.maskWarpingKernelName` 
  118     growFullMask : `int`, optional 
  119         mask bits to grow to full width of image/variance kernel 
  121     ConfigClass = WarperConfig
 
  125                  interpLength=_DefaultInterpLength,
 
  126                  cacheSize=_DefaultCacheSize,
 
  127                  maskWarpingKernelName="",
 
  128                  growFullMask=afwImage.Mask.getPlaneBitMask(
"EDGE"),):
 
  130             warpingKernelName, maskWarpingKernelName, cacheSize, interpLength, growFullMask)
 
  134         """Create a Warper from a config. 
  138         config : `WarperConfig` 
  139             The config to initialize the Warper with. 
  142             warpingKernelName=config.warpingKernelName,
 
  143             maskWarpingKernelName=config.maskWarpingKernelName,
 
  144             interpLength=config.interpLength,
 
  145             cacheSize=config.cacheSize,
 
  146             growFullMask=config.growFullMask,
 
  150         """Get the warping kernel. 
  155         """Get the mask warping kernel. 
  159     def warpExposure(self, destWcs, srcExposure, border=0, maxBBox=None, destBBox=None):
 
  164         destWcs : `lsst.afw.geom.SkyWcs` 
  165             WCS of warped exposure 
  168         border : `int`, optional 
  169             grow bbox of warped exposure by this amount in all directions 
  170             (in pixels); if negative then the bbox is shrunk; border is applied 
  171             before ``maxBBox``; ignored if ``destBBox`` is not `None` 
  172         maxBBox : `lsst.geom.Box2I`, optional 
  173             maximum allowed parent bbox of warped exposure; if `None` then the 
  174             warped exposure will be just big enough to contain all warped pixels; 
  175             if provided then the warped exposure may be smaller, and so 
  176             missing some warped pixels; ignored if ``destBBox`` is not `None` 
  177         destBBox : `lsst.geom.Box2I`, optional 
  178             exact parent bbox of warped exposure; if `None` then ``border`` and 
  179             ``maxBBox`` are used to determine the bbox, otherwise ``border`` 
  180             and ``maxBBox`` are ignored 
  184         destExposure : same type as ``srcExposure`` 
  189         calls `lsst.afw.math.warpExposure` insted of `~Warper.warpImage` because the former 
  190         copies attributes such as ``Calib``, and that should be done in one place 
  192         The PSF is not warped. To warp the PSF, use `lsst.meas.algorithms.WarpedPsf` 
  196             srcImage=srcExposure.getMaskedImage(),
 
  197             srcWcs=srcExposure.getWcs(),
 
  202         destExposure = srcExposure.Factory(destBBox, destWcs)
 
  206     def warpImage(self, destWcs, srcImage, srcWcs, border=0, maxBBox=None, destBBox=None):
 
  207         """Warp an image or masked image. 
  211         destWcs : `lsst.afw.geom.SkyWcs` 
  214             image or masked image to warp 
  215         srcWcs : `lsst.afw.geom.SkyWcs` 
  217         border : `int`, optional 
  218             grow bbox of warped image by this amount in all directions 
  219             (in pixels); if negative then the bbox is shrunk; border is applied 
  220             before ``maxBBox``; ignored if ``destBBox`` is not `None` 
  221         maxBBox : `lsst.geom.Box2I`, optional 
  222             maximum allowed parent bbox of warped image; if `None` then the 
  223             warped image will be just big enough to contain all warped pixels; 
  224             if provided then the warped image may be smaller, and so 
  225             missing some warped pixels; ignored if ``destBBox`` is not `None` 
  226         destBBox : `lsst.geom.Box2I`, optional 
  227             exact parent bbox of warped image; if `None` then ``border`` and 
  228             ``maxBBox`` are used to determine the bbox, otherwise ``border`` 
  229             and ``maxBBox`` are ignored 
  233         destImage : same type as ``srcExposure`` 
  234             warped image or masked image 
  244         destImage = srcImage.Factory(destBBox)
 
  245         mathLib.warpImage(destImage, destWcs, srcImage,
 
  249     def _computeDestBBox(self, destWcs, srcImage, srcWcs, border, maxBBox, destBBox):
 
  250         """Process destBBox argument for warpImage and warpExposure. 
  254         destWcs : `lsst.afw.geom.SkyWcs` 
  257             image or masked image to warp 
  258         srcWcs : `lsst.afw.geom.SkyWcs` 
  260         border : `int`, optional 
  261             grow bbox of warped image by this amount in all directions 
  262             (in pixels); if negative then the bbox is shrunk; border is applied 
  263             before ``maxBBox``; ignored if ``destBBox`` is not `None` 
  264         maxBBox : `lsst.geom.Box2I`, optional 
  265             maximum allowed parent bbox of warped image; if `None` then the 
  266             warped image will be just big enough to contain all warped pixels; 
  267             if provided then the warped image may be smaller, and so 
  268             missing some warped pixels; ignored if ``destBBox`` is not `None` 
  269         destBBox : `lsst.geom.Box2I`, optional 
  270             exact parent bbox of warped image; if `None` then ``border`` and 
  271             ``maxBBox`` are used to determine the bbox, otherwise ``border`` 
  272             and ``maxBBox`` are ignored 
  276                 destWcs, srcImage.getBBox(afwImage.PARENT), srcWcs)
 
  278                 destBBox.grow(border)
 
  279             if maxBBox 
is not None:
 
  280                 destBBox.clip(maxBBox)