Coverage for tests/test_objectSizeStarSelector.py: 18%

96 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-01-13 03:11 -0800

1# This file is part of meas_algorithms. 

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 numpy as np 

24 

25import lsst.afw.table as afwTable 

26from lsst.meas.algorithms import sourceSelector 

27import lsst.meas.base.tests 

28import lsst.utils.tests 

29 

30fluxField = "base_GaussianFlux_instFlux" 

31 

32 

33def addGoodSource(sourceCat, num=0): 

34 """Insert a likely-good source into the catalog. 

35 

36 Parameters 

37 ---------- 

38 sourceCat : `lsst.afw.table.SourceCatalog` 

39 The source catalog for which a "good" source is to be added for testing. 

40 num : `float` or `int` 

41 A number that is added to various values to distinguish them in catalogs with multiple objects. 

42 """ 

43 sourceCat.addNew() 

44 sourceCat["coord_ra"][-1] = 1.0 + num 

45 sourceCat["coord_dec"][-1] = 2.0 + num 

46 # Add some variability to the fluxes to form a cluster with non-finite "width" in the mag-size plane 

47 fluxFactor = np.random.uniform(low=0.98, high=1.02) 

48 sourceCat[fluxField][-1] = 100.0*fluxFactor # We set fluxMin = 50 in setUp 

49 sourceCat[fluxField + "Err"][-1] = 1.0 

50 # Add some variability to the shapes to form a cluster with non-finite "width" in the mag-size plane 

51 widthFactor = np.random.uniform(low=0.98, high=1.02) 

52 sourceCat["truth_xx"][-1] = 3.0*widthFactor 

53 sourceCat["truth_yy"][-1] = 3.0*widthFactor 

54 sourceCat["truth_xy"][-1] = 1.0 

55 

56 

57class TestObjectSizeSourceSelector(lsst.utils.tests.TestCase): 

58 

59 def setUp(self): 

60 np.random.seed(100) 

61 

62 self.sourceSelector = sourceSelector.sourceSelectorRegistry["objectSize"]() 

63 self.badFlags = self.sourceSelector.config.badFlags 

64 schema = lsst.meas.base.tests.TestDataset.makeMinimalSchema() 

65 self.sourceSelector.config.sourceFluxField = fluxField 

66 self.sourceSelector.config.fluxMin = 50.0 

67 schema.addField(fluxField, type=np.float64) 

68 schema.addField(fluxField + "Err", type=np.float64) 

69 for flag in self.badFlags: 

70 schema.addField(flag, type="Flag") 

71 self.sourceCat = afwTable.SourceCatalog(schema) 

72 

73 def tearDown(self): 

74 del self.sourceCat 

75 del self.badFlags 

76 del self.sourceSelector 

77 

78 def testSelectSourcesGood(self): 

79 for i in range(5): 

80 addGoodSource(self.sourceCat, i) 

81 result = self.sourceSelector.selectSources(self.sourceCat) 

82 for src in self.sourceCat["id"]: 

83 self.assertIn(src, self.sourceCat[result.selected]["id"]) 

84 

85 def testSelectSourcesIndividualBadFlags(self): 

86 for i in range(len(self.badFlags)): 

87 addGoodSource(self.sourceCat, i) 

88 for i in range(len(self.badFlags)): 

89 for j, flag in enumerate(self.badFlags): 

90 self.sourceCat[j].set(flag, True) if i == j else self.sourceCat[j].set(flag, False) 

91 result = self.sourceSelector.selectSources(self.sourceCat) 

92 self.assertNotIn(self.sourceCat[i]["id"], self.sourceCat[result.selected]["id"], 

93 "should not have found %s" % flag) 

94 

95 def testSelectSourcesAllBadFlags(self): 

96 for i, flag in enumerate(self.badFlags): 

97 addGoodSource(self.sourceCat, i) 

98 self.sourceCat[i].set(flag, True) 

99 with self.assertRaises(RuntimeError): 

100 self.sourceSelector.selectSources(self.sourceCat) 

101 

102 def testSelectSourcesSignalToNoiseCuts(self): 

103 for i in range(10): 

104 addGoodSource(self.sourceCat, i) 

105 

106 self.sourceCat[fluxField + "Err"][0] = self.sourceCat[fluxField][0]/20.0 

107 self.sourceCat[fluxField + "Err"][1] = self.sourceCat[fluxField][1]/500.0 

108 self.sourceCat[fluxField + "Err"][2] = self.sourceCat[fluxField][2]/2000.0 

109 

110 self.sourceSelector.config.doSignalToNoiseLimit = True 

111 self.sourceSelector.config.doFluxLimit = False 

112 self.sourceSelector.config.signalToNoiseMin = 50 

113 self.sourceSelector.config.signalToNoiseMax = 1000 

114 result = self.sourceSelector.run(self.sourceCat) 

115 self.assertNotIn(self.sourceCat[0]["id"], result.sourceCat["id"]) 

116 self.assertIn(self.sourceCat[1]["id"], result.sourceCat["id"]) 

117 self.assertNotIn(self.sourceCat[2]["id"], result.sourceCat["id"]) 

118 

119 def testSelectSourcesNoSignalToNoiseCut(self): 

120 for i in range(5): 

121 addGoodSource(self.sourceCat, i) 

122 self.sourceCat[fluxField + "Err"][0] = self.sourceCat[fluxField][0]*1e+9 # S/N ~1e-9 

123 self.sourceSelector.config.signalToNoiseMin = 0 

124 result = self.sourceSelector.run(self.sourceCat) 

125 self.assertIn(self.sourceCat[0]["id"], result.sourceCat["id"]) 

126 

127 def testSelectSourcesFluxCuts(self): 

128 for i in range(10): 

129 addGoodSource(self.sourceCat, i) 

130 

131 self.sourceSelector.config.doSignalToNoiseLimit = False 

132 self.sourceSelector.config.doFluxLimit = True 

133 self.sourceSelector.config.fluxMin = 98.0 # Just outside of range allowed in addGoodSource() 

134 self.sourceCat[fluxField][0] = 97.9 

135 self.sourceSelector.config.fluxMax = 101.3 # Just outside of range allowed in addGoodSource() 

136 self.sourceCat[fluxField][2] = 101.4 

137 result = self.sourceSelector.run(self.sourceCat) 

138 self.assertNotIn(self.sourceCat[0]["id"], result.sourceCat["id"]) 

139 self.assertIn(self.sourceCat[1]["id"], result.sourceCat["id"]) 

140 self.assertNotIn(self.sourceCat[2]["id"], result.sourceCat["id"]) 

141 

142 

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

144 pass 

145 

146 

147def setup_module(module): 

148 lsst.utils.tests.init() 

149 

150 

151if __name__ == "__main__": 151 ↛ 152line 151 didn't jump to line 152, because the condition on line 151 was never true

152 lsst.utils.tests.init() 

153 unittest.main()