Coverage for tests/test_imagePsfMatch.py: 14%
166 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-11 03:16 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-11 03:16 -0800
1#
2# LSST Data Management System
3# Copyright 2008-2016 AURA/LSST.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <https://www.lsstcorp.org/LegalNotices/>.
21#
24import unittest
27import lsst.utils.tests
28from lsst.afw.geom import makeSkyWcs
29import lsst.afw.image as afwImage
30import lsst.afw.math as afwMath
31import lsst.ip.diffim as ipDiffim
32import lsst.ip.diffim.diffimTools as diffimTools
33import lsst.daf.base as dafBase
34import lsst.utils.logging as logUtils
35import lsst.meas.algorithms as measAlg
37logUtils.trace_set_at("lsst.ip.diffim", 4)
40class PsfMatchTestCases(unittest.TestCase):
42 def setUp(self):
43 self.configAL = ipDiffim.ImagePsfMatchTask.ConfigClass()
44 self.configAL.kernel.name = "AL"
45 self.subconfigAL = self.configAL.kernel.active
47 self.configDF = ipDiffim.ImagePsfMatchTask.ConfigClass()
48 self.configDF.kernel.name = "DF"
49 self.subconfigDF = self.configDF.kernel.active
51 self.configDFr = ipDiffim.ImagePsfMatchTask.ConfigClass()
52 self.configDFr.kernel.name = "DF"
53 self.subconfigDFr = self.configDFr.kernel.active
55 self.subconfigAL.afwBackgroundConfig.useApprox = False
56 self.subconfigDF.afwBackgroundConfig.useApprox = False
57 self.subconfigDFr.afwBackgroundConfig.useApprox = False
59 self.subconfigDF.useRegularization = False
60 self.subconfigDFr.useRegularization = True
62 self.subconfigAL.constantVarianceWeighting = False
63 self.subconfigDF.constantVarianceWeighting = False
64 self.subconfigDFr.constantVarianceWeighting = False
66 # variance is a hack
67 self.subconfigAL.singleKernelClipping = False
68 self.subconfigAL.spatialKernelClipping = False
69 self.subconfigDF.singleKernelClipping = False
70 self.subconfigDF.spatialKernelClipping = False
71 self.subconfigDFr.singleKernelClipping = False
72 self.subconfigDFr.spatialKernelClipping = False
74 # Send fake kernel a differential background
75 self.bgValue = 100.
76 self.subconfigAL.fitForBackground = True
77 self.subconfigDF.fitForBackground = True
78 self.subconfigDFr.fitForBackground = True
80 # Make ideal PSF
81 self.ksize = 21
82 self.sigma = 2.0
83 self.psf = measAlg.DoubleGaussianPsf(self.ksize, self.ksize, self.sigma)
85 def makeWcs(self, offset=0):
86 # taken from $AFW_DIR/tests/testMakeWcs.py
87 metadata = dafBase.PropertySet()
88 metadata.set("SIMPLE", "T")
89 metadata.set("BITPIX", -32)
90 metadata.set("NAXIS", 2)
91 metadata.set("NAXIS1", 1024)
92 metadata.set("NAXIS2", 1153)
93 metadata.set("RADESYS", 'FK5')
94 metadata.set("EQUINOX", 2000.)
95 metadata.setDouble("CRVAL1", 215.604025685476)
96 metadata.setDouble("CRVAL2", 53.1595451514076)
97 metadata.setDouble("CRPIX1", 1109.99981456774 + offset)
98 metadata.setDouble("CRPIX2", 560.018167811613 + offset)
99 metadata.set("CTYPE1", 'RA---SIN')
100 metadata.set("CTYPE2", 'DEC--SIN')
101 metadata.setDouble("CD1_1", 5.10808596133527E-05)
102 metadata.setDouble("CD1_2", 1.85579539217196E-07)
103 metadata.setDouble("CD2_2", -5.10281493481982E-05)
104 metadata.setDouble("CD2_1", -8.27440751733828E-07)
105 return makeSkyWcs(metadata)
107 def testWarping(self):
108 tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet(bgValue=self.bgValue)
110 tWcs = self.makeWcs(offset=0)
111 sWcs = self.makeWcs(offset=1)
112 tExp = afwImage.ExposureF(tMi, tWcs)
113 sExp = afwImage.ExposureF(sMi, sWcs)
115 # Should fail due to registration problem
116 psfMatchAL = ipDiffim.ImagePsfMatchTask(config=self.configAL)
117 try:
118 psfMatchAL.subtractExposures(tExp, sExp, doWarping=True)
119 except Exception as e:
120 print("testWarning failed with %r" % (e,))
121 pass
122 else:
123 self.fail()
125 def testSubtractExposures(self):
126 # Test all 3 options
127 tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet(bgValue=self.bgValue)
129 tWcs = self.makeWcs(offset=0)
130 sWcs = self.makeWcs(offset=1)
131 tExp = afwImage.ExposureF(tMi, tWcs)
132 sExp = afwImage.ExposureF(sMi, sWcs)
133 sExp.setPsf(self.psf)
134 tExp.setPsf(self.psf)
136 psfMatchAL = ipDiffim.ImagePsfMatchTask(config=self.configAL)
137 psfMatchDF = ipDiffim.ImagePsfMatchTask(config=self.configDF)
138 psfMatchDFr = ipDiffim.ImagePsfMatchTask(config=self.configDFr)
140 self.assertEqual(psfMatchAL.useRegularization, False)
141 self.assertEqual(psfMatchDF.useRegularization, False)
142 self.assertEqual(psfMatchDFr.useRegularization, True)
144 resultsAL = psfMatchAL.subtractExposures(tExp, sExp, doWarping=True)
145 psfMatchDF.subtractExposures(tExp, sExp, doWarping=True)
146 psfMatchDFr.subtractExposures(tExp, sExp, doWarping=True)
148 self.assertEqual(type(resultsAL.subtractedExposure), afwImage.ExposureF)
149 self.assertEqual(type(resultsAL.psfMatchingKernel), afwMath.LinearCombinationKernel)
150 self.assertEqual(type(resultsAL.backgroundModel), afwMath.Chebyshev1Function2D)
151 self.assertEqual(type(resultsAL.kernelCellSet), afwMath.SpatialCellSet)
153 def testMatchExposures(self):
154 # Only test 1 option
155 tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet(bgValue=self.bgValue)
157 tWcs = self.makeWcs(offset=0)
158 sWcs = self.makeWcs(offset=1)
159 tExp = afwImage.ExposureF(tMi, tWcs)
160 sExp = afwImage.ExposureF(sMi, sWcs)
161 sExp.setPsf(self.psf)
162 tExp.setPsf(self.psf)
164 psfMatchAL = ipDiffim.ImagePsfMatchTask(config=self.configAL)
165 resultsAL = psfMatchAL.matchExposures(tExp, sExp,
166 templateFwhmPix=2.0, scienceFwhmPix=3.0, doWarping=True)
167 self.assertEqual(type(resultsAL.matchedExposure), afwImage.ExposureF)
168 self.assertEqual(type(resultsAL.psfMatchingKernel), afwMath.LinearCombinationKernel)
169 self.assertEqual(type(resultsAL.backgroundModel), afwMath.Chebyshev1Function2D)
170 self.assertEqual(type(resultsAL.kernelCellSet), afwMath.SpatialCellSet)
172 def testPca(self, nTerms=3):
173 tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet(bgValue=self.bgValue)
175 tWcs = self.makeWcs(offset=0)
176 sWcs = self.makeWcs(offset=0)
177 tExp = afwImage.ExposureF(tMi, tWcs)
178 sExp = afwImage.ExposureF(sMi, sWcs)
179 sExp.setPsf(self.psf)
181 self.subconfigDF.usePcaForSpatialKernel = True
182 self.subconfigDF.numPrincipalComponents = nTerms
184 psfMatchDF = ipDiffim.ImagePsfMatchTask(config=self.configDF)
185 candList = psfMatchDF.makeCandidateList(tExp, sExp, self.ksize)
186 resultsDF = psfMatchDF.subtractMaskedImages(tMi, sMi, candList)
188 spatialKernel = resultsDF.psfMatchingKernel
189 spatialKernelSolution = spatialKernel.getSpatialParameters()
190 self.assertEqual(len(spatialKernelSolution), nTerms)
192 # First basis has no spatial variation
193 for i in range(1, nTerms):
194 self.assertEqual(spatialKernelSolution[0][i], 0.)
196 # All bases have correct number of terms
197 sko = self.subconfigDF.spatialKernelOrder
198 nSpatialTerms = int(0.5 * (sko + 1) * (sko + 2))
199 for i in range(len(spatialKernelSolution)):
200 self.assertEqual(len(spatialKernelSolution[i]), nSpatialTerms)
202 spatialBg = resultsDF.backgroundModel
203 spatialBgSolution = spatialBg.getParameters()
204 bgo = self.subconfigDF.spatialBgOrder
205 nBgTerms = int(0.5 * (bgo + 1) * (bgo + 2))
206 self.assertEqual(len(spatialBgSolution), nBgTerms)
208 def testSubtractMaskedImages(self):
209 # Lets do some additional testing here to make sure we recover
210 # the known spatial model. No background, just the faked
211 # alard-lupton basis set. The rest of matchMaskedImages() and
212 # subtractMaskedImages() functionality is tested by the
213 # Exposure-based methods.
214 fakeCoeffs = diffimTools.fakeCoeffs()
216 # Quick note; you shouldn't change confake here, since the
217 # candidates in the KernelCellSet are initialized in
218 # makeFakeKernelSet
219 tMi, sMi, sK, kcs, confake = diffimTools.makeFakeKernelSet(bgValue=0.0, addNoise=False)
221 svar = sMi.getVariance()
222 svar.set(1.0)
223 tvar = tMi.getVariance()
224 tvar.set(1.0)
226 basisList = ipDiffim.makeKernelBasisList(confake.kernel.active)
227 psfMatchAL = ipDiffim.ImagePsfMatchTask(config=confake)
228 spatialSolution, psfMatchingKernel, backgroundModel = psfMatchAL._solve(kcs, basisList)
230 fitCoeffs = psfMatchingKernel.getSpatialParameters()
232 for b in range(len(fakeCoeffs)):
233 for s in range(len(fakeCoeffs[b])):
235 if fakeCoeffs[b][s] == 0.0:
236 self.assertAlmostEqual(fitCoeffs[b][s], 0.0)
237 else:
238 # OUTSTANDING ISSUE - WHY IS THIS ONE TERM OFF!?!?
239 if b != 4 and s != 0:
240 self.assertAlmostEqual(fitCoeffs[b][s]/fakeCoeffs[b][s], 1.0, 1)
242 def tearDown(self):
243 del self.configAL
244 del self.configDF
245 del self.configDFr
246 del self.psf
249class TestMemory(lsst.utils.tests.MemoryTestCase):
250 pass
253def setup_module(module):
254 lsst.utils.tests.init()
257if __name__ == "__main__": 257 ↛ 258line 257 didn't jump to line 258, because the condition on line 257 was never true
258 lsst.utils.tests.init()
259 unittest.main()