Coverage for tests/test_Classification.py: 25%

68 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-02 02:26 -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/>. 

21 

22import unittest 

23import warnings 

24 

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 

31 

32 

33class ClassificationTestCase(lsst.meas.base.tests.AlgorithmTestCase, lsst.utils.tests.TestCase): 

34 

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)) 

44 

45 def tearDown(self): 

46 del self.bbox 

47 del self.dataset 

48 

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) 

63 

64 def testFlags(self): 

65 """Test for success and check all failure modes. 

66 

67 Test all the failure modes of this algorithm, as well as checking that 

68 it succeeds when it should. 

69 

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``. 

75 

76 When ``psfFluxFactor != 0``, the ``PsfFluxErr`` cannot be NaN, but 

77 otherwise is ignored. 

78 

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" 

85 

86 abConfig = catCalc.CatalogCalculationConfig() 

87 

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") 

103 

104 # Test no error case - all necessary values are set 

105 self.assertFalse(runFlagTest()) 

106 

107 # Test psfFlux flag case - failure in PsfFlux 

108 self.assertTrue(runFlagTest(psfFluxFlag=True)) 

109 

110 # Test modelFlux flag case - failure in ModelFlux 

111 self.assertTrue(runFlagTest(modelFluxFlag=True)) 

112 

113 # Test modelFlux NAN case 

114 self.assertTrue(runFlagTest(modelFlux=float("NaN"), modelFluxFlag=True)) 

115 

116 # Test psfFlux NAN case 

117 self.assertTrue(runFlagTest(psfFlux=float("NaN"), psfFluxFlag=True)) 

118 

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"))) 

124 

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"))) 

130 

131 

132class TestMemory(lsst.utils.tests.MemoryTestCase): 

133 pass 

134 

135 

136def setup_module(module): 

137 lsst.utils.tests.init() 

138 

139 

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()