Coverage for tests/test_kernelPca.py: 12%

166 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-06-07 12:41 +0000

1import unittest 

2 

3 

4import lsst.utils.tests 

5import lsst.afw.image as afwImage 

6import lsst.afw.math as afwMath 

7import lsst.geom as geom 

8import lsst.ip.diffim as ipDiffim 

9import lsst.ip.diffim.diffimTools as diffimTools 

10import lsst.utils.logging as logUtils 

11import lsst.pex.config as pexConfig 

12 

13logUtils.trace_set_at("lsst.ip.diffim", 4) 

14 

15 

16class DiffimTestCases(lsst.utils.tests.TestCase): 

17 

18 def setUp(self): 

19 self.config = ipDiffim.PsfMatchConfigDF() 

20 

21 self.kList = ipDiffim.makeKernelBasisList(self.config) 

22 self.ps = pexConfig.makePropertySet(self.config) 

23 self.ps["useRegularization"] = False 

24 

25 def tearDown(self): 

26 del self.config 

27 del self.ps 

28 del self.kList 

29 

30 def makeCandidate(self, kSum, x, y, size=51): 

31 mi1 = afwImage.MaskedImageF(geom.Extent2I(size, size)) 

32 mi1.getVariance().set(1.0) # avoid NaNs 

33 mi1[size//2, size//2, afwImage.LOCAL] = (1, 0x0, 1) 

34 mi2 = afwImage.MaskedImageF(geom.Extent2I(size, size)) 

35 mi2.getVariance().set(1.0) # avoid NaNs 

36 mi2[size//2, size//2, afwImage.LOCAL] = (kSum, 0x0, kSum) 

37 kc = ipDiffim.makeKernelCandidate(x, y, mi1, mi2, self.ps) 

38 return kc 

39 

40 def testGaussian(self, size=51): 

41 gaussFunction = afwMath.GaussianFunction2D(2, 3) 

42 gaussKernel = afwMath.AnalyticKernel(size, size, gaussFunction) 

43 

44 imagePca1 = ipDiffim.KernelPcaD() # mean subtract 

45 imagePca2 = ipDiffim.KernelPcaD() # don't mean subtract 

46 kpv1 = ipDiffim.KernelPcaVisitorF(imagePca1) 

47 kpv2 = ipDiffim.KernelPcaVisitorF(imagePca2) 

48 

49 kRefIm = None 

50 

51 for i in range(100): 

52 kImage1 = afwImage.ImageD(gaussKernel.getDimensions()) 

53 gaussKernel.computeImage(kImage1, False) 

54 kImage1 *= 10000 # to get some decent peak source counts 

55 kImage1 += 10 # to get some sky background noise 

56 

57 if kRefIm is None: 

58 kRefIm = kImage1 

59 

60 kImage1 = diffimTools.makePoissonNoiseImage(kImage1) 

61 kImage2 = afwImage.ImageD(kImage1, True) 

62 

63 imagePca1.addImage(kImage1, 1.0) 

64 imagePca2.addImage(kImage2, 1.0) 

65 

66 kpv1.subtractMean() 

67 

68 imagePca1.analyze() 

69 imagePca2.analyze() 

70 

71 pcaBasisList1 = kpv1.getEigenKernels() 

72 pcaBasisList2 = kpv2.getEigenKernels() 

73 

74 eVal1 = imagePca1.getEigenValues() 

75 eVal2 = imagePca2.getEigenValues() 

76 

77 # First term is far more signficant without mean subtraction 

78 self.assertGreater(eVal2[0], eVal1[0]) 

79 

80 # Last term basically zero with mean subtraction 

81 self.assertAlmostEqual(eVal1[-1], 0.0) 

82 

83 # Extra image with mean subtraction 

84 self.assertEqual(len(pcaBasisList1), (len(eVal1) + 1)) 

85 

86 # Same shape 

87 self.assertEqual(len(pcaBasisList2), len(eVal2)) 

88 

89 # Mean kernel close to kRefIm 

90 kImageM = afwImage.ImageD(gaussKernel.getDimensions()) 

91 pcaBasisList1[0].computeImage(kImageM, False) 

92 for y in range(kRefIm.getHeight()): 

93 for x in range(kRefIm.getWidth()): 

94 self.assertLess(abs(kRefIm[x, y, afwImage.LOCAL] - kImageM[x, y, afwImage.LOCAL]) 

95 / kRefIm[x, y, afwImage.LOCAL], 0.2) 

96 

97 # First mean-unsubtracted Pca kernel close to kRefIm (normalized to peak of 1.0) 

98 kImage0 = afwImage.ImageD(gaussKernel.getDimensions()) 

99 pcaBasisList2[0].computeImage(kImage0, False) 

100 maxVal = afwMath.makeStatistics(kRefIm, afwMath.MAX).getValue(afwMath.MAX) 

101 kRefIm /= maxVal 

102 for y in range(kRefIm.getHeight()): 

103 for x in range(kRefIm.getWidth()): 

104 self.assertLess(abs(kRefIm[x, y, afwImage.LOCAL] - kImage0[x, y, afwImage.LOCAL]) 

105 / kRefIm[x, y, afwImage.LOCAL], 0.2) 

106 

107 def testImagePca(self): 

108 # Test out the ImagePca behavior 

109 kc1 = self.makeCandidate(1, 0.0, 0.0) 

110 kc1.build(self.kList) 

111 kc2 = self.makeCandidate(2, 0.0, 0.0) 

112 kc2.build(self.kList) 

113 kc3 = self.makeCandidate(3, 0.0, 0.0) 

114 kc3.build(self.kList) 

115 

116 imagePca = ipDiffim.KernelPcaD() 

117 kpv = ipDiffim.KernelPcaVisitorF(imagePca) 

118 kpv.processCandidate(kc1) 

119 kpv.processCandidate(kc2) 

120 kpv.processCandidate(kc3) 

121 

122 imagePca.analyze() 

123 eigenImages = imagePca.getEigenImages() 

124 # NOTE : this needs to be changed once ticket #1649 is resolved 

125 for i in range(len(eigenImages)): 

126 for j in range(i, len(eigenImages)): 

127 print(i, j, afwImage.innerProduct(eigenImages[i], eigenImages[j])) 

128 

129 def testEigenValues(self): 

130 kc1 = self.makeCandidate(1, 0.0, 0.0) 

131 kc1.build(self.kList) 

132 

133 kc2 = self.makeCandidate(2, 0.0, 0.0) 

134 kc2.build(self.kList) 

135 

136 kc3 = self.makeCandidate(3, 0.0, 0.0) 

137 kc3.build(self.kList) 

138 

139 imagePca = ipDiffim.KernelPcaD() 

140 kpv = ipDiffim.KernelPcaVisitorF(imagePca) 

141 kpv.processCandidate(kc1) 

142 kpv.processCandidate(kc2) 

143 kpv.processCandidate(kc3) 

144 

145 imagePca.analyze() 

146 eigenImages = imagePca.getEigenImages() 

147 eigenValues = imagePca.getEigenValues() 

148 

149 # took in 3 images 

150 self.assertEqual(len(eigenImages), 3) 

151 self.assertEqual(len(eigenValues), 3) 

152 

153 # all the same shape, only 1 eigenvalue 

154 self.assertAlmostEqual(eigenValues[0], 1.0) 

155 self.assertAlmostEqual(eigenValues[1], 0.0) 

156 self.assertAlmostEqual(eigenValues[2], 0.0) 

157 

158 def testMeanSubtraction(self): 

159 kc1 = self.makeCandidate(1, 0.0, 0.0) 

160 kc1.build(self.kList) 

161 

162 kc2 = self.makeCandidate(2, 0.0, 0.0) 

163 kc2.build(self.kList) 

164 

165 kc3 = self.makeCandidate(3, 0.0, 0.0) 

166 kc3.build(self.kList) 

167 

168 imagePca = ipDiffim.KernelPcaD() 

169 kpv = ipDiffim.KernelPcaVisitorF(imagePca) 

170 kpv.processCandidate(kc1) 

171 kpv.processCandidate(kc2) 

172 kpv.processCandidate(kc3) 

173 kpv.subtractMean() # subtract it *from* imagePca 

174 

175 imagePca.analyze() 

176 eigenImages = imagePca.getEigenImages() 

177 eigenValues = imagePca.getEigenValues() 

178 

179 # took in 3 images 

180 self.assertEqual(len(eigenImages), 3) 

181 self.assertEqual(len(eigenValues), 3) 

182 

183 # all the same shape, mean subtracted, so *no* eigenvalues 

184 self.assertAlmostEqual(eigenValues[0], 0.0) 

185 self.assertAlmostEqual(eigenValues[1], 0.0) 

186 self.assertAlmostEqual(eigenValues[2], 0.0) 

187 

188 # finally, since imagePca normalizes by the sum, this should 

189 # have central pixel value 1.0 and the rest 0.0 

190 imageMean = kpv.returnMean() 

191 rows = imageMean.getHeight() 

192 cols = imageMean.getWidth() 

193 for y in range(rows): 

194 for x in range(cols): 

195 if x == cols // 2 and y == rows // 2: 

196 self.assertAlmostEqual(imageMean[x, y, afwImage.LOCAL], 1.0) 

197 else: 

198 self.assertAlmostEqual(imageMean[x, y, afwImage.LOCAL], 0.0) 

199 

200 def testVisit(self, nCell=3): 

201 imagePca = ipDiffim.KernelPcaD() 

202 kpv = ipDiffim.makeKernelPcaVisitor(imagePca) 

203 

204 sizeCellX = self.ps["sizeCellX"] 

205 sizeCellY = self.ps["sizeCellY"] 

206 

207 kernelCellSet = afwMath.SpatialCellSet(geom.Box2I(geom.Point2I(0, 0), 

208 geom.Extent2I(sizeCellX * nCell, 

209 sizeCellY * nCell)), 

210 sizeCellX, 

211 sizeCellY) 

212 

213 for candX in range(nCell): 

214 for candY in range(nCell): 

215 if candX == nCell // 2 and candY == nCell // 2: 

216 kc = self.makeCandidate(100.0, 

217 candX * sizeCellX + sizeCellX // 2, 

218 candY * sizeCellY + sizeCellY // 2) 

219 else: 

220 kc = self.makeCandidate(1.0, 

221 candX * sizeCellX + sizeCellX // 2, 

222 candY * sizeCellY + sizeCellY // 2) 

223 kc.build(self.kList) 

224 kernelCellSet.insertCandidate(kc) 

225 

226 kernelCellSet.visitCandidates(kpv, 1) 

227 imagePca.analyze() 

228 eigenImages = imagePca.getEigenImages() 

229 eigenValues = imagePca.getEigenValues() 

230 

231 # took in 3 images 

232 self.assertEqual(len(eigenImages), nCell * nCell) 

233 self.assertEqual(len(eigenValues), nCell * nCell) 

234 

235 # all the same shape, only 1 eigenvalue 

236 self.assertAlmostEqual(eigenValues[0], 1.0) 

237 self.assertAlmostEqual(eigenValues[1], 0.0) 

238 self.assertAlmostEqual(eigenValues[2], 0.0) 

239 

240##### 

241 

242 

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

244 pass 

245 

246 

247def setup_module(module): 

248 lsst.utils.tests.init() 

249 

250 

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

252 lsst.utils.tests.init() 

253 unittest.main()