Coverage for tests/test_spatialCell.py: 17%

170 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-03-20 00:40 -0700

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/>. 

21 

22""" 

23Tests for SpatialCell 

24 

25Run with: 

26 python test_spatialCell.py 

27or 

28 pytest test_spatialCell.py 

29""" 

30import unittest 

31 

32import lsst.utils.tests 

33import lsst.pex.exceptions as pexExcept 

34import lsst.geom 

35import lsst.afw.math as afwMath 

36from lsst.afw.image import LOCAL 

37 

38 

39def getFlux(x): 

40 return 1000 - 10*x 

41 

42 

43class SpatialCellTestCase(unittest.TestCase): 

44 """A test case for SpatialCell""" 

45 

46 def setUp(self): 

47 candidateList = [] 

48 self.nCandidate = 5 

49 for i in (0, 1, 4, 3, 2): # must be all numbers in range(self.nCandidate) 

50 x, y = i, 5*i 

51 candidateList.append(afwMath.TestCandidate(x, y, getFlux(x))) 

52 

53 self.cell = afwMath.SpatialCell("Test", lsst.geom.Box2I(), candidateList) 

54 self.assertEqual(self.cell.getLabel(), "Test") 

55 

56 def tearDown(self): 

57 del self.cell 

58 

59 def testCandidateList(self): 

60 """Check that we can retrieve candidates, and that they are sorted by ranking""" 

61 self.assertEqual(self.cell[0].getXCenter(), 0) 

62 self.assertEqual(self.cell[1].getXCenter(), 1) 

63 self.assertEqual(self.cell[1].getYCenter(), 5) 

64 

65 def testBuildCandidateListByInsertion(self): 

66 """Build a candidate list by inserting candidates""" 

67 

68 self.cell = afwMath.SpatialCell("Test", lsst.geom.Box2I()) 

69 

70 for x, y in ([5, 0], [1, 1], [2, 2], [0, 0], [4, 4], [3, 4]): 

71 self.cell.insertCandidate(afwMath.TestCandidate(x, y, getFlux(x))) 

72 

73 self.assertEqual(self.cell[0].getXCenter(), 0) 

74 

75 def testIterators(self): 

76 """Test the SpatialCell iterators""" 

77 

78 # 

79 # Count the candidates 

80 # 

81 self.assertEqual(self.cell.size(), self.nCandidate) 

82 self.assertEqual(self.cell.end() - self.cell.begin(), self.nCandidate) 

83 

84 ptr = self.cell.begin() 

85 ptr.__incr__() 

86 self.assertEqual(self.cell.end() - ptr, self.nCandidate - 1) 

87 

88 self.assertEqual(ptr - self.cell.begin(), 1) 

89 # 

90 # Now label one candidate as bad 

91 # 

92 self.cell[2].setStatus(afwMath.SpatialCellCandidate.BAD) 

93 

94 self.assertEqual(self.cell.size(), self.nCandidate - 1) 

95 self.assertEqual(self.cell.end() - self.cell.begin(), 

96 self.nCandidate - 1) 

97 

98 self.cell.setIgnoreBad(False) 

99 self.assertEqual(self.cell.size(), self.nCandidate) 

100 self.assertEqual(self.cell.end() - self.cell.begin(), self.nCandidate) 

101 

102 def testGetCandidateById(self): 

103 """Check that we can lookup candidates by ID""" 

104 id = self.cell[1].getId() 

105 self.assertEqual(self.cell.getCandidateById(id).getId(), id) 

106 

107 self.assertEqual(self.cell.getCandidateById(-1, True), None) 

108 with self.assertRaises(pexExcept.NotFoundError): 

109 self.cell.getCandidateById(-1) 

110 

111 def testSetIteratorBad(self): 

112 """Setting a candidate BAD shouldn't stop us seeing the rest of the candidates""" 

113 i = 0 

114 for cand in self.cell: 

115 if i == 1: 

116 cand.setStatus(afwMath.SpatialCellCandidate.BAD) 

117 i += 1 

118 

119 self.assertEqual(i, self.nCandidate) 

120 

121 def testSortCandidates(self): 

122 """Check that we can update ratings and maintain order""" 

123 ratings0 = [cand.getCandidateRating() for cand in self.cell] 

124 # 

125 # Change a rating 

126 # 

127 i, flux = 1, 9999 

