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 __future__ import print_function 

2import warnings 

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 metricBundles 

8from .colMapDict import ColMapDict 

9from .common import standardSummary 

10from .slewBatch import slewBasics 

11from .hourglassBatch import hourglassPlots 

12 

13__all__ = ['glanceBatch'] 

14 

15 

16def glanceBatch(colmap=None, runName='opsim', 

17 nside=64, filternames=('u', 'g', 'r', 'i', 'z', 'y'), 

18 nyears=10, pairnside=32, sqlConstraint=None, slicer_camera='LSST'): 

19 """Generate a handy set of metrics that give a quick overview of how well a survey performed. 

20 This is a meta-set of other batches, to some extent. 

21 

22 Parameters 

23 ---------- 

24 colmap : dict, opt 

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

26 run_name : str, opt 

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

28 nside : int, opt 

29 The nside for the healpix slicers. Default 64. 

30 filternames : list of str, opt 

31 The list of individual filters to use when running metrics. 

32 Default is ('u', 'g', 'r', 'i', 'z', 'y'). 

33 There is always an all-visits version of the metrics run as well. 

34 nyears : int (10) 

35 How many years to attempt to make hourglass plots for 

36 pairnside : int (32) 

37 nside to use for the pair fraction metric (it's slow, so nice to use lower resolution) 

38 sqlConstraint : str or None, opt 

39 Additional SQL constraint to apply to all metrics. 

40 slicer_camera : str ('LSST') 

41 Sets which spatial slicer to use. options are 'LSST' and 'ComCam' 

42 

43 Returns 

44 ------- 

45 metricBundleDict 

46 """ 

47 if isinstance(colmap, str): 

48 raise ValueError('colmap must be a dictionary, not a string') 

49 

50 if colmap is None: 

51 colmap = ColMapDict('opsimV4') 

52 

53 bundleList = [] 

54 

55 if sqlConstraint is None: 

56 sqlC = '' 

57 else: 

58 sqlC = '(%s) and' % sqlConstraint 

59 

60 if slicer_camera == 'LSST': 

61 spatial_slicer = slicers.HealpixSlicer 

62 elif slicer_camera == 'ComCam': 

63 spatial_slicer = slicers.HealpixComCamSlicer 

64 else: 

65 raise ValueError('Camera must be LSST or Comcam') 

66 

67 sql_per_filt = ['%s %s="%s"' % (sqlC, colmap['filter'], filtername) for filtername in filternames] 

68 sql_per_and_all_filters = [sqlConstraint] + sql_per_filt 

69 

70 standardStats = standardSummary() 

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

72 

73 # Super basic things 

74 displayDict = {'group': 'Basic Stats', 'order': 1} 

75 sql = sqlConstraint 

76 slicer = slicers.UniSlicer() 

77 # Length of Survey 

78 metric = metrics.FullRangeMetric(col=colmap['mjd'], metricName='Length of Survey (days)') 

79 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

80 bundleList.append(bundle) 

81 

82 # Total number of filter changes 

83 metric = metrics.NChangesMetric(col=colmap['filter'], orderBy=colmap['mjd']) 

84 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

85 bundleList.append(bundle) 

86 

87 # Total open shutter fraction 

88 metric = metrics.OpenShutterFractionMetric(slewTimeCol=colmap['slewtime'], 

89 expTimeCol=colmap['exptime'], 

90 visitTimeCol=colmap['visittime']) 

91 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

92 bundleList.append(bundle) 

93 

94 # Total effective exposure time 

95 metric = metrics.TeffMetric(m5Col=colmap['fiveSigmaDepth'], 

96 filterCol=colmap['filter'], normed=True) 

97 for sql in sql_per_and_all_filters: 

98 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

99 bundleList.append(bundle) 

100 

101 # Number of observations, all and each filter 

102 metric = metrics.CountMetric(col=colmap['mjd'], metricName='Number of Exposures') 

103 for sql in sql_per_and_all_filters: 

104 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

105 bundleList.append(bundle) 

106 

107 # The alt/az plots of all the pointings 

108 slicer = spatial_slicer(nside=nside, latCol=colmap['alt'], 

109 lonCol=colmap['az'], latLonDeg=colmap['raDecDeg'], useCache=False) 

110 metric = metrics.CountMetric(colmap['mjd'], metricName='Nvisits as function of Alt/Az') 

111 plotFuncs = [plots.LambertSkyMap()] 

112 

113 plotDict = {'norm': 'log'} 

114 for sql in sql_per_and_all_filters: 

115 bundle = metricBundles.MetricBundle(metric, slicer, sql, plotFuncs=plotFuncs, 

116 displayDict=displayDict, plotDict=plotDict) 

117 bundleList.append(bundle) 

118 

119 # Things to check per night 

120 # Open Shutter per night 

121 displayDict = {'group': 'Pointing Efficency', 'order': 2} 

122 slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=1) 

123 metric = metrics.OpenShutterFractionMetric(slewTimeCol=colmap['slewtime'], 

124 expTimeCol=colmap['exptime'], 

125 visitTimeCol=colmap['visittime']) 

126 sql = sqlConstraint 

127 bundle = metricBundles.MetricBundle(metric, slicer, sql, 

128 summaryMetrics=standardStats, displayDict=displayDict) 

129 bundleList.append(bundle) 

130 

131 # Number of filter changes per night 

132 slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=1) 

133 metric = metrics.NChangesMetric(col=colmap['filter'], orderBy=colmap['mjd'], 

134 metricName='Filter Changes') 

