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

1import numpy as np 

2from lsst.sims.utils import _approx_RaDec2AltAz, Site, _hpid2RaDec, m5_flat_sed 

3import healpy as hp 

4from lsst.sims.featureScheduler.utils import set_default_nside, match_hp_resolution, approx_altaz2pa 

5 

6__all__ = ['Conditions'] 

7 

8 

9class Conditions(object): 

10 """ 

11 Class to hold telemetry information 

12 

13 If the incoming value is a healpix map, we use a setter to ensure the 

14 resolution matches. 

15 

16 Unless otherwise noted, all values are assumed to be valid at the time 

17 given by self.mjd 

18 """ 

19 def __init__(self, nside=None, site='LSST', exptime=30.): 

20 """ 

21 Parameters 

22 ---------- 

23 nside : int 

24 The healpixel nside to set the resolution of attributes. 

25 site : str ('LSST') 

26 A site name used to create a sims.utils.Site object. For looking up 

27 observatory paramteres like latitude and longitude. 

28 expTime : float (30) 

29 The exposure time to assume when computing the 5-sigma limiting depth 

30 

31 Atributes (Set on init) 

32 ----------- 

33 nside : int 

34 Healpix resolution. All maps are set to this reslution. 

35 site : lsst.sims.Site object ('LSST') 

36 Contains static site-specific data (lat, lon, altitude, etc). Defaults to 'LSST'. 

37 ra : np.array 

38 A healpix array with the RA of each healpixel center (radians). Automatically 

39 generated. 

40 dec : np.array 

41 A healpix array with the Dec of each healpixel center (radians). Automatically generated. 

42 

43 Atributes (to be set by user/telemetry stream) 

44 ------------------------------------------- 

45 mjd : float 

46 Modified Julian Date (days). 

47 bulk_cloud : float 

48 The fraction of sky covered by clouds. (In the future might update to transparency map) 

49 cloud_map : np.array 

50 XXX--to be done. HEALpix array with cloudy pixels set to NaN. 

51 slewtime : np.array 

52 Healpix showing the slewtime to each healpixel center (seconds) 

53 current_filter : str 

54 The name of the current filter. (expect one of u, g, r, i, z, y). 

55 mounted_filters : list of str 

56 The filters that are currently mounted and thu available (expect 5 of u, g, r, i, z, y) 

57 night : int 

58 The current night number (days). Probably starts at 1. 

59 skybrightness : dict of np.array 

60 Dictionary keyed by filtername. Values are healpix arrays with the sky brightness at each 

61 healpix center (mag/acsec^2) 

62 FWHMeff : dict of np.array 

63 Dictionary keyed by filtername. Values are the effective seeing FWHM at each healpix 

64 center (arcseconds) 

65 moonAlt : float 

66 The altitude of the Moon (radians) 

67 moonAz : float 

68 The Azimuth of the moon (radians) 

69 moonRA : float 

70 RA of the moon (radians) 

71 moonDec : float 

72 Declination of the moon (radians) 

73 moonPhase : float 

74 The Phase of the moon. (percent, 0=new moon, 100=full moon) 

75 sunAlt : float 

76 The altitude of the sun (radians). 

77 sunAz : float 

78 The Azimuth of the sun (radians). 

79 sunRA : float 

80 The RA of the sun (radians). 

81 sunDec : float 

82 The Dec of the sun (radians). 

83 telRA : float 

84 The current telescope RA pointing (radians). 

85 telDec : float 

86 The current telescope Declination (radians). 

87 telAlt : float 

88 The current telescope altitude (radians). 

89 telAz : float 

90 The current telescope azimuth (radians). 

91 cloud_map : np.array 

92 A healpix map with the cloud coverage. XXX-expand, is this bool map? Transparency map? 

93 airmass : np.array 

94 A healpix map with the airmass value of each healpixel. (unitless) 

95 sunset : float 

96 The MJD of sunset that starts the current night. Note MJDs of sunset, moonset, twilight times, etc 

97 are from interpolations. This means the sun may actually be slightly above/below the horizon 

98 at the given sunset time. 

99 sun_n12_setting : float 

100 The MJD of when the sun is at -12 degees altitude and setting during the 

101 current night. From interpolation. 

102 sun_n18_setting : float 

103 The MJD when the sun is at -18 degrees altitude and setting during the current night. 

104 From interpolation. 

105 sun_n18_rising : float 

106 The MJD when the sun is at -18 degrees altitude and rising during the current night. 

107 From interpolation. 

108 sun_n12_rising : float 

109 The MJD when the sun is at -12 degrees altitude and rising during the current night. 

110 From interpolation. 

111 sunrise : float 

112 The MJD of sunrise during the current night. From interpolation 

113 moonrise : float 

114 The MJD of moonrise during the current night. From interpolation. 

115 moonset : float 

116 The MJD of moonset during the current night. From interpolation. 

117 targets_of_opportunity : list of lsst.sims.featureScheduler.targetoO object(s) 

118 targetoO objects. 

119 planet_positions : dict 

120 Dictionary of planet name and coordinate e.g., 'venus_RA', 'mars_dec' 

121 

122 Attributes (calculated on demand and cached) 

123 ------------------------------------------ 

124 alt : np.array 

125 Altitude of each healpixel (radians). Recaclulated if mjd is updated. Uses fast 

126 approximate equation for converting RA,Dec to alt,az. 

127 az : np.array 

128 Azimuth of each healpixel (radians). Recaclulated if mjd is updated. Uses fast 

129 approximate equation for converting RA,Dec to alt,az. 

130 pa : np.array 

131 The parallactic angle of each healpixel (radians). Recaclulated if mjd is updated. 

132 Based on the fast approximate alt,az values. 

133 lmst : float 

134 The local mean sidearal time (hours). Updates is mjd is changed. 

135 M5Depth : dict of np.array 

136 the 5-sigma limiting depth healpix maps, keyed by filtername (mags). Will be recalculated 

137 if the skybrightness, seeing, or airmass are updated. 

138 HA : np.array 

139 Healpix map of the hour angle of each healpixel (radians). 

140 az_to_sun : np.array 

141 Healpix map of the azimuthal distance to the sun for each healpixel (radians) 

142 

143 Attributes (set by the scheduler) 

144 ------------------------------- 

145 queue : list of observation objects 

146 The current queue of observations core_scheduler is waiting to execute. 

147 

148 """ 

