Coverage for python/lsst/sims/featureScheduler/detailers/vary_exptime.py : 16%

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 lsst.sims.featureScheduler.detailers import Base_detailer
2from lsst.sims.utils import _raDec2Hpid, m5_flat_sed
3import numpy as np
4import healpy as hp
6__all__ = ["Vary_expt_detailer", "calc_target_m5s"]
9def calc_target_m5s(alt=65., fiducial_seeing=0.9, exptime=20.):
10 """
11 Use the skybrightness model to find some good target m5s
12 """
13 import lsst.sims.skybrightness as sb
14 sm = sb.SkyModel(moon=False, twilight=False, mags=True)
15 sm.setRaDecMjd(np.array([0.]), np.array([alt]), 49353.177645, degrees=True, azAlt=True)
16 sky_mags = sm.returnMags()
17 airmass = 1./np.cos(np.pi/2.-np.radians(alt))
19 goal_m5 = {}
20 for filtername in sky_mags:
21 goal_m5[filtername] = m5_flat_sed(filtername, sky_mags[filtername], fiducial_seeing,
22 exptime, airmass)
24 return goal_m5
27class Vary_expt_detailer(Base_detailer):
28 """
29 Detailer to vary the exposure time on observations to try and keep each observation at uniform depth.
31 Parameters
32 ----------
33 min_expt : float (20.)
34 The minimum exposure time to use (seconds).
35 max_expt : float(100.)
36 The maximum exposure time to use
37 target_m5 : dict (None)
38 Dictionary with keys of filternames as str and target 5-sigma depth values as floats.
39 If none, the target_m5s are set to a min_expt exposure at X=1.1 in dark time.
41 """
42 def __init__(self, nside=32, min_expt=20., max_expt=100., target_m5=None):
43 """
44 """
45 # Dict to hold all the features we want to track
46 self.survey_features = {}
47 self.nside = nside
48 self.min_exp = min_expt
49 self.max_exp = max_expt
50 if target_m5 is None:
51 self.target_m5 = {'g': 24.381615425253738,
52 'i': 23.41810142458083,
53 'r': 23.964359143049755,
54 'u': 22.978794343692783,
55 'y': 21.755612950787068,
56 'z': 22.80377793629767}
57 else:
58 self.target_m5 = target_m5
60 def __call__(self, observation_list, conditions):
61 """
62 Parameters
63 ----------
64 observation_list : list of observations
65 The observations to detail.
66 conditions : lsst.sims.featureScheduler.conditions object
68 Returns
69 -------
70 List of observations.
71 """
72 obs_array = np.concatenate(observation_list)
73 hpids = _raDec2Hpid(self.nside, obs_array['RA'], obs_array['dec'])
74 new_expts = np.zeros(obs_array.size, dtype=float)
75 for filtername in np.unique(obs_array['filter']):
76 in_filt = np.where(obs_array['filter'] == filtername)
77 delta_m5 = self.target_m5[filtername] - conditions.M5Depth[filtername][hpids[in_filt]]
78 # We can get NaNs because dithering pushes the center of the pointing into masked regions.
79 nan_indices = np.argwhere(np.isnan(delta_m5)).ravel()
80 for indx in nan_indices:
81 bad_hp = hpids[in_filt][indx]
82 # Note this might fail if we run at higher resolution, then we'd need to look farther for
83 # pixels to interpolate.
84 near_pix = hp.get_all_neighbours(conditions.nside, bad_hp)
85 vals = conditions.M5Depth[filtername][near_pix]
86 if True in np.isfinite(vals):
87 estimate_m5 = np.mean(vals[np.isfinite(vals)])
88 delta_m5[indx] = self.target_m5[filtername] - estimate_m5
89 else:
90 raise ValueError('Failed to find a nearby unmasked sky value.')
92 new_expts[in_filt] = conditions.exptime * 10**(delta_m5/1.25)
93 new_expts = np.clip(new_expts, self.min_exp, self.max_exp)
94 # I'm not sure what level of precision we can expect, so let's just limit to seconds
95 new_expts = np.round(new_expts)
97 for i, observation in enumerate(observation_list):
98 observation['exptime'] = new_expts[i]
100 return observation_list