Coverage for tests/test_tasks.py: 22%

113 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-10-05 11:52 +0000

1# This file is part of faro. 

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 os 

23import unittest 

24import astropy.units as u 

25 

26import lsst.afw.geom as afwGeom 

27import lsst.afw.image as afwImage 

28import lsst.geom as geom 

29 

30from lsst.afw.table import SimpleCatalog 

31 

32from lsst.faro.base import CatalogMeasurementBaseConfig, CatalogMeasurementBaseTask, NumSourcesMergeTask 

33from lsst.faro.measurement import (VisitTableMeasurementConfig, VisitTableMeasurementTask, 

34 DetectorTableMeasurementConfig, DetectorTableMeasurementTask, 

35 VisitMeasurementConfig, VisitMeasurementTask, 

36 DetectorMeasurementConfig, DetectorMeasurementTask, 

37 TractMeasurementConfig, TractMeasurementTask, 

38 TractTableValueMeasurementConfig, TractTableValueMeasurementTask, 

39 ) 

40 

41TESTDIR = os.path.abspath(os.path.dirname(__file__)) 

42DATADIR = os.path.join(TESTDIR, 'data') 

43 

44 

45class TaskTest(unittest.TestCase): 

46 

47 def load_data(self, key): 

48 cat_file = self.file_map[key] 

49 catalog = SimpleCatalog.readFits(os.path.join(DATADIR, cat_file)) 

50 return catalog 

51 

52 def setUp(self): 

53 """This is called immediately before calling each test method.""" 

54 self.file_map = {'CatalogMeasurementBaseTask': 

55 'src_HSC_i_HSC-I_903986_0_31_HSC_runs_ci_hsc_20210407T021858Z.fits'} 

56 # Make a mock wcs 

57 self.mockWcs = afwGeom.makeSkyWcs( 

58 crpix=geom.Point2D(1, 1), 

59 crval=geom.SpherePoint(0.0*geom.degrees, 90.0*geom.degrees), 

60 cdMatrix=afwGeom.makeCdMatrix(scale=0.5*geom.arcseconds) 

61 ) 

62 # Make a mock photoCalib 

63 self.mockPhotoCalib = afwImage.PhotoCalib() 

64 

65 def testCatalogMeasurementBaseTask(self): 

66 """Test run method of CatalogMeasurementBaseTask.""" 

67 catalog = self.load_data('CatalogMeasurementBaseTask') 

68 config = CatalogMeasurementBaseConfig() 

69 t = CatalogMeasurementBaseTask(config) 

70 outputs = t.run(catalog=catalog) 

71 expected = 771 * u.count 

72 self.assertEqual(outputs.measurement.quantity, expected) 

73 

74 def testVisitTableMeasurementTask(self): 

75 """Test run method of VisitTableMeasurementTask.""" 

76 catalog = self.load_data('CatalogMeasurementBaseTask') 

77 config = VisitTableMeasurementConfig() 

78 t = VisitTableMeasurementTask(config) 

79 outputs = t.run(catalog=catalog) 

80 expected = 771 * u.count 

81 self.assertEqual(outputs.measurement.quantity, expected) 

82 

83 def testDetectorTableMeasurementTask(self): 

84 """Test run method of VisitTableMeasurementTask.""" 

85 catalog = self.load_data('CatalogMeasurementBaseTask') 

86 config = DetectorTableMeasurementConfig() 

87 # For this test, we don't care that this is not a real detector column. 

88 config.measure.columns = {"detector": "id"} 

89 t = DetectorTableMeasurementTask(config) 

90 outputs = t.run(catalog=catalog) 

91 expected = 771 * u.count 

92 self.assertEqual(outputs.measurement.quantity, expected) 

93 

94 def testTractMeasurementTaskNoCalibs(self): 

95 """Test run method of TractMeasurementTask with calibs as None.""" 

96 catalog = self.load_data('CatalogMeasurementBaseTask') 

97 config = TractMeasurementConfig() 

98 config.measure.retarget(NumSourcesMergeTask) 

99 config.requireAstrometry = False # We are passing in None, so can't require 

100 config.requirePhotometry = False # We are passing in None, so can't require 

101 t = TractMeasurementTask(config) 

102 outputs = t.run( 

103 catalogs=[catalog, ], 

104 photoCalibs=[None, ], 

105 astromCalibs=[None, ], 

106 dataIds=[{'band': 'r'}, ], 

107 ) 

108 expected = 771 * u.count 

109 self.assertEqual(outputs.measurement.quantity, expected) 

110 

111 def testTractTableValueMeasurementTask(self): 

112 table = self.load_data('CatalogMeasurementBaseTask').asAstropy().to_pandas() 

113 config = TractTableValueMeasurementConfig( 

114 band_order=[''], 

115 format_column='{band}{column}', 

116 prefixes_column=[''], 

117 row=0, 

118 ) 

119 config.action.column = 'parent' 

120 t = TractTableValueMeasurementTask(config=config) 

121 outputs = t.run(table=table, bands=[''], name_metric='parent') 

122 expected = 0 * u.Unit('') 

123 self.assertEqual(outputs.measurement[0].quantity, expected) 

124 

125 def testTractMeasurementTask(self): 

126 """Test run method of TractMeasurementTask with mixed calib as None.""" 

127 catalog = self.load_data('CatalogMeasurementBaseTask') 

128 config = TractMeasurementConfig() 

