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

1from builtins import zip 

2import numpy as np 

3import unittest 

4import lsst.utils.tests 

5from lsst.sims.maf.utils.snUtils import Lims, ReferenceData 

6from lsst.sims.maf.utils.snNSNUtils import Throughputs, Telescope 

7from lsst.sims.maf.metrics import SNCadenceMetric 

8from lsst.sims.maf.metrics import SNSNRMetric 

9from lsst.sims.maf.metrics import SNSLMetric 

10from lsst.sims.maf.metrics import SNNSNMetric 

11 

12import os 

13import warnings 

14import healpy as hp 

15import time 

16 

17m5_ref = dict( 

18 zip('ugrizy', [23.60, 24.83, 24.38, 23.92, 23.35, 22.44])) 

19 

20 

21def Observations_band(day0=59000, daymin=59000, cadence=3., season_length=140., band='r'): 

22 # Define fake data 

23 names = ['observationStartMJD', 'fieldRA', 'fieldDec', 

24 'fiveSigmaDepth', 'visitExposureTime', 'numExposures', 

25 'visitTime', 'season', 'seeingFwhmEff', 'seeingFwhmGeom', 

26 'pixRA', 'pixDec'] 

27 types = ['f8']*len(names) 

28 names += ['night', 'healpixID'] 

29 types += ['i2', 'i2'] 

30 names += ['filter'] 

31 types += ['O'] 

32 

33 daylast = daymin+season_length 

34 cadence = cadence 

35 dayobs = np.arange(daymin, daylast, cadence) 

36 npts = len(dayobs) 

37 data = np.zeros(npts, dtype=list(zip(names, types))) 

38 data['observationStartMJD'] = dayobs 

39 data['night'] = np.floor(data['observationStartMJD']-day0+1) 

40 data['fiveSigmaDepth'] = m5_ref[band] 

41 data['visitExposureTime'] = 30. 

42 data['numExposures'] = 1 

43 data['visitTime'] = 34 

44 data['filter'] = band 

45 data['seeingFwhmEff'] = 0.8 

46 data['seeingFwhmGeom'] = 0.8 

47 data['healpixID'] = 10 

48 data['pixRA'] = 0.0 

49 data['pixDec'] = 0.0 

50 return data 

51 

52 

53def Observations_season(day0=59000, mjdmin=59000, cadence=3.): 

54 bands = 'grizy' 

55 Nvisits = dict(zip(bands, [10, 20, 20, 26, 20])) 

56 rat = 34./3600./24. 

57 shift_visits = {} 

58 shift_visits['g'] = 0 

59 shift_visits['r'] = rat*Nvisits['g'] 

60 shift_visits['i'] = rat*Nvisits['r'] 

61 shift_visits['z'] = rat*Nvisits['i'] 

62 shift_visits['y'] = rat*Nvisits['z'] 

63 

64 # get data 

65 data = None 

66 season_length = 180 

67 shift = 30./(3600.*24) 

68 for band in bands: 

69 

70 mjd = mjdmin+shift_visits[band] 

71 for i in range(Nvisits[band]): 

72 mjd += shift 

73 dat = Observations_band( 

74 daymin=mjd, season_length=season_length, cadence=cadence, band=band) 

75 if data is None: 

76 data = dat 

77 else: 

78 data = np.concatenate((data, dat)) 

79 

80 return data 

81 

82 

83def fakeData(band, season=1): 

84 

85 # Define fake data 

86 names = ['observationStartMJD', 'fieldRA', 'fieldDec', 

87 'fiveSigmaDepth', 'visitExposureTime', 

88 'numExposures', 'visitTime', 'season', 

89 'seeingFwhmEff', 'seeingFwhmGeom', 

90 'airmass', 'sky', 'moonPhase', 'pixRA', 'pixDec'] 

91 

92 types = ['f8']*len(names) 

93 names += ['night'] 

94 types += ['i2'] 

95 names += ['healpixID'] 

96 types += ['i2'] 

97 names += ['filter'] 

98 types += ['O'] 

99 

100 dayobs = [59948.31957176, 59959.2821412, 59970.26134259, 

101 59973.25978009, 59976.26383102, 59988.20670139, 59991.18412037, 

102 60004.1853588, 60032.08975694, 60045.11981481, 60047.98747685, 

103 60060.02083333, 60071.986875, 60075.96452546] 

104 day0 = np.min(dayobs) 

105 npts = len(dayobs) 

106 data = np.zeros(npts, dtype=list(zip(names, types))) 

107 data['observationStartMJD'] = dayobs 

108 data['night'] = np.floor(data['observationStartMJD']-day0+1) 

109 data['fiveSigmaDepth'] = m5_ref[band] 

