1 from __future__
import absolute_import, division
2 from builtins
import str
25 """Application Framework image-related classes including Image, Mask and MaskedImage
34 from .
import imageLib
36 __all__ = [
"makeImageFromArray",
"makeMaskFromArray",
"makeMaskedImageFromArrays",
37 "wcsNearlyEqualOverBBox",
"assertWcsNearlyEqualOverBBox"]
39 suffixes = {str(numpy.uint16):
"U", str(numpy.int32): "I", str(numpy.float32): "F", str(numpy.float64): "D"}
42 """Construct an Image from a NumPy array, inferring the Image type from the NumPy type.
43 Return None if input is None.
47 cls = getattr(imageLib,
"Image%s" % (suffixes[str(array.dtype.type)],))
51 """Construct an Mask from a NumPy array, inferring the Mask type from the NumPy type.
52 Return None if input is None.
56 cls = getattr(imageLib,
"Mask%s" % (suffixes[str(array.dtype.type)],))
60 """Construct a MaskedImage from three NumPy arrays, inferring the MaskedImage types from the NumPy types.
62 cls = getattr(imageLib,
"MaskedImage%s" % (suffixes[str(image.dtype.type)],))
66 maxDiffPix=0.01, nx=5, ny=5, doShortCircuit=
True):
67 """!Compare two WCS over a rectangular grid of pixel positions
69 @param[in] wcs0 WCS 0 (an lsst.afw.image.Wcs)
70 @param[in] wcs1 WCS 1 (an lsst.afw.image.Wcs)
71 @param[in] bbox boundaries of pixel grid over which to compare the WCSs (an lsst.afw.geom.Box2I or Box2D)
72 @param[in] maxDiffSky maximum separation between sky positions computed using Wcs.pixelToSky
73 (an lsst.afw.geom.Angle)
74 @param[in] maxDiffPix maximum separation between pixel positions computed using Wcs.skyToPixel
75 @param[in] nx number of points in x for the grid of pixel positions
76 @param[in] ny number of points in y for the grid of pixel positions
77 @param[in] doShortCircuit if True then stop at the first error, else test all values in the grid
78 and return information about the worst violations found
80 @return return an empty string if the WCS are sufficiently close; else return a string describing
81 the largest error measured in pixel coordinates (if sky to pixel error was excessive) and sky coordinates
82 (if pixel to sky error was excessive). If doShortCircuit is true then the reported error is likely to be
83 much less than the maximum error across the whole pixel grid.
86 raise RuntimeError(
"nx = %s and ny = %s must both be positive" % (nx, ny))
87 if maxDiffSky <= 0*afwGeom.arcseconds:
88 raise RuntimeError(
"maxDiffSky = %s must be positive" % (maxDiffSky,))
90 raise RuntimeError(
"maxDiffPix = %s must be positive" % (maxDiffPix,))
93 xList = numpy.linspace(bboxd.getMinX(), bboxd.getMaxX(), nx)
94 yList = numpy.linspace(bboxd.getMinY(), bboxd.getMaxY(), ny)
96 measDiffSky = (maxDiffSky,
"?")
97 measDiffPix = (maxDiffPix,
"?")
98 for x, y
in itertools.product(xList, yList):
100 sky0 = wcs0.pixelToSky(fromPixPos)
101 sky1 = wcs1.pixelToSky(fromPixPos)
102 diffSky = sky0.angularSeparation(sky1)
103 if diffSky > measDiffSky[0]:
104 measDiffSky = (diffSky, fromPixPos)
108 toPixPos0 = wcs0.skyToPixel(sky0)
109 toPixPos1 = wcs1.skyToPixel(sky0)
110 diffPix = math.hypot(*(toPixPos0 - toPixPos1))
111 if diffPix > measDiffPix[0]:
112 measDiffPix = (diffPix, sky0)
117 if measDiffSky[0] > maxDiffSky:
118 msgList.append(
"%s arcsec max measured sky error > %s arcsec max allowed sky error at pix pos=%s" %
119 (measDiffSky[0].asArcseconds(), maxDiffSky.asArcseconds(), measDiffSky[1]))
120 if measDiffPix[0] > maxDiffPix:
121 msgList.append(
"%s max measured pix error > %s max allowed pix error at sky pos=%s" %
122 (measDiffPix[0], maxDiffPix, measDiffPix[1]))
124 return "; ".join(msgList)
127 maxDiffPix=0.01, nx=5, ny=5):
128 """!Return True if two WCS are nearly equal over a grid of pixel positions, else False
130 @param[in] wcs0 WCS 0 (an lsst.afw.image.Wcs)
131 @param[in] wcs1 WCS 1 (an lsst.afw.image.Wcs)
132 @param[in] bbox boundaries of pixel grid over which to compare the WCSs (an lsst.afw.geom.Box2I or Box2D)
133 @param[in] maxDiffSky maximum separation between sky positions computed using Wcs.pixelToSky
134 (an lsst.afw.geom.Angle)
135 @param[in] maxDiffPix maximum separation between pixel positions computed using Wcs.skyToPixel
136 @param[in] nx number of points in x for the grid of pixel positions
137 @param[in] ny number of points in y for the grid of pixel positions
143 maxDiffSky = maxDiffSky,
144 maxDiffPix = maxDiffPix,
147 doShortCircuit =
True,
150 @lsst.utils.tests.inTestCase
152 maxDiffPix=0.01, nx=5, ny=5, msg=
"WCSs differ"):
153 """!Compare pixelToSky and skyToPixel for two WCS over a rectangular grid of pixel positions
155 If the WCS are too divergent, call testCase.fail; the message describes the largest error measured
156 in pixel coordinates (if sky to pixel error was excessive) and sky coordinates (if pixel to sky error
157 was excessive) across the entire pixel grid.
159 @param[in] testCase unittest.TestCase instance the test is part of;
160 an object supporting one method: fail(self, msgStr)
161 @param[in] wcs0 WCS 0 (an lsst.afw.image.Wcs)
162 @param[in] wcs1 WCS 1 (an lsst.afw.image.Wcs)
163 @param[in] bbox boundaries of pixel grid over which to compare the WCSs (an lsst.afw.geom.Box2I or Box2D)
164 @param[in] maxDiffSky maximum separation between sky positions computed using Wcs.pixelToSky
165 (an lsst.afw.geom.Angle)
166 @param[in] maxDiffPix maximum separation between pixel positions computed using Wcs.skyToPixel
167 @param[in] nx number of points in x for the grid of pixel positions
168 @param[in] ny number of points in y for the grid of pixel positions
169 @param[in] msg exception message prefix; details of the error are appended after ": "
175 maxDiffSky = maxDiffSky,
176 maxDiffPix = maxDiffPix,
179 doShortCircuit =
False,
182 testCase.fail(
"%s: %s" % (msg, errMsg))
def wcsNearlyEqualOverBBox
Return True if two WCS are nearly equal over a grid of pixel positions, else False.
def _compareWcsOverBBox
Compare two WCS over a rectangular grid of pixel positions.
A floating-point coordinate rectangle geometry.
def assertWcsNearlyEqualOverBBox
Compare pixelToSky and skyToPixel for two WCS over a rectangular grid of pixel positions.
def makeMaskedImageFromArrays