Coverage for python/lsst/sims/maf/batches/metadataBatch.py : 4%

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"""Some basic physical quantity metrics.
2"""
3import lsst.sims.maf.metrics as metrics
4import lsst.sims.maf.slicers as slicers
5import lsst.sims.maf.stackers as stackers
6import lsst.sims.maf.plots as plots
7import lsst.sims.maf.metricBundles as mb
8from .colMapDict import ColMapDict
9from .common import standardSummary, extendedMetrics, standardAngleMetrics, \
10 filterList, radecCols, combineMetadata
12__all__ = ['metadataBasics', 'metadataBasicsAngle', 'allMetadata', 'metadataMaps']
15def metadataBasics(value, colmap=None, runName='opsim',
16 valueName=None, groupName=None, extraSql=None,
17 extraMetadata=None, nside=64,
18 ditherStacker=None, ditherkwargs=None):
19 """Calculate basic metrics on visit metadata 'value' (e.g. airmass, normalized airmass, seeing..).
21 Calculates extended standard metrics (with unislicer) on the quantity (all visits and per filter),
22 makes histogram of the value (all visits and per filter),
24 TODO: handle stackers which need configuration (degrees, in particular) more automatically.
25 Currently have a hack for HA & normairmass.
27 Parameters
28 ----------
29 value : str
30 The column name for the quantity to evaluate. (column name in the database or created by a stacker).
31 colmap : dict or None, opt
32 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
33 runName : str, opt
34 The name of the simulated survey. Default is "opsim".
35 valueName : str, opt
36 The name of the value to be reported in the resultsDb and added to the metric.
37 This is intended to help standardize metric comparison between sim versions.
38 value = name as it is in the database (seeingFwhmGeom, etc).
39 valueName = name to be recorded ('seeingGeom', etc.). Default is None, which will match 'value'.
40 groupName : str, opt
41 The group name for this quantity in the displayDict. Default is the same as 'valueName', capitalized.
42 extraSql : str, opt
43 Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
44 Default None, for no additional constraints.
45 extraMetadata : str, opt
46 Additional metadata to add before any below (i.e. "WFD"). Default is None.
47 nside : int, opt
48 Nside value for healpix slicer. Default 64.
49 If "None" is passed, the healpixslicer-based metrics will be skipped.
50 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker
51 Optional dither stacker to use to define ra/dec columns.
52 ditherkwargs: dict, opt
53 Optional dictionary of kwargs for the dither stacker.
55 Returns
56 -------
57 metricBundleDict
58 """
59 if colmap is None:
60 colmap = ColMapDict('fbs')
61 bundleList = []
63 if valueName is None:
64 valueName = value
66 if groupName is None:
67 groupName = valueName.capitalize()
68 subgroup = extraMetadata
69 else:
70 groupName = groupName.capitalize()
71 subgroup = valueName.capitalize()
73 if subgroup is None:
74 subgroup = 'All visits'
76 displayDict = {'group': groupName, 'subgroup': subgroup}
78 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs)
79 extraMetadata = combineMetadata(extraMetadata, ditherMeta)
80 # Set up basic all and per filter sql constraints.
81 filterlist, colors, orders, sqls, metadata = filterList(all=True,
82 extraSql=extraSql,
83 extraMetadata=extraMetadata)
85 # Hack to make HA work, but really I need to account for any stackers/colmaps.
86 if value == 'HA':
87 stackerList = [stackers.HourAngleStacker(lstCol=colmap['lst'], raCol=raCol,
88 degrees=degrees)]
89 elif value == 'normairmass':
90 stackerList = [stackers.NormAirmassStacker(degrees=degrees)]
91 else:
92 stackerList = None
93 if ditherStacker is not None:
94 if stackerList is None:
95 stackerList = [ditherStacker]
96 else:
97 stackerList.append(ditherStacker)
99 # Summarize values over all and per filter (min/mean/median/max/percentiles/outliers/rms).
100 slicer = slicers.UniSlicer()
101 for f in filterlist:
102 for m in extendedMetrics(value, replace_colname=valueName):
103 displayDict['caption'] = '%s for %s.' % (m.name, metadata[f])
104 displayDict['order'] = orders[f]
105 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
106 metadata=metadata[f], displayDict=displayDict)
107 bundleList.append(bundle)
109 # Histogram values over all and per filter.
110 for f in filterlist:
111 displayDict['caption'] = 'Histogram of %s' % (value)
112 if valueName != value:
113 displayDict['caption'] += ' (%s)' % (valueName)
114 displayDict['caption'] += ' for %s.' % (metadata[f])
115 displayDict['order'] = orders[f]
116 m = metrics.CountMetric(value, metricName='%s Histogram' % (valueName))
117 slicer = slicers.OneDSlicer(sliceColName=value)
118 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
119 metadata=metadata[f], displayDict=displayDict)
120 bundleList.append(bundle)
122 # Make maps of min/median/max for all and per filter, per RA/Dec, with standard summary stats.
123 mList = []
124 mList.append(metrics.MinMetric(value, metricName='Min %s' % (valueName)))
125 mList.append(metrics.MedianMetric(value, metricName='Median %s' % (valueName)))
126 mList.append(metrics.MaxMetric(value, metricName='Max %s' % (valueName)))
127 slicer = slicers.HealpixSlicer(nside=nside, latCol=decCol, lonCol=raCol,
128 latLonDeg=degrees)
129 subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
130 for f in filterlist:
131 for m in mList:
132 displayDict['caption'] = 'Map of %s' % m.name
133 if valueName != value:
134 displayDict['caption'] += ' (%s)' % value
135 displayDict['caption'] += ' for %s.' % metadata[f]
136 displayDict['order'] = orders[f]
137 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
138 metadata=metadata[f], plotFuncs=subsetPlots,
139 displayDict=displayDict,
140 summaryMetrics=standardSummary())
141 bundleList.append(bundle)
143 # Set the runName for all bundles and return the bundleDict.
144 for b in bundleList:
145 b.setRunName(runName)
146 return mb.makeBundlesDictFromList(bundleList)
149def metadataBasicsAngle(value, colmap=None, runName='opsim',
150 valueName=None, groupName=None, extraSql=None,
151 extraMetadata=None, nside=64,
152 ditherStacker=None, ditherkwargs=None):
153 """Calculate basic metrics on visit metadata 'value', where value is a wrap-around angle.
155 Calculates extended standard metrics (with unislicer) on the quantity (all visits and per filter),
156 makes histogram of the value (all visits and per filter),
159 Parameters
160 ----------
161 value : str
162 The column name for the quantity to evaluate. (column name in the database or created by a stacker).
163 colmap : dict or None, opt
164 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
165 runName : str, opt
166 The name of the simulated survey. Default is "opsim".
167 valueName : str, opt
168 The name of the value to be reported in the resultsDb and added to the metric.
169 This is intended to help standardize metric comparison between sim versions.
170 value = name as it is in the database (seeingFwhmGeom, etc).
171 valueName = name to be recorded ('seeingGeom', etc.). Default is None, which will match 'value'.
172 groupName : str, opt
173 The group name for this quantity in the displayDict. Default is the same as 'valueName', capitalized.
174 extraSql : str, opt
175 Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
176 Default None, for no additional constraints.
177 extraMetadata : str, opt
178 Additional metadata to add before any below (i.e. "WFD"). Default is None.
179 nside : int, opt
180 Nside value for healpix slicer. Default 64.
181 If "None" is passed, the healpixslicer-based metrics will be skipped.
182 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker
183 Optional dither stacker to use to define ra/dec columns.
184 ditherkwargs: dict, opt
185 Optional dictionary of kwargs for the dither stacker.
187 Returns
188 -------
189 metricBundleDict
190 """
191 if colmap is None:
192 colmap = ColMapDict('opsimV4')
193 bundleList = []
195 if valueName is None:
196 valueName = value
198 if groupName is None:
199 groupName = valueName.capitalize()
200 subgroup = extraMetadata
201 else:
202 groupName = groupName.capitalize()
203 subgroup = valueName.capitalize()
205 if subgroup is None:
206 subgroup = 'All visits'
208 displayDict = {'group': groupName, 'subgroup': subgroup}
210 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs)
211 extraMetadata = combineMetadata(extraMetadata, ditherMeta)
212 # Set up basic all and per filter sql constraints.
213 filterlist, colors, orders, sqls, metadata = filterList(all=True,
214 extraSql=extraSql,
215 extraMetadata=extraMetadata)
217 stackerList = [ditherStacker]
219 # Summarize values over all and per filter.
220 slicer = slicers.UniSlicer()
221 for f in filterlist:
222 for m in standardAngleMetrics(value, replace_colname=valueName):
223 displayDict['caption'] = '%s for %s.' % (m.name, metadata[f])
224 displayDict['order'] = orders[f]
225 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
226 metadata=metadata[f], displayDict=displayDict)
227 bundleList.append(bundle)
229 # Histogram values over all and per filter.
230 for f in filterlist:
231 displayDict['caption'] = 'Histogram of %s' % (value)
232 if valueName != value:
233 displayDict['caption'] += ' (%s)' % (valueName)
234 displayDict['caption'] += ' for %s.' % (metadata[f])
235 displayDict['order'] = orders[f]
236 m = metrics.CountMetric(value, metricName='%s Histogram' % (valueName))
237 slicer = slicers.OneDSlicer(sliceColName=value)
238 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
239 metadata=metadata[f], displayDict=displayDict)
240 bundleList.append(bundle)
242 # Make maps of min/median/max for all and per filter, per RA/Dec, with standard summary stats.
243 mList = []
244 mList.append(metrics.MeanAngleMetric(value, metricName='AngleMean %s' % (valueName)))
245 mList.append(metrics.FullRangeAngleMetric(value, metricName='AngleRange %s' % (valueName)))
246 mList.append(metrics.RmsAngleMetric(value, metricName='AngleRms %s' % (valueName)))
247 slicer = slicers.HealpixSlicer(nside=nside, latCol=decCol, lonCol=raCol,
248 latLonDeg=degrees)
249 subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
250 for f in filterlist:
251 for m in mList:
252 displayDict['caption'] = 'Map of %s' % m.name
253 if valueName != value:
254 displayDict['caption'] += ' (%s)' % value
255 displayDict['caption'] += ' for %s.' % metadata[f]
256 displayDict['order'] = orders[f]
257 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
258 metadata=metadata[f], plotFuncs=subsetPlots,
259 displayDict=displayDict,
260 summaryMetrics=standardSummary())
261 bundleList.append(bundle)
263 # Set the runName for all bundles and return the bundleDict.
264 for b in bundleList:
265 b.setRunName(runName)
266 return mb.makeBundlesDictFromList(bundleList)
269def allMetadata(colmap=None, runName='opsim', extraSql=None, extraMetadata=None,
270 ditherStacker=None, ditherkwargs=None):
271 """Generate a large set of metrics about the metadata of each visit -
272 distributions of airmass, normalized airmass, seeing, sky brightness, single visit depth,
273 hour angle, distance to the moon, and solar elongation.
274 The exact metadata which is analyzed is set by the colmap['metadataList'] value.
276 Parameters
277 ----------
278 colmap : dict or None, opt
279 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
280 runName : str, opt
281 The name of the simulated survey. Default is "opsim".
282 extraSql : str, opt
283 Sql constraint (such as WFD only). Default is None.
284 extraMetadata : str, opt
285 Metadata to identify the sql constraint (such as WFD). Default is None.
287 Returns
288 -------
289 metricBundleDict
290 """
292 if colmap is None:
293 colmap = ColMapDict('opsimV4')
295 bdict = {}
297 for valueName in colmap['metadataList']:
298 if valueName in colmap:
299 value = colmap[valueName]
300 else:
301 value = valueName
302 bdict.update(metadataBasics(value, colmap=colmap, runName=runName,
303 valueName=valueName,
304 extraSql=extraSql, extraMetadata=extraMetadata,
305 ditherStacker=ditherStacker, ditherkwargs=ditherkwargs))
306 for valueName in colmap['metadataAngleList']:
307 if valueName in colmap:
308 value = colmap[valueName]
309 else:
310 value = valueName
311 bdict.update(metadataBasicsAngle(value, colmap=colmap, runName=runName,
312 valueName=valueName,
313 extraSql=extraSql, extraMetadata=extraMetadata,
314 ditherStacker=ditherStacker, ditherkwargs=ditherkwargs))
315 return bdict
318def metadataMaps(value, colmap=None, runName='opsim',
319 valueName=None, groupName=None, extraSql=None,
320 extraMetadata=None, nside=64,
321 ditherStacker=None, ditherkwargs=None):
322 """Calculate 25/50/75 percentile values on maps across sky for a single metadata value.
324 TODO: handle stackers which need configuration (degrees, in particular) more automatically.
325 Currently have a hack for HA & normairmass.
327 Parameters
328 ----------
329 value : str
330 The column name for the quantity to evaluate. (column name in the database or created by a stacker).
331 colmap : dict or None, opt
332 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
333 runName : str, opt
334 The name of the simulated survey. Default is "opsim".
335 valueName : str, opt
336 The name of the value to be reported in the resultsDb and added to the metric.
337 This is intended to help standardize metric comparison between sim versions.
338 value = name as it is in the database (seeingFwhmGeom, etc).
339 valueName = name to be recorded ('seeingGeom', etc.). Default is None, which will match 'value'.
340 groupName : str, opt
341 The group name for this quantity in the displayDict. Default is the same as 'valueName', capitalized.
342 extraSql : str, opt
343 Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
344 Default None, for no additional constraints.
345 extraMetadata : str, opt
346 Additional metadata to add before any below (i.e. "WFD"). Default is None.
347 nside : int, opt
348 Nside value for healpix slicer. Default 64.
349 If "None" is passed, the healpixslicer-based metrics will be skipped.
350 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker
351 Optional dither stacker to use to define ra/dec columns.
352 ditherkwargs: dict, opt
353 Optional dictionary of kwargs for the dither stacker.
355 Returns
356 -------
357 metricBundleDict
358 """
359 if colmap is None:
360 colmap = ColMapDict('opsimV4')
361 bundleList = []
363 if valueName is None:
364 valueName = value
366 if groupName is None:
367 groupName = valueName.capitalize()
368 subgroup = extraMetadata
369 else:
370 groupName = groupName.capitalize()
371 subgroup = valueName.capitalize()
373 if subgroup is None:
374 subgroup = 'All visits'
376 displayDict = {'group': groupName, 'subgroup': subgroup}
378 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs)
379 extraMetadata = combineMetadata(extraMetadata, ditherMeta)
380 # Set up basic all and per filter sql constraints.
381 filterlist, colors, orders, sqls, metadata = filterList(all=True,
382 extraSql=extraSql,
383 extraMetadata=extraMetadata)
385 # Hack to make HA work, but really I need to account for any stackers/colmaps.
386 if value == 'HA':
387 stackerList = [stackers.HourAngleStacker(lstCol=colmap['lst'], raCol=raCol,
388 degrees=degrees)]
389 elif value == 'normairmass':
390 stackerList = [stackers.NormAirmassStacker(degrees=degrees)]
391 else:
392 stackerList = None
393 if ditherStacker is not None:
394 if stackerList is None:
395 stackerList = [ditherStacker]
396 else:
397 stackerList.append(ditherStacker)
399 # Make maps of 25/median/75 for all and per filter, per RA/Dec, with standard summary stats.
400 mList = []
401 mList.append(metrics.PercentileMetric(value, percentile=25,
402 metricName='25thPercentile %s' % (valueName)))
403 mList.append(metrics.MedianMetric(value, metricName='Median %s' % (valueName)))
404 mList.append(metrics.PercentileMetric(value, percentile=75,
405 metricName='75thPercentile %s' % (valueName)))
406 slicer = slicers.HealpixSlicer(nside=nside, latCol=decCol, lonCol=raCol,
407 latLonDeg=degrees)
408 subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
409 for f in filterlist:
410 for m in mList:
411 displayDict['caption'] = 'Map of %s' % m.name
412 if valueName != value:
413 displayDict['caption'] += ' (%s)' % value
414 displayDict['caption'] += ' for %s.' % metadata[f]
415 displayDict['order'] = orders[f]
416 bundle = mb.MetricBundle(m, slicer, sqls[f], stackerList=stackerList,
417 metadata=metadata[f], plotFuncs=subsetPlots,
418 displayDict=displayDict,
419 summaryMetrics=standardSummary())
420 bundleList.append(bundle)
422 # Set the runName for all bundles and return the bundleDict.
423 for b in bundleList:
424 b.setRunName(runName)
425 plotBundles = []
426 return mb.makeBundlesDictFromList(bundleList), plotBundles