Coverage for python/lsst/sims/maf/batches/srdBatch.py : 6%

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 the SRD metrics.
2"""
3import numpy as np
4import healpy as hp
5import lsst.sims.maf.metrics as metrics
6import lsst.sims.maf.slicers as slicers
7import lsst.sims.maf.stackers as stackers
8import lsst.sims.maf.plots as plots
9import lsst.sims.maf.metricBundles as mb
10from .colMapDict import ColMapDict
11from .common import standardSummary, radecCols, combineMetadata
13__all__ = ['fOBatch', 'astrometryBatch', 'rapidRevisitBatch']
16def fOBatch(colmap=None, runName='opsim', extraSql=None, extraMetadata=None, nside=64,
17 benchmarkArea=18000, benchmarkNvisits=825, minNvisits=750):
18 """Metrics for calculating fO.
20 Parameters
21 ----------
22 colmap : dict or None, opt
23 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
24 runName : str, opt
25 The name of the simulated survey. Default is "opsim".
26 nside : int, opt
27 Nside for the healpix slicer. Default 64.
28 extraSql : str or None, opt
29 Additional sql constraint to apply to all metrics.
30 extraMetadata : str or None, opt
31 Additional metadata to apply to all results.
33 Returns
34 -------
35 metricBundleDict
36 """
37 if colmap is None:
38 colmap = ColMapDict('fbs')
40 bundleList = []
42 sql = ''
43 metadata = 'All visits'
44 # Add additional sql constraint (such as wfdWhere) and metadata, if provided.
45 if (extraSql is not None) and (len(extraSql) > 0):
46 sql = extraSql
47 if extraMetadata is None:
48 metadata = extraSql.replace('filter =', '').replace('filter=', '')
49 metadata = metadata.replace('"', '').replace("'", '')
50 if extraMetadata is not None:
51 metadata = extraMetadata
53 subgroup = metadata
55 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(None, colmap, None)
56 # Don't want dither info in subgroup (too long), but do want it in bundle name.
57 metadata = combineMetadata(metadata, ditherMeta)
59 # Set up fO metric.
60 slicer = slicers.HealpixSlicer(nside=nside, lonCol=raCol, latCol=decCol, latLonDeg=degrees)
62 displayDict = {'group': 'SRD FO metrics', 'subgroup': subgroup, 'order': 0}
64 # Configure the count metric which is what is used for f0 slicer.
65 metric = metrics.CountExplimMetric(col=colmap['mjd'], metricName='fO', expCol=colmap['exptime'])
66 plotDict = {'xlabel': 'Number of Visits', 'Asky': benchmarkArea,
67 'Nvisit': benchmarkNvisits, 'xMin': 0, 'xMax': 1500}
68 summaryMetrics = [metrics.fOArea(nside=nside, norm=False, metricName='fOArea',
69 Asky=benchmarkArea, Nvisit=benchmarkNvisits),
70 metrics.fOArea(nside=nside, norm=True, metricName='fOArea/benchmark',
71 Asky=benchmarkArea, Nvisit=benchmarkNvisits),
72 metrics.fONv(nside=nside, norm=False, metricName='fONv',
73 Asky=benchmarkArea, Nvisit=benchmarkNvisits),
74 metrics.fONv(nside=nside, norm=True, metricName='fONv/benchmark',
75 Asky=benchmarkArea, Nvisit=benchmarkNvisits),
76 metrics.fOArea(nside=nside, norm=False, metricName=f'fOArea_{minNvisits}',
77 Asky=benchmarkArea, Nvisit=minNvisits)]
78 caption = 'The FO metric evaluates the overall efficiency of observing. '
79 caption += ('foNv: out of %.2f sq degrees, the area receives at least X and a median of Y visits '
80 '(out of %d, if compared to benchmark). ' % (benchmarkArea, benchmarkNvisits))
81 caption += ('fOArea: this many sq deg (out of %.2f sq deg if compared '
82 'to benchmark) receives at least %d visits. ' % (benchmarkArea, benchmarkNvisits))
83 displayDict['caption'] = caption
84 bundle = mb.MetricBundle(metric, slicer, sql, plotDict=plotDict,
85 stackerList = [ditherStacker],
86 displayDict=displayDict, summaryMetrics=summaryMetrics,
87 plotFuncs=[plots.FOPlot()], metadata=metadata)
88 bundleList.append(bundle)
89 # Set the runName for all bundles and return the bundleDict.
90 for b in bundleList:
91 b.setRunName(runName)
92 return mb.makeBundlesDictFromList(bundleList)
95def astrometryBatch(colmap=None, runName='opsim',
96 extraSql=None, extraMetadata=None,
97 nside=64, ditherStacker=None, ditherkwargs=None):
98 """Metrics for evaluating proper motion and parallax.
100 Parameters
101 ----------
102 colmap : dict or None, opt
103 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
104 runName : str, opt
105 The name of the simulated survey. Default is "opsim".
106 nside : int, opt
107 Nside for the healpix slicer. Default 64.
108 extraSql : str or None, opt
109 Additional sql constraint to apply to all metrics.
110 extraMetadata : str or None, opt
111 Additional metadata to apply to all results.
112 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker
113 Optional dither stacker to use to define ra/dec columns.
114 ditherkwargs: dict, opt
115 Optional dictionary of kwargs for the dither stacker.
117 Returns
118 -------
119 metricBundleDict
120 """
121 if colmap is None:
122 colmap = ColMapDict('fbs')
123 bundleList = []
125 sql = ''
126 metadata = 'All visits'
127 # Add additional sql constraint (such as wfdWhere) and metadata, if provided.
128 if (extraSql is not None) and (len(extraSql) > 0):
129 sql = extraSql
130 if extraMetadata is None:
131 metadata = extraSql.replace('filter =', '').replace('filter=', '')
132 metadata = metadata.replace('"', '').replace("'", '')
133 if extraMetadata is not None:
134 metadata = extraMetadata
136 subgroup = metadata
138 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs)
139 # Don't want dither info in subgroup (too long), but do want it in bundle name.
140 metadata = combineMetadata(metadata, ditherMeta)
142 rmags_para = [22.4, 24.0]
143 rmags_pm = [20.5, 24.0]
145 # Set up parallax/dcr stackers.
146 parallaxStacker = stackers.ParallaxFactorStacker(raCol=raCol, decCol=decCol,
147 dateCol=colmap['mjd'], degrees=degrees)
148 dcrStacker = stackers.DcrStacker(filterCol=colmap['filter'], altCol=colmap['alt'], degrees=degrees,
149 raCol=raCol, decCol=decCol, lstCol=colmap['lst'],
150 site='LSST', mjdCol=colmap['mjd'])
152 # Set up parallax metrics.
153 slicer = slicers.HealpixSlicer(nside=nside, lonCol=raCol, latCol=decCol, latLonDeg=degrees)
154 subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
156 displayDict = {'group': 'SRD Parallax', 'subgroup': subgroup,
157 'order': 0, 'caption': None}
158 # Expected error on parallax at 10 AU.
159 plotmaxVals = (2.0, 15.0)
160 summary = [metrics.AreaSummaryMetric(area=18000, reduce_func=np.median, decreasing=False,
161 metricName='Median Parallax Error (18k)')]
162 summary.append(metrics.PercentileMetric(percentile=95, metricName='95th Percentile Parallax Error'))
163 summary.extend(standardSummary())
164 for rmag, plotmax in zip(rmags_para, plotmaxVals):
165 plotDict = {'xMin': 0, 'xMax': plotmax, 'colorMin': 0, 'colorMax': plotmax}
166 metric = metrics.ParallaxMetric(metricName='Parallax Error @ %.1f' % (rmag), rmag=rmag,
167 seeingCol=colmap['seeingGeom'], filterCol=colmap['filter'],
168 m5Col=colmap['fiveSigmaDepth'], normalize=False)
169 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata,
170 stackerList=[parallaxStacker, ditherStacker],
171 displayDict=displayDict, plotDict=plotDict,
172 summaryMetrics=summary,
173 plotFuncs=subsetPlots)
174 bundleList.append(bundle)
175 displayDict['order'] += 1
177 # Parallax normalized to 'best possible' if all visits separated by 6 months.
178 # This separates the effect of cadence from depth.
179 for rmag in rmags_para:
180 metric = metrics.ParallaxMetric(metricName='Normalized Parallax @ %.1f' % (rmag), rmag=rmag,
181 seeingCol=colmap['seeingGeom'], filterCol=colmap['filter'],
182 m5Col=colmap['fiveSigmaDepth'], normalize=True)
183 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata,
184 stackerList=[parallaxStacker, ditherStacker],
185 displayDict=displayDict,
186 summaryMetrics=standardSummary(),
187 plotFuncs=subsetPlots)
188 bundleList.append(bundle)
189 displayDict['order'] += 1
190 # Parallax factor coverage.
191 for rmag in rmags_para:
192 metric = metrics.ParallaxCoverageMetric(metricName='Parallax Coverage @ %.1f' % (rmag),
193 rmag=rmag, m5Col=colmap['fiveSigmaDepth'],
194 mjdCol=colmap['mjd'], filterCol=colmap['filter'],
195 seeingCol=colmap['seeingGeom'])
196 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata,
197 stackerList=[parallaxStacker, ditherStacker],
198 displayDict=displayDict, summaryMetrics=standardSummary(),
199 plotFuncs=subsetPlots)
200 bundleList.append(bundle)
201 displayDict['order'] += 1
202 # Parallax problems can be caused by HA and DCR degeneracies. Check their correlation.
203 for rmag in rmags_para:
204 metric = metrics.ParallaxDcrDegenMetric(metricName='Parallax-DCR degeneracy @ %.1f' % (rmag),
205 rmag=rmag, seeingCol=colmap['seeingEff'],
206 filterCol=colmap['filter'], m5Col=colmap['fiveSigmaDepth'])
207 caption = 'Correlation between parallax offset magnitude and hour angle for a r=%.1f star.' % (rmag)
208 caption += ' (0 is good, near -1 or 1 is bad).'
209 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata,
210 stackerList=[dcrStacker, parallaxStacker, ditherStacker],
211 displayDict=displayDict, summaryMetrics=standardSummary(),
212 plotFuncs=subsetPlots)
213 bundleList.append(bundle)
214 displayDict['order'] += 1
216 # Proper Motion metrics.
217 displayDict = {'group': 'SRD Proper Motion', 'subgroup': subgroup, 'order': 0, 'caption': None}
218 # Proper motion errors.
219 plotmaxVals = (1.0, 5.0)
220 summary = [metrics.AreaSummaryMetric(area=18000, reduce_func=np.median, decreasing=False,
221 metricName='Median Proper Motion Error (18k)')]
222 summary.append(metrics.PercentileMetric(metricName='95th Percentile Proper Motion Error'))
223 summary.extend(standardSummary())
224 for rmag, plotmax in zip(rmags_pm, plotmaxVals):
225 plotDict = {'xMin': 0, 'xMax': plotmax, 'colorMin': 0, 'colorMax': plotmax}
226 metric = metrics.ProperMotionMetric(metricName='Proper Motion Error @ %.1f' % rmag,
227 rmag=rmag, m5Col=colmap['fiveSigmaDepth'],
228 mjdCol=colmap['mjd'], filterCol=colmap['filter'],
229 seeingCol=colmap['seeingGeom'], normalize=False)
230 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata,
231 stackerList=[ditherStacker],
232 displayDict=displayDict, plotDict=plotDict,
233 summaryMetrics=summary,
234 plotFuncs=subsetPlots)
235 bundleList.append(bundle)
236 displayDict['order'] += 1
237 # Normalized proper motion.
238 for rmag in rmags_pm:
239 metric = metrics.ProperMotionMetric(metricName='Normalized Proper Motion @ %.1f' % rmag,
240 rmag=rmag, m5Col=colmap['fiveSigmaDepth'],
241 mjdCol=colmap['mjd'], filterCol=colmap['filter'],
242 seeingCol=colmap['seeingGeom'], normalize=True)
243 bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata,
244 stackerList=[ditherStacker],
245 displayDict=displayDict, summaryMetrics=standardSummary(),
246 plotFuncs=subsetPlots)
247 bundleList.append(bundle)
248 displayDict['order'] += 1
250 # Set the runName for all bundles and return the bundleDict.
251 for b in bundleList:
252 b.setRunName(runName)
253 return mb.makeBundlesDictFromList(bundleList)
256def rapidRevisitBatch(colmap=None, runName='opsim',
257 extraSql=None, extraMetadata=None, nside=64,
258 ditherStacker=None, ditherkwargs=None):
259 """Metrics for evaluating proper motion and parallax.
261 Parameters
262 ----------
263 colmap : dict or None, opt
264 A dictionary with a mapping of column names. Default will use OpsimV4 column names.
265 runName : str, opt
266 The name of the simulated survey. Default is "opsim".
267 nside : int, opt
268 Nside for the healpix slicer. Default 64.
269 extraSql : str or None, opt
270 Additional sql constraint to apply to all metrics.
271 extraMetadata : str or None, opt
272 Additional metadata to apply to all results.
273 ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker
274 Optional dither stacker to use to define ra/dec columns.
275 ditherkwargs: dict, opt
276 Optional dictionary of kwargs for the dither stacker.
278 Returns
279 -------
280 metricBundleDict
281 """
282 if colmap is None:
283 colmap = ColMapDict('fbs')
284 bundleList = []
286 sql = ''
287 metadata = 'All visits'
288 # Add additional sql constraint (such as wfdWhere) and metadata, if provided.
289 if (extraSql is not None) and (len(extraSql) > 0):
290 sql = extraSql
291 if extraMetadata is None:
292 metadata = extraSql.replace('filter =', '').replace('filter=', '')
293 metadata = metadata.replace('"', '').replace("'", '')
294 if extraMetadata is not None:
295 metadata = extraMetadata
297 subgroup = metadata
299 raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs)
300 # Don't want dither info in subgroup (too long), but do want it in bundle name.
301 metadata = combineMetadata(metadata, ditherMeta)
303 slicer = slicers.HealpixSlicer(nside=nside, lonCol=raCol, latCol=decCol, latLonDeg=degrees)
304 subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
306 displayDict = {'group': 'SRD Rapid Revisits', 'subgroup': subgroup,
307 'order': 0, 'caption': None}
309 # Calculate the actual number of revisits within 30 minutes.
310 dTmax = 30 # time in minutes
311 m2 = metrics.NRevisitsMetric(dT=dTmax, mjdCol=colmap['mjd'], normed=False,
312 metricName='NumberOfQuickRevisits')
313 plotDict = {'colorMin': 400, 'colorMax': 2000, 'xMin': 400, 'xMax': 2000}
314 caption = 'Number of consecutive visits with return times faster than %.1f minutes, ' % (dTmax)
315 caption += 'in any filter, all proposals. '
316 displayDict['caption'] = caption
317 bundle = mb.MetricBundle(m2, slicer, sql, plotDict=plotDict, plotFuncs=subsetPlots,
318 stackerList=[ditherStacker],
319 metadata=metadata, displayDict=displayDict,
320 summaryMetrics=standardSummary(withCount=False))
321 bundleList.append(bundle)
322 displayDict['order'] += 1
324 # Better version of the rapid revisit requirements: require a minimum number of visits between
325 # dtMin and dtMax, but also a minimum number of visits between dtMin and dtPair (the typical pair time).
326 # 1 means the healpix met the requirements (0 means did not).
327 dTmin = 40.0/60.0 # (minutes) 40s minumum for rapid revisit range
328 dTpairs = 20.0 # minutes (time when pairs should start kicking in)
329 dTmax = 30.0 # 30 minute maximum for rapid revisit range
330 nOne = 82 # Number of revisits between 40s-30m required
331 nTwo = 28 # Number of revisits between 40s - tPairs required.
332 pixArea = float(hp.nside2pixarea(nside, degrees=True))
333 scale = pixArea * hp.nside2npix(nside)
334 m1 = metrics.RapidRevisitMetric(metricName='RapidRevisits', mjdCol=colmap['mjd'],
335 dTmin=dTmin / 60.0 / 60.0 / 24.0, dTpairs = dTpairs / 60.0 / 24.0,
336 dTmax=dTmax / 60.0 / 24.0, minN1=nOne, minN2=nTwo)
337 plotDict = {'xMin': 0, 'xMax': 1, 'colorMin': 0, 'colorMax': 1, 'logScale': False}
338 cutoff1 = 0.9
339 summaryStats = [metrics.FracAboveMetric(cutoff=cutoff1, scale=scale, metricName='Area (sq deg)')]
340 caption = 'Rapid Revisit: area that receives at least %d visits between %.3f and %.1f minutes, ' \
341 % (nOne, dTmin, dTmax)
342 caption += 'with at least %d of those visits falling between %.3f and %.1f minutes. ' \
343 % (nTwo, dTmin, dTpairs)
344 caption += 'Summary statistic "Area" indicates the area on the sky which meets this requirement.' \
345 ' (SRD design specification is 2000 sq deg).'
346 displayDict['caption'] = caption
347 bundle = mb.MetricBundle(m1, slicer, sql, plotDict=plotDict, plotFuncs=subsetPlots,
348 stackerList=[ditherStacker],
349 metadata=metadata, displayDict=displayDict, summaryMetrics=summaryStats)
350 bundleList.append(bundle)
351 displayDict['order'] += 1
353 # Set the runName for all bundles and return the bundleDict.
354 for b in bundleList:
355 b.setRunName(runName)
356 return mb.makeBundlesDictFromList(bundleList)