Hide keyboard shortcuts

Hot-keys 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

1import numpy as np 

2import pandas as pd 

3import unittest 

4import lsst.sims.maf.metrics as metrics 

5 

6 

7class TestMoMetrics1(unittest.TestCase): 

8 

9 def setUp(self): 

10 # Set up some ssoObs data to test the metrics on. 

11 # Note that ssoObs is a numpy recarray. 

12 # The expected set of columns in ssoObs is: 

13 # cols = ['observationStartMJD', 'night', 'fieldRA', 'fieldDec', 'rotSkyPos', 'filter', 

14 # 'visitExposureTime', 'seeingFwhmGeom', 'fiveSigmaDepth', 'solarElong', 

15 # 'delta', 'ra', 'dec', 'magV', 'time', 'dradt', 'ddecdt', 'phase', 'solarelon', 

16 # 'velocity', 'magFilter', 'dmagColor', 'dmagTrail', 'dmagDetect'] 

17 # And stackers will often add 

18 # addCols = ['appMag', 'magLimit', 'snr', 'vis'] 

19 

20 # Test metrics using ssoObs for a particular object. 

21 times = np.array([0.1, 0.2, 0.3, 

22 1.1, 1.3, 

23 5.1, 

24 7.1, 7.2, 7.3, 

25 10.1, 10.2, 10.3, 

26 13.1, 13.5], dtype='float') 

27 ssoObs = np.recarray([len(times)], dtype=([('time', '<f8'), ('ra', '<f8'), ('dec', '<f8'), 

28 ('appMag', '<f8'), ('observationStartMJD', '<f8'), ('night', '<f8'), 

29 ('magLimit', '<f8'), ('SNR', '<f8'), ('vis', '<f8')])) 

30 

31 ssoObs['time'] = times 

32 ssoObs['observationStartMJD'] = times 

33 ssoObs['night'] = np.floor(times) 

34 ssoObs['ra'] = np.arange(len(times)) 

35 ssoObs['dec'] = np.arange(len(times)) 

36 ssoObs['appMag'] = np.zeros(len(times), dtype='float') + 24.0 

37 ssoObs['magLimit'] = np.zeros(len(times), dtype='float') + 25.0 

38 ssoObs['SNR'] = np.zeros(len(times), dtype='float') + 5.0 

39 ssoObs['vis'] = np.zeros(len(times), dtype='float') + 1 

40 ssoObs['vis'][0:5] = 0 

41 self.ssoObs = ssoObs 

42 self.orb = None 

43 self.Hval = 8.0 

44 

45 def testNObsMetric(self): 

46 nObsMetric = metrics.NObsMetric(snrLimit=5) 

47 nObs = nObsMetric.run(self.ssoObs, self.orb, self.Hval) 

48 self.assertEqual(nObs, len(self.ssoObs['time'])) 

49 nObsMetric = metrics.NObsMetric(snrLimit=10) 

50 nObs = nObsMetric.run(self.ssoObs, self.orb, self.Hval) 

51 self.assertEqual(nObs, 0) 

52 nObsMetric = metrics.NObsMetric(snrLimit=None) 

53 nObs = nObsMetric.run(self.ssoObs, self.orb, self.Hval) 

54 self.assertEqual(nObs, len(self.ssoObs['time']) - 5) 

55 

56 def testNObsNoSinglesMetric(self): 

57 nObsNoSinglesMetric = metrics.NObsNoSinglesMetric(snrLimit=5) 

58 nObs = nObsNoSinglesMetric.run(self.ssoObs, self.orb, self.Hval) 

59 self.assertEqual(nObs, len(self.ssoObs['time'])-1) 

60 

61 def testNNightsMetric(self): 

62 nNightsMetric = metrics.NNightsMetric(snrLimit=5) 

63 nnights = nNightsMetric.run(self.ssoObs, self.orb, self.Hval) 

