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

1"""Sets of metrics to look at general sky coverage - nvisits/coadded depth/Teff. 

2""" 

3import numpy as np 

4import lsst.sims.maf.metrics as metrics 

5import lsst.sims.maf.slicers as slicers 

6import lsst.sims.maf.plots as plots 

7import lsst.sims.maf.metricBundles as mb 

8import lsst.sims.maf.utils as mafUtils 

9from .colMapDict import ColMapDict, getColMap 

10from .common import standardSummary, filterList, radecCols, combineMetadata 

11 

12__all__ = ['nvisitsM5Maps', 'tEffMetrics', 'nvisitsPerNight', 'nvisitsPerProp'] 

13 

14 

15def nvisitsM5Maps(colmap=None, runName='opsim', 

16 extraSql=None, extraMetadata=None, 

17 nside=64, runLength=10., 

18 ditherStacker=None, ditherkwargs=None): 

19 """Generate number of visits and Coadded depth per RA/Dec point in all and per filters. 

20 

21 Parameters 

22 ---------- 

23 colmap : dict, opt 

24 A dictionary with a mapping of column names. Default will use OpsimV4 column names. 

25 runName : str, opt 

26 The name of the simulated survey. Default is "opsim". 

27 extraSql : str, opt 

28 Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522'). 

29 Default None, for no additional constraints. 

30 extraMetadata : str, opt 

31 Additional metadata to add before any below (i.e. "WFD"). Default is None. 

32 nside : int, opt 

33 Nside value for healpix slicer. Default 64. 

34 If "None" is passed, the healpixslicer-based metrics will be skipped. 

35 runLength : float, opt 

36 Length of the simulated survey, for scaling values for the plot limits. 

37 Default 10. 

38 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker 

39 Optional dither stacker to use to define ra/dec columns. 

40 ditherkwargs: dict, opt 

41 Optional dictionary of kwargs for the dither stacker. 

42 

43 Returns 

44 ------- 

45 metricBundleDict 

46 """ 

47 if colmap is None: 

48 colmap = ColMapDict('opsimV4') 

49 bundleList = [] 

50 

51 subgroup = extraMetadata 

52 if subgroup is None: 

53 subgroup = 'All visits' 

54 

55 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs) 

56 extraMetadata = combineMetadata(extraMetadata, ditherMeta) 

57 # Set up basic all and per filter sql constraints. 

58 filterlist, colors, orders, sqls, metadata = filterList(all=True, 

59 extraSql=extraSql, 

60 extraMetadata=extraMetadata) 

61 # Set up some values to make nicer looking plots. 

62 benchmarkVals = mafUtils.scaleBenchmarks(runLength, benchmark='design') 

63 # Check that nvisits is not set to zero (for very short run length). 

64 for f in benchmarkVals['nvisits']: 

65 if benchmarkVals['nvisits'][f] == 0: 

66 print('Updating benchmark nvisits value in %s to be nonzero' % (f)) 

67 benchmarkVals['nvisits'][f] = 1 

68 benchmarkVals['coaddedDepth'] = mafUtils.calcCoaddedDepth(benchmarkVals['nvisits'], 

69 benchmarkVals['singleVisitDepth']) 

70 # Scale the nvisit ranges for the runLength. 

71 nvisitsRange = {'u': [20, 80], 'g': [50, 150], 'r': [100, 250], 

72 'i': [100, 250], 'z': [100, 300], 'y': [100, 300], 'all': [700, 1200]} 

73 scale = runLength / 10.0 

74 for f in nvisitsRange: 

75 for i in [0, 1]: 

76 nvisitsRange[f][i] = int(np.floor(nvisitsRange[f][i] * scale)) 

77 

78 # Generate Nvisit maps in all and per filters 

79 displayDict = {'group': 'Nvisits Maps', 'subgroup': subgroup} 

80 metric = metrics.CountMetric(colmap['mjd'], metricName='NVisits', units='') 

81 slicer = slicers.HealpixSlicer(nside=nside, latCol=decCol, lonCol=raCol, 

82 latLonDeg=degrees) 

83 for f in filterlist: 

84 sql = sqls[f] 

85 displayDict['caption'] = 'Number of visits per healpix in %s.' % metadata[f] 

86 displayDict['order'] = orders[f] 

87 binsize = 2 

88 if f == 'all': 

89 binsize = 5 