149 if nside is None: 

150 nside = set_default_nside() 

151 self.nside = nside 

152 self.site = Site(site) 

153 self.exptime = exptime 

154 hpids = np.arange(hp.nside2npix(nside)) 

155 # Generate an empty map so we can copy when we need a new map 

156 self.zeros_map = np.zeros(hp.nside2npix(nside), dtype=float) 

157 self.nan_map = np.zeros(hp.nside2npix(nside), dtype=float) 

158 self.nan_map.fill(np.nan) 

159 # The RA, Dec grid we are using 

160 self.ra, self.dec = _hpid2RaDec(nside, hpids) 

161 

162 # Modified Julian Date (day) 

163 self._mjd = None 

164 # Altitude and azimuth. Dict with degrees and radians 

165 self._alt = None 

166 self._az = None 

167 self._pa = None 

168 # The cloud level. Fraction, but could upgrade to transparency map 

169 self.clouds = None 

170 self._slewtime = None 

171 self.current_filter = None 

172 self.mounted_filters = None 

173 self.night = None 

174 self._lmst = None 

175 # Should be a dict with filtername keys 

176 self._skybrightness = {} 

177 self._FWHMeff = {} 

178 self._M5Depth = None 

179 self._airmass = None 

180 

181 # Attribute to hold the current observing queue 

182 self.queue = None 

183 

184 # Moon 

185 self.moonAlt = None 

186 self.moonAz = None 

187 self.moonRA = None 

188 self.moonDec = None 

189 self.moonPhase = None 

190 

191 # Sun 

192 self.sunAlt = None 

193 self.sunAz = None 

194 self.sunRA = None 

195 self.sunDec = None 

196 

197 # Almanac information 

198 self.sunset = None 

199 self.sun_n12_setting = None 

200 self.sun_n18_setting = None 

201 self.sun_n18_rising = None 

202 self.sun_n12_rising = None 

203 self.sunrise = None 

204 self.moonrise = None 

205 self.moonset = None 

206 

207 self.planet_positions = None 

208 

209 # Current telescope pointing 

210 self.telRA = None 

211 self.telDec = None 

212 self.telAlt = None 

213 self.telAz = None 

214 

215 # Full sky cloud map 

216 self._cloud_map = None 

217 self._HA = None 

218 

219 # XXX--document 

220 self.bulk_cloud = None 

221 

222 self.rotTelPos = None 