64 self.assertEqual(nnights, len(np.unique(self.ssoObs['night']))) 

65 nNightsMetric = metrics.NNightsMetric(snrLimit=None) 

66 nnights = nNightsMetric.run(self.ssoObs, self.orb, self.Hval) 

67 self.assertEqual(nnights, len(np.unique(self.ssoObs['night']))-2) 

68 

69 def testArcMetric(self): 

70 arcMetric = metrics.ObsArcMetric(snrLimit=5) 

71 arc = arcMetric.run(self.ssoObs, self.orb, self.Hval) 

72 self.assertEqual(arc, self.ssoObs['observationStartMJD'][-1] - self.ssoObs['observationStartMJD'][0]) 

73 arcMetric = metrics.ObsArcMetric(snrLimit=None) 

74 arc = arcMetric.run(self.ssoObs, self.orb, self.Hval) 

75 self.assertEqual(arc, self.ssoObs['observationStartMJD'][-1] - self.ssoObs['observationStartMJD'][5]) 

76 

77 def testActivityOverPeriodMetric(self): 

78 # cometary orbit format ok 

79 orb = np.recarray(1, dtype=([('objId', (str, 20)), ('q', float), ('e', float), 

80 ('inc', float), ('Omega', float), ('argPeri', float), 

81 ('tPeri', float), ('epoch', float), ('H', float), ('g', float)])) 

82 

83 orb['objId'] = 'NESC00001HYj' 

84 orb['q'] = 1.00052 

85 orb['e'] = 0.028514 

86 orb['inc'] = 0.502477 

87 orb['Omega'] = 50.989131 

88 orb['argPeri'] = 55.091685 

89 orb['tPeri'] = 61046.627194 - 59850 

90 orb['epoch'] = 60973.799216 - 59850 

91 orb['H'] = 35.526041 

92 orb['g'] = 0.15 

93 o = pd.DataFrame(orb) 

94 activityPeriodMetric = metrics.ActivityOverPeriodMetric(binsize=360, snrLimit=5) 

95 activity = activityPeriodMetric.run(self.ssoObs, o.iloc[0], self.Hval) 

96 self.assertEqual(activity, 1.0) 

97 activityPeriodMetric = metrics.ActivityOverPeriodMetric(binsize=720, snrLimit=5) 

98 activity = activityPeriodMetric.run(self.ssoObs, o.iloc[0], self.Hval) 

99 self.assertEqual(activity, 1.0) 

100 activityPeriodMetric = metrics.ActivityOverPeriodMetric(binsize=10, snrLimit=5) 

101 activity = activityPeriodMetric.run(self.ssoObs, o.iloc[0], self.Hval) 

102 self.assertLess(activity, 0.03) 

103 # different type of orbit - currently should fail quietly 

104 orb = np.recarray(1, dtype=([('objId', (str, 20)), ('a', float), ('e', float), 

105 ('inc', float), ('Omega', float), ('argPeri', float), 

106 ('meanAnomaly', float), ('epoch', float), ('H', float), ('g', float)])) 

107 orb['objId'] = 'NESC00001HYj' 

108 orb['a'] = 1.029886 

109 orb['e'] = 0.028514 

110 orb['inc'] = 0.502477 

111 orb['Omega'] = 50.989131 

112 orb['argPeri'] = 55.091685 

113 orb['meanAnomaly'] = 291.321814 

114 orb['epoch'] = 60973.799216 - 59850 

115 orb['H'] = 35.526041 

116 orb['g'] = 0.15 

117 o = pd.DataFrame(orb) 

118 activityPeriodMetric = metrics.ActivityOverPeriodMetric(binsize=360, snrLimit=5) 

119 activity = activityPeriodMetric.run(self.ssoObs, o.iloc[0], self.Hval) 

120 self.assertEqual(activity, 1.0) 

121 activityPeriodMetric = metrics.ActivityOverPeriodMetric(binsize=180, snrLimit=5) 

