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 slew metrics. 

2""" 

3import warnings 

4import numpy as np 

5import lsst.sims.maf.metrics as metrics 

6import lsst.sims.maf.slicers as slicers 

7import lsst.sims.maf.metricBundles as mb 

8from .colMapDict import ColMapDict 

9from .common import standardMetrics, combineMetadata 

10 

11__all__ = ['slewBasics', 'slewAngles', 'slewSpeeds', 'slewActivities'] 

12 

13 

14def slewBasics(colmap=None, runName='opsim', sqlConstraint=None): 

15 """Generate a simple set of statistics about the slew times and distances. 

16 These slew statistics can be run on the summary or default tables. 

17 

18 Parameters 

19 ---------- 

20 colmap : dict or None, opt 

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

22 runName : str, opt 

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

24 sqlConstraint : str or None, opt 

25 SQL constraint to add to metrics. (note this runs on summary table). 

26 

27 Returns 

28 ------- 

29 metricBundleDict 

30 """ 

31 

32 if colmap is None: 

33 colmap = ColMapDict('opsimV4') 

34 

35 bundleList = [] 

36 

37 # Calculate basic stats on slew times. (mean/median/min/max + total). 

38 slicer = slicers.UniSlicer() 

39 

40 metadata = 'All visits' 

41 if sqlConstraint is not None and len(sqlConstraint) > 0: 

42 metadata = '%s' % (sqlConstraint) 

43 displayDict = {'group': 'Slew', 'subgroup': 'Slew Basics', 'order': -1, 'caption': None} 

44 # Add total number of slews. 

45 metric = metrics.CountMetric(colmap['slewtime'], metricName='Slew Count') 

46 displayDict['caption'] = 'Total number of slews recorded in summary table.' 

47 displayDict['order'] += 1 

48 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, metadata=metadata, displayDict=displayDict) 

49 bundleList.append(bundle) 

50 for metric in standardMetrics(colmap['slewtime']): 

51 displayDict['caption'] = '%s in seconds.' % (metric.name) 

52 displayDict['order'] += 1 

53 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, metadata=metadata, displayDict=displayDict) 

54 bundleList.append(bundle) 

55 

56 # Slew Time histogram. 

57 slicer = slicers.OneDSlicer(sliceColName=colmap['slewtime'], binsize=2) 

58 metric = metrics.CountMetric(col=colmap['slewtime'], metricName='Slew Time Histogram') 

59 metadata = 'All visits' 

60 plotDict = {'logScale': True, 'ylabel': 'Count'} 

61 displayDict['caption'] = 'Histogram of slew times (seconds) for all visits.' 

62 displayDict['order'] += 1 

63 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, metadata=metadata, 

64 plotDict=plotDict, displayDict=displayDict) 

65 bundleList.append(bundle) 

66 # Zoom in on slew time histogram near 0. 

67 slicer = slicers.OneDSlicer(sliceColName=colmap['slewtime'], binsize=0.2, binMin=0, binMax=20) 

68 metric = metrics.CountMetric(col=colmap['slewtime'], metricName='Zoom Slew Time Histogram') 

69 metadata = 'All visits' 

70 plotDict = {'logScale': True, 'ylabel': 'Count'} 

71 displayDict['caption'] = 'Histogram of slew times (seconds) for all visits (zoom).' 

72 displayDict['order'] += 1 

73 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, metadata=metadata, 

74 plotDict=plotDict, displayDict=displayDict) 

75 bundleList.append(bundle) 

76 

77 # Slew distance histogram, if available. 

78 if colmap['slewdist'] is not None: 

79 binsize = 2.0 

80 if not colmap['raDecDeg']: 

81 binsize = np.radians(binsize) 

82 slicer = slicers.OneDSlicer(sliceColName=colmap['slewdist'], binsize=binsize) 

83 metric = metrics.CountMetric(col=colmap['slewdist'], metricName='Slew Distance Histogram') 

84 plotDict = {'logScale': True, 'ylabel': 'Count'} 

85 displayDict['caption'] = 'Histogram of slew distances (angle) for all visits.' 

86 displayDict['order'] += 1 

87 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, metadata=metadata, 

88 plotDict=plotDict, displayDict=displayDict) 

89 bundleList.append(bundle) 

90 # Zoom on slew distance histogram. 

91 binMax = 20.0 

92 if not colmap['raDecDeg']: 

93 binMax = np.radians(binMax) 

94 slicer = slicers.OneDSlicer(sliceColName=colmap['slewdist'], binsize=binsize/10., 

95 binMin=0, binMax=binMax) 

96 metric = metrics.CountMetric(col=colmap['slewdist'], metricName='Zoom Slew Distance Histogram') 

97 plotDict = {'logScale': True, 'ylabel': 'Count'} 

98 displayDict['caption'] = 'Histogram of slew distances (angle) for all visits.' 

99 displayDict['order'] += 1 

100 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, metadata=metadata, 

101 plotDict=plotDict, displayDict=displayDict) 

102 bundleList.append(bundle) 

103 

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

105 for b in bundleList: 

106 b.setRunName(runName) 

107 return mb.makeBundlesDictFromList(bundleList) 

108 

109 

110def slewAngles(colmap=None, runName='opsim', sqlConstraint=None): 

111 """Generate a set of slew statistics focused on the angles of each component (dome and telescope). 

