Coverage for tests/test_loadReferenceObjects.py: 16%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

150 statements  

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 itertools 

25import unittest 

26 

27import lsst.afw.table as afwTable 

28import lsst.log 

29from lsst.meas.algorithms import ReferenceObjectLoaderBase, getRefFluxField, getRefFluxKeys 

30from lsst.meas.algorithms.loadReferenceObjects import hasNanojanskyFluxUnits, convertToNanojansky 

31import lsst.pex.config 

32import lsst.utils.tests 

33 

34 

35class TrivialLoader(ReferenceObjectLoaderBase): 

36 """Minimal subclass of ReferenceObjectLoaderBase to allow instantiation 

37 """ 

38 

39 def loadSkyCircle(self, ctrCoord, radius, filterName): 

40 pass 

41 

42 

43class TestReferenceObjectLoaderBase(lsst.utils.tests.TestCase): 

44 """Test case for ReferenceObjectLoaderBase abstract base class. 

45 

46 Only methods with concrete implementations are tested (hence not loadSkyCircle) 

47 """ 

48 

49 def testFilterMapVsAnyFilterMapsToThis(self): 

50 config = TrivialLoader.ConfigClass() 

51 # check that a filterMap-only config passes validation 

52 config.filterMap = {"b": "a"} 

53 try: 

54 config.validate() 

55 except lsst.pex.config.FieldValidationError: 

56 self.fail("`filterMap`-only LoadReferenceObjectsConfig should not fail validation.") 

57 

58 # anyFilterMapsToThis and filterMap are mutually exclusive 

59 config.anyFilterMapsToThis = "c" 

60 with self.assertRaises(lsst.pex.config.FieldValidationError): 

61 config.validate() 

62 

63 # check that a anyFilterMapsToThis-only config passes validation 

64 config.filterMap = {} 

65 try: 

66 config.validate() 

67 except lsst.pex.config.FieldValidationError: 

68 self.fail("`anyFilterMapsToThis`-only LoadReferenceObjectsConfig should not fail validation.") 

69 

70 def testMakeMinimalSchema(self): 

71 """Make a schema and check it.""" 

72 for filterNameList in (["r"], ["foo", "_bar"]): 

73 for (addIsPhotometric, addIsResolved, addIsVariable, 

74 coordErrDim, addProperMotion, properMotionErrDim, 

75 addParallax) in itertools.product( 

76 (False, True), (False, True), (False, True), 

77 (-1, 0, 1, 2, 3, 4), (False, True), (-1, 0, 1, 2, 3, 4), 

78 (False, True)): 

79 argDict = dict( 

80 filterNameList=filterNameList, 

81 addIsPhotometric=addIsPhotometric, 

82 addIsResolved=addIsResolved, 

83 addIsVariable=addIsVariable, 

84 coordErrDim=coordErrDim, 

85 addProperMotion=addProperMotion, 

86 properMotionErrDim=properMotionErrDim, 

87 addParallax=addParallax, 

88 ) 

89 if coordErrDim not in (0, 2, 3) or \ 

90 (addProperMotion and properMotionErrDim not in (0, 2, 3)): 

91 with self.assertRaises(ValueError): 

92 ReferenceObjectLoaderBase.makeMinimalSchema(**argDict) 

93 else: 

94 refSchema = ReferenceObjectLoaderBase.makeMinimalSchema(**argDict) 

95 self.assertTrue("coord_ra" in refSchema) 

96 self.assertTrue("coord_dec" in refSchema) 

97 for filterName in filterNameList: 

98 fluxField = filterName + "_flux" 

99 self.assertIn(fluxField, refSchema) 

100 self.assertNotIn("x" + fluxField, refSchema) 

101 fluxErrField = fluxField + "Err" 

102 self.assertIn(fluxErrField, refSchema) 

103 self.assertEqual(getRefFluxField(refSchema, filterName), filterName + "_flux") 