122 activity = activityPeriodMetric.run(self.ssoObs, o.iloc[0], self.Hval) 

123 self.assertEqual(activity, 0.5) 

124 

125 def tearDown(self): 

126 del self.ssoObs 

127 del self.orb 

128 del self.Hval 

129 

130 

131class TestDiscoveryMetrics(unittest.TestCase): 

132 

133 def setUp(self): 

134 rng = np.random.RandomState(61331) 

135 # Test metrics using ssoObs for a particular object. 

136 times = np.array([0.1, 0.2, 0.9, 

137 1.1, 1.3, 

138 5.1, 

139 7.1, 7.2, 7.5, 

140 10.1, 10.2, 

141 13.1, 13.5], dtype='float') 

142 ssoObs = np.recarray([len(times)], dtype=([('time', '<f8'), ('ra', '<f8'), ('dec', '<f8'), 

143 ('ecLon', '<f8'), ('ecLat', '<f8'), ('solarElong', '<f8'), 

144 ('appMag', '<f8'), ('observationStartMJD', '<f8'), ('night', '<f8'), 

145 ('magLimit', '<f8'), ('velocity', '<f8'), 

146 ('SNR', '<f8'), ('vis', '<f8'), ('magFilter', '<f8'), 

147 ('fiveSigmaDepth', '<f8'), ('seeingFwhmGeom', '<f8'), 

148 ('visitExposureTime', '<f8'), ('dmagDetect', '<f8')])) 

149 

150 ssoObs['time'] = times 

151 ssoObs['observationStartMJD'] = times 

152 ssoObs['night'] = np.floor(times) 

153 ssoObs['ra'] = np.arange(len(times)) 

154 ssoObs['dec'] = np.arange(len(times)) + 5 

155 ssoObs['ecLon'] = ssoObs['ra'] + 10 

156 ssoObs['ecLat'] = ssoObs['dec'] + 20 

157 ssoObs['solarElong'] = ssoObs['ra'] + 30 

158 ssoObs['appMag'] = np.zeros(len(times), dtype='float') + 24.0 

159 ssoObs['magFilter'] = np.zeros(len(times), dtype='float') + 24.0 

160 ssoObs['fiveSigmaDepth'] = np.zeros(len(times), dtype='float') + 25.0 

161 ssoObs['dmagDetect'] = np.zeros(len(times), dtype='float') 

162 ssoObs['magLimit'] = np.zeros(len(times), dtype='float') + 25.0 

163 ssoObs['SNR'] = np.zeros(len(times), dtype='float') + 5.0 

164 ssoObs['vis'] = np.zeros(len(times), dtype='float') + 1 

165 ssoObs['vis'][0:5] = 0 

166 ssoObs['velocity'] = rng.rand(len(times)) 

167 ssoObs['seeingFwhmGeom'] = np.ones(len(times), 'float') 

168 ssoObs['visitExposureTime'] = np.ones(len(times), 'float') * 24.0 

169 self.ssoObs = ssoObs 

170 self.orb = np.recarray([len(times)], dtype=([('H', '<f8')])) 

171 self.orb['H'] = np.zeros(len(times), dtype='float') + 8 

172 self.Hval = 8 

173 

174 def testDiscoveryMetric(self): 

175 discMetric = metrics.DiscoveryMetric(nObsPerNight=2, tMin=0.0, tMax=0.3, 

176 nNightsPerWindow=3, tWindow=9, snrLimit=5) 

177 metricValue = discMetric.run(self.ssoObs, self.orb, self.Hval) 

178 child = metrics.Discovery_N_ObsMetric(discMetric, i=0) 

179 nobs = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

180 self.assertEqual(nobs, 8) 

181 child = metrics.Discovery_N_ObsMetric(discMetric, i=1) 

182 nobs = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

183 self.assertEqual(nobs, 7) 

