Coverage for python/lsst/sims/featureScheduler/features/conditions.py : 20%

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
6__all__ = ['Conditions']
9class Conditions(object):
10 """
11 Class to hold telemetry information
13 If the incoming value is a healpix map, we use a setter to ensure the
14 resolution matches.
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
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.
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'
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)
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.
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)
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
181 # Attribute to hold the current observing queue
182 self.queue = None
184 # Moon
185 self.moonAlt = None
186 self.moonAz = None
187 self.moonRA = None
188 self.moonDec = None
189 self.moonPhase = None
191 # Sun
192 self.sunAlt = None
193 self.sunAz = None
194 self.sunRA = None
195 self.sunDec = None
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
207 self.planet_positions = None
209 # Current telescope pointing
210 self.telRA = None
211 self.telDec = None
212 self.telAlt = None
213 self.telAz = None
215 # Full sky cloud map
216 self._cloud_map = None
217 self._HA = None
219 # XXX--document
220 self.bulk_cloud = None
222 self.rotTelPos = None
224 self.targets_of_opportunity = None
226 @property
227 def lmst(self):
228 return self._lmst
230 @lmst.setter
231 def lmst(self, value):
232 self._lmst = value
233 self._HA = None
235 @property
236 def HA(self):
237 if self._HA is None:
238 self.calc_HA()
239 return self._HA
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
245 @property
246 def cloud_map(self):
247 return self._cloud_map
249 @cloud_map.setter
250 def cloud_map(self, value):
251 self._cloud_map = match_hp_resolution(value, nside_out=self.nside)
253 @property
254 def slewtime(self):
255 return self._slewtime
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)
265 @property
266 def airmass(self):
267 return self._airmass
269 @airmass.setter
270 def airmass(self, value):
271 self._airmass = match_hp_resolution(value, nside_out=self.nside)
272 self._M5Depth = None
274 @property
275 def pa(self):
276 if self._pa is None:
277 self.calc_pa()
278 return self._pa
280 def calc_pa(self):
281 self._pa = approx_altaz2pa(self.alt, self.az, self.site.latitude_rad)
283 @property
284 def alt(self):
285 if self._alt is None:
286 self.calc_altAz()
287 return self._alt
289 @property
290 def az(self):
291 if self._az is None:
292 self.calc_altAz()
293 return self._az
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)
300 @property
301 def mjd(self):
302 return self._mjd
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
315 @property
316 def skybrightness(self):
317 return self._skybrightness
319 @skybrightness.setter
320 def skybrightness(self, indict):
321 for key in indict:
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
327 @property
328 def FWHMeff(self):
329 return self._FWHMeff
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
337 @property
338 def M5Depth(self):
339 if self._M5Depth is None:
340 self.calc_M5Depth()
341 return self._M5Depth
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])
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)]
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