104 self.assertEqual("resolved" in refSchema, addIsResolved) 

105 self.assertEqual("variable" in refSchema, addIsVariable) 

106 self.assertEqual("photometric" in refSchema, addIsPhotometric) 

107 self.assertEqual("photometric" in refSchema, addIsPhotometric) 

108 self.assertEqual("epoch" in refSchema, addProperMotion or addParallax) 

109 self.assertEqual("coord_raErr" in refSchema, coordErrDim > 0) 

110 self.assertEqual("coord_decErr" in refSchema, coordErrDim > 0) 

111 self.assertEqual("coord_ra_dec_Cov" in refSchema, coordErrDim == 3) 

112 self.assertEqual("pm_ra" in refSchema, addProperMotion) 

113 self.assertEqual("pm_dec" in refSchema, addProperMotion) 

114 self.assertEqual("pm_raErr" in refSchema, addProperMotion and properMotionErrDim > 0) 

115 self.assertEqual("pm_decErr" in refSchema, addProperMotion and properMotionErrDim > 0) 

116 self.assertEqual("pm_flag" in refSchema, addProperMotion) 

117 self.assertEqual("pm_ra_dec_Cov" in refSchema, 

118 addProperMotion and properMotionErrDim == 3) 

119 self.assertEqual("parallax" in refSchema, addParallax) 

120 self.assertEqual("parallaxErr" in refSchema, addParallax) 

121 self.assertEqual("parallax_flag" in refSchema, addParallax) 

122 

123 def testFilterAliasMap(self): 

124 """Make a schema with filter aliases.""" 

125 for filterMap in ({}, {"camr": "r"}): 

126 config = TrivialLoader.ConfigClass() 

127 config.filterMap = filterMap 

128 loader = TrivialLoader(config=config) 

129 refSchema = TrivialLoader.makeMinimalSchema(filterNameList="r") 

130 loader._addFluxAliases(refSchema, 

131 anyFilterMapsToThis=config.anyFilterMapsToThis, 

132 filterMap=config.filterMap) 

133 

134 self.assertIn("r_flux", refSchema) 

135 self.assertIn("r_fluxErr", refSchema) 

136 

137 # camera filters aliases are named <filter>_camFlux 

138 if "camr" in filterMap: 

139 self.assertEqual(getRefFluxField(refSchema, "camr"), "camr_camFlux") 

140 else: 

141 with self.assertRaisesRegex(RuntimeError, 

142 r"Could not find flux field\(s\) camr_camFlux, camr_flux"): 

143 getRefFluxField(refSchema, "camr") 

144 

145 refCat = afwTable.SimpleCatalog(refSchema) 

146 refObj = refCat.addNew() 

147 refObj["r_flux"] = 1.23 

148 self.assertAlmostEqual(refCat[0].get(getRefFluxField(refSchema, "r")), 1.23) 

149 if "camr" in filterMap: 

150 self.assertAlmostEqual(refCat[0].get(getRefFluxField(refSchema, "camr")), 1.23) 

151 refObj["r_fluxErr"] = 0.111 

152 if "camr" in filterMap: 

153 self.assertEqual(refCat[0].get("camr_camFluxErr"), 0.111) 

154 fluxKey, fluxErrKey = getRefFluxKeys(refSchema, "r") 

155 self.assertEqual(refCat[0].get(fluxKey), 1.23) 

156 self.assertEqual(refCat[0].get(fluxErrKey), 0.111) 

157 if "camr" in filterMap: 

158 fluxKey, fluxErrKey = getRefFluxKeys(refSchema, "camr") 

159 self.assertEqual(refCat[0].get(fluxErrKey), 0.111) 

160 else: 

161 with self.assertRaises(RuntimeError): 

162 getRefFluxKeys(refSchema, "camr") 

163 

164 def testAnyFilterMapsToThisAlias(self): 

165 # test anyFilterMapsToThis 