112 These slew statistics must be run on the SlewFinalState or SlewInitialState table in opsimv4, 

113 and on the SlewState table in opsimv3. 

114 

115 Parameters 

116 ---------- 

117 colmap : dict or None, opt 

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

119 runName : str, opt 

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

121 sqlConstraint : str or None, opt 

122 SQL constraint to apply to metrics. Note this runs on Slew*State table, so constraints 

123 should generally be based on slew_slewCount. 

124 

125 Returns 

126 ------- 

127 metricBundleDict 

128 """ 

129 if colmap is None: 

130 colmap = ColMapDict('opsimV4') 

131 bundleList = [] 

132 

133 # All of these metrics are run with a unislicer. 

134 slicer = slicers.UniSlicer() 

135 

136 # For each angle, we will compute mean/median/min/max and rms. 

137 # Note that these angles can range over more than 360 degrees, because of cable wrap. 

138 # This is why we're not using the Angle metrics - here 380 degrees is NOT the same as 20 deg. 

139 # Stats for angle: 

140 angles = ['Tel Alt', 'Tel Az', 'Rot Tel Pos'] 

141 

142 displayDict = {'group': 'Slew', 'subgroup': 'Slew Angles', 'order': -1, 'caption': None} 

143 for angle in angles: 

144 metadata = combineMetadata(angle, sqlConstraint) 

145 metriclist = standardMetrics(colmap[angle], replace_colname='') 

146 metriclist += [metrics.RmsMetric(colmap[angle], metricName='RMS')] 

147 for metric in metriclist: 

148 displayDict['caption'] = '%s %s' % (metric.name, angle) 

149 displayDict['order'] += 1 

150 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, 

151 displayDict=displayDict, metadata=metadata) 

152 bundleList.append(bundle) 

153 

154 for b in bundleList: 

155 b.setRunName(runName) 

156 return mb.makeBundlesDictFromList(bundleList) 

157 

158 

159def slewSpeeds(colmap=None, runName='opsim', sqlConstraint=None): 

160 """Generate a set of slew statistics focused on the speeds of each component (dome and telescope). 

161 These slew statistics must be run on the SlewMaxSpeeds table in opsimv4 and opsimv3. 

162 

163 Parameters 

164 ---------- 

165 colmap : dict or None, opt 

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

167 Note that for these metrics, the column names are distinctly different in v3/v4. 

168 runName : str, opt 

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

170 sqlConstraint : str or None, opt 

171 SQL constraint to apply to metrics. Note this runs on Slew*State table, so constraints 

172 should generally be based on slew_slewCount. 

173 

174 Returns 

175 ------- 

176 metricBundleDict 

177 """ 

178 if colmap is None: 

179 colmap = ColMapDict('opsimV4') 

180 bundleList = [] 

181 

182 # All of these metrics run with a unislicer, on all the slew data. 

183 slicer = slicers.UniSlicer() 

184 

185 speeds = ['Dome Alt Speed', 'Dome Az Speed', 'Tel Alt Speed', 'Tel Az Speed', 'Rotator Speed'] 

186 

187 displayDict = {'group': 'Slew', 'subgroup': 'Slew Speeds', 'order': -1, 'caption': None} 

188 for speed in speeds: 

189 metadata = combineMetadata(speed, sqlConstraint) 

190 metric = metrics.AbsMaxMetric(col=colmap[speed], metricName='Max (Abs)') 

191 displayDict['caption'] = 'Maximum absolute value of %s.' % speed 

192 displayDict['order'] += 1 

193 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, displayDict=displayDict, metadata=metadata) 

194 bundleList.append(bundle) 

195 

196 metric = metrics.AbsMeanMetric(col=colmap[speed], metricName='Mean (Abs)') 

197 displayDict['caption'] = 'Mean absolute value of %s.' % speed 

198 displayDict['order'] += 1 

199 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, displayDict=displayDict, metadata=metadata) 

200 bundleList.append(bundle) 

201 

202 metric = metrics.AbsMaxPercentMetric(col=colmap[speed], metricName='% @ Max') 

203 displayDict['caption'] = 'Percent of slews at the maximum %s (absolute value).' % speed 

204 displayDict['order'] += 1 

205 bundle = mb.MetricBundle(metric, slicer, sqlConstraint, displayDict=displayDict, metadata=metadata) 

206 bundleList.append(bundle) 

207 

208 for b in bundleList: 

209 b.setRunName(runName) 

210 

211 return mb.makeBundlesDictFromList(bundleList) 

212 

213 

214def slewActivities(colmap=None, runName='opsim', totalSlewN=1, sqlConstraint=None): 

215 """Generate a set of slew statistics focused on finding the contributions to the overall slew time. 

216 These slew statistics must be run on the SlewActivities table in opsimv4 and opsimv3. 

