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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

import numpy as np 

from lsst.sims.featureScheduler.surveys import BaseSurvey 

import copy 

import lsst.sims.featureScheduler.basis_functions as basis_functions 

from lsst.sims.featureScheduler.utils import empty_observation 

import healpy as hp 

import random 

 

 

__all__ = ['DESC_ddf', 'generate_desc_dd_surveys'] 

 

 

class DESC_ddf(BaseSurvey): 

"""DDF survey based on Scolnic et al Cadence White Paper. 

""" 

def __init__(self, basis_functions, RA, dec, sequences=None, 

exptime=30., nexp=1, ignore_obs=None, survey_name='DD_DESC', 

reward_value=101., readtime=2., filter_change_time=120., 

nside=None, flush_pad=30., seed=42, detailers=None): 

super(DESC_ddf, self).__init__(nside=nside, basis_functions=basis_functions, 

detailers=detailers, ignore_obs=ignore_obs) 

 

self.ra = np.radians(RA) 

self.ra_hours = RA/360.*24. 

self.dec = np.radians(dec) 

self.survey_name = survey_name 

self.reward_value = reward_value 

self.flush_pad = flush_pad/60./24. # To days 

self.sequence = True # Specifies the survey gives sequence of observations 

 

self.simple_obs = empty_observation() 

self.simple_obs['RA'] = np.radians(RA) 

self.simple_obs['dec'] = np.radians(dec) 

self.simple_obs['exptime'] = exptime 

self.simple_obs['nexp'] = nexp 

self.simple_obs['note'] = survey_name 

 

# Define the sequences we would like to do 

if sequences is None: 

self.sequences = [{'g': 2, 'r': 4, 'i': 8}, {'z': 25, 'y': 4}, None] 

else: 

self.sequences = sequences 

 

self.approx_times = [] 

for sequence in self.sequences: 

if sequence is None: 

self.approx_times.append(0) 

else: 

n_exp_in_seq = np.sum(list(sequence.values())) 

time_needed = filter_change_time*len(sequence.keys()) 

time_needed += exptime*n_exp_in_seq 

time_needed += readtime*n_exp_in_seq*nexp 

self.approx_times.append(time_needed/3600./24.) 

 

# Track what we last tried to do 

# XXX-this should probably go into self.extra_features or something for consistency. 

self.sequence_index = 0 

self.last_night_observed = -100 

 

def check_continue(self, observation, conditions): 

# feasibility basis functions? 

''' 

This method enables external calls to check if a given observations that belongs to this survey is 

feasible or not. This is called once a sequence has started to make sure it can continue. 

 

XXX--TODO: Need to decide if we want to develope check_continue, or instead hold the  

sequence in the survey, and be able to check it that way. 

''' 

 

result = True 

return result 

 

def _check_feasibility(self, conditions): 

""" 

Check if the survey is feasable in the current conditions 

""" 

 

# No more if we've already observed this night 

if self.last_night_observed == conditions.night: 

return False 

 

# Advance the sequence index if we have skipped a day intentionally 

if (self.sequences[self.sequence_index] is None) & (conditions.night-self.last_night_observed > 1): 

self.sequence_index = (self.sequence_index + 1) % len(self.sequences) 

 

# If we want to skip this day 

if self.sequences[self.sequence_index] is None: 

return False 

 

# The usual basis function checks 

for bf in self.basis_functions: 

result = bf.check_feasibility(conditions) 

if not result: 

return result 

return result 

 

def calc_reward_function(self, conditions): 

result = -np.inf 

if self._check_feasibility(conditions): 

result = self.reward_value 

return result 

 

def generate_observations_rough(self, conditions): 

result = [] 

for key in self.sequences[self.sequence_index]: 

# Just skip adding the z-band ones if it's not loaded 

if key in conditions.mounted_filters: 

for i in np.arange(self.sequences[self.sequence_index][key]): 

temp_obs = self.simple_obs.copy() 

temp_obs['filter'] = key 

# XXX--need to set flush by mjd 

result.append(temp_obs) 

for i, obs in enumerate(result): 

result[i]['flush_by_mjd'] = conditions.mjd + self.approx_times[self.sequence_index] + self.flush_pad 

# Just assuming this sequence gets observed. 

self.last_night_observed = conditions.night 

self.sequence_index = (self.sequence_index + 1) % len(self.sequences) 

return result 

 

 

def desc_dd_bfs(RA, dec, survey_name, ha_limits, frac_total=0.0185): 

""" 

Convienence function to generate all the feasibility basis functions 

""" 

bfs = [] 

bfs.append(basis_functions.Not_twilight_basis_function(sun_alt_limit=-18)) 

bfs.append(basis_functions.Time_to_twilight_basis_function(time_needed=30.)) 

bfs.append(basis_functions.Hour_Angle_limit_basis_function(RA=RA, ha_limits=ha_limits)) 

bfs.append(basis_functions.Rising_more_basis_function(RA=RA)) 

bfs.append(basis_functions.Clouded_out_basis_function()) 

 

return bfs 

 

 

def generate_desc_dd_surveys(nside=None, nexp=1, detailers=None): 

surveys = [] 

 

# ELAIS S1 

RA = 9.45 

dec = -44. 

survey_name = 'DD:ELAISS1' 

ha_limits = ([0., 1.18], [21.82, 24.]) 

bfs = desc_dd_bfs(RA, dec, survey_name, ha_limits) 

surveys.append(DESC_ddf(bfs, RA, dec, survey_name=survey_name, reward_value=100, 

nside=nside, nexp=nexp, detailers=detailers)) 

 

# XMM-LSS 

survey_name = 'DD:XMM-LSS' 

RA = 35.708333 

dec = -4-45/60. 

ha_limits = ([0., 1.3], [21.7, 24.]) 

bfs = desc_dd_bfs(RA, dec, survey_name, ha_limits) 

 

surveys.append(DESC_ddf(bfs, RA, dec, survey_name=survey_name, reward_value=100, 

nside=nside, nexp=nexp, detailers=detailers)) 

# Extended Chandra Deep Field South 

RA = 53.125 

dec = -28.-6/60. 

survey_name = 'DD:ECDFS' 

ha_limits = [[0.5, 3.0], [20., 22.5]] 

bfs = desc_dd_bfs(RA, dec, survey_name, ha_limits) 

surveys.append(DESC_ddf(bfs, RA, dec, survey_name=survey_name, reward_value=100, nside=nside, 

nexp=nexp, detailers=detailers)) 

 

# COSMOS 

RA = 150.1 

dec = 2.+10./60.+55/3600. 

survey_name = 'DD:COSMOS' 

ha_limits = ([0., 1.5], [21.5, 24.]) 

bfs = desc_dd_bfs(RA, dec, survey_name, ha_limits) 

# have a special sequence for COSMOS 

sequences = [{'g': 2, 'r': 4, 'i': 8}, {'z': 25, 'y': 4}] 

surveys.append(DESC_ddf(bfs, RA, dec, survey_name=survey_name, reward_value=100, nside=nside, 

nexp=nexp, detailers=detailers, sequences=sequences)) 

 

# Extra DD Field, just to get to 5. Still not closed on this one 

survey_name = 'DD:290' 

RA = 349.386443 

dec = -63.321004 

ha_limits = ([0., 0.5], [23.5, 24.]) 

bfs = desc_dd_bfs(RA, dec, survey_name, ha_limits) 

surveys.append(DESC_ddf(bfs, RA, dec, survey_name=survey_name, reward_value=100, nside=nside, 

nexp=nexp, detailers=detailers)) 

 

return surveys 

 

pass