110 data['visitExposureTime'] = 15. 

111 data['numExposures'] = 2 

112 data['visitTime'] = 2.*15. 

113 data['season'] = season 

114 data['filter'] = band 

115 data['seeingFwhmEff'] = 0. 

116 data['seeingFwhmGeom'] = 0. 

117 data['airmass'] = 1.2 

118 data['sky'] = 20.0 

119 data['moonPhase'] = 0.5 

120 data['pixRA'] = 0.0 

121 data['pixDec'] = 0.0 

122 data['healpixID'] = 1 

123 

124 return data 

125 

126 

127class TestSNmetrics(unittest.TestCase): 

128 

129 def testThroughputs(self): 

130 """Test the Throughputs class""" 

131 ## Again, this should not be in MAF but should use appropriate classes in lsst.sims.photUtils. 

132 # Can we set it up - are the relevant standard environment variables present? 

133 tp = Throughputs() 

134 

135 

136 def testTelescope(self): 

137 """Test the Telescope class""" 

138 # The Telescope class should be replaced by lsst.sims.photUtils.BandpassSet 

139 t = Telescope(airmass=1.2) 

140 

141 

142 def testSNCadenceMetric(self): 

143 """Test the SN cadence metric """ 

144 

145 # Load up the files from sims_maf_contrib if possible 

146 sims_maf_contrib_dir = os.getenv("SIMS_MAF_CONTRIB_DIR") 

147 if sims_maf_contrib_dir is not None: 

148 # Load required SN info to run the metric 

149 band = 'r' 

150 SNR = dict(zip('griz', [30., 40., 30., 20.])) # SNR for WFD 

151 mag_range = [21., 25.5] # WFD mag range 

152 dt_range = [0.5, 30.] # WFD dt range 

153 Li_files = [os.path.join( 

154 sims_maf_contrib_dir, 'data', 'Li_SNCosmo_-2.0_0.2.npy')] 

155 mag_to_flux_files = [os.path.join( 

156 sims_maf_contrib_dir, 'data', 'Mag_to_Flux_SNCosmo.npy')] 

157 lim_sn = Lims(Li_files, mag_to_flux_files, band, SNR[band], 

158 mag_range=mag_range, dt_range=dt_range) 

159 

160 # Define fake data 

161 names = ['observationStartMJD', 'fieldRA', 'fieldDec', 

162 'fiveSigmaDepth', 'visitExposureTime', 'numExposures', 'visitTime'] 

163 types = ['f8']*len(names) 

164 names += ['night'] 

165 types += ['i2'] 

166 names += ['filter'] 

167 types += ['O'] 

168 

169 day0 = 59000 

170 daylast = day0+250 

171 cadence = 5 

172 dayobs = np.arange(day0, daylast, cadence) 

173 npts = len(dayobs) 

174 data = np.zeros(npts, dtype=list(zip(names, types))) 

175 data['observationStartMJD'] = dayobs 

176 data['night'] = np.floor(data['observationStartMJD']-day0) 

177 data['fiveSigmaDepth'] = m5_ref[band] 

178 data['visitExposureTime'] = 15. 

179 data['numExposures'] = 2 

180 data['visitTime'] = 2.*15. 

181 data['filter'] = band 

182 

183 # Run the metric with these fake data 

184 slicePoint = {'nside': 64} 

185 metric = SNCadenceMetric(lim_sn=lim_sn, coadd=False) 

186 result = metric.run(data, slicePoint) 

187 

188 # And the result should be... 

189 result_ref = 0.3743514 

190 

191 assert(np.abs(result-result_ref) < 1.e-5) 

192 else: 

193 warnings.warn( 

194 "skipping SN test because no SIMS_MAF_CONTRIB_DIR set") 

195 

196 def testSNSNRMetric(self): 

197 """Test the SN SNR metric """ 

198 

199 sims_maf_contrib_dir = os.getenv("SIMS_MAF_CONTRIB_DIR") 

200 if sims_maf_contrib_dir is not None: 

201 # Load required SN info to run the metric 

202 band = 'r' 

203 z = 0.3 

204 season = 1. 

205 Li_files = [os.path.join( 

206 sims_maf_contrib_dir, 'data', 'Li_SNCosmo_-2.0_0.2.npy')] 

207 mag_to_flux_files = [os.path.join( 

208 sims_maf_contrib_dir, 'data', 'Mag_to_Flux_SNCosmo.npy')] 

209 

210 names_ref = ['SNCosmo'] 

211 coadd = False 

212 

213 lim_sn = ReferenceData(Li_files, mag_to_flux_files, band, z) 

214 

215 # Define fake data 

