Coverage for tests/test_filterDiaSourceCatalog.py: 19%

85 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-10 10:38 +0000

1# This file is part of ap_association. 

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 

23 

24from lsst.ap.association.filterDiaSourceCatalog import (FilterDiaSourceCatalogConfig, 

25 FilterDiaSourceCatalogTask) 

26import lsst.geom as geom 

27import lsst.meas.base.tests as measTests 

28import lsst.utils.tests 

29import lsst.afw.image as afwImage 

30import lsst.daf.base as dafBase 

31 

32 

33class TestFilterDiaSourceCatalogTask(unittest.TestCase): 

34 

35 def setUp(self): 

36 self.nSources = 15 

37 self.nSkySources = 5 

38 self.yLoc = 100 

39 self.expId = 4321 

40 self.bbox = geom.Box2I(geom.Point2I(0, 0), 

41 geom.Extent2I(1024, 1153)) 

42 dataset = measTests.TestDataset(self.bbox) 

43 for srcIdx in range(self.nSources): 

44 dataset.addSource(10000.0, geom.Point2D(srcIdx, self.yLoc)) 

45 schema = dataset.makeMinimalSchema() 

46 schema.addField("sky_source", type="Flag", doc="Sky objects.") 

47 schema.addField('ext_trailedSources_Naive_flag_off_image', type="Flag", 

48 doc="Trail extends off image") 

49 schema.addField('ext_trailedSources_Naive_flag_suspect_long_trail', 

50 type="Flag", doc="Trail length is greater than three times the psf radius") 

51 schema.addField('ext_trailedSources_Naive_flag_edge', type="Flag", 

52 doc="Trail contains edge pixels") 

53 schema.addField('ext_trailedSources_Naive_flag_nan', type="Flag", 

54 doc="One or more trail coordinates are missing") 

55 schema.addField('ext_trailedSources_Naive_length', type="F", 

56 doc="Length of the source trail") 

57 _, self.diaSourceCat = dataset.realize(10.0, schema, randomSeed=1234) 

58 self.diaSourceCat[0:self.nSkySources]["sky_source"] = True 

59 # The last 10 sources will all contained trail length measurements, 

60 # increasing in size by 1.5 arcseconds. Only the last three will have 

61 # lengths which are too long and will be filtered out. 

62 self.nFilteredTrailedSources = 0 

63 for srcIdx in range(5, 15): 

64 self.diaSourceCat[srcIdx]["ext_trailedSources_Naive_length"] = 1.5*(srcIdx-4) 

65 if 1.5*(srcIdx-4) > 36000/3600.0/24.0 * 30.0: 

66 self.nFilteredTrailedSources += 1 

67 # Setting a combination of flags for filtering in tests 

68 self.diaSourceCat[5]["ext_trailedSources_Naive_flag_off_image"] = True 

69 self.diaSourceCat[6]["ext_trailedSources_Naive_flag_suspect_long_trail"] = True 

70 self.diaSourceCat[6]["ext_trailedSources_Naive_flag_edge"] = True 

71 # As only two of these flags are set, the total number of filtered 

72 # sources will be self.nFilteredTrailedSources + 2 

73 self.nFilteredTrailedSources += 2 

74 self.config = FilterDiaSourceCatalogConfig() 

75 mjd = 57071.0 

76 self.utc_jd = mjd + 2_400_000.5 - 35.0 / (24.0 * 60.0 * 60.0) 

77 

78 self.visitInfo = afwImage.VisitInfo( 

79 # This incomplete visitInfo is sufficient for testing because the 

80 # Python constructor sets all other required values to some 

81 # default. 

82 exposureTime=30.0, 

83 darkTime=3.0, 

84 date=dafBase.DateTime(mjd, system=dafBase.DateTime.MJD), 

85 boresightRaDec=geom.SpherePoint(0.0, 0.0, geom.degrees), 

86 ) 

87 

88 def test_run_without_filter(self): 

89 """Test that when all filters are turned off all sources in the catalog 

90 are returned. 

91 """ 

