Coverage for tests/test_astrometrySourceSelector.py: 22%

98 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-27 11:28 +0000

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# 

23 

24import unittest 

25import numpy as np 

26 

27import lsst.afw.table as afwTable 

28from lsst.meas.algorithms import sourceSelector 

29import lsst.meas.base.tests 

30import lsst.utils.tests 

31 

32# badFlags are flags that, if the bad flag is set the object should be 

33# immediately thrown out. This is as opposed to combinations of flags 

34# signifying good or bad data. Such flags should then be a part of the 

35# isGood test. 

36badFlags = ["base_PixelFlags_flag_edge", 

37 "base_PixelFlags_flag_interpolatedCenter", 

38 "base_PixelFlags_flag_saturated", 

39 "base_PixelFlags_flag_saturatedCenter", 

40 "base_PixelFlags_flag_crCenter", 

41 "base_PixelFlags_flag_bad", 

42 "slot_Centroid_flag", 

43 "slot_ApFlux_flag", 

44 ] 

45 

46# goodFlags are flags that should NOT cause the object to be immediately 

47# thrown out, despite their possibly ominous-sounding names. 

48goodFlags = ["base_PixelFlags_flag_interpolated"] 

49 

50 

51def add_good_source(src, num=0): 

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

53 """ 

54 num is added to various values to distinguish them in catalogs with multiple objects. 

55 """ 

56 src.addNew() 

57 src['coord_ra'][-1] = 1. + num 

58 src['coord_dec'][-1] = 2. + num 

59 src['slot_Centroid_x'][-1] = 10. + num 

60 src['slot_Centroid_y'][-1] = 20. + num 

61 src['slot_Centroid_xErr'][-1] = 1. + num 

62 src['slot_Centroid_yErr'][-1] = 2. + num 

63 src['slot_Centroid_x_y_Cov'][-1] = 3. + num 

64 src['slot_ApFlux_instFlux'][-1] = 100. + num 

65 src['slot_ApFlux_instFluxErr'][-1] = 1. 

66 src['detect_isPrimary'] = True 

67 

68 

69class TestAstrometrySourceSelector(lsst.utils.tests.TestCase): 

70 

71 def setUp(self): 

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

73 schema.addField("slot_ApFlux_instFlux", type=np.float64) 

74 schema.addField("slot_ApFlux_instFluxErr", type=np.float64) 

75 schema.addField("detect_isPrimary", type="Flag") 

76 for flag in badFlags + goodFlags: 

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

78 

79 self.src = afwTable.SourceCatalog(schema) 

80 self.sourceSelector = sourceSelector.sourceSelectorRegistry['astrometry']() 

81 

82 def tearDown(self): 

83 del self.src 

84 del self.sourceSelector 

85 

86 def testSelectSources_good(self): 

87 for i in range(5): 

88 add_good_source(self.src, i) 

89 for flag in goodFlags: 

90 self.src[i].set(flag, True) 

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

92 # TODO: assertEqual doesn't work correctly on source catalogs. 

93 # self.assertEqual(self.src[result.selected], self.src) 

94 for x in self.src['id']: 

95 self.assertIn(x, self.src[result.selected]['id']) 

96 

97 def testSelectSources_bad(self): 

98 for i, flag in enumerate(badFlags): 

99 add_good_source(self.src, i) 

100 self.src[i].set(flag, True) 

101 result = self.sourceSelector.selectSources(self.src) 

102 for i, x in enumerate(self.src['id']): 

103 self.assertNotIn(x, self.src[result.selected]['id'], "should not have found %s" % badFlags[i]) 

104 

105 def testSelectSources_bad_centroid(self): 

106 """NaN centroids should just assert.""" 

107 add_good_source(self.src, 1) 

108 self.src[0].set('slot_Centroid_x', np.nan) 

109 with self.assertRaises(AssertionError): 

110 self.sourceSelector.selectSources(self.src) 

111 self.src[0].set('slot_Centroid_x', 5.0) 

112 self.src[0].set('slot_Centroid_y', np.nan) 

113 with self.assertRaises(AssertionError): 

114 self.sourceSelector.selectSources(self.src) 

115 

116 def testSelectSources_bad_centroid_Sigma(self): 

117 """Reject sources with NaN centroid_[xy]Sigma. 

118 Currently, there is no guarantee that a valid centroid_flag implies 

119 a finite variance.""" 

120 add_good_source(self.src, 1) 

121 add_good_source(self.src, 2) 

122 self.src[0].set('slot_Centroid_xErr', np.nan) 

123 self.src[1].set('slot_Centroid_yErr', np.nan) 

124 result = self.sourceSelector.selectSources(self.src) 

125 self.assertNotIn(self.src['id'][0], self.src[result.selected]['id']) 

126 self.assertNotIn(self.src['id'][1], self.src[result.selected]['id']) 

127 

128 def testSelectSources_is_parent(self): 

129 add_good_source(self.src, 1) 

130 self.src[0].set('parent', 1) 

131 result = self.sourceSelector.selectSources(self.src) 

132 self.assertNotIn(self.src['id'][0], self.src[result.selected]['id']) 

133 

134 def testSelectSources_has_children(self): 

135 add_good_source(self.src, 1) 

136 self.src[0].set('deblend_nChild', 1) 

137 result = self.sourceSelector.selectSources(self.src) 

138 self.assertNotIn(self.src['id'][0], self.src[result.selected]['id']) 

139 

140 def testSelectSources_highSN_cut(self): 

141 add_good_source(self.src, 1) 

142 add_good_source(self.src, 2) 

143 self.src['slot_ApFlux_instFlux'][0] = 20. 

144 self.src['slot_ApFlux_instFlux'][1] = 1000. 

145 

146 self.sourceSelector.config.minSnr = 100 

147 result = self.sourceSelector.selectSources(self.src) 

148 self.assertNotIn(self.src[0]['id'], self.src[result.selected]['id']) 

149 self.assertIn(self.src[1]['id'], self.src[result.selected]['id']) 

150 

151 def testSelectSources_no_SN_cut(self): 

152 self.sourceSelector.config.minSnr = 0 

153 add_good_source(self.src, 1) 

154 self.src['slot_ApFlux_instFlux'][0] = 0 

155 result = self.sourceSelector.selectSources(self.src) 

156 self.assertIn(self.src[0]['id'], self.src[result.selected]['id']) 

157 

158 

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

160 pass 

161 

162 

163def setup_module(module): 

164 lsst.utils.tests.init() 

165 

166 

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

168 lsst.utils.tests.init() 

169 unittest.main()