135 bundle = metricBundles.MetricBundle(metric, slicer, sql, 

136 summaryMetrics=standardStats, displayDict=displayDict) 

137 bundleList.append(bundle) 

138 

139 # A few basic maps 

140 # Number of observations, coadded depths 

141 extended_stats = standardStats.copy() 

142 extended_stats.append(metrics.AreaSummaryMetric(decreasing=True, metricName='top18k')) 

143 extended_stats.append(metrics.PercentileMetric(col='metricdata', percentile=10)) 

144 displayDict = {'group': 'Basic Maps', 'order': 3} 

145 slicer = spatial_slicer(nside=nside, latCol=colmap['dec'], lonCol=colmap['ra'], 

146 latLonDeg=colmap['raDecDeg']) 

147 metric = metrics.CountMetric(col=colmap['mjd']) 

148 plotDict = {'percentileClip': 95.} 

149 for sql in sql_per_and_all_filters: 

150 bundle = metricBundles.MetricBundle(metric, slicer, sql, 

151 summaryMetrics=extended_stats, 

152 displayDict=displayDict, 

153 plotDict=plotDict) 

154 bundleList.append(bundle) 

155 

156 metric = metrics.Coaddm5Metric(m5Col=colmap['fiveSigmaDepth']) 

157 for sql in sql_per_and_all_filters: 

158 bundle = metricBundles.MetricBundle(metric, slicer, sql, 

159 summaryMetrics=extended_stats, displayDict=displayDict) 

160 bundleList.append(bundle) 

161 

162 # Checking a few basic science things 

163 # Maybe check astrometry, observation pairs, SN 

164 plotDict = {'percentileClip': 95.} 

165 displayDict = {'group': 'Science', 'subgroup': 'Astrometry', 'order': 4} 

166 

167 stackerList = [] 

168 stacker = stackers.ParallaxFactorStacker(raCol=colmap['ra'], 

169 decCol=colmap['dec'], 

170 degrees=colmap['raDecDeg'], 

171 dateCol=colmap['mjd']) 

172 stackerList.append(stacker) 

173 

174 astrom_stats = [metrics.AreaSummaryMetric(decreasing=False, metricName='best18k'), 

175 metrics.PercentileMetric(col='metricdata', percentile=90)] 

176 # Maybe parallax and proper motion, fraction of visits in a good pair for SS 

177 displayDict['caption'] = r'Parallax precision of an $r=20$ flat SED star' 

178 metric = metrics.ParallaxMetric(m5Col=colmap['fiveSigmaDepth'], 

179 filterCol=colmap['filter'], 

180 seeingCol=colmap['seeingGeom']) 

181 sql = sqlConstraint 

182 bundle = metricBundles.MetricBundle(metric, slicer, sql, plotFuncs=subsetPlots, 

183 displayDict=displayDict, stackerList=stackerList, 

184 plotDict=plotDict, 

185 summaryMetrics=astrom_stats) 

186 bundleList.append(bundle) 

187 displayDict['caption'] = r'Proper motion precision of an $r=20$ flat SED star' 

188 metric = metrics.ProperMotionMetric(m5Col=colmap['fiveSigmaDepth'], 

189 mjdCol=colmap['mjd'], 

190 filterCol=colmap['filter'], 

191 seeingCol=colmap['seeingGeom']) 

192 bundle = metricBundles.MetricBundle(metric, slicer, sql, plotFuncs=subsetPlots, 

193 displayDict=displayDict, plotDict=plotDict, 

194 summaryMetrics=astrom_stats) 

195 bundleList.append(bundle) 

196 

197 # Solar system stuff 

198 displayDict['caption'] = 'Fraction of observations that are in pairs' 

199 displayDict['subgroup'] = 'Solar System' 

200 

201 sql = '%s (filter="g" or filter="r" or filter="i")' % sqlC 

202 pairSlicer = slicers.HealpixSlicer(nside=pairnside, latCol=colmap['dec'], lonCol=colmap['ra'], 

203 latLonDeg=colmap['raDecDeg']) 

204 metric = metrics.PairFractionMetric(mjdCol=colmap['mjd']) 

205 bundle = metricBundles.MetricBundle(metric, pairSlicer, sql, plotFuncs=subsetPlots, 

206 displayDict=displayDict) 

207 bundleList.append(bundle) 

208 

209 # stats from the note column 

210 if 'note' in colmap.keys(): 

211 displayDict = {'group': 'Basic Stats', 'subgroup': 'Percent stats'} 

212 metric = metrics.StringCountMetric(col=colmap['note'], percent=True, metricName='Percents') 

213 sql = '' 

214 slicer = slicers.UniSlicer() 

215 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

216 bundleList.append(bundle) 

217 displayDict['subgroup'] = 'Count Stats' 

218 metric = metrics.StringCountMetric(col=colmap['note'], metricName='Counts') 

219 bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict) 

220 bundleList.append(bundle) 

221 

222 for b in bundleList: 

223 b.setRunName(runName) 

224 

225 bd = metricBundles.makeBundlesDictFromList(bundleList) 

226 

227 # Add hourglass plots. 

228 hrDict = hourglassPlots(colmap=colmap, runName=runName, nyears=nyears, extraSql=sqlConstraint) 

229 bd.update(hrDict) 

230 # Add basic slew stats. 

231 try: 

232 slewDict = slewBasics(colmap=colmap, runName=runName) 

233 bd.update(slewDict) 

234 except KeyError as e: 

235 warnings.warn('Could not add slew stats: missing required key %s from colmap' % (e)) 

236 

237 return bd 

238