128 self.cell[i].setCandidateRating(flux) 

129 ratings0[i] = flux 

130 

131 self.assertEqual(ratings0, [cand.getCandidateRating() 

132 for cand in self.cell]) 

133 

134 self.cell.sortCandidates() 

135 self.assertNotEqual( 

136 ratings0, [cand.getCandidateRating() for cand in self.cell]) 

137 

138 def sortKey(a): 

139 return -a 

140 self.assertEqual(sorted(ratings0, key=sortKey), 

141 [cand.getCandidateRating() for cand in self.cell]) 

142 

143 

144class SpatialCellSetTestCase(unittest.TestCase): 

145 """A test case for SpatialCellSet""" 

146 

147 def setUp(self): 

148 self.cellSet = afwMath.SpatialCellSet(lsst.geom.Box2I( 

149 lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(501, 501)), 260, 200) 

150 

151 def makeTestCandidateCellSet(self): 

152 """Populate a SpatialCellSet""" 

153 

154 if False: # Print the bboxes for the cells 

155 print() 

156 for i in range(len(self.cellSet.getCellList())): 

157 cell = self.cellSet.getCellList()[i] 

158 print(i, f"{cell.getBBox().getMinX():3d},{cell.getBBox().getMinY():3d} -- " 

159 f"{cell.getBBox().getMaxX():3d},{cell.getBBox().getMaxY():3d}", 

160 cell.getLabel()) 

161 self.assertEqual(len(self.cellSet.getCellList()), 6) 

162 

163 # number of candidates 

164 self.NTestCandidates = 0 

165 for x, y in ([5, 0], [1, 1], [2, 2], [0, 0], [4, 4], [3, 4]): # all in cell0 

166 self.cellSet.insertCandidate(afwMath.TestCandidate(x, y, -x)) 

167 self.NTestCandidates += 1 

168 

169 # in cell1 

170 self.cellSet.insertCandidate(afwMath.TestCandidate(305, 0, 100)) 

171 self.NTestCandidates += 1 

172 # the top right corner of cell5 

173 self.cellSet.insertCandidate(afwMath.TestCandidate(500, 500, 100)) 

174 self.NTestCandidates += 1 

175 

176 def tearDown(self): 

177 del self.cellSet 

178 

179 def testNoCells(self): 

180 """Test that we check for a request to make a SpatialCellSet with no cells""" 

181 def tst(): 

182 afwMath.SpatialCellSet(lsst.geom.Box2I( 

183 lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(500, 500)), 0, 3) 

184 

185 self.assertRaises(pexExcept.LengthError, tst) 

186 

187 def testInsertCandidate(self): 

188 """Insert candidates into the SpatialCellSet""" 

189 

190 self.makeTestCandidateCellSet() 

191 

192 def tst(): 

193 # Doesn't fit 

194 self.cellSet.insertCandidate(afwMath.TestCandidate(501, 501, 100)) 

195 self.assertRaises(pexExcept.OutOfRangeError, tst) 

196 # 

197 # OK, the SpatialCellList is populated 

198 # 

199 cell0 = self.cellSet.getCellList()[0] 

200 self.assertFalse(cell0.empty()) 

201 self.assertEqual(cell0[0].getXCenter(), 0.0) 

202 

203 self.assertEqual(self.cellSet.getCellList()[1][0].getXCenter(), 305.0) 

204 

205 self.assertTrue(self.cellSet.getCellList()[2].empty()) 

206 

207 def tst1(): 

208 self.cellSet.getCellList()[2][0] 

209 self.assertRaises(IndexError, tst1) 

210 

211 def tst2(): 

212 self.cellSet.getCellList()[2].begin().__deref__() 

213 self.assertRaises(pexExcept.NotFoundError, tst2) 

214 

215 self.assertFalse(self.cellSet.getCellList()[5].empty()) 

216 

217 def testVisitor(self): 

218 """Test the candidate visitors""" 

219 

220 self.makeTestCandidateCellSet() 

221 

222 visitor = afwMath.TestCandidateVisitor() 

223 

224 self.cellSet.visitCandidates(visitor) 

225 self.assertEqual(visitor.getN(), self.NTestCandidates) 

226 

227 self.cellSet.visitCandidates(visitor, 1) 

228 self.assertEqual(visitor.getN(), 3) 