166 config = TrivialLoader.ConfigClass() 

167 config.anyFilterMapsToThis = "gg" 

168 loader = TrivialLoader(config=config) 

169 refSchema = TrivialLoader.makeMinimalSchema(filterNameList=["gg"]) 

170 loader._addFluxAliases(refSchema, 

171 anyFilterMapsToThis=config.anyFilterMapsToThis, 

172 filterMap=config.filterMap) 

173 self.assertEqual(getRefFluxField(refSchema, "r"), "gg_flux") 

174 # raise if "gg" is not in the refcat filter list 

175 with self.assertRaises(RuntimeError): 

176 refSchema = TrivialLoader.makeMinimalSchema(filterNameList=["rr"]) 

177 refSchema = loader._addFluxAliases(refSchema, 

178 anyFilterMapsToThis=config.anyFilterMapsToThis, 

179 filterMap=config.filterMap) 

180 

181 def testCheckFluxUnits(self): 

182 """Test that we can identify old style fluxes in a schema.""" 

183 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

184 # the default schema should pass 

185 self.assertTrue(hasNanojanskyFluxUnits(schema)) 

186 schema.addField('bad_fluxSigma', doc='old flux units', type=float, units='') 

187 self.assertFalse(hasNanojanskyFluxUnits(schema)) 

188 

189 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

190 schema.addField('bad_flux', doc='old flux units', type=float, units='') 

191 self.assertFalse(hasNanojanskyFluxUnits(schema)) 

192 

193 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

194 schema.addField('bad_flux', doc='old flux units', type=float, units='Jy') 

195 self.assertFalse(hasNanojanskyFluxUnits(schema)) 

196 

197 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

198 schema.addField('bad_fluxErr', doc='old flux units', type=float, units='') 

199 self.assertFalse(hasNanojanskyFluxUnits(schema)) 

200 

201 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

202 schema.addField('bad_fluxErr', doc='old flux units', type=float, units='Jy') 

203 self.assertFalse(hasNanojanskyFluxUnits(schema)) 

204 

205 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

206 schema.addField('bad_fluxSigma', doc='old flux units', type=float, units='') 

207 self.assertFalse(hasNanojanskyFluxUnits(schema)) 

208 

209 def testConvertOldFluxes(self): 

210 """Check that we can convert old style fluxes in a catalog.""" 

211 flux = 1.234 

212 fluxErr = 5.678 

213 log = lsst.log.Log() 

214 

215 def make_catalog(): 

216 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z']) 

217 schema.addField('bad_flux', doc='old flux units', type=float, units='') 

218 schema.addField('bad_fluxErr', doc='old flux units', type=float, units='Jy') 

219 refCat = afwTable.SimpleCatalog(schema) 

220 refObj = refCat.addNew() 

221 refObj["bad_flux"] = flux 

222 refObj["bad_fluxErr"] = fluxErr 

223 return refCat 

224 

225 oldRefCat = make_catalog() 

226 newRefCat = convertToNanojansky(oldRefCat, log) 

227 self.assertEqual(newRefCat['bad_flux'], [flux*1e9, ]) 

228 self.assertEqual(newRefCat['bad_fluxErr'], [fluxErr*1e9, ]) 

229 self.assertEqual(newRefCat.schema['bad_flux'].asField().getUnits(), 'nJy') 

230 self.assertEqual(newRefCat.schema['bad_fluxErr'].asField().getUnits(), 'nJy') 

231 

232 # check that doConvert=False returns None (it also logs a summary) 

233 oldRefCat = make_catalog() 

234 newRefCat = convertToNanojansky(oldRefCat, log, doConvert=False) 

235 self.assertIsNone(newRefCat) 

236 

237 

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

239 pass 

240 

241 

242def setup_module(module): 

243 lsst.utils.tests.init() 

244 

245 

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

247 lsst.utils.tests.init() 

248 unittest.main()