90 plotDict = {'xMin': nvisitsRange[f][0], 'xMax': nvisitsRange[f][1], 

91 'colorMin': nvisitsRange[f][0], 'colorMax': nvisitsRange[f][1], 

92 'binsize': binsize, 'color': colors[f]} 

93 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata[f], 

94 stackerList=ditherStacker, 

95 displayDict=displayDict, plotDict=plotDict, 

96 summaryMetrics=standardSummary()) 

97 bundleList.append(bundle) 

98 

99 # Generate Coadded depth maps per filter 

100 displayDict = {'group': 'Coadded M5 Maps', 'subgroup': subgroup} 

101 metric = metrics.Coaddm5Metric(m5Col=colmap['fiveSigmaDepth'], metricName='CoaddM5') 

102 slicer = slicers.HealpixSlicer(nside=nside, latCol=decCol, lonCol=raCol, 

103 latLonDeg=degrees) 

104 for f in filterlist: 

105 # Skip "all" for coadded depth. 

106 if f == 'all': 

107 continue 

108 mag_zp = benchmarkVals['coaddedDepth'][f] 

109 sql = sqls[f] 

110 displayDict['caption'] = 'Coadded depth per healpix, with %s benchmark value subtracted (%.1f) ' \ 

111 'in %s.' % (f, mag_zp, metadata[f]) 

112 displayDict['caption'] += ' More positive numbers indicate fainter limiting magnitudes.' 

113 displayDict['order'] = orders[f] 

114 plotDict = {'zp': mag_zp, 'xMin': -0.6, 'xMax': 0.6, 

115 'xlabel': 'coadded m5 - %.1f' % mag_zp, 

116 'colorMin': -0.6, 'colorMax': 0.6, 'color': colors[f]} 

117 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata[f], 

118 stackerList=ditherStacker, 

119 displayDict=displayDict, plotDict=plotDict, 

120 summaryMetrics=standardSummary()) 

121 bundleList.append(bundle) 

122 

123 # Set the runName for all bundles and return the bundleDict. 

124 for b in bundleList: 

125 b.setRunName(runName) 

126 return mb.makeBundlesDictFromList(bundleList) 

127 

128 

129def tEffMetrics(colmap=None, runName='opsim', 

130 extraSql=None, extraMetadata=None, nside=64, 

131 ditherStacker=None, ditherkwargs=None): 

132 """Generate a series of Teff metrics. Teff total, per night, and sky maps (all and per filter). 

133 

134 Parameters 

135 ---------- 

136 colmap : dict, opt 

137 A dictionary with a mapping of column names. Default will use OpsimV4 column names. 

138 runName : str, opt 

139 The name of the simulated survey. Default is "opsim". 

140 extraSql : str, opt 

141 Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522'). 

142 Default None, for no additional constraints. 

143 extraMetadata : str, opt 

144 Additional metadata to add before any below (i.e. "WFD"). Default is None. 

145 nside : int, opt 

146 Nside value for healpix slicer. Default 64. 

147 If "None" is passed, the healpixslicer-based metrics will be skipped. 

148 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker 

149 Optional dither stacker to use to define ra/dec columns. 

150 ditherkwargs: dict, opt 

151 Optional dictionary of kwargs for the dither stacker. 

152 

153 Returns 

154 ------- 

155 metricBundleDict 

156 """ 

157 if colmap is None: 

158 colmap = ColMapDict('opsimV4') 

159 bundleList = [] 

160 

161 subgroup = extraMetadata 

162 if subgroup is None: 

163 subgroup = 'All visits' 

164 

165 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs) 

166 extraMetadata = combineMetadata(extraMetadata, ditherMeta) 

167 

168 # Set up basic all and per filter sql constraints. 

169 filterlist, colors, orders, sqls, metadata = filterList(all=True, 

170 extraSql=extraSql, 

171 extraMetadata=extraMetadata) 

172 if metadata['all'] is None: 

173 metadata['all'] = 'All visits' 

174 

175 subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()] 

176 

177 # Total Teff and normalized Teff. 

178 displayDict = {'group': 'T_eff Summary', 'subgroup': subgroup} 

179 displayDict['caption'] = 'Total effective time of the survey (see Teff metric).' 

180 displayDict['order'] = 0 

181 metric = metrics.TeffMetric(m5Col=colmap['fiveSigmaDepth'], filterCol=colmap['filter'], 

182 normed=False, metricName='Total Teff') 

183 slicer = slicers.UniSlicer() 

