Coverage for tests/test_measureApCorr.py : 98%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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 as np
26import lsst.geom
27import lsst.afw.image as afwImage
28import lsst.afw.table as afwTable
29from lsst.afw.math import ChebyshevBoundedField
30import lsst.pex.config
31import lsst.meas.algorithms.measureApCorr as measureApCorr
32from lsst.meas.base.apCorrRegistry import addApCorrName
33import lsst.meas.base.tests
34import lsst.utils.tests
37def apCorrDefaultMap(value=None, bbox=None):
38 default_coefficients = np.ones((1, 1), dtype=float)
39 default_coefficients /= value
40 default_apCorrMap = ChebyshevBoundedField(bbox, default_coefficients)
41 default_fill = afwImage.ImageF(bbox)
42 default_apCorrMap.fillImage(default_fill)
43 return(default_fill)
46class MeasureApCorrTestCase(lsst.meas.base.tests.AlgorithmTestCase, lsst.utils.tests.TestCase):
48 def makeCatalog(self, apCorrScale=1.0, numSources=5):
49 sourceCat = afwTable.SourceCatalog(self.schema)
50 fluxName = self.name + "_instFlux"
51 flagName = self.name + "_flag"
52 fluxErrName = self.name + "_instFluxErr"
53 apFluxName = self.apname + "_instFlux"
54 apFlagName = self.apname + "_flag"
55 apFluxErrName = self.apname + "_instFluxErr"
56 fluxKey = self.schema.find(fluxName).key
57 flagKey = self.schema.find(flagName).key
58 fluxErrKey = self.schema.find(fluxErrName).key
59 apFluxKey = self.schema.find(apFluxName).key
60 apFlagKey = self.schema.find(apFlagName).key
61 apFluxErrKey = self.schema.find(apFluxErrName).key
62 centroidKey = afwTable.Point2DKey(self.schema["slot_Centroid"])
63 inputFilterFlagKey = self.schema.find(self.meas_apCorr_task.config.sourceSelector.active.field).key
64 x = np.random.rand(numSources)*self.exposure.getWidth() + self.exposure.getX0()
65 y = np.random.rand(numSources)*self.exposure.getHeight() + self.exposure.getY0()
66 for _i in range(numSources):
67 source_test_instFlux = 5.1
68 source_test_centroid = lsst.geom.Point2D(x[_i], y[_i])
69 source = sourceCat.addNew()
70 source.set(fluxKey, source_test_instFlux)
71 source.set(apFluxKey, source_test_instFlux * apCorrScale)
72 source.set(centroidKey, source_test_centroid)
73 source.set(fluxErrKey, 0.)
74 source.set(apFluxErrKey, 0.)
75 source.set(flagKey, False)
76 source.set(apFlagKey, False)
77 source.set(inputFilterFlagKey, True)
78 return(sourceCat)
80 def setUp(self):
81 schema = afwTable.SourceTable.makeMinimalSchema()
82 name = "test"
83 apname = "testAp"
84 calib_flag_name = "cal_source_use"
85 addApCorrName(apname)
86 schema.addField(name + "_instFlux", type=float)
87 schema.addField(name + "_instFluxErr", type=float)
88 schema.addField(name + "_flag", type="Flag")
89 schema.addField(apname + "_instFlux", type=float)
90 schema.addField(apname + "_instFluxErr", type=float)
91 schema.addField(apname + "_flag", type="Flag")
92 schema.addField(calib_flag_name, type="Flag")
93 schema.addField(name + "_Centroid_x", type=float)
94 schema.addField(name + "_Centroid_y", type=float)
95 schema.getAliasMap().set('slot_Centroid', name + '_Centroid')
96 config = measureApCorr.MeasureApCorrTask.ConfigClass()
97 config.refFluxName = name
98 config.sourceSelector.active.field = calib_flag_name
99 self.meas_apCorr_task = measureApCorr.MeasureApCorrTask(schema=schema, config=config)
100 self.name = name
101 self.apname = apname
102 self.schema = schema
103 self.exposure = lsst.afw.image.ExposureF(10, 10)
105 def tearDown(self):
106 del self.schema
107 del self.meas_apCorr_task
108 del self.exposure
110 def testAddFields(self):
111 """Instantiating the task should add one field to the schema."""
112 self.assertIn("apcorr_" + self.name + "_used", self.schema.getNames())
114 def testReturnApCorrMap(self):
115 """The measureApCorr task should return a structure with a single key 'apCorrMap'."""
116 struct = self.meas_apCorr_task.run(catalog=self.makeCatalog(), exposure=self.exposure)
117 self.assertEqual(list(struct.getDict().keys()), ['apCorrMap'])
119 def testApCorrMapKeys(self):
120 """An apCorrMap structure should have two keys, based on the name supplied to addApCorrName()."""
121 apfluxName = self.apname + "_instFlux"
122 apfluxErrName = self.apname + "_instFluxErr"
123 struct = self.meas_apCorr_task.run(catalog=self.makeCatalog(), exposure=self.exposure)
124 key_names = [apfluxName, apfluxErrName]
125 self.assertEqual(set(struct.apCorrMap.keys()), set(key_names))
127 def testTooFewSources(self):
128 """ If there are too few sources, check that an exception is raised."""
129 catalog = afwTable.SourceCatalog(self.schema)
130 with self.assertRaises(RuntimeError):
131 self.meas_apCorr_task.run(catalog=catalog, exposure=self.exposure)
132 # With the measurement algorithm declared as something that might fail, should not get an exception
133 self.meas_apCorr_task.config.allowFailure.append(self.apname)
134 self.meas_apCorr_task.run(catalog=catalog, exposure=self.exposure)
136 def testSourceNotUsed(self):
137 """ Check that a source outside the bounding box is flagged as not used (False)."""
138 fluxName = self.name + "_instFlux"
139 apCorrFlagKey = self.schema.find("apcorr_" + self.name + "_used").key
140 sourceCat = self.makeCatalog()
141 source = sourceCat.addNew()
142 source_test_instFlux = 5.1
143 source_test_centroid = lsst.geom.Point2D(15, 7.1)
144 fluxKey = self.schema.find(fluxName).key
145 centroidKey = afwTable.Point2DKey(self.schema["slot_Centroid"])
146 source.set(fluxKey, source_test_instFlux)
147 source.set(centroidKey, source_test_centroid)
148 self.meas_apCorr_task.run(catalog=sourceCat, exposure=self.exposure)
149 self.assertFalse(sourceCat[apCorrFlagKey][-1])
151 def testSourceUsed(self):
152 """Check that valid sources inside the bounding box that are used have their flags set to True."""
153 inputFilterFlagKey = self.schema.find(self.meas_apCorr_task.config.sourceSelector.active.field).key
154 sourceCat = self.makeCatalog()
155 self.meas_apCorr_task.run(catalog=sourceCat, exposure=self.exposure)
156 self.assertTrue(sourceCat[inputFilterFlagKey].all())
158 def testApertureMeasOnes(self):
159 """ Check that sources with aperture fluxes exactly the same as their catalog fluxes
160 returns an aperture correction map of 1s"""
161 apFluxName = self.apname + "_instFlux"
162 sourceCat = self.makeCatalog()
163 struct = self.meas_apCorr_task.run(catalog=sourceCat, exposure=self.exposure)
164 default_fill = apCorrDefaultMap(value=1.0, bbox=self.exposure.getBBox())
165 test_fill = afwImage.ImageF(self.exposure.getBBox())
166 struct.apCorrMap[apFluxName].fillImage(test_fill)
167 np.testing.assert_allclose(test_fill.getArray(), default_fill.getArray())
169 def testApertureMeasTens(self):
170 """Check that aperture correction scales source fluxes in the correct direction."""
171 apCorr_factor = 10.
172 sourceCat = self.makeCatalog(apCorrScale=apCorr_factor)
173 apFluxName = self.apname + "_instFlux"
174 struct = self.meas_apCorr_task.run(catalog=sourceCat, exposure=self.exposure)
175 default_fill = apCorrDefaultMap(value=apCorr_factor, bbox=self.exposure.getBBox())
176 test_fill = afwImage.ImageF(self.exposure.getBBox())
177 struct.apCorrMap[apFluxName].fillImage(test_fill)
178 np.testing.assert_allclose(test_fill.getArray(), default_fill.getArray())
181class TestMemory(lsst.utils.tests.MemoryTestCase):
182 pass
185def setup_module(module):
186 lsst.utils.tests.init()
189if __name__ == "__main__": 189 ↛ 190line 189 didn't jump to line 190, because the condition on line 189 was never true
190 lsst.utils.tests.init()
191 unittest.main()