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

from builtins import object 

from collections import OrderedDict 

import os 

import sqlite3 

import numpy as np 

from astropy.time import Time, TimeDelta 

from lsst.utils import getPackageDir 

 

 

__all__ = ['ScheduledDowntimeData'] 

 

 

class ScheduledDowntimeData(object): 

"""Read the scheduled downtime data. 

 

This class deals with the scheduled downtime information that was previously produced for 

OpSim version 3. 

 

Parameters 

---------- 

start_time : astropy.time.Time 

The time of the start of the simulation. 

The cloud database will be assumed to start on Jan 01 of the same year. 

cloud_db : str, opt 

The full path name for the cloud database. Default None, 

which will use the database stored in the module ($SIMS_CLOUDMODEL_DIR/data/cloud.db). 

start_of_night_offset : float, opt 

The fraction of a day to offset from MJD.0 to reach the defined start of a night ('noon' works). 

Default 0.16 (UTC midnight in Chile) - 0.5 (minus half a day) = -0.34 

""" 

def __init__(self, start_time, scheduled_downtime_db=None, start_of_night_offset=-0.34): 

self.scheduled_downtime_db = scheduled_downtime_db 

if self.scheduled_downtime_db is None: 

self.scheduled_downtime_db = os.path.join(getPackageDir('sims_downtimeModel'), 

'data', 'scheduled_downtime.db') 

 

# downtime database starts in Jan 01 of the year of the start of the simulation. 

year_start = start_time.datetime.year 

self.night0 = Time('%d-01-01' % year_start, format='isot', scale='tai') + start_of_night_offset 

 

# Scheduled downtime data is a np.ndarray of start / end / activity for each scheduled downtime. 

self.downtime = None 

self.read_data() 

 

def __call__(self): 

"""Return the current (if any) and any future scheduled downtimes. 

 

Parameters 

---------- 

time : astropy.time.Time 

Time in the simulation for which to find the current downtime. 

 

Returns 

------- 

np.ndarray 

The array of all unscheduled downtimes, with keys for 'start', 'end', 'activity', 

corresponding to astropy.time.Time, astropy.time.Time, and str. 

""" 

return self.downtime 

 

def _downtimeStatus(self, time): 

"""Look behind the scenes at the downtime status/next values 

""" 

next_start = self.downtime['start'].searchsorted(time, side='right') 

next_end = self.downtime['end'].searchsorted(time, side='right') 

if next_start > next_end: 

current = self.downtime[next_end] 

else: 

current = None 

future = self.downtime[next_start:] 

return current, future 

 

def read_data(self): 

"""Read the scheduled downtime information from disk and translate to astropy.time.Times. 

 

This function gets the appropriate database file and creates the set of 

scheduled downtimes from it. The default behavior is to use the module stored 

database. However, an alternate database file can be provided. The alternate 

database file needs to have a table called *Downtime* with the following columns: 

 

night 

int : The night (from start of simulation) the downtime occurs. 

duration 

int : The duration (units=days) of the downtime. 

activity 

str : A description of the activity involved. 

""" 

# Read from database. 

starts = [] 

ends = [] 

acts = [] 

with sqlite3.connect(self.scheduled_downtime_db) as conn: 

cur = conn.cursor() 

cur.execute("select * from Downtime;") 

for row in cur: 

start_night = int(row[0]) 

start_night = self.night0 + TimeDelta(start_night, format='jd') 

n_down = int(row[1]) 

end_night = start_night + TimeDelta(n_down) 

activity = row[2] 

starts.append(start_night) 

ends.append(end_night) 

acts.append(activity) 

cur.close() 

self.downtime = np.array(list(zip(starts, ends, acts)), 

dtype=[('start', 'O'), ('end', 'O'), ('activity', 'O')]) 

 

def config_info(self): 

"""Report information about configuration of this data. 

 

Returns 

------- 

OrderedDict 

""" 

config_info = OrderedDict() 

config_info['Survey start'] = self.night0.isot 

config_info['Last scheduled downtime ends'] = self.downtime['end'][-1].isot 

config_info['Total scheduled downtime (days)'] = self.total_downtime() 

config_info['Scheduled Downtimes'] = self.downtime 

return config_info 

 

def total_downtime(self): 

"""Return total downtime (in days). 

 

Returns 

------- 

int 

Total number of downtime days. 

""" 

total = 0 

for td in (self.downtime['end'] - self.downtime['start']): 

total += td.jd 

return total