184 bundle = mb.MetricBundle(metric, slicer, constraint=sqls['all'], displayDict=displayDict, 

185 metadata=metadata['all']) 

186 bundleList.append(bundle) 

187 

188 displayDict['caption'] = 'Normalized total effective time of the survey (see Teff metric).' 

189 displayDict['order'] = 1 

190 metric = metrics.TeffMetric(m5Col=colmap['fiveSigmaDepth'], filterCol=colmap['filter'], 

191 normed=True, metricName='Normalized Teff') 

192 slicer = slicers.UniSlicer() 

193 bundle = mb.MetricBundle(metric, slicer, constraint=sqls['all'], displayDict=displayDict, 

194 metadata=metadata['all']) 

195 bundleList.append(bundle) 

196 

197 # Generate Teff maps in all and per filters 

198 displayDict = {'group': 'T_eff Maps', 'subgroup': subgroup} 

199 if ditherMeta is not None: 

200 for m in metadata: 

201 metadata[m] = combineMetadata(metadata[m], ditherMeta) 

202 

203 metric = metrics.TeffMetric(m5Col=colmap['fiveSigmaDepth'], filterCol=colmap['filter'], 

204 normed=True, metricName='Normalized Teff') 

205 slicer = slicers.HealpixSlicer(nside=nside, latCol=decCol, lonCol=raCol, 

206 latLonDeg=degrees) 

207 for f in filterlist: 

208 displayDict['caption'] = 'Normalized effective time of the survey, for %s' % metadata[f] 

209 displayDict['order'] = orders[f] 

210 plotDict = {'color': colors[f]} 

211 bundle = mb.MetricBundle(metric, slicer, sqls[f], metadata=metadata[f], 

212 stackerList=ditherStacker, 

213 displayDict=displayDict, plotFuncs=subsetPlots, plotDict=plotDict, 

214 summaryMetrics=standardSummary()) 

215 bundleList.append(bundle) 

216 

217 # Set the runName for all bundles and return the bundleDict. 

218 for b in bundleList: 

219 b.setRunName(runName) 

220 return mb.makeBundlesDictFromList(bundleList) 

221 

222 

223def nvisitsPerNight(colmap=None, runName='opsim', binNights=1, 

224 extraSql=None, extraMetadata=None, subgroup=None): 

225 """Count the number of visits per night through the survey. 

226 

227 Parameters 

228 ---------- 

229 colmap : dict or None, opt 

230 A dictionary with a mapping of column names. Default will use OpsimV4 column names. 

231 runName : str, opt 

232 The name of the simulated survey. Default is "opsim". 

233 binNights : int, opt 

234 Number of nights to count in each bin. Default = 1, count number of visits in each night. 

235 extraSql : str or None, opt 

236 Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522'). 

237 Default None, for no additional constraints. 

238 extraMetadata : str or None, opt 

239 Additional metadata to add before any below (i.e. "WFD"). Default is None. 

240 subgroup : str or None, opt 

241 Use this for the 'subgroup' in the displayDict, instead of metadata. Default is None. 

242 

243 Returns 

244 ------- 

245 metricBundleDict 

246 """ 

247 if colmap is None: 

248 colmap = ColMapDict('opsimV4') 

249 

250 subgroup = subgroup 

251 if subgroup is None: 

252 subgroup = extraMetadata 

253 if subgroup is None: 

254 subgroup = 'All visits' 

255 

256 metadataCaption = extraMetadata 

257 if extraMetadata is None: 

258 if extraSql is not None: 

259 metadataCaption = extraSql 

260 else: 

261 metadataCaption = 'all visits' 

262 

263 bundleList = [] 

264 

265 displayDict = {'group': 'Nvisits Per Night', 'subgroup': subgroup} 

266 displayDict['caption'] = 'Number of visits per night for %s.' % (metadataCaption) 

267 displayDict['order'] = 0 

268 metric = metrics.CountMetric(colmap['mjd'], metricName='Nvisits') 

269 slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=binNights) 

270 bundle = mb.MetricBundle(metric, slicer, extraSql, metadata=metadataCaption, 

271 displayDict=displayDict, summaryMetrics=standardSummary()) 

272 bundleList.append(bundle) 

273 

274 # Set the runName for all bundles and return the bundleDict. 

275 for b in bundleList: 

276 b.setRunName(runName) 

277 return mb.makeBundlesDictFromList(bundleList) 

278 

279 

