Coverage for tests/test_Classification.py: 30%
65 statements
« prev ^ index » next coverage.py v6.4, created at 2022-05-24 02:54 -0700
« prev ^ index » next coverage.py v6.4, created at 2022-05-24 02:54 -0700
1# This file is part of meas_base.
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/>.
22import unittest
24import lsst.utils.tests
25import lsst.geom
26import lsst.afw.geom
27import lsst.meas.base.tests
28import lsst.meas.base as measBase
29import lsst.meas.base.catalogCalculation as catCalc
32class ClassificationTestCase(lsst.meas.base.tests.AlgorithmTestCase, lsst.utils.tests.TestCase):
34 def setUp(self):
35 self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(-20, -20),
36 lsst.geom.Extent2I(250, 150))
37 self.dataset = lsst.meas.base.tests.TestDataset(self.bbox)
38 # first source is a point
39 self.dataset.addSource(100000.0, lsst.geom.Point2D(50.1, 49.8))
40 # second source is extended
41 self.dataset.addSource(100000.0, lsst.geom.Point2D(149.9, 50.3),
42 lsst.afw.geom.Quadrupole(8, 9, 3))
44 def tearDown(self):
45 del self.bbox
46 del self.dataset
48 def testSingleFramePlugin(self):
49 config = measBase.SingleFrameMeasurementConfig()
50 # n.b. we use the truth value as ModelFlux
51 config.slots.psfFlux = "base_PsfFlux"
52 config.slots.modelFlux = "truth"
53 task = self.makeSingleFrameMeasurementTask(config=config)
54 abTask = catCalc.CatalogCalculationTask(schema=task.schema)
55 exposure, catalog = self.dataset.realize(10.0, task.schema, randomSeed=0)
56 task.run(catalog, exposure)
57 abTask.run(catalog)
58 self.assertLess(catalog[0].get("base_ClassificationExtendedness_value"), 0.5)
59 self.assertGreater(catalog[1].get("base_ClassificationExtendedness_value"), 0.5)
61 def testFlags(self):
62 """Test for success and check all failure modes.
64 Test all the failure modes of this algorithm, as well as checking that
65 it succeeds when it should.
67 Notes
68 -----
69 Since this algorithm depends on having a ``ModelFlux`` and a
70 ``PsfFlux`` measurement, it is a failure mode when either is NaN, or
71 when ``ModelFluxFlag`` or ``PsfFluxFlag`` is ``True``.
73 When ``psfFluxFactor != 0``, the ``PsfFluxErr`` cannot be NaN, but
74 otherwise is ignored.
76 When ``modelFluxFactor != 0``, the ``ModelFluxErr`` cannot be NaN, but
77 otherwise is ignored.
78 """
79 config = measBase.SingleFrameMeasurementConfig()
80 config.slots.psfFlux = "base_PsfFlux"
81 config.slots.modelFlux = "base_GaussianFlux"
83 abConfig = catCalc.CatalogCalculationConfig()
85 def runFlagTest(psfFlux=100.0, modelFlux=200.0,
86 psfFluxErr=1.0, modelFluxErr=2.0,
87 psfFluxFlag=False, modelFluxFlag=False):
88 task = self.makeSingleFrameMeasurementTask(config=config)
89 abTask = catCalc.CatalogCalculationTask(schema=task.schema, config=abConfig)
90 exposure, catalog = self.dataset.realize(10.0, task.schema, randomSeed=1)
91 source = catalog[0]
92 source.set("base_PsfFlux_instFlux", psfFlux)
93 source.set("base_PsfFlux_instFluxErr", psfFluxErr)
94 source.set("base_PsfFlux_flag", psfFluxFlag)
95 source.set("base_GaussianFlux_instFlux", modelFlux)
96 source.set("base_GaussianFlux_instFluxErr", modelFluxErr)
97 source.set("base_GaussianFlux_flag", modelFluxFlag)
98 abTask.plugins["base_ClassificationExtendedness"].calculate(source)
99 return source.get("base_ClassificationExtendedness_flag")
101 # Test no error case - all necessary values are set
102 self.assertFalse(runFlagTest())
104 # Test psfFlux flag case - failure in PsfFlux
105 self.assertTrue(runFlagTest(psfFluxFlag=True))
107 # Test modelFlux flag case - failure in ModelFlux
108 self.assertTrue(runFlagTest(modelFluxFlag=True))
110 # Test modelFlux NAN case
111 self.assertTrue(runFlagTest(modelFlux=float("NaN"), modelFluxFlag=True))
113 # Test psfFlux NAN case
114 self.assertTrue(runFlagTest(psfFlux=float("NaN"), psfFluxFlag=True))
116 # Test modelFluxErr NAN case when modelErrFactor is zero and non-zero
117 abConfig.plugins["base_ClassificationExtendedness"].modelErrFactor = 0.
118 self.assertFalse(runFlagTest(modelFluxErr=float("NaN")))
119 abConfig.plugins["base_ClassificationExtendedness"].modelErrFactor = 1.
120 self.assertTrue(runFlagTest(modelFluxErr=float("NaN")))
122 # Test psfFluxErr NAN case when psfErrFactor is zero and non-zero
123 abConfig.plugins["base_ClassificationExtendedness"].psfErrFactor = 0.
124 self.assertFalse(runFlagTest(psfFluxErr=float("NaN")))
125 abConfig.plugins["base_ClassificationExtendedness"].psfErrFactor = 1.
126 self.assertTrue(runFlagTest(psfFluxErr=float("NaN")))
129class TestMemory(lsst.utils.tests.MemoryTestCase):
130 pass
133def setup_module(module):
134 lsst.utils.tests.init()
137if __name__ == "__main__": 137 ↛ 138line 137 didn't jump to line 138, because the condition on line 137 was never true
138 lsst.utils.tests.init()
139 unittest.main()