92 self.config.doRemoveSkySources = False 

93 self.config.doWriteRejectedSkySources = False 

94 self.config.doTrailedSourceFilter = False 

95 filterDiaSourceCatalogTask = FilterDiaSourceCatalogTask(config=self.config) 

96 result = filterDiaSourceCatalogTask.run(self.diaSourceCat, self.visitInfo) 

97 self.assertEqual(len(result.filteredDiaSourceCat), len(self.diaSourceCat)) 

98 self.assertEqual(len(result.rejectedDiaSources), 0) 

99 self.assertEqual(len(self.diaSourceCat), self.nSources) 

100 

101 def test_run_with_filter_sky_only(self): 

102 """Test that when only the sky filter is turned on the first five 

103 sources which are flagged as sky objects are filtered out of the 

104 catalog and the rest are returned. 

105 """ 

106 self.config.doRemoveSkySources = True 

107 self.config.doWriteRejectedSkySources = True 

108 self.config.doTrailedSourceFilter = False 

109 filterDiaSourceCatalogTask = FilterDiaSourceCatalogTask(config=self.config) 

110 result = filterDiaSourceCatalogTask.run(self.diaSourceCat, self.visitInfo) 

111 nExpectedFilteredSources = self.nSources - self.nSkySources 

112 self.assertEqual(len(result.filteredDiaSourceCat), 

113 len(self.diaSourceCat[~self.diaSourceCat['sky_source']])) 

114 self.assertEqual(len(result.filteredDiaSourceCat), nExpectedFilteredSources) 

115 self.assertEqual(len(result.rejectedDiaSources), self.nSkySources) 

116 self.assertEqual(len(self.diaSourceCat), self.nSources) 

117 

118 def test_run_with_filter_trailed_sources_only(self): 

119 """Test that when only the trail filter is turned on the correct number 

120 of sources are filtered out. The filtered sources should be the last 

121 three sources which have long trails, one source where both the suspect 

122 trail and edge trail flag are set, and one source where off_image is 

123 set. All sky objects should remain in the catalog. 

124 """ 

125 self.config.doRemoveSkySources = False 

126 self.config.doWriteRejectedSkySources = False 

127 self.config.doTrailedSourceFilter = True 

128 filterDiaSourceCatalogTask = FilterDiaSourceCatalogTask(config=self.config) 

129 result = filterDiaSourceCatalogTask.run(self.diaSourceCat, self.visitInfo) 

130 nExpectedFilteredSources = self.nSources - self.nFilteredTrailedSources 

131 self.assertEqual(len(result.filteredDiaSourceCat), nExpectedFilteredSources) 

132 self.assertEqual(len(self.diaSourceCat), self.nSources) 

133 

134 def test_run_with_all_filters(self): 

135 """Test that all sources are filtered out correctly. Only six sources 

136 should remain in the catalog after filtering. 

137 """ 

138 self.config.doRemoveSkySources = True 

139 self.config.doWriteRejectedSkySources = True 

140 self.config.doTrailedSourceFilter = True 

141 filterDiaSourceCatalogTask = FilterDiaSourceCatalogTask(config=self.config) 

142 result = filterDiaSourceCatalogTask.run(self.diaSourceCat, self.visitInfo) 

143 nExpectedFilteredSources = self.nSources - self.nSkySources - self.nFilteredTrailedSources 

144 # 5 filtered out sky sources 

145 # 4 filtered out trailed sources, 2 with long trails 2 with flags 

146 # 6 sources left 

147 self.assertEqual(len(result.filteredDiaSourceCat), nExpectedFilteredSources) 

148 self.assertEqual(len(result.rejectedDiaSources), self.nSkySources) 

149 self.assertEqual(len(self.diaSourceCat), self.nSources) 

150 

151 

152class MemoryTester(lsst.utils.tests.MemoryTestCase): 

153 pass 

154 

155 

156def setup_module(module): 

157 lsst.utils.tests.init() 

158 

159 

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

161 lsst.utils.tests.init() 

162 unittest.main()