Coverage for tests/test_chebyshevBoundedField.py: 12%
273 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-06 12:52 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-06 12:52 -0800
1# This file is part of afw.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
22"""
23Tests for math.ChebyshevBoundedField
25Run with:
26 python test_chebyshevBoundedField.py
27or
28 pytest test_chebyshevBoundedField.py
29"""
31import os
32import unittest
34import numpy as np
36import lsst.utils.tests
37import lsst.pex.exceptions
38import lsst.geom
39import lsst.afw.image
40import lsst.afw.math
41import lsst.afw.geom
43testPath = os.path.abspath(os.path.dirname(__file__))
45CHEBYSHEV_T = [ 45 ↛ exitline 45 didn't jump to the function exit
46 lambda x: x**0,
47 lambda x: x,
48 lambda x: 2*x**2 - 1,
49 lambda x: (4*x**2 - 3)*x,
50 lambda x: (8*x**2 - 8)*x**2 + 1,
51 lambda x: ((16*x**2 - 20)*x**2 + 5)*x,
52]
55def multiply(image, field):
56 """Return the product of image and field() at each point in image.
57 """
58 box = image.getBBox()
59 outImage = lsst.afw.image.ImageF(box)
60 for i in range(box.getMinX(), box.getMaxX() + 1):
61 for j in range(box.getMinY(), box.getMaxY() + 1):
62 outImage[i, j] = image[i, j]*field.evaluate(i, j)
63 return outImage
66class ChebyshevBoundedFieldTestCase(lsst.utils.tests.TestCase):
68 def setUp(self):
69 self.longMessage = True
70 np.random.seed(5)
71 self.bbox = lsst.geom.Box2I(
72 lsst.geom.Point2I(-5, -5), lsst.geom.Point2I(5, 5))
73 self.x1d = np.linspace(self.bbox.getBeginX(), self.bbox.getEndX())
74 self.y1d = np.linspace(self.bbox.getBeginY(), self.bbox.getEndY())
75 self.x2d, self.y2d = np.meshgrid(self.x1d, self.y1d)
76 self.xFlat = np.ravel(self.x2d)
77 self.yFlat = np.ravel(self.y2d)
78 self.cases = []
79 for orderX in range(0, 5):
80 for orderY in range(0, 5):
81 indexX, indexY = np.meshgrid(np.arange(orderX + 1, dtype=int),
82 np.arange(orderY + 1, dtype=int))
83 for triangular in (True, False):
84 ctrl = lsst.afw.math.ChebyshevBoundedFieldControl()
85 ctrl.orderX = orderX
86 ctrl.orderY = orderY
87 ctrl.triangular = triangular
88 coefficients = np.random.randn(orderY + 1, orderX + 1)
89 if triangular:
90 coefficients[indexX + indexY > max(orderX, orderY)] = 0.0
91 self.cases.append((ctrl, coefficients))
93 array = np.arange(self.bbox.getArea(), dtype=np.float32).reshape(self.bbox.getDimensions())
94 self.image = lsst.afw.image.ImageF(array)
95 self.fields = [lsst.afw.math.ChebyshevBoundedField(self.bbox, coeffs) for _, coeffs in self.cases]
96 self.product = lsst.afw.math.ProductBoundedField(self.fields)
98 def tearDown(self):
99 del self.bbox
101 def testFillImageInterpolation(self):
102 ctrl, coefficients = self.cases[-2]
103 bbox = lsst.geom.Box2I(lsst.geom.Point2I(10, 15),
104 lsst.geom.Extent2I(360, 350))
105 field = lsst.afw.math.ChebyshevBoundedField(bbox, coefficients)
106 image1 = lsst.afw.image.ImageF(bbox)
107 image2 = lsst.afw.image.ImageF(bbox)
108 image3 = lsst.afw.image.ImageF(bbox)
109 image4 = lsst.afw.image.ImageF(bbox)
110 field.fillImage(image1)
111 field.fillImage(image2, xStep=3)
112 field.fillImage(image3, yStep=4)
113 field.fillImage(image4, xStep=3, yStep=4)
114 self.assertFloatsAlmostEqual(image1.array, image2.array, rtol=1E-2, atol=1E-2)
115 self.assertFloatsAlmostEqual(image1.array, image3.array, rtol=1.5E-2, atol=1.5E-2)
116 self.assertFloatsAlmostEqual(image1.array, image4.array, rtol=2E-2, atol=2E-2)
118 def testEvaluate(self):
119 """Test the single-point evaluate method against explicitly-defined 1-d Chebyshevs
120 (at the top of this file).
121 """
122 factor = 12.345
123 boxD = lsst.geom.Box2D(self.bbox)
124 # sx, sy: transform from self.bbox range to [-1, -1]
125 sx = 2.0/boxD.getWidth()
126 sy = 2.0/boxD.getHeight()
127 nPoints = 50
128 for ctrl, coefficients in self.cases:
129 field = lsst.afw.math.ChebyshevBoundedField(
130 self.bbox, coefficients)
131 x = np.random.rand(nPoints)*boxD.getWidth() + boxD.getMinX()
132 y = np.random.rand(nPoints)*boxD.getHeight() + boxD.getMinY()
133 z1 = field.evaluate(x, y)
134 tx = np.array([CHEBYSHEV_T[i](sx*x)
135 for i in range(coefficients.shape[1])])
136 ty = np.array([CHEBYSHEV_T[i](sy*y)
137 for i in range(coefficients.shape[0])])
138 self.assertEqual(tx.shape, (coefficients.shape[1], x.size))
139 self.assertEqual(ty.shape, (coefficients.shape[0], y.size))
140 z2 = np.array([np.dot(ty[:, i], np.dot(coefficients, tx[:, i]))
141 for i in range(nPoints)])
142 self.assertFloatsAlmostEqual(z1, z2, rtol=1E-12)
144 scaled = field*factor
145 self.assertFloatsAlmostEqual(scaled.evaluate(x, y),
146 factor*z2,
147 rtol=factor*1E-13)
148 self.assertFloatsEqual(
149 scaled.getCoefficients(), factor*field.getCoefficients())
151 def testProductEvaluate(self):
152 """Test that ProductBoundedField.evaluate is equivalent to multiplying
153 its nested BoundedFields.
154 """
155 zFlat1 = self.product.evaluate(self.xFlat, self.yFlat)
156 zFlat2 = np.array([self.product.evaluate(x, y) for x, y in zip(self.xFlat, self.yFlat)])
157 self.assertFloatsAlmostEqual(zFlat1, zFlat2)
158 zFlat3 = np.ones(zFlat1.shape, dtype=float)
159 for field in self.fields:
160 zFlat3 *= field.evaluate(self.xFlat, self.yFlat)
161 self.assertFloatsAlmostEqual(zFlat1, zFlat3)
163 def testMultiplyImage(self):
164 """Test Multiplying in place an image.
165 """
166 _, coefficients = self.cases[-2]
167 field = lsst.afw.math.ChebyshevBoundedField(self.image.getBBox(), coefficients)
168 # multiplyImage() is in-place, so we have to make the expected result first.
169 expect = multiply(self.image, field)
170 field.multiplyImage(self.image)
171 self.assertImagesAlmostEqual(self.image, expect)
173 def testMultiplyImageRaisesUnequalBBox(self):
174 """Multiplying an image with a different bbox should raise.
175 """
176 _, coefficients = self.cases[-2]
177 field = lsst.afw.math.ChebyshevBoundedField(self.image.getBBox(), coefficients)
178 subBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 3), lsst.geom.Point2I(3, 4))
179 subImage = self.image.subset(subBox)
180 with(self.assertRaises(RuntimeError)):
181 field.multiplyImage(subImage)
183 def testMultiplyImageOverlapSubImage(self):
184 """Multiplying a subimage with overlapOnly=true should only modify
185 the subimage, when a subimage is passed in.
186 """
187 _, coefficients = self.cases[-2]
188 field = lsst.afw.math.ChebyshevBoundedField(self.image.getBBox(), coefficients)
189 subBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 3), lsst.geom.Point2I(3, 4))
190 subImage = self.image.subset(subBox)
191 expect = self.image.clone()
192 expect[subBox] = multiply(subImage, field)
193 field.multiplyImage(subImage, overlapOnly=True)
194 self.assertImagesAlmostEqual(self.image, expect)
196 def testMultiplyImageOverlapSmallerBoundedField(self):
197 """Multiplying a subimage with overlapOnly=true should only modify
198 the subimage if the boundedField bbox is smaller than the image.
200 This is checking for a bug where the bounded field was writing outside
201 the overlap bbox.
202 """
203 _, coefficients = self.cases[-2]
204 subBox = lsst.geom.Box2I(lsst.geom.Point2I(0, 3), lsst.geom.Point2I(3, 4))
205 # The BF is only defined on the subBox, not the whole image bbox.
206 field = lsst.afw.math.ChebyshevBoundedField(subBox, coefficients)
207 subImage = self.image.subset(subBox)
208 expect = self.image.clone()
209 expect[subBox] = multiply(subImage, field)
210 field.multiplyImage(self.image, overlapOnly=True)
211 self.assertImagesAlmostEqual(self.image, expect)
213 def _testIntegrateBox(self, bbox, coeffs, expect):
214 field = lsst.afw.math.ChebyshevBoundedField(bbox, coeffs)
215 self.assertFloatsAlmostEqual(field.integrate(), expect, rtol=1E-14)
217 def testIntegrateTrivialBox(self):
218 """Test integrating over a "trivial" [-1,1] box.
220 NOTE: a "trivial" BBox can't be constructed exactly, given that Box2I
221 is inclusive, but the [0,1] box has the same area (because it is
222 actually (-0.5, 1.5) when converted to a Box2D), and the translation
223 doesn't affect the integral.
224 """
225 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
226 lsst.geom.Point2I(1, 1))
228 # 0th order polynomial
229 coeffs = np.array([[5.0]])
230 self._testIntegrateBox(bbox, coeffs, 4.0*coeffs[0, 0])
232 # 1st order polynomial: odd orders drop out of integral
233 coeffs = np.array([[5.0, 2.0], [3.0, 4.0]])
234 self._testIntegrateBox(bbox, coeffs, 4.0*coeffs[0, 0])
236 # 2nd order polynomial in x, 0th in y
237 coeffs = np.array([[5.0, 0.0, 7.0]])
238 self._testIntegrateBox(
239 bbox, coeffs, 4.0*coeffs[0, 0] - (4.0/3.0)*coeffs[0, 2])
241 # 2nd order polynomial in y, 0th in x
242 coeffs = np.zeros((3, 3))
243 coeffs[0, 0] = 5.0
244 coeffs[2, 0] = 7.0
245 self._testIntegrateBox(
246 bbox, coeffs, 4.0*coeffs[0, 0] - (4.0/3.0)*coeffs[2, 0])
248 # 2nd order polynomial in x and y, no cross-term
249 coeffs = np.zeros((3, 3))
250 coeffs[0, 0] = 5.0
251 coeffs[1, 0] = 7.0
252 coeffs[0, 2] = 3.0
253 self._testIntegrateBox(bbox, coeffs,
254 4.0*coeffs[0, 0] - (4.0/3.0)*coeffs[2, 0] - (4.0/3.0)*coeffs[0, 2])
256 def testIntegrateBox(self):
257 r"""Test integrating over an "interesting" box.
259 The values of these integrals were checked in Mathematica. The code
260 block below can be pasted into Mathematica to re-do those calculations.
262 ::
264 f[x_, y_, n_, m_] := \!\(
265 \*UnderoverscriptBox[\(\[Sum]\), \(i = 0\), \(n\)]\(
266 \*UnderoverscriptBox[\(\[Sum]\), \(j = 0\), \(m\)]
267 \*SubscriptBox[\(a\), \(i, j\)]*ChebyshevT[i, x]*ChebyshevT[j, y]\)\)
268 integrate2dBox[n_, m_, x0_, x1_, y0_, y1_] := \!\(
269 \*SubsuperscriptBox[\(\[Integral]\), \(y0\), \(y1\)]\(
270 \*SubsuperscriptBox[\(\[Integral]\), \(x0\), \(x1\)]f[
271 \*FractionBox[\(2 x - x0 - x1\), \(x1 - x0\)],
272 \*FractionBox[\(2 y - y0 - y1\), \(y1 - y0\)], n,
273 m] \[DifferentialD]x \[DifferentialD]y\)\)
274 integrate2dBox[0, 0, -2.5, 5.5, -3.5, 7.5]
275 integrate2dBox[1, 0, -2.5, 5.5, -3.5, 7.5]
276 integrate2dBox[0, 1, -2.5, 5.5, -3.5, 7.5]
277 integrate2dBox[1, 1, -2.5, 5.5, -3.5, 7.5]
278 integrate2dBox[1, 2, -2.5, 5.5, -3.5, 7.5]
279 integrate2dBox[2, 2, -2.5, 5.5, -3.5, 7.5]
280 """
281 bbox = lsst.geom.Box2I(
282 lsst.geom.Point2I(-2, -3), lsst.geom.Point2I(5, 7))
284 # 0th order polynomial
285 coeffs = np.array([[5.0]])
286 self._testIntegrateBox(bbox, coeffs, 88.0*coeffs[0, 0])
288 # 1st order polynomial: odd orders drop out of integral
289 coeffs = np.array([[5.0, 2.0], [3.0, 4.0]])
290 self._testIntegrateBox(bbox, coeffs, 88.0*coeffs[0, 0])
292 # 2nd order polynomial in x, 0th in y
293 coeffs = np.array([[5.0, 0.0, 7.0]])
294 self._testIntegrateBox(
295 bbox, coeffs, 88.0*coeffs[0, 0] - (88.0/3.0)*coeffs[0, 2])
297 # 2nd order polynomial in y, 0th in x
298 coeffs = np.zeros((3, 3))
299 coeffs[0, 0] = 5.0
300 coeffs[2, 0] = 7.0
301 self._testIntegrateBox(
302 bbox, coeffs, 88.0*coeffs[0, 0] - (88.0/3.0)*coeffs[2, 0])
304 # 2nd order polynomial in x,y
305 coeffs = np.zeros((3, 3))
306 coeffs[2, 2] = 11.0
307 self._testIntegrateBox(bbox, coeffs, (88.0/9.0)*coeffs[2, 2])
309 def testMean(self):
310 """The mean of the nth 1d Chebyshev (a_n*T_n(x)) on [-1,1] is
311 0 for odd n
312 a_n / (1-n^2) for even n
314 Similarly, the mean of the (n,m)th 2d Chebyshev is the appropriate
315 product of the above.
316 """
317 bbox = lsst.geom.Box2I(
318 lsst.geom.Point2I(-2, -3), lsst.geom.Point2I(5, 7))
320 coeffs = np.array([[5.0]])
321 field = lsst.afw.math.ChebyshevBoundedField(bbox, coeffs)
322 self.assertEqual(field.mean(), coeffs[0, 0])
324 coeffs = np.array([[5.0, 0.0, 3.0]])
325 field = lsst.afw.math.ChebyshevBoundedField(bbox, coeffs)
326 self.assertEqual(field.mean(), coeffs[0, 0] - coeffs[0, 2]/3.0)
328 # 2nd order polynomial in x,y
329 coeffs = np.zeros((3, 3))
330 coeffs[0, 0] = 7.0
331 coeffs[1, 0] = 31.0
332 coeffs[0, 2] = 13.0
333 coeffs[2, 2] = 11.0
334 field = lsst.afw.math.ChebyshevBoundedField(bbox, coeffs)
335 self.assertFloatsAlmostEqual(
336 field.mean(), coeffs[0, 0] - coeffs[0, 2]/3.0 + coeffs[2, 2]/9.0)
338 def testImageFit(self):
339 """Test that we can fit an image produced by a ChebyshevBoundedField and
340 get the same coefficients back.
341 """
342 for ctrl, coefficients in self.cases:
343 inField = lsst.afw.math.ChebyshevBoundedField(
344 self.bbox, coefficients)
345 for Image in (lsst.afw.image.ImageF, lsst.afw.image.ImageD):
346 image = Image(self.bbox)
347 inField.fillImage(image)
348 outField = lsst.afw.math.ChebyshevBoundedField.fit(image, ctrl)
349 self.assertFloatsAlmostEqual(
350 outField.getCoefficients(), coefficients, rtol=1E-6, atol=1E-7)
352 def testArrayFit(self):
353 """Test that we can fit 1-d arrays produced by a ChebyshevBoundedField and
354 get the same coefficients back.
355 """
356 for ctrl, coefficients in self.cases:
357 inField = lsst.afw.math.ChebyshevBoundedField(
358 self.bbox, coefficients)
359 for Image in (lsst.afw.image.ImageF, lsst.afw.image.ImageD):
360 array = inField.evaluate(self.xFlat, self.yFlat)
361 outField1 = lsst.afw.math.ChebyshevBoundedField.fit(self.bbox, self.xFlat, self.yFlat,
362 array, ctrl)
363 self.assertFloatsAlmostEqual(
364 outField1.getCoefficients(), coefficients, rtol=1E-6, atol=1E-7)
365 weights = (1.0 + np.random.randn(array.size)**2)
366 # Should get same results with different weights, since we still have no noise
367 # and a model that can exactly reproduce the data.
368 outField2 = lsst.afw.math.ChebyshevBoundedField.fit(self.bbox, self.xFlat, self.yFlat,
369 array, weights, ctrl)
370 self.assertFloatsAlmostEqual(
371 outField2.getCoefficients(), coefficients, rtol=1E-7, atol=1E-7)
373 def testApproximate(self):
374 """Test the approximate instantiation with the example of
375 fitting a PixelAreaBoundedField to reasonable precision.
376 """
378 # This HSC-R band wcs was chosen arbitrarily from the edge of
379 # field-of-view (ccd 4) for the w_2019_38 processing of RC2 as it
380 # represents the typical use case of the approxBoundedField method.
381 skyWcs = lsst.afw.geom.SkyWcs.readFits(os.path.join(testPath,
382 "data/jointcal_wcs-0034772-004.fits"))
383 bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
384 lsst.geom.Point2I(2047, 4175))
386 pixelAreaField = lsst.afw.math.PixelAreaBoundedField(bbox, skyWcs,
387 unit=lsst.geom.arcseconds)
388 approxField = lsst.afw.math.ChebyshevBoundedField.approximate(pixelAreaField)
390 # Choose random points to test rather than a grid to ensure that
391 # we are not using the same gridded points as used for the
392 # approximation.
393 np.random.seed(seed=1000)
394 xTest = np.random.uniform(low=0.0, high=bbox.getMaxX(), size=10000)
395 yTest = np.random.uniform(low=0.0, high=bbox.getMaxY(), size=10000)
397 # The evaluation of approxField is ~80x faster than the
398 # evaluation of pixelAreaField.
399 expect = pixelAreaField.evaluate(xTest, yTest)
400 result = approxField.evaluate(xTest, yTest)
402 # The approximation is good to the 1e-7 level (absolute)
403 self.assertFloatsAlmostEqual(result, expect, atol=1e-7)
404 # and to the 1e-5 level (relative). This is < 0.01 mmag.
405 self.assertFloatsAlmostEqual(result, expect, rtol=1e-5)
407 def testPersistence(self):
408 """Test that we can round-trip a ChebyshevBoundedField through
409 persistence.
410 """
411 boxD = lsst.geom.Box2D(self.bbox)
412 nPoints = 50
413 with lsst.utils.tests.getTempFilePath(".fits") as filename:
414 for ctrl, coefficients in self.cases:
415 inField = lsst.afw.math.ChebyshevBoundedField(
416 self.bbox, coefficients)
417 inField.writeFits(filename)
418 outField = lsst.afw.math.ChebyshevBoundedField.readFits(filename)
419 self.assertEqual(inField.getBBox(), outField.getBBox())
420 self.assertFloatsAlmostEqual(
421 inField.getCoefficients(), outField.getCoefficients())
422 x = np.random.rand(nPoints)*boxD.getWidth() + boxD.getMinX()
423 y = np.random.rand(nPoints)*boxD.getHeight() + boxD.getMinY()
424 z1 = inField.evaluate(x, y)
425 z2 = inField.evaluate(x, y)
426 self.assertFloatsAlmostEqual(z1, z2, rtol=1E-13)
428 # test with an empty bbox
429 inField = lsst.afw.math.ChebyshevBoundedField(lsst.geom.Box2I(),
430 np.array([[1.0, 2.0], [3.0, 4.0]]))
431 inField.writeFits(filename)
432 outField = lsst.afw.math.ChebyshevBoundedField.readFits(filename)
433 self.assertEqual(inField.getBBox(), outField.getBBox())
435 def testProductPersistence(self):
436 """Test that we can round-trip a ProductBoundedField through
437 persistence.
438 """
439 with lsst.utils.tests.getTempFilePath(".fits") as filename:
440 self.product.writeFits(filename)
441 out = lsst.afw.math.ProductBoundedField.readFits(filename)
442 self.assertEqual(self.product, out)
444 def testTruncate(self):
445 """Test that truncate() works as expected.
446 """
447 for ctrl, coefficients in self.cases:
448 field1 = lsst.afw.math.ChebyshevBoundedField(
449 self.bbox, coefficients)
450 field2 = field1.truncate(ctrl)
451 self.assertFloatsAlmostEqual(
452 field1.getCoefficients(), field2.getCoefficients())
453 self.assertEqual(field1.getBBox(), field2.getBBox())
454 config3 = lsst.afw.math.ChebyshevBoundedField.ConfigClass()
455 config3.readControl(ctrl)
456 if ctrl.orderX > 0:
457 config3.orderX -= 1
458 if ctrl.orderY > 0:
459 config3.orderY -= 1
460 field3 = field1.truncate(config3.makeControl())
461 for i in range(config3.orderY + 1):
462 for j in range(config3.orderX + 1):
463 if config3.triangular and i + j > max(config3.orderX, config3.orderY):
464 self.assertEqual(field3.getCoefficients()[i, j], 0.0)
465 else:
466 self.assertEqual(field3.getCoefficients()[i, j],
467 field1.getCoefficients()[i, j])
469 def testEquality(self):
470 for ctrl, coefficients in self.cases:
471 field1 = lsst.afw.math.ChebyshevBoundedField(self.bbox, coefficients)
472 field2 = lsst.afw.math.ChebyshevBoundedField(self.bbox, coefficients)
473 self.assertEqual(field1, field2, msg=coefficients)
475 # same coefficients, instantiated from different arrays
476 field1 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0]]))
477 field2 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0]]))
478 self.assertEqual(field1, field2)
479 field1 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0, 2.0], [3., 4.]]))
480 field2 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0, 2.0], [3., 4.]]))
481 self.assertEqual(field1, field2)
483 # different coefficient(s)
484 field1 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0]]))
485 field2 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[2.0]]))
486 self.assertNotEqual(field1, field2)
487 field1 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0, 0.0]]))
488 field2 = lsst.afw.math.ChebyshevBoundedField(self.bbox, np.array([[1.0], [0.0]]))
489 self.assertNotEqual(field1, field2)
491 # different bbox
492 bbox1 = lsst.geom.Box2I(lsst.geom.Point2I(-10, -10), lsst.geom.Point2I(5, 5))
493 bbox2 = lsst.geom.Box2I(lsst.geom.Point2I(-5, -5), lsst.geom.Point2I(5, 5))
494 field1 = lsst.afw.math.ChebyshevBoundedField(bbox1, np.array([[1.0]]))
495 field2 = lsst.afw.math.ChebyshevBoundedField(bbox2, np.array([[1.0]]))
496 self.assertNotEqual(field1, field2)
499class MemoryTester(lsst.utils.tests.MemoryTestCase):
500 pass
503def setup_module(module):
504 lsst.utils.tests.init()
507if __name__ == "__main__": 507 ↛ 508line 507 didn't jump to line 508, because the condition on line 507 was never true
508 lsst.utils.tests.init()
509 unittest.main()