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 lsst.sims.featureScheduler.detailers import Base_detailer 

2from lsst.sims.utils import _raDec2Hpid, m5_flat_sed 

3import numpy as np 

4import healpy as hp 

5 

6__all__ = ["Vary_expt_detailer", "calc_target_m5s"] 

7 

8 

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)) 

18 

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) 

23 

24 return goal_m5 

25 

26 

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. 

30 

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. 

40 

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 

59 

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 

67 

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.') 

91 

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) 

96 

97 for i, observation in enumerate(observation_list): 

98 observation['exptime'] = new_expts[i] 

99 

100 return observation_list