184 child = metrics.Discovery_N_ChancesMetric(discMetric) 

185 nchances = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

186 self.assertEqual(nchances, 2) 

187 child = metrics.Discovery_TimeMetric(discMetric, i=0) 

188 time = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

189 self.assertEqual(time, self.ssoObs['observationStartMJD'][0]) 

190 child = metrics.Discovery_TimeMetric(discMetric, i=1) 

191 time = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

192 self.assertEqual(time, self.ssoObs['observationStartMJD'][3]) 

193 child = metrics.Discovery_RADecMetric(discMetric, i=0) 

194 ra, dec = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

195 self.assertEqual(ra, 0) 

196 self.assertEqual(dec, 5) 

197 child = metrics.Discovery_EcLonLatMetric(discMetric, i=0) 

198 lon, lat, solarElong = child.run(self.ssoObs, self.orb, self.Hval, metricValue) 

199 self.assertEqual(lon, 10) 

200 self.assertEqual(lat, 25) 

201 

202 discMetric3 = metrics.MagicDiscoveryMetric(nObs=5, tWindow=2, snrLimit=5) 

203 magic = discMetric3.run(self.ssoObs, self.orb, self.Hval) 

204 self.assertEqual(magic, 1) 

205 discMetric3 = metrics.MagicDiscoveryMetric(nObs=3, tWindow=1, snrLimit=5) 

206 magic = discMetric3.run(self.ssoObs, self.orb, self.Hval) 

207 self.assertEqual(magic, 2) 

208 discMetric3 = metrics.MagicDiscoveryMetric(nObs=4, tWindow=4, snrLimit=5) 

209 magic = discMetric3.run(self.ssoObs, self.orb, self.Hval) 

210 self.assertEqual(magic, 6) 

211 

212 def testHighVelocityMetric(self): 

213 rng = np.random.RandomState(8123) 

214 velMetric = metrics.HighVelocityMetric(psfFactor=1.0, snrLimit=5) 

215 metricValue = velMetric.run(self.ssoObs, self.orb, self.Hval) 

216 self.assertEqual(metricValue, 0) 

217 self.ssoObs['velocity'][0:2] = 1.5 

218 metricValue = velMetric.run(self.ssoObs, self.orb, self.Hval) 

219 self.assertEqual(metricValue, 2) 

220 velMetric = metrics.HighVelocityMetric(psfFactor=2.0, snrLimit=5) 

221 metricValue = velMetric.run(self.ssoObs, self.orb, self.Hval) 

222 self.assertEqual(metricValue, 0) 

223 self.ssoObs['velocity'][0:2] = rng.rand(1) 

224 

225 def testHighVelocityNightsMetric(self): 

226 velMetric = metrics.HighVelocityNightsMetric(psfFactor=1.0, nObsPerNight=1, snrLimit=5) 

227 metricValue = velMetric.run(self.ssoObs, self.orb, self.Hval) 

228 self.assertEqual(metricValue, 0) 

229 self.ssoObs['velocity'][0:2] = 1.5 

230 metricValue = velMetric.run(self.ssoObs, self.orb, self.Hval) 

231 self.assertEqual(metricValue, self.ssoObs['observationStartMJD'][0]) 

232 self.ssoObs['velocity'][0:2] = np.random.rand(1) 

233 

234class TestKnownObjectMetrics(unittest.TestCase): 

235 

236 def setUp(self): 

237 self.t1 = 53371 

238 self.t2 = 57023 

239 self.t3 = 59580 

240 times = np.arange(self.t1-365*2, self.t3+365*3, 1) 

241 cols = ['MJD(UTC)', 'RA', 'Dec', 'magV', 'Elongation', 'appMagV'] 

242 dtype = [] 

243 for c in cols: 

244 dtype.append((c, '<f8')) 

245 ssoObs = np.recarray([len(times)], dtype=dtype) 

246 

247 ssoObs['MJD(UTC)'] = times 

