Coverage for tests/test_spatialCell.py: 16%
178 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-22 03:22 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-22 03:22 -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/>.
22import unittest
24import lsst.utils.tests
25import lsst.pex.exceptions as pexExcept
26import lsst.geom
27import lsst.afw.math as afwMath
28from lsst.afw.image import LOCAL
31def getFlux(x):
32 return 1000 - 10*x
35class SpatialCellTestCase(unittest.TestCase):
37 def setUp(self):
38 candidateList = []
39 self.nCandidate = 5
40 for i in (0, 1, 4, 3, 2): # must be all numbers in range(self.nCandidate)
41 x, y = i, 5*i
42 candidateList.append(afwMath.TestCandidate(x, y, getFlux(x)))
44 self.cell = afwMath.SpatialCell("Test", lsst.geom.Box2I(), candidateList)
45 self.assertEqual(self.cell.getLabel(), "Test")
47 def testCandidateList(self):
48 """Check that we can retrieve candidates, and that they are sorted by ranking"""
49 self.assertEqual(self.cell[0].getXCenter(), 0)
50 self.assertEqual(self.cell[1].getXCenter(), 1)
51 self.assertEqual(self.cell[1].getYCenter(), 5)
53 def testBuildCandidateListByInsertion(self):
54 """Build a candidate list by inserting candidates"""
56 self.cell = afwMath.SpatialCell("Test", lsst.geom.Box2I())
58 for x, y in ([5, 0], [1, 1], [2, 2], [0, 0], [4, 4], [3, 4]):
59 self.cell.insertCandidate(afwMath.TestCandidate(x, y, getFlux(x)))
61 self.assertEqual(self.cell[0].getXCenter(), 0)
63 def testIterators(self):
64 """Test the SpatialCell iterators"""
65 # Count the candidates
66 self.assertEqual(self.cell.size(), self.nCandidate)
67 self.assertEqual(self.cell.end() - self.cell.begin(), self.nCandidate)
69 ptr = self.cell.begin()
70 ptr.__incr__()
71 self.assertEqual(self.cell.end() - ptr, self.nCandidate - 1)
73 self.assertEqual(ptr - self.cell.begin(), 1)
75 # Now label one candidate as bad
76 self.cell[2].setStatus(afwMath.SpatialCellCandidate.BAD)
78 self.assertEqual(self.cell.size(), self.nCandidate - 1)
79 self.assertEqual(self.cell.end() - self.cell.begin(),
80 self.nCandidate - 1)
82 self.cell.setIgnoreBad(False)
83 self.assertEqual(self.cell.size(), self.nCandidate)
84 self.assertEqual(self.cell.end() - self.cell.begin(), self.nCandidate)
86 def testGetCandidateById(self):
87 """Check that we can lookup candidates by ID"""
88 id = self.cell[1].getId()
89 self.assertEqual(self.cell.getCandidateById(id).getId(), id)
91 self.assertEqual(self.cell.getCandidateById(-1, True), None)
92 with self.assertRaises(pexExcept.NotFoundError):
93 self.cell.getCandidateById(-1)
95 def testSetIteratorBad(self):
96 """Setting a candidate BAD shouldn't stop us seeing the rest of the candidates"""
97 i = 0
98 for cand in self.cell:
99 if i == 1:
100 cand.setStatus(afwMath.SpatialCellCandidate.BAD)
101 i += 1
103 self.assertEqual(i, self.nCandidate)
105 def testSortCandidates(self):
106 """Check that we can update ratings and maintain order"""
107 ratings0 = [cand.getCandidateRating() for cand in self.cell]
109 # Change a rating
110 i, flux = 1, 9999
111 self.cell[i].setCandidateRating(flux)
112 ratings0[i] = flux
114 self.assertEqual(ratings0, [cand.getCandidateRating()
115 for cand in self.cell])
117 self.cell.sortCandidates()
118 self.assertNotEqual(
119 ratings0, [cand.getCandidateRating() for cand in self.cell])
121 def sortKey(a):
122 return -a
123 self.assertEqual(sorted(ratings0, key=sortKey),
124 [cand.getCandidateRating() for cand in self.cell])
126 def testStr(self):
127 expect = ("Test: bbox=(minimum=(0, 0), maximum=(-1, -1)), ignoreBad=True, candidates=[\n"
128 "(center=(0.0,0.0), status=UNKNOWN, rating=1000.0)\n"
129 "(center=(1.0,5.0), status=UNKNOWN, rating=990.0)\n"
130 "(center=(2.0,10.0), status=UNKNOWN, rating=980.0)\n"
131 "(center=(3.0,15.0), status=UNKNOWN, rating=970.0)\n"
132 "(center=(4.0,20.0), status=UNKNOWN, rating=960.0)]")
133 self.assertEqual(str(self.cell), expect)
135 # Check that a SpatialCell containing no candidates fits on one line.
136 emptyCell = afwMath.SpatialCell("Test2", lsst.geom.Box2I(), [])
137 expect = "Test2: bbox=(minimum=(0, 0), maximum=(-1, -1)), ignoreBad=True, candidates=[]"
138 self.assertEqual(str(emptyCell), expect)
141class SpatialCellSetTestCase(unittest.TestCase):
143 def setUp(self):
144 self.cellSet = afwMath.SpatialCellSet(lsst.geom.Box2I(
145 lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(501, 501)), 260, 200)
147 def makeTestCandidateCellSet(self):
148 """Populate a SpatialCellSet"""
149 # ensure we're starting with a list of empty cells
150 self.assertEqual(len(self.cellSet.getCellList()), 6)
152 # number of candidates
153 self.NTestCandidates = 0
154 for x, y in ([5, 0], [1, 1], [2, 2], [0, 0], [4, 4], [3, 4]): # all in cell0
155 self.cellSet.insertCandidate(afwMath.TestCandidate(x, y, -x))
156 self.NTestCandidates += 1
158 # in cell1
159 self.cellSet.insertCandidate(afwMath.TestCandidate(305, 0, 100))
160 self.NTestCandidates += 1
161 # the top right corner of cell5
162 self.cellSet.insertCandidate(afwMath.TestCandidate(500, 500, 100))
163 self.NTestCandidates += 1
165 def testNoCells(self):
166 """Test that we check for a request to make a SpatialCellSet with no cells"""
167 def tst():
168 afwMath.SpatialCellSet(lsst.geom.Box2I(
169 lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(500, 500)), 0, 3)
171 self.assertRaises(pexExcept.LengthError, tst)
173 def testInsertCandidate(self):
174 """Test inserting candidates into the SpatialCellSet"""
175 self.makeTestCandidateCellSet()
177 # we can't insert outside the box
178 with self.assertRaises(pexExcept.OutOfRangeError):
179 self.cellSet.insertCandidate(afwMath.TestCandidate(501, 501, 100))
181 cell0 = self.cellSet.getCellList()[0]
182 self.assertFalse(cell0.empty())
183 self.assertEqual(cell0[0].getXCenter(), 0.0)
185 self.assertEqual(self.cellSet.getCellList()[1][0].getXCenter(), 305.0)
187 self.assertTrue(self.cellSet.getCellList()[2].empty())
189 def tst1():
190 self.cellSet.getCellList()[2][0]
191 self.assertRaises(IndexError, tst1)
193 def tst2():
194 self.cellSet.getCellList()[2].begin().__deref__()
195 self.assertRaises(pexExcept.NotFoundError, tst2)
197 self.assertFalse(self.cellSet.getCellList()[5].empty())
199 def testVisitor(self):
200 """Test the candidate visitors"""
201 self.makeTestCandidateCellSet()
203 visitor = afwMath.TestCandidateVisitor()
205 self.cellSet.visitCandidates(visitor)
206 self.assertEqual(visitor.getN(), self.NTestCandidates)
208 self.cellSet.visitCandidates(visitor, 1)
209 self.assertEqual(visitor.getN(), 3)
211 def testGetCandidateById(self):
212 """Check that we can lookup candidates by ID"""
213 self.makeTestCandidateCellSet()
215 id = self.cellSet.getCellList()[0][1].getId()
216 self.assertEqual(self.cellSet.getCandidateById(id).getId(), id)
218 def tst():
219 self.cellSet.getCandidateById(-1) # non-existent ID
221 self.assertEqual(self.cellSet.getCandidateById(-1, True), None)
222 self.assertRaises(pexExcept.NotFoundError, tst)
224 def testSpatialCell(self):
225 dx, dy, sx, sy = 100, 100, 50, 50
226 for x0, y0 in [(0, 0), (100, 100)]:
227 # only works for tests where dx,dx is some multiple of sx,sy
228 assert(dx//sx == float(dx)/float(sx))
229 assert(dy//sy == float(dy)/float(sy))
231 bbox = lsst.geom.Box2I(lsst.geom.Point2I(x0, y0),
232 lsst.geom.Extent2I(dx, dy))
233 cset = afwMath.SpatialCellSet(bbox, sx, sy)
234 for cell in cset.getCellList():
235 label = cell.getLabel()
236 nx, ny = [int(z) for z in label.split()[1].split('x')]
238 cbbox = cell.getBBox()
240 self.assertEqual(cbbox.getMinX(), nx*sx + x0)
241 self.assertEqual(cbbox.getMinY(), ny*sy + y0)
242 self.assertEqual(cbbox.getMaxX(), (nx+1)*sx + x0 - 1)
243 self.assertEqual(cbbox.getMaxY(), (ny+1)*sy + y0 - 1)
245 def testSortCandidates(self):
246 """Check that we can update ratings and maintain order"""
247 self.makeTestCandidateCellSet()
249 cell1 = self.cellSet.getCellList()[0]
250 self.assertFalse(cell1.empty())
252 ratings0 = [cand.getCandidateRating() for cand in cell1]
254 # Change a rating
255 i, flux = 1, 9999
256 cell1[i].setCandidateRating(flux)
257 ratings0[i] = flux
259 self.assertEqual(
260 ratings0, [cand.getCandidateRating() for cand in cell1])
262 self.cellSet.sortCandidates()
263 self.assertNotEqual(
264 ratings0, [cand.getCandidateRating() for cand in cell1])
266 def sortKey(a):
267 return -a
268 self.assertEqual(sorted(ratings0, key=sortKey),
269 [cand.getCandidateRating() for cand in cell1])
271 def testStr(self):
272 expect = ("bbox=(minimum=(0, 0), maximum=(500, 500)), 6 cells\n"
273 "Cell 0x0: bbox=(minimum=(0, 0), maximum=(259, 199)), ignoreBad=True, candidates=[]\n"
274 "Cell 1x0: bbox=(minimum=(260, 0), maximum=(500, 199)), ignoreBad=True, candidates=[]\n"
275 "Cell 0x1: bbox=(minimum=(0, 200), maximum=(259, 399)), ignoreBad=True, candidates=[]\n"
276 "Cell 1x1: bbox=(minimum=(260, 200), maximum=(500, 399)), ignoreBad=True, candidates=[]\n"
277 "Cell 0x2: bbox=(minimum=(0, 400), maximum=(259, 500)), ignoreBad=True, candidates=[]\n"
278 "Cell 1x2: bbox=(minimum=(260, 400), maximum=(500, 500)), ignoreBad=True, candidates=[]")
279 self.assertEqual(str(self.cellSet), expect)
282class SpatialCellImageCandidateTestCase(unittest.TestCase):
284 def setUp(self):
285 # To ensure consistency across tests: width/height are static members
286 # of SpatialCellImageCandidate, and tests can run in any order.
287 self.width = 15
288 self.height = 21
289 self.cellSet = afwMath.SpatialCellSet(lsst.geom.Box2I(
290 lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(501, 501)), 2, 3)
292 def testInsertCandidate(self):
293 """Test that we can use SpatialCellMaskedImageCandidate"""
294 flux = 10
295 self.cellSet.insertCandidate(afwMath.TestImageCandidate(0, 0, flux))
297 cand = self.cellSet.getCellList()[0][0]
299 cand.setWidth(self.width)
300 cand.setHeight(self.height)
302 im = cand.getMaskedImage().getImage()
303 # This is how TestMaskedImageCandidate sets its pixels
304 self.assertEqual(im[0, 0, LOCAL], flux)
305 self.assertEqual(im.getWidth(), self.width)
306 self.assertEqual(im.getHeight(), self.height)
308 def testStr(self):
309 candidate = afwMath.TestImageCandidate(1, 2, 3)
310 candidate.setChi2(4)
311 candidate.setWidth(self.width)
312 candidate.setHeight(self.height)
313 expect = "center=(1.0,2.0), status=UNKNOWN, rating=3.0, size=(15, 21), chi2=4.0"
314 self.assertEqual(str(candidate), expect)
317class TestMemory(lsst.utils.tests.MemoryTestCase):
318 pass
321def setup_module(module):
322 lsst.utils.tests.init()
325if __name__ == "__main__": 325 ↛ 326line 325 didn't jump to line 326, because the condition on line 325 was never true
326 lsst.utils.tests.init()
327 unittest.main()