280def nvisitsPerProp(opsdb, colmap=None, runName='opsim', binNights=1, extraSql=None): 

281 """Set up a group of all and per-proposal nvisits metrics. 

282 

283 Parameters 

284 ---------- 

285 opsdb : lsst.sims.maf.db.Database or lsst.sims.maf.db.OpsimDatabase* object 

286 colmap : dict or None, opt 

287 A dictionary with a mapping of column names. Default will use OpsimV4 column names. 

288 runName : str, opt 

289 The name of the simulated survey. Default is "opsim". 

290 binNights : int, opt 

291 Number of nights to count in each bin. Default = 1, count number of visits in each night. 

292 sqlConstraint : str or None, opt 

293 SQL constraint to add to all metrics. 

294 

295 Returns 

296 ------- 

297 metricBundle 

298 """ 

299 if colmap is None: 

300 colmap = getColMap(opsdb) 

301 

302 propids, proptags = opsdb.fetchPropInfo() 

303 

304 bdict = {} 

305 bundleList = [] 

306 

307 totvisits = opsdb.fetchNVisits() 

308 

309 metadata = 'All props' 

310 if extraSql is not None and len(extraSql) > 0: 

311 metadata += ' %s' % extraSql 

312 # Nvisits per night, all proposals. 

313 bdict.update(nvisitsPerNight(colmap=colmap, runName=runName, binNights=binNights, 

314 extraSql=extraSql, extraMetadata=metadata, subgroup='All proposals')) 

315 # Nvisits total, all proposals. 

316 metric = metrics.CountMetric(colmap['mjd'], metricName='Nvisits') 

317 slicer = slicers.UniSlicer() 

318 summaryMetrics = [metrics.IdentityMetric(metricName='Count'), 

319 metrics.NormalizeMetric(normVal=totvisits, metricName='Fraction of total')] 

320 displayDict = {'group': 'Nvisit Summary', 'subgroup': 'Proposal distribution', 'order': -1} 

321 displayDict['caption'] = 'Total number of visits for all proposals.' 

322 if extraSql is not None and len(extraSql) > 0: 

323 displayDict['caption'] += ' (with constraint %s.)' % extraSql 

324 bundle = mb.MetricBundle(metric, slicer, extraSql, metadata=metadata, 

325 displayDict=displayDict, summaryMetrics=summaryMetrics) 

326 bundleList.append(bundle) 

327 

328 # Look for any multi-proposal groups that we should include. 

329 for tag in proptags: 

330 if len(proptags[tag]) > 1: 

331 pids = proptags[tag] 

332 sql = '(' 

333 for pid in pids[:-1]: 

334 sql += '%s=%d or ' % (colmap['proposalId'], pid) 

335 sql += ' %s=%d)' % (colmap['proposalId'], pids[-1]) 

336 metadata = '%s' % tag 

337 if extraSql is not None: 

338 sql = '(%s) and (%s)' % (sql, extraSql) 

339 metadata += ' %s' % (extraSql) 

340 bdict.update(nvisitsPerNight(colmap=colmap, runName=runName, binNights=binNights, 

341 extraSql=sql, extraMetadata=metadata, subgroup=tag)) 

342 displayDict['order'] += 1 

343 displayDict['caption'] = 'Number of visits and fraction of total visits, for %s.' % metadata 

344 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata, 

345 summaryMetrics=summaryMetrics, displayDict=displayDict) 

346 bundleList.append(bundle) 

347 

348 # And each proposal separately. 

349 for propid in propids: 

350 sql = '%s=%d' % (colmap['proposalId'], propid) 

351 metadata = '%s' % (propids[propid]) 

352 if extraSql is not None: 

353 sql += ' and (%s)' % (extraSql) 

354 metadata += ' %s' % extraSql 

355 bdict.update(nvisitsPerNight(colmap=colmap, runName=runName, binNights=binNights, 

356 extraSql=sql, extraMetadata=metadata, subgroup='Per proposal')) 

357 displayDict['order'] += 1 

358 displayDict['caption'] = 'Number of visits and fraction of total visits, for %s.' % metadata 

359 bundle = mb.MetricBundle(metric, slicer, constraint=sql, metadata=metadata, 

360 summaryMetrics=summaryMetrics, displayDict=displayDict) 

361 bundleList.append(bundle) 

362 

363 for b in bundleList: 

364 b.setRunName(runName) 

365 bdict.update(mb.makeBundlesDictFromList(bundleList)) 

366 return bdict