248 ssoObs['RA'] = np.arange(len(times)) 

249 ssoObs['Dec'] = np.arange(len(times)) 

250 ssoObs['magV'] = np.zeros(len(times), dtype='float') + 20.0 

251 ssoObs['Elongation'] = np.zeros(len(times), dtype=float) + 180.0 

252 self.Hval = 0.0 

253 ssoObs['appMagV'] = ssoObs['magV'] + self.Hval 

254 self.orb = None 

255 self.ssoObs = ssoObs 

256 

257 def testKnownObjectsMetric(self): 

258 knownObjectMetric = metrics.KnownObjectsMetric(tSwitch1=self.t1, eff1=1.0, vMagThresh1=20.5, 

259 tSwitch2=self.t2, eff2=1.0, vMagThresh2=20.5, 

260 tSwitch3=self.t3, eff3=1.0, vMagThresh3=20.5, 

261 eff4=1.0, vMagThresh4=22) 

262 mVal = knownObjectMetric.run(self.ssoObs, self.orb, self.Hval) 

263 self.assertEqual(mVal, self.ssoObs['MJD(UTC)'].min()) 

264 knownObjectMetric = metrics.KnownObjectsMetric(tSwitch1=self.t1, eff1=1.0, vMagThresh1=15.0, 

265 tSwitch2=self.t2, eff2=1.0, vMagThresh2=20.5, 

266 tSwitch3=self.t3, eff3=1.0, vMagThresh3=20.5, 

267 eff4=1.0, vMagThresh4=22) 

268 mVal = knownObjectMetric.run(self.ssoObs, self.orb, self.Hval) 

269 self.assertEqual(mVal, self.t1) 

270 knownObjectMetric = metrics.KnownObjectsMetric(tSwitch1=self.t1, eff1=0.0, vMagThresh1=20.5, 

271 tSwitch2=self.t2, eff2=1.0, vMagThresh2=20.5, 

272 tSwitch3=self.t3, eff3=1.0, vMagThresh3=20.5, 

273 eff4=1.0, vMagThresh4=22) 

274 mVal = knownObjectMetric.run(self.ssoObs, self.orb, self.Hval) 

275 self.assertEqual(mVal, self.t1) 

276 knownObjectMetric = metrics.KnownObjectsMetric(tSwitch1=self.t1, eff1=1.0, vMagThresh1=10, 

277 tSwitch2=self.t2, eff2=1.0, vMagThresh2=10.5, 

278 tSwitch3=self.t3, eff3=1.0, vMagThresh3=20.5, 

279 eff4=1.0, vMagThresh4=22) 

280 mVal = knownObjectMetric.run(self.ssoObs, self.orb, self.Hval) 

281 self.assertEqual(mVal, self.t2) 

282 knownObjectMetric = metrics.KnownObjectsMetric(tSwitch1=self.t1, eff1=1.0, vMagThresh1=10, 

283 tSwitch2=self.t2, eff2=1.0, vMagThresh2=10.5, 

284 tSwitch3=self.t3, eff3=1.0, vMagThresh3=10.5, 

285 eff4=1.0, vMagThresh4=22) 

286 mVal = knownObjectMetric.run(self.ssoObs, self.orb, self.Hval) 

287 self.assertEqual(mVal, self.t3) 

288 knownObjectMetric = metrics.KnownObjectsMetric(tSwitch1=self.t1, eff1=1.0, vMagThresh1=10, 

289 tSwitch2=self.t2, eff2=1.0, vMagThresh2=10.5, 

290 tSwitch3=self.t3, eff3=1.0, vMagThresh3=10.5, 

291 eff4=1.0, vMagThresh4=10.5) 

292 mVal = knownObjectMetric.run(self.ssoObs, self.orb, self.Hval) 

293 self.assertEqual(mVal, knownObjectMetric.badval) 

294 

295 

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

297 unittest.main()