Coverage for tests/test_mask.py: 15%

391 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-08-30 02:37 -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 Masks 

24 

25Run with: 

26 python test_mask.py 

27or 

28 pytest test_mask.py 

29""" 

30import os.path 

31import unittest 

32 

33import numpy as np 

34 

35import lsst.utils 

36import lsst.utils.tests as utilsTests 

37import lsst.pex.exceptions as pexExcept 

38import lsst.daf.base 

39import lsst.geom 

40import lsst.afw.image as afwImage 

41import lsst.afw.display as afwDisplay 

42import lsst.afw.display.ds9 as ds9 # noqa: F401 for some reason images don't display without both imports 

43 

44try: 

45 type(display) 

46except NameError: 

47 display = False 

48 

49try: 

50 afwdataDir = lsst.utils.getPackageDir("afwdata") 

51except LookupError: 

52 afwdataDir = None 

53 

54afwDisplay.setDefaultMaskTransparency(75) 

55 

56 

57def showMaskDict(d=None, msg=None): 

58 if not d: 

59 d = afwImage.Mask(0, 0) 

60 if not msg: 

61 msg = "default" 

62 

63 try: 

64 d = d.getMaskPlaneDict() 

65 except AttributeError: 

66 pass 

67 

68 if msg: 

69 print("%-15s" % msg, end=' ') 

70 print(sorted([(d[p], p) for p in d])) 

71 

72 

73class MaskTestCase(utilsTests.TestCase): 

74 """A test case for Mask""" 

75 

76 def setUp(self): 

77 np.random.seed(1) 

78 self.Mask = afwImage.Mask[afwImage.MaskPixel] 

79 

80 # Store the default mask planes for later use 

81 maskPlaneDict = self.Mask().getMaskPlaneDict() 

82 self.defaultMaskPlanes = sorted( 

83 maskPlaneDict, key=maskPlaneDict.__getitem__) 

84 

85 # reset so tests will be deterministic 

86 self.Mask.clearMaskPlaneDict() 

87 for p in ("BAD", "SAT", "INTRP", "CR", "EDGE"): 

88 self.Mask.addMaskPlane(p) 

89 

90 self.BAD = self.Mask.getPlaneBitMask("BAD") 

91 self.CR = self.Mask.getPlaneBitMask("CR") 

92 self.EDGE = self.Mask.getPlaneBitMask("EDGE") 

93 

94 self.val1 = self.BAD | self.CR 

95 self.val2 = self.val1 | self.EDGE 

96 

97 self.mask1 = afwImage.Mask(100, 200) 

98 self.mask1.set(self.val1) 

99 self.mask2 = afwImage.Mask(self.mask1.getDimensions()) 

100 self.mask2.set(self.val2) 

101 

102 if afwdataDir is not None: 

103 self.maskFile = os.path.join(afwdataDir, "data", "small_MI.fits") 

104 # Below: what to expect from the mask plane in the above data. 

105 # For some tests, it is left-shifted by some number of mask planes. 

106 self.expect = np.zeros((256, 256), dtype='i8') 

107 self.expect[:, 0] = 1 

108 

109 def tearDown(self): 

110 del self.mask1 

111 del self.mask2 

112 # Reset the mask plane to the default 

113 self.Mask.clearMaskPlaneDict() 

114 for p in self.defaultMaskPlanes: 

115 self.Mask.addMaskPlane(p) 

116 

117 def testArrays(self): 

118 # could use Mask(5, 6) but check extent(5, 6) form too 

119 image1 = afwImage.Mask(lsst.geom.ExtentI(5, 6)) 

120 array1 = image1.getArray() 

121 self.assertEqual(array1.shape[0], image1.getHeight()) 

122 self.assertEqual(array1.shape[1], image1.getWidth()) 

123 image2 = afwImage.Mask(array1, False) 

124 self.assertEqual(array1.shape[0], image2.getHeight()) 

125 self.assertEqual(array1.shape[1], image2.getWidth()) 

126 image3 = afwImage.makeMaskFromArray(array1) 

127 self.assertEqual(array1.shape[0], image2.getHeight()) 

128 self.assertEqual(array1.shape[1], image2.getWidth()) 

129 self.assertEqual(type(image3), afwImage.Mask[afwImage.MaskPixel]) 

130 array1[:, :] = np.random.uniform(low=0, high=10, size=array1.shape) 

131 self.assertMasksEqual(image1, array1) 

132 array2 = image1.array 

133 np.testing.assert_array_equal(image1.array, array2) 

134 array3 = np.random.uniform(low=0, high=10, 

135 size=array1.shape).astype(array1.dtype) 

136 image1.array = array3 

137 np.testing.assert_array_equal(array1, array3) 

138 

139 def testInitializeMasks(self): 

140 val = 0x1234 

141 msk = afwImage.Mask(lsst.geom.ExtentI(10, 10), val) 

142 self.assertEqual(msk[0, 0], val) 

143 

144 def testSetGetMasks(self): 

145 self.assertEqual(self.mask1[0, 0], self.val1) 

146 

147 def testOrMasks(self): 

148 self.mask2 |= self.mask1 

149 self.mask1 |= self.val2 

150 

151 self.assertMasksEqual(self.mask1, self.mask2) 

152 expect = np.empty_like(self.mask1.getArray()) 

153 expect[:] = self.val2 | self.val1 

154 self.assertMasksEqual(self.mask1, expect) 

155 

156 def testAndMasks(self): 

157 self.mask2 &= self.mask1 

158 self.mask1 &= self.val2 

159 

160 self.assertMasksEqual(self.mask1, self.mask2) 

161 expect = np.empty_like(self.mask1.getArray()) 

162 expect[:] = self.val1 & self.val2 

163 self.assertMasksEqual(self.mask1, expect) 

164 

165 def testXorMasks(self): 

166 self.mask2 ^= self.mask1 

167 self.mask1 ^= self.val2 

168 

169 self.assertMasksEqual(self.mask1, self.mask2) 

170 expect = np.empty_like(self.mask1.getArray()) 

171 expect[:] = self.val1 ^ self.val2 

172 self.assertMasksEqual(self.mask1, expect) 

173 

174 def testLogicalMasksMismatch(self): 

175 "Test logical operations on Masks of different sizes" 

176 i1 = afwImage.Mask(lsst.geom.ExtentI(100, 100)) 

177 i1.set(100) 

178 i2 = afwImage.Mask(lsst.geom.ExtentI(10, 10)) 

179 i2.set(10) 

180 

181 with self.assertRaises(lsst.pex.exceptions.LengthError): 

182 i1 |= i2 

183 

184 with self.assertRaises(lsst.pex.exceptions.LengthError): 

185 i1 &= i2 

186 

187 with self.assertRaises(lsst.pex.exceptions.LengthError): 

188 i1 ^= i2 

189 

190 def testMaskPlanes(self): 

191 planes = self.Mask().getMaskPlaneDict() 

192 self.assertEqual(len(planes), self.Mask.getNumPlanesUsed()) 

193 

194 for k in sorted(planes.keys()): 

195 self.assertEqual(planes[k], self.Mask.getMaskPlane(k)) 

196 

197 def testCopyConstructors(self): 

198 dmask = afwImage.Mask(self.mask1, True) # deep copy 

199 smask = afwImage.Mask(self.mask1) # shallow copy 

200 

201 self.mask1 |= 32767 # should only change smask 

202 temp = np.zeros_like(self.mask1.getArray()) | self.val1 

203 self.assertMasksEqual(dmask, temp) 

204 self.assertMasksEqual(smask, self.mask1) 

205 self.assertMasksEqual(smask, temp | 32767) 

206 

207 def testSubmasks(self): 

208 smask = afwImage.Mask(self.mask1, 

209 lsst.geom.Box2I(lsst.geom.Point2I(1, 1), 

210 lsst.geom.ExtentI(3, 2)), 

211 afwImage.LOCAL) 

212 mask2 = afwImage.Mask(smask.getDimensions()) 

213 

214 mask2.set(666) 

215 smask[:] = mask2 

216 

217 del smask 

218 del mask2 

219 

220 self.assertEqual(self.mask1[0, 0, afwImage.LOCAL], self.val1) 

221 self.assertEqual(self.mask1[1, 1, afwImage.LOCAL], 666) 

222 self.assertEqual(self.mask1[4, 1, afwImage.LOCAL], self.val1) 

223 self.assertEqual(self.mask1[1, 2, afwImage.LOCAL], 666) 

224 self.assertEqual(self.mask1[4, 2, afwImage.LOCAL], self.val1) 

225 self.assertEqual(self.mask1[1, 3, afwImage.LOCAL], self.val1) 

226 

227 @unittest.skipIf(afwdataDir is None, "afwdata not setup") 

228 def testReadFits(self): 

229 nMaskPlanes0 = self.Mask.getNumPlanesUsed() 

230 # will shift any unrecognised mask planes into unused slots 

231 mask = self.Mask(self.maskFile, hdu=2) 

232 

233 self.assertMasksEqual(mask, self.expect << nMaskPlanes0) 

234 

235 @unittest.skipIf(afwdataDir is None, "afwdata not setup") 

236 def testReadFitsConform(self): 

237 hdu = 2 

238 mask = afwImage.Mask(self.maskFile, hdu, None, 

239 lsst.geom.Box2I(), afwImage.LOCAL, True) 

240 

241 self.assertMasksEqual(mask, self.expect) 

242 

243 @unittest.skipIf(afwdataDir is None, "afwdata not setup") 

244 def testWriteFits(self): 

245 nMaskPlanes0 = self.Mask.getNumPlanesUsed() 

246 mask = self.Mask(self.maskFile, hdu=2) 

247 

248 self.assertMasksEqual(mask, self.expect << nMaskPlanes0) 

249 

250 mask.clearMaskPlaneDict() 

251 

252 with utilsTests.getTempFilePath(".fits") as tmpFile: 

253 mask.writeFits(tmpFile) 

254 

255 # Read it back 

256 md = lsst.daf.base.PropertySet() 

257 rmask = self.Mask(tmpFile, 0, md) 

258 

259 self.assertMasksEqual(mask, rmask) 

260 

261 # Check that we wrote (and read) the metadata successfully 

262 mp_ = "MP_" if True else self.Mask.maskPlanePrefix() # currently private 

263 for (k, v) in self.Mask().getMaskPlaneDict().items(): 

264 self.assertEqual(md.getArray(mp_ + k), v) 

265 

266 def testReadWriteXY0(self): 

267 """Test that we read and write (X0, Y0) correctly""" 

268 mask = afwImage.Mask(lsst.geom.ExtentI(10, 20)) 

269 

270 x0, y0 = 1, 2 

271 mask.setXY0(x0, y0) 

272 with utilsTests.getTempFilePath(".fits") as tmpFile: 

273 mask.writeFits(tmpFile) 

274 

275 mask2 = mask.Factory(tmpFile) 

276 

277 self.assertEqual(mask2.getX0(), x0) 

278 self.assertEqual(mask2.getY0(), y0) 

279 

280 def testMaskInitialisation(self): 

281 dims = self.mask1.getDimensions() 

282 factory = self.mask1.Factory 

283 

284 self.mask1.set(666) 

285 

286 del self.mask1 # tempt C++ to reuse the memory 

287 self.mask1 = factory(dims) 

288 self.assertEqual(self.mask1[10, 10], 0) 

289 

290 del self.mask1 

291 self.mask1 = factory(lsst.geom.ExtentI(20, 20)) 

292 self.assertEqual(self.mask1[10, 10], 0) 

293 

294 def testCtorWithPlaneDefs(self): 

295 """Test that we can create a Mask with a given MaskPlaneDict""" 

296 FOO, val = "FOO", 2 

297 mask = afwImage.Mask(100, 200, {FOO: val}) 

298 mpd = mask.getMaskPlaneDict() 

299 self.assertIn(FOO, mpd.keys()) 

300 self.assertEqual(mpd[FOO], val) 

301 

302 def testImageSlices(self): 

303 """Test image slicing, which generate sub-images using Box2I under the covers""" 

304 mask = afwImage.Mask(10, 20) 

305 mask[-3:, -2:, afwImage.LOCAL] = 0x4 

306 mask[4, 10] = 0x2 

307 smask = mask[1:4, 6:10] 

308 smask[:] = 0x8 

309 mask[0:4, 0:4] = mask[2:6, 8:12] 

310 

311 if display: 

312 afwDisplay.Display(frame=0).mtv(mask, title="testImageSlices") 

313 

314 self.assertEqual(mask[0, 6], 0) 

315 self.assertEqual(mask[6, 17], 0) 

316 self.assertEqual(mask[7, 18], 0x4) 

317 self.assertEqual(mask[9, 19], 0x4) 

318 self.assertEqual(mask[1, 6], 0x8) 

319 self.assertEqual(mask[3, 9], 0x8) 

320 self.assertEqual(mask[4, 10], 0x2) 

321 self.assertEqual(mask[4, 9], 0) 

322 self.assertEqual(mask[2, 2], 0x2) 

323 self.assertEqual(mask[0, 0], 0x8) 

324 

325 def testInterpret(self): 

326 """Interpretation of Mask values""" 

327 planes = self.Mask().getMaskPlaneDict() 

328 im = self.Mask(len(planes), 1) 

329 

330 allBits = 0 

331 for i, p in enumerate(planes): 

332 bitmask = self.Mask.getPlaneBitMask(p) 

333 allBits |= bitmask 

334 self.assertEqual(im.interpret(bitmask), p) 

335 im.getArray()[0, i] = bitmask 

336 self.assertEqual(im.getAsString(i, 0), p) 

337 self.assertEqual(self.Mask.interpret(allBits), 

338 ",".join(sorted(planes.keys()))) 

339 

340 def testString(self): 

341 mask = afwImage.Mask(100, 100) 

342 self.assertIn(str(np.zeros((100, 100), dtype=mask.dtype)), str(mask)) 

343 self.assertIn("bbox=%s"%str(mask.getBBox()), str(mask)) 

344 self.assertIn("maskPlaneDict=%s"%str(mask.getMaskPlaneDict()), str(mask)) 

345 

346 smallMask = afwImage.Mask(2, 2) 

347 self.assertIn(str(np.zeros((2, 2), dtype=mask.dtype)), str(smallMask)) 

348 

349 self.assertIn("MaskX=", repr(mask)) 

350 

351 

352class OldMaskTestCase(unittest.TestCase): 

353 """A test case for Mask (based on Mask_1.cc); these are taken over from the DC2 fw tests 

