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