Coverage for tests/test_generalShapeletPsfModels.py: 25%
130 statements
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-23 03:16 -0700
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-23 03:16 -0700
1#
2# LSST Data Management System
3#
4# Copyright 2008-2016 AURA/LSST.
5#
6# This product includes software developed by the
7# LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20# the GNU General Public License along with this program. If not,
21# see <https://www.lsstcorp.org/LegalNotices/>.
22#
23import unittest
24import numpy
25import os
27import lsst.utils.tests
28import lsst.shapelet
29import lsst.geom
30import lsst.afw.geom.ellipses
31import lsst.afw.table
32import lsst.afw.detection
33import lsst.log
34import lsst.utils.logging
35import lsst.meas.modelfit
36import lsst.meas.base
37import lsst.meas.algorithms
39# Set trace to 0-5 to view debug messages. Level 5 enables all traces.
40lsst.utils.logging.trace_set_at("lsst.meas.modelfit.optimizer.Optimizer", -1)
41lsst.utils.logging.trace_set_at("lsst.meas.modelfit.optimizer.solveTrustRegion", -1)
44class GeneralShapeletPsfApproxPluginsTestCase(lsst.utils.tests.TestCase):
46 def setUp(self):
47 numpy.random.seed(500)
48 self.exposure = lsst.afw.image.ExposureF(41, 41)
49 self.schema = lsst.afw.table.SourceTable.makeMinimalSchema()
50 self.centroidKey = lsst.afw.table.Point2DKey.addFields(self.schema, "centroid", "centroid", "pixel")
51 self.schema.getAliasMap().set("slot_Centroid", "centroid")
52 self.psfDir = os.path.join(os.environ["MEAS_MODELFIT_DIR"], "tests", "data", "psfs")
54 def tearDown(self):
55 del self.exposure
56 del self.schema
57 del self.centroidKey
58 del self.psfDir
60 def makePsf(self, psfname, max=None):
61 data = lsst.afw.image.ImageF(os.path.join(self.psfDir, psfname)).getArray().astype(numpy.float64)
62 if max is not None:
63 trim0 = (data.shape[0] - max)//2
64 trim1 = (data.shape[1] - max)//2
65 if trim0 > 0 and trim1 > 0:
66 data = data[trim0:trim0+max, trim1:trim1+max]
67 kernel = lsst.afw.math.FixedKernel(lsst.afw.image.ImageD(data))
68 return lsst.meas.algorithms.KernelPsf(kernel)
70 def runTask(self, psftype, sequence):
71 config = lsst.meas.base.SingleFrameMeasurementTask.ConfigClass()
72 config.slots.centroid = None
73 config.slots.shape = None
74 config.slots.psfFlux = None
75 config.slots.apFlux = None
76 config.slots.gaussianFlux = None
77 config.slots.modelFlux = None
78 config.slots.calibFlux = None
79 config.doReplaceWithNoise = False
80 config.plugins.names = ["modelfit_GeneralShapeletPsfApprox"]
81 config.plugins["modelfit_GeneralShapeletPsfApprox"].sequence = sequence
82 task = lsst.meas.base.SingleFrameMeasurementTask(config=config, schema=self.schema)
83 measCat = lsst.afw.table.SourceCatalog(self.schema)
84 measRecord = measCat.addNew()
85 measRecord.set(self.centroidKey, lsst.geom.Point2D(20.0, 20.0))
86 measRecord.set(self.centroidKey, lsst.geom.Point2D(20.0, 20.0))
87 task.run(measCat, self.exposure)
88 return measRecord
90 def testSingleGaussian(self):
91 sigma1 = 3.0
92 self.exposure.setPsf(lsst.afw.detection.GaussianPsf(19, 19, sigma1))
93 measRecord = self.runTask("Single Gaussian Psf", ["SingleGaussian"])
94 keySingleGaussian = lsst.shapelet.MultiShapeletFunctionKey(
95 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["SingleGaussian"]
96 )
97 msfSingleGaussian = measRecord.get(keySingleGaussian)
98 self.assertEqual(len(msfSingleGaussian.getComponents()), 1)
99 comps = msfSingleGaussian.getComponents()
100 r0 = comps[0].getEllipse().getCore().getDeterminantRadius()
101 self.assertFloatsAlmostEqual(r0, sigma1, .05)
103 def testDoubleGaussian(self):
104 sigma1 = 2.0
105 sigma2 = 4.0
106 self.exposure.setPsf(lsst.meas.algorithms.DoubleGaussianPsf(19, 19, sigma1, sigma2, .25))
107 measRecord = self.runTask("Double Gaussian Psf", ["DoubleGaussian"])
108 keyDoubleGaussian = lsst.shapelet.MultiShapeletFunctionKey(
109 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["DoubleGaussian"]
110 )
111 msf = measRecord.get(keyDoubleGaussian)
112 comps = msf.getComponents()
113 self.assertEqual(len(comps), 2)
114 # amplitudes are equal by construction
115 A0 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleGaussian_0_0")
116 A1 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleGaussian_1_0")
117 self.assertFloatsAlmostEqual(A0, A1, .05)
118 r0 = comps[0].getEllipse().getCore().getDeterminantRadius()
119 r1 = comps[1].getEllipse().getCore().getDeterminantRadius()
120 self.assertFloatsAlmostEqual(r0, sigma1, .05)
121 self.assertFloatsAlmostEqual(r1, sigma2, .05)
123 def testDoubleShapelet(self):
124 self.exposure.setPsf(self.makePsf("galsimPsf_0.5.fits", max=33))
125 measRecord = self.runTask("Galsim Psf", ["DoubleShapelet"])
126 keyDoubleShapelet = lsst.shapelet.MultiShapeletFunctionKey(
127 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["DoubleShapelet"]
128 )
129 msf = measRecord.get(keyDoubleShapelet)
130 comps = msf.getComponents()
131 self.assertEqual(len(comps), 2)
132 A0 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleShapelet_0_0")
133 A1 = measRecord.get("modelfit_GeneralShapeletPsfApprox_DoubleShapelet_1_0")
134 self.assertGreater(A1, .04)
135 self.assertGreater(A0, .04)
137 def testFull(self):
138 self.exposure.setPsf(self.makePsf("galsimPsf_0.9.fits", max=33))
139 measRecord = self.runTask("Galsim Psf", ["Full"])
140 keyFull = lsst.shapelet.MultiShapeletFunctionKey(
141 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["Full"]
142 )
143 msf = measRecord.get(keyFull)
144 comps = msf.getComponents()
145 self.assertEqual(len(comps), 4)
146 A1 = measRecord.get("modelfit_GeneralShapeletPsfApprox_Full_1_0")
147 A2 = measRecord.get("modelfit_GeneralShapeletPsfApprox_Full_2_0")
148 # test the primary and wings to be sure we are getting something
149 self.assertGreater(A2, .04)
150 self.assertGreater(A1, .04)
152 def testSequence(self):
153 sigma1 = 2.0
154 sigma2 = 4.0
155 self.exposure.setPsf(lsst.meas.algorithms.DoubleGaussianPsf(19, 19, sigma1, sigma2, .25))
156 measRecord = self.runTask("Single Gaussian Psf", ["SingleGaussian", "DoubleGaussian",
157 "DoubleShapelet"])
158 keySingleGaussian = lsst.shapelet.MultiShapeletFunctionKey(
159 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["SingleGaussian"]
160 )
161 msfSingleGaussian = measRecord.get(keySingleGaussian)
162 self.assertEqual(len(msfSingleGaussian.getComponents()), 1)
163 comps = msfSingleGaussian.getComponents()
164 r0 = comps[0].getEllipse().getCore().getDeterminantRadius()
165 # don't expect it to be all that close, but the DoubleGaussian should be
166 self.assertFloatsAlmostEqual(r0, sigma1, .3)
168 keyDoubleGaussian = lsst.shapelet.MultiShapeletFunctionKey(
169 self.schema["modelfit"]["GeneralShapeletPsfApprox"]["DoubleGaussian"]
170 )
171 msfDoubleGaussian = measRecord.get(keyDoubleGaussian)
172 comps = msfDoubleGaussian.getComponents()
173 r0 = comps[0].getEllipse().getCore().getDeterminantRadius()
174 r1 = comps[1].getEllipse().getCore().getDeterminantRadius()
175 self.assertFloatsAlmostEqual(r0, sigma1, .05)
176 self.assertFloatsAlmostEqual(r1, sigma2, .05)
179class TestMemory(lsst.utils.tests.MemoryTestCase):
180 pass
183def setup_module(module):
184 lsst.utils.tests.init()
187if __name__ == "__main__": 187 ↛ 188line 187 didn't jump to line 188, because the condition on line 187 was never true
188 lsst.utils.tests.init()
189 unittest.main()