229 

230 def testGetCandidateById(self): 

231 """Check that we can lookup candidates by ID""" 

232 

233 self.makeTestCandidateCellSet() 

234 # 

235 # OK, the SpatialCellList is populated 

236 # 

237 id = self.cellSet.getCellList()[0][1].getId() 

238 self.assertEqual(self.cellSet.getCandidateById(id).getId(), id) 

239 

240 def tst(): 

241 self.cellSet.getCandidateById(-1) # non-existent ID 

242 

243 self.assertEqual(self.cellSet.getCandidateById(-1, True), None) 

244 self.assertRaises(pexExcept.NotFoundError, tst) 

245 

246 def testSpatialCell(self): 

247 dx, dy, sx, sy = 100, 100, 50, 50 

248 for x0, y0 in [(0, 0), (100, 100)]: 

249 # only works for tests where dx,dx is some multiple of sx,sy 

250 assert dx//sx == float(dx)/float(sx) 

251 assert dy//sy == float(dy)/float(sy) 

252 

253 bbox = lsst.geom.Box2I(lsst.geom.Point2I(x0, y0), 

254 lsst.geom.Extent2I(dx, dy)) 

255 cset = afwMath.SpatialCellSet(bbox, sx, sy) 

256 for cell in cset.getCellList(): 

257 label = cell.getLabel() 

258 nx, ny = [int(z) for z in label.split()[1].split('x')] 

259 

260 cbbox = cell.getBBox() 

261 

262 self.assertEqual(cbbox.getMinX(), nx*sx + x0) 

263 self.assertEqual(cbbox.getMinY(), ny*sy + y0) 

264 self.assertEqual(cbbox.getMaxX(), (nx+1)*sx + x0 - 1) 

265 self.assertEqual(cbbox.getMaxY(), (ny+1)*sy + y0 - 1) 

266 

267 def testSortCandidates(self): 

268 """Check that we can update ratings and maintain order""" 

269 

270 self.makeTestCandidateCellSet() 

271 

272 cell1 = self.cellSet.getCellList()[0] 

273 self.assertFalse(cell1.empty()) 

274 

275 ratings0 = [cand.getCandidateRating() for cand in cell1] 

276 # 

277 # Change a rating 

278 # 

279 i, flux = 1, 9999 

280 cell1[i].setCandidateRating(flux) 

281 ratings0[i] = flux 

282 

283 self.assertEqual( 

284 ratings0, [cand.getCandidateRating() for cand in cell1]) 

285 

286 self.cellSet.sortCandidates() 

287 self.assertNotEqual( 

288 ratings0, [cand.getCandidateRating() for cand in cell1]) 

289 

290 def sortKey(a): 

291 return -a 

292 self.assertEqual(sorted(ratings0, key=sortKey), 

293 [cand.getCandidateRating() for cand in cell1]) 

294 

295 

296class TestImageCandidateCase(unittest.TestCase): 

297 """A test case for TestImageCandidate""" 

298 

299 def setUp(self): 

300 self.cellSet = afwMath.SpatialCellSet(lsst.geom.Box2I( 

301 lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(501, 501)), 2, 3) 

302 

303 def tearDown(self): 

304 del self.cellSet 

305 

306 def testInsertCandidate(self): 

307 """Test that we can use SpatialCellMaskedImageCandidate""" 

308 

309 flux = 10 

310 self.cellSet.insertCandidate(afwMath.TestImageCandidate(0, 0, flux)) 

311 

312 cand = self.cellSet.getCellList()[0][0] 

313 

314 width, height = 15, 21 

315 cand.setWidth(width) 

316 cand.setHeight(height) 

317 

318 im = cand.getMaskedImage().getImage() 

319 # This is how TestMaskedImageCandidate sets its pixels 

320 self.assertEqual(im[0, 0, LOCAL], flux) 

321 self.assertEqual(im.getWidth(), width) 

322 self.assertEqual(im.getHeight(), height) 

323 

324 

325class TestMemory(lsst.utils.tests.MemoryTestCase): 

326 pass 

327 

328 

329def setup_module(module): 

330 lsst.utils.tests.init() 

331 

332 

333if __name__ == "__main__": 333 ↛ 334line 333 didn't jump to line 334, because the condition on line 333 was never true

334 lsst.utils.tests.init() 

335 unittest.main()