216 names = ['observationStartMJD', 'fieldRA', 'fieldDec', 

217 'fiveSigmaDepth', 'visitExposureTime', 'numExposures', 'visitTime', 'season'] 

218 types = ['f8']*len(names) 

219 names += ['night'] 

220 types += ['i2'] 

221 names += ['filter'] 

222 types += ['O'] 

223 

224 dayobs = [59948.31957176, 59959.2821412, 59970.26134259, 

225 59973.25978009, 59976.26383102, 59988.20670139, 59991.18412037, 

226 60004.1853588, 60032.08975694, 60045.11981481, 60047.98747685, 

227 60060.02083333, 60071.986875, 60075.96452546] 

228 day0 = np.min(dayobs) 

229 npts = len(dayobs) 

230 data = np.zeros(npts, dtype=list(zip(names, types))) 

231 

232 data['observationStartMJD'] = dayobs 

233 data['night'] = np.floor(data['observationStartMJD']-day0) 

234 data['fiveSigmaDepth'] = m5_ref[band] 

235 data['visitExposureTime'] = 15. 

236 data['numExposures'] = 2 

237 data['visitTime'] = 2.*15. 

238 data['season'] = season 

239 data['filter'] = band 

240 

241 # Run the metric with these fake data 

242 slicePoint = {'nside': 64} 

243 metric = SNSNRMetric( 

244 lim_sn=lim_sn, coadd=coadd, names_ref=names_ref, season=season, z=z) 

245 

246 result = metric.run(data, slicePoint) 

247 

248 # And the result should be... 

249 result_ref = 0.4830508474576271 

250 

251 assert(np.abs(result-result_ref) < 1.e-5) 

252 else: 

253 warnings.warn( 

254 "skipping SN test because no SIMS_MAF_CONTRIB_DIR set") 

255 

256 def testSNSLMetric(self): 

257 """Test the SN SL metric """ 

258 

259 # load some fake data 

260 data = None 

261 bands = 'griz' 

262 cadence = dict(zip(bands, [2, 1, 2, 1])) 

263 for band in bands: 

264 for i in range(cadence[band]): 

265 fakes = fakeData(band) 

266 if data is None: 

267 data = fakes 

268 else: 

269 data = np.concatenate((data, fakes)) 

270 

271 # metric instance 

272 night_collapse = True 

273 

274 metric = SNSLMetric(night_collapse=night_collapse, nfilters_min=4, min_season_obs=5, 

275 m5mins={'u': 22.7, 'g': 24.1, 'r': 23.7, 'i': 23.1, 'z': 22.2, 'y': 21.4}) 

276 

277 # run the metric 

278 nSL = metric.run(data, slicePoint={'nside': 64, 'ra': 0., 'ebv': 0.}) 

279 

280 # and the result should be 

281 # Changing the refernce value because we have new coadd and mag limits 

282 nSL_ref = 1.42168e-6 # 0.00012650940 

283 

284 assert(np.abs(nSL-nSL_ref) < 1.e-8) 

285 

286 def testNSNMetric(self): 

287 """ Test the SN NSN metric """ 

288 sims_maf_contrib_dir = os.getenv("SIMS_MAF_CONTRIB_DIR") 

289 if sims_maf_contrib_dir is not None: 

290 

291 day0 = 59000 

292 data = None 

293 

294 diff_season = 280. 

295 nseasons = 1 

296 for val in np.arange(59000, 59000+nseasons*diff_season, diff_season): 

297 dat = Observations_season(day0, val) 

298 if data is None: 

299 data = dat 

300 else: 

301 data = np.concatenate((data, dat)) 

302 

303 #print('data generated', len(data)) 

304 

305 # this is to mimic healpixilization 

306 nside = 128 

307 area = hp.nside2pixarea(nside, degrees=True) 

308 # metric instance 

309 templateDir = None 

310 metric = SNNSNMetric( 

311 pixArea=area, season=[-1], verbose=False, templateDir=templateDir) 

312 

313 time_ref = time.time() 

314 

315 res = metric.run(data) 

316 

317 nSN = res['nSN'].item() 

318 zlim = res['zlim'].item() 

319 

320 #print(time.time()-time_ref, nSN, zlim) 

321 nSN_ref = 2.523 

322 zlim_ref = 0.65 

323 

324 assert(np.isclose(nSN, nSN_ref)) 

325 assert(np.isclose(zlim, zlim_ref)) 

326 else: 

327 warnings.warn( 

328 "skipping SN test because no SIMS_MAF_CONTRIB_DIR set") 

329 

330def setup_module(module): 

331 lsst.utils.tests.init() 

332 

333 

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

335 lsst.utils.tests.init() 

336 unittest.main()