354 and modified to run with the new (DC3) APIs""" 

355 

356 def setUp(self): 

357 self.Mask = afwImage.Mask[afwImage.MaskPixel] # the class 

358 

359 self.testMask = self.Mask(lsst.geom.Extent2I(300, 400), 0) 

360 

361 # Store the default mask planes for later use 

362 maskPlaneDict = self.Mask().getMaskPlaneDict() 

363 self.defaultMaskPlanes = sorted( 

364 maskPlaneDict, key=maskPlaneDict.__getitem__) 

365 

366 # reset so tests will be deterministic 

367 self.Mask.clearMaskPlaneDict() 

368 for p in ("CR", "BP"): 

369 self.Mask.addMaskPlane(p) 

370 

371 self.region = lsst.geom.Box2I(lsst.geom.Point2I(100, 300), 

372 lsst.geom.Extent2I(10, 40)) 

373 self.subTestMask = self.Mask( 

374 self.testMask, self.region, afwImage.LOCAL) 

375 

376 if False: 

377 self.pixelList = afwImage.listPixelCoord() 

378 for x in range(0, 300): 

379 for y in range(300, 400, 20): 

380 self.pixelList.push_back(afwImage.PixelCoord(x, y)) 

381 

382 def tearDown(self): 

383 del self.testMask 

384 del self.subTestMask 

385 del self.region 

386 # Reset the mask plane to the default 

387 self.Mask.clearMaskPlaneDict() 

388 for p in self.defaultMaskPlanes: 

389 self.Mask.addMaskPlane(p) 

390 

391 def testPlaneAddition(self): 

392 """Test mask plane addition""" 

393 

394 nplane = self.testMask.getNumPlanesUsed() 

395 for p in ("XCR", "XBP"): 

396 self.assertEqual(self.Mask.addMaskPlane(p), 

397 nplane, f"Assigning plane {p}") 

398 nplane += 1 

399 

400 def pname(p): 

401 return f"P{p}" 

402 

403 nextra = 8 

404 for p in range(0, nextra): 

405 self.Mask.addMaskPlane(pname(p)) 

406 

407 for p in range(0, nextra): 

408 self.testMask.removeAndClearMaskPlane(pname(p)) 

409 

410 self.assertEqual( 

411 nplane + nextra, self.Mask.getNumPlanesUsed(), "Adding and removing planes") 

412 

413 for p in range(0, nextra): 

414 self.Mask.removeMaskPlane(pname(p)) 

415 

416 self.assertEqual(nplane, self.testMask.getNumPlanesUsed(), 

417 "Adding and removing planes") 

418 

419 def testMetadata(self): 

420 """Test mask plane metadata interchange with MaskPlaneDict""" 

421 # 

422 # Demonstrate that we can extract a MaskPlaneDict into metadata 

423 # 

424 metadata = lsst.daf.base.PropertySet() 

425 

426 self.Mask.addMaskPlanesToMetadata(metadata) 

427 for (k, v) in self.Mask().getMaskPlaneDict().items(): 

428 self.assertEqual(metadata.getInt(f"MP_{k}"), v) 

429 # 

430 # Now add another plane to metadata and make it appear in the mask Dict, albeit 

431 # in general at another location (hence the getNumPlanesUsed call) 

432 # 

433 metadata.addInt("MP_" + "Whatever", self.Mask.getNumPlanesUsed()) 

434 

435 self.testMask.conformMaskPlanes( 

436 self.Mask.parseMaskPlaneMetadata(metadata)) 

437 for (k, v) in self.Mask().getMaskPlaneDict().items(): 

438 self.assertEqual(metadata.getInt(f"MP_{k}"), v) 

439 

440 def testPlaneOperations(self): 

441 """Test mask plane operations""" 

442 

443 planes = self.Mask().getMaskPlaneDict() 

444 self.testMask.clearMaskPlane(planes['CR']) 

445 

446 if False: 

447 for p in planes.keys(): 

448 self.testMask.setMaskPlaneValues(planes[p], self.pixelList) 

449 

450 # print "\nClearing mask" 

451 self.testMask.clearMaskPlane(planes['CR']) 

452 

453 def testPlaneRemoval(self): 

454 """Test mask plane removal""" 

455 

456 def checkPlaneBP(): 

457 self.Mask.getMaskPlane("BP") 

458 

459 testMask2 = self.Mask(self.testMask.getDimensions()) 

460 self.testMask = self.Mask(self.testMask.getDimensions()) 

461 self.testMask.removeAndClearMaskPlane("BP") 

462 

463 testMask2.getMaskPlaneDict() 

464 

465 # still present in default mask 

466 checkPlaneBP() 

467 # should still be in testMask2 

468 self.assertIn("BP", testMask2.getMaskPlaneDict()) 

469 

470 self.Mask.removeMaskPlane("BP") # remove from default mask too 

471 

472 self.assertRaises(pexExcept.InvalidParameterError, checkPlaneBP) 

473 

474 self.assertRaises(pexExcept.InvalidParameterError, 

475 lambda: self.Mask.removeMaskPlane("BP")) # Plane is already removed 

476 self.assertRaises(pexExcept.InvalidParameterError, 

477 lambda: self.testMask.removeMaskPlane("RHL gets names right")) 

478 # 

479 self.Mask.clearMaskPlaneDict() 

480 self.Mask.addMaskPlane("P0") 

481 self.Mask.addMaskPlane("P1") 

482 # a no-op -- readding a plane has no effect 

483 self.Mask.addMaskPlane("P1") 

484 # 

485 # Check that removing default mask planes doesn't affect pre-existing planes 

486 # 

487 msk = self.Mask() 

488 nmask = len(msk.getMaskPlaneDict()) 

489 self.Mask.removeMaskPlane("P0") 

490 self.Mask.removeMaskPlane("P1") 

491 self.assertEqual(len(msk.getMaskPlaneDict()), nmask) 

492 del msk 

493 # 

494 # Check that removeAndClearMaskPlane can clear the default too 

495 # 

496 self.Mask.addMaskPlane("BP") 

497 self.testMask.removeAndClearMaskPlane("BP", True) 

498 

499 self.assertRaises(pexExcept.InvalidParameterError, checkPlaneBP) 

500 

501 def testInvalidPlaneOperations(self): 

502 """Test mask plane operations invalidated by Mask changes""" 

503 

504 testMask3 = self.Mask(self.testMask.getDimensions()) 

505 

506 name = "Great Timothy" 

507 self.Mask.addMaskPlane(name) 

508 testMask3.removeAndClearMaskPlane(name) 

509 

510 self.Mask.getMaskPlane(name) # should be fine 

511 self.assertRaises(KeyError, lambda: testMask3.getMaskPlaneDict()[name]) 

512 

513 def tst(): 

514 self.testMask |= testMask3 

515 

516 self.assertRaises(pexExcept.RuntimeError, tst) 

517 

518 # The dictionary should be back to the same state, so ... 

519 self.Mask.addMaskPlane(name) 

520 tst # ... assertion should not fail 

521 

522 self.testMask.removeAndClearMaskPlane(name, True) 

523 self.Mask.addMaskPlane("Mario") # takes name's slot 

524 self.Mask.addMaskPlane(name) 

525 

526 self.assertRaises(pexExcept.RuntimeError, tst) 

527 

528 def testInvalidPlaneOperations2(self): 

529 """Test mask plane operations invalidated by Mask changes""" 

530 

531 testMask3 = self.Mask(self.testMask.getDimensions()) 

532 

533 name = "Great Timothy" 

534 name2 = "Our Boss" 

535 self.Mask.addMaskPlane(name) 

536 self.Mask.addMaskPlane(name2) 

537 # a description of the Mask's current dictionary 

538 oldDict = testMask3.getMaskPlaneDict() 

539 

540 for n in (name, name2): 

541 self.testMask.removeAndClearMaskPlane(n, True) 

542 

543 # added in opposite order to the planes in testMask3 

544 self.Mask.addMaskPlane(name2) 

545 self.Mask.addMaskPlane(name) 

546 

547 self.assertNotEqual(self.testMask.getMaskPlaneDict()[ 

548 name], oldDict[name]) 

549 

550 def tst(): 

551 self.testMask |= testMask3 

552 

553 self.testMask.removeAndClearMaskPlane("BP") 

554 

555 self.assertRaises(pexExcept.RuntimeError, tst) 

556 # 

557 # OK, that failed as it should. Fixup the dictionaries and try again 

558 # 

559 self.Mask.addMaskPlane("BP") 

560 # convert testMask3 from oldDict to current default 

561 testMask3.conformMaskPlanes(oldDict) 

562 

563 self.testMask |= testMask3 # shouldn't throw 

564 

565 def testConformMaskPlanes(self): 

566 """Test conformMaskPlanes() when the two planes are actually the same""" 

567 

568 testMask3 = self.Mask(self.testMask.getDimensions()) 

569 

570 name = "XXX" 

571 self.Mask.addMaskPlane(name) 

572 oldDict = testMask3.getMaskPlaneDict() 

573 # invalidates dictionary version 

574 testMask3.removeAndClearMaskPlane(name) 

575 

576 testMask3.conformMaskPlanes(oldDict) 

577 

578 self.testMask |= testMask3 

579 

580 def testConformMaskPlanes2(self): 

581 """Test conformMaskPlanes() when the two planes are different""" 

582 

583 testMask3 = afwImage.Mask(self.testMask.getDimensions()) 

584 

585 name1 = "Great Timothy" 

586 name2 = "Our Boss" 

587 p1 = self.Mask.addMaskPlane(name1) 

588 p2 = self.Mask.addMaskPlane(name2) 

589 oldDict = self.testMask.getMaskPlaneDict() 

590 

591 testMask3.setMaskPlaneValues(p1, 0, 5, 0) 

592 testMask3.setMaskPlaneValues(p2, 0, 5, 1) 

593 

594 if display: 

595 afwDisplay.Display(frame=1).mtv(testMask3, title="testConformMaskPlanes2") 

596 

597 self.assertEqual(testMask3[0, 0], testMask3.getPlaneBitMask(name1)) 

598 self.assertEqual(testMask3[0, 1], testMask3.getPlaneBitMask(name2)) 

599 

600 self.testMask.removeAndClearMaskPlane(name1, True) 

601 self.testMask.removeAndClearMaskPlane(name2, True) 

602 self.Mask.addMaskPlane(name2) # added in opposite order to testMask3 

603 self.Mask.addMaskPlane(name1) 

604 

605 self.assertEqual(self.testMask[0, 0], 0) 

606 

607 if display: 

608 afwDisplay.Display(frame=2).mtv(testMask3, title="testConformMaskPlanes2 (cleared and re-added)") 

609 

610 self.assertNotEqual(testMask3[0, 0], 

611 testMask3.getPlaneBitMask(name1)) 

612 self.assertNotEqual(testMask3[0, 1], 

613 testMask3.getPlaneBitMask(name2)) 

614 

615 testMask3.conformMaskPlanes(oldDict) 

616 

617 self.assertEqual(testMask3[0, 0], testMask3.getPlaneBitMask(name1)) 

618 self.assertEqual(testMask3[0, 1], testMask3.getPlaneBitMask(name2)) 

619 

620 if display: 

621 afwDisplay.Display(frame=3).mtv(testMask3, title="testConformMaskPlanes2 (conform with oldDict)") 

622 

623 self.testMask |= testMask3 

624 

625 

626def printMaskPlane(mask, plane, 

627 xrange=list(range(250, 300, 10)), yrange=list(range(300, 400, 20))): 

628 """Print parts of the specified plane of the mask""" 

629 

630 xrange = list(range(min(xrange), max(xrange), 25)) 

631 yrange = list(range(min(yrange), max(yrange), 25)) 

632 

633 for x in xrange: 

634 for y in yrange: 

635 if False: # mask(x,y) confuses swig 

636 print(x, y, mask(x, y), mask(x, y, plane)) 

637 else: 

638 print(x, y, mask(x, y, plane)) 

639 

640 

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

642 pass 

643 

644 

645def setup_module(module): 

646 lsst.utils.tests.init() 

647 

648 

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

650 lsst.utils.tests.init() 

651 unittest.main()