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 

2import os 

3import sqlite3 

4import numpy as np 

5from astropy.time import Time 

6from lsst.utils import getPackageDir 

7 

8__all__ = ["CloudData"] 

9 

10 

11class CloudData(object): 

12 """Handle the cloud information. 

13 

14 This class deals with the cloud information that was previously produced for 

15 OpSim version 3. 

16 

17 Parameters 

18 ---------- 

19 start_time : astropy.time.Time 

20 The time of the start of the simulation. 

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

22 cloud_db : str, opt 

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

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

25 offset_year : float, opt 

26 Offset into the cloud database by 'offset_year' years. Default 0. 

27 scale : float (1e6) 

28 Enforce machine precision for cross-platform repeatability by scaling and rounding date values. 

29 """ 

30 def __init__(self, start_time, cloud_db=None, offset_year=0, scale=1e6): 

31 self.cloud_db = cloud_db 

32 if self.cloud_db is None: 

33 self.cloud_db = os.path.join(getPackageDir('sims_cloudModel'), 'data', 'cloud.db') 

34 

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

36 year_start = start_time.datetime.year + offset_year 

37 self.start_time = Time('%d-01-01' % year_start, format='isot', scale='tai') 

38 

39 self.cloud_dates = None 

40 self.cloud_values = None 

41 self.scale = scale 

42 self.read_data() 

43 

44 def __call__(self, time): 

45 """Get the cloud for the specified time. 

46 

47 Parameters 

48 ---------- 

49 time : astropy.time.Time 

50 Time in the simulation for which to find the current cloud coverage. 

51 The difference between this time and the start_time, plus the offset, 

52 will be used to query the cloud database for the 'current' conditions. 

53 

54 Returns 

55 ------- 

56 float 

57 The fraction of the sky that is cloudy (measured in steps of 8ths) closest to the specified time. 

58 """ 

59 delta_time = (time - self.start_time).sec 

60 dbdate = delta_time % self.time_range + self.min_time 

61 if self.scale is not None: 

62 dbdate = np.round(dbdate*self.scale).astype(int) 

63 idx = np.searchsorted(self.cloud_dates, dbdate) 

64 # searchsorted ensures that left < date < right 

65 # but we need to know if date is closer to left or to right 

66 left = self.cloud_dates[idx - 1] 

67 right = self.cloud_dates[idx] 

68 if dbdate - left < right - dbdate: 

69 idx -= 1 

70 return self.cloud_values[idx] 

71 

72 def read_data(self): 

73 """Read the cloud data from disk. 

74 

75 The default behavior is to use the module stored database. However, an 

76 alternate database file can be provided. The alternate database file needs to have a 

77 table called *Cloud* with the following columns: 

78 

79 cloudId 

80 int : A unique index for each cloud entry. 

81 c_date 

82 int : The time (units=seconds) since the start of the simulation for the cloud observation. 

83 cloud 

84 float : The cloud coverage (in steps of 8ths) of the sky. 

85 """ 

86 with sqlite3.connect(self.cloud_db) as conn: 

87 cur = conn.cursor() 

88 query = "select c_date, cloud from Cloud order by c_date;" 

89 cur.execute(query) 

90 results = np.array(cur.fetchall()) 

91 self.cloud_dates = np.hsplit(results, 2)[0].flatten() 

92 self.cloud_values = np.hsplit(results, 2)[1].flatten() 

93 cur.close() 

94 # Make sure seeing dates are ordered appropriately (monotonically increasing). 

95 ordidx = self.cloud_dates.argsort() 

96 self.cloud_dates = self.cloud_dates[ordidx] 

97 if self.scale is not None: 

98 self.cloud_dates = np.round(self.cloud_dates*self.scale).astype(int) 

99 self.cloud_values = self.cloud_values[ordidx] 

100 # Record this information, in case the cloud database does not start at t=0. 

101 self.min_time = self.cloud_dates[0] 

102 self.max_time = self.cloud_dates[-1] 

103 self.time_range = self.max_time - self.min_time 

104 

105 def config_info(self): 

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

107 

108 Returns 

109 ------- 

110 Dict 

111 """ 

112 config_info = {} 

113 config_info['Start time for db'] = self.start_time 

114 config_info['Cloud database'] = self.cloud_db 

115 return config_info