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
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
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#
24import itertools
25import unittest
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
35class TrivialLoader(ReferenceObjectLoaderBase):
36 """Minimal subclass of ReferenceObjectLoaderBase to allow instantiation
37 """
39 def loadSkyCircle(self, ctrCoord, radius, filterName):
40 pass
43class TestReferenceObjectLoaderBase(lsst.utils.tests.TestCase):
44 """Test case for ReferenceObjectLoaderBase abstract base class.
46 Only methods with concrete implementations are tested (hence not loadSkyCircle)
47 """
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.")
58 # anyFilterMapsToThis and filterMap are mutually exclusive
59 config.anyFilterMapsToThis = "c"
60 with self.assertRaises(lsst.pex.config.FieldValidationError):
61 config.validate()
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.")
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)
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)
134 self.assertIn("r_flux", refSchema)
135 self.assertIn("r_fluxErr", refSchema)
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")
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")
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)
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))
189 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z'])
190 schema.addField('bad_flux', doc='old flux units', type=float, units='')
191 self.assertFalse(hasNanojanskyFluxUnits(schema))
193 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z'])
194 schema.addField('bad_flux', doc='old flux units', type=float, units='Jy')
195 self.assertFalse(hasNanojanskyFluxUnits(schema))
197 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z'])
198 schema.addField('bad_fluxErr', doc='old flux units', type=float, units='')
199 self.assertFalse(hasNanojanskyFluxUnits(schema))
201 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z'])
202 schema.addField('bad_fluxErr', doc='old flux units', type=float, units='Jy')
203 self.assertFalse(hasNanojanskyFluxUnits(schema))
205 schema = ReferenceObjectLoaderBase.makeMinimalSchema(['r', 'z'])
206 schema.addField('bad_fluxSigma', doc='old flux units', type=float, units='')
207 self.assertFalse(hasNanojanskyFluxUnits(schema))
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()
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
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')
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)
238class TestMemory(lsst.utils.tests.MemoryTestCase):
239 pass
242def setup_module(module):
243 lsst.utils.tests.init()
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()