1 import datetime |
|
2 import os |
|
3 import glob |
|
4 |
|
5 import numpy as np |
|
6 |
|
7 from generic import BaseLidarMeasurement, LidarChannel |
|
8 from ciao import CiaoMixin |
|
9 |
|
10 import pearl_netcdf_parameters |
|
11 from report_file import Report_file |
|
12 |
|
13 |
|
14 repository = '/mnt/storage/lidar_data/pearl/' |
|
15 |
|
16 |
|
17 class PearlLidarMeasurement(CiaoMixin, BaseLidarMeasurement): |
|
18 |
|
19 extra_netcdf_parameters = pearl_netcdf_parameters |
|
20 |
|
21 def import_file(self,filename): |
|
22 ''' Import a pearl file. ''' |
|
23 |
|
24 if filename in self.files: |
|
25 print "File has been imported already:" + filename |
|
26 else: |
|
27 parameters, channels_dict = self.read_pearl_data(filename) |
|
28 start_time = self._gettime(parameters['Acq_date'],parameters['Acq_start_time']) |
|
29 |
|
30 for channel_info in channels_dict.itervalues(): |
|
31 |
|
32 if channel_info['name'] == '1064ALR': |
|
33 name = '1064' |
|
34 tm = start_time |
|
35 elif channel_info['name'] == '1064BLR': |
|
36 name = '1064' |
|
37 tm = start_time + datetime.timedelta(seconds = 30) |
|
38 else: |
|
39 name = channel_info['name'] |
|
40 tm = start_time |
|
41 if name not in self.channels: |
|
42 self.channels[name] = LidarChannel(channel_info) |
|
43 self.channels[name].data[tm] = channel_info['data'] |
|
44 self.files.append(filename) |
|
45 |
|
46 def read_pearl_data(self, filename): |
|
47 ''' |
|
48 Reads a pearl file. |
|
49 |
|
50 Returns: |
|
51 parameters - a dictionary of general parameters |
|
52 channels - a dictionary with keys the channel number and values lists |
|
53 [channel name, channel bin width, channel data]. |
|
54 ''' |
|
55 f = open(filename,'r') # Open the file |
|
56 s = f.read(26) # Read the first 26 bytes |
|
57 |
|
58 #Get the values in a dictionary |
|
59 parameters = {} |
|
60 parameters['Acq_date'] = s[0:10] # First 10 bytes are the acquisition date. |
|
61 parameters['Acq_start_time'] = s[10:20].strip() # Next 10 bytes are start time. Strip from trailing spaces. |
|
62 parameters['Channel_no'] = np.fromstring(s[20:22], dtype = np.int16) # Next 2 bytes are the number of channels. Short integer. |
|
63 parameters['Point_no'] = np.fromstring(s[22:26], dtype = np.int32) # Next 4 bytes are the number of points. Integer. |
|
64 p = parameters # Just for less typing |
|
65 |
|
66 # Read the channel parameters |
|
67 len = 20*p['Channel_no'] |
|
68 s = f.read(len) |
|
69 channels = {} |
|
70 for (c1,n) in zip(range(0,len, 20),range(p['Channel_no'])): |
|
71 channels[str(n)] = {'name' : s[c1+10:c1+20].strip(), |
|
72 'binwidth' : s[c1:c1+10].strip()} |
|
73 |
|
74 #Read the data |
|
75 data = np.fromfile(f,dtype = np.float32) |
|
76 #print filename + ': ' + str(data.size) +',' + str(p['Point_no']) +str(p['Channel_no']) |
|
77 data = data.reshape(p['Point_no'],p['Channel_no']) |
|
78 for ch in channels.iterkeys(): |
|
79 channels[ch]['data'] = data[:,int(ch)] |
|
80 #Close the file |
|
81 f.close() |
|
82 return parameters,channels |
|
83 |
|
84 |
|
85 def get_measurement_for_interval(start_time, stop_time): |
|
86 ''' Searches for a pearl measurement based on a time interval |
|
87 ''' |
|
88 |
|
89 correct_series = None |
|
90 day = datetime.timedelta(hours = 24) |
|
91 |
|
92 if start_time > stop_time: |
|
93 raise ValueError('Stop time should be after start time') |
|
94 |
|
95 |
|
96 |
|
97 #The list of directories based on the given time. Same, previous, Next day |
|
98 possible_paths = [get_path(t) for t in [start_time - day, start_time, start_time + day] |
|
99 if get_path(t) is not None] |
|
100 for path in possible_paths: |
|
101 try: |
|
102 rf = Report_file(path) |
|
103 except: |
|
104 rf = None |
|
105 |
|
106 if rf is not None: |
|
107 for serie in rf.series: |
|
108 if (start_time > serie.starttime) and (stop_time < serie.endtime): |
|
109 correct_series = serie |
|
110 |
|
111 if correct_series: |
|
112 files = correct_series.files.get('apd', []) + correct_series.files.get('mcb', []) |
|
113 m_series = PearlLidarMeasurement(files) |
|
114 m_subset = m_series.subset_by_time(start_time, stop_time) |
|
115 return m_subset |
|
116 else: |
|
117 return None |
|
118 |
|
119 |
|
120 def get_channel(tim, channel = '1064'): |
|
121 if channel =='1064': |
|
122 extension = '*.apd' |
|
123 else: |
|
124 extension = '*.mcb' |
|
125 |
|
126 dirstr = get_path(tim) |
|
127 |
|
128 if not os.path.isdir(dirstr): |
|
129 raise IOError('No measurement for that date (directory does not exist.).') |
|
130 #No measurement for that date (directory does not exist.). |
|
131 files = glob.glob(dirstr + extension) |
|
132 m = PearlLidarMeasurement(files) |
|
133 c = m.channels[channel] |
|
134 return c |
|
135 |
|
136 |
|
137 def get_path(tim): |
|
138 dirstr = repository + tim.strftime('%Y')+ '/' +tim.strftime('%d%m%Y') + '/' |
|
139 return dirstr |
|