LSSTApplications  16.0-11-g09ed895+2,16.0-11-g12e47bd,16.0-11-g9bb73b2+6,16.0-12-g5c924a4+6,16.0-14-g9a974b3+1,16.0-15-g1417920+1,16.0-15-gdd5ca33+1,16.0-16-gf0259e2,16.0-17-g31abd91+7,16.0-17-g7d7456e+7,16.0-17-ga3d2e9f+13,16.0-18-ga4d4bcb+1,16.0-18-gd06566c+1,16.0-2-g0febb12+21,16.0-2-g9d5294e+69,16.0-2-ga8830df+6,16.0-20-g21842373+7,16.0-24-g3eae5ec,16.0-28-gfc9ea6c+4,16.0-29-ge8801f9,16.0-3-ge00e371+34,16.0-4-g18f3627+13,16.0-4-g5f3a788+20,16.0-4-ga3eb747+10,16.0-4-gabf74b7+29,16.0-4-gb13d127+6,16.0-49-g42e581f7+6,16.0-5-g27fb78a+7,16.0-5-g6a53317+34,16.0-5-gb3f8a4b+87,16.0-6-g9321be7+4,16.0-6-gcbc7b31+42,16.0-6-gf49912c+29,16.0-7-gd2eeba5+51,16.0-71-ge89f8615e,16.0-8-g21fd5fe+29,16.0-8-g3a9f023+20,16.0-8-g4734f7a+1,16.0-8-g5858431+3,16.0-9-gf5c1f43+8,master-gd73dc1d098+1,w.2019.01
LSSTDataManagementBasePackage
warper.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 import lsst.pex.config as pexConfig
23 import lsst.geom
24 import lsst.afw.image as afwImage
25 from . import mathLib
26 
27 __all__ = ["Warper", "WarperConfig"]
28 
29 
30 def computeWarpedBBox(destWcs, srcBBox, srcWcs):
31  """Compute the bounding box of a warped image
32 
33  The bounding box includes all warped pixels and it may be a bit oversize.
34 
35  @param destWcs: WCS of warped exposure, an lsst.afw.geom.SkyWcs
36  @param srcBBox: parent bounding box of unwarped image
37  @param srcWcs: WCS of unwarped image, an lsst.afw.geom.SkyWcs
38 
39  @return destBBox: bounding box of warped exposure
40  """
41  srcPosBox = lsst.geom.Box2D(srcBBox)
42  destPosBox = lsst.geom.Box2D()
43  for inX in (srcPosBox.getMinX(), srcPosBox.getMaxX()):
44  for inY in (srcPosBox.getMinY(), srcPosBox.getMaxY()):
45  destPos = destWcs.skyToPixel(srcWcs.pixelToSky(inX, inY))
46  destPosBox.include(destPos)
47  destBBox = lsst.geom.Box2I(destPosBox, lsst.geom.Box2I.EXPAND)
48  return destBBox
49 
50 
51 _DefaultInterpLength = 10
52 _DefaultCacheSize = 1000000
53 
54 
55 class WarperConfig(pexConfig.Config):
56  warpingKernelName = pexConfig.ChoiceField(
57  dtype=str,
58  doc="Warping kernel",
59  default="lanczos3",
60  allowed={
61  "bilinear": "bilinear interpolation",
62  "lanczos3": "Lanczos kernel of order 3",
63  "lanczos4": "Lanczos kernel of order 4",
64  "lanczos5": "Lanczos kernel of order 5",
65  }
66  )
67  maskWarpingKernelName = pexConfig.ChoiceField(
68  dtype=str,
69  doc="Warping kernel for mask (use warpingKernelName if '')",
70  default="bilinear",
71  allowed={
72  "": "use the regular warping kernel for the mask plane, as well as the image and variance planes",
73  "bilinear": "bilinear interpolation",
74  "lanczos3": "Lanczos kernel of order 3",
75  "lanczos4": "Lanczos kernel of order 4",
76  "lanczos5": "Lanczos kernel of order 5",
77  }
78  )
79  interpLength = pexConfig.Field(
80  dtype=int,
81  doc="interpLength argument to lsst.afw.math.warpExposure",
82  default=_DefaultInterpLength,
83  )
84  cacheSize = pexConfig.Field(
85  dtype=int,
86  doc="cacheSize argument to lsst.afw.math.SeparableKernel.computeCache",
87  default=_DefaultCacheSize,
88  )
89  growFullMask = pexConfig.Field(
90  dtype=int,
91  doc="mask bits to grow to full width of image/variance kernel,",
92  default=afwImage.Mask.getPlaneBitMask("EDGE"),
93  )
94 
95 
96 class Warper:
97  """Warp images
98  """
99  ConfigClass = WarperConfig
100 
101  def __init__(self,
102  warpingKernelName,
103  interpLength=_DefaultInterpLength,
104  cacheSize=_DefaultCacheSize,
105  maskWarpingKernelName="",
106  growFullMask=afwImage.Mask.getPlaneBitMask("EDGE"),):
107  """Create a Warper
108 
109  Inputs:
110  - warpingKernelName: argument to lsst.afw.math.makeWarpingKernel
111  - interpLength: interpLength argument to lsst.afw.warpExposure
112  - cacheSize: size of computeCache
113  - maskWarpingKernelName: name of mask warping kernel (if "" then use warpingKernelName);
114  an argument to lsst.afw.math.makeWarpingKernel
115  """
116  self._warpingControl = mathLib.WarpingControl(
117  warpingKernelName, maskWarpingKernelName, cacheSize, interpLength, growFullMask)
118 
119  @classmethod
120  def fromConfig(cls, config):
121  """Create a Warper from a config
122 
123  @param config: an instance of Warper.ConfigClass
124  """
125  return cls(
126  warpingKernelName=config.warpingKernelName,
127  maskWarpingKernelName=config.maskWarpingKernelName,
128  interpLength=config.interpLength,
129  cacheSize=config.cacheSize,
130  growFullMask=config.growFullMask,
131  )
132 
133  def getWarpingKernel(self):
134  """Get the warping kernel"""
135  return self._warpingControl.getWarpingKernel()
136 
138  """Get the mask warping kernel"""
140 
141  def warpExposure(self, destWcs, srcExposure, border=0, maxBBox=None, destBBox=None):
142  """Warp an exposure
143 
144  @param destWcs: WCS of warped exposure, an lsst.afw.geom.SkyWcs
145  @param srcExposure: exposure to warp
146  @param border: grow bbox of warped exposure by this amount in all directions (int pixels);
147  if negative then the bbox is shrunk;
148  border is applied before maxBBox;
149  ignored if destBBox is not None
150  @param maxBBox: maximum allowed parent bbox of warped exposure (an lsst.geom.Box2I or None);
151  if None then the warped exposure will be just big enough to contain all warped pixels;
152  if provided then the warped exposure may be smaller, and so missing some warped pixels;
153  ignored if destBBox is not None
154  @param destBBox: exact parent bbox of warped exposure (an lsst.geom.Box2I or None);
155  if None then border and maxBBox are used to determine the bbox,
156  otherwise border and maxBBox are ignored
157 
158  @return destExposure: warped exposure (of same type as srcExposure)
159 
160  @note: calls mathLib.warpExposure insted of self.warpImage because the former
161  copies attributes such as Calib, and that should be done in one place
162  """
163  destBBox = self._computeDestBBox(
164  destWcs=destWcs,
165  srcImage=srcExposure.getMaskedImage(),
166  srcWcs=srcExposure.getWcs(),
167  border=border,
168  maxBBox=maxBBox,
169  destBBox=destBBox,
170  )
171  destExposure = srcExposure.Factory(destBBox, destWcs)
172  mathLib.warpExposure(destExposure, srcExposure, self._warpingControl)
173  return destExposure
174 
175  def warpImage(self, destWcs, srcImage, srcWcs, border=0, maxBBox=None, destBBox=None):
176  """Warp an image or masked image
177 
178  @param destWcs: WCS of warped image, an lsst.afw.geom.SkyWcs
179  @param srcImage: image or masked image to warp
180  @param srcWcs: WCS of image, an lsst.afw.geom.SkyWcs
181  @param border: grow bbox of warped image by this amount in all directions (int pixels);
182  if negative then the bbox is shrunk;
183  border is applied before maxBBox;
184  ignored if destBBox is not None
185  @param maxBBox: maximum allowed parent bbox of warped image (an lsst.geom.Box2I or None);
186  if None then the warped image will be just big enough to contain all warped pixels;
187  if provided then the warped image may be smaller, and so missing some warped pixels;
188  ignored if destBBox is not None
189  @param destBBox: exact parent bbox of warped image (an lsst.geom.Box2I or None);
190  if None then border and maxBBox are used to determine the bbox,
191  otherwise border and maxBBox are ignored
192 
193  @return destImage: warped image or masked image (of same type as srcImage)
194  """
195  destBBox = self._computeDestBBox(
196  destWcs=destWcs,
197  srcImage=srcImage,
198  srcWcs=srcWcs,
199  border=border,
200  maxBBox=maxBBox,
201  destBBox=destBBox,
202  )
203  destImage = srcImage.Factory(destBBox)
204  mathLib.warpImage(destImage, destWcs, srcImage,
205  srcWcs, self._warpingControl)
206  return destImage
207 
208  def _computeDestBBox(self, destWcs, srcImage, srcWcs, border, maxBBox, destBBox):
209  """Process destBBox argument for warpImage and warpExposure
210 
211  @param destWcs: WCS of warped image, an lsst.afw.geom.SkyWcs
212  @param srcImage: image or masked image to warp
213  @param srcWcs: WCS of image, an lsst.afw.geom.SkyWcs
214  @param border: grow bbox of warped image by this amount in all directions (int pixels);
215  if negative then the bbox is shrunk;
216  border is applied before maxBBox;
217  ignored if destBBox is not None
218  @param maxBBox: maximum allowed parent bbox of warped image (an lsst.geom.Box2I or None);
219  if None then the warped image will be just big enough to contain all warped pixels;
220  if provided then the warped image may be smaller, and so missing some warped pixels;
221  ignored if destBBox is not None
222  @param destBBox: exact parent bbox of warped image (an lsst.geom.Box2I or None);
223  if None then border and maxBBox are used to determine the bbox,
224  otherwise border and maxBBox are ignored
225  """
226  if destBBox is None: # warning: == None fails due to Box2I.__eq__
227  destBBox = computeWarpedBBox(
228  destWcs, srcImage.getBBox(afwImage.PARENT), srcWcs)
229  if border:
230  destBBox.grow(border)
231  if maxBBox is not None:
232  destBBox.clip(maxBBox)
233  return destBBox
def _computeDestBBox(self, destWcs, srcImage, srcWcs, border, maxBBox, destBBox)
Definition: warper.py:208
A floating-point coordinate rectangle geometry.
Definition: Box.h:294
def getMaskWarpingKernel(self)
Definition: warper.py:137
def warpExposure(self, destWcs, srcExposure, border=0, maxBBox=None, destBBox=None)
Definition: warper.py:141
def computeWarpedBBox(destWcs, srcBBox, srcWcs)
Definition: warper.py:30
def __init__(self, warpingKernelName, interpLength=_DefaultInterpLength, cacheSize=_DefaultCacheSize, maskWarpingKernelName="", growFullMask=afwImage.Mask.getPlaneBitMask("EDGE"))
Definition: warper.py:106
def warpImage(self, destWcs, srcImage, srcWcs, border=0, maxBBox=None, destBBox=None)
Definition: warper.py:175
def fromConfig(cls, config)
Definition: warper.py:120
An integer coordinate rectangle.
Definition: Box.h:54