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 builtins import object 

2from collections import OrderedDict 

3import os 

4import sqlite3 

5import numpy as np 

6from astropy.time import Time, TimeDelta 

7from lsst.utils import getPackageDir 

8 

9 

10__all__ = ['ScheduledDowntimeData'] 

11 

12 

13class ScheduledDowntimeData(object): 

14 """Read the scheduled downtime data. 

15 

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

17 OpSim version 3. 

18 

19 Parameters 

20 ---------- 

21 start_time : astropy.time.Time 

22 The time of the start of the simulation. 

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

24 cloud_db : str, opt 

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

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

27 start_of_night_offset : float, opt 

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

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

30 """ 

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

32 self.scheduled_downtime_db = scheduled_downtime_db 

33 if self.scheduled_downtime_db is None: 

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

35 'data', 'scheduled_downtime.db') 

36 

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

38 year_start = start_time.datetime.year 

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

40 

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

42 self.downtime = None 

43 self.read_data() 

44 

45 def __call__(self): 

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

47 

48 Parameters 

49 ---------- 

50 time : astropy.time.Time 

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

52 

53 Returns 

54 ------- 

55 np.ndarray 

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

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

58 """ 

59 return self.downtime 

60 

61 def _downtimeStatus(self, time): 

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

63 """ 

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

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

66 if next_start > next_end: 

67 current = self.downtime[next_end] 

68 else: 

69 current = None 

70 future = self.downtime[next_start:] 

71 return current, future 

72 

73 def read_data(self): 

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

75 

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

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

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

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

80 

81 night 

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

83 duration 

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

85 activity 

86 str : A description of the activity involved. 

87 """ 

88 # Read from database. 

89 starts = [] 

90 ends = [] 

91 acts = [] 

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

93 cur = conn.cursor() 

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

95 for row in cur: 

96 start_night = int(row[0]) 

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

98 n_down = int(row[1]) 

99 end_night = start_night + TimeDelta(n_down) 

100 activity = row[2] 

101 starts.append(start_night) 

102 ends.append(end_night) 

103 acts.append(activity) 

104 cur.close() 

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

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

107 

108 def config_info(self): 

109 """Report information about configuration of this data. 

110 

111 Returns 

112 ------- 

113 OrderedDict 

114 """ 

115 config_info = OrderedDict() 

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

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

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

119 config_info['Scheduled Downtimes'] = self.downtime 

120 return config_info 

121 

122 def total_downtime(self): 

123 """Return total downtime (in days). 

124 

125 Returns 

126 ------- 

127 int 

128 Total number of downtime days. 

129 """ 

130 total = 0 

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

132 total += td.jd 

133 return total