129 config.measure.retarget(NumSourcesMergeTask) 

130 t = TractMeasurementTask(config) 

131 

132 # Add four input catalogs, only one of which should get added because 

133 # we have left requireAstrometry and requirePhotometry as True. 

134 outputs = t.run( 

135 catalogs=[catalog]*4, 

136 photoCalibs=[None, self.mockPhotoCalib, None, self.mockPhotoCalib], 

137 astromCalibs=[None, self.mockWcs, self.mockWcs, None], 

138 dataIds=[{'band': 'r'}]*4, 

139 ) 

140 expected = 771 * u.count 

141 self.assertEqual(outputs.measurement.quantity, expected) 

142 

143 # Add four input catalogs, only two of which should get added because 

144 # we have set requireAstrometry to False but left requirePhotometry 

145 # as True. 

146 config.requireAstrometry = False 

147 outputs = t.run( 

148 catalogs=[catalog]*4, 

149 photoCalibs=[None, self.mockPhotoCalib, None, self.mockPhotoCalib], 

150 astromCalibs=[None, self.mockWcs, self.mockWcs, None], 

151 dataIds=[{'band': 'r'}]*4, 

152 ) 

153 expected = 2*771 * u.count 

154 self.assertEqual(outputs.measurement.quantity, expected) 

155 

156 # Add four input catalogs, only two of which should get added because 

157 # we have set requirePhotometry to False but left requireAstrometry 

158 # as True. 

159 config.requireAstrometry = True 

160 config.requirePhotometry = False 

161 outputs = t.run( 

162 catalogs=[catalog]*4, 

163 photoCalibs=[None, self.mockPhotoCalib, None, self.mockPhotoCalib], 

164 astromCalibs=[None, self.mockWcs, self.mockWcs, None], 

165 dataIds=[{'band': 'r'}]*4, 

166 ) 

167 expected = 2*771 * u.count 

168 self.assertEqual(outputs.measurement.quantity, expected) 

169 

170 def testVisitMeasurementTaskNoCalibs(self): 

171 """Test run method of VisitMeasurementTask with calibs as None.""" 

172 catalog = self.load_data('CatalogMeasurementBaseTask') 

173 config = VisitMeasurementConfig() 

174 config.measure.retarget(NumSourcesMergeTask) 

175 config.requireAstrometry = False # We are passing in None, so can't require 

176 config.requirePhotometry = False # We are passing in None, so can't require 

177 t = VisitMeasurementTask(config) 

178 outputs = t.run( 

179 catalogs=[catalog, ], 

180 photoCalibs=[None, ], 

181 astromCalibs=[None, ], 

182 dataIds=[{'band': 'r'}, ], 

183 ) 

184 expected = 771 * u.count 

185 self.assertEqual(outputs.measurement.quantity, expected) 

186 

187 def testVisitMeasurementTask(self): 

188 """Test run method of VisitMeasurementTask with mixed calib as None.""" 

189 catalog = self.load_data('CatalogMeasurementBaseTask') 

190 config = VisitMeasurementConfig() 

191 config.measure.retarget(NumSourcesMergeTask) 

192 t = VisitMeasurementTask(config) 

193 

194 # Add four input catalogs, only one of which should get added because 

195 # we have left requireAstrometry and requirePhotometry as True. 

196 outputs = t.run( 

197 catalogs=[catalog]*4, 

198 photoCalibs=[None, self.mockPhotoCalib, None, self.mockPhotoCalib], 

199 astromCalibs=[None, self.mockWcs, self.mockWcs, None], 

200 dataIds=[{'band': 'r'}]*4, 

201 ) 

202 expected = 771 * u.count 

203 self.assertEqual(outputs.measurement.quantity, expected) 

204 

205 # Add four input catalogs, only two of which should get added because 

206 # we have set requireAstrometry to False but left requirePhotometry 

207 # as True. 

208 config.requireAstrometry = False 

209 outputs = t.run( 

210 catalogs=[catalog]*4, 

211 photoCalibs=[None, self.mockPhotoCalib, None, self.mockPhotoCalib], 

212 astromCalibs=[None, self.mockWcs, self.mockWcs, None], 

213 dataIds=[{'band': 'r'}]*4, 

214 ) 

215 expected = 2*771 * u.count 

216 self.assertEqual(outputs.measurement.quantity, expected) 

217 

218 # Add four input catalogs, only two of which should get added because 

219 # we have set requirePhotometry to False but left requireAstrometry 

220 # as True. 

221 config.requireAstrometry = True 

222 config.requirePhotometry = False 

223 outputs = t.run( 

224 catalogs=[catalog]*4, 

225 photoCalibs=[None, self.mockPhotoCalib, None, self.mockPhotoCalib], 

226 astromCalibs=[None, self.mockWcs, self.mockWcs, None], 

227 dataIds=[{'band': 'r'}]*4, 

228 ) 

229 expected = 2*771 * u.count 

230 self.assertEqual(outputs.measurement.quantity, expected) 

231 

232 def testDetectorMeasurementTask(self): 

233 """Test run method of DetectorMeasurementTask.""" 

234 catalog = self.load_data('CatalogMeasurementBaseTask') 

235 config = DetectorMeasurementConfig() 

236 t = DetectorMeasurementTask(config) 

237 outputs = t.run(catalog=catalog) 

238 expected = 771 * u.count 

239 self.assertEqual(outputs.measurement.quantity, expected) 

240 

241 

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

243 unittest.main()