217 

218 Note that the type of activities listed are different between v3 and v4. 

219 

220 Parameters 

221 ---------- 

222 colmap : dict or None, opt 

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

224 runName : str, opt 

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

226 totalSlewN : int, opt 

227 The total number of slews in the simulated survey. 

228 Used to calculate % of slew activities for each component. 

229 Default is 1. 

230 sqlConstraint : str or None, opt 

231 SQL constraint to apply to metrics. Note this runs on Slew*State table, so constraints 

232 should generally be based on slew_slewCount. 

233 

234 

235 Returns 

236 ------- 

237 metricBundleDict 

238 """ 

239 if totalSlewN == 1: 

240 warnings.warn('TotalSlewN should be set (using 1). Percents from activities may be incorrect.') 

241 

242 if colmap is None: 

243 colmap = ColMapDict('opsimV4') 

244 bundleList = [] 

245 

246 # All of these metrics run with a unislicer, on all the slew data. 

247 slicer = slicers.UniSlicer() 

248 

249 if 'slewactivities' not in colmap: 

250 raise ValueError("List of slewactivities not in colmap! Will not create slewActivities bundles.") 

251 

252 slewTypeDict = colmap['slewactivities'] 

253 

254 displayDict = {'group': 'Slew', 'subgroup': 'Slew Activities', 'order': -1, 'caption': None} 

255 

256 for slewType in slewTypeDict: 

257 metadata = combineMetadata(slewType, sqlConstraint) 

258 tableValue = slewTypeDict[slewType] 

259 

260 # Metrics for all activities of this type. 

261 sql = 'activityDelay>0 and activity="%s"' % tableValue 

262 if sqlConstraint is not None: 

263 sql = '(%s) and (%s)' % (sql, sqlConstraint) 

264 

265 # Percent of slews which include this activity. 

266 metric = metrics.CountRatioMetric(col='activityDelay', normVal=totalSlewN / 100.0, 

267 metricName='ActivePerc') 

268 displayDict['caption'] = 'Percent of total slews which include %s movement.' % slewType 

269 displayDict['order'] += 1 

270 bundle = mb.MetricBundle(metric, slicer, sql, displayDict=displayDict, metadata=metadata) 

271 bundleList.append(bundle) 

272 

273 # Mean time for this activity, in all slews. 

274 metric = metrics.MeanMetric(col='activityDelay', metricName='Ave T(s)') 

275 displayDict['caption'] = 'Mean amount of time (in seconds) for %s movements.' % (slewType) 

276 displayDict['order'] += 1 

277 bundle = mb.MetricBundle(metric, slicer, sql, displayDict=displayDict, metadata=metadata) 

278 bundleList.append(bundle) 

279 

280 # Maximum time for this activity, in all slews. 

281 metric = metrics.MaxMetric(col='activityDelay', metricName='Max T(s)') 

282 displayDict['caption'] = 'Max amount of time (in seconds) for %s movement.' % (slewType) 

283 displayDict['order'] += 1 

284 bundle = mb.MetricBundle(metric, slicer, sql, displayDict=displayDict, metadata=metadata) 

285 bundleList.append(bundle) 

286 

287 # Metrics for activities of this type which are in the critical path. 

288 sql = 'activityDelay>0 and inCriticalPath="True" and activity="%s"' % tableValue 

289 if sqlConstraint is not None: 

290 sql = '(%s) and (%s)' % (sql, sqlConstraint) 

291 

292 # Percent of slews which include this activity in the critical path. 

293 metric = metrics.CountRatioMetric(col='activityDelay', normVal=totalSlewN / 100.0, 

294 metricName='ActivePerc in crit') 

295 displayDict['caption'] = 'Percent of total slew which include %s movement, ' \ 

296 'and are in critical path.' % (slewType) 

297 displayDict['order'] += 1 

298 bundle = mb.MetricBundle(metric, slicer, sql, displayDict=displayDict, metadata=metadata) 

299 bundleList.append(bundle) 

300 

301 # Mean time for slews which include this activity, in the critical path. 

302 metric = metrics.MeanMetric(col='activityDelay', metricName='Ave T(s) in crit') 

303 displayDict['caption'] = 'Mean time (in seconds) for %s movements, ' \ 

304 'when in critical path.' % (slewType) 

305 displayDict['order'] += 1 

306 bundle = mb.MetricBundle(metric, slicer, sql, displayDict=displayDict, metadata=metadata) 

307 bundleList.append(bundle) 

308 

309 # Total time that this activity was in the critical path. 

310 metric = metrics.SumMetric(col='activityDelay', metricName='Total T(s) in crit') 

311 displayDict['caption'] = 'Total time (in seconds) for %s movements, ' \ 

312 'when in critical path.' % (slewType) 

313 displayDict['order'] += 1 

314 bundle = mb.MetricBundle(metric, slicer, sql, displayDict=displayDict, metadata=metadata) 

315 bundleList.append(bundle) 

316 

317 for b in bundleList: 

318 b.setRunName(runName) 

319 return mb.makeBundlesDictFromList(bundleList)