223 

224 self.targets_of_opportunity = None 

225 

226 @property 

227 def lmst(self): 

228 return self._lmst 

229 

230 @lmst.setter 

231 def lmst(self, value): 

232 self._lmst = value 

233 self._HA = None 

234 

235 @property 

236 def HA(self): 

237 if self._HA is None: 

238 self.calc_HA() 

239 return self._HA 

240 

241 def calc_HA(self): 

242 self._HA = np.radians(self._lmst*360./24.) - self.ra 

243 self._HA[np.where(self._HA < 0)] += 2.*np.pi 

244 

245 @property 

246 def cloud_map(self): 

247 return self._cloud_map 

248 

249 @cloud_map.setter 

250 def cloud_map(self, value): 

251 self._cloud_map = match_hp_resolution(value, nside_out=self.nside) 

252 

253 @property 

254 def slewtime(self): 

255 return self._slewtime 

256 

257 @slewtime.setter 

258 def slewtime(self, value): 

259 # Using 0 for start of night 

260 if np.size(value) == 1: 

261 self._slewtime = value 

262 else: 

263 self._slewtime = match_hp_resolution(value, nside_out=self.nside) 

264 

265 @property 

266 def airmass(self): 

267 return self._airmass 

268 

269 @airmass.setter 

270 def airmass(self, value): 

271 self._airmass = match_hp_resolution(value, nside_out=self.nside) 

272 self._M5Depth = None 

273 

274 @property 

275 def pa(self): 

276 if self._pa is None: 

277 self.calc_pa() 

278 return self._pa 

279 

280 def calc_pa(self): 

281 self._pa = approx_altaz2pa(self.alt, self.az, self.site.latitude_rad) 

282 

283 @property 

284 def alt(self): 

285 if self._alt is None: 

286 self.calc_altAz() 

287 return self._alt 

288 

289 @property 

290 def az(self): 

291 if self._az is None: 

292 self.calc_altAz() 

293 return self._az 

294 

295 def calc_altAz(self): 

296 self._alt, self._az = _approx_RaDec2AltAz(self.ra, self.dec, 

297 self.site.latitude_rad, 

298 self.site.longitude_rad, self._mjd) 

299 

300 @property 

301 def mjd(self): 

302 return self._mjd 

303 

304 @mjd.setter 

305 def mjd(self, value): 

306 self._mjd = value 

307 # Set things that need to be recalculated to None 

308 self._az = None 

309 self._alt = None 

310 self._pa = None 

311 self._HA = None 

312 self._lmst = None 

313 self._az_to_sun = None 

314 

315 @property 

316 def skybrightness(self): 

317 return self._skybrightness 

318 

319 @skybrightness.setter 

320 def skybrightness(self, indict): 

321 for key in indict: 

322 

323 self._skybrightness[key] = match_hp_resolution(indict[key], nside_out=self.nside) 

324 # If sky brightness changes, need to recalc M5 depth. 

325 self._M5Depth = None 

326 

327 @property 

328 def FWHMeff(self): 

329 return self._FWHMeff 

330 

331 @FWHMeff.setter 

332 def FWHMeff(self, indict): 

333 for key in indict: 

334 self._FWHMeff[key] = match_hp_resolution(indict[key], nside_out=self.nside) 

335 self._M5Depth = None 

336 

337 @property 

338 def M5Depth(self): 

339 if self._M5Depth is None: 

340 self.calc_M5Depth() 

341 return self._M5Depth 

342 

343 def calc_M5Depth(self): 

344 self._M5Depth = {} 

345 for filtername in self._skybrightness: 

346 good = ~np.isnan(self._skybrightness[filtername]) 

347 self._M5Depth[filtername] = self.nan_map.copy() 

348 self._M5Depth[filtername][good] = m5_flat_sed(filtername, 

349 self._skybrightness[filtername][good], 

350 self._FWHMeff[filtername][good], 

351 self.exptime, 

352 self._airmass[good]) 

353 

354 def calc_az_to_sun(self): 

355 diff = np.abs(self.ra - self.sunRA) 

356 self._az_to_sun = diff 

357 self._az_to_sun[np.where(diff > np.pi)] = 2.*np.pi-diff[np.where(diff > np.pi)] 

358 

359 @property 

360 def az_to_sun(self): 

361 if self._az_to_sun is None: 

362 self.calc_az_to_sun() 

363 return self._az_to_sun