##// END OF EJS Templates
MADReader support for HDF5 (mad2 & mad3)
jespinoza -
r1065:9a4424b32cac
parent child
Show More
@@ -1,7 +1,7
1 '''
1 '''
2 Created on Feb 7, 2012
2 Created on Feb 7, 2012
3
3
4 @author $Author$
4 @author $Author$
5 @version $Id$
5 @version $Id$
6 '''
6 '''
7 __version__ = "2.3"
7 __version__ = '2.3'
@@ -1,782 +1,783
1
1
2 import os
2 import os
3 import time
3 import time
4 import glob
4 import glob
5 import datetime
5 import datetime
6 from multiprocessing import Process
6 from multiprocessing import Process
7
7
8 import zmq
8 import zmq
9 import numpy
9 import numpy
10 import matplotlib
10 import matplotlib
11 import matplotlib.pyplot as plt
11 import matplotlib.pyplot as plt
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
14
14
15 from schainpy.model.proc.jroproc_base import Operation
15 from schainpy.model.proc.jroproc_base import Operation
16 from schainpy.utils import log
16 from schainpy.utils import log
17
17
18 func = lambda x, pos: ('%s') %(datetime.datetime.fromtimestamp(x).strftime('%H:%M'))
18 func = lambda x, pos: ('%s') %(datetime.datetime.fromtimestamp(x).strftime('%H:%M'))
19
19
20 d1970 = datetime.datetime(1970, 1, 1)
20 d1970 = datetime.datetime(1970, 1, 1)
21
21
22
22
23 class PlotData(Operation, Process):
23 class PlotData(Operation, Process):
24 '''
24 '''
25 Base class for Schain plotting operations
25 Base class for Schain plotting operations
26 '''
26 '''
27
27
28 CODE = 'Figure'
28 CODE = 'Figure'
29 colormap = 'jro'
29 colormap = 'jro'
30 bgcolor = 'white'
30 bgcolor = 'white'
31 CONFLATE = False
31 CONFLATE = False
32 __MAXNUMX = 80
32 __MAXNUMX = 80
33 __missing = 1E30
33 __missing = 1E30
34
34
35 def __init__(self, **kwargs):
35 def __init__(self, **kwargs):
36
36
37 Operation.__init__(self, plot=True, **kwargs)
37 Operation.__init__(self, plot=True, **kwargs)
38 Process.__init__(self)
38 Process.__init__(self)
39 self.kwargs['code'] = self.CODE
39 self.kwargs['code'] = self.CODE
40 self.mp = False
40 self.mp = False
41 self.data = None
41 self.data = None
42 self.isConfig = False
42 self.isConfig = False
43 self.figures = []
43 self.figures = []
44 self.axes = []
44 self.axes = []
45 self.cb_axes = []
45 self.cb_axes = []
46 self.localtime = kwargs.pop('localtime', True)
46 self.localtime = kwargs.pop('localtime', True)
47 self.show = kwargs.get('show', True)
47 self.show = kwargs.get('show', True)
48 self.save = kwargs.get('save', False)
48 self.save = kwargs.get('save', False)
49 self.colormap = kwargs.get('colormap', self.colormap)
49 self.colormap = kwargs.get('colormap', self.colormap)
50 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
50 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
51 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
51 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
52 self.colormaps = kwargs.get('colormaps', None)
52 self.colormaps = kwargs.get('colormaps', None)
53 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
53 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
54 self.showprofile = kwargs.get('showprofile', False)
54 self.showprofile = kwargs.get('showprofile', False)
55 self.title = kwargs.get('wintitle', self.CODE.upper())
55 self.title = kwargs.get('wintitle', self.CODE.upper())
56 self.cb_label = kwargs.get('cb_label', None)
56 self.cb_label = kwargs.get('cb_label', None)
57 self.cb_labels = kwargs.get('cb_labels', None)
57 self.cb_labels = kwargs.get('cb_labels', None)
58 self.xaxis = kwargs.get('xaxis', 'frequency')
58 self.xaxis = kwargs.get('xaxis', 'frequency')
59 self.zmin = kwargs.get('zmin', None)
59 self.zmin = kwargs.get('zmin', None)
60 self.zmax = kwargs.get('zmax', None)
60 self.zmax = kwargs.get('zmax', None)
61 self.zlimits = kwargs.get('zlimits', None)
61 self.zlimits = kwargs.get('zlimits', None)
62 self.xmin = kwargs.get('xmin', None)
62 self.xmin = kwargs.get('xmin', None)
63 if self.xmin is not None:
63 if self.xmin is not None:
64 self.xmin += 5
64 self.xmin += 5
65 self.xmax = kwargs.get('xmax', None)
65 self.xmax = kwargs.get('xmax', None)
66 self.xrange = kwargs.get('xrange', 24)
66 self.xrange = kwargs.get('xrange', 24)
67 self.ymin = kwargs.get('ymin', None)
67 self.ymin = kwargs.get('ymin', None)
68 self.ymax = kwargs.get('ymax', None)
68 self.ymax = kwargs.get('ymax', None)
69 self.xlabel = kwargs.get('xlabel', None)
69 self.xlabel = kwargs.get('xlabel', None)
70 self.__MAXNUMY = kwargs.get('decimation', 100)
70 self.__MAXNUMY = kwargs.get('decimation', 100)
71 self.showSNR = kwargs.get('showSNR', False)
71 self.showSNR = kwargs.get('showSNR', False)
72 self.oneFigure = kwargs.get('oneFigure', True)
72 self.oneFigure = kwargs.get('oneFigure', True)
73 self.width = kwargs.get('width', None)
73 self.width = kwargs.get('width', None)
74 self.height = kwargs.get('height', None)
74 self.height = kwargs.get('height', None)
75 self.colorbar = kwargs.get('colorbar', True)
75 self.colorbar = kwargs.get('colorbar', True)
76 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
76 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
77 self.titles = ['' for __ in range(16)]
77 self.titles = ['' for __ in range(16)]
78
78
79 def __setup(self):
79 def __setup(self):
80 '''
80 '''
81 Common setup for all figures, here figures and axes are created
81 Common setup for all figures, here figures and axes are created
82 '''
82 '''
83
83
84 self.setup()
84 self.setup()
85
85
86 if self.width is None:
86 if self.width is None:
87 self.width = 8
87 self.width = 8
88
88
89 self.figures = []
89 self.figures = []
90 self.axes = []
90 self.axes = []
91 self.cb_axes = []
91 self.cb_axes = []
92 self.pf_axes = []
92 self.pf_axes = []
93 self.cmaps = []
93 self.cmaps = []
94
94
95 size = '15%' if self.ncols==1 else '30%'
95 size = '15%' if self.ncols==1 else '30%'
96 pad = '4%' if self.ncols==1 else '8%'
96 pad = '4%' if self.ncols==1 else '8%'
97
97
98 if self.oneFigure:
98 if self.oneFigure:
99 if self.height is None:
99 if self.height is None:
100 self.height = 1.4*self.nrows + 1
100 self.height = 1.4*self.nrows + 1
101 fig = plt.figure(figsize=(self.width, self.height),
101 fig = plt.figure(figsize=(self.width, self.height),
102 edgecolor='k',
102 edgecolor='k',
103 facecolor='w')
103 facecolor='w')
104 self.figures.append(fig)
104 self.figures.append(fig)
105 for n in range(self.nplots):
105 for n in range(self.nplots):
106 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
106 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
107 ax.tick_params(labelsize=8)
107 ax.tick_params(labelsize=8)
108 ax.firsttime = True
108 ax.firsttime = True
109 self.axes.append(ax)
109 self.axes.append(ax)
110 if self.showprofile:
110 if self.showprofile:
111 cax = self.__add_axes(ax, size=size, pad=pad)
111 cax = self.__add_axes(ax, size=size, pad=pad)
112 cax.tick_params(labelsize=8)
112 cax.tick_params(labelsize=8)
113 self.pf_axes.append(cax)
113 self.pf_axes.append(cax)
114 else:
114 else:
115 if self.height is None:
115 if self.height is None:
116 self.height = 3
116 self.height = 3
117 for n in range(self.nplots):
117 for n in range(self.nplots):
118 fig = plt.figure(figsize=(self.width, self.height),
118 fig = plt.figure(figsize=(self.width, self.height),
119 edgecolor='k',
119 edgecolor='k',
120 facecolor='w')
120 facecolor='w')
121 ax = fig.add_subplot(1, 1, 1)
121 ax = fig.add_subplot(1, 1, 1)
122 ax.tick_params(labelsize=8)
122 ax.tick_params(labelsize=8)
123 ax.firsttime = True
123 ax.firsttime = True
124 self.figures.append(fig)
124 self.figures.append(fig)
125 self.axes.append(ax)
125 self.axes.append(ax)
126 if self.showprofile:
126 if self.showprofile:
127 cax = self.__add_axes(ax, size=size, pad=pad)
127 cax = self.__add_axes(ax, size=size, pad=pad)
128 cax.tick_params(labelsize=8)
128 cax.tick_params(labelsize=8)
129 self.pf_axes.append(cax)
129 self.pf_axes.append(cax)
130
130
131 for n in range(self.nrows):
131 for n in range(self.nrows):
132 if self.colormaps is not None:
132 if self.colormaps is not None:
133 cmap = plt.get_cmap(self.colormaps[n])
133 cmap = plt.get_cmap(self.colormaps[n])
134 else:
134 else:
135 cmap = plt.get_cmap(self.colormap)
135 cmap = plt.get_cmap(self.colormap)
136 cmap.set_bad(self.bgcolor, 1.)
136 cmap.set_bad(self.bgcolor, 1.)
137 self.cmaps.append(cmap)
137 self.cmaps.append(cmap)
138
138
139 def __add_axes(self, ax, size='30%', pad='8%'):
139 def __add_axes(self, ax, size='30%', pad='8%'):
140 '''
140 '''
141 Add new axes to the given figure
141 Add new axes to the given figure
142 '''
142 '''
143 divider = make_axes_locatable(ax)
143 divider = make_axes_locatable(ax)
144 nax = divider.new_horizontal(size=size, pad=pad)
144 nax = divider.new_horizontal(size=size, pad=pad)
145 ax.figure.add_axes(nax)
145 ax.figure.add_axes(nax)
146 return nax
146 return nax
147
147
148 self.setup()
148
149
149 def setup(self):
150 def setup(self):
150 '''
151 '''
151 This method should be implemented in the child class, the following
152 This method should be implemented in the child class, the following
152 attributes should be set:
153 attributes should be set:
153
154
154 self.nrows: number of rows
155 self.nrows: number of rows
155 self.ncols: number of cols
156 self.ncols: number of cols
156 self.nplots: number of plots (channels or pairs)
157 self.nplots: number of plots (channels or pairs)
157 self.ylabel: label for Y axes
158 self.ylabel: label for Y axes
158 self.titles: list of axes title
159 self.titles: list of axes title
159
160
160 '''
161 '''
161 raise(NotImplementedError, 'Implement this method in child class')
162 raise(NotImplementedError, 'Implement this method in child class')
162
163
163 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
164 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
164 '''
165 '''
165 Create a masked array for missing data
166 Create a masked array for missing data
166 '''
167 '''
167 if x_buffer.shape[0] < 2:
168 if x_buffer.shape[0] < 2:
168 return x_buffer, y_buffer, z_buffer
169 return x_buffer, y_buffer, z_buffer
169
170
170 deltas = x_buffer[1:] - x_buffer[0:-1]
171 deltas = x_buffer[1:] - x_buffer[0:-1]
171 x_median = numpy.median(deltas)
172 x_median = numpy.median(deltas)
172
173
173 index = numpy.where(deltas > 5*x_median)
174 index = numpy.where(deltas > 5*x_median)
174
175
175 if len(index[0]) != 0:
176 if len(index[0]) != 0:
176 z_buffer[::, index[0], ::] = self.__missing
177 z_buffer[::, index[0], ::] = self.__missing
177 z_buffer = numpy.ma.masked_inside(z_buffer,
178 z_buffer = numpy.ma.masked_inside(z_buffer,
178 0.99*self.__missing,
179 0.99*self.__missing,
179 1.01*self.__missing)
180 1.01*self.__missing)
180
181
181 return x_buffer, y_buffer, z_buffer
182 return x_buffer, y_buffer, z_buffer
182
183
183 def decimate(self):
184 def decimate(self):
184
185
185 # dx = int(len(self.x)/self.__MAXNUMX) + 1
186 # dx = int(len(self.x)/self.__MAXNUMX) + 1
186 dy = int(len(self.y)/self.__MAXNUMY) + 1
187 dy = int(len(self.y)/self.__MAXNUMY) + 1
187
188
188 # x = self.x[::dx]
189 # x = self.x[::dx]
189 x = self.x
190 x = self.x
190 y = self.y[::dy]
191 y = self.y[::dy]
191 z = self.z[::, ::, ::dy]
192 z = self.z[::, ::, ::dy]
192
193
193 return x, y, z
194 return x, y, z
194
195
195 def format(self):
196 def format(self):
196 '''
197 '''
197 Set min and max values, labels, ticks and titles
198 Set min and max values, labels, ticks and titles
198 '''
199 '''
199
200
200 if self.xmin is None:
201 if self.xmin is None:
201 xmin = self.min_time
202 xmin = self.min_time
202 else:
203 else:
203 if self.xaxis is 'time':
204 if self.xaxis is 'time':
204 dt = datetime.datetime.fromtimestamp(self.min_time)
205 dt = datetime.datetime.fromtimestamp(self.min_time)
205 xmin = (datetime.datetime.combine(dt.date(),
206 xmin = (datetime.datetime.combine(dt.date(),
206 datetime.time(int(self.xmin), 0, 0))-d1970).total_seconds()
207 datetime.time(int(self.xmin), 0, 0))-d1970).total_seconds()
207 else:
208 else:
208 xmin = self.xmin
209 xmin = self.xmin
209
210
210 if self.xmax is None:
211 if self.xmax is None:
211 xmax = xmin+self.xrange*60*60
212 xmax = xmin+self.xrange*60*60
212 else:
213 else:
213 if self.xaxis is 'time':
214 if self.xaxis is 'time':
214 dt = datetime.datetime.fromtimestamp(self.min_time)
215 dt = datetime.datetime.fromtimestamp(self.min_time)
215 xmax = (datetime.datetime.combine(dt.date(),
216 xmax = (datetime.datetime.combine(dt.date(),
216 datetime.time(int(self.xmax), 0, 0))-d1970).total_seconds()
217 datetime.time(int(self.xmax), 0, 0))-d1970).total_seconds()
217 else:
218 else:
218 xmax = self.xmax
219 xmax = self.xmax
219
220
220 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
221 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
221 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
222 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
222
223
223 ystep = 200 if ymax>= 800 else 100 if ymax>=400 else 50 if ymax>=200 else 20
224 ystep = 200 if ymax>= 800 else 100 if ymax>=400 else 50 if ymax>=200 else 20
224
225
225 for n, ax in enumerate(self.axes):
226 for n, ax in enumerate(self.axes):
226 if ax.firsttime:
227 if ax.firsttime:
227 ax.set_facecolor(self.bgcolor)
228 ax.set_facecolor(self.bgcolor)
228 ax.yaxis.set_major_locator(MultipleLocator(ystep))
229 ax.yaxis.set_major_locator(MultipleLocator(ystep))
229 if self.xaxis is 'time':
230 if self.xaxis is 'time':
230 ax.xaxis.set_major_formatter(FuncFormatter(func))
231 ax.xaxis.set_major_formatter(FuncFormatter(func))
231 ax.xaxis.set_major_locator(LinearLocator(9))
232 ax.xaxis.set_major_locator(LinearLocator(9))
232 if self.xlabel is not None:
233 if self.xlabel is not None:
233 ax.set_xlabel(self.xlabel)
234 ax.set_xlabel(self.xlabel)
234 ax.set_ylabel(self.ylabel)
235 ax.set_ylabel(self.ylabel)
235 ax.firsttime = False
236 ax.firsttime = False
236 if self.showprofile:
237 if self.showprofile:
237 self.pf_axes[n].set_ylim(ymin, ymax)
238 self.pf_axes[n].set_ylim(ymin, ymax)
238 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
239 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
239 self.pf_axes[n].set_xlabel('dB')
240 self.pf_axes[n].set_xlabel('dB')
240 self.pf_axes[n].grid(b=True, axis='x')
241 self.pf_axes[n].grid(b=True, axis='x')
241 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
242 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
242 if self.colorbar:
243 if self.colorbar:
243 cb = plt.colorbar(ax.plt, ax=ax, pad=0.02)
244 cb = plt.colorbar(ax.plt, ax=ax, pad=0.02)
244 cb.ax.tick_params(labelsize=8)
245 cb.ax.tick_params(labelsize=8)
245 if self.cb_label:
246 if self.cb_label:
246 cb.set_label(self.cb_label, size=8)
247 cb.set_label(self.cb_label, size=8)
247 elif self.cb_labels:
248 elif self.cb_labels:
248 cb.set_label(self.cb_labels[n], size=8)
249 cb.set_label(self.cb_labels[n], size=8)
249
250
250 ax.set_title('{} - {} UTC'.format(
251 ax.set_title('{} - {} UTC'.format(
251 self.titles[n],
252 self.titles[n],
252 datetime.datetime.fromtimestamp(self.max_time).strftime('%H:%M:%S')),
253 datetime.datetime.fromtimestamp(self.max_time).strftime('%H:%M:%S')),
253 size=8)
254 size=8)
254 ax.set_xlim(xmin, xmax)
255 ax.set_xlim(xmin, xmax)
255 ax.set_ylim(ymin, ymax)
256 ax.set_ylim(ymin, ymax)
256
257
257
258
258 def __plot(self):
259 def __plot(self):
259 '''
260 '''
260 '''
261 '''
261 log.success('Plotting', self.name)
262 log.success('Plotting', self.name)
262
263
263 self.plot()
264 self.plot()
264 self.format()
265 self.format()
265
266
266 for n, fig in enumerate(self.figures):
267 for n, fig in enumerate(self.figures):
267 if self.nrows == 0 or self.nplots == 0:
268 if self.nrows == 0 or self.nplots == 0:
268 log.warning('No data', self.name)
269 log.warning('No data', self.name)
269 continue
270 continue
270 if self.show:
271 if self.show:
271 fig.show()
272 fig.show()
272
273
273 fig.tight_layout()
274 fig.tight_layout()
274 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
275 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
275 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
276 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
276 # fig.canvas.draw()
277 # fig.canvas.draw()
277
278
278 if self.save and self.data.ended:
279 if self.save and self.data.ended:
279 channels = range(self.nrows)
280 channels = range(self.nrows)
280 if self.oneFigure:
281 if self.oneFigure:
281 label = ''
282 label = ''
282 else:
283 else:
283 label = '_{}'.format(channels[n])
284 label = '_{}'.format(channels[n])
284 figname = os.path.join(
285 figname = os.path.join(
285 self.save,
286 self.save,
286 '{}{}_{}.png'.format(
287 '{}{}_{}.png'.format(
287 self.CODE,
288 self.CODE,
288 label,
289 label,
289 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')
290 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')
290 )
291 )
291 )
292 )
292 print 'Saving figure: {}'.format(figname)
293 print 'Saving figure: {}'.format(figname)
293 fig.savefig(figname)
294 fig.savefig(figname)
294
295
295 def plot(self):
296 def plot(self):
296 '''
297 '''
297 '''
298 '''
298 raise(NotImplementedError, 'Implement this method in child class')
299 raise(NotImplementedError, 'Implement this method in child class')
299
300
300 def run(self):
301 def run(self):
301
302
302 log.success('Starting', self.name)
303 log.success('Starting', self.name)
303
304
304 context = zmq.Context()
305 context = zmq.Context()
305 receiver = context.socket(zmq.SUB)
306 receiver = context.socket(zmq.SUB)
306 receiver.setsockopt(zmq.SUBSCRIBE, '')
307 receiver.setsockopt(zmq.SUBSCRIBE, '')
307 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
308 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
308
309
309 if 'server' in self.kwargs['parent']:
310 if 'server' in self.kwargs['parent']:
310 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
311 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
311 else:
312 else:
312 receiver.connect("ipc:///tmp/zmq.plots")
313 receiver.connect("ipc:///tmp/zmq.plots")
313
314
314 while True:
315 while True:
315 try:
316 try:
316 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
317 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
317
318
318 self.min_time = self.data.times[0]
319 self.min_time = self.data.times[0]
319 self.max_time = self.data.times[-1]
320 self.max_time = self.data.times[-1]
320
321
321 if self.isConfig is False:
322 if self.isConfig is False:
322 self.__setup()
323 self.__setup()
323 self.isConfig = True
324 self.isConfig = True
324
325
325 self.__plot()
326 self.__plot()
326
327
327 except zmq.Again as e:
328 except zmq.Again as e:
328 log.log('Waiting for data...')
329 log.log('Waiting for data...')
329 if self.data:
330 if self.data:
330 plt.pause(self.data.throttle)
331 plt.pause(self.data.throttle)
331 else:
332 else:
332 time.sleep(2)
333 time.sleep(2)
333
334
334 def close(self):
335 def close(self):
335 if self.data:
336 if self.data:
336 self.__plot()
337 self.__plot()
337
338
338
339 class PlotSpectraData(PlotData):
339 class PlotSpectraData(PlotData):
340 '''
340 '''
341 Plot for Spectra data
341 Plot for Spectra data
342 '''
342 '''
343
343
344 CODE = 'spc'
344 CODE = 'spc'
345 colormap = 'jro'
345 colormap = 'jro'
346
346
347 def setup(self):
347 def setup(self):
348 self.nplots = len(self.data.channels)
348 self.nplots = len(self.data.channels)
349 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
349 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
350 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
350 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
351 self.width = 3.4*self.ncols
351 self.width = 3.4*self.ncols
352 self.height = 3*self.nrows
352 self.height = 3*self.nrows
353 self.cb_label = 'dB'
353 self.cb_label = 'dB'
354 if self.showprofile:
354 if self.showprofile:
355 self.width += 0.8*self.ncols
355 self.width += 0.8*self.ncols
356
356
357 self.ylabel = 'Range [Km]'
357 self.ylabel = 'Range [Km]'
358
358
359 def plot(self):
359 def plot(self):
360 if self.xaxis == "frequency":
360 if self.xaxis == "frequency":
361 x = self.data.xrange[0]
361 x = self.data.xrange[0]
362 self.xlabel = "Frequency (kHz)"
362 self.xlabel = "Frequency (kHz)"
363 elif self.xaxis == "time":
363 elif self.xaxis == "time":
364 x = self.data.xrange[1]
364 x = self.data.xrange[1]
365 self.xlabel = "Time (ms)"
365 self.xlabel = "Time (ms)"
366 else:
366 else:
367 x = self.data.xrange[2]
367 x = self.data.xrange[2]
368 self.xlabel = "Velocity (m/s)"
368 self.xlabel = "Velocity (m/s)"
369
369
370 if self.CODE == 'spc_mean':
370 if self.CODE == 'spc_mean':
371 x = self.data.xrange[2]
371 x = self.data.xrange[2]
372 self.xlabel = "Velocity (m/s)"
372 self.xlabel = "Velocity (m/s)"
373
373
374 self.titles = []
374 self.titles = []
375
375
376 y = self.data.heights
376 y = self.data.heights
377 self.y = y
377 self.y = y
378 z = self.data['spc']
378 z = self.data['spc']
379
379
380 for n, ax in enumerate(self.axes):
380 for n, ax in enumerate(self.axes):
381 noise = self.data['noise'][n][-1]
381 noise = self.data['noise'][n][-1]
382 if self.CODE == 'spc_mean':
382 if self.CODE == 'spc_mean':
383 mean = self.data['mean'][n][-1]
383 mean = self.data['mean'][n][-1]
384 if ax.firsttime:
384 if ax.firsttime:
385 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
385 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
386 self.xmin = self.xmin if self.xmin else -self.xmax
386 self.xmin = self.xmin if self.xmin else -self.xmax
387 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
387 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
388 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
388 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
389 ax.plt = ax.pcolormesh(x, y, z[n].T,
389 ax.plt = ax.pcolormesh(x, y, z[n].T,
390 vmin=self.zmin,
390 vmin=self.zmin,
391 vmax=self.zmax,
391 vmax=self.zmax,
392 cmap=plt.get_cmap(self.colormap)
392 cmap=plt.get_cmap(self.colormap)
393 )
393 )
394
394
395 if self.showprofile:
395 if self.showprofile:
396 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
396 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
397 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
397 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
398 color="k", linestyle="dashed", lw=1)[0]
398 color="k", linestyle="dashed", lw=1)[0]
399 if self.CODE == 'spc_mean':
399 if self.CODE == 'spc_mean':
400 ax.plt_mean = ax.plot(mean, y, color='k')[0]
400 ax.plt_mean = ax.plot(mean, y, color='k')[0]
401 else:
401 else:
402 ax.plt.set_array(z[n].T.ravel())
402 ax.plt.set_array(z[n].T.ravel())
403 if self.showprofile:
403 if self.showprofile:
404 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
404 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
405 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
405 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
406 if self.CODE == 'spc_mean':
406 if self.CODE == 'spc_mean':
407 ax.plt_mean.set_data(mean, y)
407 ax.plt_mean.set_data(mean, y)
408
408
409 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
409 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
410 self.saveTime = self.max_time
410 self.saveTime = self.max_time
411
411
412
412
413 class PlotCrossSpectraData(PlotData):
413 class PlotCrossSpectraData(PlotData):
414
414
415 CODE = 'cspc'
415 CODE = 'cspc'
416 zmin_coh = None
416 zmin_coh = None
417 zmax_coh = None
417 zmax_coh = None
418 zmin_phase = None
418 zmin_phase = None
419 zmax_phase = None
419 zmax_phase = None
420
420
421 def setup(self):
421 def setup(self):
422
422
423 self.ncols = 4
423 self.ncols = 4
424 self.nrows = len(self.data.pairs)
424 self.nrows = len(self.data.pairs)
425 self.nplots = self.nrows*4
425 self.nplots = self.nrows*4
426 self.width = 3.4*self.ncols
426 self.width = 3.4*self.ncols
427 self.height = 3*self.nrows
427 self.height = 3*self.nrows
428 self.ylabel = 'Range [Km]'
428 self.ylabel = 'Range [Km]'
429 self.showprofile = False
429 self.showprofile = False
430
430
431 def plot(self):
431 def plot(self):
432
432
433 if self.xaxis == "frequency":
433 if self.xaxis == "frequency":
434 x = self.data.xrange[0]
434 x = self.data.xrange[0]
435 self.xlabel = "Frequency (kHz)"
435 self.xlabel = "Frequency (kHz)"
436 elif self.xaxis == "time":
436 elif self.xaxis == "time":
437 x = self.data.xrange[1]
437 x = self.data.xrange[1]
438 self.xlabel = "Time (ms)"
438 self.xlabel = "Time (ms)"
439 else:
439 else:
440 x = self.data.xrange[2]
440 x = self.data.xrange[2]
441 self.xlabel = "Velocity (m/s)"
441 self.xlabel = "Velocity (m/s)"
442
442
443 self.titles = []
443 self.titles = []
444
444
445 y = self.data.heights
445 y = self.data.heights
446 self.y = y
446 self.y = y
447 spc = self.data['spc']
447 spc = self.data['spc']
448 cspc = self.data['cspc']
448 cspc = self.data['cspc']
449
449
450 for n in range(self.nrows):
450 for n in range(self.nrows):
451 noise = self.data['noise'][n][-1]
451 noise = self.data['noise'][n][-1]
452 pair = self.data.pairs[n]
452 pair = self.data.pairs[n]
453 ax = self.axes[4*n]
453 ax = self.axes[4*n]
454 ax3 = self.axes[4*n+3]
454 ax3 = self.axes[4*n+3]
455 if ax.firsttime:
455 if ax.firsttime:
456 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
456 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
457 self.xmin = self.xmin if self.xmin else -self.xmax
457 self.xmin = self.xmin if self.xmin else -self.xmax
458 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
458 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
459 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
459 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
460 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
460 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
461 vmin=self.zmin,
461 vmin=self.zmin,
462 vmax=self.zmax,
462 vmax=self.zmax,
463 cmap=plt.get_cmap(self.colormap)
463 cmap=plt.get_cmap(self.colormap)
464 )
464 )
465 else:
465 else:
466 ax.plt.set_array(spc[pair[0]].T.ravel())
466 ax.plt.set_array(spc[pair[0]].T.ravel())
467 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
467 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
468
468
469 ax = self.axes[4*n+1]
469 ax = self.axes[4*n+1]
470 if ax.firsttime:
470 if ax.firsttime:
471 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
471 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
472 vmin=self.zmin,
472 vmin=self.zmin,
473 vmax=self.zmax,
473 vmax=self.zmax,
474 cmap=plt.get_cmap(self.colormap)
474 cmap=plt.get_cmap(self.colormap)
475 )
475 )
476 else:
476 else:
477 ax.plt.set_array(spc[pair[1]].T.ravel())
477 ax.plt.set_array(spc[pair[1]].T.ravel())
478 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
478 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
479
479
480 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
480 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
481 coh = numpy.abs(out)
481 coh = numpy.abs(out)
482 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
482 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
483
483
484 ax = self.axes[4*n+2]
484 ax = self.axes[4*n+2]
485 if ax.firsttime:
485 if ax.firsttime:
486 ax.plt = ax.pcolormesh(x, y, coh.T,
486 ax.plt = ax.pcolormesh(x, y, coh.T,
487 vmin=0,
487 vmin=0,
488 vmax=1,
488 vmax=1,
489 cmap=plt.get_cmap(self.colormap_coh)
489 cmap=plt.get_cmap(self.colormap_coh)
490 )
490 )
491 else:
491 else:
492 ax.plt.set_array(coh.T.ravel())
492 ax.plt.set_array(coh.T.ravel())
493 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
493 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
494
494
495 ax = self.axes[4*n+3]
495 ax = self.axes[4*n+3]
496 if ax.firsttime:
496 if ax.firsttime:
497 ax.plt = ax.pcolormesh(x, y, phase.T,
497 ax.plt = ax.pcolormesh(x, y, phase.T,
498 vmin=-180,
498 vmin=-180,
499 vmax=180,
499 vmax=180,
500 cmap=plt.get_cmap(self.colormap_phase)
500 cmap=plt.get_cmap(self.colormap_phase)
501 )
501 )
502 else:
502 else:
503 ax.plt.set_array(phase.T.ravel())
503 ax.plt.set_array(phase.T.ravel())
504 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
504 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
505
505
506 self.saveTime = self.max_time
506 self.saveTime = self.max_time
507
507
508
508
509 class PlotSpectraMeanData(PlotSpectraData):
509 class PlotSpectraMeanData(PlotSpectraData):
510 '''
510 '''
511 Plot for Spectra and Mean
511 Plot for Spectra and Mean
512 '''
512 '''
513 CODE = 'spc_mean'
513 CODE = 'spc_mean'
514 colormap = 'jro'
514 colormap = 'jro'
515
515
516
516
517 class PlotRTIData(PlotData):
517 class PlotRTIData(PlotData):
518 '''
518 '''
519 Plot for RTI data
519 Plot for RTI data
520 '''
520 '''
521
521
522 CODE = 'rti'
522 CODE = 'rti'
523 colormap = 'jro'
523 colormap = 'jro'
524
524
525 def setup(self):
525 def setup(self):
526 self.xaxis = 'time'
526 self.xaxis = 'time'
527 self.ncols = 1
527 self.ncols = 1
528 self.nrows = len(self.data.channels)
528 self.nrows = len(self.data.channels)
529 self.nplots = len(self.data.channels)
529 self.nplots = len(self.data.channels)
530 self.ylabel = 'Range [Km]'
530 self.ylabel = 'Range [Km]'
531 self.cb_label = 'dB'
531 self.cb_label = 'dB'
532 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
532 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
533
533
534 def plot(self):
534 def plot(self):
535 self.x = self.data.times
535 self.x = self.data.times
536 self.y = self.data.heights
536 self.y = self.data.heights
537 self.z = self.data[self.CODE]
537 self.z = self.data[self.CODE]
538 self.z = numpy.ma.masked_invalid(self.z)
538 self.z = numpy.ma.masked_invalid(self.z)
539
539
540 for n, ax in enumerate(self.axes):
540 for n, ax in enumerate(self.axes):
541 x, y, z = self.fill_gaps(*self.decimate())
541 x, y, z = self.fill_gaps(*self.decimate())
542 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
542 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
543 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
543 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
544 if ax.firsttime:
544 if ax.firsttime:
545 ax.plt = ax.pcolormesh(x, y, z[n].T,
545 ax.plt = ax.pcolormesh(x, y, z[n].T,
546 vmin=self.zmin,
546 vmin=self.zmin,
547 vmax=self.zmax,
547 vmax=self.zmax,
548 cmap=plt.get_cmap(self.colormap)
548 cmap=plt.get_cmap(self.colormap)
549 )
549 )
550 if self.showprofile:
550 if self.showprofile:
551 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
551 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
552 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
552 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
553 color="k", linestyle="dashed", lw=1)[0]
553 color="k", linestyle="dashed", lw=1)[0]
554 else:
554 else:
555 ax.collections.remove(ax.collections[0])
555 ax.collections.remove(ax.collections[0])
556 ax.plt = ax.pcolormesh(x, y, z[n].T,
556 ax.plt = ax.pcolormesh(x, y, z[n].T,
557 vmin=self.zmin,
557 vmin=self.zmin,
558 vmax=self.zmax,
558 vmax=self.zmax,
559 cmap=plt.get_cmap(self.colormap)
559 cmap=plt.get_cmap(self.colormap)
560 )
560 )
561 if self.showprofile:
561 if self.showprofile:
562 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
562 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
563 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
563 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
564
564
565 self.saveTime = self.min_time
565 self.saveTime = self.min_time
566
566
567
567
568 class PlotCOHData(PlotRTIData):
568 class PlotCOHData(PlotRTIData):
569 '''
569 '''
570 Plot for Coherence data
570 Plot for Coherence data
571 '''
571 '''
572
572
573 CODE = 'coh'
573 CODE = 'coh'
574
574
575 def setup(self):
575 def setup(self):
576 self.xaxis = 'time'
576 self.xaxis = 'time'
577 self.ncols = 1
577 self.ncols = 1
578 self.nrows = len(self.data.pairs)
578 self.nrows = len(self.data.pairs)
579 self.nplots = len(self.data.pairs)
579 self.nplots = len(self.data.pairs)
580 self.ylabel = 'Range [Km]'
580 self.ylabel = 'Range [Km]'
581 if self.CODE == 'coh':
581 if self.CODE == 'coh':
582 self.cb_label = ''
582 self.cb_label = ''
583 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
583 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
584 else:
584 else:
585 self.cb_label = 'Degrees'
585 self.cb_label = 'Degrees'
586 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
586 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
587
587
588
588
589 class PlotPHASEData(PlotCOHData):
589 class PlotPHASEData(PlotCOHData):
590 '''
590 '''
591 Plot for Phase map data
591 Plot for Phase map data
592 '''
592 '''
593
593
594 CODE = 'phase'
594 CODE = 'phase'
595 colormap = 'seismic'
595 colormap = 'seismic'
596
596
597
597
598 class PlotNoiseData(PlotData):
598 class PlotNoiseData(PlotData):
599 '''
599 '''
600 Plot for noise
600 Plot for noise
601 '''
601 '''
602
602
603 CODE = 'noise'
603 CODE = 'noise'
604
604
605 def setup(self):
605 def setup(self):
606 self.xaxis = 'time'
606 self.xaxis = 'time'
607 self.ncols = 1
607 self.ncols = 1
608 self.nrows = 1
608 self.nrows = 1
609 self.nplots = 1
609 self.nplots = 1
610 self.ylabel = 'Intensity [dB]'
610 self.ylabel = 'Intensity [dB]'
611 self.titles = ['Noise']
611 self.titles = ['Noise']
612 self.colorbar = False
612 self.colorbar = False
613
613
614 def plot(self):
614 def plot(self):
615
615
616 x = self.data.times
616 x = self.data.times
617 xmin = self.min_time
617 xmin = self.min_time
618 xmax = xmin+self.xrange*60*60
618 xmax = xmin+self.xrange*60*60
619 Y = self.data[self.CODE]
619 Y = self.data[self.CODE]
620
620
621 if self.axes[0].firsttime:
621 if self.axes[0].firsttime:
622 for ch in self.data.channels:
622 for ch in self.data.channels:
623 y = Y[ch]
623 y = Y[ch]
624 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
624 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
625 plt.legend()
625 plt.legend()
626 else:
626 else:
627 for ch in self.data.channels:
627 for ch in self.data.channels:
628 y = Y[ch]
628 y = Y[ch]
629 self.axes[0].lines[ch].set_data(x, y)
629 self.axes[0].lines[ch].set_data(x, y)
630
630
631 self.ymin = numpy.nanmin(Y) - 5
631 self.ymin = numpy.nanmin(Y) - 5
632 self.ymax = numpy.nanmax(Y) + 5
632 self.ymax = numpy.nanmax(Y) + 5
633 self.saveTime = self.min_time
633 self.saveTime = self.min_time
634
634
635
635
636 class PlotSNRData(PlotRTIData):
636 class PlotSNRData(PlotRTIData):
637 '''
637 '''
638 Plot for SNR Data
638 Plot for SNR Data
639 '''
639 '''
640
640
641 CODE = 'snr'
641 CODE = 'snr'
642 colormap = 'jet'
642 colormap = 'jet'
643
643
644
644
645 class PlotDOPData(PlotRTIData):
645 class PlotDOPData(PlotRTIData):
646 '''
646 '''
647 Plot for DOPPLER Data
647 Plot for DOPPLER Data
648 '''
648 '''
649
649
650 CODE = 'dop'
650 CODE = 'dop'
651 colormap = 'jet'
651 colormap = 'jet'
652
652
653
653
654 class PlotSkyMapData(PlotData):
654 class PlotSkyMapData(PlotData):
655 '''
655 '''
656 Plot for meteors detection data
656 Plot for meteors detection data
657 '''
657 '''
658
658
659 CODE = 'met'
659 CODE = 'met'
660
660
661 def setup(self):
661 def setup(self):
662
662
663 self.ncols = 1
663 self.ncols = 1
664 self.nrows = 1
664 self.nrows = 1
665 self.width = 7.2
665 self.width = 7.2
666 self.height = 7.2
666 self.height = 7.2
667
667
668 self.xlabel = 'Zonal Zenith Angle (deg)'
668 self.xlabel = 'Zonal Zenith Angle (deg)'
669 self.ylabel = 'Meridional Zenith Angle (deg)'
669 self.ylabel = 'Meridional Zenith Angle (deg)'
670
670
671 if self.figure is None:
671 if self.figure is None:
672 self.figure = plt.figure(figsize=(self.width, self.height),
672 self.figure = plt.figure(figsize=(self.width, self.height),
673 edgecolor='k',
673 edgecolor='k',
674 facecolor='w')
674 facecolor='w')
675 else:
675 else:
676 self.figure.clf()
676 self.figure.clf()
677
677
678 self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
678 self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
679 self.ax.firsttime = True
679 self.ax.firsttime = True
680
680
681
681
682 def plot(self):
682 def plot(self):
683
683
684 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.data.times])
684 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.data.times])
685 error = arrayParameters[:,-1]
685 error = arrayParameters[:,-1]
686 indValid = numpy.where(error == 0)[0]
686 indValid = numpy.where(error == 0)[0]
687 finalMeteor = arrayParameters[indValid,:]
687 finalMeteor = arrayParameters[indValid,:]
688 finalAzimuth = finalMeteor[:,3]
688 finalAzimuth = finalMeteor[:,3]
689 finalZenith = finalMeteor[:,4]
689 finalZenith = finalMeteor[:,4]
690
690
691 x = finalAzimuth*numpy.pi/180
691 x = finalAzimuth*numpy.pi/180
692 y = finalZenith
692 y = finalZenith
693
693
694 if self.ax.firsttime:
694 if self.ax.firsttime:
695 self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
695 self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
696 self.ax.set_ylim(0,90)
696 self.ax.set_ylim(0,90)
697 self.ax.set_yticks(numpy.arange(0,90,20))
697 self.ax.set_yticks(numpy.arange(0,90,20))
698 self.ax.set_xlabel(self.xlabel)
698 self.ax.set_xlabel(self.xlabel)
699 self.ax.set_ylabel(self.ylabel)
699 self.ax.set_ylabel(self.ylabel)
700 self.ax.yaxis.labelpad = 40
700 self.ax.yaxis.labelpad = 40
701 self.ax.firsttime = False
701 self.ax.firsttime = False
702 else:
702 else:
703 self.ax.plot.set_data(x, y)
703 self.ax.plot.set_data(x, y)
704
704
705
705
706 dt1 = datetime.datetime.fromtimestamp(self.min_time).strftime('%y/%m/%d %H:%M:%S')
706 dt1 = datetime.datetime.fromtimestamp(self.min_time).strftime('%y/%m/%d %H:%M:%S')
707 dt2 = datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')
707 dt2 = datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')
708 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
708 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
709 dt2,
709 dt2,
710 len(x))
710 len(x))
711 self.ax.set_title(title, size=8)
711 self.ax.set_title(title, size=8)
712
712
713 self.saveTime = self.max_time
713 self.saveTime = self.max_time
714
714
715 class PlotParamData(PlotRTIData):
715 class PlotParamData(PlotRTIData):
716 '''
716 '''
717 Plot for data_param object
717 Plot for data_param object
718 '''
718 '''
719
719
720 CODE = 'param'
720 CODE = 'param'
721 colormap = 'seismic'
721 colormap = 'seismic'
722
722
723 def setup(self):
723 def setup(self):
724 self.xaxis = 'time'
724 self.xaxis = 'time'
725 self.ncols = 1
725 self.ncols = 1
726 self.nrows = self.data.shape(self.CODE)[0]
726 self.nrows = self.data.shape(self.CODE)[0]
727 self.nplots = self.nrows
727 self.nplots = self.nrows
728 if self.showSNR:
728 if self.showSNR:
729 self.nrows += 1
729 self.nrows += 1
730 self.nplots += 1
730
731
731 self.ylabel = 'Height [Km]'
732 self.ylabel = 'Height [Km]'
732 self.titles = self.data.parameters \
733 self.titles = self.data.parameters \
733 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
734 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
734 if self.showSNR:
735 if self.showSNR:
735 self.titles.append('SNR')
736 self.titles.append('SNR')
736
737
737 def plot(self):
738 def plot(self):
738 self.data.normalize_heights()
739 self.data.normalize_heights()
739 self.x = self.data.times
740 self.x = self.data.times
740 self.y = self.data.heights
741 self.y = self.data.heights
741 if self.showSNR:
742 if self.showSNR:
742 self.z = numpy.concatenate(
743 self.z = numpy.concatenate(
743 (self.data[self.CODE], self.data['snr'])
744 (self.data[self.CODE], self.data['snr'])
744 )
745 )
745 else:
746 else:
746 self.z = self.data[self.CODE]
747 self.z = self.data[self.CODE]
747
748
748 self.z = numpy.ma.masked_invalid(self.z)
749 self.z = numpy.ma.masked_invalid(self.z)
749
750
750 for n, ax in enumerate(self.axes):
751 for n, ax in enumerate(self.axes):
751
752
752 x, y, z = self.fill_gaps(*self.decimate())
753 x, y, z = self.fill_gaps(*self.decimate())
753
754
754 if ax.firsttime:
755 if ax.firsttime:
755 if self.zlimits is not None:
756 if self.zlimits is not None:
756 self.zmin, self.zmax = self.zlimits[n]
757 self.zmin, self.zmax = self.zlimits[n]
757 self.zmax = self.zmax if self.zmax is not None else numpy.nanmax(abs(self.z[:-1, :]))
758 self.zmax = self.zmax if self.zmax is not None else numpy.nanmax(abs(self.z[:-1, :]))
758 self.zmin = self.zmin if self.zmin is not None else -self.zmax
759 self.zmin = self.zmin if self.zmin is not None else -self.zmax
759 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
760 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
760 vmin=self.zmin,
761 vmin=self.zmin,
761 vmax=self.zmax,
762 vmax=self.zmax,
762 cmap=self.cmaps[n]
763 cmap=self.cmaps[n]
763 )
764 )
764 else:
765 else:
765 if self.zlimits is not None:
766 if self.zlimits is not None:
766 self.zmin, self.zmax = self.zlimits[n]
767 self.zmin, self.zmax = self.zlimits[n]
767 ax.collections.remove(ax.collections[0])
768 ax.collections.remove(ax.collections[0])
768 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
769 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
769 vmin=self.zmin,
770 vmin=self.zmin,
770 vmax=self.zmax,
771 vmax=self.zmax,
771 cmap=self.cmaps[n]
772 cmap=self.cmaps[n]
772 )
773 )
773
774
774 self.saveTime = self.min_time
775 self.saveTime = self.min_time
775
776
776 class PlotOuputData(PlotParamData):
777 class PlotOuputData(PlotParamData):
777 '''
778 '''
778 Plot data_output object
779 Plot data_output object
779 '''
780 '''
780
781
781 CODE = 'output'
782 CODE = 'output'
782 colormap = 'seismic' No newline at end of file
783 colormap = 'seismic'
@@ -1,2154 +1,2151
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4 import inspect
4 import inspect
5 from figure import Figure, isRealtime, isTimeInHourRange
5 from figure import Figure, isRealtime, isTimeInHourRange
6 from plotting_codes import *
6 from plotting_codes import *
7
7
8
8
9 class FitGauPlot(Figure):
9 class FitGauPlot(Figure):
10
10
11 isConfig = None
11 isConfig = None
12 __nsubplots = None
12 __nsubplots = None
13
13
14 WIDTHPROF = None
14 WIDTHPROF = None
15 HEIGHTPROF = None
15 HEIGHTPROF = None
16 PREFIX = 'fitgau'
16 PREFIX = 'fitgau'
17
17
18 def __init__(self, **kwargs):
18 def __init__(self, **kwargs):
19 Figure.__init__(self, **kwargs)
19 Figure.__init__(self, **kwargs)
20 self.isConfig = False
20 self.isConfig = False
21 self.__nsubplots = 1
21 self.__nsubplots = 1
22
22
23 self.WIDTH = 250
23 self.WIDTH = 250
24 self.HEIGHT = 250
24 self.HEIGHT = 250
25 self.WIDTHPROF = 120
25 self.WIDTHPROF = 120
26 self.HEIGHTPROF = 0
26 self.HEIGHTPROF = 0
27 self.counter_imagwr = 0
27 self.counter_imagwr = 0
28
28
29 self.PLOT_CODE = SPEC_CODE
29 self.PLOT_CODE = SPEC_CODE
30
30
31 self.FTP_WEI = None
31 self.FTP_WEI = None
32 self.EXP_CODE = None
32 self.EXP_CODE = None
33 self.SUB_EXP_CODE = None
33 self.SUB_EXP_CODE = None
34 self.PLOT_POS = None
34 self.PLOT_POS = None
35
35
36 self.__xfilter_ena = False
36 self.__xfilter_ena = False
37 self.__yfilter_ena = False
37 self.__yfilter_ena = False
38
38
39 def getSubplots(self):
39 def getSubplots(self):
40
40
41 ncol = int(numpy.sqrt(self.nplots)+0.9)
41 ncol = int(numpy.sqrt(self.nplots)+0.9)
42 nrow = int(self.nplots*1./ncol + 0.9)
42 nrow = int(self.nplots*1./ncol + 0.9)
43
43
44 return nrow, ncol
44 return nrow, ncol
45
45
46 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
46 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
47
47
48 self.__showprofile = showprofile
48 self.__showprofile = showprofile
49 self.nplots = nplots
49 self.nplots = nplots
50
50
51 ncolspan = 1
51 ncolspan = 1
52 colspan = 1
52 colspan = 1
53 if showprofile:
53 if showprofile:
54 ncolspan = 3
54 ncolspan = 3
55 colspan = 2
55 colspan = 2
56 self.__nsubplots = 2
56 self.__nsubplots = 2
57
57
58 self.createFigure(id = id,
58 self.createFigure(id = id,
59 wintitle = wintitle,
59 wintitle = wintitle,
60 widthplot = self.WIDTH + self.WIDTHPROF,
60 widthplot = self.WIDTH + self.WIDTHPROF,
61 heightplot = self.HEIGHT + self.HEIGHTPROF,
61 heightplot = self.HEIGHT + self.HEIGHTPROF,
62 show=show)
62 show=show)
63
63
64 nrow, ncol = self.getSubplots()
64 nrow, ncol = self.getSubplots()
65
65
66 counter = 0
66 counter = 0
67 for y in range(nrow):
67 for y in range(nrow):
68 for x in range(ncol):
68 for x in range(ncol):
69
69
70 if counter >= self.nplots:
70 if counter >= self.nplots:
71 break
71 break
72
72
73 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
73 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
74
74
75 if showprofile:
75 if showprofile:
76 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
76 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
77
77
78 counter += 1
78 counter += 1
79
79
80 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
80 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
81 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
81 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
82 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
82 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
83 server=None, folder=None, username=None, password=None,
83 server=None, folder=None, username=None, password=None,
84 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
84 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
85 xaxis="frequency", colormap='jet', normFactor=None , GauSelector = 1):
85 xaxis="frequency", colormap='jet', normFactor=None , GauSelector = 1):
86
86
87 """
87 """
88
88
89 Input:
89 Input:
90 dataOut :
90 dataOut :
91 id :
91 id :
92 wintitle :
92 wintitle :
93 channelList :
93 channelList :
94 showProfile :
94 showProfile :
95 xmin : None,
95 xmin : None,
96 xmax : None,
96 xmax : None,
97 ymin : None,
97 ymin : None,
98 ymax : None,
98 ymax : None,
99 zmin : None,
99 zmin : None,
100 zmax : None
100 zmax : None
101 """
101 """
102 if realtime:
102 if realtime:
103 if not(isRealtime(utcdatatime = dataOut.utctime)):
103 if not(isRealtime(utcdatatime = dataOut.utctime)):
104 print 'Skipping this plot function'
104 print 'Skipping this plot function'
105 return
105 return
106
106
107 if channelList == None:
107 if channelList == None:
108 channelIndexList = dataOut.channelIndexList
108 channelIndexList = dataOut.channelIndexList
109 else:
109 else:
110 channelIndexList = []
110 channelIndexList = []
111 for channel in channelList:
111 for channel in channelList:
112 if channel not in dataOut.channelList:
112 if channel not in dataOut.channelList:
113 raise ValueError, "Channel %d is not in dataOut.channelList" %channel
113 raise ValueError, "Channel %d is not in dataOut.channelList" %channel
114 channelIndexList.append(dataOut.channelList.index(channel))
114 channelIndexList.append(dataOut.channelList.index(channel))
115
115
116 # if normFactor is None:
116 # if normFactor is None:
117 # factor = dataOut.normFactor
117 # factor = dataOut.normFactor
118 # else:
118 # else:
119 # factor = normFactor
119 # factor = normFactor
120 if xaxis == "frequency":
120 if xaxis == "frequency":
121 x = dataOut.spc_range[0]
121 x = dataOut.spc_range[0]
122 xlabel = "Frequency (kHz)"
122 xlabel = "Frequency (kHz)"
123
123
124 elif xaxis == "time":
124 elif xaxis == "time":
125 x = dataOut.spc_range[1]
125 x = dataOut.spc_range[1]
126 xlabel = "Time (ms)"
126 xlabel = "Time (ms)"
127
127
128 else:
128 else:
129 x = dataOut.spc_range[2]
129 x = dataOut.spc_range[2]
130 xlabel = "Velocity (m/s)"
130 xlabel = "Velocity (m/s)"
131
131
132 ylabel = "Range (Km)"
132 ylabel = "Range (Km)"
133
133
134 y = dataOut.getHeiRange()
134 y = dataOut.getHeiRange()
135
135
136 z = dataOut.GauSPC[:,GauSelector,:,:] #GauSelector] #dataOut.data_spc/factor
136 z = dataOut.GauSPC[:,GauSelector,:,:] #GauSelector] #dataOut.data_spc/factor
137 print 'GausSPC', z[0,32,10:40]
137 print 'GausSPC', z[0,32,10:40]
138 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
138 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
139 zdB = 10*numpy.log10(z)
139 zdB = 10*numpy.log10(z)
140
140
141 avg = numpy.average(z, axis=1)
141 avg = numpy.average(z, axis=1)
142 avgdB = 10*numpy.log10(avg)
142 avgdB = 10*numpy.log10(avg)
143
143
144 noise = dataOut.spc_noise
144 noise = dataOut.spc_noise
145 noisedB = 10*numpy.log10(noise)
145 noisedB = 10*numpy.log10(noise)
146
146
147 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
147 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
148 title = wintitle + " Spectra"
148 title = wintitle + " Spectra"
149 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
149 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
150 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
150 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
151
151
152 if not self.isConfig:
152 if not self.isConfig:
153
153
154 nplots = len(channelIndexList)
154 nplots = len(channelIndexList)
155
155
156 self.setup(id=id,
156 self.setup(id=id,
157 nplots=nplots,
157 nplots=nplots,
158 wintitle=wintitle,
158 wintitle=wintitle,
159 showprofile=showprofile,
159 showprofile=showprofile,
160 show=show)
160 show=show)
161
161
162 if xmin == None: xmin = numpy.nanmin(x)
162 if xmin == None: xmin = numpy.nanmin(x)
163 if xmax == None: xmax = numpy.nanmax(x)
163 if xmax == None: xmax = numpy.nanmax(x)
164 if ymin == None: ymin = numpy.nanmin(y)
164 if ymin == None: ymin = numpy.nanmin(y)
165 if ymax == None: ymax = numpy.nanmax(y)
165 if ymax == None: ymax = numpy.nanmax(y)
166 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
166 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
167 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
167 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
168
168
169 self.FTP_WEI = ftp_wei
169 self.FTP_WEI = ftp_wei
170 self.EXP_CODE = exp_code
170 self.EXP_CODE = exp_code
171 self.SUB_EXP_CODE = sub_exp_code
171 self.SUB_EXP_CODE = sub_exp_code
172 self.PLOT_POS = plot_pos
172 self.PLOT_POS = plot_pos
173
173
174 self.isConfig = True
174 self.isConfig = True
175
175
176 self.setWinTitle(title)
176 self.setWinTitle(title)
177
177
178 for i in range(self.nplots):
178 for i in range(self.nplots):
179 index = channelIndexList[i]
179 index = channelIndexList[i]
180 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
180 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
181 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
181 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
182 if len(dataOut.beam.codeList) != 0:
182 if len(dataOut.beam.codeList) != 0:
183 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
183 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
184
184
185 axes = self.axesList[i*self.__nsubplots]
185 axes = self.axesList[i*self.__nsubplots]
186 axes.pcolor(x, y, zdB[index,:,:],
186 axes.pcolor(x, y, zdB[index,:,:],
187 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
187 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
188 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
188 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
189 ticksize=9, cblabel='')
189 ticksize=9, cblabel='')
190
190
191 if self.__showprofile:
191 if self.__showprofile:
192 axes = self.axesList[i*self.__nsubplots +1]
192 axes = self.axesList[i*self.__nsubplots +1]
193 axes.pline(avgdB[index,:], y,
193 axes.pline(avgdB[index,:], y,
194 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
194 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
195 xlabel='dB', ylabel='', title='',
195 xlabel='dB', ylabel='', title='',
196 ytick_visible=False,
196 ytick_visible=False,
197 grid='x')
197 grid='x')
198
198
199 noiseline = numpy.repeat(noisedB[index], len(y))
199 noiseline = numpy.repeat(noisedB[index], len(y))
200 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
200 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
201
201
202 self.draw()
202 self.draw()
203
203
204 if figfile == None:
204 if figfile == None:
205 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
205 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
206 name = str_datetime
206 name = str_datetime
207 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
207 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
208 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
208 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
209 figfile = self.getFilename(name)
209 figfile = self.getFilename(name)
210
210
211 self.save(figpath=figpath,
211 self.save(figpath=figpath,
212 figfile=figfile,
212 figfile=figfile,
213 save=save,
213 save=save,
214 ftp=ftp,
214 ftp=ftp,
215 wr_period=wr_period,
215 wr_period=wr_period,
216 thisDatetime=thisDatetime)
216 thisDatetime=thisDatetime)
217
217
218
218
219
219
220 class MomentsPlot(Figure):
220 class MomentsPlot(Figure):
221
221
222 isConfig = None
222 isConfig = None
223 __nsubplots = None
223 __nsubplots = None
224
224
225 WIDTHPROF = None
225 WIDTHPROF = None
226 HEIGHTPROF = None
226 HEIGHTPROF = None
227 PREFIX = 'prm'
227 PREFIX = 'prm'
228 def __init__(self, **kwargs):
228 def __init__(self, **kwargs):
229 Figure.__init__(self, **kwargs)
229 Figure.__init__(self, **kwargs)
230 self.isConfig = False
230 self.isConfig = False
231 self.__nsubplots = 1
231 self.__nsubplots = 1
232
232
233 self.WIDTH = 280
233 self.WIDTH = 280
234 self.HEIGHT = 250
234 self.HEIGHT = 250
235 self.WIDTHPROF = 120
235 self.WIDTHPROF = 120
236 self.HEIGHTPROF = 0
236 self.HEIGHTPROF = 0
237 self.counter_imagwr = 0
237 self.counter_imagwr = 0
238
238
239 self.PLOT_CODE = MOMENTS_CODE
239 self.PLOT_CODE = MOMENTS_CODE
240
240
241 self.FTP_WEI = None
241 self.FTP_WEI = None
242 self.EXP_CODE = None
242 self.EXP_CODE = None
243 self.SUB_EXP_CODE = None
243 self.SUB_EXP_CODE = None
244 self.PLOT_POS = None
244 self.PLOT_POS = None
245
245
246 def getSubplots(self):
246 def getSubplots(self):
247
247
248 ncol = int(numpy.sqrt(self.nplots)+0.9)
248 ncol = int(numpy.sqrt(self.nplots)+0.9)
249 nrow = int(self.nplots*1./ncol + 0.9)
249 nrow = int(self.nplots*1./ncol + 0.9)
250
250
251 return nrow, ncol
251 return nrow, ncol
252
252
253 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
253 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
254
254
255 self.__showprofile = showprofile
255 self.__showprofile = showprofile
256 self.nplots = nplots
256 self.nplots = nplots
257
257
258 ncolspan = 1
258 ncolspan = 1
259 colspan = 1
259 colspan = 1
260 if showprofile:
260 if showprofile:
261 ncolspan = 3
261 ncolspan = 3
262 colspan = 2
262 colspan = 2
263 self.__nsubplots = 2
263 self.__nsubplots = 2
264
264
265 self.createFigure(id = id,
265 self.createFigure(id = id,
266 wintitle = wintitle,
266 wintitle = wintitle,
267 widthplot = self.WIDTH + self.WIDTHPROF,
267 widthplot = self.WIDTH + self.WIDTHPROF,
268 heightplot = self.HEIGHT + self.HEIGHTPROF,
268 heightplot = self.HEIGHT + self.HEIGHTPROF,
269 show=show)
269 show=show)
270
270
271 nrow, ncol = self.getSubplots()
271 nrow, ncol = self.getSubplots()
272
272
273 counter = 0
273 counter = 0
274 for y in range(nrow):
274 for y in range(nrow):
275 for x in range(ncol):
275 for x in range(ncol):
276
276
277 if counter >= self.nplots:
277 if counter >= self.nplots:
278 break
278 break
279
279
280 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
280 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
281
281
282 if showprofile:
282 if showprofile:
283 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
283 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
284
284
285 counter += 1
285 counter += 1
286
286
287 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
287 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
288 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
288 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
289 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
289 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
290 server=None, folder=None, username=None, password=None,
290 server=None, folder=None, username=None, password=None,
291 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
291 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
292
292
293 """
293 """
294
294
295 Input:
295 Input:
296 dataOut :
296 dataOut :
297 id :
297 id :
298 wintitle :
298 wintitle :
299 channelList :
299 channelList :
300 showProfile :
300 showProfile :
301 xmin : None,
301 xmin : None,
302 xmax : None,
302 xmax : None,
303 ymin : None,
303 ymin : None,
304 ymax : None,
304 ymax : None,
305 zmin : None,
305 zmin : None,
306 zmax : None
306 zmax : None
307 """
307 """
308
308
309 if dataOut.flagNoData:
309 if dataOut.flagNoData:
310 return None
310 return None
311
311
312 if realtime:
312 if realtime:
313 if not(isRealtime(utcdatatime = dataOut.utctime)):
313 if not(isRealtime(utcdatatime = dataOut.utctime)):
314 print 'Skipping this plot function'
314 print 'Skipping this plot function'
315 return
315 return
316
316
317 if channelList == None:
317 if channelList == None:
318 channelIndexList = dataOut.channelIndexList
318 channelIndexList = dataOut.channelIndexList
319 else:
319 else:
320 channelIndexList = []
320 channelIndexList = []
321 for channel in channelList:
321 for channel in channelList:
322 if channel not in dataOut.channelList:
322 if channel not in dataOut.channelList:
323 raise ValueError, "Channel %d is not in dataOut.channelList"
323 raise ValueError, "Channel %d is not in dataOut.channelList"
324 channelIndexList.append(dataOut.channelList.index(channel))
324 channelIndexList.append(dataOut.channelList.index(channel))
325
325
326 factor = dataOut.normFactor
326 factor = dataOut.normFactor
327 x = dataOut.abscissaList
327 x = dataOut.abscissaList
328 y = dataOut.heightList
328 y = dataOut.heightList
329
329
330 z = dataOut.data_pre[channelIndexList,:,:]/factor
330 z = dataOut.data_pre[channelIndexList,:,:]/factor
331 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
331 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
332 avg = numpy.average(z, axis=1)
332 avg = numpy.average(z, axis=1)
333 noise = dataOut.noise/factor
333 noise = dataOut.noise/factor
334
334
335 zdB = 10*numpy.log10(z)
335 zdB = 10*numpy.log10(z)
336 avgdB = 10*numpy.log10(avg)
336 avgdB = 10*numpy.log10(avg)
337 noisedB = 10*numpy.log10(noise)
337 noisedB = 10*numpy.log10(noise)
338
338
339 #thisDatetime = dataOut.datatime
339 #thisDatetime = dataOut.datatime
340 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
340 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
341 title = wintitle + " Parameters"
341 title = wintitle + " Parameters"
342 xlabel = "Velocity (m/s)"
342 xlabel = "Velocity (m/s)"
343 ylabel = "Range (Km)"
343 ylabel = "Range (Km)"
344
344
345 update_figfile = False
345 update_figfile = False
346
346
347 if not self.isConfig:
347 if not self.isConfig:
348
348
349 nplots = len(channelIndexList)
349 nplots = len(channelIndexList)
350
350
351 self.setup(id=id,
351 self.setup(id=id,
352 nplots=nplots,
352 nplots=nplots,
353 wintitle=wintitle,
353 wintitle=wintitle,
354 showprofile=showprofile,
354 showprofile=showprofile,
355 show=show)
355 show=show)
356
356
357 if xmin == None: xmin = numpy.nanmin(x)
357 if xmin == None: xmin = numpy.nanmin(x)
358 if xmax == None: xmax = numpy.nanmax(x)
358 if xmax == None: xmax = numpy.nanmax(x)
359 if ymin == None: ymin = numpy.nanmin(y)
359 if ymin == None: ymin = numpy.nanmin(y)
360 if ymax == None: ymax = numpy.nanmax(y)
360 if ymax == None: ymax = numpy.nanmax(y)
361 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
361 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
362 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
362 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
363
363
364 self.FTP_WEI = ftp_wei
364 self.FTP_WEI = ftp_wei
365 self.EXP_CODE = exp_code
365 self.EXP_CODE = exp_code
366 self.SUB_EXP_CODE = sub_exp_code
366 self.SUB_EXP_CODE = sub_exp_code
367 self.PLOT_POS = plot_pos
367 self.PLOT_POS = plot_pos
368
368
369 self.isConfig = True
369 self.isConfig = True
370 update_figfile = True
370 update_figfile = True
371
371
372 self.setWinTitle(title)
372 self.setWinTitle(title)
373
373
374 for i in range(self.nplots):
374 for i in range(self.nplots):
375 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
375 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
376 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
376 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
377 axes = self.axesList[i*self.__nsubplots]
377 axes = self.axesList[i*self.__nsubplots]
378 axes.pcolor(x, y, zdB[i,:,:],
378 axes.pcolor(x, y, zdB[i,:,:],
379 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
379 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
380 xlabel=xlabel, ylabel=ylabel, title=title,
380 xlabel=xlabel, ylabel=ylabel, title=title,
381 ticksize=9, cblabel='')
381 ticksize=9, cblabel='')
382 #Mean Line
382 #Mean Line
383 mean = dataOut.data_param[i, 1, :]
383 mean = dataOut.data_param[i, 1, :]
384 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
384 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
385
385
386 if self.__showprofile:
386 if self.__showprofile:
387 axes = self.axesList[i*self.__nsubplots +1]
387 axes = self.axesList[i*self.__nsubplots +1]
388 axes.pline(avgdB[i], y,
388 axes.pline(avgdB[i], y,
389 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
389 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
390 xlabel='dB', ylabel='', title='',
390 xlabel='dB', ylabel='', title='',
391 ytick_visible=False,
391 ytick_visible=False,
392 grid='x')
392 grid='x')
393
393
394 noiseline = numpy.repeat(noisedB[i], len(y))
394 noiseline = numpy.repeat(noisedB[i], len(y))
395 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
395 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
396
396
397 self.draw()
397 self.draw()
398
398
399 self.save(figpath=figpath,
399 self.save(figpath=figpath,
400 figfile=figfile,
400 figfile=figfile,
401 save=save,
401 save=save,
402 ftp=ftp,
402 ftp=ftp,
403 wr_period=wr_period,
403 wr_period=wr_period,
404 thisDatetime=thisDatetime)
404 thisDatetime=thisDatetime)
405
405
406
406
407
407
408 class SkyMapPlot(Figure):
408 class SkyMapPlot(Figure):
409
409
410 __isConfig = None
410 __isConfig = None
411 __nsubplots = None
411 __nsubplots = None
412
412
413 WIDTHPROF = None
413 WIDTHPROF = None
414 HEIGHTPROF = None
414 HEIGHTPROF = None
415 PREFIX = 'mmap'
415 PREFIX = 'mmap'
416
416
417 def __init__(self, **kwargs):
417 def __init__(self, **kwargs):
418 Figure.__init__(self, **kwargs)
418 Figure.__init__(self, **kwargs)
419 self.isConfig = False
419 self.isConfig = False
420 self.__nsubplots = 1
420 self.__nsubplots = 1
421
421
422 # self.WIDTH = 280
422 # self.WIDTH = 280
423 # self.HEIGHT = 250
423 # self.HEIGHT = 250
424 self.WIDTH = 600
424 self.WIDTH = 600
425 self.HEIGHT = 600
425 self.HEIGHT = 600
426 self.WIDTHPROF = 120
426 self.WIDTHPROF = 120
427 self.HEIGHTPROF = 0
427 self.HEIGHTPROF = 0
428 self.counter_imagwr = 0
428 self.counter_imagwr = 0
429
429
430 self.PLOT_CODE = MSKYMAP_CODE
430 self.PLOT_CODE = MSKYMAP_CODE
431
431
432 self.FTP_WEI = None
432 self.FTP_WEI = None
433 self.EXP_CODE = None
433 self.EXP_CODE = None
434 self.SUB_EXP_CODE = None
434 self.SUB_EXP_CODE = None
435 self.PLOT_POS = None
435 self.PLOT_POS = None
436
436
437 def getSubplots(self):
437 def getSubplots(self):
438
438
439 ncol = int(numpy.sqrt(self.nplots)+0.9)
439 ncol = int(numpy.sqrt(self.nplots)+0.9)
440 nrow = int(self.nplots*1./ncol + 0.9)
440 nrow = int(self.nplots*1./ncol + 0.9)
441
441
442 return nrow, ncol
442 return nrow, ncol
443
443
444 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
444 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
445
445
446 self.__showprofile = showprofile
446 self.__showprofile = showprofile
447 self.nplots = nplots
447 self.nplots = nplots
448
448
449 ncolspan = 1
449 ncolspan = 1
450 colspan = 1
450 colspan = 1
451
451
452 self.createFigure(id = id,
452 self.createFigure(id = id,
453 wintitle = wintitle,
453 wintitle = wintitle,
454 widthplot = self.WIDTH, #+ self.WIDTHPROF,
454 widthplot = self.WIDTH, #+ self.WIDTHPROF,
455 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
455 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
456 show=show)
456 show=show)
457
457
458 nrow, ncol = 1,1
458 nrow, ncol = 1,1
459 counter = 0
459 counter = 0
460 x = 0
460 x = 0
461 y = 0
461 y = 0
462 self.addAxes(1, 1, 0, 0, 1, 1, True)
462 self.addAxes(1, 1, 0, 0, 1, 1, True)
463
463
464 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
464 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
465 tmin=0, tmax=24, timerange=None,
465 tmin=0, tmax=24, timerange=None,
466 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
466 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
467 server=None, folder=None, username=None, password=None,
467 server=None, folder=None, username=None, password=None,
468 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
468 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
469
469
470 """
470 """
471
471
472 Input:
472 Input:
473 dataOut :
473 dataOut :
474 id :
474 id :
475 wintitle :
475 wintitle :
476 channelList :
476 channelList :
477 showProfile :
477 showProfile :
478 xmin : None,
478 xmin : None,
479 xmax : None,
479 xmax : None,
480 ymin : None,
480 ymin : None,
481 ymax : None,
481 ymax : None,
482 zmin : None,
482 zmin : None,
483 zmax : None
483 zmax : None
484 """
484 """
485
485
486 arrayParameters = dataOut.data_param
486 arrayParameters = dataOut.data_param
487 error = arrayParameters[:,-1]
487 error = arrayParameters[:,-1]
488 indValid = numpy.where(error == 0)[0]
488 indValid = numpy.where(error == 0)[0]
489 finalMeteor = arrayParameters[indValid,:]
489 finalMeteor = arrayParameters[indValid,:]
490 finalAzimuth = finalMeteor[:,3]
490 finalAzimuth = finalMeteor[:,3]
491 finalZenith = finalMeteor[:,4]
491 finalZenith = finalMeteor[:,4]
492
492
493 x = finalAzimuth*numpy.pi/180
493 x = finalAzimuth*numpy.pi/180
494 y = finalZenith
494 y = finalZenith
495 x1 = [dataOut.ltctime, dataOut.ltctime]
495 x1 = [dataOut.ltctime, dataOut.ltctime]
496
496
497 #thisDatetime = dataOut.datatime
497 #thisDatetime = dataOut.datatime
498 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
498 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
499 title = wintitle + " Parameters"
499 title = wintitle + " Parameters"
500 xlabel = "Zonal Zenith Angle (deg) "
500 xlabel = "Zonal Zenith Angle (deg) "
501 ylabel = "Meridional Zenith Angle (deg)"
501 ylabel = "Meridional Zenith Angle (deg)"
502 update_figfile = False
502 update_figfile = False
503
503
504 if not self.isConfig:
504 if not self.isConfig:
505
505
506 nplots = 1
506 nplots = 1
507
507
508 self.setup(id=id,
508 self.setup(id=id,
509 nplots=nplots,
509 nplots=nplots,
510 wintitle=wintitle,
510 wintitle=wintitle,
511 showprofile=showprofile,
511 showprofile=showprofile,
512 show=show)
512 show=show)
513
513
514 if self.xmin is None and self.xmax is None:
514 if self.xmin is None and self.xmax is None:
515 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
515 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
516
516
517 if timerange != None:
517 if timerange != None:
518 self.timerange = timerange
518 self.timerange = timerange
519 else:
519 else:
520 self.timerange = self.xmax - self.xmin
520 self.timerange = self.xmax - self.xmin
521
521
522 self.FTP_WEI = ftp_wei
522 self.FTP_WEI = ftp_wei
523 self.EXP_CODE = exp_code
523 self.EXP_CODE = exp_code
524 self.SUB_EXP_CODE = sub_exp_code
524 self.SUB_EXP_CODE = sub_exp_code
525 self.PLOT_POS = plot_pos
525 self.PLOT_POS = plot_pos
526 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
526 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
527 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
527 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
528 self.isConfig = True
528 self.isConfig = True
529 update_figfile = True
529 update_figfile = True
530
530
531 self.setWinTitle(title)
531 self.setWinTitle(title)
532
532
533 i = 0
533 i = 0
534 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
534 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
535
535
536 axes = self.axesList[i*self.__nsubplots]
536 axes = self.axesList[i*self.__nsubplots]
537 nevents = axes.x_buffer.shape[0] + x.shape[0]
537 nevents = axes.x_buffer.shape[0] + x.shape[0]
538 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
538 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
539 axes.polar(x, y,
539 axes.polar(x, y,
540 title=title, xlabel=xlabel, ylabel=ylabel,
540 title=title, xlabel=xlabel, ylabel=ylabel,
541 ticksize=9, cblabel='')
541 ticksize=9, cblabel='')
542
542
543 self.draw()
543 self.draw()
544
544
545 self.save(figpath=figpath,
545 self.save(figpath=figpath,
546 figfile=figfile,
546 figfile=figfile,
547 save=save,
547 save=save,
548 ftp=ftp,
548 ftp=ftp,
549 wr_period=wr_period,
549 wr_period=wr_period,
550 thisDatetime=thisDatetime,
550 thisDatetime=thisDatetime,
551 update_figfile=update_figfile)
551 update_figfile=update_figfile)
552
552
553 if dataOut.ltctime >= self.xmax:
553 if dataOut.ltctime >= self.xmax:
554 self.isConfigmagwr = wr_period
554 self.isConfigmagwr = wr_period
555 self.isConfig = False
555 self.isConfig = False
556 update_figfile = True
556 update_figfile = True
557 axes.__firsttime = True
557 axes.__firsttime = True
558 self.xmin += self.timerange
558 self.xmin += self.timerange
559 self.xmax += self.timerange
559 self.xmax += self.timerange
560
560
561
561
562
562
563
563
564 class WindProfilerPlot(Figure):
564 class WindProfilerPlot(Figure):
565
565
566 __isConfig = None
566 __isConfig = None
567 __nsubplots = None
567 __nsubplots = None
568
568
569 WIDTHPROF = None
569 WIDTHPROF = None
570 HEIGHTPROF = None
570 HEIGHTPROF = None
571 PREFIX = 'wind'
571 PREFIX = 'wind'
572
572
573 def __init__(self, **kwargs):
573 def __init__(self, **kwargs):
574 Figure.__init__(self, **kwargs)
574 Figure.__init__(self, **kwargs)
575 self.timerange = None
575 self.timerange = None
576 self.isConfig = False
576 self.isConfig = False
577 self.__nsubplots = 1
577 self.__nsubplots = 1
578
578
579 self.WIDTH = 800
579 self.WIDTH = 800
580 self.HEIGHT = 300
580 self.HEIGHT = 300
581 self.WIDTHPROF = 120
581 self.WIDTHPROF = 120
582 self.HEIGHTPROF = 0
582 self.HEIGHTPROF = 0
583 self.counter_imagwr = 0
583 self.counter_imagwr = 0
584
584
585 self.PLOT_CODE = WIND_CODE
585 self.PLOT_CODE = WIND_CODE
586
586
587 self.FTP_WEI = None
587 self.FTP_WEI = None
588 self.EXP_CODE = None
588 self.EXP_CODE = None
589 self.SUB_EXP_CODE = None
589 self.SUB_EXP_CODE = None
590 self.PLOT_POS = None
590 self.PLOT_POS = None
591 self.tmin = None
591 self.tmin = None
592 self.tmax = None
592 self.tmax = None
593
593
594 self.xmin = None
594 self.xmin = None
595 self.xmax = None
595 self.xmax = None
596
596
597 self.figfile = None
597 self.figfile = None
598
598
599 def getSubplots(self):
599 def getSubplots(self):
600
600
601 ncol = 1
601 ncol = 1
602 nrow = self.nplots
602 nrow = self.nplots
603
603
604 return nrow, ncol
604 return nrow, ncol
605
605
606 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
606 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
607
607
608 self.__showprofile = showprofile
608 self.__showprofile = showprofile
609 self.nplots = nplots
609 self.nplots = nplots
610
610
611 ncolspan = 1
611 ncolspan = 1
612 colspan = 1
612 colspan = 1
613
613
614 self.createFigure(id = id,
614 self.createFigure(id = id,
615 wintitle = wintitle,
615 wintitle = wintitle,
616 widthplot = self.WIDTH + self.WIDTHPROF,
616 widthplot = self.WIDTH + self.WIDTHPROF,
617 heightplot = self.HEIGHT + self.HEIGHTPROF,
617 heightplot = self.HEIGHT + self.HEIGHTPROF,
618 show=show)
618 show=show)
619
619
620 nrow, ncol = self.getSubplots()
620 nrow, ncol = self.getSubplots()
621
621
622 counter = 0
622 counter = 0
623 for y in range(nrow):
623 for y in range(nrow):
624 if counter >= self.nplots:
624 if counter >= self.nplots:
625 break
625 break
626
626
627 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
627 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
628 counter += 1
628 counter += 1
629
629
630 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
630 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
631 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
631 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
632 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
632 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
633 timerange=None, SNRthresh = None,
633 timerange=None, SNRthresh = None,
634 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
634 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
635 server=None, folder=None, username=None, password=None,
635 server=None, folder=None, username=None, password=None,
636 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
636 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
637 """
637 """
638
638
639 Input:
639 Input:
640 dataOut :
640 dataOut :
641 id :
641 id :
642 wintitle :
642 wintitle :
643 channelList :
643 channelList :
644 showProfile :
644 showProfile :
645 xmin : None,
645 xmin : None,
646 xmax : None,
646 xmax : None,
647 ymin : None,
647 ymin : None,
648 ymax : None,
648 ymax : None,
649 zmin : None,
649 zmin : None,
650 zmax : None
650 zmax : None
651 """
651 """
652
652
653 # if timerange is not None:
653 # if timerange is not None:
654 # self.timerange = timerange
654 # self.timerange = timerange
655 #
655 #
656 # tmin = None
656 # tmin = None
657 # tmax = None
657 # tmax = None
658
658
659 x = dataOut.getTimeRange1(dataOut.paramInterval)
659 x = dataOut.getTimeRange1(dataOut.paramInterval)
660 y = dataOut.heightList
660 y = dataOut.heightList
661 z = dataOut.data_output.copy()
661 z = dataOut.data_output.copy()
662 nplots = z.shape[0] #Number of wind dimensions estimated
662 nplots = z.shape[0] #Number of wind dimensions estimated
663 nplotsw = nplots
663 nplotsw = nplots
664
664
665
665
666 #If there is a SNR function defined
666 #If there is a SNR function defined
667 if dataOut.data_SNR is not None:
667 if dataOut.data_SNR is not None:
668 nplots += 1
668 nplots += 1
669 SNR = dataOut.data_SNR
669 SNR = dataOut.data_SNR
670 SNRavg = numpy.average(SNR, axis=0)
670 SNRavg = numpy.average(SNR, axis=0)
671
671
672 SNRdB = 10*numpy.log10(SNR)
672 SNRdB = 10*numpy.log10(SNR)
673 SNRavgdB = 10*numpy.log10(SNRavg)
673 SNRavgdB = 10*numpy.log10(SNRavg)
674
674
675 if SNRthresh == None: SNRthresh = -5.0
675 if SNRthresh == None: SNRthresh = -5.0
676 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
676 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
677
677
678 for i in range(nplotsw):
678 for i in range(nplotsw):
679 z[i,ind] = numpy.nan
679 z[i,ind] = numpy.nan
680
680
681 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
681 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
682 #thisDatetime = datetime.datetime.now()
682 #thisDatetime = datetime.datetime.now()
683 title = wintitle + "Wind"
683 title = wintitle + "Wind"
684 xlabel = ""
684 xlabel = ""
685 ylabel = "Height (km)"
685 ylabel = "Height (km)"
686 update_figfile = False
686 update_figfile = False
687
687
688 if not self.isConfig:
688 if not self.isConfig:
689
689
690 self.setup(id=id,
690 self.setup(id=id,
691 nplots=nplots,
691 nplots=nplots,
692 wintitle=wintitle,
692 wintitle=wintitle,
693 showprofile=showprofile,
693 showprofile=showprofile,
694 show=show)
694 show=show)
695
695
696 if timerange is not None:
696 if timerange is not None:
697 self.timerange = timerange
697 self.timerange = timerange
698
698
699 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
699 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
700
700
701 if ymin == None: ymin = numpy.nanmin(y)
701 if ymin == None: ymin = numpy.nanmin(y)
702 if ymax == None: ymax = numpy.nanmax(y)
702 if ymax == None: ymax = numpy.nanmax(y)
703
703
704 if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:]))
704 if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:]))
705 #if numpy.isnan(zmax): zmax = 50
705 #if numpy.isnan(zmax): zmax = 50
706 if zmin == None: zmin = -zmax
706 if zmin == None: zmin = -zmax
707
707
708 if nplotsw == 3:
708 if nplotsw == 3:
709 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
709 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
710 if zmin_ver == None: zmin_ver = -zmax_ver
710 if zmin_ver == None: zmin_ver = -zmax_ver
711
711
712 if dataOut.data_SNR is not None:
712 if dataOut.data_SNR is not None:
713 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
713 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
714 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
714 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
715
715
716
716
717 self.FTP_WEI = ftp_wei
717 self.FTP_WEI = ftp_wei
718 self.EXP_CODE = exp_code
718 self.EXP_CODE = exp_code
719 self.SUB_EXP_CODE = sub_exp_code
719 self.SUB_EXP_CODE = sub_exp_code
720 self.PLOT_POS = plot_pos
720 self.PLOT_POS = plot_pos
721
721
722 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
722 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
723 self.isConfig = True
723 self.isConfig = True
724 self.figfile = figfile
724 self.figfile = figfile
725 update_figfile = True
725 update_figfile = True
726
726
727 self.setWinTitle(title)
727 self.setWinTitle(title)
728
728
729 if ((self.xmax - x[1]) < (x[1]-x[0])):
729 if ((self.xmax - x[1]) < (x[1]-x[0])):
730 x[1] = self.xmax
730 x[1] = self.xmax
731
731
732 strWind = ['Zonal', 'Meridional', 'Vertical']
732 strWind = ['Zonal', 'Meridional', 'Vertical']
733 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
733 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
734 zmaxVector = [zmax, zmax, zmax_ver]
734 zmaxVector = [zmax, zmax, zmax_ver]
735 zminVector = [zmin, zmin, zmin_ver]
735 zminVector = [zmin, zmin, zmin_ver]
736 windFactor = [1,1,100]
736 windFactor = [1,1,100]
737
737
738 for i in range(nplotsw):
738 for i in range(nplotsw):
739
739
740 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
740 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
741 axes = self.axesList[i*self.__nsubplots]
741 axes = self.axesList[i*self.__nsubplots]
742
742
743 z1 = z[i,:].reshape((1,-1))*windFactor[i]
743 z1 = z[i,:].reshape((1,-1))*windFactor[i]
744 #z1=numpy.ma.masked_where(z1==0.,z1)
744 #z1=numpy.ma.masked_where(z1==0.,z1)
745
745
746 axes.pcolorbuffer(x, y, z1,
746 axes.pcolorbuffer(x, y, z1,
747 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
747 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
748 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
748 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
749 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
749 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
750
750
751 if dataOut.data_SNR is not None:
751 if dataOut.data_SNR is not None:
752 i += 1
752 i += 1
753 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
753 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
754 axes = self.axesList[i*self.__nsubplots]
754 axes = self.axesList[i*self.__nsubplots]
755 SNRavgdB = SNRavgdB.reshape((1,-1))
755 SNRavgdB = SNRavgdB.reshape((1,-1))
756 axes.pcolorbuffer(x, y, SNRavgdB,
756 axes.pcolorbuffer(x, y, SNRavgdB,
757 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
757 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
758 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
758 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
759 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
759 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
760
760
761 self.draw()
761 self.draw()
762
762
763 self.save(figpath=figpath,
763 self.save(figpath=figpath,
764 figfile=figfile,
764 figfile=figfile,
765 save=save,
765 save=save,
766 ftp=ftp,
766 ftp=ftp,
767 wr_period=wr_period,
767 wr_period=wr_period,
768 thisDatetime=thisDatetime,
768 thisDatetime=thisDatetime,
769 update_figfile=update_figfile)
769 update_figfile=update_figfile)
770
770
771 if dataOut.ltctime + dataOut.paramInterval >= self.xmax:
771 if dataOut.ltctime + dataOut.paramInterval >= self.xmax:
772 self.counter_imagwr = wr_period
772 self.counter_imagwr = wr_period
773 self.isConfig = False
773 self.isConfig = False
774 update_figfile = True
774 update_figfile = True
775
775
776
776
777 class ParametersPlot(Figure):
777 class ParametersPlot(Figure):
778
778
779 __isConfig = None
779 __isConfig = None
780 __nsubplots = None
780 __nsubplots = None
781
781
782 WIDTHPROF = None
782 WIDTHPROF = None
783 HEIGHTPROF = None
783 HEIGHTPROF = None
784 PREFIX = 'param'
784 PREFIX = 'param'
785
785
786 nplots = None
786 nplots = None
787 nchan = None
787 nchan = None
788
788
789 def __init__(self, **kwargs):
789 def __init__(self, **kwargs):
790 Figure.__init__(self, **kwargs)
790 Figure.__init__(self, **kwargs)
791 self.timerange = None
791 self.timerange = None
792 self.isConfig = False
792 self.isConfig = False
793 self.__nsubplots = 1
793 self.__nsubplots = 1
794
794
795 self.WIDTH = 800
795 self.WIDTH = 800
796 self.HEIGHT = 180
796 self.HEIGHT = 180
797 self.WIDTHPROF = 120
797 self.WIDTHPROF = 120
798 self.HEIGHTPROF = 0
798 self.HEIGHTPROF = 0
799 self.counter_imagwr = 0
799 self.counter_imagwr = 0
800
800
801 self.PLOT_CODE = RTI_CODE
801 self.PLOT_CODE = RTI_CODE
802
802
803 self.FTP_WEI = None
803 self.FTP_WEI = None
804 self.EXP_CODE = None
804 self.EXP_CODE = None
805 self.SUB_EXP_CODE = None
805 self.SUB_EXP_CODE = None
806 self.PLOT_POS = None
806 self.PLOT_POS = None
807 self.tmin = None
807 self.tmin = None
808 self.tmax = None
808 self.tmax = None
809
809
810 self.xmin = None
810 self.xmin = None
811 self.xmax = None
811 self.xmax = None
812
812
813 self.figfile = None
813 self.figfile = None
814
814
815 def getSubplots(self):
815 def getSubplots(self):
816
816
817 ncol = 1
817 ncol = 1
818 nrow = self.nplots
818 nrow = self.nplots
819
819
820 return nrow, ncol
820 return nrow, ncol
821
821
822 def setup(self, id, nplots, wintitle, show=True):
822 def setup(self, id, nplots, wintitle, show=True):
823
823
824 self.nplots = nplots
824 self.nplots = nplots
825
825
826 ncolspan = 1
826 ncolspan = 1
827 colspan = 1
827 colspan = 1
828
828
829 self.createFigure(id = id,
829 self.createFigure(id = id,
830 wintitle = wintitle,
830 wintitle = wintitle,
831 widthplot = self.WIDTH + self.WIDTHPROF,
831 widthplot = self.WIDTH + self.WIDTHPROF,
832 heightplot = self.HEIGHT + self.HEIGHTPROF,
832 heightplot = self.HEIGHT + self.HEIGHTPROF,
833 show=show)
833 show=show)
834
834
835 nrow, ncol = self.getSubplots()
835 nrow, ncol = self.getSubplots()
836
836
837 counter = 0
837 counter = 0
838 for y in range(nrow):
838 for y in range(nrow):
839 for x in range(ncol):
839 for x in range(ncol):
840
840
841 if counter >= self.nplots:
841 if counter >= self.nplots:
842 break
842 break
843
843
844 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
844 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
845
845
846 counter += 1
846 counter += 1
847
847
848 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet",
848 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet",
849 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
849 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
850 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
850 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
851 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
851 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
852 server=None, folder=None, username=None, password=None,
852 server=None, folder=None, username=None, password=None,
853 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None):
853 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None):
854 """
854 """
855
855
856 Input:
856 Input:
857 dataOut :
857 dataOut :
858 id :
858 id :
859 wintitle :
859 wintitle :
860 channelList :
860 channelList :
861 showProfile :
861 showProfile :
862 xmin : None,
862 xmin : None,
863 xmax : None,
863 xmax : None,
864 ymin : None,
864 ymin : None,
865 ymax : None,
865 ymax : None,
866 zmin : None,
866 zmin : None,
867 zmax : None
867 zmax : None
868 """
868 """
869
869
870 if HEIGHT is not None:
870 if HEIGHT is not None:
871 self.HEIGHT = HEIGHT
871 self.HEIGHT = HEIGHT
872
872
873
873
874 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
874 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
875 return
875 return
876
876
877 if channelList == None:
877 if channelList == None:
878 channelIndexList = range(dataOut.data_param.shape[0])
878 channelIndexList = range(dataOut.data_param.shape[0])
879 else:
879 else:
880 channelIndexList = []
880 channelIndexList = []
881 for channel in channelList:
881 for channel in channelList:
882 if channel not in dataOut.channelList:
882 if channel not in dataOut.channelList:
883 raise ValueError, "Channel %d is not in dataOut.channelList"
883 raise ValueError, "Channel %d is not in dataOut.channelList"
884 channelIndexList.append(dataOut.channelList.index(channel))
884 channelIndexList.append(dataOut.channelList.index(channel))
885
885
886 x = dataOut.getTimeRange1(dataOut.paramInterval)
886 x = dataOut.getTimeRange1(dataOut.paramInterval)
887 y = dataOut.getHeiRange()
887 y = dataOut.getHeiRange()
888
888
889 if dataOut.data_param.ndim == 3:
889 if dataOut.data_param.ndim == 3:
890 z = dataOut.data_param[channelIndexList,paramIndex,:]
890 z = dataOut.data_param[channelIndexList,paramIndex,:]
891 else:
891 else:
892 z = dataOut.data_param[channelIndexList,:]
892 z = dataOut.data_param[channelIndexList,:]
893
893
894 if showSNR:
894 if showSNR:
895 #SNR data
895 #SNR data
896 SNRarray = dataOut.data_SNR[channelIndexList,:]
896 SNRarray = dataOut.data_SNR[channelIndexList,:]
897 SNRdB = 10*numpy.log10(SNRarray)
897 SNRdB = 10*numpy.log10(SNRarray)
898 ind = numpy.where(SNRdB < SNRthresh)
898 ind = numpy.where(SNRdB < SNRthresh)
899 z[ind] = numpy.nan
899 z[ind] = numpy.nan
900
900
901 thisDatetime = dataOut.datatime
901 thisDatetime = dataOut.datatime
902 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
902 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
903 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
903 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
904 xlabel = ""
904 xlabel = ""
905 ylabel = "Range (Km)"
905 ylabel = "Range (Km)"
906
906
907 update_figfile = False
907 update_figfile = False
908
908
909 if not self.isConfig:
909 if not self.isConfig:
910
910
911 nchan = len(channelIndexList)
911 nchan = len(channelIndexList)
912 self.nchan = nchan
912 self.nchan = nchan
913 self.plotFact = 1
913 self.plotFact = 1
914 nplots = nchan
914 nplots = nchan
915
915
916 if showSNR:
916 if showSNR:
917 nplots = nchan*2
917 nplots = nchan*2
918 self.plotFact = 2
918 self.plotFact = 2
919 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
919 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
920 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
920 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
921
921
922 self.setup(id=id,
922 self.setup(id=id,
923 nplots=nplots,
923 nplots=nplots,
924 wintitle=wintitle,
924 wintitle=wintitle,
925 show=show)
925 show=show)
926
926
927 if timerange != None:
927 if timerange != None:
928 self.timerange = timerange
928 self.timerange = timerange
929
929
930 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
930 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
931
931
932 if ymin == None: ymin = numpy.nanmin(y)
932 if ymin == None: ymin = numpy.nanmin(y)
933 if ymax == None: ymax = numpy.nanmax(y)
933 if ymax == None: ymax = numpy.nanmax(y)
934 if zmin == None: zmin = numpy.nanmin(z)
934 if zmin == None: zmin = numpy.nanmin(z)
935 if zmax == None: zmax = numpy.nanmax(z)
935 if zmax == None: zmax = numpy.nanmax(z)
936
936
937 self.FTP_WEI = ftp_wei
937 self.FTP_WEI = ftp_wei
938 self.EXP_CODE = exp_code
938 self.EXP_CODE = exp_code
939 self.SUB_EXP_CODE = sub_exp_code
939 self.SUB_EXP_CODE = sub_exp_code
940 self.PLOT_POS = plot_pos
940 self.PLOT_POS = plot_pos
941
941
942 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
942 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
943 self.isConfig = True
943 self.isConfig = True
944 self.figfile = figfile
944 self.figfile = figfile
945 update_figfile = True
945 update_figfile = True
946
946
947 self.setWinTitle(title)
947 self.setWinTitle(title)
948
948
949 for i in range(self.nchan):
949 for i in range(self.nchan):
950 index = channelIndexList[i]
950 index = channelIndexList[i]
951 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
951 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
952 axes = self.axesList[i*self.plotFact]
952 axes = self.axesList[i*self.plotFact]
953 z1 = z[i,:].reshape((1,-1))
953 z1 = z[i,:].reshape((1,-1))
954 axes.pcolorbuffer(x, y, z1,
954 axes.pcolorbuffer(x, y, z1,
955 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
955 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
956 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
956 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
957 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
957 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
958
958
959 if showSNR:
959 if showSNR:
960 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
960 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
961 axes = self.axesList[i*self.plotFact + 1]
961 axes = self.axesList[i*self.plotFact + 1]
962 SNRdB1 = SNRdB[i,:].reshape((1,-1))
962 SNRdB1 = SNRdB[i,:].reshape((1,-1))
963 axes.pcolorbuffer(x, y, SNRdB1,
963 axes.pcolorbuffer(x, y, SNRdB1,
964 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
964 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
965 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
965 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
966 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
966 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
967
967
968
968
969 self.draw()
969 self.draw()
970
970
971 if dataOut.ltctime >= self.xmax:
971 if dataOut.ltctime >= self.xmax:
972 self.counter_imagwr = wr_period
972 self.counter_imagwr = wr_period
973 self.isConfig = False
973 self.isConfig = False
974 update_figfile = True
974 update_figfile = True
975
975
976 self.save(figpath=figpath,
976 self.save(figpath=figpath,
977 figfile=figfile,
977 figfile=figfile,
978 save=save,
978 save=save,
979 ftp=ftp,
979 ftp=ftp,
980 wr_period=wr_period,
980 wr_period=wr_period,
981 thisDatetime=thisDatetime,
981 thisDatetime=thisDatetime,
982 update_figfile=update_figfile)
982 update_figfile=update_figfile)
983
983
984
984
985
985
986 class Parameters1Plot(Figure):
986 class Parameters1Plot(Figure):
987
987
988 __isConfig = None
988 __isConfig = None
989 __nsubplots = None
989 __nsubplots = None
990
990
991 WIDTHPROF = None
991 WIDTHPROF = None
992 HEIGHTPROF = None
992 HEIGHTPROF = None
993 PREFIX = 'prm'
993 PREFIX = 'prm'
994
994
995 def __init__(self, **kwargs):
995 def __init__(self, **kwargs):
996 Figure.__init__(self, **kwargs)
996 Figure.__init__(self, **kwargs)
997 self.timerange = 2*60*60
997 self.timerange = 2*60*60
998 self.isConfig = False
998 self.isConfig = False
999 self.__nsubplots = 1
999 self.__nsubplots = 1
1000
1000
1001 self.WIDTH = 800
1001 self.WIDTH = 800
1002 self.HEIGHT = 180
1002 self.HEIGHT = 180
1003 self.WIDTHPROF = 120
1003 self.WIDTHPROF = 120
1004 self.HEIGHTPROF = 0
1004 self.HEIGHTPROF = 0
1005 self.counter_imagwr = 0
1005 self.counter_imagwr = 0
1006
1006
1007 self.PLOT_CODE = PARMS_CODE
1007 self.PLOT_CODE = PARMS_CODE
1008
1008
1009 self.FTP_WEI = None
1009 self.FTP_WEI = None
1010 self.EXP_CODE = None
1010 self.EXP_CODE = None
1011 self.SUB_EXP_CODE = None
1011 self.SUB_EXP_CODE = None
1012 self.PLOT_POS = None
1012 self.PLOT_POS = None
1013 self.tmin = None
1013 self.tmin = None
1014 self.tmax = None
1014 self.tmax = None
1015
1015
1016 self.xmin = None
1016 self.xmin = None
1017 self.xmax = None
1017 self.xmax = None
1018
1018
1019 self.figfile = None
1019 self.figfile = None
1020
1020
1021 def getSubplots(self):
1021 def getSubplots(self):
1022
1022
1023 ncol = 1
1023 ncol = 1
1024 nrow = self.nplots
1024 nrow = self.nplots
1025
1025
1026 return nrow, ncol
1026 return nrow, ncol
1027
1027
1028 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1028 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1029
1029
1030 self.__showprofile = showprofile
1030 self.__showprofile = showprofile
1031 self.nplots = nplots
1031 self.nplots = nplots
1032
1032
1033 ncolspan = 1
1033 ncolspan = 1
1034 colspan = 1
1034 colspan = 1
1035
1035
1036 self.createFigure(id = id,
1036 self.createFigure(id = id,
1037 wintitle = wintitle,
1037 wintitle = wintitle,
1038 widthplot = self.WIDTH + self.WIDTHPROF,
1038 widthplot = self.WIDTH + self.WIDTHPROF,
1039 heightplot = self.HEIGHT + self.HEIGHTPROF,
1039 heightplot = self.HEIGHT + self.HEIGHTPROF,
1040 show=show)
1040 show=show)
1041
1041
1042 nrow, ncol = self.getSubplots()
1042 nrow, ncol = self.getSubplots()
1043
1043
1044 counter = 0
1044 counter = 0
1045 for y in range(nrow):
1045 for y in range(nrow):
1046 for x in range(ncol):
1046 for x in range(ncol):
1047
1047
1048 if counter >= self.nplots:
1048 if counter >= self.nplots:
1049 break
1049 break
1050
1050
1051 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1051 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1052
1052
1053 if showprofile:
1053 if showprofile:
1054 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1054 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1055
1055
1056 counter += 1
1056 counter += 1
1057
1057
1058 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
1058 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
1059 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
1059 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
1060 parameterIndex = None, onlyPositive = False,
1060 parameterIndex = None, onlyPositive = False,
1061 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
1061 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
1062 DOP = True,
1062 DOP = True,
1063 zlabel = "", parameterName = "", parameterObject = "data_param",
1063 zlabel = "", parameterName = "", parameterObject = "data_param",
1064 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1064 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1065 server=None, folder=None, username=None, password=None,
1065 server=None, folder=None, username=None, password=None,
1066 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1066 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1067 #print inspect.getargspec(self.run).args
1067 #print inspect.getargspec(self.run).args
1068 """
1068 """
1069
1069
1070 Input:
1070 Input:
1071 dataOut :
1071 dataOut :
1072 id :
1072 id :
1073 wintitle :
1073 wintitle :
1074 channelList :
1074 channelList :
1075 showProfile :
1075 showProfile :
1076 xmin : None,
1076 xmin : None,
1077 xmax : None,
1077 xmax : None,
1078 ymin : None,
1078 ymin : None,
1079 ymax : None,
1079 ymax : None,
1080 zmin : None,
1080 zmin : None,
1081 zmax : None
1081 zmax : None
1082 """
1082 """
1083
1083
1084 data_param = getattr(dataOut, parameterObject)
1084 data_param = getattr(dataOut, parameterObject)
1085
1085
1086 if channelList == None:
1086 if channelList == None:
1087 channelIndexList = numpy.arange(data_param.shape[0])
1087 channelIndexList = numpy.arange(data_param.shape[0])
1088 else:
1088 else:
1089 channelIndexList = numpy.array(channelList)
1089 channelIndexList = numpy.array(channelList)
1090
1090
1091 nchan = len(channelIndexList) #Number of channels being plotted
1091 nchan = len(channelIndexList) #Number of channels being plotted
1092
1092
1093 if nchan < 1:
1093 if nchan < 1:
1094 return
1094 return
1095
1095
1096 nGraphsByChannel = 0
1096 nGraphsByChannel = 0
1097
1097
1098 if SNR:
1098 if SNR:
1099 nGraphsByChannel += 1
1099 nGraphsByChannel += 1
1100 if DOP:
1100 if DOP:
1101 nGraphsByChannel += 1
1101 nGraphsByChannel += 1
1102
1102
1103 if nGraphsByChannel < 1:
1103 if nGraphsByChannel < 1:
1104 return
1104 return
1105
1105
1106 nplots = nGraphsByChannel*nchan
1106 nplots = nGraphsByChannel*nchan
1107
1107
1108 if timerange is not None:
1108 if timerange is not None:
1109 self.timerange = timerange
1109 self.timerange = timerange
1110
1110
1111 #tmin = None
1111 #tmin = None
1112 #tmax = None
1112 #tmax = None
1113 if parameterIndex == None:
1113 if parameterIndex == None:
1114 parameterIndex = 1
1114 parameterIndex = 1
1115
1115
1116 x = dataOut.getTimeRange1(dataOut.paramInterval)
1116 x = dataOut.getTimeRange1(dataOut.paramInterval)
1117 y = dataOut.heightList
1117 y = dataOut.heightList
1118 z = data_param[channelIndexList,parameterIndex,:].copy()
1119
1118
1120 zRange = dataOut.abscissaList
1119 if dataOut.data_param.ndim == 3:
1121 # nChannels = z.shape[0] #Number of wind dimensions estimated
1120 z = dataOut.data_param[channelIndexList,parameterIndex,:]
1122 # thisDatetime = dataOut.datatime
1121 else:
1122 z = dataOut.data_param[channelIndexList,:]
1123
1123
1124 if dataOut.data_SNR is not None:
1124 if dataOut.data_SNR is not None:
1125 SNRarray = dataOut.data_SNR[channelIndexList,:]
1125 if dataOut.data_SNR.ndim == 2:
1126 SNRdB = 10*numpy.log10(SNRarray)
1126 SNRavg = numpy.average(dataOut.data_SNR, axis=0)
1127 # SNRavgdB = 10*numpy.log10(SNRavg)
1127 else:
1128 ind = numpy.where(SNRdB < 10**(SNRthresh/10))
1128 SNRavg = dataOut.data_SNR
1129 z[ind] = numpy.nan
1129 SNRdB = 10*numpy.log10(SNRavg)
1130
1130
1131 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1131 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1132 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1132 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1133 xlabel = ""
1133 xlabel = ""
1134 ylabel = "Range (Km)"
1134 ylabel = "Range (Km)"
1135
1136 if (SNR and not onlySNR): nplots = 2*nplots
1137
1135
1138 if onlyPositive:
1136 if onlyPositive:
1139 colormap = "jet"
1137 colormap = "jet"
1140 zmin = 0
1138 zmin = 0
1141 else: colormap = "RdBu_r"
1139 else: colormap = "RdBu_r"
1142
1140
1143 if not self.isConfig:
1141 if not self.isConfig:
1144
1142
1145 self.setup(id=id,
1143 self.setup(id=id,
1146 nplots=nplots,
1144 nplots=nplots,
1147 wintitle=wintitle,
1145 wintitle=wintitle,
1148 showprofile=showprofile,
1146 showprofile=showprofile,
1149 show=show)
1147 show=show)
1150
1148
1151 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1149 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1152
1150
1153 if ymin == None: ymin = numpy.nanmin(y)
1151 if ymin == None: ymin = numpy.nanmin(y)
1154 if ymax == None: ymax = numpy.nanmax(y)
1152 if ymax == None: ymax = numpy.nanmax(y)
1155 if zmin == None: zmin = numpy.nanmin(zRange)
1153 if zmin == None: zmin = numpy.nanmin(z)
1156 if zmax == None: zmax = numpy.nanmax(zRange)
1154 if zmax == None: zmax = numpy.nanmax(z)
1157
1155
1158 if SNR:
1156 if SNR:
1159 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1157 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1160 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1158 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1161
1159
1162 self.FTP_WEI = ftp_wei
1160 self.FTP_WEI = ftp_wei
1163 self.EXP_CODE = exp_code
1161 self.EXP_CODE = exp_code
1164 self.SUB_EXP_CODE = sub_exp_code
1162 self.SUB_EXP_CODE = sub_exp_code
1165 self.PLOT_POS = plot_pos
1163 self.PLOT_POS = plot_pos
1166
1164
1167 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1165 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1168 self.isConfig = True
1166 self.isConfig = True
1169 self.figfile = figfile
1167 self.figfile = figfile
1170
1168
1171 self.setWinTitle(title)
1169 self.setWinTitle(title)
1172
1170
1173 if ((self.xmax - x[1]) < (x[1]-x[0])):
1171 if ((self.xmax - x[1]) < (x[1]-x[0])):
1174 x[1] = self.xmax
1172 x[1] = self.xmax
1175
1173
1176 for i in range(nchan):
1174 for i in range(nchan):
1177
1175
1178 if (SNR and not onlySNR): j = 2*i
1176 if (SNR and not onlySNR): j = 2*i
1179 else: j = i
1177 else: j = i
1180
1178
1181 j = nGraphsByChannel*i
1179 j = nGraphsByChannel*i
1182
1180
1183 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1181 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1184 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1182 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1185
1183
1186 if not onlySNR:
1184 if not onlySNR:
1187 axes = self.axesList[j*self.__nsubplots]
1185 axes = self.axesList[j*self.__nsubplots]
1188 z1 = z[i,:].reshape((1,-1))
1186 z1 = z[i,:].reshape((1,-1))
1189 axes.pcolorbuffer(x, y, z1,
1187 axes.pcolorbuffer(x, y, z1,
1190 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1188 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1191 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1189 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1192 ticksize=9, cblabel=zlabel, cbsize="1%")
1190 ticksize=9, cblabel=zlabel, cbsize="1%")
1193
1191
1194 if DOP:
1192 if DOP:
1195 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1193 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1196
1194
1197 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1195 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1198 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1196 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1199 axes = self.axesList[j]
1197 axes = self.axesList[j]
1200 z1 = z[i,:].reshape((1,-1))
1198 z1 = z[i,:].reshape((1,-1))
1201 axes.pcolorbuffer(x, y, z1,
1199 axes.pcolorbuffer(x, y, z1,
1202 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1200 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1203 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1201 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1204 ticksize=9, cblabel=zlabel, cbsize="1%")
1202 ticksize=9, cblabel=zlabel, cbsize="1%")
1205
1203
1206 if SNR:
1204 if SNR:
1207 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1205 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1208 axes = self.axesList[(j)*self.__nsubplots]
1206 axes = self.axesList[(j)*self.__nsubplots]
1209 if not onlySNR:
1207 if not onlySNR:
1210 axes = self.axesList[(j + 1)*self.__nsubplots]
1208 axes = self.axesList[(j + 1)*self.__nsubplots]
1211
1212 axes = self.axesList[(j + nGraphsByChannel-1)]
1213
1209
1214 z1 = SNRdB[i,:].reshape((1,-1))
1210 axes = self.axesList[(j + nGraphsByChannel-1)]
1215 axes.pcolorbuffer(x, y, z1,
1211 z1 = SNRdB.reshape((1,-1))
1216 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1212 axes.pcolorbuffer(x, y, z1,
1217 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1213 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1218 ticksize=9, cblabel=zlabel, cbsize="1%")
1214 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1215 ticksize=9, cblabel=zlabel, cbsize="1%")
1219
1216
1220
1217
1221
1218
1222 self.draw()
1219 self.draw()
1223
1220
1224 if x[1] >= self.axesList[0].xmax:
1221 if x[1] >= self.axesList[0].xmax:
1225 self.counter_imagwr = wr_period
1222 self.counter_imagwr = wr_period
1226 self.isConfig = False
1223 self.isConfig = False
1227 self.figfile = None
1224 self.figfile = None
1228
1225
1229 self.save(figpath=figpath,
1226 self.save(figpath=figpath,
1230 figfile=figfile,
1227 figfile=figfile,
1231 save=save,
1228 save=save,
1232 ftp=ftp,
1229 ftp=ftp,
1233 wr_period=wr_period,
1230 wr_period=wr_period,
1234 thisDatetime=thisDatetime,
1231 thisDatetime=thisDatetime,
1235 update_figfile=False)
1232 update_figfile=False)
1236
1233
1237 class SpectralFittingPlot(Figure):
1234 class SpectralFittingPlot(Figure):
1238
1235
1239 __isConfig = None
1236 __isConfig = None
1240 __nsubplots = None
1237 __nsubplots = None
1241
1238
1242 WIDTHPROF = None
1239 WIDTHPROF = None
1243 HEIGHTPROF = None
1240 HEIGHTPROF = None
1244 PREFIX = 'prm'
1241 PREFIX = 'prm'
1245
1242
1246
1243
1247 N = None
1244 N = None
1248 ippSeconds = None
1245 ippSeconds = None
1249
1246
1250 def __init__(self, **kwargs):
1247 def __init__(self, **kwargs):
1251 Figure.__init__(self, **kwargs)
1248 Figure.__init__(self, **kwargs)
1252 self.isConfig = False
1249 self.isConfig = False
1253 self.__nsubplots = 1
1250 self.__nsubplots = 1
1254
1251
1255 self.PLOT_CODE = SPECFIT_CODE
1252 self.PLOT_CODE = SPECFIT_CODE
1256
1253
1257 self.WIDTH = 450
1254 self.WIDTH = 450
1258 self.HEIGHT = 250
1255 self.HEIGHT = 250
1259 self.WIDTHPROF = 0
1256 self.WIDTHPROF = 0
1260 self.HEIGHTPROF = 0
1257 self.HEIGHTPROF = 0
1261
1258
1262 def getSubplots(self):
1259 def getSubplots(self):
1263
1260
1264 ncol = int(numpy.sqrt(self.nplots)+0.9)
1261 ncol = int(numpy.sqrt(self.nplots)+0.9)
1265 nrow = int(self.nplots*1./ncol + 0.9)
1262 nrow = int(self.nplots*1./ncol + 0.9)
1266
1263
1267 return nrow, ncol
1264 return nrow, ncol
1268
1265
1269 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1266 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1270
1267
1271 showprofile = False
1268 showprofile = False
1272 self.__showprofile = showprofile
1269 self.__showprofile = showprofile
1273 self.nplots = nplots
1270 self.nplots = nplots
1274
1271
1275 ncolspan = 5
1272 ncolspan = 5
1276 colspan = 4
1273 colspan = 4
1277 if showprofile:
1274 if showprofile:
1278 ncolspan = 5
1275 ncolspan = 5
1279 colspan = 4
1276 colspan = 4
1280 self.__nsubplots = 2
1277 self.__nsubplots = 2
1281
1278
1282 self.createFigure(id = id,
1279 self.createFigure(id = id,
1283 wintitle = wintitle,
1280 wintitle = wintitle,
1284 widthplot = self.WIDTH + self.WIDTHPROF,
1281 widthplot = self.WIDTH + self.WIDTHPROF,
1285 heightplot = self.HEIGHT + self.HEIGHTPROF,
1282 heightplot = self.HEIGHT + self.HEIGHTPROF,
1286 show=show)
1283 show=show)
1287
1284
1288 nrow, ncol = self.getSubplots()
1285 nrow, ncol = self.getSubplots()
1289
1286
1290 counter = 0
1287 counter = 0
1291 for y in range(nrow):
1288 for y in range(nrow):
1292 for x in range(ncol):
1289 for x in range(ncol):
1293
1290
1294 if counter >= self.nplots:
1291 if counter >= self.nplots:
1295 break
1292 break
1296
1293
1297 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1294 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1298
1295
1299 if showprofile:
1296 if showprofile:
1300 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1297 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1301
1298
1302 counter += 1
1299 counter += 1
1303
1300
1304 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1301 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1305 xmin=None, xmax=None, ymin=None, ymax=None,
1302 xmin=None, xmax=None, ymin=None, ymax=None,
1306 save=False, figpath='./', figfile=None, show=True):
1303 save=False, figpath='./', figfile=None, show=True):
1307
1304
1308 """
1305 """
1309
1306
1310 Input:
1307 Input:
1311 dataOut :
1308 dataOut :
1312 id :
1309 id :
1313 wintitle :
1310 wintitle :
1314 channelList :
1311 channelList :
1315 showProfile :
1312 showProfile :
1316 xmin : None,
1313 xmin : None,
1317 xmax : None,
1314 xmax : None,
1318 zmin : None,
1315 zmin : None,
1319 zmax : None
1316 zmax : None
1320 """
1317 """
1321
1318
1322 if cutHeight==None:
1319 if cutHeight==None:
1323 h=270
1320 h=270
1324 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1321 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1325 cutHeight = dataOut.heightList[heightindex]
1322 cutHeight = dataOut.heightList[heightindex]
1326
1323
1327 factor = dataOut.normFactor
1324 factor = dataOut.normFactor
1328 x = dataOut.abscissaList[:-1]
1325 x = dataOut.abscissaList[:-1]
1329 #y = dataOut.getHeiRange()
1326 #y = dataOut.getHeiRange()
1330
1327
1331 z = dataOut.data_pre[:,:,heightindex]/factor
1328 z = dataOut.data_pre[:,:,heightindex]/factor
1332 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1329 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1333 avg = numpy.average(z, axis=1)
1330 avg = numpy.average(z, axis=1)
1334 listChannels = z.shape[0]
1331 listChannels = z.shape[0]
1335
1332
1336 #Reconstruct Function
1333 #Reconstruct Function
1337 if fit==True:
1334 if fit==True:
1338 groupArray = dataOut.groupList
1335 groupArray = dataOut.groupList
1339 listChannels = groupArray.reshape((groupArray.size))
1336 listChannels = groupArray.reshape((groupArray.size))
1340 listChannels.sort()
1337 listChannels.sort()
1341 spcFitLine = numpy.zeros(z.shape)
1338 spcFitLine = numpy.zeros(z.shape)
1342 constants = dataOut.constants
1339 constants = dataOut.constants
1343
1340
1344 nGroups = groupArray.shape[0]
1341 nGroups = groupArray.shape[0]
1345 nChannels = groupArray.shape[1]
1342 nChannels = groupArray.shape[1]
1346 nProfiles = z.shape[1]
1343 nProfiles = z.shape[1]
1347
1344
1348 for f in range(nGroups):
1345 for f in range(nGroups):
1349 groupChann = groupArray[f,:]
1346 groupChann = groupArray[f,:]
1350 p = dataOut.data_param[f,:,heightindex]
1347 p = dataOut.data_param[f,:,heightindex]
1351 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1348 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1352 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1349 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1353 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1350 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1354 spcFitLine[groupChann,:] = fitLineAux
1351 spcFitLine[groupChann,:] = fitLineAux
1355 # spcFitLine = spcFitLine/factor
1352 # spcFitLine = spcFitLine/factor
1356
1353
1357 z = z[listChannels,:]
1354 z = z[listChannels,:]
1358 spcFitLine = spcFitLine[listChannels,:]
1355 spcFitLine = spcFitLine[listChannels,:]
1359 spcFitLinedB = 10*numpy.log10(spcFitLine)
1356 spcFitLinedB = 10*numpy.log10(spcFitLine)
1360
1357
1361 zdB = 10*numpy.log10(z)
1358 zdB = 10*numpy.log10(z)
1362 #thisDatetime = dataOut.datatime
1359 #thisDatetime = dataOut.datatime
1363 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1360 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1364 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1361 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1365 xlabel = "Velocity (m/s)"
1362 xlabel = "Velocity (m/s)"
1366 ylabel = "Spectrum"
1363 ylabel = "Spectrum"
1367
1364
1368 if not self.isConfig:
1365 if not self.isConfig:
1369
1366
1370 nplots = listChannels.size
1367 nplots = listChannels.size
1371
1368
1372 self.setup(id=id,
1369 self.setup(id=id,
1373 nplots=nplots,
1370 nplots=nplots,
1374 wintitle=wintitle,
1371 wintitle=wintitle,
1375 showprofile=showprofile,
1372 showprofile=showprofile,
1376 show=show)
1373 show=show)
1377
1374
1378 if xmin == None: xmin = numpy.nanmin(x)
1375 if xmin == None: xmin = numpy.nanmin(x)
1379 if xmax == None: xmax = numpy.nanmax(x)
1376 if xmax == None: xmax = numpy.nanmax(x)
1380 if ymin == None: ymin = numpy.nanmin(zdB)
1377 if ymin == None: ymin = numpy.nanmin(zdB)
1381 if ymax == None: ymax = numpy.nanmax(zdB)+2
1378 if ymax == None: ymax = numpy.nanmax(zdB)+2
1382
1379
1383 self.isConfig = True
1380 self.isConfig = True
1384
1381
1385 self.setWinTitle(title)
1382 self.setWinTitle(title)
1386 for i in range(self.nplots):
1383 for i in range(self.nplots):
1387 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1384 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1388 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1385 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1389 axes = self.axesList[i*self.__nsubplots]
1386 axes = self.axesList[i*self.__nsubplots]
1390 if fit == False:
1387 if fit == False:
1391 axes.pline(x, zdB[i,:],
1388 axes.pline(x, zdB[i,:],
1392 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1389 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1393 xlabel=xlabel, ylabel=ylabel, title=title
1390 xlabel=xlabel, ylabel=ylabel, title=title
1394 )
1391 )
1395 if fit == True:
1392 if fit == True:
1396 fitline=spcFitLinedB[i,:]
1393 fitline=spcFitLinedB[i,:]
1397 y=numpy.vstack([zdB[i,:],fitline] )
1394 y=numpy.vstack([zdB[i,:],fitline] )
1398 legendlabels=['Data','Fitting']
1395 legendlabels=['Data','Fitting']
1399 axes.pmultilineyaxis(x, y,
1396 axes.pmultilineyaxis(x, y,
1400 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1397 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1401 xlabel=xlabel, ylabel=ylabel, title=title,
1398 xlabel=xlabel, ylabel=ylabel, title=title,
1402 legendlabels=legendlabels, marker=None,
1399 legendlabels=legendlabels, marker=None,
1403 linestyle='solid', grid='both')
1400 linestyle='solid', grid='both')
1404
1401
1405 self.draw()
1402 self.draw()
1406
1403
1407 self.save(figpath=figpath,
1404 self.save(figpath=figpath,
1408 figfile=figfile,
1405 figfile=figfile,
1409 save=save,
1406 save=save,
1410 ftp=ftp,
1407 ftp=ftp,
1411 wr_period=wr_period,
1408 wr_period=wr_period,
1412 thisDatetime=thisDatetime)
1409 thisDatetime=thisDatetime)
1413
1410
1414
1411
1415 class EWDriftsPlot(Figure):
1412 class EWDriftsPlot(Figure):
1416
1413
1417 __isConfig = None
1414 __isConfig = None
1418 __nsubplots = None
1415 __nsubplots = None
1419
1416
1420 WIDTHPROF = None
1417 WIDTHPROF = None
1421 HEIGHTPROF = None
1418 HEIGHTPROF = None
1422 PREFIX = 'drift'
1419 PREFIX = 'drift'
1423
1420
1424 def __init__(self, **kwargs):
1421 def __init__(self, **kwargs):
1425 Figure.__init__(self, **kwargs)
1422 Figure.__init__(self, **kwargs)
1426 self.timerange = 2*60*60
1423 self.timerange = 2*60*60
1427 self.isConfig = False
1424 self.isConfig = False
1428 self.__nsubplots = 1
1425 self.__nsubplots = 1
1429
1426
1430 self.WIDTH = 800
1427 self.WIDTH = 800
1431 self.HEIGHT = 150
1428 self.HEIGHT = 150
1432 self.WIDTHPROF = 120
1429 self.WIDTHPROF = 120
1433 self.HEIGHTPROF = 0
1430 self.HEIGHTPROF = 0
1434 self.counter_imagwr = 0
1431 self.counter_imagwr = 0
1435
1432
1436 self.PLOT_CODE = EWDRIFT_CODE
1433 self.PLOT_CODE = EWDRIFT_CODE
1437
1434
1438 self.FTP_WEI = None
1435 self.FTP_WEI = None
1439 self.EXP_CODE = None
1436 self.EXP_CODE = None
1440 self.SUB_EXP_CODE = None
1437 self.SUB_EXP_CODE = None
1441 self.PLOT_POS = None
1438 self.PLOT_POS = None
1442 self.tmin = None
1439 self.tmin = None
1443 self.tmax = None
1440 self.tmax = None
1444
1441
1445 self.xmin = None
1442 self.xmin = None
1446 self.xmax = None
1443 self.xmax = None
1447
1444
1448 self.figfile = None
1445 self.figfile = None
1449
1446
1450 def getSubplots(self):
1447 def getSubplots(self):
1451
1448
1452 ncol = 1
1449 ncol = 1
1453 nrow = self.nplots
1450 nrow = self.nplots
1454
1451
1455 return nrow, ncol
1452 return nrow, ncol
1456
1453
1457 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1454 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1458
1455
1459 self.__showprofile = showprofile
1456 self.__showprofile = showprofile
1460 self.nplots = nplots
1457 self.nplots = nplots
1461
1458
1462 ncolspan = 1
1459 ncolspan = 1
1463 colspan = 1
1460 colspan = 1
1464
1461
1465 self.createFigure(id = id,
1462 self.createFigure(id = id,
1466 wintitle = wintitle,
1463 wintitle = wintitle,
1467 widthplot = self.WIDTH + self.WIDTHPROF,
1464 widthplot = self.WIDTH + self.WIDTHPROF,
1468 heightplot = self.HEIGHT + self.HEIGHTPROF,
1465 heightplot = self.HEIGHT + self.HEIGHTPROF,
1469 show=show)
1466 show=show)
1470
1467
1471 nrow, ncol = self.getSubplots()
1468 nrow, ncol = self.getSubplots()
1472
1469
1473 counter = 0
1470 counter = 0
1474 for y in range(nrow):
1471 for y in range(nrow):
1475 if counter >= self.nplots:
1472 if counter >= self.nplots:
1476 break
1473 break
1477
1474
1478 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1475 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1479 counter += 1
1476 counter += 1
1480
1477
1481 def run(self, dataOut, id, wintitle="", channelList=None,
1478 def run(self, dataOut, id, wintitle="", channelList=None,
1482 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1479 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1483 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1480 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1484 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1481 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1485 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1482 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1486 server=None, folder=None, username=None, password=None,
1483 server=None, folder=None, username=None, password=None,
1487 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1484 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1488 """
1485 """
1489
1486
1490 Input:
1487 Input:
1491 dataOut :
1488 dataOut :
1492 id :
1489 id :
1493 wintitle :
1490 wintitle :
1494 channelList :
1491 channelList :
1495 showProfile :
1492 showProfile :
1496 xmin : None,
1493 xmin : None,
1497 xmax : None,
1494 xmax : None,
1498 ymin : None,
1495 ymin : None,
1499 ymax : None,
1496 ymax : None,
1500 zmin : None,
1497 zmin : None,
1501 zmax : None
1498 zmax : None
1502 """
1499 """
1503
1500
1504 if timerange is not None:
1501 if timerange is not None:
1505 self.timerange = timerange
1502 self.timerange = timerange
1506
1503
1507 tmin = None
1504 tmin = None
1508 tmax = None
1505 tmax = None
1509
1506
1510 x = dataOut.getTimeRange1(dataOut.outputInterval)
1507 x = dataOut.getTimeRange1(dataOut.outputInterval)
1511 # y = dataOut.heightList
1508 # y = dataOut.heightList
1512 y = dataOut.heightList
1509 y = dataOut.heightList
1513
1510
1514 z = dataOut.data_output
1511 z = dataOut.data_output
1515 nplots = z.shape[0] #Number of wind dimensions estimated
1512 nplots = z.shape[0] #Number of wind dimensions estimated
1516 nplotsw = nplots
1513 nplotsw = nplots
1517
1514
1518 #If there is a SNR function defined
1515 #If there is a SNR function defined
1519 if dataOut.data_SNR is not None:
1516 if dataOut.data_SNR is not None:
1520 nplots += 1
1517 nplots += 1
1521 SNR = dataOut.data_SNR
1518 SNR = dataOut.data_SNR
1522
1519
1523 if SNR_1:
1520 if SNR_1:
1524 SNR += 1
1521 SNR += 1
1525
1522
1526 SNRavg = numpy.average(SNR, axis=0)
1523 SNRavg = numpy.average(SNR, axis=0)
1527
1524
1528 SNRdB = 10*numpy.log10(SNR)
1525 SNRdB = 10*numpy.log10(SNR)
1529 SNRavgdB = 10*numpy.log10(SNRavg)
1526 SNRavgdB = 10*numpy.log10(SNRavg)
1530
1527
1531 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1528 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1532
1529
1533 for i in range(nplotsw):
1530 for i in range(nplotsw):
1534 z[i,ind] = numpy.nan
1531 z[i,ind] = numpy.nan
1535
1532
1536
1533
1537 showprofile = False
1534 showprofile = False
1538 # thisDatetime = dataOut.datatime
1535 # thisDatetime = dataOut.datatime
1539 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1536 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1540 title = wintitle + " EW Drifts"
1537 title = wintitle + " EW Drifts"
1541 xlabel = ""
1538 xlabel = ""
1542 ylabel = "Height (Km)"
1539 ylabel = "Height (Km)"
1543
1540
1544 if not self.isConfig:
1541 if not self.isConfig:
1545
1542
1546 self.setup(id=id,
1543 self.setup(id=id,
1547 nplots=nplots,
1544 nplots=nplots,
1548 wintitle=wintitle,
1545 wintitle=wintitle,
1549 showprofile=showprofile,
1546 showprofile=showprofile,
1550 show=show)
1547 show=show)
1551
1548
1552 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1549 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1553
1550
1554 if ymin == None: ymin = numpy.nanmin(y)
1551 if ymin == None: ymin = numpy.nanmin(y)
1555 if ymax == None: ymax = numpy.nanmax(y)
1552 if ymax == None: ymax = numpy.nanmax(y)
1556
1553
1557 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1554 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1558 if zminZonal == None: zminZonal = -zmaxZonal
1555 if zminZonal == None: zminZonal = -zmaxZonal
1559 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1556 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1560 if zminVertical == None: zminVertical = -zmaxVertical
1557 if zminVertical == None: zminVertical = -zmaxVertical
1561
1558
1562 if dataOut.data_SNR is not None:
1559 if dataOut.data_SNR is not None:
1563 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1560 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1564 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1561 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1565
1562
1566 self.FTP_WEI = ftp_wei
1563 self.FTP_WEI = ftp_wei
1567 self.EXP_CODE = exp_code
1564 self.EXP_CODE = exp_code
1568 self.SUB_EXP_CODE = sub_exp_code
1565 self.SUB_EXP_CODE = sub_exp_code
1569 self.PLOT_POS = plot_pos
1566 self.PLOT_POS = plot_pos
1570
1567
1571 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1568 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1572 self.isConfig = True
1569 self.isConfig = True
1573
1570
1574
1571
1575 self.setWinTitle(title)
1572 self.setWinTitle(title)
1576
1573
1577 if ((self.xmax - x[1]) < (x[1]-x[0])):
1574 if ((self.xmax - x[1]) < (x[1]-x[0])):
1578 x[1] = self.xmax
1575 x[1] = self.xmax
1579
1576
1580 strWind = ['Zonal','Vertical']
1577 strWind = ['Zonal','Vertical']
1581 strCb = 'Velocity (m/s)'
1578 strCb = 'Velocity (m/s)'
1582 zmaxVector = [zmaxZonal, zmaxVertical]
1579 zmaxVector = [zmaxZonal, zmaxVertical]
1583 zminVector = [zminZonal, zminVertical]
1580 zminVector = [zminZonal, zminVertical]
1584
1581
1585 for i in range(nplotsw):
1582 for i in range(nplotsw):
1586
1583
1587 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1584 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1588 axes = self.axesList[i*self.__nsubplots]
1585 axes = self.axesList[i*self.__nsubplots]
1589
1586
1590 z1 = z[i,:].reshape((1,-1))
1587 z1 = z[i,:].reshape((1,-1))
1591
1588
1592 axes.pcolorbuffer(x, y, z1,
1589 axes.pcolorbuffer(x, y, z1,
1593 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1590 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1594 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1591 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1595 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1592 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1596
1593
1597 if dataOut.data_SNR is not None:
1594 if dataOut.data_SNR is not None:
1598 i += 1
1595 i += 1
1599 if SNR_1:
1596 if SNR_1:
1600 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1597 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1601 else:
1598 else:
1602 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1599 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1603 axes = self.axesList[i*self.__nsubplots]
1600 axes = self.axesList[i*self.__nsubplots]
1604 SNRavgdB = SNRavgdB.reshape((1,-1))
1601 SNRavgdB = SNRavgdB.reshape((1,-1))
1605
1602
1606 axes.pcolorbuffer(x, y, SNRavgdB,
1603 axes.pcolorbuffer(x, y, SNRavgdB,
1607 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1604 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1608 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1605 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1609 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1606 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1610
1607
1611 self.draw()
1608 self.draw()
1612
1609
1613 if x[1] >= self.axesList[0].xmax:
1610 if x[1] >= self.axesList[0].xmax:
1614 self.counter_imagwr = wr_period
1611 self.counter_imagwr = wr_period
1615 self.isConfig = False
1612 self.isConfig = False
1616 self.figfile = None
1613 self.figfile = None
1617
1614
1618
1615
1619
1616
1620
1617
1621 class PhasePlot(Figure):
1618 class PhasePlot(Figure):
1622
1619
1623 __isConfig = None
1620 __isConfig = None
1624 __nsubplots = None
1621 __nsubplots = None
1625
1622
1626 PREFIX = 'mphase'
1623 PREFIX = 'mphase'
1627
1624
1628
1625
1629 def __init__(self, **kwargs):
1626 def __init__(self, **kwargs):
1630 Figure.__init__(self, **kwargs)
1627 Figure.__init__(self, **kwargs)
1631 self.timerange = 24*60*60
1628 self.timerange = 24*60*60
1632 self.isConfig = False
1629 self.isConfig = False
1633 self.__nsubplots = 1
1630 self.__nsubplots = 1
1634 self.counter_imagwr = 0
1631 self.counter_imagwr = 0
1635 self.WIDTH = 600
1632 self.WIDTH = 600
1636 self.HEIGHT = 300
1633 self.HEIGHT = 300
1637 self.WIDTHPROF = 120
1634 self.WIDTHPROF = 120
1638 self.HEIGHTPROF = 0
1635 self.HEIGHTPROF = 0
1639 self.xdata = None
1636 self.xdata = None
1640 self.ydata = None
1637 self.ydata = None
1641
1638
1642 self.PLOT_CODE = MPHASE_CODE
1639 self.PLOT_CODE = MPHASE_CODE
1643
1640
1644 self.FTP_WEI = None
1641 self.FTP_WEI = None
1645 self.EXP_CODE = None
1642 self.EXP_CODE = None
1646 self.SUB_EXP_CODE = None
1643 self.SUB_EXP_CODE = None
1647 self.PLOT_POS = None
1644 self.PLOT_POS = None
1648
1645
1649
1646
1650 self.filename_phase = None
1647 self.filename_phase = None
1651
1648
1652 self.figfile = None
1649 self.figfile = None
1653
1650
1654 def getSubplots(self):
1651 def getSubplots(self):
1655
1652
1656 ncol = 1
1653 ncol = 1
1657 nrow = 1
1654 nrow = 1
1658
1655
1659 return nrow, ncol
1656 return nrow, ncol
1660
1657
1661 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1658 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1662
1659
1663 self.__showprofile = showprofile
1660 self.__showprofile = showprofile
1664 self.nplots = nplots
1661 self.nplots = nplots
1665
1662
1666 ncolspan = 7
1663 ncolspan = 7
1667 colspan = 6
1664 colspan = 6
1668 self.__nsubplots = 2
1665 self.__nsubplots = 2
1669
1666
1670 self.createFigure(id = id,
1667 self.createFigure(id = id,
1671 wintitle = wintitle,
1668 wintitle = wintitle,
1672 widthplot = self.WIDTH+self.WIDTHPROF,
1669 widthplot = self.WIDTH+self.WIDTHPROF,
1673 heightplot = self.HEIGHT+self.HEIGHTPROF,
1670 heightplot = self.HEIGHT+self.HEIGHTPROF,
1674 show=show)
1671 show=show)
1675
1672
1676 nrow, ncol = self.getSubplots()
1673 nrow, ncol = self.getSubplots()
1677
1674
1678 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1675 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1679
1676
1680
1677
1681 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1678 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1682 xmin=None, xmax=None, ymin=None, ymax=None,
1679 xmin=None, xmax=None, ymin=None, ymax=None,
1683 timerange=None,
1680 timerange=None,
1684 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1681 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1685 server=None, folder=None, username=None, password=None,
1682 server=None, folder=None, username=None, password=None,
1686 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1683 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1687
1684
1688
1685
1689 tmin = None
1686 tmin = None
1690 tmax = None
1687 tmax = None
1691 x = dataOut.getTimeRange1(dataOut.outputInterval)
1688 x = dataOut.getTimeRange1(dataOut.outputInterval)
1692 y = dataOut.getHeiRange()
1689 y = dataOut.getHeiRange()
1693
1690
1694
1691
1695 #thisDatetime = dataOut.datatime
1692 #thisDatetime = dataOut.datatime
1696 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1693 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1697 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1694 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1698 xlabel = "Local Time"
1695 xlabel = "Local Time"
1699 ylabel = "Phase"
1696 ylabel = "Phase"
1700
1697
1701
1698
1702 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1699 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1703 phase_beacon = dataOut.data_output
1700 phase_beacon = dataOut.data_output
1704 update_figfile = False
1701 update_figfile = False
1705
1702
1706 if not self.isConfig:
1703 if not self.isConfig:
1707
1704
1708 self.nplots = phase_beacon.size
1705 self.nplots = phase_beacon.size
1709
1706
1710 self.setup(id=id,
1707 self.setup(id=id,
1711 nplots=self.nplots,
1708 nplots=self.nplots,
1712 wintitle=wintitle,
1709 wintitle=wintitle,
1713 showprofile=showprofile,
1710 showprofile=showprofile,
1714 show=show)
1711 show=show)
1715
1712
1716 if timerange is not None:
1713 if timerange is not None:
1717 self.timerange = timerange
1714 self.timerange = timerange
1718
1715
1719 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1716 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1720
1717
1721 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1718 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1722 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1719 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1723
1720
1724 self.FTP_WEI = ftp_wei
1721 self.FTP_WEI = ftp_wei
1725 self.EXP_CODE = exp_code
1722 self.EXP_CODE = exp_code
1726 self.SUB_EXP_CODE = sub_exp_code
1723 self.SUB_EXP_CODE = sub_exp_code
1727 self.PLOT_POS = plot_pos
1724 self.PLOT_POS = plot_pos
1728
1725
1729 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1726 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1730 self.isConfig = True
1727 self.isConfig = True
1731 self.figfile = figfile
1728 self.figfile = figfile
1732 self.xdata = numpy.array([])
1729 self.xdata = numpy.array([])
1733 self.ydata = numpy.array([])
1730 self.ydata = numpy.array([])
1734
1731
1735 #open file beacon phase
1732 #open file beacon phase
1736 path = '%s%03d' %(self.PREFIX, self.id)
1733 path = '%s%03d' %(self.PREFIX, self.id)
1737 beacon_file = os.path.join(path,'%s.txt'%self.name)
1734 beacon_file = os.path.join(path,'%s.txt'%self.name)
1738 self.filename_phase = os.path.join(figpath,beacon_file)
1735 self.filename_phase = os.path.join(figpath,beacon_file)
1739 update_figfile = True
1736 update_figfile = True
1740
1737
1741
1738
1742 #store data beacon phase
1739 #store data beacon phase
1743 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1740 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1744
1741
1745 self.setWinTitle(title)
1742 self.setWinTitle(title)
1746
1743
1747
1744
1748 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1745 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1749
1746
1750 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1747 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1751
1748
1752 axes = self.axesList[0]
1749 axes = self.axesList[0]
1753
1750
1754 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1751 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1755
1752
1756 if len(self.ydata)==0:
1753 if len(self.ydata)==0:
1757 self.ydata = phase_beacon.reshape(-1,1)
1754 self.ydata = phase_beacon.reshape(-1,1)
1758 else:
1755 else:
1759 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1756 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1760
1757
1761
1758
1762 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1759 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1763 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1760 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1764 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1761 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1765 XAxisAsTime=True, grid='both'
1762 XAxisAsTime=True, grid='both'
1766 )
1763 )
1767
1764
1768 self.draw()
1765 self.draw()
1769
1766
1770 self.save(figpath=figpath,
1767 self.save(figpath=figpath,
1771 figfile=figfile,
1768 figfile=figfile,
1772 save=save,
1769 save=save,
1773 ftp=ftp,
1770 ftp=ftp,
1774 wr_period=wr_period,
1771 wr_period=wr_period,
1775 thisDatetime=thisDatetime,
1772 thisDatetime=thisDatetime,
1776 update_figfile=update_figfile)
1773 update_figfile=update_figfile)
1777
1774
1778 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
1775 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
1779 self.counter_imagwr = wr_period
1776 self.counter_imagwr = wr_period
1780 self.isConfig = False
1777 self.isConfig = False
1781 update_figfile = True
1778 update_figfile = True
1782
1779
1783
1780
1784
1781
1785 class NSMeteorDetection1Plot(Figure):
1782 class NSMeteorDetection1Plot(Figure):
1786
1783
1787 isConfig = None
1784 isConfig = None
1788 __nsubplots = None
1785 __nsubplots = None
1789
1786
1790 WIDTHPROF = None
1787 WIDTHPROF = None
1791 HEIGHTPROF = None
1788 HEIGHTPROF = None
1792 PREFIX = 'nsm'
1789 PREFIX = 'nsm'
1793
1790
1794 zminList = None
1791 zminList = None
1795 zmaxList = None
1792 zmaxList = None
1796 cmapList = None
1793 cmapList = None
1797 titleList = None
1794 titleList = None
1798 nPairs = None
1795 nPairs = None
1799 nChannels = None
1796 nChannels = None
1800 nParam = None
1797 nParam = None
1801
1798
1802 def __init__(self, **kwargs):
1799 def __init__(self, **kwargs):
1803 Figure.__init__(self, **kwargs)
1800 Figure.__init__(self, **kwargs)
1804 self.isConfig = False
1801 self.isConfig = False
1805 self.__nsubplots = 1
1802 self.__nsubplots = 1
1806
1803
1807 self.WIDTH = 750
1804 self.WIDTH = 750
1808 self.HEIGHT = 250
1805 self.HEIGHT = 250
1809 self.WIDTHPROF = 120
1806 self.WIDTHPROF = 120
1810 self.HEIGHTPROF = 0
1807 self.HEIGHTPROF = 0
1811 self.counter_imagwr = 0
1808 self.counter_imagwr = 0
1812
1809
1813 self.PLOT_CODE = SPEC_CODE
1810 self.PLOT_CODE = SPEC_CODE
1814
1811
1815 self.FTP_WEI = None
1812 self.FTP_WEI = None
1816 self.EXP_CODE = None
1813 self.EXP_CODE = None
1817 self.SUB_EXP_CODE = None
1814 self.SUB_EXP_CODE = None
1818 self.PLOT_POS = None
1815 self.PLOT_POS = None
1819
1816
1820 self.__xfilter_ena = False
1817 self.__xfilter_ena = False
1821 self.__yfilter_ena = False
1818 self.__yfilter_ena = False
1822
1819
1823 def getSubplots(self):
1820 def getSubplots(self):
1824
1821
1825 ncol = 3
1822 ncol = 3
1826 nrow = int(numpy.ceil(self.nplots/3.0))
1823 nrow = int(numpy.ceil(self.nplots/3.0))
1827
1824
1828 return nrow, ncol
1825 return nrow, ncol
1829
1826
1830 def setup(self, id, nplots, wintitle, show=True):
1827 def setup(self, id, nplots, wintitle, show=True):
1831
1828
1832 self.nplots = nplots
1829 self.nplots = nplots
1833
1830
1834 ncolspan = 1
1831 ncolspan = 1
1835 colspan = 1
1832 colspan = 1
1836
1833
1837 self.createFigure(id = id,
1834 self.createFigure(id = id,
1838 wintitle = wintitle,
1835 wintitle = wintitle,
1839 widthplot = self.WIDTH + self.WIDTHPROF,
1836 widthplot = self.WIDTH + self.WIDTHPROF,
1840 heightplot = self.HEIGHT + self.HEIGHTPROF,
1837 heightplot = self.HEIGHT + self.HEIGHTPROF,
1841 show=show)
1838 show=show)
1842
1839
1843 nrow, ncol = self.getSubplots()
1840 nrow, ncol = self.getSubplots()
1844
1841
1845 counter = 0
1842 counter = 0
1846 for y in range(nrow):
1843 for y in range(nrow):
1847 for x in range(ncol):
1844 for x in range(ncol):
1848
1845
1849 if counter >= self.nplots:
1846 if counter >= self.nplots:
1850 break
1847 break
1851
1848
1852 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1849 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1853
1850
1854 counter += 1
1851 counter += 1
1855
1852
1856 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1853 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1857 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1854 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1858 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1855 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1859 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1856 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1860 server=None, folder=None, username=None, password=None,
1857 server=None, folder=None, username=None, password=None,
1861 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1858 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1862 xaxis="frequency"):
1859 xaxis="frequency"):
1863
1860
1864 """
1861 """
1865
1862
1866 Input:
1863 Input:
1867 dataOut :
1864 dataOut :
1868 id :
1865 id :
1869 wintitle :
1866 wintitle :
1870 channelList :
1867 channelList :
1871 showProfile :
1868 showProfile :
1872 xmin : None,
1869 xmin : None,
1873 xmax : None,
1870 xmax : None,
1874 ymin : None,
1871 ymin : None,
1875 ymax : None,
1872 ymax : None,
1876 zmin : None,
1873 zmin : None,
1877 zmax : None
1874 zmax : None
1878 """
1875 """
1879 #SEPARAR EN DOS PLOTS
1876 #SEPARAR EN DOS PLOTS
1880 nParam = dataOut.data_param.shape[1] - 3
1877 nParam = dataOut.data_param.shape[1] - 3
1881
1878
1882 utctime = dataOut.data_param[0,0]
1879 utctime = dataOut.data_param[0,0]
1883 tmet = dataOut.data_param[:,1].astype(int)
1880 tmet = dataOut.data_param[:,1].astype(int)
1884 hmet = dataOut.data_param[:,2].astype(int)
1881 hmet = dataOut.data_param[:,2].astype(int)
1885
1882
1886 x = dataOut.abscissaList
1883 x = dataOut.abscissaList
1887 y = dataOut.heightList
1884 y = dataOut.heightList
1888
1885
1889 z = numpy.zeros((nParam, y.size, x.size - 1))
1886 z = numpy.zeros((nParam, y.size, x.size - 1))
1890 z[:,:] = numpy.nan
1887 z[:,:] = numpy.nan
1891 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
1888 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
1892 z[0,:,:] = 10*numpy.log10(z[0,:,:])
1889 z[0,:,:] = 10*numpy.log10(z[0,:,:])
1893
1890
1894 xlabel = "Time (s)"
1891 xlabel = "Time (s)"
1895 ylabel = "Range (km)"
1892 ylabel = "Range (km)"
1896
1893
1897 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1894 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1898
1895
1899 if not self.isConfig:
1896 if not self.isConfig:
1900
1897
1901 nplots = nParam
1898 nplots = nParam
1902
1899
1903 self.setup(id=id,
1900 self.setup(id=id,
1904 nplots=nplots,
1901 nplots=nplots,
1905 wintitle=wintitle,
1902 wintitle=wintitle,
1906 show=show)
1903 show=show)
1907
1904
1908 if xmin is None: xmin = numpy.nanmin(x)
1905 if xmin is None: xmin = numpy.nanmin(x)
1909 if xmax is None: xmax = numpy.nanmax(x)
1906 if xmax is None: xmax = numpy.nanmax(x)
1910 if ymin is None: ymin = numpy.nanmin(y)
1907 if ymin is None: ymin = numpy.nanmin(y)
1911 if ymax is None: ymax = numpy.nanmax(y)
1908 if ymax is None: ymax = numpy.nanmax(y)
1912 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1909 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1913 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1910 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1914 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1911 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1915 if vmin is None: vmin = -vmax
1912 if vmin is None: vmin = -vmax
1916 if wmin is None: wmin = 0
1913 if wmin is None: wmin = 0
1917 if wmax is None: wmax = 50
1914 if wmax is None: wmax = 50
1918
1915
1919 pairsList = dataOut.groupList
1916 pairsList = dataOut.groupList
1920 self.nPairs = len(dataOut.groupList)
1917 self.nPairs = len(dataOut.groupList)
1921
1918
1922 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
1919 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
1923 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
1920 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
1924 titleList = ["SNR","Radial Velocity","Coherence"]
1921 titleList = ["SNR","Radial Velocity","Coherence"]
1925 cmapList = ["jet","RdBu_r","jet"]
1922 cmapList = ["jet","RdBu_r","jet"]
1926
1923
1927 for i in range(self.nPairs):
1924 for i in range(self.nPairs):
1928 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
1925 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
1929 titleList = titleList + [strAux1]
1926 titleList = titleList + [strAux1]
1930 cmapList = cmapList + ["RdBu_r"]
1927 cmapList = cmapList + ["RdBu_r"]
1931
1928
1932 self.zminList = zminList
1929 self.zminList = zminList
1933 self.zmaxList = zmaxList
1930 self.zmaxList = zmaxList
1934 self.cmapList = cmapList
1931 self.cmapList = cmapList
1935 self.titleList = titleList
1932 self.titleList = titleList
1936
1933
1937 self.FTP_WEI = ftp_wei
1934 self.FTP_WEI = ftp_wei
1938 self.EXP_CODE = exp_code
1935 self.EXP_CODE = exp_code
1939 self.SUB_EXP_CODE = sub_exp_code
1936 self.SUB_EXP_CODE = sub_exp_code
1940 self.PLOT_POS = plot_pos
1937 self.PLOT_POS = plot_pos
1941
1938
1942 self.isConfig = True
1939 self.isConfig = True
1943
1940
1944 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1941 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1945
1942
1946 for i in range(nParam):
1943 for i in range(nParam):
1947 title = self.titleList[i] + ": " +str_datetime
1944 title = self.titleList[i] + ": " +str_datetime
1948 axes = self.axesList[i]
1945 axes = self.axesList[i]
1949 axes.pcolor(x, y, z[i,:].T,
1946 axes.pcolor(x, y, z[i,:].T,
1950 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1947 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1951 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1948 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1952 self.draw()
1949 self.draw()
1953
1950
1954 if figfile == None:
1951 if figfile == None:
1955 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1952 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1956 name = str_datetime
1953 name = str_datetime
1957 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1954 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1958 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1955 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1959 figfile = self.getFilename(name)
1956 figfile = self.getFilename(name)
1960
1957
1961 self.save(figpath=figpath,
1958 self.save(figpath=figpath,
1962 figfile=figfile,
1959 figfile=figfile,
1963 save=save,
1960 save=save,
1964 ftp=ftp,
1961 ftp=ftp,
1965 wr_period=wr_period,
1962 wr_period=wr_period,
1966 thisDatetime=thisDatetime)
1963 thisDatetime=thisDatetime)
1967
1964
1968
1965
1969 class NSMeteorDetection2Plot(Figure):
1966 class NSMeteorDetection2Plot(Figure):
1970
1967
1971 isConfig = None
1968 isConfig = None
1972 __nsubplots = None
1969 __nsubplots = None
1973
1970
1974 WIDTHPROF = None
1971 WIDTHPROF = None
1975 HEIGHTPROF = None
1972 HEIGHTPROF = None
1976 PREFIX = 'nsm'
1973 PREFIX = 'nsm'
1977
1974
1978 zminList = None
1975 zminList = None
1979 zmaxList = None
1976 zmaxList = None
1980 cmapList = None
1977 cmapList = None
1981 titleList = None
1978 titleList = None
1982 nPairs = None
1979 nPairs = None
1983 nChannels = None
1980 nChannels = None
1984 nParam = None
1981 nParam = None
1985
1982
1986 def __init__(self, **kwargs):
1983 def __init__(self, **kwargs):
1987 Figure.__init__(self, **kwargs)
1984 Figure.__init__(self, **kwargs)
1988 self.isConfig = False
1985 self.isConfig = False
1989 self.__nsubplots = 1
1986 self.__nsubplots = 1
1990
1987
1991 self.WIDTH = 750
1988 self.WIDTH = 750
1992 self.HEIGHT = 250
1989 self.HEIGHT = 250
1993 self.WIDTHPROF = 120
1990 self.WIDTHPROF = 120
1994 self.HEIGHTPROF = 0
1991 self.HEIGHTPROF = 0
1995 self.counter_imagwr = 0
1992 self.counter_imagwr = 0
1996
1993
1997 self.PLOT_CODE = SPEC_CODE
1994 self.PLOT_CODE = SPEC_CODE
1998
1995
1999 self.FTP_WEI = None
1996 self.FTP_WEI = None
2000 self.EXP_CODE = None
1997 self.EXP_CODE = None
2001 self.SUB_EXP_CODE = None
1998 self.SUB_EXP_CODE = None
2002 self.PLOT_POS = None
1999 self.PLOT_POS = None
2003
2000
2004 self.__xfilter_ena = False
2001 self.__xfilter_ena = False
2005 self.__yfilter_ena = False
2002 self.__yfilter_ena = False
2006
2003
2007 def getSubplots(self):
2004 def getSubplots(self):
2008
2005
2009 ncol = 3
2006 ncol = 3
2010 nrow = int(numpy.ceil(self.nplots/3.0))
2007 nrow = int(numpy.ceil(self.nplots/3.0))
2011
2008
2012 return nrow, ncol
2009 return nrow, ncol
2013
2010
2014 def setup(self, id, nplots, wintitle, show=True):
2011 def setup(self, id, nplots, wintitle, show=True):
2015
2012
2016 self.nplots = nplots
2013 self.nplots = nplots
2017
2014
2018 ncolspan = 1
2015 ncolspan = 1
2019 colspan = 1
2016 colspan = 1
2020
2017
2021 self.createFigure(id = id,
2018 self.createFigure(id = id,
2022 wintitle = wintitle,
2019 wintitle = wintitle,
2023 widthplot = self.WIDTH + self.WIDTHPROF,
2020 widthplot = self.WIDTH + self.WIDTHPROF,
2024 heightplot = self.HEIGHT + self.HEIGHTPROF,
2021 heightplot = self.HEIGHT + self.HEIGHTPROF,
2025 show=show)
2022 show=show)
2026
2023
2027 nrow, ncol = self.getSubplots()
2024 nrow, ncol = self.getSubplots()
2028
2025
2029 counter = 0
2026 counter = 0
2030 for y in range(nrow):
2027 for y in range(nrow):
2031 for x in range(ncol):
2028 for x in range(ncol):
2032
2029
2033 if counter >= self.nplots:
2030 if counter >= self.nplots:
2034 break
2031 break
2035
2032
2036 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2033 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2037
2034
2038 counter += 1
2035 counter += 1
2039
2036
2040 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2037 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2041 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2038 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2042 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2039 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2043 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2040 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2044 server=None, folder=None, username=None, password=None,
2041 server=None, folder=None, username=None, password=None,
2045 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2042 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2046 xaxis="frequency"):
2043 xaxis="frequency"):
2047
2044
2048 """
2045 """
2049
2046
2050 Input:
2047 Input:
2051 dataOut :
2048 dataOut :
2052 id :
2049 id :
2053 wintitle :
2050 wintitle :
2054 channelList :
2051 channelList :
2055 showProfile :
2052 showProfile :
2056 xmin : None,
2053 xmin : None,
2057 xmax : None,
2054 xmax : None,
2058 ymin : None,
2055 ymin : None,
2059 ymax : None,
2056 ymax : None,
2060 zmin : None,
2057 zmin : None,
2061 zmax : None
2058 zmax : None
2062 """
2059 """
2063 #Rebuild matrix
2060 #Rebuild matrix
2064 utctime = dataOut.data_param[0,0]
2061 utctime = dataOut.data_param[0,0]
2065 cmet = dataOut.data_param[:,1].astype(int)
2062 cmet = dataOut.data_param[:,1].astype(int)
2066 tmet = dataOut.data_param[:,2].astype(int)
2063 tmet = dataOut.data_param[:,2].astype(int)
2067 hmet = dataOut.data_param[:,3].astype(int)
2064 hmet = dataOut.data_param[:,3].astype(int)
2068
2065
2069 nParam = 3
2066 nParam = 3
2070 nChan = len(dataOut.groupList)
2067 nChan = len(dataOut.groupList)
2071 x = dataOut.abscissaList
2068 x = dataOut.abscissaList
2072 y = dataOut.heightList
2069 y = dataOut.heightList
2073
2070
2074 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
2071 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
2075 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
2072 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
2076 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
2073 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
2077 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
2074 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
2078
2075
2079 xlabel = "Time (s)"
2076 xlabel = "Time (s)"
2080 ylabel = "Range (km)"
2077 ylabel = "Range (km)"
2081
2078
2082 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2079 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2083
2080
2084 if not self.isConfig:
2081 if not self.isConfig:
2085
2082
2086 nplots = nParam*nChan
2083 nplots = nParam*nChan
2087
2084
2088 self.setup(id=id,
2085 self.setup(id=id,
2089 nplots=nplots,
2086 nplots=nplots,
2090 wintitle=wintitle,
2087 wintitle=wintitle,
2091 show=show)
2088 show=show)
2092
2089
2093 if xmin is None: xmin = numpy.nanmin(x)
2090 if xmin is None: xmin = numpy.nanmin(x)
2094 if xmax is None: xmax = numpy.nanmax(x)
2091 if xmax is None: xmax = numpy.nanmax(x)
2095 if ymin is None: ymin = numpy.nanmin(y)
2092 if ymin is None: ymin = numpy.nanmin(y)
2096 if ymax is None: ymax = numpy.nanmax(y)
2093 if ymax is None: ymax = numpy.nanmax(y)
2097 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2094 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2098 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2095 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2099 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2096 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2100 if vmin is None: vmin = -vmax
2097 if vmin is None: vmin = -vmax
2101 if wmin is None: wmin = 0
2098 if wmin is None: wmin = 0
2102 if wmax is None: wmax = 50
2099 if wmax is None: wmax = 50
2103
2100
2104 self.nChannels = nChan
2101 self.nChannels = nChan
2105
2102
2106 zminList = []
2103 zminList = []
2107 zmaxList = []
2104 zmaxList = []
2108 titleList = []
2105 titleList = []
2109 cmapList = []
2106 cmapList = []
2110 for i in range(self.nChannels):
2107 for i in range(self.nChannels):
2111 strAux1 = "SNR Channel "+ str(i)
2108 strAux1 = "SNR Channel "+ str(i)
2112 strAux2 = "Radial Velocity Channel "+ str(i)
2109 strAux2 = "Radial Velocity Channel "+ str(i)
2113 strAux3 = "Spectral Width Channel "+ str(i)
2110 strAux3 = "Spectral Width Channel "+ str(i)
2114
2111
2115 titleList = titleList + [strAux1,strAux2,strAux3]
2112 titleList = titleList + [strAux1,strAux2,strAux3]
2116 cmapList = cmapList + ["jet","RdBu_r","jet"]
2113 cmapList = cmapList + ["jet","RdBu_r","jet"]
2117 zminList = zminList + [SNRmin,vmin,wmin]
2114 zminList = zminList + [SNRmin,vmin,wmin]
2118 zmaxList = zmaxList + [SNRmax,vmax,wmax]
2115 zmaxList = zmaxList + [SNRmax,vmax,wmax]
2119
2116
2120 self.zminList = zminList
2117 self.zminList = zminList
2121 self.zmaxList = zmaxList
2118 self.zmaxList = zmaxList
2122 self.cmapList = cmapList
2119 self.cmapList = cmapList
2123 self.titleList = titleList
2120 self.titleList = titleList
2124
2121
2125 self.FTP_WEI = ftp_wei
2122 self.FTP_WEI = ftp_wei
2126 self.EXP_CODE = exp_code
2123 self.EXP_CODE = exp_code
2127 self.SUB_EXP_CODE = sub_exp_code
2124 self.SUB_EXP_CODE = sub_exp_code
2128 self.PLOT_POS = plot_pos
2125 self.PLOT_POS = plot_pos
2129
2126
2130 self.isConfig = True
2127 self.isConfig = True
2131
2128
2132 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2129 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2133
2130
2134 for i in range(self.nplots):
2131 for i in range(self.nplots):
2135 title = self.titleList[i] + ": " +str_datetime
2132 title = self.titleList[i] + ": " +str_datetime
2136 axes = self.axesList[i]
2133 axes = self.axesList[i]
2137 axes.pcolor(x, y, z[i,:].T,
2134 axes.pcolor(x, y, z[i,:].T,
2138 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2135 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2139 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2136 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2140 self.draw()
2137 self.draw()
2141
2138
2142 if figfile == None:
2139 if figfile == None:
2143 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2140 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2144 name = str_datetime
2141 name = str_datetime
2145 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2142 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2146 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2143 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2147 figfile = self.getFilename(name)
2144 figfile = self.getFilename(name)
2148
2145
2149 self.save(figpath=figpath,
2146 self.save(figpath=figpath,
2150 figfile=figfile,
2147 figfile=figfile,
2151 save=save,
2148 save=save,
2152 ftp=ftp,
2149 ftp=ftp,
2153 wr_period=wr_period,
2150 wr_period=wr_period,
2154 thisDatetime=thisDatetime)
2151 thisDatetime=thisDatetime)
@@ -1,481 +1,481
1 import numpy
1 import numpy
2 import datetime
2 import datetime
3 import sys
3 import sys
4 import matplotlib
4 import matplotlib
5
5
6 if 'linux' in sys.platform:
6 if 'linux' in sys.platform:
7 matplotlib.use("TKAgg")
7 matplotlib.use("GTK3Agg")
8
8
9 if 'darwin' in sys.platform:
9 if 'darwin' in sys.platform:
10 matplotlib.use('TKAgg')
10 matplotlib.use('TKAgg')
11 #Qt4Agg', 'GTK', 'GTKAgg', 'ps', 'agg', 'cairo', 'MacOSX', 'GTKCairo', 'WXAgg', 'template', 'TkAgg', 'GTK3Cairo', 'GTK3Agg', 'svg', 'WebAgg', 'CocoaAgg', 'emf', 'gdk', 'WX'
11 #Qt4Agg', 'GTK', 'GTKAgg', 'ps', 'agg', 'cairo', 'MacOSX', 'GTKCairo', 'WXAgg', 'template', 'TkAgg', 'GTK3Cairo', 'GTK3Agg', 'svg', 'WebAgg', 'CocoaAgg', 'emf', 'gdk', 'WX'
12 import matplotlib.pyplot
12 import matplotlib.pyplot
13
13
14 from mpl_toolkits.axes_grid1 import make_axes_locatable
14 from mpl_toolkits.axes_grid1 import make_axes_locatable
15 from matplotlib.ticker import FuncFormatter, LinearLocator
15 from matplotlib.ticker import FuncFormatter, LinearLocator
16
16
17 ###########################################
17 ###########################################
18 #Actualizacion de las funciones del driver
18 #Actualizacion de las funciones del driver
19 ###########################################
19 ###########################################
20
20
21 # create jro colormap
21 # create jro colormap
22
22
23 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
23 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
24 blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15]
24 blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15]
25 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values)))
25 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values)))
26 matplotlib.pyplot.register_cmap(cmap=ncmap)
26 matplotlib.pyplot.register_cmap(cmap=ncmap)
27
27
28 def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi = 80):
28 def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi = 80):
29
29
30 matplotlib.pyplot.ioff()
30 matplotlib.pyplot.ioff()
31
31
32 fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor, figsize=(1.0*width/dpi, 1.0*height/dpi))
32 fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor, figsize=(1.0*width/dpi, 1.0*height/dpi))
33 fig.canvas.manager.set_window_title(wintitle)
33 fig.canvas.manager.set_window_title(wintitle)
34 # fig.canvas.manager.resize(width, height)
34 # fig.canvas.manager.resize(width, height)
35 matplotlib.pyplot.ion()
35 matplotlib.pyplot.ion()
36
36
37 if show:
37 if show:
38 matplotlib.pyplot.show()
38 matplotlib.pyplot.show()
39
39
40 return fig
40 return fig
41
41
42 def closeFigure(show=False, fig=None):
42 def closeFigure(show=False, fig=None):
43
43
44 # matplotlib.pyplot.ioff()
44 # matplotlib.pyplot.ioff()
45 # matplotlib.pyplot.pause(0)
45 # matplotlib.pyplot.pause(0)
46
46
47 if show:
47 if show:
48 matplotlib.pyplot.show()
48 matplotlib.pyplot.show()
49
49
50 if fig != None:
50 if fig != None:
51 matplotlib.pyplot.close(fig)
51 matplotlib.pyplot.close(fig)
52 # matplotlib.pyplot.pause(0)
52 # matplotlib.pyplot.pause(0)
53 # matplotlib.pyplot.ion()
53 # matplotlib.pyplot.ion()
54
54
55 return
55 return
56
56
57 matplotlib.pyplot.close("all")
57 matplotlib.pyplot.close("all")
58 # matplotlib.pyplot.pause(0)
58 # matplotlib.pyplot.pause(0)
59 # matplotlib.pyplot.ion()
59 # matplotlib.pyplot.ion()
60
60
61 return
61 return
62
62
63 def saveFigure(fig, filename):
63 def saveFigure(fig, filename):
64
64
65 # matplotlib.pyplot.ioff()
65 # matplotlib.pyplot.ioff()
66 fig.savefig(filename, dpi=matplotlib.pyplot.gcf().dpi)
66 fig.savefig(filename, dpi=matplotlib.pyplot.gcf().dpi)
67 # matplotlib.pyplot.ion()
67 # matplotlib.pyplot.ion()
68
68
69 def clearFigure(fig):
69 def clearFigure(fig):
70
70
71 fig.clf()
71 fig.clf()
72
72
73 def setWinTitle(fig, title):
73 def setWinTitle(fig, title):
74
74
75 fig.canvas.manager.set_window_title(title)
75 fig.canvas.manager.set_window_title(title)
76
76
77 def setTitle(fig, title):
77 def setTitle(fig, title):
78
78
79 fig.suptitle(title)
79 fig.suptitle(title)
80
80
81 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan, polar=False):
81 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan, polar=False):
82
82
83 matplotlib.pyplot.ioff()
83 matplotlib.pyplot.ioff()
84 matplotlib.pyplot.figure(fig.number)
84 matplotlib.pyplot.figure(fig.number)
85 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
85 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
86 (xpos, ypos),
86 (xpos, ypos),
87 colspan=colspan,
87 colspan=colspan,
88 rowspan=rowspan,
88 rowspan=rowspan,
89 polar=polar)
89 polar=polar)
90
90
91 axes.grid(True)
91 axes.grid(True)
92
92
93 matplotlib.pyplot.ion()
93 matplotlib.pyplot.ion()
94 return axes
94 return axes
95
95
96 def setAxesText(ax, text):
96 def setAxesText(ax, text):
97
97
98 ax.annotate(text,
98 ax.annotate(text,
99 xy = (.1, .99),
99 xy = (.1, .99),
100 xycoords = 'figure fraction',
100 xycoords = 'figure fraction',
101 horizontalalignment = 'left',
101 horizontalalignment = 'left',
102 verticalalignment = 'top',
102 verticalalignment = 'top',
103 fontsize = 10)
103 fontsize = 10)
104
104
105 def printLabels(ax, xlabel, ylabel, title):
105 def printLabels(ax, xlabel, ylabel, title):
106
106
107 ax.set_xlabel(xlabel, size=11)
107 ax.set_xlabel(xlabel, size=11)
108 ax.set_ylabel(ylabel, size=11)
108 ax.set_ylabel(ylabel, size=11)
109 ax.set_title(title, size=8)
109 ax.set_title(title, size=8)
110
110
111 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='',
111 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='',
112 ticksize=9, xtick_visible=True, ytick_visible=True,
112 ticksize=9, xtick_visible=True, ytick_visible=True,
113 nxticks=4, nyticks=10,
113 nxticks=4, nyticks=10,
114 grid=None,color='blue'):
114 grid=None,color='blue'):
115
115
116 """
116 """
117
117
118 Input:
118 Input:
119 grid : None, 'both', 'x', 'y'
119 grid : None, 'both', 'x', 'y'
120 """
120 """
121
121
122 matplotlib.pyplot.ioff()
122 matplotlib.pyplot.ioff()
123
123
124 ax.set_xlim([xmin,xmax])
124 ax.set_xlim([xmin,xmax])
125 ax.set_ylim([ymin,ymax])
125 ax.set_ylim([ymin,ymax])
126
126
127 printLabels(ax, xlabel, ylabel, title)
127 printLabels(ax, xlabel, ylabel, title)
128
128
129 ######################################################
129 ######################################################
130 if (xmax-xmin)<=1:
130 if (xmax-xmin)<=1:
131 xtickspos = numpy.linspace(xmin,xmax,nxticks)
131 xtickspos = numpy.linspace(xmin,xmax,nxticks)
132 xtickspos = numpy.array([float("%.1f"%i) for i in xtickspos])
132 xtickspos = numpy.array([float("%.1f"%i) for i in xtickspos])
133 ax.set_xticks(xtickspos)
133 ax.set_xticks(xtickspos)
134 else:
134 else:
135 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
135 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
136 # xtickspos = numpy.arange(nxticks)*float(xmax-xmin)/float(nxticks) + int(xmin)
136 # xtickspos = numpy.arange(nxticks)*float(xmax-xmin)/float(nxticks) + int(xmin)
137 ax.set_xticks(xtickspos)
137 ax.set_xticks(xtickspos)
138
138
139 for tick in ax.get_xticklabels():
139 for tick in ax.get_xticklabels():
140 tick.set_visible(xtick_visible)
140 tick.set_visible(xtick_visible)
141
141
142 for tick in ax.xaxis.get_major_ticks():
142 for tick in ax.xaxis.get_major_ticks():
143 tick.label.set_fontsize(ticksize)
143 tick.label.set_fontsize(ticksize)
144
144
145 ######################################################
145 ######################################################
146 for tick in ax.get_yticklabels():
146 for tick in ax.get_yticklabels():
147 tick.set_visible(ytick_visible)
147 tick.set_visible(ytick_visible)
148
148
149 for tick in ax.yaxis.get_major_ticks():
149 for tick in ax.yaxis.get_major_ticks():
150 tick.label.set_fontsize(ticksize)
150 tick.label.set_fontsize(ticksize)
151
151
152 ax.plot(x, y, color=color)
152 ax.plot(x, y, color=color)
153 iplot = ax.lines[-1]
153 iplot = ax.lines[-1]
154
154
155 ######################################################
155 ######################################################
156 if '0.' in matplotlib.__version__[0:2]:
156 if '0.' in matplotlib.__version__[0:2]:
157 print "The matplotlib version has to be updated to 1.1 or newer"
157 print "The matplotlib version has to be updated to 1.1 or newer"
158 return iplot
158 return iplot
159
159
160 if '1.0.' in matplotlib.__version__[0:4]:
160 if '1.0.' in matplotlib.__version__[0:4]:
161 print "The matplotlib version has to be updated to 1.1 or newer"
161 print "The matplotlib version has to be updated to 1.1 or newer"
162 return iplot
162 return iplot
163
163
164 if grid != None:
164 if grid != None:
165 ax.grid(b=True, which='major', axis=grid)
165 ax.grid(b=True, which='major', axis=grid)
166
166
167 matplotlib.pyplot.tight_layout()
167 matplotlib.pyplot.tight_layout()
168
168
169 matplotlib.pyplot.ion()
169 matplotlib.pyplot.ion()
170
170
171 return iplot
171 return iplot
172
172
173 def set_linedata(ax, x, y, idline):
173 def set_linedata(ax, x, y, idline):
174
174
175 ax.lines[idline].set_data(x,y)
175 ax.lines[idline].set_data(x,y)
176
176
177 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
177 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
178
178
179 ax = iplot.get_axes()
179 ax = iplot.get_axes()
180
180
181 printLabels(ax, xlabel, ylabel, title)
181 printLabels(ax, xlabel, ylabel, title)
182
182
183 set_linedata(ax, x, y, idline=0)
183 set_linedata(ax, x, y, idline=0)
184
184
185 def addpline(ax, x, y, color, linestyle, lw):
185 def addpline(ax, x, y, color, linestyle, lw):
186
186
187 ax.plot(x,y,color=color,linestyle=linestyle,lw=lw)
187 ax.plot(x,y,color=color,linestyle=linestyle,lw=lw)
188
188
189
189
190 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
190 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
191 xlabel='', ylabel='', title='', ticksize = 9,
191 xlabel='', ylabel='', title='', ticksize = 9,
192 colormap='jet',cblabel='', cbsize="5%",
192 colormap='jet',cblabel='', cbsize="5%",
193 XAxisAsTime=False):
193 XAxisAsTime=False):
194
194
195 matplotlib.pyplot.ioff()
195 matplotlib.pyplot.ioff()
196
196
197 divider = make_axes_locatable(ax)
197 divider = make_axes_locatable(ax)
198 ax_cb = divider.new_horizontal(size=cbsize, pad=0.05)
198 ax_cb = divider.new_horizontal(size=cbsize, pad=0.05)
199 fig = ax.get_figure()
199 fig = ax.get_figure()
200 fig.add_axes(ax_cb)
200 fig.add_axes(ax_cb)
201
201
202 ax.set_xlim([xmin,xmax])
202 ax.set_xlim([xmin,xmax])
203 ax.set_ylim([ymin,ymax])
203 ax.set_ylim([ymin,ymax])
204
204
205 printLabels(ax, xlabel, ylabel, title)
205 printLabels(ax, xlabel, ylabel, title)
206
206
207 z = numpy.ma.masked_invalid(z)
207 z = numpy.ma.masked_invalid(z)
208 cmap=matplotlib.pyplot.get_cmap(colormap)
208 cmap=matplotlib.pyplot.get_cmap(colormap)
209 cmap.set_bad('white',1.)
209 cmap.set_bad('white',1.)
210 imesh = ax.pcolormesh(x,y,z.T, vmin=zmin, vmax=zmax, cmap=cmap)
210 imesh = ax.pcolormesh(x,y,z.T, vmin=zmin, vmax=zmax, cmap=cmap)
211 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
211 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
212 cb.set_label(cblabel)
212 cb.set_label(cblabel)
213
213
214 # for tl in ax_cb.get_yticklabels():
214 # for tl in ax_cb.get_yticklabels():
215 # tl.set_visible(True)
215 # tl.set_visible(True)
216
216
217 for tick in ax.yaxis.get_major_ticks():
217 for tick in ax.yaxis.get_major_ticks():
218 tick.label.set_fontsize(ticksize)
218 tick.label.set_fontsize(ticksize)
219
219
220 for tick in ax.xaxis.get_major_ticks():
220 for tick in ax.xaxis.get_major_ticks():
221 tick.label.set_fontsize(ticksize)
221 tick.label.set_fontsize(ticksize)
222
222
223 for tick in cb.ax.get_yticklabels():
223 for tick in cb.ax.get_yticklabels():
224 tick.set_fontsize(ticksize)
224 tick.set_fontsize(ticksize)
225
225
226 ax_cb.yaxis.tick_right()
226 ax_cb.yaxis.tick_right()
227
227
228 if '0.' in matplotlib.__version__[0:2]:
228 if '0.' in matplotlib.__version__[0:2]:
229 print "The matplotlib version has to be updated to 1.1 or newer"
229 print "The matplotlib version has to be updated to 1.1 or newer"
230 return imesh
230 return imesh
231
231
232 if '1.0.' in matplotlib.__version__[0:4]:
232 if '1.0.' in matplotlib.__version__[0:4]:
233 print "The matplotlib version has to be updated to 1.1 or newer"
233 print "The matplotlib version has to be updated to 1.1 or newer"
234 return imesh
234 return imesh
235
235
236 matplotlib.pyplot.tight_layout()
236 matplotlib.pyplot.tight_layout()
237
237
238 if XAxisAsTime:
238 if XAxisAsTime:
239
239
240 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
240 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
241 ax.xaxis.set_major_formatter(FuncFormatter(func))
241 ax.xaxis.set_major_formatter(FuncFormatter(func))
242 ax.xaxis.set_major_locator(LinearLocator(7))
242 ax.xaxis.set_major_locator(LinearLocator(7))
243
243
244 ax.grid(True)
244 ax.grid(True)
245 matplotlib.pyplot.ion()
245 matplotlib.pyplot.ion()
246 return imesh
246 return imesh
247
247
248 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
248 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
249
249
250 z = numpy.ma.masked_invalid(z)
250 z = numpy.ma.masked_invalid(z)
251
251
252 cmap=matplotlib.pyplot.get_cmap('jet')
252 cmap=matplotlib.pyplot.get_cmap('jet')
253 cmap.set_bad('white',1.)
253 cmap.set_bad('white',1.)
254
254
255 z = z.T
255 z = z.T
256 ax = imesh.get_axes()
256 ax = imesh.get_axes()
257 printLabels(ax, xlabel, ylabel, title)
257 printLabels(ax, xlabel, ylabel, title)
258 imesh.set_array(z.ravel())
258 imesh.set_array(z.ravel())
259 ax.grid(True)
259 ax.grid(True)
260
260
261
261
262 def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
262 def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
263
263
264 printLabels(ax, xlabel, ylabel, title)
264 printLabels(ax, xlabel, ylabel, title)
265 z = numpy.ma.masked_invalid(z)
265 z = numpy.ma.masked_invalid(z)
266 cmap=matplotlib.pyplot.get_cmap(colormap)
266 cmap=matplotlib.pyplot.get_cmap(colormap)
267 cmap.set_bad('white',1.)
267 cmap.set_bad('white',1.)
268 ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
268 ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
269 ax.grid(True)
269 ax.grid(True)
270
270
271 def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
271 def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
272
272
273 printLabels(ax, xlabel, ylabel, title)
273 printLabels(ax, xlabel, ylabel, title)
274
274
275 ax.collections.remove(ax.collections[0])
275 ax.collections.remove(ax.collections[0])
276
276
277 z = numpy.ma.masked_invalid(z)
277 z = numpy.ma.masked_invalid(z)
278
278
279 cmap=matplotlib.pyplot.get_cmap(colormap)
279 cmap=matplotlib.pyplot.get_cmap(colormap)
280 cmap.set_bad('white',1.)
280 cmap.set_bad('white',1.)
281
281
282 ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=cmap)
282 ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=cmap)
283 ax.grid(True)
283 ax.grid(True)
284
284
285
285
286 def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
286 def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
287 ticksize=9, xtick_visible=True, ytick_visible=True,
287 ticksize=9, xtick_visible=True, ytick_visible=True,
288 nxticks=4, nyticks=10,
288 nxticks=4, nyticks=10,
289 grid=None):
289 grid=None):
290
290
291 """
291 """
292
292
293 Input:
293 Input:
294 grid : None, 'both', 'x', 'y'
294 grid : None, 'both', 'x', 'y'
295 """
295 """
296
296
297 matplotlib.pyplot.ioff()
297 matplotlib.pyplot.ioff()
298
298
299 lines = ax.plot(x.T, y)
299 lines = ax.plot(x.T, y)
300 leg = ax.legend(lines, legendlabels, loc='upper right')
300 leg = ax.legend(lines, legendlabels, loc='upper right')
301 leg.get_frame().set_alpha(0.5)
301 leg.get_frame().set_alpha(0.5)
302 ax.set_xlim([xmin,xmax])
302 ax.set_xlim([xmin,xmax])
303 ax.set_ylim([ymin,ymax])
303 ax.set_ylim([ymin,ymax])
304 printLabels(ax, xlabel, ylabel, title)
304 printLabels(ax, xlabel, ylabel, title)
305
305
306 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
306 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
307 ax.set_xticks(xtickspos)
307 ax.set_xticks(xtickspos)
308
308
309 for tick in ax.get_xticklabels():
309 for tick in ax.get_xticklabels():
310 tick.set_visible(xtick_visible)
310 tick.set_visible(xtick_visible)
311
311
312 for tick in ax.xaxis.get_major_ticks():
312 for tick in ax.xaxis.get_major_ticks():
313 tick.label.set_fontsize(ticksize)
313 tick.label.set_fontsize(ticksize)
314
314
315 for tick in ax.get_yticklabels():
315 for tick in ax.get_yticklabels():
316 tick.set_visible(ytick_visible)
316 tick.set_visible(ytick_visible)
317
317
318 for tick in ax.yaxis.get_major_ticks():
318 for tick in ax.yaxis.get_major_ticks():
319 tick.label.set_fontsize(ticksize)
319 tick.label.set_fontsize(ticksize)
320
320
321 iplot = ax.lines[-1]
321 iplot = ax.lines[-1]
322
322
323 if '0.' in matplotlib.__version__[0:2]:
323 if '0.' in matplotlib.__version__[0:2]:
324 print "The matplotlib version has to be updated to 1.1 or newer"
324 print "The matplotlib version has to be updated to 1.1 or newer"
325 return iplot
325 return iplot
326
326
327 if '1.0.' in matplotlib.__version__[0:4]:
327 if '1.0.' in matplotlib.__version__[0:4]:
328 print "The matplotlib version has to be updated to 1.1 or newer"
328 print "The matplotlib version has to be updated to 1.1 or newer"
329 return iplot
329 return iplot
330
330
331 if grid != None:
331 if grid != None:
332 ax.grid(b=True, which='major', axis=grid)
332 ax.grid(b=True, which='major', axis=grid)
333
333
334 matplotlib.pyplot.tight_layout()
334 matplotlib.pyplot.tight_layout()
335
335
336 matplotlib.pyplot.ion()
336 matplotlib.pyplot.ion()
337
337
338 return iplot
338 return iplot
339
339
340
340
341 def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''):
341 def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''):
342
342
343 ax = iplot.get_axes()
343 ax = iplot.get_axes()
344
344
345 printLabels(ax, xlabel, ylabel, title)
345 printLabels(ax, xlabel, ylabel, title)
346
346
347 for i in range(len(ax.lines)):
347 for i in range(len(ax.lines)):
348 line = ax.lines[i]
348 line = ax.lines[i]
349 line.set_data(x[i,:],y)
349 line.set_data(x[i,:],y)
350
350
351 def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
351 def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
352 ticksize=9, xtick_visible=True, ytick_visible=True,
352 ticksize=9, xtick_visible=True, ytick_visible=True,
353 nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None",
353 nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None",
354 grid=None, XAxisAsTime=False):
354 grid=None, XAxisAsTime=False):
355
355
356 """
356 """
357
357
358 Input:
358 Input:
359 grid : None, 'both', 'x', 'y'
359 grid : None, 'both', 'x', 'y'
360 """
360 """
361
361
362 matplotlib.pyplot.ioff()
362 matplotlib.pyplot.ioff()
363
363
364 # lines = ax.plot(x, y.T, marker=marker,markersize=markersize,linestyle=linestyle)
364 # lines = ax.plot(x, y.T, marker=marker,markersize=markersize,linestyle=linestyle)
365 lines = ax.plot(x, y.T)
365 lines = ax.plot(x, y.T)
366 # leg = ax.legend(lines, legendlabels, loc=2, bbox_to_anchor=(1.01, 1.00), numpoints=1, handlelength=1.5, \
366 # leg = ax.legend(lines, legendlabels, loc=2, bbox_to_anchor=(1.01, 1.00), numpoints=1, handlelength=1.5, \
367 # handletextpad=0.5, borderpad=0.5, labelspacing=0.5, borderaxespad=0.)
367 # handletextpad=0.5, borderpad=0.5, labelspacing=0.5, borderaxespad=0.)
368
368
369 leg = ax.legend(lines, legendlabels,
369 leg = ax.legend(lines, legendlabels,
370 loc='upper right', bbox_to_anchor=(1.16, 1), borderaxespad=0)
370 loc='upper right', bbox_to_anchor=(1.16, 1), borderaxespad=0)
371
371
372 for label in leg.get_texts(): label.set_fontsize(9)
372 for label in leg.get_texts(): label.set_fontsize(9)
373
373
374 ax.set_xlim([xmin,xmax])
374 ax.set_xlim([xmin,xmax])
375 ax.set_ylim([ymin,ymax])
375 ax.set_ylim([ymin,ymax])
376 printLabels(ax, xlabel, ylabel, title)
376 printLabels(ax, xlabel, ylabel, title)
377
377
378 # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
378 # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
379 # ax.set_xticks(xtickspos)
379 # ax.set_xticks(xtickspos)
380
380
381 for tick in ax.get_xticklabels():
381 for tick in ax.get_xticklabels():
382 tick.set_visible(xtick_visible)
382 tick.set_visible(xtick_visible)
383
383
384 for tick in ax.xaxis.get_major_ticks():
384 for tick in ax.xaxis.get_major_ticks():
385 tick.label.set_fontsize(ticksize)
385 tick.label.set_fontsize(ticksize)
386
386
387 for tick in ax.get_yticklabels():
387 for tick in ax.get_yticklabels():
388 tick.set_visible(ytick_visible)
388 tick.set_visible(ytick_visible)
389
389
390 for tick in ax.yaxis.get_major_ticks():
390 for tick in ax.yaxis.get_major_ticks():
391 tick.label.set_fontsize(ticksize)
391 tick.label.set_fontsize(ticksize)
392
392
393 iplot = ax.lines[-1]
393 iplot = ax.lines[-1]
394
394
395 if '0.' in matplotlib.__version__[0:2]:
395 if '0.' in matplotlib.__version__[0:2]:
396 print "The matplotlib version has to be updated to 1.1 or newer"
396 print "The matplotlib version has to be updated to 1.1 or newer"
397 return iplot
397 return iplot
398
398
399 if '1.0.' in matplotlib.__version__[0:4]:
399 if '1.0.' in matplotlib.__version__[0:4]:
400 print "The matplotlib version has to be updated to 1.1 or newer"
400 print "The matplotlib version has to be updated to 1.1 or newer"
401 return iplot
401 return iplot
402
402
403 if grid != None:
403 if grid != None:
404 ax.grid(b=True, which='major', axis=grid)
404 ax.grid(b=True, which='major', axis=grid)
405
405
406 matplotlib.pyplot.tight_layout()
406 matplotlib.pyplot.tight_layout()
407
407
408 if XAxisAsTime:
408 if XAxisAsTime:
409
409
410 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
410 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
411 ax.xaxis.set_major_formatter(FuncFormatter(func))
411 ax.xaxis.set_major_formatter(FuncFormatter(func))
412 ax.xaxis.set_major_locator(LinearLocator(7))
412 ax.xaxis.set_major_locator(LinearLocator(7))
413
413
414 matplotlib.pyplot.ion()
414 matplotlib.pyplot.ion()
415
415
416 return iplot
416 return iplot
417
417
418 def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''):
418 def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''):
419
419
420 ax = iplot.get_axes()
420 ax = iplot.get_axes()
421 printLabels(ax, xlabel, ylabel, title)
421 printLabels(ax, xlabel, ylabel, title)
422
422
423 for i in range(len(ax.lines)):
423 for i in range(len(ax.lines)):
424 line = ax.lines[i]
424 line = ax.lines[i]
425 line.set_data(x,y[i,:])
425 line.set_data(x,y[i,:])
426
426
427 def createPolar(ax, x, y,
427 def createPolar(ax, x, y,
428 xlabel='', ylabel='', title='', ticksize = 9,
428 xlabel='', ylabel='', title='', ticksize = 9,
429 colormap='jet',cblabel='', cbsize="5%",
429 colormap='jet',cblabel='', cbsize="5%",
430 XAxisAsTime=False):
430 XAxisAsTime=False):
431
431
432 matplotlib.pyplot.ioff()
432 matplotlib.pyplot.ioff()
433
433
434 ax.plot(x,y,'bo', markersize=5)
434 ax.plot(x,y,'bo', markersize=5)
435 # ax.set_rmax(90)
435 # ax.set_rmax(90)
436 ax.set_ylim(0,90)
436 ax.set_ylim(0,90)
437 ax.set_yticks(numpy.arange(0,90,20))
437 ax.set_yticks(numpy.arange(0,90,20))
438 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center' ,size='11')
438 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center' ,size='11')
439 # ax.text(0, 50, ylabel, rotation='vertical', va ='center', ha = 'left' ,size='11')
439 # ax.text(0, 50, ylabel, rotation='vertical', va ='center', ha = 'left' ,size='11')
440 # ax.text(100, 100, 'example', ha='left', va='center', rotation='vertical')
440 # ax.text(100, 100, 'example', ha='left', va='center', rotation='vertical')
441 ax.yaxis.labelpad = 230
441 ax.yaxis.labelpad = 230
442 printLabels(ax, xlabel, ylabel, title)
442 printLabels(ax, xlabel, ylabel, title)
443 iplot = ax.lines[-1]
443 iplot = ax.lines[-1]
444
444
445 if '0.' in matplotlib.__version__[0:2]:
445 if '0.' in matplotlib.__version__[0:2]:
446 print "The matplotlib version has to be updated to 1.1 or newer"
446 print "The matplotlib version has to be updated to 1.1 or newer"
447 return iplot
447 return iplot
448
448
449 if '1.0.' in matplotlib.__version__[0:4]:
449 if '1.0.' in matplotlib.__version__[0:4]:
450 print "The matplotlib version has to be updated to 1.1 or newer"
450 print "The matplotlib version has to be updated to 1.1 or newer"
451 return iplot
451 return iplot
452
452
453 # if grid != None:
453 # if grid != None:
454 # ax.grid(b=True, which='major', axis=grid)
454 # ax.grid(b=True, which='major', axis=grid)
455
455
456 matplotlib.pyplot.tight_layout()
456 matplotlib.pyplot.tight_layout()
457
457
458 matplotlib.pyplot.ion()
458 matplotlib.pyplot.ion()
459
459
460
460
461 return iplot
461 return iplot
462
462
463 def polar(iplot, x, y, xlabel='', ylabel='', title=''):
463 def polar(iplot, x, y, xlabel='', ylabel='', title=''):
464
464
465 ax = iplot.get_axes()
465 ax = iplot.get_axes()
466
466
467 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center',size='11')
467 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center',size='11')
468 printLabels(ax, xlabel, ylabel, title)
468 printLabels(ax, xlabel, ylabel, title)
469
469
470 set_linedata(ax, x, y, idline=0)
470 set_linedata(ax, x, y, idline=0)
471
471
472 def draw(fig):
472 def draw(fig):
473
473
474 if type(fig) == 'int':
474 if type(fig) == 'int':
475 raise ValueError, "Error drawing: Fig parameter should be a matplotlib figure object figure"
475 raise ValueError, "Error drawing: Fig parameter should be a matplotlib figure object figure"
476
476
477 fig.canvas.draw()
477 fig.canvas.draw()
478
478
479 def pause(interval=0.000001):
479 def pause(interval=0.000001):
480
480
481 matplotlib.pyplot.pause(interval)
481 matplotlib.pyplot.pause(interval)
@@ -1,21 +1,20
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
5 '''
5 '''
6
6
7 from jroIO_voltage import *
7 from jroIO_voltage import *
8 from jroIO_spectra import *
8 from jroIO_spectra import *
9 from jroIO_heispectra import *
9 from jroIO_heispectra import *
10 from jroIO_usrp import *
10 from jroIO_usrp import *
11
11
12 from jroIO_kamisr import *
12 from jroIO_kamisr import *
13 from jroIO_param import *
13 from jroIO_param import *
14 from jroIO_hf import *
14 from jroIO_hf import *
15
15
16 from jroIO_madrigal import *
16 from jroIO_madrigal import *
17
17
18 from bltrIO_param import *
18 from bltrIO_param import *
19 from jroIO_bltr import *
19 from jroIO_bltr import *
20 from jroIO_mira35c import *
20 from jroIO_mira35c import *
21
@@ -1,1795 +1,1807
1 '''
1 '''
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import os
6 import os
7 import sys
7 import sys
8 import glob
8 import glob
9 import time
9 import time
10 import numpy
10 import numpy
11 import fnmatch
11 import fnmatch
12 import inspect
12 import inspect
13 import time, datetime
13 import time, datetime
14 import traceback
14 import traceback
15 import zmq
15 import zmq
16
16
17 try:
17 try:
18 from gevent import sleep
18 from gevent import sleep
19 except:
19 except:
20 from time import sleep
20 from time import sleep
21
21
22 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
22 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
23 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
23 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
24
24
25 LOCALTIME = True
25 LOCALTIME = True
26
26
27 def isNumber(cad):
27 def isNumber(cad):
28 """
28 """
29 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
29 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
30
30
31 Excepciones:
31 Excepciones:
32 Si un determinado string no puede ser convertido a numero
32 Si un determinado string no puede ser convertido a numero
33 Input:
33 Input:
34 str, string al cual se le analiza para determinar si convertible a un numero o no
34 str, string al cual se le analiza para determinar si convertible a un numero o no
35
35
36 Return:
36 Return:
37 True : si el string es uno numerico
37 True : si el string es uno numerico
38 False : no es un string numerico
38 False : no es un string numerico
39 """
39 """
40 try:
40 try:
41 float( cad )
41 float( cad )
42 return True
42 return True
43 except:
43 except:
44 return False
44 return False
45
45
46 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
46 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
47 """
47 """
48 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
48 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
49
49
50 Inputs:
50 Inputs:
51 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
51 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
52
52
53 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
53 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
54 segundos contados desde 01/01/1970.
54 segundos contados desde 01/01/1970.
55 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
55 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
56 segundos contados desde 01/01/1970.
56 segundos contados desde 01/01/1970.
57
57
58 Return:
58 Return:
59 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
59 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
60 fecha especificado, de lo contrario retorna False.
60 fecha especificado, de lo contrario retorna False.
61
61
62 Excepciones:
62 Excepciones:
63 Si el archivo no existe o no puede ser abierto
63 Si el archivo no existe o no puede ser abierto
64 Si la cabecera no puede ser leida.
64 Si la cabecera no puede ser leida.
65
65
66 """
66 """
67 basicHeaderObj = BasicHeader(LOCALTIME)
67 basicHeaderObj = BasicHeader(LOCALTIME)
68
68
69 try:
69 try:
70 fp = open(filename,'rb')
70 fp = open(filename,'rb')
71 except IOError:
71 except IOError:
72 print "The file %s can't be opened" %(filename)
72 print "The file %s can't be opened" %(filename)
73 return 0
73 return 0
74
74
75 sts = basicHeaderObj.read(fp)
75 sts = basicHeaderObj.read(fp)
76 fp.close()
76 fp.close()
77
77
78 if not(sts):
78 if not(sts):
79 print "Skipping the file %s because it has not a valid header" %(filename)
79 print "Skipping the file %s because it has not a valid header" %(filename)
80 return 0
80 return 0
81
81
82 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
82 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
83 return 0
83 return 0
84
84
85 return 1
85 return 1
86
86
87 def isTimeInRange(thisTime, startTime, endTime):
87 def isTimeInRange(thisTime, startTime, endTime):
88
88
89 if endTime >= startTime:
89 if endTime >= startTime:
90 if (thisTime < startTime) or (thisTime > endTime):
90 if (thisTime < startTime) or (thisTime > endTime):
91 return 0
91 return 0
92
92
93 return 1
93 return 1
94 else:
94 else:
95 if (thisTime < startTime) and (thisTime > endTime):
95 if (thisTime < startTime) and (thisTime > endTime):
96 return 0
96 return 0
97
97
98 return 1
98 return 1
99
99
100 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
100 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
101 """
101 """
102 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
102 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
103
103
104 Inputs:
104 Inputs:
105 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
105 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
106
106
107 startDate : fecha inicial del rango seleccionado en formato datetime.date
107 startDate : fecha inicial del rango seleccionado en formato datetime.date
108
108
109 endDate : fecha final del rango seleccionado en formato datetime.date
109 endDate : fecha final del rango seleccionado en formato datetime.date
110
110
111 startTime : tiempo inicial del rango seleccionado en formato datetime.time
111 startTime : tiempo inicial del rango seleccionado en formato datetime.time
112
112
113 endTime : tiempo final del rango seleccionado en formato datetime.time
113 endTime : tiempo final del rango seleccionado en formato datetime.time
114
114
115 Return:
115 Return:
116 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
116 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
117 fecha especificado, de lo contrario retorna False.
117 fecha especificado, de lo contrario retorna False.
118
118
119 Excepciones:
119 Excepciones:
120 Si el archivo no existe o no puede ser abierto
120 Si el archivo no existe o no puede ser abierto
121 Si la cabecera no puede ser leida.
121 Si la cabecera no puede ser leida.
122
122
123 """
123 """
124
124
125
125
126 try:
126 try:
127 fp = open(filename,'rb')
127 fp = open(filename,'rb')
128 except IOError:
128 except IOError:
129 print "The file %s can't be opened" %(filename)
129 print "The file %s can't be opened" %(filename)
130 return None
130 return None
131
131
132 firstBasicHeaderObj = BasicHeader(LOCALTIME)
132 firstBasicHeaderObj = BasicHeader(LOCALTIME)
133 systemHeaderObj = SystemHeader()
133 systemHeaderObj = SystemHeader()
134 radarControllerHeaderObj = RadarControllerHeader()
134 radarControllerHeaderObj = RadarControllerHeader()
135 processingHeaderObj = ProcessingHeader()
135 processingHeaderObj = ProcessingHeader()
136
136
137 lastBasicHeaderObj = BasicHeader(LOCALTIME)
137 lastBasicHeaderObj = BasicHeader(LOCALTIME)
138
138
139 sts = firstBasicHeaderObj.read(fp)
139 sts = firstBasicHeaderObj.read(fp)
140
140
141 if not(sts):
141 if not(sts):
142 print "[Reading] Skipping the file %s because it has not a valid header" %(filename)
142 print "[Reading] Skipping the file %s because it has not a valid header" %(filename)
143 return None
143 return None
144
144
145 if not systemHeaderObj.read(fp):
145 if not systemHeaderObj.read(fp):
146 return None
146 return None
147
147
148 if not radarControllerHeaderObj.read(fp):
148 if not radarControllerHeaderObj.read(fp):
149 return None
149 return None
150
150
151 if not processingHeaderObj.read(fp):
151 if not processingHeaderObj.read(fp):
152 return None
152 return None
153
153
154 filesize = os.path.getsize(filename)
154 filesize = os.path.getsize(filename)
155
155
156 offset = processingHeaderObj.blockSize + 24 #header size
156 offset = processingHeaderObj.blockSize + 24 #header size
157
157
158 if filesize <= offset:
158 if filesize <= offset:
159 print "[Reading] %s: This file has not enough data" %filename
159 print "[Reading] %s: This file has not enough data" %filename
160 return None
160 return None
161
161
162 fp.seek(-offset, 2)
162 fp.seek(-offset, 2)
163
163
164 sts = lastBasicHeaderObj.read(fp)
164 sts = lastBasicHeaderObj.read(fp)
165
165
166 fp.close()
166 fp.close()
167
167
168 thisDatetime = lastBasicHeaderObj.datatime
168 thisDatetime = lastBasicHeaderObj.datatime
169 thisTime_last_block = thisDatetime.time()
169 thisTime_last_block = thisDatetime.time()
170
170
171 thisDatetime = firstBasicHeaderObj.datatime
171 thisDatetime = firstBasicHeaderObj.datatime
172 thisDate = thisDatetime.date()
172 thisDate = thisDatetime.date()
173 thisTime_first_block = thisDatetime.time()
173 thisTime_first_block = thisDatetime.time()
174
174
175 #General case
175 #General case
176 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
176 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
177 #-----------o----------------------------o-----------
177 #-----------o----------------------------o-----------
178 # startTime endTime
178 # startTime endTime
179
179
180 if endTime >= startTime:
180 if endTime >= startTime:
181 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
181 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
182 return None
182 return None
183
183
184 return thisDatetime
184 return thisDatetime
185
185
186 #If endTime < startTime then endTime belongs to the next day
186 #If endTime < startTime then endTime belongs to the next day
187
187
188
188
189 #<<<<<<<<<<<o o>>>>>>>>>>>
189 #<<<<<<<<<<<o o>>>>>>>>>>>
190 #-----------o----------------------------o-----------
190 #-----------o----------------------------o-----------
191 # endTime startTime
191 # endTime startTime
192
192
193 if (thisDate == startDate) and (thisTime_last_block < startTime):
193 if (thisDate == startDate) and (thisTime_last_block < startTime):
194 return None
194 return None
195
195
196 if (thisDate == endDate) and (thisTime_first_block > endTime):
196 if (thisDate == endDate) and (thisTime_first_block > endTime):
197 return None
197 return None
198
198
199 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
199 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
200 return None
200 return None
201
201
202 return thisDatetime
202 return thisDatetime
203
203
204 def isFolderInDateRange(folder, startDate=None, endDate=None):
204 def isFolderInDateRange(folder, startDate=None, endDate=None):
205 """
205 """
206 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
206 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
207
207
208 Inputs:
208 Inputs:
209 folder : nombre completo del directorio.
209 folder : nombre completo del directorio.
210 Su formato deberia ser "/path_root/?YYYYDDD"
210 Su formato deberia ser "/path_root/?YYYYDDD"
211
211
212 siendo:
212 siendo:
213 YYYY : Anio (ejemplo 2015)
213 YYYY : Anio (ejemplo 2015)
214 DDD : Dia del anio (ejemplo 305)
214 DDD : Dia del anio (ejemplo 305)
215
215
216 startDate : fecha inicial del rango seleccionado en formato datetime.date
216 startDate : fecha inicial del rango seleccionado en formato datetime.date
217
217
218 endDate : fecha final del rango seleccionado en formato datetime.date
218 endDate : fecha final del rango seleccionado en formato datetime.date
219
219
220 Return:
220 Return:
221 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
221 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
222 fecha especificado, de lo contrario retorna False.
222 fecha especificado, de lo contrario retorna False.
223 Excepciones:
223 Excepciones:
224 Si el directorio no tiene el formato adecuado
224 Si el directorio no tiene el formato adecuado
225 """
225 """
226
226
227 basename = os.path.basename(folder)
227 basename = os.path.basename(folder)
228
228
229 if not isRadarFolder(basename):
229 if not isRadarFolder(basename):
230 print "The folder %s has not the rigth format" %folder
230 print "The folder %s has not the rigth format" %folder
231 return 0
231 return 0
232
232
233 if startDate and endDate:
233 if startDate and endDate:
234 thisDate = getDateFromRadarFolder(basename)
234 thisDate = getDateFromRadarFolder(basename)
235
235
236 if thisDate < startDate:
236 if thisDate < startDate:
237 return 0
237 return 0
238
238
239 if thisDate > endDate:
239 if thisDate > endDate:
240 return 0
240 return 0
241
241
242 return 1
242 return 1
243
243
244 def isFileInDateRange(filename, startDate=None, endDate=None):
244 def isFileInDateRange(filename, startDate=None, endDate=None):
245 """
245 """
246 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
246 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
247
247
248 Inputs:
248 Inputs:
249 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
249 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
250
250
251 Su formato deberia ser "?YYYYDDDsss"
251 Su formato deberia ser "?YYYYDDDsss"
252
252
253 siendo:
253 siendo:
254 YYYY : Anio (ejemplo 2015)
254 YYYY : Anio (ejemplo 2015)
255 DDD : Dia del anio (ejemplo 305)
255 DDD : Dia del anio (ejemplo 305)
256 sss : set
256 sss : set
257
257
258 startDate : fecha inicial del rango seleccionado en formato datetime.date
258 startDate : fecha inicial del rango seleccionado en formato datetime.date
259
259
260 endDate : fecha final del rango seleccionado en formato datetime.date
260 endDate : fecha final del rango seleccionado en formato datetime.date
261
261
262 Return:
262 Return:
263 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
263 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
264 fecha especificado, de lo contrario retorna False.
264 fecha especificado, de lo contrario retorna False.
265 Excepciones:
265 Excepciones:
266 Si el archivo no tiene el formato adecuado
266 Si el archivo no tiene el formato adecuado
267 """
267 """
268
268
269 basename = os.path.basename(filename)
269 basename = os.path.basename(filename)
270
270
271 if not isRadarFile(basename):
271 if not isRadarFile(basename):
272 print "The filename %s has not the rigth format" %filename
272 print "The filename %s has not the rigth format" %filename
273 return 0
273 return 0
274
274
275 if startDate and endDate:
275 if startDate and endDate:
276 thisDate = getDateFromRadarFile(basename)
276 thisDate = getDateFromRadarFile(basename)
277
277
278 if thisDate < startDate:
278 if thisDate < startDate:
279 return 0
279 return 0
280
280
281 if thisDate > endDate:
281 if thisDate > endDate:
282 return 0
282 return 0
283
283
284 return 1
284 return 1
285
285
286 def getFileFromSet(path, ext, set):
286 def getFileFromSet(path, ext, set):
287 validFilelist = []
287 validFilelist = []
288 fileList = os.listdir(path)
288 fileList = os.listdir(path)
289
289
290 # 0 1234 567 89A BCDE
290 # 0 1234 567 89A BCDE
291 # H YYYY DDD SSS .ext
291 # H YYYY DDD SSS .ext
292
292
293 for thisFile in fileList:
293 for thisFile in fileList:
294 try:
294 try:
295 year = int(thisFile[1:5])
295 year = int(thisFile[1:5])
296 doy = int(thisFile[5:8])
296 doy = int(thisFile[5:8])
297 except:
297 except:
298 continue
298 continue
299
299
300 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
300 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
301 continue
301 continue
302
302
303 validFilelist.append(thisFile)
303 validFilelist.append(thisFile)
304
304
305 myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set))
305 myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set))
306
306
307 if len(myfile)!= 0:
307 if len(myfile)!= 0:
308 return myfile[0]
308 return myfile[0]
309 else:
309 else:
310 filename = '*%4.4d%3.3d%3.3d%s'%(year,doy,set,ext.lower())
310 filename = '*%4.4d%3.3d%3.3d%s'%(year,doy,set,ext.lower())
311 print 'the filename %s does not exist'%filename
311 print 'the filename %s does not exist'%filename
312 print '...going to the last file: '
312 print '...going to the last file: '
313
313
314 if validFilelist:
314 if validFilelist:
315 validFilelist = sorted( validFilelist, key=str.lower )
315 validFilelist = sorted( validFilelist, key=str.lower )
316 return validFilelist[-1]
316 return validFilelist[-1]
317
317
318 return None
318 return None
319
319
320 def getlastFileFromPath(path, ext):
320 def getlastFileFromPath(path, ext):
321 """
321 """
322 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
322 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
323 al final de la depuracion devuelve el ultimo file de la lista que quedo.
323 al final de la depuracion devuelve el ultimo file de la lista que quedo.
324
324
325 Input:
325 Input:
326 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
326 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
327 ext : extension de los files contenidos en una carpeta
327 ext : extension de los files contenidos en una carpeta
328
328
329 Return:
329 Return:
330 El ultimo file de una determinada carpeta, no se considera el path.
330 El ultimo file de una determinada carpeta, no se considera el path.
331 """
331 """
332 validFilelist = []
332 validFilelist = []
333 fileList = os.listdir(path)
333 fileList = os.listdir(path)
334
334
335 # 0 1234 567 89A BCDE
335 # 0 1234 567 89A BCDE
336 # H YYYY DDD SSS .ext
336 # H YYYY DDD SSS .ext
337
337
338 for thisFile in fileList:
338 for thisFile in fileList:
339
339
340 year = thisFile[1:5]
340 year = thisFile[1:5]
341 if not isNumber(year):
341 if not isNumber(year):
342 continue
342 continue
343
343
344 doy = thisFile[5:8]
344 doy = thisFile[5:8]
345 if not isNumber(doy):
345 if not isNumber(doy):
346 continue
346 continue
347
347
348 year = int(year)
348 year = int(year)
349 doy = int(doy)
349 doy = int(doy)
350
350
351 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
351 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
352 continue
352 continue
353
353
354 validFilelist.append(thisFile)
354 validFilelist.append(thisFile)
355
355
356 if validFilelist:
356 if validFilelist:
357 validFilelist = sorted( validFilelist, key=str.lower )
357 validFilelist = sorted( validFilelist, key=str.lower )
358 return validFilelist[-1]
358 return validFilelist[-1]
359
359
360 return None
360 return None
361
361
362 def checkForRealPath(path, foldercounter, year, doy, set, ext):
362 def checkForRealPath(path, foldercounter, year, doy, set, ext):
363 """
363 """
364 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
364 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
365 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
365 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
366 el path exacto de un determinado file.
366 el path exacto de un determinado file.
367
367
368 Example :
368 Example :
369 nombre correcto del file es .../.../D2009307/P2009307367.ext
369 nombre correcto del file es .../.../D2009307/P2009307367.ext
370
370
371 Entonces la funcion prueba con las siguientes combinaciones
371 Entonces la funcion prueba con las siguientes combinaciones
372 .../.../y2009307367.ext
372 .../.../y2009307367.ext
373 .../.../Y2009307367.ext
373 .../.../Y2009307367.ext
374 .../.../x2009307/y2009307367.ext
374 .../.../x2009307/y2009307367.ext
375 .../.../x2009307/Y2009307367.ext
375 .../.../x2009307/Y2009307367.ext
376 .../.../X2009307/y2009307367.ext
376 .../.../X2009307/y2009307367.ext
377 .../.../X2009307/Y2009307367.ext
377 .../.../X2009307/Y2009307367.ext
378 siendo para este caso, la ultima combinacion de letras, identica al file buscado
378 siendo para este caso, la ultima combinacion de letras, identica al file buscado
379
379
380 Return:
380 Return:
381 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
381 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
382 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
382 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
383 para el filename
383 para el filename
384 """
384 """
385 fullfilename = None
385 fullfilename = None
386 find_flag = False
386 find_flag = False
387 filename = None
387 filename = None
388
388
389 prefixDirList = [None,'d','D']
389 prefixDirList = [None,'d','D']
390 if ext.lower() == ".r": #voltage
390 if ext.lower() == ".r": #voltage
391 prefixFileList = ['d','D']
391 prefixFileList = ['d','D']
392 elif ext.lower() == ".pdata": #spectra
392 elif ext.lower() == ".pdata": #spectra
393 prefixFileList = ['p','P']
393 prefixFileList = ['p','P']
394 else:
394 else:
395 return None, filename
395 return None, filename
396
396
397 #barrido por las combinaciones posibles
397 #barrido por las combinaciones posibles
398 for prefixDir in prefixDirList:
398 for prefixDir in prefixDirList:
399 thispath = path
399 thispath = path
400 if prefixDir != None:
400 if prefixDir != None:
401 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
401 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
402 if foldercounter == 0:
402 if foldercounter == 0:
403 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
403 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
404 else:
404 else:
405 thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter))
405 thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter))
406 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
406 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
407 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
407 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
408 fullfilename = os.path.join( thispath, filename ) #formo el path completo
408 fullfilename = os.path.join( thispath, filename ) #formo el path completo
409
409
410 if os.path.exists( fullfilename ): #verifico que exista
410 if os.path.exists( fullfilename ): #verifico que exista
411 find_flag = True
411 find_flag = True
412 break
412 break
413 if find_flag:
413 if find_flag:
414 break
414 break
415
415
416 if not(find_flag):
416 if not(find_flag):
417 return None, filename
417 return None, filename
418
418
419 return fullfilename, filename
419 return fullfilename, filename
420
420
421 def isRadarFolder(folder):
421 def isRadarFolder(folder):
422 try:
422 try:
423 year = int(folder[1:5])
423 year = int(folder[1:5])
424 doy = int(folder[5:8])
424 doy = int(folder[5:8])
425 except:
425 except:
426 return 0
426 return 0
427
427
428 return 1
428 return 1
429
429
430 def isRadarFile(file):
430 def isRadarFile(file):
431 try:
431 try:
432 year = int(file[1:5])
432 year = int(file[1:5])
433 doy = int(file[5:8])
433 doy = int(file[5:8])
434 set = int(file[8:11])
434 set = int(file[8:11])
435 except:
435 except:
436 return 0
436 return 0
437
437
438 return 1
438 return 1
439
439
440 def getDateFromRadarFile(file):
440 def getDateFromRadarFile(file):
441 try:
441 try:
442 year = int(file[1:5])
442 year = int(file[1:5])
443 doy = int(file[5:8])
443 doy = int(file[5:8])
444 set = int(file[8:11])
444 set = int(file[8:11])
445 except:
445 except:
446 return None
446 return None
447
447
448 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1)
448 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1)
449 return thisDate
449 return thisDate
450
450
451 def getDateFromRadarFolder(folder):
451 def getDateFromRadarFolder(folder):
452 try:
452 try:
453 year = int(folder[1:5])
453 year = int(folder[1:5])
454 doy = int(folder[5:8])
454 doy = int(folder[5:8])
455 except:
455 except:
456 return None
456 return None
457
457
458 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1)
458 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1)
459 return thisDate
459 return thisDate
460
460
461 class JRODataIO:
461 class JRODataIO:
462
462
463 c = 3E8
463 c = 3E8
464
464
465 isConfig = False
465 isConfig = False
466
466
467 basicHeaderObj = None
467 basicHeaderObj = None
468
468
469 systemHeaderObj = None
469 systemHeaderObj = None
470
470
471 radarControllerHeaderObj = None
471 radarControllerHeaderObj = None
472
472
473 processingHeaderObj = None
473 processingHeaderObj = None
474
474
475 dtype = None
475 dtype = None
476
476
477 pathList = []
477 pathList = []
478
478
479 filenameList = []
479 filenameList = []
480
480
481 filename = None
481 filename = None
482
482
483 ext = None
483 ext = None
484
484
485 flagIsNewFile = 1
485 flagIsNewFile = 1
486
486
487 flagDiscontinuousBlock = 0
487 flagDiscontinuousBlock = 0
488
488
489 flagIsNewBlock = 0
489 flagIsNewBlock = 0
490
490
491 fp = None
491 fp = None
492
492
493 firstHeaderSize = 0
493 firstHeaderSize = 0
494
494
495 basicHeaderSize = 24
495 basicHeaderSize = 24
496
496
497 versionFile = 1103
497 versionFile = 1103
498
498
499 fileSize = None
499 fileSize = None
500
500
501 # ippSeconds = None
501 # ippSeconds = None
502
502
503 fileSizeByHeader = None
503 fileSizeByHeader = None
504
504
505 fileIndex = None
505 fileIndex = None
506
506
507 profileIndex = None
507 profileIndex = None
508
508
509 blockIndex = None
509 blockIndex = None
510
510
511 nTotalBlocks = None
511 nTotalBlocks = None
512
512
513 maxTimeStep = 30
513 maxTimeStep = 30
514
514
515 lastUTTime = None
515 lastUTTime = None
516
516
517 datablock = None
517 datablock = None
518
518
519 dataOut = None
519 dataOut = None
520
520
521 blocksize = None
521 blocksize = None
522
522
523 getByBlock = False
523 getByBlock = False
524
524
525 def __init__(self):
525 def __init__(self):
526
526
527 raise NotImplementedError
527 raise NotImplementedError
528
528
529 def run(self):
529 def run(self):
530
530
531 raise NotImplementedError
531 raise NotImplementedError
532
532
533 def getDtypeWidth(self):
533 def getDtypeWidth(self):
534
534
535 dtype_index = get_dtype_index(self.dtype)
535 dtype_index = get_dtype_index(self.dtype)
536 dtype_width = get_dtype_width(dtype_index)
536 dtype_width = get_dtype_width(dtype_index)
537
537
538 return dtype_width
538 return dtype_width
539
539
540 def getAllowedArgs(self):
540 def getAllowedArgs(self):
541 return inspect.getargspec(self.run).args
541 return inspect.getargspec(self.run).args
542
542
543 class JRODataReader(JRODataIO):
543 class JRODataReader(JRODataIO):
544
544
545 online = 0
545 online = 0
546
546
547 realtime = 0
547 realtime = 0
548
548
549 nReadBlocks = 0
549 nReadBlocks = 0
550
550
551 delay = 10 #number of seconds waiting a new file
551 delay = 10 #number of seconds waiting a new file
552
552
553 nTries = 3 #quantity tries
553 nTries = 3 #quantity tries
554
554
555 nFiles = 3 #number of files for searching
555 nFiles = 3 #number of files for searching
556
556
557 path = None
557 path = None
558
558
559 foldercounter = 0
559 foldercounter = 0
560
560
561 flagNoMoreFiles = 0
561 flagNoMoreFiles = 0
562
562
563 datetimeList = []
563 datetimeList = []
564
564
565 __isFirstTimeOnline = 1
565 __isFirstTimeOnline = 1
566
566
567 __printInfo = True
567 __printInfo = True
568
568
569 profileIndex = None
569 profileIndex = None
570
570
571 nTxs = 1
571 nTxs = 1
572
572
573 txIndex = None
573 txIndex = None
574
574
575 #Added--------------------
575 #Added--------------------
576
576
577 selBlocksize = None
577 selBlocksize = None
578
578
579 selBlocktime = None
579 selBlocktime = None
580
580
581 def __init__(self):
581 def __init__(self):
582
582
583 """
583 """
584 This class is used to find data files
584 This class is used to find data files
585
585
586 Example:
586 Example:
587 reader = JRODataReader()
587 reader = JRODataReader()
588 fileList = reader.findDataFiles()
588 fileList = reader.findDataFiles()
589
589
590 """
590 """
591 pass
591 pass
592
592
593
593
594 def createObjByDefault(self):
594 def createObjByDefault(self):
595 """
595 """
596
596
597 """
597 """
598 raise NotImplementedError
598 raise NotImplementedError
599
599
600 def getBlockDimension(self):
600 def getBlockDimension(self):
601
601
602 raise NotImplementedError
602 raise NotImplementedError
603
603
604 def searchFilesOffLine(self,
604 def searchFilesOffLine(self,
605 path,
605 path,
606 startDate=None,
606 startDate=None,
607 endDate=None,
607 endDate=None,
608 startTime=datetime.time(0,0,0),
608 startTime=datetime.time(0,0,0),
609 endTime=datetime.time(23,59,59),
609 endTime=datetime.time(23,59,59),
610 set=None,
610 set=None,
611 expLabel='',
611 expLabel='',
612 ext='.r',
612 ext='.r',
613 cursor=None,
613 cursor=None,
614 skip=None,
614 skip=None,
615 walk=True):
615 walk=True):
616
616
617 self.filenameList = []
617 self.filenameList = []
618 self.datetimeList = []
618 self.datetimeList = []
619
619
620 pathList = []
620 pathList = []
621
621
622 dateList, pathList = self.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True)
622 dateList, pathList = self.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True)
623
623
624 if dateList == []:
624 if dateList == []:
625 return [], []
625 return [], []
626
626
627 if len(dateList) > 1:
627 if len(dateList) > 1:
628 print "[Reading] Data found for date range [%s - %s]: total days = %d" %(startDate, endDate, len(dateList))
628 print "[Reading] Data found for date range [%s - %s]: total days = %d" %(startDate, endDate, len(dateList))
629 else:
629 else:
630 print "[Reading] Data found for date range [%s - %s]: date = %s" %(startDate, endDate, dateList[0])
630 print "[Reading] Data found for date range [%s - %s]: date = %s" %(startDate, endDate, dateList[0])
631
631
632 filenameList = []
632 filenameList = []
633 datetimeList = []
633 datetimeList = []
634
634
635 for thisPath in pathList:
635 for thisPath in pathList:
636
636
637 fileList = glob.glob1(thisPath, "*%s" %ext)
637 fileList = glob.glob1(thisPath, "*%s" %ext)
638 fileList.sort()
638 fileList.sort()
639
639
640 skippedFileList = []
640 skippedFileList = []
641
641
642 if cursor is not None and skip is not None:
642 if cursor is not None and skip is not None:
643
643
644 if skip == 0:
644 if skip == 0:
645 skippedFileList = []
645 skippedFileList = []
646 else:
646 else:
647 skippedFileList = fileList[cursor*skip: cursor*skip + skip]
647 skippedFileList = fileList[cursor*skip: cursor*skip + skip]
648
648
649 else:
649 else:
650 skippedFileList = fileList
650 skippedFileList = fileList
651
651
652 for file in skippedFileList:
652 for file in skippedFileList:
653
653
654 filename = os.path.join(thisPath,file)
654 filename = os.path.join(thisPath,file)
655
655
656 if not isFileInDateRange(filename, startDate, endDate):
656 if not isFileInDateRange(filename, startDate, endDate):
657 continue
657 continue
658
658
659 thisDatetime = isFileInTimeRange(filename, startDate, endDate, startTime, endTime)
659 thisDatetime = isFileInTimeRange(filename, startDate, endDate, startTime, endTime)
660
660
661 if not(thisDatetime):
661 if not(thisDatetime):
662 continue
662 continue
663
663
664 filenameList.append(filename)
664 filenameList.append(filename)
665 datetimeList.append(thisDatetime)
665 datetimeList.append(thisDatetime)
666
666
667 if not(filenameList):
667 if not(filenameList):
668 print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" %(startTime, endTime, ext, path)
668 print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" %(startTime, endTime, ext, path)
669 return [], []
669 return [], []
670
670
671 print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime)
671 print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime)
672 print
672 print
673
673
674 # for i in range(len(filenameList)):
674 # for i in range(len(filenameList)):
675 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
675 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
676
676
677 self.filenameList = filenameList
677 self.filenameList = filenameList
678 self.datetimeList = datetimeList
678 self.datetimeList = datetimeList
679
679
680 return pathList, filenameList
680 return pathList, filenameList
681
681
682 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True, set=None):
682 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True, set=None):
683
683
684 """
684 """
685 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
685 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
686 devuelve el archivo encontrado ademas de otros datos.
686 devuelve el archivo encontrado ademas de otros datos.
687
687
688 Input:
688 Input:
689 path : carpeta donde estan contenidos los files que contiene data
689 path : carpeta donde estan contenidos los files que contiene data
690
690
691 expLabel : Nombre del subexperimento (subfolder)
691 expLabel : Nombre del subexperimento (subfolder)
692
692
693 ext : extension de los files
693 ext : extension de los files
694
694
695 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
695 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
696
696
697 Return:
697 Return:
698 directory : eL directorio donde esta el file encontrado
698 directory : eL directorio donde esta el file encontrado
699 filename : el ultimo file de una determinada carpeta
699 filename : el ultimo file de una determinada carpeta
700 year : el anho
700 year : el anho
701 doy : el numero de dia del anho
701 doy : el numero de dia del anho
702 set : el set del archivo
702 set : el set del archivo
703
703
704
704
705 """
705 """
706 if not os.path.isdir(path):
706 if not os.path.isdir(path):
707 return None, None, None, None, None, None
707 return None, None, None, None, None, None
708
708
709 dirList = []
709 dirList = []
710
710
711 if not walk:
711 if not walk:
712 fullpath = path
712 fullpath = path
713 foldercounter = 0
713 foldercounter = 0
714 else:
714 else:
715 #Filtra solo los directorios
715 #Filtra solo los directorios
716 for thisPath in os.listdir(path):
716 for thisPath in os.listdir(path):
717 if not os.path.isdir(os.path.join(path,thisPath)):
717 if not os.path.isdir(os.path.join(path,thisPath)):
718 continue
718 continue
719 if not isRadarFolder(thisPath):
719 if not isRadarFolder(thisPath):
720 continue
720 continue
721
721
722 dirList.append(thisPath)
722 dirList.append(thisPath)
723
723
724 if not(dirList):
724 if not(dirList):
725 return None, None, None, None, None, None
725 return None, None, None, None, None, None
726
726
727 dirList = sorted( dirList, key=str.lower )
727 dirList = sorted( dirList, key=str.lower )
728
728
729 doypath = dirList[-1]
729 doypath = dirList[-1]
730 foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0
730 foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0
731 fullpath = os.path.join(path, doypath, expLabel)
731 fullpath = os.path.join(path, doypath, expLabel)
732
732
733
733
734 print "[Reading] %s folder was found: " %(fullpath )
734 print "[Reading] %s folder was found: " %(fullpath )
735
735
736 if set == None:
736 if set == None:
737 filename = getlastFileFromPath(fullpath, ext)
737 filename = getlastFileFromPath(fullpath, ext)
738 else:
738 else:
739 filename = getFileFromSet(fullpath, ext, set)
739 filename = getFileFromSet(fullpath, ext, set)
740
740
741 if not(filename):
741 if not(filename):
742 return None, None, None, None, None, None
742 return None, None, None, None, None, None
743
743
744 print "[Reading] %s file was found" %(filename)
744 print "[Reading] %s file was found" %(filename)
745
745
746 if not(self.__verifyFile(os.path.join(fullpath, filename))):
746 if not(self.__verifyFile(os.path.join(fullpath, filename))):
747 return None, None, None, None, None, None
747 return None, None, None, None, None, None
748
748
749 year = int( filename[1:5] )
749 year = int( filename[1:5] )
750 doy = int( filename[5:8] )
750 doy = int( filename[5:8] )
751 set = int( filename[8:11] )
751 set = int( filename[8:11] )
752
752
753 return fullpath, foldercounter, filename, year, doy, set
753 return fullpath, foldercounter, filename, year, doy, set
754
754
755 def __setNextFileOffline(self):
755 def __setNextFileOffline(self):
756
756
757 idFile = self.fileIndex
757 idFile = self.fileIndex
758
758
759 while (True):
759 while (True):
760 idFile += 1
760 idFile += 1
761 if not(idFile < len(self.filenameList)):
761 if not(idFile < len(self.filenameList)):
762 self.flagNoMoreFiles = 1
762 self.flagNoMoreFiles = 1
763 # print "[Reading] No more Files"
763 # print "[Reading] No more Files"
764 return 0
764 return 0
765
765
766 filename = self.filenameList[idFile]
766 filename = self.filenameList[idFile]
767
767
768 if not(self.__verifyFile(filename)):
768 if not(self.__verifyFile(filename)):
769 continue
769 continue
770
770
771 fileSize = os.path.getsize(filename)
771 fileSize = os.path.getsize(filename)
772 fp = open(filename,'rb')
772 fp = open(filename,'rb')
773 break
773 break
774
774
775 self.flagIsNewFile = 1
775 self.flagIsNewFile = 1
776 self.fileIndex = idFile
776 self.fileIndex = idFile
777 self.filename = filename
777 self.filename = filename
778 self.fileSize = fileSize
778 self.fileSize = fileSize
779 self.fp = fp
779 self.fp = fp
780
780
781 # print "[Reading] Setting the file: %s"%self.filename
781 # print "[Reading] Setting the file: %s"%self.filename
782
782
783 return 1
783 return 1
784
784
785 def __setNextFileOnline(self):
785 def __setNextFileOnline(self):
786 """
786 """
787 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
787 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
788 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
788 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
789 siguientes.
789 siguientes.
790
790
791 Affected:
791 Affected:
792 self.flagIsNewFile
792 self.flagIsNewFile
793 self.filename
793 self.filename
794 self.fileSize
794 self.fileSize
795 self.fp
795 self.fp
796 self.set
796 self.set
797 self.flagNoMoreFiles
797 self.flagNoMoreFiles
798
798
799 Return:
799 Return:
800 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
800 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
801 1 : si el file fue abierto con exito y esta listo a ser leido
801 1 : si el file fue abierto con exito y esta listo a ser leido
802
802
803 Excepciones:
803 Excepciones:
804 Si un determinado file no puede ser abierto
804 Si un determinado file no puede ser abierto
805 """
805 """
806 nFiles = 0
806 nFiles = 0
807 fileOk_flag = False
807 fileOk_flag = False
808 firstTime_flag = True
808 firstTime_flag = True
809
809
810 self.set += 1
810 self.set += 1
811
811
812 if self.set > 999:
812 if self.set > 999:
813 self.set = 0
813 self.set = 0
814 self.foldercounter += 1
814 self.foldercounter += 1
815
815
816 #busca el 1er file disponible
816 #busca el 1er file disponible
817 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
817 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
818 if fullfilename:
818 if fullfilename:
819 if self.__verifyFile(fullfilename, False):
819 if self.__verifyFile(fullfilename, False):
820 fileOk_flag = True
820 fileOk_flag = True
821
821
822 #si no encuentra un file entonces espera y vuelve a buscar
822 #si no encuentra un file entonces espera y vuelve a buscar
823 if not(fileOk_flag):
823 if not(fileOk_flag):
824 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
824 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
825
825
826 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
826 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
827 tries = self.nTries
827 tries = self.nTries
828 else:
828 else:
829 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
829 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
830
830
831 for nTries in range( tries ):
831 for nTries in range( tries ):
832 if firstTime_flag:
832 if firstTime_flag:
833 print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
833 print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
834 sleep( self.delay )
834 sleep( self.delay )
835 else:
835 else:
836 print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
836 print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
837
837
838 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
838 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
839 if fullfilename:
839 if fullfilename:
840 if self.__verifyFile(fullfilename):
840 if self.__verifyFile(fullfilename):
841 fileOk_flag = True
841 fileOk_flag = True
842 break
842 break
843
843
844 if fileOk_flag:
844 if fileOk_flag:
845 break
845 break
846
846
847 firstTime_flag = False
847 firstTime_flag = False
848
848
849 print "\t[Reading] Skipping the file \"%s\" due to this file doesn't exist" % filename
849 print "\t[Reading] Skipping the file \"%s\" due to this file doesn't exist" % filename
850 self.set += 1
850 self.set += 1
851
851
852 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
852 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
853 self.set = 0
853 self.set = 0
854 self.doy += 1
854 self.doy += 1
855 self.foldercounter = 0
855 self.foldercounter = 0
856
856
857 if fileOk_flag:
857 if fileOk_flag:
858 self.fileSize = os.path.getsize( fullfilename )
858 self.fileSize = os.path.getsize( fullfilename )
859 self.filename = fullfilename
859 self.filename = fullfilename
860 self.flagIsNewFile = 1
860 self.flagIsNewFile = 1
861 if self.fp != None: self.fp.close()
861 if self.fp != None: self.fp.close()
862 self.fp = open(fullfilename, 'rb')
862 self.fp = open(fullfilename, 'rb')
863 self.flagNoMoreFiles = 0
863 self.flagNoMoreFiles = 0
864 # print '[Reading] Setting the file: %s' % fullfilename
864 # print '[Reading] Setting the file: %s' % fullfilename
865 else:
865 else:
866 self.fileSize = 0
866 self.fileSize = 0
867 self.filename = None
867 self.filename = None
868 self.flagIsNewFile = 0
868 self.flagIsNewFile = 0
869 self.fp = None
869 self.fp = None
870 self.flagNoMoreFiles = 1
870 self.flagNoMoreFiles = 1
871 # print '[Reading] No more files to read'
871 # print '[Reading] No more files to read'
872
872
873 return fileOk_flag
873 return fileOk_flag
874
874
875 def setNextFile(self):
875 def setNextFile(self):
876 if self.fp != None:
876 if self.fp != None:
877 self.fp.close()
877 self.fp.close()
878
878
879 if self.online:
879 if self.online:
880 newFile = self.__setNextFileOnline()
880 newFile = self.__setNextFileOnline()
881 else:
881 else:
882 newFile = self.__setNextFileOffline()
882 newFile = self.__setNextFileOffline()
883
883
884 if not(newFile):
884 if not(newFile):
885 print '[Reading] No more files to read'
885 print '[Reading] No more files to read'
886 return 0
886 return 0
887
887
888 if self.verbose:
888 if self.verbose:
889 print '[Reading] Setting the file: %s' % self.filename
889 print '[Reading] Setting the file: %s' % self.filename
890
890
891 self.__readFirstHeader()
891 self.__readFirstHeader()
892 self.nReadBlocks = 0
892 self.nReadBlocks = 0
893 return 1
893 return 1
894
894
895 def __waitNewBlock(self):
895 def __waitNewBlock(self):
896 """
896 """
897 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
897 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
898
898
899 Si el modo de lectura es OffLine siempre retorn 0
899 Si el modo de lectura es OffLine siempre retorn 0
900 """
900 """
901 if not self.online:
901 if not self.online:
902 return 0
902 return 0
903
903
904 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
904 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
905 return 0
905 return 0
906
906
907 currentPointer = self.fp.tell()
907 currentPointer = self.fp.tell()
908
908
909 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
909 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
910
910
911 for nTries in range( self.nTries ):
911 for nTries in range( self.nTries ):
912
912
913 self.fp.close()
913 self.fp.close()
914 self.fp = open( self.filename, 'rb' )
914 self.fp = open( self.filename, 'rb' )
915 self.fp.seek( currentPointer )
915 self.fp.seek( currentPointer )
916
916
917 self.fileSize = os.path.getsize( self.filename )
917 self.fileSize = os.path.getsize( self.filename )
918 currentSize = self.fileSize - currentPointer
918 currentSize = self.fileSize - currentPointer
919
919
920 if ( currentSize >= neededSize ):
920 if ( currentSize >= neededSize ):
921 self.basicHeaderObj.read(self.fp)
921 self.basicHeaderObj.read(self.fp)
922 return 1
922 return 1
923
923
924 if self.fileSize == self.fileSizeByHeader:
924 if self.fileSize == self.fileSizeByHeader:
925 # self.flagEoF = True
925 # self.flagEoF = True
926 return 0
926 return 0
927
927
928 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
928 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
929 sleep( self.delay )
929 sleep( self.delay )
930
930
931
931
932 return 0
932 return 0
933
933
934 def waitDataBlock(self,pointer_location):
934 def waitDataBlock(self,pointer_location):
935
935
936 currentPointer = pointer_location
936 currentPointer = pointer_location
937
937
938 neededSize = self.processingHeaderObj.blockSize #+ self.basicHeaderSize
938 neededSize = self.processingHeaderObj.blockSize #+ self.basicHeaderSize
939
939
940 for nTries in range( self.nTries ):
940 for nTries in range( self.nTries ):
941 self.fp.close()
941 self.fp.close()
942 self.fp = open( self.filename, 'rb' )
942 self.fp = open( self.filename, 'rb' )
943 self.fp.seek( currentPointer )
943 self.fp.seek( currentPointer )
944
944
945 self.fileSize = os.path.getsize( self.filename )
945 self.fileSize = os.path.getsize( self.filename )
946 currentSize = self.fileSize - currentPointer
946 currentSize = self.fileSize - currentPointer
947
947
948 if ( currentSize >= neededSize ):
948 if ( currentSize >= neededSize ):
949 return 1
949 return 1
950
950
951 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
951 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
952 sleep( self.delay )
952 sleep( self.delay )
953
953
954 return 0
954 return 0
955
955
956 def __jumpToLastBlock(self):
956 def __jumpToLastBlock(self):
957
957
958 if not(self.__isFirstTimeOnline):
958 if not(self.__isFirstTimeOnline):
959 return
959 return
960
960
961 csize = self.fileSize - self.fp.tell()
961 csize = self.fileSize - self.fp.tell()
962 blocksize = self.processingHeaderObj.blockSize
962 blocksize = self.processingHeaderObj.blockSize
963
963
964 #salta el primer bloque de datos
964 #salta el primer bloque de datos
965 if csize > self.processingHeaderObj.blockSize:
965 if csize > self.processingHeaderObj.blockSize:
966 self.fp.seek(self.fp.tell() + blocksize)
966 self.fp.seek(self.fp.tell() + blocksize)
967 else:
967 else:
968 return
968 return
969
969
970 csize = self.fileSize - self.fp.tell()
970 csize = self.fileSize - self.fp.tell()
971 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
971 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
972 while True:
972 while True:
973
973
974 if self.fp.tell()<self.fileSize:
974 if self.fp.tell()<self.fileSize:
975 self.fp.seek(self.fp.tell() + neededsize)
975 self.fp.seek(self.fp.tell() + neededsize)
976 else:
976 else:
977 self.fp.seek(self.fp.tell() - neededsize)
977 self.fp.seek(self.fp.tell() - neededsize)
978 break
978 break
979
979
980 # csize = self.fileSize - self.fp.tell()
980 # csize = self.fileSize - self.fp.tell()
981 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
981 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
982 # factor = int(csize/neededsize)
982 # factor = int(csize/neededsize)
983 # if factor > 0:
983 # if factor > 0:
984 # self.fp.seek(self.fp.tell() + factor*neededsize)
984 # self.fp.seek(self.fp.tell() + factor*neededsize)
985
985
986 self.flagIsNewFile = 0
986 self.flagIsNewFile = 0
987 self.__isFirstTimeOnline = 0
987 self.__isFirstTimeOnline = 0
988
988
989 def __setNewBlock(self):
989 def __setNewBlock(self):
990 #if self.server is None:
990 #if self.server is None:
991 if self.fp == None:
991 if self.fp == None:
992 return 0
992 return 0
993
993
994 # if self.online:
994 # if self.online:
995 # self.__jumpToLastBlock()
995 # self.__jumpToLastBlock()
996
996
997 if self.flagIsNewFile:
997 if self.flagIsNewFile:
998 self.lastUTTime = self.basicHeaderObj.utc
998 self.lastUTTime = self.basicHeaderObj.utc
999 return 1
999 return 1
1000
1000
1001 if self.realtime:
1001 if self.realtime:
1002 self.flagDiscontinuousBlock = 1
1002 self.flagDiscontinuousBlock = 1
1003 if not(self.setNextFile()):
1003 if not(self.setNextFile()):
1004 return 0
1004 return 0
1005 else:
1005 else:
1006 return 1
1006 return 1
1007 #if self.server is None:
1007 #if self.server is None:
1008 currentSize = self.fileSize - self.fp.tell()
1008 currentSize = self.fileSize - self.fp.tell()
1009 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
1009 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
1010 if (currentSize >= neededSize):
1010 if (currentSize >= neededSize):
1011 self.basicHeaderObj.read(self.fp)
1011 self.basicHeaderObj.read(self.fp)
1012 self.lastUTTime = self.basicHeaderObj.utc
1012 self.lastUTTime = self.basicHeaderObj.utc
1013 return 1
1013 return 1
1014 # else:
1014 # else:
1015 # self.basicHeaderObj.read(self.zHeader)
1015 # self.basicHeaderObj.read(self.zHeader)
1016 # self.lastUTTime = self.basicHeaderObj.utc
1016 # self.lastUTTime = self.basicHeaderObj.utc
1017 # return 1
1017 # return 1
1018 if self.__waitNewBlock():
1018 if self.__waitNewBlock():
1019 self.lastUTTime = self.basicHeaderObj.utc
1019 self.lastUTTime = self.basicHeaderObj.utc
1020 return 1
1020 return 1
1021 #if self.server is None:
1021 #if self.server is None:
1022 if not(self.setNextFile()):
1022 if not(self.setNextFile()):
1023 return 0
1023 return 0
1024
1024
1025 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
1025 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
1026 self.lastUTTime = self.basicHeaderObj.utc
1026 self.lastUTTime = self.basicHeaderObj.utc
1027
1027
1028 self.flagDiscontinuousBlock = 0
1028 self.flagDiscontinuousBlock = 0
1029
1029
1030 if deltaTime > self.maxTimeStep:
1030 if deltaTime > self.maxTimeStep:
1031 self.flagDiscontinuousBlock = 1
1031 self.flagDiscontinuousBlock = 1
1032
1032
1033 return 1
1033 return 1
1034
1034
1035 def readNextBlock(self):
1035 def readNextBlock(self):
1036
1036
1037 #Skip block out of startTime and endTime
1037 #Skip block out of startTime and endTime
1038 while True:
1038 while True:
1039 if not(self.__setNewBlock()):
1039 if not(self.__setNewBlock()):
1040 return 0
1040 return 0
1041
1041
1042 if not(self.readBlock()):
1042 if not(self.readBlock()):
1043 return 0
1043 return 0
1044
1044
1045 self.getBasicHeader()
1045 self.getBasicHeader()
1046
1046
1047 if not isTimeInRange(self.dataOut.datatime.time(), self.startTime, self.endTime):
1047 if not isTimeInRange(self.dataOut.datatime.time(), self.startTime, self.endTime):
1048
1048
1049 print "[Reading] Block No. %d/%d -> %s [Skipping]" %(self.nReadBlocks,
1049 print "[Reading] Block No. %d/%d -> %s [Skipping]" %(self.nReadBlocks,
1050 self.processingHeaderObj.dataBlocksPerFile,
1050 self.processingHeaderObj.dataBlocksPerFile,
1051 self.dataOut.datatime.ctime())
1051 self.dataOut.datatime.ctime())
1052 continue
1052 continue
1053
1053
1054 break
1054 break
1055
1055
1056 if self.verbose:
1056 if self.verbose:
1057 print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1057 print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1058 self.processingHeaderObj.dataBlocksPerFile,
1058 self.processingHeaderObj.dataBlocksPerFile,
1059 self.dataOut.datatime.ctime())
1059 self.dataOut.datatime.ctime())
1060 return 1
1060 return 1
1061
1061
1062 def __readFirstHeader(self):
1062 def __readFirstHeader(self):
1063
1063
1064 self.basicHeaderObj.read(self.fp)
1064 self.basicHeaderObj.read(self.fp)
1065 self.systemHeaderObj.read(self.fp)
1065 self.systemHeaderObj.read(self.fp)
1066 self.radarControllerHeaderObj.read(self.fp)
1066 self.radarControllerHeaderObj.read(self.fp)
1067 self.processingHeaderObj.read(self.fp)
1067 self.processingHeaderObj.read(self.fp)
1068
1068
1069 self.firstHeaderSize = self.basicHeaderObj.size
1069 self.firstHeaderSize = self.basicHeaderObj.size
1070
1070
1071 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
1071 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
1072 if datatype == 0:
1072 if datatype == 0:
1073 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
1073 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
1074 elif datatype == 1:
1074 elif datatype == 1:
1075 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
1075 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
1076 elif datatype == 2:
1076 elif datatype == 2:
1077 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
1077 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
1078 elif datatype == 3:
1078 elif datatype == 3:
1079 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
1079 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
1080 elif datatype == 4:
1080 elif datatype == 4:
1081 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
1081 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
1082 elif datatype == 5:
1082 elif datatype == 5:
1083 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
1083 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
1084 else:
1084 else:
1085 raise ValueError, 'Data type was not defined'
1085 raise ValueError, 'Data type was not defined'
1086
1086
1087 self.dtype = datatype_str
1087 self.dtype = datatype_str
1088 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
1088 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
1089 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
1089 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
1090 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
1090 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
1091 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
1091 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
1092 self.getBlockDimension()
1092 self.getBlockDimension()
1093
1093
1094 def __verifyFile(self, filename, msgFlag=True):
1094 def __verifyFile(self, filename, msgFlag=True):
1095
1095
1096 msg = None
1096 msg = None
1097
1097
1098 try:
1098 try:
1099 fp = open(filename, 'rb')
1099 fp = open(filename, 'rb')
1100 except IOError:
1100 except IOError:
1101
1101
1102 if msgFlag:
1102 if msgFlag:
1103 print "[Reading] File %s can't be opened" % (filename)
1103 print "[Reading] File %s can't be opened" % (filename)
1104
1104
1105 return False
1105 return False
1106
1106
1107 currentPosition = fp.tell()
1107 currentPosition = fp.tell()
1108 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
1108 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
1109
1109
1110 if neededSize == 0:
1110 if neededSize == 0:
1111 basicHeaderObj = BasicHeader(LOCALTIME)
1111 basicHeaderObj = BasicHeader(LOCALTIME)
1112 systemHeaderObj = SystemHeader()
1112 systemHeaderObj = SystemHeader()
1113 radarControllerHeaderObj = RadarControllerHeader()
1113 radarControllerHeaderObj = RadarControllerHeader()
1114 processingHeaderObj = ProcessingHeader()
1114 processingHeaderObj = ProcessingHeader()
1115
1115
1116 if not( basicHeaderObj.read(fp) ):
1116 if not( basicHeaderObj.read(fp) ):
1117 fp.close()
1117 fp.close()
1118 return False
1118 return False
1119
1119
1120 if not( systemHeaderObj.read(fp) ):
1120 if not( systemHeaderObj.read(fp) ):
1121 fp.close()
1121 fp.close()
1122 return False
1122 return False
1123
1123
1124 if not( radarControllerHeaderObj.read(fp) ):
1124 if not( radarControllerHeaderObj.read(fp) ):
1125 fp.close()
1125 fp.close()
1126 return False
1126 return False
1127
1127
1128 if not( processingHeaderObj.read(fp) ):
1128 if not( processingHeaderObj.read(fp) ):
1129 fp.close()
1129 fp.close()
1130 return False
1130 return False
1131
1131
1132 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
1132 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
1133 else:
1133 else:
1134 msg = "[Reading] Skipping the file %s due to it hasn't enough data" %filename
1134 msg = "[Reading] Skipping the file %s due to it hasn't enough data" %filename
1135
1135
1136 fp.close()
1136 fp.close()
1137
1137
1138 fileSize = os.path.getsize(filename)
1138 fileSize = os.path.getsize(filename)
1139 currentSize = fileSize - currentPosition
1139 currentSize = fileSize - currentPosition
1140
1140
1141 if currentSize < neededSize:
1141 if currentSize < neededSize:
1142 if msgFlag and (msg != None):
1142 if msgFlag and (msg != None):
1143 print msg
1143 print msg
1144 return False
1144 return False
1145
1145
1146 return True
1146 return True
1147
1147
1148 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1148 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1149
1149
1150 path_empty = True
1150 path_empty = True
1151
1151
1152 dateList = []
1152 dateList = []
1153 pathList = []
1153 pathList = []
1154
1154
1155 multi_path = path.split(',')
1155 multi_path = path.split(',')
1156
1156
1157 if not walk:
1157 if not walk:
1158
1158
1159 for single_path in multi_path:
1159 for single_path in multi_path:
1160
1160
1161 if not os.path.isdir(single_path):
1161 if not os.path.isdir(single_path):
1162 continue
1162 continue
1163
1163
1164 fileList = glob.glob1(single_path, "*"+ext)
1164 fileList = glob.glob1(single_path, "*"+ext)
1165
1165
1166 if not fileList:
1166 if not fileList:
1167 continue
1167 continue
1168
1168
1169 path_empty = False
1169 path_empty = False
1170
1170
1171 fileList.sort()
1171 fileList.sort()
1172
1172
1173 for thisFile in fileList:
1173 for thisFile in fileList:
1174
1174
1175 if not os.path.isfile(os.path.join(single_path, thisFile)):
1175 if not os.path.isfile(os.path.join(single_path, thisFile)):
1176 continue
1176 continue
1177
1177
1178 if not isRadarFile(thisFile):
1178 if not isRadarFile(thisFile):
1179 continue
1179 continue
1180
1180
1181 if not isFileInDateRange(thisFile, startDate, endDate):
1181 if not isFileInDateRange(thisFile, startDate, endDate):
1182 continue
1182 continue
1183
1183
1184 thisDate = getDateFromRadarFile(thisFile)
1184 thisDate = getDateFromRadarFile(thisFile)
1185
1185
1186 if thisDate in dateList:
1186 if thisDate in dateList:
1187 continue
1187 continue
1188
1188
1189 dateList.append(thisDate)
1189 dateList.append(thisDate)
1190 pathList.append(single_path)
1190 pathList.append(single_path)
1191
1191
1192 else:
1192 else:
1193 for single_path in multi_path:
1193 for single_path in multi_path:
1194
1194
1195 if not os.path.isdir(single_path):
1195 if not os.path.isdir(single_path):
1196 continue
1196 continue
1197
1197
1198 dirList = []
1198 dirList = []
1199
1199
1200 for thisPath in os.listdir(single_path):
1200 for thisPath in os.listdir(single_path):
1201
1201
1202 if not os.path.isdir(os.path.join(single_path,thisPath)):
1202 if not os.path.isdir(os.path.join(single_path,thisPath)):
1203 continue
1203 continue
1204
1204
1205 if not isRadarFolder(thisPath):
1205 if not isRadarFolder(thisPath):
1206 continue
1206 continue
1207
1207
1208 if not isFolderInDateRange(thisPath, startDate, endDate):
1208 if not isFolderInDateRange(thisPath, startDate, endDate):
1209 continue
1209 continue
1210
1210
1211 dirList.append(thisPath)
1211 dirList.append(thisPath)
1212
1212
1213 if not dirList:
1213 if not dirList:
1214 continue
1214 continue
1215
1215
1216 dirList.sort()
1216 dirList.sort()
1217
1217
1218 for thisDir in dirList:
1218 for thisDir in dirList:
1219
1219
1220 datapath = os.path.join(single_path, thisDir, expLabel)
1220 datapath = os.path.join(single_path, thisDir, expLabel)
1221 fileList = glob.glob1(datapath, "*"+ext)
1221 fileList = glob.glob1(datapath, "*"+ext)
1222
1222
1223 if not fileList:
1223 if not fileList:
1224 continue
1224 continue
1225
1225
1226 path_empty = False
1226 path_empty = False
1227
1227
1228 thisDate = getDateFromRadarFolder(thisDir)
1228 thisDate = getDateFromRadarFolder(thisDir)
1229
1229
1230 pathList.append(datapath)
1230 pathList.append(datapath)
1231 dateList.append(thisDate)
1231 dateList.append(thisDate)
1232
1232
1233 dateList.sort()
1233 dateList.sort()
1234
1234
1235 if walk:
1235 if walk:
1236 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1236 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1237 else:
1237 else:
1238 pattern_path = multi_path[0]
1238 pattern_path = multi_path[0]
1239
1239
1240 if path_empty:
1240 if path_empty:
1241 print "[Reading] No *%s files in %s for %s to %s" %(ext, pattern_path, startDate, endDate)
1241 print "[Reading] No *%s files in %s for %s to %s" %(ext, pattern_path, startDate, endDate)
1242 else:
1242 else:
1243 if not dateList:
1243 if not dateList:
1244 print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" %(startDate, endDate, ext, path)
1244 print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" %(startDate, endDate, ext, path)
1245
1245
1246 if include_path:
1246 if include_path:
1247 return dateList, pathList
1247 return dateList, pathList
1248
1248
1249 return dateList
1249 return dateList
1250
1250
1251 def setup(self,
1251 def setup(self,
1252 path=None,
1252 path=None,
1253 startDate=None,
1253 startDate=None,
1254 endDate=None,
1254 endDate=None,
1255 startTime=datetime.time(0,0,0),
1255 startTime=datetime.time(0,0,0),
1256 endTime=datetime.time(23,59,59),
1256 endTime=datetime.time(23,59,59),
1257 set=None,
1257 set=None,
1258 expLabel = "",
1258 expLabel = "",
1259 ext = None,
1259 ext = None,
1260 online = False,
1260 online = False,
1261 delay = 60,
1261 delay = 60,
1262 walk = True,
1262 walk = True,
1263 getblock = False,
1263 getblock = False,
1264 nTxs = 1,
1264 nTxs = 1,
1265 realtime=False,
1265 realtime=False,
1266 blocksize=None,
1266 blocksize=None,
1267 blocktime=None,
1267 blocktime=None,
1268 skip=None,
1268 skip=None,
1269 cursor=None,
1269 cursor=None,
1270 warnings=True,
1270 warnings=True,
1271 verbose=True,
1271 verbose=True,
1272 server=None):
1272 server=None,
1273 format=None,
1274 oneDDict=None,
1275 twoDDict=None,
1276 ind2DList=None):
1273 if server is not None:
1277 if server is not None:
1274 if 'tcp://' in server:
1278 if 'tcp://' in server:
1275 address = server
1279 address = server
1276 else:
1280 else:
1277 address = 'ipc:///tmp/%s' % server
1281 address = 'ipc:///tmp/%s' % server
1278 self.server = address
1282 self.server = address
1279 self.context = zmq.Context()
1283 self.context = zmq.Context()
1280 self.receiver = self.context.socket(zmq.PULL)
1284 self.receiver = self.context.socket(zmq.PULL)
1281 self.receiver.connect(self.server)
1285 self.receiver.connect(self.server)
1282 time.sleep(0.5)
1286 time.sleep(0.5)
1283 print '[Starting] ReceiverData from {}'.format(self.server)
1287 print '[Starting] ReceiverData from {}'.format(self.server)
1284 else:
1288 else:
1285 self.server = None
1289 self.server = None
1286 if path == None:
1290 if path == None:
1287 raise ValueError, "[Reading] The path is not valid"
1291 raise ValueError, "[Reading] The path is not valid"
1288
1292
1289 if ext == None:
1293 if ext == None:
1290 ext = self.ext
1294 ext = self.ext
1291
1295
1292 if online:
1296 if online:
1293 print "[Reading] Searching files in online mode..."
1297 print "[Reading] Searching files in online mode..."
1294
1298
1295 for nTries in range( self.nTries ):
1299 for nTries in range( self.nTries ):
1296 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
1300 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
1297
1301
1298 if fullpath:
1302 if fullpath:
1299 break
1303 break
1300
1304
1301 print '[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
1305 print '[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
1302 sleep( self.delay )
1306 sleep( self.delay )
1303
1307
1304 if not(fullpath):
1308 if not(fullpath):
1305 print "[Reading] There 'isn't any valid file in %s" % path
1309 print "[Reading] There 'isn't any valid file in %s" % path
1306 return
1310 return
1307
1311
1308 self.year = year
1312 self.year = year
1309 self.doy = doy
1313 self.doy = doy
1310 self.set = set - 1
1314 self.set = set - 1
1311 self.path = path
1315 self.path = path
1312 self.foldercounter = foldercounter
1316 self.foldercounter = foldercounter
1313 last_set = None
1317 last_set = None
1314 else:
1318 else:
1315 print "[Reading] Searching files in offline mode ..."
1319 print "[Reading] Searching files in offline mode ..."
1316 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
1320 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
1317 startTime=startTime, endTime=endTime,
1321 startTime=startTime, endTime=endTime,
1318 set=set, expLabel=expLabel, ext=ext,
1322 set=set, expLabel=expLabel, ext=ext,
1319 walk=walk, cursor=cursor,
1323 walk=walk, cursor=cursor,
1320 skip=skip)
1324 skip=skip)
1321
1325
1322 if not(pathList):
1326 if not(pathList):
1323 self.fileIndex = -1
1327 self.fileIndex = -1
1324 self.pathList = []
1328 self.pathList = []
1325 self.filenameList = []
1329 self.filenameList = []
1326 return
1330 return
1327
1331
1328 self.fileIndex = -1
1332 self.fileIndex = -1
1329 self.pathList = pathList
1333 self.pathList = pathList
1330 self.filenameList = filenameList
1334 self.filenameList = filenameList
1331 file_name = os.path.basename(filenameList[-1])
1335 file_name = os.path.basename(filenameList[-1])
1332 basename, ext = os.path.splitext(file_name)
1336 basename, ext = os.path.splitext(file_name)
1333 last_set = int(basename[-3:])
1337 last_set = int(basename[-3:])
1334
1338
1335 self.online = online
1339 self.online = online
1336 self.realtime = realtime
1340 self.realtime = realtime
1337 self.delay = delay
1341 self.delay = delay
1338 ext = ext.lower()
1342 ext = ext.lower()
1339 self.ext = ext
1343 self.ext = ext
1340 self.getByBlock = getblock
1344 self.getByBlock = getblock
1341 self.nTxs = nTxs
1345 self.nTxs = nTxs
1342 self.startTime = startTime
1346 self.startTime = startTime
1343 self.endTime = endTime
1347 self.endTime = endTime
1344
1348
1345 #Added-----------------
1349 #Added-----------------
1346 self.selBlocksize = blocksize
1350 self.selBlocksize = blocksize
1347 self.selBlocktime = blocktime
1351 self.selBlocktime = blocktime
1348
1352
1349 # Verbose-----------
1353 # Verbose-----------
1350 self.verbose = verbose
1354 self.verbose = verbose
1351 self.warnings = warnings
1355 self.warnings = warnings
1352
1356
1353 if not(self.setNextFile()):
1357 if not(self.setNextFile()):
1354 if (startDate!=None) and (endDate!=None):
1358 if (startDate!=None) and (endDate!=None):
1355 print "[Reading] No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
1359 print "[Reading] No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
1356 elif startDate != None:
1360 elif startDate != None:
1357 print "[Reading] No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
1361 print "[Reading] No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
1358 else:
1362 else:
1359 print "[Reading] No files"
1363 print "[Reading] No files"
1360
1364
1361 self.fileIndex = -1
1365 self.fileIndex = -1
1362 self.pathList = []
1366 self.pathList = []
1363 self.filenameList = []
1367 self.filenameList = []
1364 return
1368 return
1365
1369
1366 # self.getBasicHeader()
1370 # self.getBasicHeader()
1367
1371
1368 if last_set != None:
1372 if last_set != None:
1369 self.dataOut.last_block = last_set * self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock
1373 self.dataOut.last_block = last_set * self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock
1370 return
1374 return
1371
1375
1372 def getBasicHeader(self):
1376 def getBasicHeader(self):
1373
1377
1374 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1378 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1375
1379
1376 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1380 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1377
1381
1378 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1382 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1379
1383
1380 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1384 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1381
1385
1382 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1386 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1383
1387
1384 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1388 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1385
1389
1386 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds/self.nTxs
1390 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds/self.nTxs
1387
1391
1388 # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs
1392 # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs
1389
1393
1390
1394
1391 def getFirstHeader(self):
1395 def getFirstHeader(self):
1392
1396
1393 raise NotImplementedError
1397 raise NotImplementedError
1394
1398
1395 def getData(self):
1399 def getData(self):
1396
1400
1397 raise NotImplementedError
1401 raise NotImplementedError
1398
1402
1399 def hasNotDataInBuffer(self):
1403 def hasNotDataInBuffer(self):
1400
1404
1401 raise NotImplementedError
1405 raise NotImplementedError
1402
1406
1403 def readBlock(self):
1407 def readBlock(self):
1404
1408
1405 raise NotImplementedError
1409 raise NotImplementedError
1406
1410
1407 def isEndProcess(self):
1411 def isEndProcess(self):
1408
1412
1409 return self.flagNoMoreFiles
1413 return self.flagNoMoreFiles
1410
1414
1411 def printReadBlocks(self):
1415 def printReadBlocks(self):
1412
1416
1413 print "[Reading] Number of read blocks per file %04d" %self.nReadBlocks
1417 print "[Reading] Number of read blocks per file %04d" %self.nReadBlocks
1414
1418
1415 def printTotalBlocks(self):
1419 def printTotalBlocks(self):
1416
1420
1417 print "[Reading] Number of read blocks %04d" %self.nTotalBlocks
1421 print "[Reading] Number of read blocks %04d" %self.nTotalBlocks
1418
1422
1419 def printNumberOfBlock(self):
1423 def printNumberOfBlock(self):
1420 'SPAM!'
1424 'SPAM!'
1421
1425
1422 # if self.flagIsNewBlock:
1426 # if self.flagIsNewBlock:
1423 # print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1427 # print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1424 # self.processingHeaderObj.dataBlocksPerFile,
1428 # self.processingHeaderObj.dataBlocksPerFile,
1425 # self.dataOut.datatime.ctime())
1429 # self.dataOut.datatime.ctime())
1426
1430
1427 def printInfo(self):
1431 def printInfo(self):
1428
1432
1429 if self.__printInfo == False:
1433 if self.__printInfo == False:
1430 return
1434 return
1431
1435
1432 self.basicHeaderObj.printInfo()
1436 self.basicHeaderObj.printInfo()
1433 self.systemHeaderObj.printInfo()
1437 self.systemHeaderObj.printInfo()
1434 self.radarControllerHeaderObj.printInfo()
1438 self.radarControllerHeaderObj.printInfo()
1435 self.processingHeaderObj.printInfo()
1439 self.processingHeaderObj.printInfo()
1436
1440
1437 self.__printInfo = False
1441 self.__printInfo = False
1438
1442
1439 def run(self,
1443 def run(self,
1440 path=None,
1444 path=None,
1441 startDate=None,
1445 startDate=None,
1442 endDate=None,
1446 endDate=None,
1443 startTime=datetime.time(0,0,0),
1447 startTime=datetime.time(0,0,0),
1444 endTime=datetime.time(23,59,59),
1448 endTime=datetime.time(23,59,59),
1445 set=None,
1449 set=None,
1446 expLabel = "",
1450 expLabel = "",
1447 ext = None,
1451 ext = None,
1448 online = False,
1452 online = False,
1449 delay = 60,
1453 delay = 60,
1450 walk = True,
1454 walk = True,
1451 getblock = False,
1455 getblock = False,
1452 nTxs = 1,
1456 nTxs = 1,
1453 realtime=False,
1457 realtime=False,
1454 blocksize=None,
1458 blocksize=None,
1455 blocktime=None,
1459 blocktime=None,
1456 skip=None,
1460 skip=None,
1457 cursor=None,
1461 cursor=None,
1458 warnings=True,
1462 warnings=True,
1459 server=None,
1463 server=None,
1460 verbose=True, **kwargs):
1464 verbose=True,
1465 format=None,
1466 oneDDict=None,
1467 twoDDict=None,
1468 ind2DList=None, **kwargs):
1461
1469
1462 if not(self.isConfig):
1470 if not(self.isConfig):
1463 self.setup(path=path,
1471 self.setup(path=path,
1464 startDate=startDate,
1472 startDate=startDate,
1465 endDate=endDate,
1473 endDate=endDate,
1466 startTime=startTime,
1474 startTime=startTime,
1467 endTime=endTime,
1475 endTime=endTime,
1468 set=set,
1476 set=set,
1469 expLabel=expLabel,
1477 expLabel=expLabel,
1470 ext=ext,
1478 ext=ext,
1471 online=online,
1479 online=online,
1472 delay=delay,
1480 delay=delay,
1473 walk=walk,
1481 walk=walk,
1474 getblock=getblock,
1482 getblock=getblock,
1475 nTxs=nTxs,
1483 nTxs=nTxs,
1476 realtime=realtime,
1484 realtime=realtime,
1477 blocksize=blocksize,
1485 blocksize=blocksize,
1478 blocktime=blocktime,
1486 blocktime=blocktime,
1479 skip=skip,
1487 skip=skip,
1480 cursor=cursor,
1488 cursor=cursor,
1481 warnings=warnings,
1489 warnings=warnings,
1482 server=server,
1490 server=server,
1483 verbose=verbose)
1491 verbose=verbose,
1492 format=format,
1493 oneDDict=oneDDict,
1494 twoDDict=twoDDict,
1495 ind2DList=ind2DList)
1484 self.isConfig = True
1496 self.isConfig = True
1485 if server is None:
1497 if server is None:
1486 self.getData()
1498 self.getData()
1487 else:
1499 else:
1488 self.getFromServer()
1500 self.getFromServer()
1489
1501
1490 class JRODataWriter(JRODataIO):
1502 class JRODataWriter(JRODataIO):
1491
1503
1492 """
1504 """
1493 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1505 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1494 de los datos siempre se realiza por bloques.
1506 de los datos siempre se realiza por bloques.
1495 """
1507 """
1496
1508
1497 blockIndex = 0
1509 blockIndex = 0
1498
1510
1499 path = None
1511 path = None
1500
1512
1501 setFile = None
1513 setFile = None
1502
1514
1503 profilesPerBlock = None
1515 profilesPerBlock = None
1504
1516
1505 blocksPerFile = None
1517 blocksPerFile = None
1506
1518
1507 nWriteBlocks = 0
1519 nWriteBlocks = 0
1508
1520
1509 fileDate = None
1521 fileDate = None
1510
1522
1511 def __init__(self, dataOut=None):
1523 def __init__(self, dataOut=None):
1512 raise NotImplementedError
1524 raise NotImplementedError
1513
1525
1514
1526
1515 def hasAllDataInBuffer(self):
1527 def hasAllDataInBuffer(self):
1516 raise NotImplementedError
1528 raise NotImplementedError
1517
1529
1518
1530
1519 def setBlockDimension(self):
1531 def setBlockDimension(self):
1520 raise NotImplementedError
1532 raise NotImplementedError
1521
1533
1522
1534
1523 def writeBlock(self):
1535 def writeBlock(self):
1524 raise NotImplementedError
1536 raise NotImplementedError
1525
1537
1526
1538
1527 def putData(self):
1539 def putData(self):
1528 raise NotImplementedError
1540 raise NotImplementedError
1529
1541
1530
1542
1531 def getProcessFlags(self):
1543 def getProcessFlags(self):
1532
1544
1533 processFlags = 0
1545 processFlags = 0
1534
1546
1535 dtype_index = get_dtype_index(self.dtype)
1547 dtype_index = get_dtype_index(self.dtype)
1536 procflag_dtype = get_procflag_dtype(dtype_index)
1548 procflag_dtype = get_procflag_dtype(dtype_index)
1537
1549
1538 processFlags += procflag_dtype
1550 processFlags += procflag_dtype
1539
1551
1540 if self.dataOut.flagDecodeData:
1552 if self.dataOut.flagDecodeData:
1541 processFlags += PROCFLAG.DECODE_DATA
1553 processFlags += PROCFLAG.DECODE_DATA
1542
1554
1543 if self.dataOut.flagDeflipData:
1555 if self.dataOut.flagDeflipData:
1544 processFlags += PROCFLAG.DEFLIP_DATA
1556 processFlags += PROCFLAG.DEFLIP_DATA
1545
1557
1546 if self.dataOut.code is not None:
1558 if self.dataOut.code is not None:
1547 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1559 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1548
1560
1549 if self.dataOut.nCohInt > 1:
1561 if self.dataOut.nCohInt > 1:
1550 processFlags += PROCFLAG.COHERENT_INTEGRATION
1562 processFlags += PROCFLAG.COHERENT_INTEGRATION
1551
1563
1552 if self.dataOut.type == "Spectra":
1564 if self.dataOut.type == "Spectra":
1553 if self.dataOut.nIncohInt > 1:
1565 if self.dataOut.nIncohInt > 1:
1554 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1566 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1555
1567
1556 if self.dataOut.data_dc is not None:
1568 if self.dataOut.data_dc is not None:
1557 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1569 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1558
1570
1559 if self.dataOut.flagShiftFFT:
1571 if self.dataOut.flagShiftFFT:
1560 processFlags += PROCFLAG.SHIFT_FFT_DATA
1572 processFlags += PROCFLAG.SHIFT_FFT_DATA
1561
1573
1562 return processFlags
1574 return processFlags
1563
1575
1564 def setBasicHeader(self):
1576 def setBasicHeader(self):
1565
1577
1566 self.basicHeaderObj.size = self.basicHeaderSize #bytes
1578 self.basicHeaderObj.size = self.basicHeaderSize #bytes
1567 self.basicHeaderObj.version = self.versionFile
1579 self.basicHeaderObj.version = self.versionFile
1568 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1580 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1569
1581
1570 utc = numpy.floor(self.dataOut.utctime)
1582 utc = numpy.floor(self.dataOut.utctime)
1571 milisecond = (self.dataOut.utctime - utc)* 1000.0
1583 milisecond = (self.dataOut.utctime - utc)* 1000.0
1572
1584
1573 self.basicHeaderObj.utc = utc
1585 self.basicHeaderObj.utc = utc
1574 self.basicHeaderObj.miliSecond = milisecond
1586 self.basicHeaderObj.miliSecond = milisecond
1575 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1587 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1576 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1588 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1577 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1589 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1578
1590
1579 def setFirstHeader(self):
1591 def setFirstHeader(self):
1580 """
1592 """
1581 Obtiene una copia del First Header
1593 Obtiene una copia del First Header
1582
1594
1583 Affected:
1595 Affected:
1584
1596
1585 self.basicHeaderObj
1597 self.basicHeaderObj
1586 self.systemHeaderObj
1598 self.systemHeaderObj
1587 self.radarControllerHeaderObj
1599 self.radarControllerHeaderObj
1588 self.processingHeaderObj self.
1600 self.processingHeaderObj self.
1589
1601
1590 Return:
1602 Return:
1591 None
1603 None
1592 """
1604 """
1593
1605
1594 raise NotImplementedError
1606 raise NotImplementedError
1595
1607
1596 def __writeFirstHeader(self):
1608 def __writeFirstHeader(self):
1597 """
1609 """
1598 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1610 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1599
1611
1600 Affected:
1612 Affected:
1601 __dataType
1613 __dataType
1602
1614
1603 Return:
1615 Return:
1604 None
1616 None
1605 """
1617 """
1606
1618
1607 # CALCULAR PARAMETROS
1619 # CALCULAR PARAMETROS
1608
1620
1609 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1621 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1610 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1622 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1611
1623
1612 self.basicHeaderObj.write(self.fp)
1624 self.basicHeaderObj.write(self.fp)
1613 self.systemHeaderObj.write(self.fp)
1625 self.systemHeaderObj.write(self.fp)
1614 self.radarControllerHeaderObj.write(self.fp)
1626 self.radarControllerHeaderObj.write(self.fp)
1615 self.processingHeaderObj.write(self.fp)
1627 self.processingHeaderObj.write(self.fp)
1616
1628
1617 def __setNewBlock(self):
1629 def __setNewBlock(self):
1618 """
1630 """
1619 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1631 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1620
1632
1621 Return:
1633 Return:
1622 0 : si no pudo escribir nada
1634 0 : si no pudo escribir nada
1623 1 : Si escribio el Basic el First Header
1635 1 : Si escribio el Basic el First Header
1624 """
1636 """
1625 if self.fp == None:
1637 if self.fp == None:
1626 self.setNextFile()
1638 self.setNextFile()
1627
1639
1628 if self.flagIsNewFile:
1640 if self.flagIsNewFile:
1629 return 1
1641 return 1
1630
1642
1631 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1643 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1632 self.basicHeaderObj.write(self.fp)
1644 self.basicHeaderObj.write(self.fp)
1633 return 1
1645 return 1
1634
1646
1635 if not( self.setNextFile() ):
1647 if not( self.setNextFile() ):
1636 return 0
1648 return 0
1637
1649
1638 return 1
1650 return 1
1639
1651
1640
1652
1641 def writeNextBlock(self):
1653 def writeNextBlock(self):
1642 """
1654 """
1643 Selecciona el bloque siguiente de datos y los escribe en un file
1655 Selecciona el bloque siguiente de datos y los escribe en un file
1644
1656
1645 Return:
1657 Return:
1646 0 : Si no hizo pudo escribir el bloque de datos
1658 0 : Si no hizo pudo escribir el bloque de datos
1647 1 : Si no pudo escribir el bloque de datos
1659 1 : Si no pudo escribir el bloque de datos
1648 """
1660 """
1649 if not( self.__setNewBlock() ):
1661 if not( self.__setNewBlock() ):
1650 return 0
1662 return 0
1651
1663
1652 self.writeBlock()
1664 self.writeBlock()
1653
1665
1654 print "[Writing] Block No. %d/%d" %(self.blockIndex,
1666 print "[Writing] Block No. %d/%d" %(self.blockIndex,
1655 self.processingHeaderObj.dataBlocksPerFile)
1667 self.processingHeaderObj.dataBlocksPerFile)
1656
1668
1657 return 1
1669 return 1
1658
1670
1659 def setNextFile(self):
1671 def setNextFile(self):
1660 """
1672 """
1661 Determina el siguiente file que sera escrito
1673 Determina el siguiente file que sera escrito
1662
1674
1663 Affected:
1675 Affected:
1664 self.filename
1676 self.filename
1665 self.subfolder
1677 self.subfolder
1666 self.fp
1678 self.fp
1667 self.setFile
1679 self.setFile
1668 self.flagIsNewFile
1680 self.flagIsNewFile
1669
1681
1670 Return:
1682 Return:
1671 0 : Si el archivo no puede ser escrito
1683 0 : Si el archivo no puede ser escrito
1672 1 : Si el archivo esta listo para ser escrito
1684 1 : Si el archivo esta listo para ser escrito
1673 """
1685 """
1674 ext = self.ext
1686 ext = self.ext
1675 path = self.path
1687 path = self.path
1676
1688
1677 if self.fp != None:
1689 if self.fp != None:
1678 self.fp.close()
1690 self.fp.close()
1679
1691
1680 timeTuple = time.localtime( self.dataOut.utctime)
1692 timeTuple = time.localtime( self.dataOut.utctime)
1681 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1693 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1682
1694
1683 fullpath = os.path.join( path, subfolder )
1695 fullpath = os.path.join( path, subfolder )
1684 setFile = self.setFile
1696 setFile = self.setFile
1685
1697
1686 if not( os.path.exists(fullpath) ):
1698 if not( os.path.exists(fullpath) ):
1687 os.mkdir(fullpath)
1699 os.mkdir(fullpath)
1688 setFile = -1 #inicializo mi contador de seteo
1700 setFile = -1 #inicializo mi contador de seteo
1689 else:
1701 else:
1690 filesList = os.listdir( fullpath )
1702 filesList = os.listdir( fullpath )
1691 if len( filesList ) > 0:
1703 if len( filesList ) > 0:
1692 filesList = sorted( filesList, key=str.lower )
1704 filesList = sorted( filesList, key=str.lower )
1693 filen = filesList[-1]
1705 filen = filesList[-1]
1694 # el filename debera tener el siguiente formato
1706 # el filename debera tener el siguiente formato
1695 # 0 1234 567 89A BCDE (hex)
1707 # 0 1234 567 89A BCDE (hex)
1696 # x YYYY DDD SSS .ext
1708 # x YYYY DDD SSS .ext
1697 if isNumber( filen[8:11] ):
1709 if isNumber( filen[8:11] ):
1698 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1710 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1699 else:
1711 else:
1700 setFile = -1
1712 setFile = -1
1701 else:
1713 else:
1702 setFile = -1 #inicializo mi contador de seteo
1714 setFile = -1 #inicializo mi contador de seteo
1703
1715
1704 setFile += 1
1716 setFile += 1
1705
1717
1706 #If this is a new day it resets some values
1718 #If this is a new day it resets some values
1707 if self.dataOut.datatime.date() > self.fileDate:
1719 if self.dataOut.datatime.date() > self.fileDate:
1708 setFile = 0
1720 setFile = 0
1709 self.nTotalBlocks = 0
1721 self.nTotalBlocks = 0
1710
1722
1711 filen = '%s%4.4d%3.3d%3.3d%s' % (self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext )
1723 filen = '%s%4.4d%3.3d%3.3d%s' % (self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext )
1712
1724
1713 filename = os.path.join( path, subfolder, filen )
1725 filename = os.path.join( path, subfolder, filen )
1714
1726
1715 fp = open( filename,'wb' )
1727 fp = open( filename,'wb' )
1716
1728
1717 self.blockIndex = 0
1729 self.blockIndex = 0
1718
1730
1719 #guardando atributos
1731 #guardando atributos
1720 self.filename = filename
1732 self.filename = filename
1721 self.subfolder = subfolder
1733 self.subfolder = subfolder
1722 self.fp = fp
1734 self.fp = fp
1723 self.setFile = setFile
1735 self.setFile = setFile
1724 self.flagIsNewFile = 1
1736 self.flagIsNewFile = 1
1725 self.fileDate = self.dataOut.datatime.date()
1737 self.fileDate = self.dataOut.datatime.date()
1726
1738
1727 self.setFirstHeader()
1739 self.setFirstHeader()
1728
1740
1729 print '[Writing] Opening file: %s'%self.filename
1741 print '[Writing] Opening file: %s'%self.filename
1730
1742
1731 self.__writeFirstHeader()
1743 self.__writeFirstHeader()
1732
1744
1733 return 1
1745 return 1
1734
1746
1735 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1747 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1736 """
1748 """
1737 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1749 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1738
1750
1739 Inputs:
1751 Inputs:
1740 path : directory where data will be saved
1752 path : directory where data will be saved
1741 profilesPerBlock : number of profiles per block
1753 profilesPerBlock : number of profiles per block
1742 set : initial file set
1754 set : initial file set
1743 datatype : An integer number that defines data type:
1755 datatype : An integer number that defines data type:
1744 0 : int8 (1 byte)
1756 0 : int8 (1 byte)
1745 1 : int16 (2 bytes)
1757 1 : int16 (2 bytes)
1746 2 : int32 (4 bytes)
1758 2 : int32 (4 bytes)
1747 3 : int64 (8 bytes)
1759 3 : int64 (8 bytes)
1748 4 : float32 (4 bytes)
1760 4 : float32 (4 bytes)
1749 5 : double64 (8 bytes)
1761 5 : double64 (8 bytes)
1750
1762
1751 Return:
1763 Return:
1752 0 : Si no realizo un buen seteo
1764 0 : Si no realizo un buen seteo
1753 1 : Si realizo un buen seteo
1765 1 : Si realizo un buen seteo
1754 """
1766 """
1755
1767
1756 if ext == None:
1768 if ext == None:
1757 ext = self.ext
1769 ext = self.ext
1758
1770
1759 self.ext = ext.lower()
1771 self.ext = ext.lower()
1760
1772
1761 self.path = path
1773 self.path = path
1762
1774
1763 if set is None:
1775 if set is None:
1764 self.setFile = -1
1776 self.setFile = -1
1765 else:
1777 else:
1766 self.setFile = set - 1
1778 self.setFile = set - 1
1767
1779
1768 self.blocksPerFile = blocksPerFile
1780 self.blocksPerFile = blocksPerFile
1769
1781
1770 self.profilesPerBlock = profilesPerBlock
1782 self.profilesPerBlock = profilesPerBlock
1771
1783
1772 self.dataOut = dataOut
1784 self.dataOut = dataOut
1773 self.fileDate = self.dataOut.datatime.date()
1785 self.fileDate = self.dataOut.datatime.date()
1774 #By default
1786 #By default
1775 self.dtype = self.dataOut.dtype
1787 self.dtype = self.dataOut.dtype
1776
1788
1777 if datatype is not None:
1789 if datatype is not None:
1778 self.dtype = get_numpy_dtype(datatype)
1790 self.dtype = get_numpy_dtype(datatype)
1779
1791
1780 if not(self.setNextFile()):
1792 if not(self.setNextFile()):
1781 print "[Writing] There isn't a next file"
1793 print "[Writing] There isn't a next file"
1782 return 0
1794 return 0
1783
1795
1784 self.setBlockDimension()
1796 self.setBlockDimension()
1785
1797
1786 return 1
1798 return 1
1787
1799
1788 def run(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1800 def run(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1789
1801
1790 if not(self.isConfig):
1802 if not(self.isConfig):
1791
1803
1792 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock, set=set, ext=ext, datatype=datatype, **kwargs)
1804 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock, set=set, ext=ext, datatype=datatype, **kwargs)
1793 self.isConfig = True
1805 self.isConfig = True
1794
1806
1795 self.putData()
1807 self.putData()
@@ -1,243 +1,580
1 '''
1 '''
2 Created on Aug 1, 2017
2 Created on Aug 1, 2017
3
3
4 @author: Juan C. Espinoza
4 @author: Juan C. Espinoza
5 '''
5 '''
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import time
9 import time
10 import json
10 import json
11 import glob
11 import datetime
12 import datetime
12
13
13 import numpy
14 import numpy
15 import h5py
14
16
15 try:
17 try:
16 import madrigal
18 import madrigal
17 import madrigal.cedar
19 import madrigal.cedar
18 except:
20 except:
19 print 'You should install "madrigal library" module if you want to read/write Madrigal data'
21 print 'You should install "madrigal library" module if you want to read/write Madrigal data'
20
22
21 from schainpy.model.proc.jroproc_base import Operation
23 from schainpy.model.io.jroIO_base import JRODataReader
24 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
22 from schainpy.model.data.jrodata import Parameters
25 from schainpy.model.data.jrodata import Parameters
26 from schainpy.utils import log
27
23
28
24 MISSING = -32767
25 DEF_CATALOG = {
29 DEF_CATALOG = {
26 'principleInvestigator': 'Marco Milla',
30 'principleInvestigator': 'Marco Milla',
27 'expPurpose': None,
31 'expPurpose': None,
28 'expMode': None,
32 'expMode': None,
29 'cycleTime': None,
33 'cycleTime': None,
30 'correlativeExp': None,
34 'correlativeExp': None,
31 'sciRemarks': None,
35 'sciRemarks': None,
32 'instRemarks': None
36 'instRemarks': None
33 }
37 }
34 DEF_HEADER = {
38 DEF_HEADER = {
35 'kindatDesc': None,
39 'kindatDesc': None,
36 'analyst': 'Jicamarca User',
40 'analyst': 'Jicamarca User',
37 'comments': None,
41 'comments': None,
38 'history': None
42 'history': None
39 }
43 }
40 MNEMONICS = {
44 MNEMONICS = {
41 10: 'jro',
45 10: 'jro',
42 11: 'jbr',
46 11: 'jbr',
43 840: 'jul',
47 840: 'jul',
44 13: 'jas',
48 13: 'jas',
45 1000: 'pbr',
49 1000: 'pbr',
46 1001: 'hbr',
50 1001: 'hbr',
47 1002: 'obr',
51 1002: 'obr',
48 }
52 }
49
53
54 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
55
50 def load_json(obj):
56 def load_json(obj):
51 '''
57 '''
52 Parse json as string instead of unicode
58 Parse json as string instead of unicode
53 '''
59 '''
54
60
55 if isinstance(obj, str):
61 if isinstance(obj, str):
56 obj = json.loads(obj)
62 iterable = json.loads(obj)
63
64 if isinstance(iterable, dict):
65 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, unicode) else v
66 for k, v in iterable.items()}
67 elif isinstance(iterable, (list, tuple)):
68 return [str(v) if isinstance(v, unicode) else v for v in iterable]
69
70 return iterable
71
72
73 class MADReader(JRODataReader, ProcessingUnit):
74
75 def __init__(self, **kwargs):
76
77 ProcessingUnit.__init__(self, **kwargs)
78
79 self.dataOut = Parameters()
80 self.counter_records = 0
81 self.nrecords = None
82 self.flagNoMoreFiles = 0
83 self.isConfig = False
84 self.filename = None
85 self.intervals = set()
86
87 def setup(self,
88 path=None,
89 startDate=None,
90 endDate=None,
91 format=None,
92 startTime=datetime.time(0, 0, 0),
93 endTime=datetime.time(23, 59, 59),
94 **kwargs):
95
96 self.started = True
97 self.path = path
98 self.startDate = startDate
99 self.endDate = endDate
100 self.startTime = startTime
101 self.endTime = endTime
102 self.datatime = datetime.datetime(1900,1,1)
103 self.oneDDict = load_json(kwargs.get('oneDDict',
104 "{\"GDLATR\":\"lat\", \"GDLONR\":\"lon\"}"))
105 self.twoDDict = load_json(kwargs.get('twoDDict',
106 "{\"GDALT\": \"heightList\"}"))
107 self.ind2DList = load_json(kwargs.get('ind2DList',
108 "[\"GDALT\"]"))
109 if self.path is None:
110 raise ValueError, 'The path is not valid'
111
112 if format is None:
113 raise ValueError, 'The format is not valid choose simple or hdf5'
114 elif format.lower() in ('simple', 'txt'):
115 self.ext = '.txt'
116 elif format.lower() in ('cedar',):
117 self.ext = '.001'
118 else:
119 self.ext = '.hdf5'
120
121 self.search_files(self.path)
122 self.fileId = 0
123
124 if not self.fileList:
125 raise Warning, 'There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path)
126
127 self.setNextFile()
128
129 def search_files(self, path):
130 '''
131 Searching for madrigal files in path
132 Creating a list of files to procces included in [startDate,endDate]
133
134 Input:
135 path - Path to find files
136 '''
137
138 print 'Searching files {} in {} '.format(self.ext, path)
139 foldercounter = 0
140 fileList0 = glob.glob1(path, '*{}'.format(self.ext))
141 fileList0.sort()
142
143 self.fileList = []
144 self.dateFileList = []
57
145
58 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, unicode) else v
146 startDate = self.startDate - datetime.timedelta(1)
59 for k, v in obj.items()}
147 endDate = self.endDate + datetime.timedelta(1)
148
149 for thisFile in fileList0:
150 year = thisFile[3:7]
151 if not year.isdigit():
152 continue
153
154 month = thisFile[7:9]
155 if not month.isdigit():
156 continue
157
158 day = thisFile[9:11]
159 if not day.isdigit():
160 continue
161
162 year, month, day = int(year), int(month), int(day)
163 dateFile = datetime.date(year, month, day)
164
165 if (startDate > dateFile) or (endDate < dateFile):
166 continue
167
168 self.fileList.append(thisFile)
169 self.dateFileList.append(dateFile)
170
171 return
172
173 def parseHeader(self):
174 '''
175 '''
176
177 self.output = {}
178 self.version = '2'
179 s_parameters = None
180 if self.ext == '.txt':
181 self.parameters = [s.strip().lower() for s in self.fp.readline().strip().split(' ') if s]
182 elif self.ext == '.hdf5':
183 metadata = self.fp['Metadata']
184 data = self.fp['Data']['Array Layout']
185 if 'Independent Spatial Parameters' in metadata:
186 s_parameters = [s[0].lower() for s in metadata['Independent Spatial Parameters']]
187 self.version = '3'
188 one = [s[0].lower() for s in data['1D Parameters']['Data Parameters']]
189 one_d = [1 for s in one]
190 two = [s[0].lower() for s in data['2D Parameters']['Data Parameters']]
191 two_d = [2 for s in two]
192 self.parameters = one + two
193 self.parameters_d = one_d + two_d
194
195 log.success('Parameters found: {}'.format(','.join(self.parameters)),
196 'MADReader')
197 if s_parameters:
198 log.success('Spatial parameters: {}'.format(','.join(s_parameters)),
199 'MADReader')
200
201 for param in self.oneDDict.keys():
202 if param.lower() not in self.parameters:
203 print('\x1b[33m[Warning]\x1b[0m Parameter \x1b[1;32m{}\x1b[0m not found will be ignored'.format(
204 param
205 ))
206 self.oneDDict.pop(param, None)
207
208 for param, value in self.twoDDict.items():
209 if param.lower() not in self.parameters:
210 print('\x1b[33m[Warning]\x1b[0m Parameter \x1b[1;32m{}\x1b[0m not found will be ignored'.format(
211 param
212 ))
213 self.twoDDict.pop(param, None)
214 continue
215 if isinstance(value, list):
216 if value[0] not in self.output:
217 self.output[value[0]] = []
218 self.output[value[0]].append(None)
219
220 def parseData(self):
221 '''
222 '''
223
224 if self.ext == '.txt':
225 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
226 self.nrecords = self.data.shape[0]
227 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.ind2DList[0].lower())])
228 elif self.ext == '.hdf5':
229 self.data = self.fp['Data']['Array Layout']
230 self.nrecords = len(self.data['timestamps'].value)
231 self.ranges = self.data['range'].value
232
233 def setNextFile(self):
234 '''
235 '''
236
237 file_id = self.fileId
238
239 if file_id == len(self.fileList):
240 print '\nNo more files in the folder'
241 print 'Total number of file(s) read : {}'.format(self.fileId)
242 self.flagNoMoreFiles = 1
243 return 0
244
245 print('\x1b[32m[Info]\x1b[0m Opening: {}'.format(
246 self.fileList[file_id]
247 ))
248 filename = os.path.join(self.path, self.fileList[file_id])
249
250 if self.filename is not None:
251 self.fp.close()
252
253 self.filename = filename
254 self.filedate = self.dateFileList[file_id]
255
256 if self.ext=='.hdf5':
257 self.fp = h5py.File(self.filename, 'r')
258 else:
259 self.fp = open(self.filename, 'rb')
260
261 self.parseHeader()
262 self.parseData()
263 self.sizeOfFile = os.path.getsize(self.filename)
264 self.counter_records = 0
265 self.flagIsNewFile = 0
266 self.fileId += 1
267
268 return 1
269
270 def readNextBlock(self):
271
272 while True:
273
274 if self.flagIsNewFile:
275 if not self.setNextFile():
276 return 0
277
278 self.readBlock()
279
280 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
281 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
282 print "\x1b[32m[Reading]\x1b[0m Record No. %d/%d -> %s \x1b[33m[Skipping]\x1b[0m" %(
283 self.counter_records,
284 self.nrecords,
285 self.datatime.ctime())
286 continue
287 break
288
289 print "\x1b[32m[Reading]\x1b[0m Record No. %d/%d -> %s" %(
290 self.counter_records,
291 self.nrecords,
292 self.datatime.ctime())
293
294 return 1
295
296 def readBlock(self):
297 '''
298 '''
299 dum = []
300 if self.ext == '.txt':
301 dt = self.data[self.counter_records][:6].astype(int)
302 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
303 while True:
304 dt = self.data[self.counter_records][:6].astype(int)
305 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
306 if datatime == self.datatime:
307 dum.append(self.data[self.counter_records])
308 self.counter_records += 1
309 if self.counter_records == self.nrecords:
310 self.flagIsNewFile = True
311 break
312 continue
313 self.intervals.add((datatime-self.datatime).seconds)
314 break
315 elif self.ext == '.hdf5':
316 datatime = datetime.datetime.utcfromtimestamp(
317 self.data['timestamps'][self.counter_records])
318 nHeights = len(self.ranges)
319 for n, param in enumerate(self.parameters):
320 if self.parameters_d[n] == 1:
321 dum.append(numpy.ones(nHeights)*self.data['1D Parameters'][param][self.counter_records])
322 else:
323 if self.version == '2':
324 dum.append(self.data['2D Parameters'][param][self.counter_records])
325 else:
326 tmp = self.data['2D Parameters'][param].value.T
327 dum.append(tmp[self.counter_records])
328 self.intervals.add((datatime-self.datatime).seconds)
329 self.datatime = datatime
330 self.counter_records += 1
331 if self.counter_records == self.nrecords:
332 self.flagIsNewFile = True
333
334 self.buffer = numpy.array(dum)
335 return
336
337 def set_output(self):
338 '''
339 Storing data from buffer to dataOut object
340 '''
341
342 parameters = [None for __ in self.parameters]
343
344 for param, attr in self.oneDDict.items():
345 x = self.parameters.index(param.lower())
346 setattr(self.dataOut, attr, self.buffer[0][x])
347
348 for param, value in self.twoDDict.items():
349 x = self.parameters.index(param.lower())
350 if self.ext == '.txt':
351 y = self.parameters.index(self.ind2DList[0].lower())
352 ranges = self.buffer[:,y]
353 if self.ranges.size == ranges.size:
354 continue
355 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
356 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
357 dummy[index] = self.buffer[:,x]
358 else:
359
360 dummy = self.buffer[x]
361
362 if isinstance(value, str):
363 if value not in self.ind2DList:
364 setattr(self.dataOut, value, dummy.reshape(1,-1))
365 elif isinstance(value, list):
366 self.output[value[0]][value[1]] = dummy
367 parameters[value[1]] = param
368
369 for key, value in self.output.items():
370 setattr(self.dataOut, key, numpy.array(value))
371
372 self.dataOut.parameters = [s for s in parameters if s]
373 self.dataOut.heightList = self.ranges
374 self.dataOut.utctime = (self.datatime - UT1970).total_seconds()
375 self.dataOut.utctimeInit = self.dataOut.utctime
376 self.dataOut.paramInterval = min(self.intervals)
377 self.dataOut.useLocalTime = False
378 self.dataOut.flagNoData = False
379 self.dataOut.started = self.started
380
381 def getData(self):
382 '''
383 Storing data from databuffer to dataOut object
384 '''
385 if self.flagNoMoreFiles:
386 self.dataOut.flagNoData = True
387 print 'No file left to process'
388 return 0
389
390 if not self.readNextBlock():
391 self.dataOut.flagNoData = True
392 return 0
393
394 self.set_output()
395
396 return 1
60
397
61
398
62 class MAD2Writer(Operation):
399 class MAD2Writer(Operation):
400
401 missing = -32767
402 ext = '.dat'
63
403
64 def __init__(self, **kwargs):
404 def __init__(self, **kwargs):
65
405
66 Operation.__init__(self, **kwargs)
406 Operation.__init__(self, **kwargs)
67 self.dataOut = Parameters()
407 self.dataOut = Parameters()
68 self.path = None
408 self.path = None
69 self.dataOut = None
409 self.dataOut = None
70 self.ext = '.dat'
71
72 return
73
410
74 def run(self, dataOut, path, oneDList, twoDParam='', twoDList='{}', metadata='{}', **kwargs):
411 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}', metadata='{}', **kwargs):
75 '''
412 '''
76 Inputs:
413 Inputs:
77 path - path where files will be created
414 path - path where files will be created
78 oneDList - json of one-dimensional parameters in record where keys
415 oneDDict - json of one-dimensional parameters in record where keys
79 are Madrigal codes (integers or mnemonics) and values the corresponding
416 are Madrigal codes (integers or mnemonics) and values the corresponding
80 dataOut attribute e.g: {
417 dataOut attribute e.g: {
81 'gdlatr': 'lat',
418 'gdlatr': 'lat',
82 'gdlonr': 'lon',
419 'gdlonr': 'lon',
83 'gdlat2':'lat',
420 'gdlat2':'lat',
84 'glon2':'lon'}
421 'glon2':'lon'}
85 twoDParam - independent parameter to get the number of rows e.g:
422 ind2DList - list of independent spatial two-dimensional parameters e.g:
86 heighList
423 ['heighList']
87 twoDList - json of two-dimensional parameters in record where keys
424 twoDDict - json of two-dimensional parameters in record where keys
88 are Madrigal codes (integers or mnemonics) and values the corresponding
425 are Madrigal codes (integers or mnemonics) and values the corresponding
89 dataOut attribute if multidimensional array specify as tupple
426 dataOut attribute if multidimensional array specify as tupple
90 ('attr', pos) e.g: {
427 ('attr', pos) e.g: {
91 'gdalt': 'heightList',
428 'gdalt': 'heightList',
92 'vn1p2': ('data_output', 0),
429 'vn1p2': ('data_output', 0),
93 'vn2p2': ('data_output', 1),
430 'vn2p2': ('data_output', 1),
94 'vn3': ('data_output', 2),
431 'vn3': ('data_output', 2),
95 'snl': ('data_SNR', 'db')
432 'snl': ('data_SNR', 'db')
96 }
433 }
97 metadata - json of madrigal metadata (kinst, kindat, catalog and header)
434 metadata - json of madrigal metadata (kinst, kindat, catalog and header)
98 '''
435 '''
99 if not self.isConfig:
436 if not self.isConfig:
100 self.setup(dataOut, path, oneDList, twoDParam, twoDList, metadata, **kwargs)
437 self.setup(dataOut, path, oneDDict, ind2DList, twoDDict, metadata, **kwargs)
101 self.isConfig = True
438 self.isConfig = True
102
439
103 self.putData()
440 self.putData()
104 return
441 return
105
442
106 def setup(self, dataOut, path, oneDList, twoDParam, twoDList, metadata, **kwargs):
443 def setup(self, dataOut, path, oneDDict, ind2DList, twoDDict, metadata, **kwargs):
107 '''
444 '''
108 Configure Operation
445 Configure Operation
109 '''
446 '''
110
447
111 self.dataOut = dataOut
448 self.dataOut = dataOut
112 self.nmodes = self.dataOut.nmodes
449 self.nmodes = self.dataOut.nmodes
113 self.path = path
450 self.path = path
114 self.blocks = kwargs.get('blocks', None)
451 self.blocks = kwargs.get('blocks', None)
115 self.counter = 0
452 self.counter = 0
116 self.oneDList = load_json(oneDList)
453 self.oneDDict = load_json(oneDDict)
117 self.twoDList = load_json(twoDList)
454 self.twoDDict = load_json(twoDDict)
118 self.twoDParam = twoDParam
455 self.ind2DList = load_json(ind2DList)
119 meta = load_json(metadata)
456 meta = load_json(metadata)
120 self.kinst = meta.get('kinst')
457 self.kinst = meta.get('kinst')
121 self.kindat = meta.get('kindat')
458 self.kindat = meta.get('kindat')
122 self.catalog = meta.get('catalog', DEF_CATALOG)
459 self.catalog = meta.get('catalog', DEF_CATALOG)
123 self.header = meta.get('header', DEF_HEADER)
460 self.header = meta.get('header', DEF_HEADER)
124
461
125 return
462 return
126
463
127 def setFile(self):
464 def setFile(self):
128 '''
465 '''
129 Create new cedar file object
466 Create new cedar file object
130 '''
467 '''
131
468
132 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
469 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
133 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
470 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
134
471
135 filename = '%s%s_%s%s' % (self.mnemonic,
472 filename = '%s%s_%s%s' % (self.mnemonic,
136 date.strftime('%Y%m%d_%H%M%S'),
473 date.strftime('%Y%m%d_%H%M%S'),
137 self.dataOut.mode,
474 self.dataOut.mode,
138 self.ext)
475 self.ext)
139
476
140 self.fullname = os.path.join(self.path, filename)
477 self.fullname = os.path.join(self.path, filename)
141
478
142 if os.path.isfile(self.fullname) :
479 if os.path.isfile(self.fullname) :
143 print "Destination path '%s' already exists. Previous file deleted. " %self.fullname
480 print "Destination path '%s' already exists. Previous file deleted. " %self.fullname
144 os.remove(self.fullname)
481 os.remove(self.fullname)
145
482
146 try:
483 try:
147 print '[Writing] creating file : %s' % (self.fullname)
484 print '[Writing] creating file : %s' % (self.fullname)
148 self.cedarObj = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
485 self.cedarObj = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
149 except ValueError, e:
486 except ValueError, e:
150 print '[Error]: Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile" '
487 print '[Error]: Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile" '
151 return
488 return
152
489
153 return 1
490 return 1
154
491
155 def writeBlock(self):
492 def writeBlock(self):
156 '''
493 '''
157 Add data records to cedar file taking data from oneDList and twoDList
494 Add data records to cedar file taking data from oneDDict and twoDDict
158 attributes.
495 attributes.
159 Allowed parameters in: parcodes.tab
496 Allowed parameters in: parcodes.tab
160 '''
497 '''
161
498
162 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
499 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
163 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
500 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
164 nrows = len(getattr(self.dataOut, self.twoDParam))
501 nrows = len(getattr(self.dataOut, self.ind2DList))
165
502
166 rec = madrigal.cedar.MadrigalDataRecord(
503 rec = madrigal.cedar.MadrigalDataRecord(
167 self.kinst,
504 self.kinst,
168 self.kindat,
505 self.kindat,
169 startTime.year,
506 startTime.year,
170 startTime.month,
507 startTime.month,
171 startTime.day,
508 startTime.day,
172 startTime.hour,
509 startTime.hour,
173 startTime.minute,
510 startTime.minute,
174 startTime.second,
511 startTime.second,
175 startTime.microsecond/10000,
512 startTime.microsecond/10000,
176 endTime.year,
513 endTime.year,
177 endTime.month,
514 endTime.month,
178 endTime.day,
515 endTime.day,
179 endTime.hour,
516 endTime.hour,
180 endTime.minute,
517 endTime.minute,
181 endTime.second,
518 endTime.second,
182 endTime.microsecond/10000,
519 endTime.microsecond/10000,
183 self.oneDList.keys(),
520 self.oneDDict.keys(),
184 self.twoDList.keys(),
521 self.twoDDict.keys(),
185 nrows
522 nrows
186 )
523 )
187
524
188 # Setting 1d values
525 # Setting 1d values
189 for key in self.oneDList:
526 for key in self.oneDDict:
190 rec.set1D(key, getattr(self.dataOut, self.oneDList[key]))
527 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
191
528
192 # Setting 2d values
529 # Setting 2d values
193 invalid = numpy.isnan(self.dataOut.data_output)
530 invalid = numpy.isnan(self.dataOut.data_output)
194 self.dataOut.data_output[invalid] = MISSING
531 self.dataOut.data_output[invalid] = self.missing
195 out = {}
532 out = {}
196 for key, value in self.twoDList.items():
533 for key, value in self.twoDDict.items():
197 if isinstance(value, str):
534 if isinstance(value, str):
198 out[key] = getattr(self.dataOut, value)
535 out[key] = getattr(self.dataOut, value)
199 elif isinstance(value, tuple):
536 elif isinstance(value, tuple):
200 attr, x = value
537 attr, x = value
201 if isinstance(x, (int, float)):
538 if isinstance(x, (int, float)):
202 out[key] = getattr(self.dataOut, attr)[int(x)]
539 out[key] = getattr(self.dataOut, attr)[int(x)]
203 elif x.lower()=='db':
540 elif x.lower()=='db':
204 tmp = getattr(self.dataOut, attr)
541 tmp = getattr(self.dataOut, attr)
205 SNRavg = numpy.average(tmp, axis=0)
542 SNRavg = numpy.average(tmp, axis=0)
206 out[key] = 10*numpy.log10(SNRavg)
543 out[key] = 10*numpy.log10(SNRavg)
207
544
208 for n in range(nrows):
545 for n in range(nrows):
209 for key in out:
546 for key in out:
210 rec.set2D(key, n, out[key][n])
547 rec.set2D(key, n, out[key][n])
211
548
212 self.cedarObj.append(rec)
549 self.cedarObj.append(rec)
213 self.cedarObj.dump()
550 self.cedarObj.dump()
214 print '[Writing] Record No. {} (mode {}).'.format(
551 print '[Writing] Record No. {} (mode {}).'.format(
215 self.counter,
552 self.counter,
216 self.dataOut.mode
553 self.dataOut.mode
217 )
554 )
218
555
219 def setHeader(self):
556 def setHeader(self):
220 '''
557 '''
221 Create an add catalog and header to cedar file
558 Create an add catalog and header to cedar file
222 '''
559 '''
223
560
224 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
561 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
225 header.createCatalog(**self.catalog)
562 header.createCatalog(**self.catalog)
226 header.createHeader(**self.header)
563 header.createHeader(**self.header)
227 header.write()
564 header.write()
228
565
229 def putData(self):
566 def putData(self):
230
567
231 if self.dataOut.flagNoData:
568 if self.dataOut.flagNoData:
232 return 0
569 return 0
233
570
234 if self.counter == 0:
571 if self.counter == 0:
235 self.setFile()
572 self.setFile()
236
573
237 if self.counter <= self.dataOut.nrecords:
574 if self.counter <= self.dataOut.nrecords:
238 self.writeBlock()
575 self.writeBlock()
239 self.counter += 1
576 self.counter += 1
240
577
241 if self.counter == self.dataOut.nrecords or self.counter == self.blocks:
578 if self.counter == self.dataOut.nrecords or self.counter == self.blocks:
242 self.setHeader()
579 self.setHeader()
243 self.counter = 0
580 self.counter = 0
@@ -1,707 +1,698
1 '''
1 '''
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import numpy
6 import numpy
7
7
8 from jroIO_base import LOCALTIME, JRODataReader, JRODataWriter
8 from jroIO_base import LOCALTIME, JRODataReader, JRODataWriter
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
10 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
10 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
11 from schainpy.model.data.jrodata import Spectra
11 from schainpy.model.data.jrodata import Spectra
12
12
13 class SpectraReader(JRODataReader, ProcessingUnit):
13 class SpectraReader(JRODataReader, ProcessingUnit):
14
14
15 """
15 """
16 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
16 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
17 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
17 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
18 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
18 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
19
19
20 paresCanalesIguales * alturas * perfiles (Self Spectra)
20 paresCanalesIguales * alturas * perfiles (Self Spectra)
21 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
21 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
22 canales * alturas (DC Channels)
22 canales * alturas (DC Channels)
23
23
24
24
25 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
25 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
26 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
26 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
27 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
27 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
28 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
28 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
29
29
30 Example:
30 Example:
31 dpath = "/home/myuser/data"
31 dpath = "/home/myuser/data"
32
32
33 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
33 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
34
34
35 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
35 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
36
36
37 readerObj = SpectraReader()
37 readerObj = SpectraReader()
38
38
39 readerObj.setup(dpath, startTime, endTime)
39 readerObj.setup(dpath, startTime, endTime)
40
40
41 while(True):
41 while(True):
42
42
43 readerObj.getData()
43 readerObj.getData()
44
44
45 print readerObj.data_spc
45 print readerObj.data_spc
46
46
47 print readerObj.data_cspc
47 print readerObj.data_cspc
48
48
49 print readerObj.data_dc
49 print readerObj.data_dc
50
50
51 if readerObj.flagNoMoreFiles:
51 if readerObj.flagNoMoreFiles:
52 break
52 break
53
53
54 """
54 """
55
55
56 pts2read_SelfSpectra = 0
56 pts2read_SelfSpectra = 0
57
57
58 pts2read_CrossSpectra = 0
58 pts2read_CrossSpectra = 0
59
59
60 pts2read_DCchannels = 0
60 pts2read_DCchannels = 0
61
61
62 ext = ".pdata"
62 ext = ".pdata"
63
63
64 optchar = "P"
64 optchar = "P"
65
65
66 dataOut = None
66 dataOut = None
67
67
68 nRdChannels = None
68 nRdChannels = None
69
69
70 nRdPairs = None
70 nRdPairs = None
71
71
72 rdPairList = []
72 rdPairList = []
73
73
74 def __init__(self, **kwargs):
74 def __init__(self, **kwargs):
75 """
75 """
76 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
76 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
77
77
78 Inputs:
78 Inputs:
79
79
80 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
80 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
81 almacenar un perfil de datos cada vez que se haga un requerimiento
81 almacenar un perfil de datos cada vez que se haga un requerimiento
82 (getData). El perfil sera obtenido a partir del buffer de datos,
82 (getData). El perfil sera obtenido a partir del buffer de datos,
83 si el buffer esta vacio se hara un nuevo proceso de lectura de un
83 si el buffer esta vacio se hara un nuevo proceso de lectura de un
84 bloque de datos.
84 bloque de datos.
85 Si este parametro no es pasado se creara uno internamente.
85 Si este parametro no es pasado se creara uno internamente.
86
86
87
87
88 Affected:
88 Affected:
89
89
90 self.dataOut
90 self.dataOut
91
91
92 Return : None
92 Return : None
93 """
93 """
94
94
95
95
96 #Eliminar de la base la herencia
96 #Eliminar de la base la herencia
97 ProcessingUnit.__init__(self, **kwargs)
97 ProcessingUnit.__init__(self, **kwargs)
98
98
99 # self.isConfig = False
99 # self.isConfig = False
100
100
101 self.pts2read_SelfSpectra = 0
101 self.pts2read_SelfSpectra = 0
102
102
103 self.pts2read_CrossSpectra = 0
103 self.pts2read_CrossSpectra = 0
104
104
105 self.pts2read_DCchannels = 0
105 self.pts2read_DCchannels = 0
106
106
107 self.datablock = None
107 self.datablock = None
108
108
109 self.utc = None
109 self.utc = None
110
110
111 self.ext = ".pdata"
111 self.ext = ".pdata"
112
112
113 self.optchar = "P"
113 self.optchar = "P"
114
114
115 self.basicHeaderObj = BasicHeader(LOCALTIME)
115 self.basicHeaderObj = BasicHeader(LOCALTIME)
116
116
117 self.systemHeaderObj = SystemHeader()
117 self.systemHeaderObj = SystemHeader()
118
118
119 self.radarControllerHeaderObj = RadarControllerHeader()
119 self.radarControllerHeaderObj = RadarControllerHeader()
120
120
121 self.processingHeaderObj = ProcessingHeader()
121 self.processingHeaderObj = ProcessingHeader()
122
122
123 self.online = 0
123 self.online = 0
124
124
125 self.fp = None
125 self.fp = None
126
126
127 self.idFile = None
127 self.idFile = None
128
128
129 self.dtype = None
129 self.dtype = None
130
130
131 self.fileSizeByHeader = None
131 self.fileSizeByHeader = None
132
132
133 self.filenameList = []
133 self.filenameList = []
134
134
135 self.filename = None
135 self.filename = None
136
136
137 self.fileSize = None
137 self.fileSize = None
138
138
139 self.firstHeaderSize = 0
139 self.firstHeaderSize = 0
140
140
141 self.basicHeaderSize = 24
141 self.basicHeaderSize = 24
142
142
143 self.pathList = []
143 self.pathList = []
144
144
145 self.lastUTTime = 0
145 self.lastUTTime = 0
146
146
147 self.maxTimeStep = 30
147 self.maxTimeStep = 30
148
148
149 self.flagNoMoreFiles = 0
149 self.flagNoMoreFiles = 0
150
150
151 self.set = 0
151 self.set = 0
152
152
153 self.path = None
153 self.path = None
154
154
155 self.delay = 60 #seconds
155 self.delay = 60 #seconds
156
156
157 self.nTries = 3 #quantity tries
157 self.nTries = 3 #quantity tries
158
158
159 self.nFiles = 3 #number of files for searching
159 self.nFiles = 3 #number of files for searching
160
160
161 self.nReadBlocks = 0
161 self.nReadBlocks = 0
162
162
163 self.flagIsNewFile = 1
163 self.flagIsNewFile = 1
164
164
165 self.__isFirstTimeOnline = 1
165 self.__isFirstTimeOnline = 1
166
166
167 # self.ippSeconds = 0
167 # self.ippSeconds = 0
168
168
169 self.flagDiscontinuousBlock = 0
169 self.flagDiscontinuousBlock = 0
170
170
171 self.flagIsNewBlock = 0
171 self.flagIsNewBlock = 0
172
172
173 self.nTotalBlocks = 0
173 self.nTotalBlocks = 0
174
174
175 self.blocksize = 0
175 self.blocksize = 0
176
176
177 self.dataOut = self.createObjByDefault()
177 self.dataOut = self.createObjByDefault()
178
178
179 self.profileIndex = 1 #Always
179 self.profileIndex = 1 #Always
180
180
181
181
182 def createObjByDefault(self):
182 def createObjByDefault(self):
183
183
184 dataObj = Spectra()
184 dataObj = Spectra()
185
185
186 return dataObj
186 return dataObj
187
187
188 def __hasNotDataInBuffer(self):
188 def __hasNotDataInBuffer(self):
189 return 1
189 return 1
190
190
191
191
192 def getBlockDimension(self):
192 def getBlockDimension(self):
193 """
193 """
194 Obtiene la cantidad de puntos a leer por cada bloque de datos
194 Obtiene la cantidad de puntos a leer por cada bloque de datos
195
195
196 Affected:
196 Affected:
197 self.nRdChannels
197 self.nRdChannels
198 self.nRdPairs
198 self.nRdPairs
199 self.pts2read_SelfSpectra
199 self.pts2read_SelfSpectra
200 self.pts2read_CrossSpectra
200 self.pts2read_CrossSpectra
201 self.pts2read_DCchannels
201 self.pts2read_DCchannels
202 self.blocksize
202 self.blocksize
203 self.dataOut.nChannels
203 self.dataOut.nChannels
204 self.dataOut.nPairs
204 self.dataOut.nPairs
205
205
206 Return:
206 Return:
207 None
207 None
208 """
208 """
209 self.nRdChannels = 0
209 self.nRdChannels = 0
210 self.nRdPairs = 0
210 self.nRdPairs = 0
211 self.rdPairList = []
211 self.rdPairList = []
212
212
213 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
213 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
214 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
214 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
215 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
215 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
216
216
217 else:
217 else:
218 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
218 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
219 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
219 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
220
220
221 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
221 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
222
222
223 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
223 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
224 self.blocksize = self.pts2read_SelfSpectra
224 self.blocksize = self.pts2read_SelfSpectra
225
225
226 if self.processingHeaderObj.flag_cspc:
226 if self.processingHeaderObj.flag_cspc:
227 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
227 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
228 self.blocksize += self.pts2read_CrossSpectra
228 self.blocksize += self.pts2read_CrossSpectra
229
229
230 if self.processingHeaderObj.flag_dc:
230 if self.processingHeaderObj.flag_dc:
231 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
231 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
232 self.blocksize += self.pts2read_DCchannels
232 self.blocksize += self.pts2read_DCchannels
233
233
234 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
234 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
235
235
236
236
237 def readBlock(self):
237 def readBlock(self):
238 """
238 """
239 Lee el bloque de datos desde la posicion actual del puntero del archivo
239 Lee el bloque de datos desde la posicion actual del puntero del archivo
240 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
240 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
241 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
241 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
242 es seteado a 0
242 es seteado a 0
243
243
244 Return: None
244 Return: None
245
245
246 Variables afectadas:
246 Variables afectadas:
247
247
248
248
249 self.flagIsNewFile
249 self.flagIsNewFile
250 self.flagIsNewBlock
250 self.flagIsNewBlock
251 self.nTotalBlocks
251 self.nTotalBlocks
252 self.data_spc
252 self.data_spc
253 self.data_cspc
253 self.data_cspc
254 self.data_dc
254 self.data_dc
255
255
256 Exceptions:
256 Exceptions:
257 Si un bloque leido no es un bloque valido
257 Si un bloque leido no es un bloque valido
258 """
258 """
259 print ' ======================================================== '
260 print ' '
261 print ' '
262 print self.processingHeaderObj.totalSpectra, 'TotalSpectra', type(self.processingHeaderObj.totalSpectra)
263 print self.processingHeaderObj.spectraComb, 'SpectraComb', type(self.processingHeaderObj.spectraComb)
264 print ' '
265 print ' '
266 print ' ======================================================== '
267
268
259
269 blockOk_flag = False
260 blockOk_flag = False
270 fpointer = self.fp.tell()
261 fpointer = self.fp.tell()
271
262
272 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
263 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
273 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
264 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
274
265
275 if self.processingHeaderObj.flag_cspc:
266 if self.processingHeaderObj.flag_cspc:
276 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
267 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
277 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
268 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
278
269
279 if self.processingHeaderObj.flag_dc:
270 if self.processingHeaderObj.flag_dc:
280 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
271 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
281 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
272 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
282
273
283
274
284 if not(self.processingHeaderObj.shif_fft):
275 if not(self.processingHeaderObj.shif_fft):
285 #desplaza a la derecha en el eje 2 determinadas posiciones
276 #desplaza a la derecha en el eje 2 determinadas posiciones
286 shift = int(self.processingHeaderObj.profilesPerBlock/2)
277 shift = int(self.processingHeaderObj.profilesPerBlock/2)
287 spc = numpy.roll( spc, shift , axis=2 )
278 spc = numpy.roll( spc, shift , axis=2 )
288
279
289 if self.processingHeaderObj.flag_cspc:
280 if self.processingHeaderObj.flag_cspc:
290 #desplaza a la derecha en el eje 2 determinadas posiciones
281 #desplaza a la derecha en el eje 2 determinadas posiciones
291 cspc = numpy.roll( cspc, shift, axis=2 )
282 cspc = numpy.roll( cspc, shift, axis=2 )
292
283
293 #Dimensions : nChannels, nProfiles, nSamples
284 #Dimensions : nChannels, nProfiles, nSamples
294 spc = numpy.transpose( spc, (0,2,1) )
285 spc = numpy.transpose( spc, (0,2,1) )
295 self.data_spc = spc
286 self.data_spc = spc
296
287
297 if self.processingHeaderObj.flag_cspc:
288 if self.processingHeaderObj.flag_cspc:
298
289
299 cspc = numpy.transpose( cspc, (0,2,1) )
290 cspc = numpy.transpose( cspc, (0,2,1) )
300 self.data_cspc = cspc['real'] + cspc['imag']*1j
291 self.data_cspc = cspc['real'] + cspc['imag']*1j
301 else:
292 else:
302 self.data_cspc = None
293 self.data_cspc = None
303
294
304
295
305 if self.processingHeaderObj.flag_dc:
296 if self.processingHeaderObj.flag_dc:
306 self.data_dc = dc['real'] + dc['imag']*1j
297 self.data_dc = dc['real'] + dc['imag']*1j
307 else:
298 else:
308 self.data_dc = None
299 self.data_dc = None
309
300
310 self.flagIsNewFile = 0
301 self.flagIsNewFile = 0
311 self.flagIsNewBlock = 1
302 self.flagIsNewBlock = 1
312
303
313 self.nTotalBlocks += 1
304 self.nTotalBlocks += 1
314 self.nReadBlocks += 1
305 self.nReadBlocks += 1
315
306
316 return 1
307 return 1
317
308
318 def getFirstHeader(self):
309 def getFirstHeader(self):
319
310
320 self.getBasicHeader()
311 self.getBasicHeader()
321
312
322 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
313 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
323
314
324 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
315 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
325
316
326 # self.dataOut.ippSeconds = self.ippSeconds
317 # self.dataOut.ippSeconds = self.ippSeconds
327
318
328 # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.processingHeaderObj.profilesPerBlock
319 # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.processingHeaderObj.profilesPerBlock
329
320
330 self.dataOut.dtype = self.dtype
321 self.dataOut.dtype = self.dtype
331
322
332 # self.dataOut.nPairs = self.nPairs
323 # self.dataOut.nPairs = self.nPairs
333
324
334 self.dataOut.pairsList = self.rdPairList
325 self.dataOut.pairsList = self.rdPairList
335
326
336 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
327 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
337
328
338 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
329 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
339
330
340 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
331 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
341
332
342 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
333 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
343
334
344 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
335 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
345
336
346 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
337 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
347
338
348 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
339 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
349
340
350 self.dataOut.flagShiftFFT = True #Data is always shifted
341 self.dataOut.flagShiftFFT = True #Data is always shifted
351
342
352 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode #asumo q la data no esta decodificada
343 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode #asumo q la data no esta decodificada
353
344
354 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip #asumo q la data esta sin flip
345 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip #asumo q la data esta sin flip
355
346
356 def getData(self):
347 def getData(self):
357 """
348 """
358 First method to execute before "RUN" is called.
349 First method to execute before "RUN" is called.
359
350
360 Copia el buffer de lectura a la clase "Spectra",
351 Copia el buffer de lectura a la clase "Spectra",
361 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
352 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
362 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
353 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
363
354
364 Return:
355 Return:
365 0 : Si no hay mas archivos disponibles
356 0 : Si no hay mas archivos disponibles
366 1 : Si hizo una buena copia del buffer
357 1 : Si hizo una buena copia del buffer
367
358
368 Affected:
359 Affected:
369 self.dataOut
360 self.dataOut
370
361
371 self.flagDiscontinuousBlock
362 self.flagDiscontinuousBlock
372 self.flagIsNewBlock
363 self.flagIsNewBlock
373 """
364 """
374
365
375 if self.flagNoMoreFiles:
366 if self.flagNoMoreFiles:
376 self.dataOut.flagNoData = True
367 self.dataOut.flagNoData = True
377 print 'Process finished'
368 print 'Process finished'
378 return 0
369 return 0
379
370
380 self.flagDiscontinuousBlock = 0
371 self.flagDiscontinuousBlock = 0
381 self.flagIsNewBlock = 0
372 self.flagIsNewBlock = 0
382
373
383 if self.__hasNotDataInBuffer():
374 if self.__hasNotDataInBuffer():
384
375
385 if not( self.readNextBlock() ):
376 if not( self.readNextBlock() ):
386 self.dataOut.flagNoData = True
377 self.dataOut.flagNoData = True
387 return 0
378 return 0
388
379
389
380
390 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
381 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
391
382
392 if self.data_spc is None:
383 if self.data_spc is None:
393 self.dataOut.flagNoData = True
384 self.dataOut.flagNoData = True
394 return 0
385 return 0
395
386
396 self.getBasicHeader()
387 self.getBasicHeader()
397
388
398 self.getFirstHeader()
389 self.getFirstHeader()
399
390
400 self.dataOut.data_spc = self.data_spc
391 self.dataOut.data_spc = self.data_spc
401
392
402 self.dataOut.data_cspc = self.data_cspc
393 self.dataOut.data_cspc = self.data_cspc
403
394
404 self.dataOut.data_dc = self.data_dc
395 self.dataOut.data_dc = self.data_dc
405
396
406 self.dataOut.flagNoData = False
397 self.dataOut.flagNoData = False
407
398
408 self.dataOut.realtime = self.online
399 self.dataOut.realtime = self.online
409
400
410 return self.dataOut.data_spc
401 return self.dataOut.data_spc
411
402
412 class SpectraWriter(JRODataWriter, Operation):
403 class SpectraWriter(JRODataWriter, Operation):
413
404
414 """
405 """
415 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
406 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
416 de los datos siempre se realiza por bloques.
407 de los datos siempre se realiza por bloques.
417 """
408 """
418
409
419 ext = ".pdata"
410 ext = ".pdata"
420
411
421 optchar = "P"
412 optchar = "P"
422
413
423 shape_spc_Buffer = None
414 shape_spc_Buffer = None
424
415
425 shape_cspc_Buffer = None
416 shape_cspc_Buffer = None
426
417
427 shape_dc_Buffer = None
418 shape_dc_Buffer = None
428
419
429 data_spc = None
420 data_spc = None
430
421
431 data_cspc = None
422 data_cspc = None
432
423
433 data_dc = None
424 data_dc = None
434
425
435 # dataOut = None
426 # dataOut = None
436
427
437 def __init__(self):
428 def __init__(self):
438 """
429 """
439 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
430 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
440
431
441 Affected:
432 Affected:
442
433
443 self.dataOut
434 self.dataOut
444 self.basicHeaderObj
435 self.basicHeaderObj
445 self.systemHeaderObj
436 self.systemHeaderObj
446 self.radarControllerHeaderObj
437 self.radarControllerHeaderObj
447 self.processingHeaderObj
438 self.processingHeaderObj
448
439
449 Return: None
440 Return: None
450 """
441 """
451
442
452 Operation.__init__(self)
443 Operation.__init__(self)
453
444
454 self.isConfig = False
445 self.isConfig = False
455
446
456 self.nTotalBlocks = 0
447 self.nTotalBlocks = 0
457
448
458 self.data_spc = None
449 self.data_spc = None
459
450
460 self.data_cspc = None
451 self.data_cspc = None
461
452
462
453
463 self.data_dc = None
454 self.data_dc = None
464
455
465 self.fp = None
456 self.fp = None
466
457
467 self.flagIsNewFile = 1
458 self.flagIsNewFile = 1
468
459
469 self.nTotalBlocks = 0
460 self.nTotalBlocks = 0
470
461
471 self.flagIsNewBlock = 0
462 self.flagIsNewBlock = 0
472
463
473 self.setFile = None
464 self.setFile = None
474
465
475 self.dtype = None
466 self.dtype = None
476
467
477 self.path = None
468 self.path = None
478
469
479 self.noMoreFiles = 0
470 self.noMoreFiles = 0
480
471
481 self.filename = None
472 self.filename = None
482
473
483 self.basicHeaderObj = BasicHeader(LOCALTIME)
474 self.basicHeaderObj = BasicHeader(LOCALTIME)
484
475
485 self.systemHeaderObj = SystemHeader()
476 self.systemHeaderObj = SystemHeader()
486
477
487 self.radarControllerHeaderObj = RadarControllerHeader()
478 self.radarControllerHeaderObj = RadarControllerHeader()
488
479
489 self.processingHeaderObj = ProcessingHeader()
480 self.processingHeaderObj = ProcessingHeader()
490
481
491
482
492 def hasAllDataInBuffer(self):
483 def hasAllDataInBuffer(self):
493 return 1
484 return 1
494
485
495
486
496
487
497 def setBlockDimension(self):
488 def setBlockDimension(self):
498 """
489 """
499 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
490 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
500
491
501 Affected:
492 Affected:
502 self.shape_spc_Buffer
493 self.shape_spc_Buffer
503 self.shape_cspc_Buffer
494 self.shape_cspc_Buffer
504 self.shape_dc_Buffer
495 self.shape_dc_Buffer
505
496
506 Return: None
497 Return: None
507 """
498 """
508 self.shape_spc_Buffer = (self.dataOut.nChannels,
499 self.shape_spc_Buffer = (self.dataOut.nChannels,
509 self.processingHeaderObj.nHeights,
500 self.processingHeaderObj.nHeights,
510 self.processingHeaderObj.profilesPerBlock)
501 self.processingHeaderObj.profilesPerBlock)
511
502
512 self.shape_cspc_Buffer = (self.dataOut.nPairs,
503 self.shape_cspc_Buffer = (self.dataOut.nPairs,
513 self.processingHeaderObj.nHeights,
504 self.processingHeaderObj.nHeights,
514 self.processingHeaderObj.profilesPerBlock)
505 self.processingHeaderObj.profilesPerBlock)
515
506
516 self.shape_dc_Buffer = (self.dataOut.nChannels,
507 self.shape_dc_Buffer = (self.dataOut.nChannels,
517 self.processingHeaderObj.nHeights)
508 self.processingHeaderObj.nHeights)
518
509
519
510
520 def writeBlock(self):
511 def writeBlock(self):
521 """
512 """
522 Escribe el buffer en el file designado
513 Escribe el buffer en el file designado
523
514
524
515
525 Affected:
516 Affected:
526 self.data_spc
517 self.data_spc
527 self.data_cspc
518 self.data_cspc
528 self.data_dc
519 self.data_dc
529 self.flagIsNewFile
520 self.flagIsNewFile
530 self.flagIsNewBlock
521 self.flagIsNewBlock
531 self.nTotalBlocks
522 self.nTotalBlocks
532 self.nWriteBlocks
523 self.nWriteBlocks
533
524
534 Return: None
525 Return: None
535 """
526 """
536
527
537 spc = numpy.transpose( self.data_spc, (0,2,1) )
528 spc = numpy.transpose( self.data_spc, (0,2,1) )
538 if not( self.processingHeaderObj.shif_fft ):
529 if not( self.processingHeaderObj.shif_fft ):
539 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
530 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
540 data = spc.reshape((-1))
531 data = spc.reshape((-1))
541 data = data.astype(self.dtype[0])
532 data = data.astype(self.dtype[0])
542 data.tofile(self.fp)
533 data.tofile(self.fp)
543
534
544 if self.data_cspc is not None:
535 if self.data_cspc is not None:
545 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
536 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
546 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
537 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
547 if not( self.processingHeaderObj.shif_fft ):
538 if not( self.processingHeaderObj.shif_fft ):
548 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
539 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
549 data['real'] = cspc.real
540 data['real'] = cspc.real
550 data['imag'] = cspc.imag
541 data['imag'] = cspc.imag
551 data = data.reshape((-1))
542 data = data.reshape((-1))
552 data.tofile(self.fp)
543 data.tofile(self.fp)
553
544
554
545
555 if self.data_dc is not None:
546 if self.data_dc is not None:
556 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
547 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
557 dc = self.data_dc
548 dc = self.data_dc
558 data['real'] = dc.real
549 data['real'] = dc.real
559 data['imag'] = dc.imag
550 data['imag'] = dc.imag
560 data = data.reshape((-1))
551 data = data.reshape((-1))
561 data.tofile(self.fp)
552 data.tofile(self.fp)
562
553
563 # self.data_spc.fill(0)
554 # self.data_spc.fill(0)
564 #
555 #
565 # if self.data_dc is not None:
556 # if self.data_dc is not None:
566 # self.data_dc.fill(0)
557 # self.data_dc.fill(0)
567 #
558 #
568 # if self.data_cspc is not None:
559 # if self.data_cspc is not None:
569 # self.data_cspc.fill(0)
560 # self.data_cspc.fill(0)
570
561
571
562
572 self.flagIsNewFile = 0
563 self.flagIsNewFile = 0
573 self.flagIsNewBlock = 1
564 self.flagIsNewBlock = 1
574 self.nTotalBlocks += 1
565 self.nTotalBlocks += 1
575 self.nWriteBlocks += 1
566 self.nWriteBlocks += 1
576 self.blockIndex += 1
567 self.blockIndex += 1
577
568
578 # print "[Writing] Block = %d04" %self.blockIndex
569 # print "[Writing] Block = %d04" %self.blockIndex
579
570
580 def putData(self):
571 def putData(self):
581 """
572 """
582 Setea un bloque de datos y luego los escribe en un file
573 Setea un bloque de datos y luego los escribe en un file
583
574
584
575
585 Affected:
576 Affected:
586 self.data_spc
577 self.data_spc
587 self.data_cspc
578 self.data_cspc
588 self.data_dc
579 self.data_dc
589
580
590 Return:
581 Return:
591 0 : Si no hay data o no hay mas files que puedan escribirse
582 0 : Si no hay data o no hay mas files que puedan escribirse
592 1 : Si se escribio la data de un bloque en un file
583 1 : Si se escribio la data de un bloque en un file
593 """
584 """
594
585
595 if self.dataOut.flagNoData:
586 if self.dataOut.flagNoData:
596 return 0
587 return 0
597
588
598 self.flagIsNewBlock = 0
589 self.flagIsNewBlock = 0
599
590
600 if self.dataOut.flagDiscontinuousBlock:
591 if self.dataOut.flagDiscontinuousBlock:
601 self.data_spc.fill(0)
592 self.data_spc.fill(0)
602 self.data_cspc.fill(0)
593 self.data_cspc.fill(0)
603 self.data_dc.fill(0)
594 self.data_dc.fill(0)
604 self.setNextFile()
595 self.setNextFile()
605
596
606 if self.flagIsNewFile == 0:
597 if self.flagIsNewFile == 0:
607 self.setBasicHeader()
598 self.setBasicHeader()
608
599
609 self.data_spc = self.dataOut.data_spc.copy()
600 self.data_spc = self.dataOut.data_spc.copy()
610
601
611 if self.dataOut.data_cspc is not None:
602 if self.dataOut.data_cspc is not None:
612 self.data_cspc = self.dataOut.data_cspc.copy()
603 self.data_cspc = self.dataOut.data_cspc.copy()
613
604
614 if self.dataOut.data_dc is not None:
605 if self.dataOut.data_dc is not None:
615 self.data_dc = self.dataOut.data_dc.copy()
606 self.data_dc = self.dataOut.data_dc.copy()
616
607
617 # #self.processingHeaderObj.dataBlocksPerFile)
608 # #self.processingHeaderObj.dataBlocksPerFile)
618 if self.hasAllDataInBuffer():
609 if self.hasAllDataInBuffer():
619 # self.setFirstHeader()
610 # self.setFirstHeader()
620 self.writeNextBlock()
611 self.writeNextBlock()
621
612
622 return 1
613 return 1
623
614
624
615
625 def __getBlockSize(self):
616 def __getBlockSize(self):
626 '''
617 '''
627 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
618 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
628 '''
619 '''
629
620
630 dtype_width = self.getDtypeWidth()
621 dtype_width = self.getDtypeWidth()
631
622
632 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
623 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
633
624
634 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
625 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
635 blocksize = (pts2write_SelfSpectra*dtype_width)
626 blocksize = (pts2write_SelfSpectra*dtype_width)
636
627
637 if self.dataOut.data_cspc is not None:
628 if self.dataOut.data_cspc is not None:
638 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
629 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
639 blocksize += (pts2write_CrossSpectra*dtype_width*2)
630 blocksize += (pts2write_CrossSpectra*dtype_width*2)
640
631
641 if self.dataOut.data_dc is not None:
632 if self.dataOut.data_dc is not None:
642 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
633 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
643 blocksize += (pts2write_DCchannels*dtype_width*2)
634 blocksize += (pts2write_DCchannels*dtype_width*2)
644
635
645 # blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
636 # blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
646
637
647 return blocksize
638 return blocksize
648
639
649 def setFirstHeader(self):
640 def setFirstHeader(self):
650
641
651 """
642 """
652 Obtiene una copia del First Header
643 Obtiene una copia del First Header
653
644
654 Affected:
645 Affected:
655 self.systemHeaderObj
646 self.systemHeaderObj
656 self.radarControllerHeaderObj
647 self.radarControllerHeaderObj
657 self.dtype
648 self.dtype
658
649
659 Return:
650 Return:
660 None
651 None
661 """
652 """
662
653
663 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
654 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
664 self.systemHeaderObj.nChannels = self.dataOut.nChannels
655 self.systemHeaderObj.nChannels = self.dataOut.nChannels
665 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
656 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
666
657
667 self.processingHeaderObj.dtype = 1 # Spectra
658 self.processingHeaderObj.dtype = 1 # Spectra
668 self.processingHeaderObj.blockSize = self.__getBlockSize()
659 self.processingHeaderObj.blockSize = self.__getBlockSize()
669 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
660 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
670 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
661 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
671 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
662 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
672 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
663 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
673 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
664 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
674 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
665 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
675 self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT
666 self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT
676
667
677
668
678 if self.processingHeaderObj.totalSpectra > 0:
669 if self.processingHeaderObj.totalSpectra > 0:
679 channelList = []
670 channelList = []
680 for channel in range(self.dataOut.nChannels):
671 for channel in range(self.dataOut.nChannels):
681 channelList.append(channel)
672 channelList.append(channel)
682 channelList.append(channel)
673 channelList.append(channel)
683
674
684 pairsList = []
675 pairsList = []
685 if self.dataOut.nPairs > 0:
676 if self.dataOut.nPairs > 0:
686 for pair in self.dataOut.pairsList:
677 for pair in self.dataOut.pairsList:
687 pairsList.append(pair[0])
678 pairsList.append(pair[0])
688 pairsList.append(pair[1])
679 pairsList.append(pair[1])
689
680
690 spectraComb = channelList + pairsList
681 spectraComb = channelList + pairsList
691 spectraComb = numpy.array(spectraComb, dtype="u1")
682 spectraComb = numpy.array(spectraComb, dtype="u1")
692 self.processingHeaderObj.spectraComb = spectraComb
683 self.processingHeaderObj.spectraComb = spectraComb
693
684
694 if self.dataOut.code is not None:
685 if self.dataOut.code is not None:
695 self.processingHeaderObj.code = self.dataOut.code
686 self.processingHeaderObj.code = self.dataOut.code
696 self.processingHeaderObj.nCode = self.dataOut.nCode
687 self.processingHeaderObj.nCode = self.dataOut.nCode
697 self.processingHeaderObj.nBaud = self.dataOut.nBaud
688 self.processingHeaderObj.nBaud = self.dataOut.nBaud
698
689
699 if self.processingHeaderObj.nWindows != 0:
690 if self.processingHeaderObj.nWindows != 0:
700 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
691 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
701 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
692 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
702 self.processingHeaderObj.nHeights = self.dataOut.nHeights
693 self.processingHeaderObj.nHeights = self.dataOut.nHeights
703 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
694 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
704
695
705 self.processingHeaderObj.processFlags = self.getProcessFlags()
696 self.processingHeaderObj.processFlags = self.getProcessFlags()
706
697
707 self.setBasicHeader()
698 self.setBasicHeader()
@@ -1,4042 +1,4045
1 import numpy
1 import numpy
2 import math
2 import math
3 from scipy import optimize, interpolate, signal, stats, ndimage
3 from scipy import optimize, interpolate, signal, stats, ndimage
4 import scipy
4 import scipy
5 import re
5 import re
6 import datetime
6 import datetime
7 import copy
7 import copy
8 import sys
8 import sys
9 import importlib
9 import importlib
10 import itertools
10 import itertools
11 from multiprocessing import Pool, TimeoutError
11 from multiprocessing import Pool, TimeoutError
12 from multiprocessing.pool import ThreadPool
12 from multiprocessing.pool import ThreadPool
13 import copy_reg
13 import copy_reg
14 import cPickle
14 import cPickle
15 import types
15 import types
16 from functools import partial
16 from functools import partial
17 import time
17 import time
18 #from sklearn.cluster import KMeans
18 #from sklearn.cluster import KMeans
19
19
20 import matplotlib.pyplot as plt
20 import matplotlib.pyplot as plt
21
21
22 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
22 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
23 from jroproc_base import ProcessingUnit, Operation
23 from jroproc_base import ProcessingUnit, Operation
24 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
24 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
25 from scipy import asarray as ar,exp
25 from scipy import asarray as ar,exp
26 from scipy.optimize import curve_fit
26 from scipy.optimize import curve_fit
27
27
28 import warnings
28 import warnings
29 from numpy import NaN
29 from numpy import NaN
30 from scipy.optimize.optimize import OptimizeWarning
30 from scipy.optimize.optimize import OptimizeWarning
31 warnings.filterwarnings('ignore')
31 warnings.filterwarnings('ignore')
32
32
33
33
34 SPEED_OF_LIGHT = 299792458
34 SPEED_OF_LIGHT = 299792458
35
35
36
36
37 '''solving pickling issue'''
37 '''solving pickling issue'''
38
38
39 def _pickle_method(method):
39 def _pickle_method(method):
40 func_name = method.im_func.__name__
40 func_name = method.im_func.__name__
41 obj = method.im_self
41 obj = method.im_self
42 cls = method.im_class
42 cls = method.im_class
43 return _unpickle_method, (func_name, obj, cls)
43 return _unpickle_method, (func_name, obj, cls)
44
44
45 def _unpickle_method(func_name, obj, cls):
45 def _unpickle_method(func_name, obj, cls):
46 for cls in cls.mro():
46 for cls in cls.mro():
47 try:
47 try:
48 func = cls.__dict__[func_name]
48 func = cls.__dict__[func_name]
49 except KeyError:
49 except KeyError:
50 pass
50 pass
51 else:
51 else:
52 break
52 break
53 return func.__get__(obj, cls)
53 return func.__get__(obj, cls)
54
54
55 class ParametersProc(ProcessingUnit):
55 class ParametersProc(ProcessingUnit):
56
56
57 nSeconds = None
57 nSeconds = None
58
58
59 def __init__(self):
59 def __init__(self):
60 ProcessingUnit.__init__(self)
60 ProcessingUnit.__init__(self)
61
61
62 # self.objectDict = {}
62 # self.objectDict = {}
63 self.buffer = None
63 self.buffer = None
64 self.firstdatatime = None
64 self.firstdatatime = None
65 self.profIndex = 0
65 self.profIndex = 0
66 self.dataOut = Parameters()
66 self.dataOut = Parameters()
67
67
68 def __updateObjFromInput(self):
68 def __updateObjFromInput(self):
69
69
70 self.dataOut.inputUnit = self.dataIn.type
70 self.dataOut.inputUnit = self.dataIn.type
71
71
72 self.dataOut.timeZone = self.dataIn.timeZone
72 self.dataOut.timeZone = self.dataIn.timeZone
73 self.dataOut.dstFlag = self.dataIn.dstFlag
73 self.dataOut.dstFlag = self.dataIn.dstFlag
74 self.dataOut.errorCount = self.dataIn.errorCount
74 self.dataOut.errorCount = self.dataIn.errorCount
75 self.dataOut.useLocalTime = self.dataIn.useLocalTime
75 self.dataOut.useLocalTime = self.dataIn.useLocalTime
76
76
77 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
77 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
78 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
78 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
79 self.dataOut.channelList = self.dataIn.channelList
79 self.dataOut.channelList = self.dataIn.channelList
80 self.dataOut.heightList = self.dataIn.heightList
80 self.dataOut.heightList = self.dataIn.heightList
81 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
81 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
82 # self.dataOut.nHeights = self.dataIn.nHeights
82 # self.dataOut.nHeights = self.dataIn.nHeights
83 # self.dataOut.nChannels = self.dataIn.nChannels
83 # self.dataOut.nChannels = self.dataIn.nChannels
84 self.dataOut.nBaud = self.dataIn.nBaud
84 self.dataOut.nBaud = self.dataIn.nBaud
85 self.dataOut.nCode = self.dataIn.nCode
85 self.dataOut.nCode = self.dataIn.nCode
86 self.dataOut.code = self.dataIn.code
86 self.dataOut.code = self.dataIn.code
87 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
87 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
88 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
88 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
89 # self.dataOut.utctime = self.firstdatatime
89 # self.dataOut.utctime = self.firstdatatime
90 self.dataOut.utctime = self.dataIn.utctime
90 self.dataOut.utctime = self.dataIn.utctime
91 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
91 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
92 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
92 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
93 self.dataOut.nCohInt = self.dataIn.nCohInt
93 self.dataOut.nCohInt = self.dataIn.nCohInt
94 # self.dataOut.nIncohInt = 1
94 # self.dataOut.nIncohInt = 1
95 self.dataOut.ippSeconds = self.dataIn.ippSeconds
95 self.dataOut.ippSeconds = self.dataIn.ippSeconds
96 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
96 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
97 self.dataOut.timeInterval1 = self.dataIn.timeInterval
97 self.dataOut.timeInterval1 = self.dataIn.timeInterval
98 self.dataOut.heightList = self.dataIn.getHeiRange()
98 self.dataOut.heightList = self.dataIn.getHeiRange()
99 self.dataOut.frequency = self.dataIn.frequency
99 self.dataOut.frequency = self.dataIn.frequency
100 # self.dataOut.noise = self.dataIn.noise
100 # self.dataOut.noise = self.dataIn.noise
101
101
102 def run(self):
102 def run(self):
103
103
104 #---------------------- Voltage Data ---------------------------
104 #---------------------- Voltage Data ---------------------------
105
105
106 if self.dataIn.type == "Voltage":
106 if self.dataIn.type == "Voltage":
107
107
108 self.__updateObjFromInput()
108 self.__updateObjFromInput()
109 self.dataOut.data_pre = self.dataIn.data.copy()
109 self.dataOut.data_pre = self.dataIn.data.copy()
110 self.dataOut.flagNoData = False
110 self.dataOut.flagNoData = False
111 self.dataOut.utctimeInit = self.dataIn.utctime
111 self.dataOut.utctimeInit = self.dataIn.utctime
112 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
112 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
113 return
113 return
114
114
115 #---------------------- Spectra Data ---------------------------
115 #---------------------- Spectra Data ---------------------------
116
116
117 if self.dataIn.type == "Spectra":
117 if self.dataIn.type == "Spectra":
118
118
119 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
119 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
120 self.dataOut.data_spc = self.dataIn.data_spc
120 self.dataOut.data_spc = self.dataIn.data_spc
121 self.dataOut.data_cspc = self.dataIn.data_cspc
121 self.dataOut.data_cspc = self.dataIn.data_cspc
122 self.dataOut.nProfiles = self.dataIn.nProfiles
122 self.dataOut.nProfiles = self.dataIn.nProfiles
123 self.dataOut.nIncohInt = self.dataIn.nIncohInt
123 self.dataOut.nIncohInt = self.dataIn.nIncohInt
124 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
124 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
125 self.dataOut.ippFactor = self.dataIn.ippFactor
125 self.dataOut.ippFactor = self.dataIn.ippFactor
126 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
126 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
127 self.dataOut.spc_noise = self.dataIn.getNoise()
127 self.dataOut.spc_noise = self.dataIn.getNoise()
128 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
128 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
129 self.dataOut.pairsList = self.dataIn.pairsList
129 self.dataOut.pairsList = self.dataIn.pairsList
130 self.dataOut.groupList = self.dataIn.pairsList
130 self.dataOut.groupList = self.dataIn.pairsList
131 self.dataOut.flagNoData = False
131 self.dataOut.flagNoData = False
132
132
133 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
133 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
134 self.dataOut.ChanDist = self.dataIn.ChanDist
134 self.dataOut.ChanDist = self.dataIn.ChanDist
135 else: self.dataOut.ChanDist = None
135 else: self.dataOut.ChanDist = None
136
136
137 if hasattr(self.dataIn, 'VelRange'): #Velocities range
137 if hasattr(self.dataIn, 'VelRange'): #Velocities range
138 self.dataOut.VelRange = self.dataIn.VelRange
138 self.dataOut.VelRange = self.dataIn.VelRange
139 else: self.dataOut.VelRange = None
139 else: self.dataOut.VelRange = None
140
140
141 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
141 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
142 self.dataOut.RadarConst = self.dataIn.RadarConst
142 self.dataOut.RadarConst = self.dataIn.RadarConst
143
143
144 if hasattr(self.dataIn, 'NPW'): #NPW
144 if hasattr(self.dataIn, 'NPW'): #NPW
145 self.dataOut.NPW = self.dataIn.NPW
145 self.dataOut.NPW = self.dataIn.NPW
146
146
147 if hasattr(self.dataIn, 'COFA'): #COFA
147 if hasattr(self.dataIn, 'COFA'): #COFA
148 self.dataOut.COFA = self.dataIn.COFA
148 self.dataOut.COFA = self.dataIn.COFA
149
149
150
150
151
151
152 #---------------------- Correlation Data ---------------------------
152 #---------------------- Correlation Data ---------------------------
153
153
154 if self.dataIn.type == "Correlation":
154 if self.dataIn.type == "Correlation":
155 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
155 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
156
156
157 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
157 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
158 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
158 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
159 self.dataOut.groupList = (acf_pairs, ccf_pairs)
159 self.dataOut.groupList = (acf_pairs, ccf_pairs)
160
160
161 self.dataOut.abscissaList = self.dataIn.lagRange
161 self.dataOut.abscissaList = self.dataIn.lagRange
162 self.dataOut.noise = self.dataIn.noise
162 self.dataOut.noise = self.dataIn.noise
163 self.dataOut.data_SNR = self.dataIn.SNR
163 self.dataOut.data_SNR = self.dataIn.SNR
164 self.dataOut.flagNoData = False
164 self.dataOut.flagNoData = False
165 self.dataOut.nAvg = self.dataIn.nAvg
165 self.dataOut.nAvg = self.dataIn.nAvg
166
166
167 #---------------------- Parameters Data ---------------------------
167 #---------------------- Parameters Data ---------------------------
168
168
169 if self.dataIn.type == "Parameters":
169 if self.dataIn.type == "Parameters":
170 self.dataOut.copy(self.dataIn)
170 self.dataOut.copy(self.dataIn)
171 self.dataOut.flagNoData = False
171 self.dataOut.flagNoData = False
172
172
173 return True
173 return True
174
174
175 self.__updateObjFromInput()
175 self.__updateObjFromInput()
176 self.dataOut.utctimeInit = self.dataIn.utctime
176 self.dataOut.utctimeInit = self.dataIn.utctime
177 self.dataOut.paramInterval = self.dataIn.timeInterval
177 self.dataOut.paramInterval = self.dataIn.timeInterval
178
178
179 return
179 return
180
180
181
181
182 def target(tups):
182 def target(tups):
183
183
184 obj, args = tups
184 obj, args = tups
185 #print 'TARGETTT', obj, args
185 #print 'TARGETTT', obj, args
186 return obj.FitGau(args)
186 return obj.FitGau(args)
187
187
188 class GaussianFit(Operation):
188 class GaussianFit(Operation):
189
189
190 '''
190 '''
191 Function that fit of one and two generalized gaussians (gg) based
191 Function that fit of one and two generalized gaussians (gg) based
192 on the PSD shape across an "power band" identified from a cumsum of
192 on the PSD shape across an "power band" identified from a cumsum of
193 the measured spectrum - noise.
193 the measured spectrum - noise.
194
194
195 Input:
195 Input:
196 self.dataOut.data_pre : SelfSpectra
196 self.dataOut.data_pre : SelfSpectra
197
197
198 Output:
198 Output:
199 self.dataOut.GauSPC : SPC_ch1, SPC_ch2
199 self.dataOut.GauSPC : SPC_ch1, SPC_ch2
200
200
201 '''
201 '''
202 def __init__(self, **kwargs):
202 def __init__(self, **kwargs):
203 Operation.__init__(self, **kwargs)
203 Operation.__init__(self, **kwargs)
204 self.i=0
204 self.i=0
205
205
206
206
207 def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
207 def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
208 """This routine will find a couple of generalized Gaussians to a power spectrum
208 """This routine will find a couple of generalized Gaussians to a power spectrum
209 input: spc
209 input: spc
210 output:
210 output:
211 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
211 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
212 """
212 """
213
213
214 self.spc = dataOut.data_pre[0].copy()
214 self.spc = dataOut.data_pre[0].copy()
215
215
216
216
217 print 'SelfSpectra Shape', numpy.asarray(self.spc).shape
217 print 'SelfSpectra Shape', numpy.asarray(self.spc).shape
218
218
219
219
220 #plt.figure(50)
220 #plt.figure(50)
221 #plt.subplot(121)
221 #plt.subplot(121)
222 #plt.plot(self.spc,'k',label='spc(66)')
222 #plt.plot(self.spc,'k',label='spc(66)')
223 #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
223 #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
224 #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
224 #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
225 #plt.plot(xFrec,FitGauss,'yo:',label='fit')
225 #plt.plot(xFrec,FitGauss,'yo:',label='fit')
226 #plt.legend()
226 #plt.legend()
227 #plt.title('DATOS A ALTURA DE 7500 METROS')
227 #plt.title('DATOS A ALTURA DE 7500 METROS')
228 #plt.show()
228 #plt.show()
229
229
230 self.Num_Hei = self.spc.shape[2]
230 self.Num_Hei = self.spc.shape[2]
231 #self.Num_Bin = len(self.spc)
231 #self.Num_Bin = len(self.spc)
232 self.Num_Bin = self.spc.shape[1]
232 self.Num_Bin = self.spc.shape[1]
233 self.Num_Chn = self.spc.shape[0]
233 self.Num_Chn = self.spc.shape[0]
234
234
235 Vrange = dataOut.abscissaList
235 Vrange = dataOut.abscissaList
236
236
237 #print 'self.spc2', numpy.asarray(self.spc).shape
237 #print 'self.spc2', numpy.asarray(self.spc).shape
238
238
239 GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei])
239 GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei])
240 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
240 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
241 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
241 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
242 SPC_ch1[:] = numpy.NaN
242 SPC_ch1[:] = numpy.NaN
243 SPC_ch2[:] = numpy.NaN
243 SPC_ch2[:] = numpy.NaN
244
244
245
245
246 start_time = time.time()
246 start_time = time.time()
247
247
248 noise_ = dataOut.spc_noise[0].copy()
248 noise_ = dataOut.spc_noise[0].copy()
249
249
250
250
251
251
252 pool = Pool(processes=self.Num_Chn)
252 pool = Pool(processes=self.Num_Chn)
253 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
253 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
254 objs = [self for __ in range(self.Num_Chn)]
254 objs = [self for __ in range(self.Num_Chn)]
255 attrs = zip(objs, args)
255 attrs = zip(objs, args)
256 gauSPC = pool.map(target, attrs)
256 gauSPC = pool.map(target, attrs)
257 dataOut.GauSPC = numpy.asarray(gauSPC)
257 dataOut.GauSPC = numpy.asarray(gauSPC)
258 # ret = []
258 # ret = []
259 # for n in range(self.Num_Chn):
259 # for n in range(self.Num_Chn):
260 # self.FitGau(args[n])
260 # self.FitGau(args[n])
261 # dataOut.GauSPC = ret
261 # dataOut.GauSPC = ret
262
262
263
263
264
264
265 # for ch in range(self.Num_Chn):
265 # for ch in range(self.Num_Chn):
266 #
266 #
267 # for ht in range(self.Num_Hei):
267 # for ht in range(self.Num_Hei):
268 # #print (numpy.asarray(self.spc).shape)
268 # #print (numpy.asarray(self.spc).shape)
269 # spc = numpy.asarray(self.spc)[ch,:,ht]
269 # spc = numpy.asarray(self.spc)[ch,:,ht]
270 #
270 #
271 # #############################################
271 # #############################################
272 # # normalizing spc and noise
272 # # normalizing spc and noise
273 # # This part differs from gg1
273 # # This part differs from gg1
274 # spc_norm_max = max(spc)
274 # spc_norm_max = max(spc)
275 # spc = spc / spc_norm_max
275 # spc = spc / spc_norm_max
276 # pnoise = pnoise / spc_norm_max
276 # pnoise = pnoise / spc_norm_max
277 # #############################################
277 # #############################################
278 #
278 #
279 # if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's
279 # if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's
280 # fatspectra=1.0
280 # fatspectra=1.0
281 # else:
281 # else:
282 # fatspectra=0.5
282 # fatspectra=0.5
283 #
283 #
284 # wnoise = noise_ / spc_norm_max
284 # wnoise = noise_ / spc_norm_max
285 # #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise
285 # #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise
286 # #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
286 # #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
287 # #if wnoise>1.1*pnoise: # to be tested later
287 # #if wnoise>1.1*pnoise: # to be tested later
288 # # wnoise=pnoise
288 # # wnoise=pnoise
289 # noisebl=wnoise*0.9; noisebh=wnoise*1.1
289 # noisebl=wnoise*0.9; noisebh=wnoise*1.1
290 # spc=spc-wnoise
290 # spc=spc-wnoise
291 #
291 #
292 # minx=numpy.argmin(spc)
292 # minx=numpy.argmin(spc)
293 # spcs=numpy.roll(spc,-minx)
293 # spcs=numpy.roll(spc,-minx)
294 # cum=numpy.cumsum(spcs)
294 # cum=numpy.cumsum(spcs)
295 # tot_noise=wnoise * self.Num_Bin #64;
295 # tot_noise=wnoise * self.Num_Bin #64;
296 # #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
296 # #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
297 # #snr=tot_signal/tot_noise
297 # #snr=tot_signal/tot_noise
298 # #snr=cum[-1]/tot_noise
298 # #snr=cum[-1]/tot_noise
299 #
299 #
300 # #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
300 # #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
301 #
301 #
302 # snr = sum(spcs)/tot_noise
302 # snr = sum(spcs)/tot_noise
303 # snrdB=10.*numpy.log10(snr)
303 # snrdB=10.*numpy.log10(snr)
304 #
304 #
305 # #if snrdB < -9 :
305 # #if snrdB < -9 :
306 # # snrdB = numpy.NaN
306 # # snrdB = numpy.NaN
307 # # continue
307 # # continue
308 #
308 #
309 # #print 'snr',snrdB # , sum(spcs) , tot_noise
309 # #print 'snr',snrdB # , sum(spcs) , tot_noise
310 #
310 #
311 #
311 #
312 # #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
312 # #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
313 # # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
313 # # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
314 #
314 #
315 # cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
315 # cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
316 # cumlo=cummax*epsi;
316 # cumlo=cummax*epsi;
317 # cumhi=cummax*(1-epsi)
317 # cumhi=cummax*(1-epsi)
318 # powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
318 # powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
319 #
319 #
320 # #if len(powerindex)==1:
320 # #if len(powerindex)==1:
321 # ##return [numpy.mod(powerindex[0]+minx,64),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
321 # ##return [numpy.mod(powerindex[0]+minx,64),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
322 # #return [numpy.mod(powerindex[0]+minx, self.Num_Bin ),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
322 # #return [numpy.mod(powerindex[0]+minx, self.Num_Bin ),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
323 # #elif len(powerindex)<4*fatspectra:
323 # #elif len(powerindex)<4*fatspectra:
324 # #return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
324 # #return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
325 #
325 #
326 # if len(powerindex) < 1:# case for powerindex 0
326 # if len(powerindex) < 1:# case for powerindex 0
327 # continue
327 # continue
328 # powerlo=powerindex[0]
328 # powerlo=powerindex[0]
329 # powerhi=powerindex[-1]
329 # powerhi=powerindex[-1]
330 # powerwidth=powerhi-powerlo
330 # powerwidth=powerhi-powerlo
331 #
331 #
332 # firstpeak=powerlo+powerwidth/10.# first gaussian energy location
332 # firstpeak=powerlo+powerwidth/10.# first gaussian energy location
333 # secondpeak=powerhi-powerwidth/10.#second gaussian energy location
333 # secondpeak=powerhi-powerwidth/10.#second gaussian energy location
334 # midpeak=(firstpeak+secondpeak)/2.
334 # midpeak=(firstpeak+secondpeak)/2.
335 # firstamp=spcs[int(firstpeak)]
335 # firstamp=spcs[int(firstpeak)]
336 # secondamp=spcs[int(secondpeak)]
336 # secondamp=spcs[int(secondpeak)]
337 # midamp=spcs[int(midpeak)]
337 # midamp=spcs[int(midpeak)]
338 # #x=numpy.spc.shape[1]
338 # #x=numpy.spc.shape[1]
339 #
339 #
340 # #x=numpy.arange(64)
340 # #x=numpy.arange(64)
341 # x=numpy.arange( self.Num_Bin )
341 # x=numpy.arange( self.Num_Bin )
342 # y_data=spc+wnoise
342 # y_data=spc+wnoise
343 #
343 #
344 # # single gaussian
344 # # single gaussian
345 # #shift0=numpy.mod(midpeak+minx,64)
345 # #shift0=numpy.mod(midpeak+minx,64)
346 # shift0=numpy.mod(midpeak+minx, self.Num_Bin )
346 # shift0=numpy.mod(midpeak+minx, self.Num_Bin )
347 # width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
347 # width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
348 # power0=2.
348 # power0=2.
349 # amplitude0=midamp
349 # amplitude0=midamp
350 # state0=[shift0,width0,amplitude0,power0,wnoise]
350 # state0=[shift0,width0,amplitude0,power0,wnoise]
351 # #bnds=((0,63),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
351 # #bnds=((0,63),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
352 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
352 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
353 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(0.1,0.5))
353 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(0.1,0.5))
354 # # bnds = range of fft, power width, amplitude, power, noise
354 # # bnds = range of fft, power width, amplitude, power, noise
355 # lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
355 # lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
356 #
356 #
357 # chiSq1=lsq1[1];
357 # chiSq1=lsq1[1];
358 # jack1= self.y_jacobian1(x,lsq1[0])
358 # jack1= self.y_jacobian1(x,lsq1[0])
359 #
359 #
360 #
360 #
361 # try:
361 # try:
362 # sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
362 # sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
363 # except:
363 # except:
364 # std1=32.; sigmas1=numpy.ones(5)
364 # std1=32.; sigmas1=numpy.ones(5)
365 # else:
365 # else:
366 # std1=sigmas1[0]
366 # std1=sigmas1[0]
367 #
367 #
368 #
368 #
369 # if fatspectra<1.0 and powerwidth<4:
369 # if fatspectra<1.0 and powerwidth<4:
370 # choice=0
370 # choice=0
371 # Amplitude0=lsq1[0][2]
371 # Amplitude0=lsq1[0][2]
372 # shift0=lsq1[0][0]
372 # shift0=lsq1[0][0]
373 # width0=lsq1[0][1]
373 # width0=lsq1[0][1]
374 # p0=lsq1[0][3]
374 # p0=lsq1[0][3]
375 # Amplitude1=0.
375 # Amplitude1=0.
376 # shift1=0.
376 # shift1=0.
377 # width1=0.
377 # width1=0.
378 # p1=0.
378 # p1=0.
379 # noise=lsq1[0][4]
379 # noise=lsq1[0][4]
380 # #return (numpy.array([shift0,width0,Amplitude0,p0]),
380 # #return (numpy.array([shift0,width0,Amplitude0,p0]),
381 # # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
381 # # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
382 #
382 #
383 # # two gaussians
383 # # two gaussians
384 # #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
384 # #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
385 # shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
385 # shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
386 # shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
386 # shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
387 # width0=powerwidth/6.;
387 # width0=powerwidth/6.;
388 # width1=width0
388 # width1=width0
389 # power0=2.;
389 # power0=2.;
390 # power1=power0
390 # power1=power0
391 # amplitude0=firstamp;
391 # amplitude0=firstamp;
392 # amplitude1=secondamp
392 # amplitude1=secondamp
393 # state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
393 # state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
394 # #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
394 # #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
395 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
395 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
396 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
396 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
397 #
397 #
398 # lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
398 # lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
399 #
399 #
400 #
400 #
401 # chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
401 # chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
402 #
402 #
403 #
403 #
404 # try:
404 # try:
405 # sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
405 # sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
406 # except:
406 # except:
407 # std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
407 # std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
408 # else:
408 # else:
409 # std2a=sigmas2[0]; std2b=sigmas2[4]
409 # std2a=sigmas2[0]; std2b=sigmas2[4]
410 #
410 #
411 #
411 #
412 #
412 #
413 # oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
413 # oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
414 #
414 #
415 # if snrdB>-9: # when SNR is strong pick the peak with least shift (LOS velocity) error
415 # if snrdB>-9: # when SNR is strong pick the peak with least shift (LOS velocity) error
416 # if oneG:
416 # if oneG:
417 # choice=0
417 # choice=0
418 # else:
418 # else:
419 # w1=lsq2[0][1]; w2=lsq2[0][5]
419 # w1=lsq2[0][1]; w2=lsq2[0][5]
420 # a1=lsq2[0][2]; a2=lsq2[0][6]
420 # a1=lsq2[0][2]; a2=lsq2[0][6]
421 # p1=lsq2[0][3]; p2=lsq2[0][7]
421 # p1=lsq2[0][3]; p2=lsq2[0][7]
422 # s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
422 # s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
423 # gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
423 # gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
424 #
424 #
425 # if gp1>gp2:
425 # if gp1>gp2:
426 # if a1>0.7*a2:
426 # if a1>0.7*a2:
427 # choice=1
427 # choice=1
428 # else:
428 # else:
429 # choice=2
429 # choice=2
430 # elif gp2>gp1:
430 # elif gp2>gp1:
431 # if a2>0.7*a1:
431 # if a2>0.7*a1:
432 # choice=2
432 # choice=2
433 # else:
433 # else:
434 # choice=1
434 # choice=1
435 # else:
435 # else:
436 # choice=numpy.argmax([a1,a2])+1
436 # choice=numpy.argmax([a1,a2])+1
437 # #else:
437 # #else:
438 # #choice=argmin([std2a,std2b])+1
438 # #choice=argmin([std2a,std2b])+1
439 #
439 #
440 # else: # with low SNR go to the most energetic peak
440 # else: # with low SNR go to the most energetic peak
441 # choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
441 # choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
442 #
442 #
443 # #print 'choice',choice
443 # #print 'choice',choice
444 #
444 #
445 # if choice==0: # pick the single gaussian fit
445 # if choice==0: # pick the single gaussian fit
446 # Amplitude0=lsq1[0][2]
446 # Amplitude0=lsq1[0][2]
447 # shift0=lsq1[0][0]
447 # shift0=lsq1[0][0]
448 # width0=lsq1[0][1]
448 # width0=lsq1[0][1]
449 # p0=lsq1[0][3]
449 # p0=lsq1[0][3]
450 # Amplitude1=0.
450 # Amplitude1=0.
451 # shift1=0.
451 # shift1=0.
452 # width1=0.
452 # width1=0.
453 # p1=0.
453 # p1=0.
454 # noise=lsq1[0][4]
454 # noise=lsq1[0][4]
455 # elif choice==1: # take the first one of the 2 gaussians fitted
455 # elif choice==1: # take the first one of the 2 gaussians fitted
456 # Amplitude0 = lsq2[0][2]
456 # Amplitude0 = lsq2[0][2]
457 # shift0 = lsq2[0][0]
457 # shift0 = lsq2[0][0]
458 # width0 = lsq2[0][1]
458 # width0 = lsq2[0][1]
459 # p0 = lsq2[0][3]
459 # p0 = lsq2[0][3]
460 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
460 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
461 # shift1 = lsq2[0][4] # This is 0 in gg1
461 # shift1 = lsq2[0][4] # This is 0 in gg1
462 # width1 = lsq2[0][5] # This is 0 in gg1
462 # width1 = lsq2[0][5] # This is 0 in gg1
463 # p1 = lsq2[0][7] # This is 0 in gg1
463 # p1 = lsq2[0][7] # This is 0 in gg1
464 # noise = lsq2[0][8]
464 # noise = lsq2[0][8]
465 # else: # the second one
465 # else: # the second one
466 # Amplitude0 = lsq2[0][6]
466 # Amplitude0 = lsq2[0][6]
467 # shift0 = lsq2[0][4]
467 # shift0 = lsq2[0][4]
468 # width0 = lsq2[0][5]
468 # width0 = lsq2[0][5]
469 # p0 = lsq2[0][7]
469 # p0 = lsq2[0][7]
470 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
470 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
471 # shift1 = lsq2[0][0] # This is 0 in gg1
471 # shift1 = lsq2[0][0] # This is 0 in gg1
472 # width1 = lsq2[0][1] # This is 0 in gg1
472 # width1 = lsq2[0][1] # This is 0 in gg1
473 # p1 = lsq2[0][3] # This is 0 in gg1
473 # p1 = lsq2[0][3] # This is 0 in gg1
474 # noise = lsq2[0][8]
474 # noise = lsq2[0][8]
475 #
475 #
476 # #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
476 # #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
477 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
477 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
478 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
478 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
479 # #print 'SPC_ch1.shape',SPC_ch1.shape
479 # #print 'SPC_ch1.shape',SPC_ch1.shape
480 # #print 'SPC_ch2.shape',SPC_ch2.shape
480 # #print 'SPC_ch2.shape',SPC_ch2.shape
481 # #dataOut.data_param = SPC_ch1
481 # #dataOut.data_param = SPC_ch1
482 # GauSPC[0] = SPC_ch1
482 # GauSPC[0] = SPC_ch1
483 # GauSPC[1] = SPC_ch2
483 # GauSPC[1] = SPC_ch2
484
484
485 # #plt.gcf().clear()
485 # #plt.gcf().clear()
486 # plt.figure(50+self.i)
486 # plt.figure(50+self.i)
487 # self.i=self.i+1
487 # self.i=self.i+1
488 # #plt.subplot(121)
488 # #plt.subplot(121)
489 # plt.plot(self.spc,'k')#,label='spc(66)')
489 # plt.plot(self.spc,'k')#,label='spc(66)')
490 # plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1')
490 # plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1')
491 # #plt.plot(SPC_ch2,'r')#,label='gg2')
491 # #plt.plot(SPC_ch2,'r')#,label='gg2')
492 # #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
492 # #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
493 # #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
493 # #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
494 # #plt.plot(xFrec,FitGauss,'yo:',label='fit')
494 # #plt.plot(xFrec,FitGauss,'yo:',label='fit')
495 # plt.legend()
495 # plt.legend()
496 # plt.title('DATOS A ALTURA DE 7500 METROS')
496 # plt.title('DATOS A ALTURA DE 7500 METROS')
497 # plt.show()
497 # plt.show()
498 # print 'shift0', shift0
498 # print 'shift0', shift0
499 # print 'Amplitude0', Amplitude0
499 # print 'Amplitude0', Amplitude0
500 # print 'width0', width0
500 # print 'width0', width0
501 # print 'p0', p0
501 # print 'p0', p0
502 # print '========================'
502 # print '========================'
503 # print 'shift1', shift1
503 # print 'shift1', shift1
504 # print 'Amplitude1', Amplitude1
504 # print 'Amplitude1', Amplitude1
505 # print 'width1', width1
505 # print 'width1', width1
506 # print 'p1', p1
506 # print 'p1', p1
507 # print 'noise', noise
507 # print 'noise', noise
508 # print 's_noise', wnoise
508 # print 's_noise', wnoise
509
509
510 print '========================================================'
510 print '========================================================'
511 print 'total_time: ', time.time()-start_time
511 print 'total_time: ', time.time()-start_time
512
512
513 # re-normalizing spc and noise
513 # re-normalizing spc and noise
514 # This part differs from gg1
514 # This part differs from gg1
515
515
516
516
517
517
518 ''' Parameters:
518 ''' Parameters:
519 1. Amplitude
519 1. Amplitude
520 2. Shift
520 2. Shift
521 3. Width
521 3. Width
522 4. Power
522 4. Power
523 '''
523 '''
524
524
525
525
526 ###############################################################################
526 ###############################################################################
527 def FitGau(self, X):
527 def FitGau(self, X):
528
528
529 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
529 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
530 #print 'VARSSSS', ch, pnoise, noise, num_intg
530 #print 'VARSSSS', ch, pnoise, noise, num_intg
531
531
532 #print 'HEIGHTS', self.Num_Hei
532 #print 'HEIGHTS', self.Num_Hei
533
533
534 GauSPC = []
534 GauSPC = []
535 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
535 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
536 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
536 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
537 SPC_ch1[:] = 0#numpy.NaN
537 SPC_ch1[:] = 0#numpy.NaN
538 SPC_ch2[:] = 0#numpy.NaN
538 SPC_ch2[:] = 0#numpy.NaN
539
539
540
540
541
541
542 for ht in range(self.Num_Hei):
542 for ht in range(self.Num_Hei):
543 #print (numpy.asarray(self.spc).shape)
543 #print (numpy.asarray(self.spc).shape)
544
544
545 #print 'TTTTT', ch , ht
545 #print 'TTTTT', ch , ht
546 #print self.spc.shape
546 #print self.spc.shape
547
547
548
548
549 spc = numpy.asarray(self.spc)[ch,:,ht]
549 spc = numpy.asarray(self.spc)[ch,:,ht]
550
550
551 #############################################
551 #############################################
552 # normalizing spc and noise
552 # normalizing spc and noise
553 # This part differs from gg1
553 # This part differs from gg1
554 spc_norm_max = max(spc)
554 spc_norm_max = max(spc)
555 spc = spc / spc_norm_max
555 spc = spc / spc_norm_max
556 pnoise = pnoise / spc_norm_max
556 pnoise = pnoise / spc_norm_max
557 #############################################
557 #############################################
558
558
559 fatspectra=1.0
559 fatspectra=1.0
560
560
561 wnoise = noise_ / spc_norm_max
561 wnoise = noise_ / spc_norm_max
562 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
562 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
563 #if wnoise>1.1*pnoise: # to be tested later
563 #if wnoise>1.1*pnoise: # to be tested later
564 # wnoise=pnoise
564 # wnoise=pnoise
565 noisebl=wnoise*0.9; noisebh=wnoise*1.1
565 noisebl=wnoise*0.9; noisebh=wnoise*1.1
566 spc=spc-wnoise
566 spc=spc-wnoise
567 # print 'wnoise', noise_[0], spc_norm_max, wnoise
567 # print 'wnoise', noise_[0], spc_norm_max, wnoise
568 minx=numpy.argmin(spc)
568 minx=numpy.argmin(spc)
569 spcs=numpy.roll(spc,-minx)
569 spcs=numpy.roll(spc,-minx)
570 cum=numpy.cumsum(spcs)
570 cum=numpy.cumsum(spcs)
571 tot_noise=wnoise * self.Num_Bin #64;
571 tot_noise=wnoise * self.Num_Bin #64;
572 #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
572 #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
573 #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
573 #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
574 #snr=tot_signal/tot_noise
574 #snr=tot_signal/tot_noise
575 #snr=cum[-1]/tot_noise
575 #snr=cum[-1]/tot_noise
576 snr = sum(spcs)/tot_noise
576 snr = sum(spcs)/tot_noise
577 snrdB=10.*numpy.log10(snr)
577 snrdB=10.*numpy.log10(snr)
578
578
579 if snrdB < SNRlimit :
579 if snrdB < SNRlimit :
580 snr = numpy.NaN
580 snr = numpy.NaN
581 SPC_ch1[:,ht] = 0#numpy.NaN
581 SPC_ch1[:,ht] = 0#numpy.NaN
582 SPC_ch1[:,ht] = 0#numpy.NaN
582 SPC_ch1[:,ht] = 0#numpy.NaN
583 GauSPC = (SPC_ch1,SPC_ch2)
583 GauSPC = (SPC_ch1,SPC_ch2)
584 continue
584 continue
585 #print 'snr',snrdB #, sum(spcs) , tot_noise
585 #print 'snr',snrdB #, sum(spcs) , tot_noise
586
586
587
587
588
588
589 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
589 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
590 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
590 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
591
591
592 cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
592 cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
593 cumlo=cummax*epsi;
593 cumlo=cummax*epsi;
594 cumhi=cummax*(1-epsi)
594 cumhi=cummax*(1-epsi)
595 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
595 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
596
596
597
597
598 if len(powerindex) < 1:# case for powerindex 0
598 if len(powerindex) < 1:# case for powerindex 0
599 continue
599 continue
600 powerlo=powerindex[0]
600 powerlo=powerindex[0]
601 powerhi=powerindex[-1]
601 powerhi=powerindex[-1]
602 powerwidth=powerhi-powerlo
602 powerwidth=powerhi-powerlo
603
603
604 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
604 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
605 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
605 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
606 midpeak=(firstpeak+secondpeak)/2.
606 midpeak=(firstpeak+secondpeak)/2.
607 firstamp=spcs[int(firstpeak)]
607 firstamp=spcs[int(firstpeak)]
608 secondamp=spcs[int(secondpeak)]
608 secondamp=spcs[int(secondpeak)]
609 midamp=spcs[int(midpeak)]
609 midamp=spcs[int(midpeak)]
610
610
611 x=numpy.arange( self.Num_Bin )
611 x=numpy.arange( self.Num_Bin )
612 y_data=spc+wnoise
612 y_data=spc+wnoise
613
613
614 # single gaussian
614 # single gaussian
615 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
615 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
616 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
616 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
617 power0=2.
617 power0=2.
618 amplitude0=midamp
618 amplitude0=midamp
619 state0=[shift0,width0,amplitude0,power0,wnoise]
619 state0=[shift0,width0,amplitude0,power0,wnoise]
620 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
620 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
621 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
621 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
622
622
623 chiSq1=lsq1[1];
623 chiSq1=lsq1[1];
624 jack1= self.y_jacobian1(x,lsq1[0])
624 jack1= self.y_jacobian1(x,lsq1[0])
625
625
626
626
627 try:
627 try:
628 sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
628 sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
629 except:
629 except:
630 std1=32.; sigmas1=numpy.ones(5)
630 std1=32.; sigmas1=numpy.ones(5)
631 else:
631 else:
632 std1=sigmas1[0]
632 std1=sigmas1[0]
633
633
634
634
635 if fatspectra<1.0 and powerwidth<4:
635 if fatspectra<1.0 and powerwidth<4:
636 choice=0
636 choice=0
637 Amplitude0=lsq1[0][2]
637 Amplitude0=lsq1[0][2]
638 shift0=lsq1[0][0]
638 shift0=lsq1[0][0]
639 width0=lsq1[0][1]
639 width0=lsq1[0][1]
640 p0=lsq1[0][3]
640 p0=lsq1[0][3]
641 Amplitude1=0.
641 Amplitude1=0.
642 shift1=0.
642 shift1=0.
643 width1=0.
643 width1=0.
644 p1=0.
644 p1=0.
645 noise=lsq1[0][4]
645 noise=lsq1[0][4]
646 #return (numpy.array([shift0,width0,Amplitude0,p0]),
646 #return (numpy.array([shift0,width0,Amplitude0,p0]),
647 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
647 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
648
648
649 # two gaussians
649 # two gaussians
650 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
650 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
651 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
651 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
652 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
652 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
653 width0=powerwidth/6.;
653 width0=powerwidth/6.;
654 width1=width0
654 width1=width0
655 power0=2.;
655 power0=2.;
656 power1=power0
656 power1=power0
657 amplitude0=firstamp;
657 amplitude0=firstamp;
658 amplitude1=secondamp
658 amplitude1=secondamp
659 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
659 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
660 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
660 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
661 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
661 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
662 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
662 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
663
663
664 lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
664 lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
665
665
666
666
667 chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
667 chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
668
668
669
669
670 try:
670 try:
671 sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
671 sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
672 except:
672 except:
673 std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
673 std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
674 else:
674 else:
675 std2a=sigmas2[0]; std2b=sigmas2[4]
675 std2a=sigmas2[0]; std2b=sigmas2[4]
676
676
677
677
678
678
679 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
679 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
680
680
681 if snrdB>-6: # when SNR is strong pick the peak with least shift (LOS velocity) error
681 if snrdB>-6: # when SNR is strong pick the peak with least shift (LOS velocity) error
682 if oneG:
682 if oneG:
683 choice=0
683 choice=0
684 else:
684 else:
685 w1=lsq2[0][1]; w2=lsq2[0][5]
685 w1=lsq2[0][1]; w2=lsq2[0][5]
686 a1=lsq2[0][2]; a2=lsq2[0][6]
686 a1=lsq2[0][2]; a2=lsq2[0][6]
687 p1=lsq2[0][3]; p2=lsq2[0][7]
687 p1=lsq2[0][3]; p2=lsq2[0][7]
688 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
688 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
689 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
689 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
690 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
690 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
691
691
692 if gp1>gp2:
692 if gp1>gp2:
693 if a1>0.7*a2:
693 if a1>0.7*a2:
694 choice=1
694 choice=1
695 else:
695 else:
696 choice=2
696 choice=2
697 elif gp2>gp1:
697 elif gp2>gp1:
698 if a2>0.7*a1:
698 if a2>0.7*a1:
699 choice=2
699 choice=2
700 else:
700 else:
701 choice=1
701 choice=1
702 else:
702 else:
703 choice=numpy.argmax([a1,a2])+1
703 choice=numpy.argmax([a1,a2])+1
704 #else:
704 #else:
705 #choice=argmin([std2a,std2b])+1
705 #choice=argmin([std2a,std2b])+1
706
706
707 else: # with low SNR go to the most energetic peak
707 else: # with low SNR go to the most energetic peak
708 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
708 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
709
709
710
710
711 shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
711 shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
712 shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
712 shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
713
713
714 max_vel = 20
714 max_vel = 20
715
715
716 #first peak will be 0, second peak will be 1
716 #first peak will be 0, second peak will be 1
717 if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range
717 if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range
718 shift0=lsq2[0][0]
718 shift0=lsq2[0][0]
719 width0=lsq2[0][1]
719 width0=lsq2[0][1]
720 Amplitude0=lsq2[0][2]
720 Amplitude0=lsq2[0][2]
721 p0=lsq2[0][3]
721 p0=lsq2[0][3]
722
722
723 shift1=lsq2[0][4]
723 shift1=lsq2[0][4]
724 width1=lsq2[0][5]
724 width1=lsq2[0][5]
725 Amplitude1=lsq2[0][6]
725 Amplitude1=lsq2[0][6]
726 p1=lsq2[0][7]
726 p1=lsq2[0][7]
727 noise=lsq2[0][8]
727 noise=lsq2[0][8]
728 else:
728 else:
729 shift1=lsq2[0][0]
729 shift1=lsq2[0][0]
730 width1=lsq2[0][1]
730 width1=lsq2[0][1]
731 Amplitude1=lsq2[0][2]
731 Amplitude1=lsq2[0][2]
732 p1=lsq2[0][3]
732 p1=lsq2[0][3]
733
733
734 shift0=lsq2[0][4]
734 shift0=lsq2[0][4]
735 width0=lsq2[0][5]
735 width0=lsq2[0][5]
736 Amplitude0=lsq2[0][6]
736 Amplitude0=lsq2[0][6]
737 p0=lsq2[0][7]
737 p0=lsq2[0][7]
738 noise=lsq2[0][8]
738 noise=lsq2[0][8]
739
739
740 if Amplitude0<0.1: # in case the peak is noise
740 if Amplitude0<0.1: # in case the peak is noise
741 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
741 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
742 if Amplitude1<0.1:
742 if Amplitude1<0.1:
743 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
743 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
744
744
745
745
746 # if choice==0: # pick the single gaussian fit
746 # if choice==0: # pick the single gaussian fit
747 # Amplitude0=lsq1[0][2]
747 # Amplitude0=lsq1[0][2]
748 # shift0=lsq1[0][0]
748 # shift0=lsq1[0][0]
749 # width0=lsq1[0][1]
749 # width0=lsq1[0][1]
750 # p0=lsq1[0][3]
750 # p0=lsq1[0][3]
751 # Amplitude1=0.
751 # Amplitude1=0.
752 # shift1=0.
752 # shift1=0.
753 # width1=0.
753 # width1=0.
754 # p1=0.
754 # p1=0.
755 # noise=lsq1[0][4]
755 # noise=lsq1[0][4]
756 # elif choice==1: # take the first one of the 2 gaussians fitted
756 # elif choice==1: # take the first one of the 2 gaussians fitted
757 # Amplitude0 = lsq2[0][2]
757 # Amplitude0 = lsq2[0][2]
758 # shift0 = lsq2[0][0]
758 # shift0 = lsq2[0][0]
759 # width0 = lsq2[0][1]
759 # width0 = lsq2[0][1]
760 # p0 = lsq2[0][3]
760 # p0 = lsq2[0][3]
761 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
761 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
762 # shift1 = lsq2[0][4] # This is 0 in gg1
762 # shift1 = lsq2[0][4] # This is 0 in gg1
763 # width1 = lsq2[0][5] # This is 0 in gg1
763 # width1 = lsq2[0][5] # This is 0 in gg1
764 # p1 = lsq2[0][7] # This is 0 in gg1
764 # p1 = lsq2[0][7] # This is 0 in gg1
765 # noise = lsq2[0][8]
765 # noise = lsq2[0][8]
766 # else: # the second one
766 # else: # the second one
767 # Amplitude0 = lsq2[0][6]
767 # Amplitude0 = lsq2[0][6]
768 # shift0 = lsq2[0][4]
768 # shift0 = lsq2[0][4]
769 # width0 = lsq2[0][5]
769 # width0 = lsq2[0][5]
770 # p0 = lsq2[0][7]
770 # p0 = lsq2[0][7]
771 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
771 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
772 # shift1 = lsq2[0][0] # This is 0 in gg1
772 # shift1 = lsq2[0][0] # This is 0 in gg1
773 # width1 = lsq2[0][1] # This is 0 in gg1
773 # width1 = lsq2[0][1] # This is 0 in gg1
774 # p1 = lsq2[0][3] # This is 0 in gg1
774 # p1 = lsq2[0][3] # This is 0 in gg1
775 # noise = lsq2[0][8]
775 # noise = lsq2[0][8]
776
776
777 #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
777 #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
778 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
778 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
779 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
779 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
780 #print 'SPC_ch1.shape',SPC_ch1.shape
780 #print 'SPC_ch1.shape',SPC_ch1.shape
781 #print 'SPC_ch2.shape',SPC_ch2.shape
781 #print 'SPC_ch2.shape',SPC_ch2.shape
782 #dataOut.data_param = SPC_ch1
782 #dataOut.data_param = SPC_ch1
783 GauSPC = (SPC_ch1,SPC_ch2)
783 GauSPC = (SPC_ch1,SPC_ch2)
784 #GauSPC[1] = SPC_ch2
784 #GauSPC[1] = SPC_ch2
785
785
786 # print 'shift0', shift0
786 # print 'shift0', shift0
787 # print 'Amplitude0', Amplitude0
787 # print 'Amplitude0', Amplitude0
788 # print 'width0', width0
788 # print 'width0', width0
789 # print 'p0', p0
789 # print 'p0', p0
790 # print '========================'
790 # print '========================'
791 # print 'shift1', shift1
791 # print 'shift1', shift1
792 # print 'Amplitude1', Amplitude1
792 # print 'Amplitude1', Amplitude1
793 # print 'width1', width1
793 # print 'width1', width1
794 # print 'p1', p1
794 # print 'p1', p1
795 # print 'noise', noise
795 # print 'noise', noise
796 # print 's_noise', wnoise
796 # print 's_noise', wnoise
797
797
798 return GauSPC
798 return GauSPC
799
799
800
800
801 def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination.
801 def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination.
802 y_model=self.y_model1(x,state)
802 y_model=self.y_model1(x,state)
803 s0,w0,a0,p0,n=state
803 s0,w0,a0,p0,n=state
804 e0=((x-s0)/w0)**2;
804 e0=((x-s0)/w0)**2;
805
805
806 e0u=((x-s0-self.Num_Bin)/w0)**2;
806 e0u=((x-s0-self.Num_Bin)/w0)**2;
807
807
808 e0d=((x-s0+self.Num_Bin)/w0)**2
808 e0d=((x-s0+self.Num_Bin)/w0)**2
809 m0=numpy.exp(-0.5*e0**(p0/2.));
809 m0=numpy.exp(-0.5*e0**(p0/2.));
810 m0u=numpy.exp(-0.5*e0u**(p0/2.));
810 m0u=numpy.exp(-0.5*e0u**(p0/2.));
811 m0d=numpy.exp(-0.5*e0d**(p0/2.))
811 m0d=numpy.exp(-0.5*e0d**(p0/2.))
812 JA=m0+m0u+m0d
812 JA=m0+m0u+m0d
813 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
813 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
814
814
815 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
815 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
816
816
817 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
817 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
818 jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model])
818 jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model])
819 return jack1.T
819 return jack1.T
820
820
821 def y_jacobian2(self,x,state):
821 def y_jacobian2(self,x,state):
822 y_model=self.y_model2(x,state)
822 y_model=self.y_model2(x,state)
823 s0,w0,a0,p0,s1,w1,a1,p1,n=state
823 s0,w0,a0,p0,s1,w1,a1,p1,n=state
824 e0=((x-s0)/w0)**2;
824 e0=((x-s0)/w0)**2;
825
825
826 e0u=((x-s0- self.Num_Bin )/w0)**2;
826 e0u=((x-s0- self.Num_Bin )/w0)**2;
827
827
828 e0d=((x-s0+ self.Num_Bin )/w0)**2
828 e0d=((x-s0+ self.Num_Bin )/w0)**2
829 e1=((x-s1)/w1)**2;
829 e1=((x-s1)/w1)**2;
830
830
831 e1u=((x-s1- self.Num_Bin )/w1)**2;
831 e1u=((x-s1- self.Num_Bin )/w1)**2;
832
832
833 e1d=((x-s1+ self.Num_Bin )/w1)**2
833 e1d=((x-s1+ self.Num_Bin )/w1)**2
834 m0=numpy.exp(-0.5*e0**(p0/2.));
834 m0=numpy.exp(-0.5*e0**(p0/2.));
835 m0u=numpy.exp(-0.5*e0u**(p0/2.));
835 m0u=numpy.exp(-0.5*e0u**(p0/2.));
836 m0d=numpy.exp(-0.5*e0d**(p0/2.))
836 m0d=numpy.exp(-0.5*e0d**(p0/2.))
837 m1=numpy.exp(-0.5*e1**(p1/2.));
837 m1=numpy.exp(-0.5*e1**(p1/2.));
838 m1u=numpy.exp(-0.5*e1u**(p1/2.));
838 m1u=numpy.exp(-0.5*e1u**(p1/2.));
839 m1d=numpy.exp(-0.5*e1d**(p1/2.))
839 m1d=numpy.exp(-0.5*e1d**(p1/2.))
840 JA=m0+m0u+m0d
840 JA=m0+m0u+m0d
841 JA1=m1+m1u+m1d
841 JA1=m1+m1u+m1d
842 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
842 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
843 JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d)
843 JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d)
844
844
845 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
845 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
846
846
847 JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)
847 JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)
848
848
849 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
849 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
850
850
851 JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2
851 JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2
852 jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model])
852 jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model])
853 return jack2.T
853 return jack2.T
854
854
855 def y_model1(self,x,state):
855 def y_model1(self,x,state):
856 shift0,width0,amplitude0,power0,noise=state
856 shift0,width0,amplitude0,power0,noise=state
857 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
857 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
858
858
859 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
859 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
860
860
861 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
861 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
862 return model0+model0u+model0d+noise
862 return model0+model0u+model0d+noise
863
863
864 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
864 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
865 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
865 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
866 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
866 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
867
867
868 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
868 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
869
869
870 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
870 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
871 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
871 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
872
872
873 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
873 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
874
874
875 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
875 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
876 return model0+model0u+model0d+model1+model1u+model1d+noise
876 return model0+model0u+model0d+model1+model1u+model1d+noise
877
877
878 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
878 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
879
879
880 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
880 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
881
881
882 def misfit2(self,state,y_data,x,num_intg):
882 def misfit2(self,state,y_data,x,num_intg):
883 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
883 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
884
884
885
885
886 class PrecipitationProc(Operation):
886 class PrecipitationProc(Operation):
887
887
888 '''
888 '''
889 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
889 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
890
890
891 Input:
891 Input:
892 self.dataOut.data_pre : SelfSpectra
892 self.dataOut.data_pre : SelfSpectra
893
893
894 Output:
894 Output:
895
895
896 self.dataOut.data_output : Reflectivity factor, rainfall Rate
896 self.dataOut.data_output : Reflectivity factor, rainfall Rate
897
897
898
898
899 Parameters affected:
899 Parameters affected:
900 '''
900 '''
901
901
902
902
903 def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None,
903 def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None,
904 tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None):
904 tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None):
905
905
906 self.spc = dataOut.data_pre[0].copy()
906 self.spc = dataOut.data_pre[0].copy()
907 self.Num_Hei = self.spc.shape[2]
907 self.Num_Hei = self.spc.shape[2]
908 self.Num_Bin = self.spc.shape[1]
908 self.Num_Bin = self.spc.shape[1]
909 self.Num_Chn = self.spc.shape[0]
909 self.Num_Chn = self.spc.shape[0]
910
910
911 Velrange = dataOut.abscissaList
911 Velrange = dataOut.abscissaList
912
912
913 if radar == "MIRA35C" :
913 if radar == "MIRA35C" :
914
914
915 Ze = self.dBZeMODE2(dataOut)
915 Ze = self.dBZeMODE2(dataOut)
916
916
917 else:
917 else:
918
918
919 self.Pt = Pt
919 self.Pt = Pt
920 self.Gt = Gt
920 self.Gt = Gt
921 self.Gr = Gr
921 self.Gr = Gr
922 self.Lambda = Lambda
922 self.Lambda = Lambda
923 self.aL = aL
923 self.aL = aL
924 self.tauW = tauW
924 self.tauW = tauW
925 self.ThetaT = ThetaT
925 self.ThetaT = ThetaT
926 self.ThetaR = ThetaR
926 self.ThetaR = ThetaR
927
927
928 RadarConstant = GetRadarConstant()
928 RadarConstant = GetRadarConstant()
929 SPCmean = numpy.mean(self.spc,0)
929 SPCmean = numpy.mean(self.spc,0)
930 ETA = numpy.zeros(self.Num_Hei)
930 ETA = numpy.zeros(self.Num_Hei)
931 Pr = numpy.sum(SPCmean,0)
931 Pr = numpy.sum(SPCmean,0)
932
932
933 #for R in range(self.Num_Hei):
933 #for R in range(self.Num_Hei):
934 # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
934 # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
935
935
936 D_range = numpy.zeros(self.Num_Hei)
936 D_range = numpy.zeros(self.Num_Hei)
937 EqSec = numpy.zeros(self.Num_Hei)
937 EqSec = numpy.zeros(self.Num_Hei)
938 del_V = numpy.zeros(self.Num_Hei)
938 del_V = numpy.zeros(self.Num_Hei)
939
939
940 for R in range(self.Num_Hei):
940 for R in range(self.Num_Hei):
941 ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
941 ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
942
942
943 h = R + Altitude #Range from ground to radar pulse altitude
943 h = R + Altitude #Range from ground to radar pulse altitude
944 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
944 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
945
945
946 D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity
946 D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity
947 SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma)
947 SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma)
948
948
949 N_dist[R] = ETA[R] / SIGMA[R]
949 N_dist[R] = ETA[R] / SIGMA[R]
950
950
951 Ze = (ETA * Lambda**4) / (numpy.pi * Km)
951 Ze = (ETA * Lambda**4) / (numpy.pi * Km)
952 Z = numpy.sum( N_dist * D_range**6 )
952 Z = numpy.sum( N_dist * D_range**6 )
953 RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate
953 RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate
954
954
955
955
956 RR = (Ze/200)**(1/1.6)
956 RR = (Ze/200)**(1/1.6)
957 dBRR = 10*numpy.log10(RR)
957 dBRR = 10*numpy.log10(RR)
958
958
959 dBZe = 10*numpy.log10(Ze)
959 dBZe = 10*numpy.log10(Ze)
960 dataOut.data_output = Ze
960 dataOut.data_output = Ze
961 dataOut.data_param = numpy.ones([2,self.Num_Hei])
961 dataOut.data_param = numpy.ones([2,self.Num_Hei])
962 dataOut.channelList = [0,1]
962 dataOut.channelList = [0,1]
963 print 'channelList', dataOut.channelList
963 print 'channelList', dataOut.channelList
964 dataOut.data_param[0]=dBZe
964 dataOut.data_param[0]=dBZe
965 dataOut.data_param[1]=dBRR
965 dataOut.data_param[1]=dBRR
966 print 'RR SHAPE', dBRR.shape
966 print 'RR SHAPE', dBRR.shape
967 print 'Ze SHAPE', dBZe.shape
967 print 'Ze SHAPE', dBZe.shape
968 print 'dataOut.data_param SHAPE', dataOut.data_param.shape
968 print 'dataOut.data_param SHAPE', dataOut.data_param.shape
969
969
970
970
971 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
971 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
972
972
973 NPW = dataOut.NPW
973 NPW = dataOut.NPW
974 COFA = dataOut.COFA
974 COFA = dataOut.COFA
975
975
976 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
976 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
977 RadarConst = dataOut.RadarConst
977 RadarConst = dataOut.RadarConst
978 #frequency = 34.85*10**9
978 #frequency = 34.85*10**9
979
979
980 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
980 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
981 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
981 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
982
982
983 ETA = numpy.sum(SNR,1)
983 ETA = numpy.sum(SNR,1)
984 print 'ETA' , ETA
984 print 'ETA' , ETA
985 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
985 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
986
986
987 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
987 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
988
988
989 for r in range(self.Num_Hei):
989 for r in range(self.Num_Hei):
990
990
991 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
991 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
992 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
992 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
993
993
994 return Ze
994 return Ze
995
995
996 def GetRadarConstant(self):
996 def GetRadarConstant(self):
997
997
998 """
998 """
999 Constants:
999 Constants:
1000
1000
1001 Pt: Transmission Power dB
1001 Pt: Transmission Power dB
1002 Gt: Transmission Gain dB
1002 Gt: Transmission Gain dB
1003 Gr: Reception Gain dB
1003 Gr: Reception Gain dB
1004 Lambda: Wavelenght m
1004 Lambda: Wavelenght m
1005 aL: Attenuation loses dB
1005 aL: Attenuation loses dB
1006 tauW: Width of transmission pulse s
1006 tauW: Width of transmission pulse s
1007 ThetaT: Transmission antenna bean angle rad
1007 ThetaT: Transmission antenna bean angle rad
1008 ThetaR: Reception antenna beam angle rad
1008 ThetaR: Reception antenna beam angle rad
1009
1009
1010 """
1010 """
1011 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
1011 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
1012 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
1012 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
1013 RadarConstant = Numerator / Denominator
1013 RadarConstant = Numerator / Denominator
1014
1014
1015 return RadarConstant
1015 return RadarConstant
1016
1016
1017
1017
1018
1018
1019 class FullSpectralAnalysis(Operation):
1019 class FullSpectralAnalysis(Operation):
1020
1020
1021 """
1021 """
1022 Function that implements Full Spectral Analisys technique.
1022 Function that implements Full Spectral Analisys technique.
1023
1023
1024 Input:
1024 Input:
1025 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
1025 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
1026 self.dataOut.groupList : Pairlist of channels
1026 self.dataOut.groupList : Pairlist of channels
1027 self.dataOut.ChanDist : Physical distance between receivers
1027 self.dataOut.ChanDist : Physical distance between receivers
1028
1028
1029
1029
1030 Output:
1030 Output:
1031
1031
1032 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
1032 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
1033
1033
1034
1034
1035 Parameters affected: Winds, height range, SNR
1035 Parameters affected: Winds, height range, SNR
1036
1036
1037 """
1037 """
1038 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7):
1038 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7):
1039
1039
1040 spc = dataOut.data_pre[0].copy()
1040 spc = dataOut.data_pre[0].copy()
1041 cspc = dataOut.data_pre[1].copy()
1041 cspc = dataOut.data_pre[1].copy()
1042
1042
1043 nChannel = spc.shape[0]
1043 nChannel = spc.shape[0]
1044 nProfiles = spc.shape[1]
1044 nProfiles = spc.shape[1]
1045 nHeights = spc.shape[2]
1045 nHeights = spc.shape[2]
1046
1046
1047 pairsList = dataOut.groupList
1047 pairsList = dataOut.groupList
1048 if dataOut.ChanDist is not None :
1048 if dataOut.ChanDist is not None :
1049 ChanDist = dataOut.ChanDist
1049 ChanDist = dataOut.ChanDist
1050 else:
1050 else:
1051 ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]])
1051 ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]])
1052
1052
1053 #print 'ChanDist', ChanDist
1053 #print 'ChanDist', ChanDist
1054
1054
1055 if dataOut.VelRange is not None:
1055 if dataOut.VelRange is not None:
1056 VelRange= dataOut.VelRange
1056 VelRange= dataOut.VelRange
1057 else:
1057 else:
1058 VelRange= dataOut.abscissaList
1058 VelRange= dataOut.abscissaList
1059
1059
1060 ySamples=numpy.ones([nChannel,nProfiles])
1060 ySamples=numpy.ones([nChannel,nProfiles])
1061 phase=numpy.ones([nChannel,nProfiles])
1061 phase=numpy.ones([nChannel,nProfiles])
1062 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
1062 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
1063 coherence=numpy.ones([nChannel,nProfiles])
1063 coherence=numpy.ones([nChannel,nProfiles])
1064 PhaseSlope=numpy.ones(nChannel)
1064 PhaseSlope=numpy.ones(nChannel)
1065 PhaseInter=numpy.ones(nChannel)
1065 PhaseInter=numpy.ones(nChannel)
1066 dataSNR = dataOut.data_SNR
1066 dataSNR = dataOut.data_SNR
1067
1067
1068
1068
1069
1069
1070 data = dataOut.data_pre
1070 data = dataOut.data_pre
1071 noise = dataOut.noise
1071 noise = dataOut.noise
1072 print 'noise',noise
1072 print 'noise',noise
1073 #SNRdB = 10*numpy.log10(dataOut.data_SNR)
1073 #SNRdB = 10*numpy.log10(dataOut.data_SNR)
1074
1074
1075 FirstMoment = numpy.average(dataOut.data_param[:,1,:],0)
1075 FirstMoment = numpy.average(dataOut.data_param[:,1,:],0)
1076 #SNRdBMean = []
1076 #SNRdBMean = []
1077
1077
1078
1078
1079 #for j in range(nHeights):
1079 #for j in range(nHeights):
1080 # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1080 # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1081 # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1081 # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1082
1082
1083 data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN
1083 data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN
1084
1084
1085 velocityX=[]
1085 velocityX=[]
1086 velocityY=[]
1086 velocityY=[]
1087 velocityV=[]
1087 velocityV=[]
1088
1088
1089 dbSNR = 10*numpy.log10(dataSNR)
1089 dbSNR = 10*numpy.log10(dataSNR)
1090 dbSNR = numpy.average(dbSNR,0)
1090 dbSNR = numpy.average(dbSNR,0)
1091 for Height in range(nHeights):
1091 for Height in range(nHeights):
1092
1092
1093 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1093 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1094
1094
1095 if abs(Vzon)<100. and abs(Vzon)> 0.:
1095 if abs(Vzon)<100. and abs(Vzon)> 0.:
1096 velocityX=numpy.append(velocityX, Vzon)#Vmag
1096 velocityX=numpy.append(velocityX, Vzon)#Vmag
1097
1097
1098 else:
1098 else:
1099 print 'Vzon',Vzon
1099 print 'Vzon',Vzon
1100 velocityX=numpy.append(velocityX, numpy.NaN)
1100 velocityX=numpy.append(velocityX, numpy.NaN)
1101
1101
1102 if abs(Vmer)<100. and abs(Vmer) > 0.:
1102 if abs(Vmer)<100. and abs(Vmer) > 0.:
1103 velocityY=numpy.append(velocityY, Vmer)#Vang
1103 velocityY=numpy.append(velocityY, Vmer)#Vang
1104
1104
1105 else:
1105 else:
1106 print 'Vmer',Vmer
1106 print 'Vmer',Vmer
1107 velocityY=numpy.append(velocityY, numpy.NaN)
1107 velocityY=numpy.append(velocityY, numpy.NaN)
1108
1108
1109 if dbSNR[Height] > SNRlimit:
1109 if dbSNR[Height] > SNRlimit:
1110 velocityV=numpy.append(velocityV, FirstMoment[Height])
1110 velocityV=numpy.append(velocityV, FirstMoment[Height])
1111 else:
1111 else:
1112 velocityV=numpy.append(velocityV, numpy.NaN)
1112 velocityV=numpy.append(velocityV, numpy.NaN)
1113 #FirstMoment[Height]= numpy.NaN
1113 #FirstMoment[Height]= numpy.NaN
1114 # if SNRdBMean[Height] <12:
1114 # if SNRdBMean[Height] <12:
1115 # FirstMoment[Height] = numpy.NaN
1115 # FirstMoment[Height] = numpy.NaN
1116 # velocityX[Height] = numpy.NaN
1116 # velocityX[Height] = numpy.NaN
1117 # velocityY[Height] = numpy.NaN
1117 # velocityY[Height] = numpy.NaN
1118
1118
1119
1119
1120 data_output[0]=numpy.array(velocityX)
1120 data_output[0]=numpy.array(velocityX)
1121 data_output[1]=numpy.array(velocityY)
1121 data_output[1]=numpy.array(velocityY)
1122 data_output[2]=-velocityV#FirstMoment
1122 data_output[2]=-velocityV#FirstMoment
1123
1123
1124 print ' '
1124 print ' '
1125 #print 'FirstMoment'
1125 #print 'FirstMoment'
1126 #print FirstMoment
1126 #print FirstMoment
1127 print 'velocityX',data_output[0]
1127 print 'velocityX',data_output[0]
1128 print ' '
1128 print ' '
1129 print 'velocityY',data_output[1]
1129 print 'velocityY',data_output[1]
1130 #print numpy.array(velocityY)
1130 #print numpy.array(velocityY)
1131 print ' '
1131 print ' '
1132 #print 'SNR'
1132 #print 'SNR'
1133 #print 10*numpy.log10(dataOut.data_SNR)
1133 #print 10*numpy.log10(dataOut.data_SNR)
1134 #print numpy.shape(10*numpy.log10(dataOut.data_SNR))
1134 #print numpy.shape(10*numpy.log10(dataOut.data_SNR))
1135 print ' '
1135 print ' '
1136
1136
1137
1137
1138 dataOut.data_output=data_output
1138 dataOut.data_output=data_output
1139 return
1139 return
1140
1140
1141
1141
1142 def moving_average(self,x, N=2):
1142 def moving_average(self,x, N=2):
1143 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
1143 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
1144
1144
1145 def gaus(self,xSamples,a,x0,sigma):
1145 def gaus(self,xSamples,a,x0,sigma):
1146 return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2))
1146 return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2))
1147
1147
1148 def Find(self,x,value):
1148 def Find(self,x,value):
1149 for index in range(len(x)):
1149 for index in range(len(x)):
1150 if x[index]==value:
1150 if x[index]==value:
1151 return index
1151 return index
1152
1152
1153 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit):
1153 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit):
1154
1154
1155 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
1155 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
1156 phase=numpy.ones([spc.shape[0],spc.shape[1]])
1156 phase=numpy.ones([spc.shape[0],spc.shape[1]])
1157 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
1157 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
1158 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
1158 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
1159 PhaseSlope=numpy.ones(spc.shape[0])
1159 PhaseSlope=numpy.ones(spc.shape[0])
1160 PhaseInter=numpy.ones(spc.shape[0])
1160 PhaseInter=numpy.ones(spc.shape[0])
1161 xFrec=VelRange
1161 xFrec=VelRange
1162
1162
1163 '''Getting Eij and Nij'''
1163 '''Getting Eij and Nij'''
1164
1164
1165 E01=ChanDist[0][0]
1165 E01=ChanDist[0][0]
1166 N01=ChanDist[0][1]
1166 N01=ChanDist[0][1]
1167
1167
1168 E02=ChanDist[1][0]
1168 E02=ChanDist[1][0]
1169 N02=ChanDist[1][1]
1169 N02=ChanDist[1][1]
1170
1170
1171 E12=ChanDist[2][0]
1171 E12=ChanDist[2][0]
1172 N12=ChanDist[2][1]
1172 N12=ChanDist[2][1]
1173
1173
1174 z = spc.copy()
1174 z = spc.copy()
1175 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1175 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1176
1176
1177 for i in range(spc.shape[0]):
1177 for i in range(spc.shape[0]):
1178
1178
1179 '''****** Line of Data SPC ******'''
1179 '''****** Line of Data SPC ******'''
1180 zline=z[i,:,Height]
1180 zline=z[i,:,Height]
1181
1181
1182 '''****** SPC is normalized ******'''
1182 '''****** SPC is normalized ******'''
1183 FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy())
1183 FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy())
1184 FactNorm= FactNorm/numpy.sum(FactNorm)
1184 FactNorm= FactNorm/numpy.sum(FactNorm)
1185
1185
1186 SmoothSPC=self.moving_average(FactNorm,N=3)
1186 SmoothSPC=self.moving_average(FactNorm,N=3)
1187
1187
1188 xSamples = ar(range(len(SmoothSPC)))
1188 xSamples = ar(range(len(SmoothSPC)))
1189 ySamples[i] = SmoothSPC
1189 ySamples[i] = SmoothSPC
1190
1190
1191 #dbSNR=10*numpy.log10(dataSNR)
1191 #dbSNR=10*numpy.log10(dataSNR)
1192 print ' '
1192 print ' '
1193 print ' '
1193 print ' '
1194 print ' '
1194 print ' '
1195
1195
1196 #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120]
1196 #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120]
1197 print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1197 print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1198 print 'noise',noise
1198 print 'noise',noise
1199 print 'zline',zline.shape, zline[0:20]
1199 print 'zline',zline.shape, zline[0:20]
1200 print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1200 print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1201 print 'FactNorm suma', numpy.sum(FactNorm)
1201 print 'FactNorm suma', numpy.sum(FactNorm)
1202
1202
1203 for i in range(spc.shape[0]):
1203 for i in range(spc.shape[0]):
1204
1204
1205 '''****** Line of Data CSPC ******'''
1205 '''****** Line of Data CSPC ******'''
1206 cspcLine=cspc[i,:,Height].copy()
1206 cspcLine=cspc[i,:,Height].copy()
1207
1207
1208 '''****** CSPC is normalized ******'''
1208 '''****** CSPC is normalized ******'''
1209 chan_index0 = pairsList[i][0]
1209 chan_index0 = pairsList[i][0]
1210 chan_index1 = pairsList[i][1]
1210 chan_index1 = pairsList[i][1]
1211 CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) #
1211 CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) #
1212
1212
1213 CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor)
1213 CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor)
1214
1214
1215 CSPCSamples[i] = CSPCNorm
1215 CSPCSamples[i] = CSPCNorm
1216 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
1216 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
1217
1217
1218 coherence[i]= self.moving_average(coherence[i],N=2)
1218 coherence[i]= self.moving_average(coherence[i],N=2)
1219
1219
1220 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
1220 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
1221
1221
1222 print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1222 print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1223 print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1223 print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1224 print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1224 print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1225 print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1225 print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1226 print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1226 print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1227 print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1227 print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1228
1228
1229 '''****** Getting fij width ******'''
1229 '''****** Getting fij width ******'''
1230
1230
1231 yMean=[]
1231 yMean=[]
1232 yMean2=[]
1232 yMean2=[]
1233
1233
1234 for j in range(len(ySamples[1])):
1234 for j in range(len(ySamples[1])):
1235 yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
1235 yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
1236
1236
1237 '''******* Getting fitting Gaussian ******'''
1237 '''******* Getting fitting Gaussian ******'''
1238 meanGauss=sum(xSamples*yMean) / len(xSamples)
1238 meanGauss=sum(xSamples*yMean) / len(xSamples)
1239 sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
1239 sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
1240
1240
1241 print '****************************'
1241 print '****************************'
1242 print 'len(xSamples): ',len(xSamples)
1242 print 'len(xSamples): ',len(xSamples)
1243 print 'yMean: ', yMean.shape, yMean[0:20]
1243 print 'yMean: ', yMean.shape, yMean[0:20]
1244 print 'ySamples', ySamples.shape, ySamples[0,0:20]
1244 print 'ySamples', ySamples.shape, ySamples[0,0:20]
1245 print 'xSamples: ',xSamples.shape, xSamples[0:20]
1245 print 'xSamples: ',xSamples.shape, xSamples[0:20]
1246
1246
1247 print 'meanGauss',meanGauss
1247 print 'meanGauss',meanGauss
1248 print 'sigma',sigma
1248 print 'sigma',sigma
1249
1249
1250 #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001):
1250 #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001):
1251 if dbSNR > SNRlimit :
1251 if dbSNR > SNRlimit :
1252 try:
1252 try:
1253 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
1253 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
1254
1254
1255 if numpy.amax(popt)>numpy.amax(yMean)*0.3:
1255 if numpy.amax(popt)>numpy.amax(yMean)*0.3:
1256 FitGauss=self.gaus(xSamples,*popt)
1256 FitGauss=self.gaus(xSamples,*popt)
1257
1257
1258 else:
1258 else:
1259 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1259 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1260 print 'Verificador: Dentro', Height
1260 print 'Verificador: Dentro', Height
1261 except :#RuntimeError:
1261 except :#RuntimeError:
1262 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1262 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1263
1263
1264
1264
1265 else:
1265 else:
1266 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1266 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1267
1267
1268 Maximun=numpy.amax(yMean)
1268 Maximun=numpy.amax(yMean)
1269 eMinus1=Maximun*numpy.exp(-1)#*0.8
1269 eMinus1=Maximun*numpy.exp(-1)#*0.8
1270
1270
1271 HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
1271 HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
1272 HalfWidth= xFrec[HWpos]
1272 HalfWidth= xFrec[HWpos]
1273 GCpos=self.Find(FitGauss, numpy.amax(FitGauss))
1273 GCpos=self.Find(FitGauss, numpy.amax(FitGauss))
1274 Vpos=self.Find(FactNorm, numpy.amax(FactNorm))
1274 Vpos=self.Find(FactNorm, numpy.amax(FactNorm))
1275
1275
1276 #Vpos=FirstMoment[]
1276 #Vpos=FirstMoment[]
1277
1277
1278 '''****** Getting Fij ******'''
1278 '''****** Getting Fij ******'''
1279
1279
1280 GaussCenter=xFrec[GCpos]
1280 GaussCenter=xFrec[GCpos]
1281 if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
1281 if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
1282 Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
1282 Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
1283 else:
1283 else:
1284 Fij=abs(GaussCenter-HalfWidth)+0.0000001
1284 Fij=abs(GaussCenter-HalfWidth)+0.0000001
1285
1285
1286 '''****** Getting Frecuency range of significant data ******'''
1286 '''****** Getting Frecuency range of significant data ******'''
1287
1287
1288 Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
1288 Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
1289
1289
1290 if Rangpos<GCpos:
1290 if Rangpos<GCpos:
1291 Range=numpy.array([Rangpos,2*GCpos-Rangpos])
1291 Range=numpy.array([Rangpos,2*GCpos-Rangpos])
1292 elif Rangpos< ( len(xFrec)- len(xFrec)*0.1):
1292 elif Rangpos< ( len(xFrec)- len(xFrec)*0.1):
1293 Range=numpy.array([2*GCpos-Rangpos,Rangpos])
1293 Range=numpy.array([2*GCpos-Rangpos,Rangpos])
1294 else:
1294 else:
1295 Range = numpy.array([0,0])
1295 Range = numpy.array([0,0])
1296
1296
1297 print ' '
1297 print ' '
1298 print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1298 print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1299 print 'Rangpos',Rangpos
1299 print 'Rangpos',Rangpos
1300 print 'RANGE: ', Range
1300 print 'RANGE: ', Range
1301 FrecRange=xFrec[Range[0]:Range[1]]
1301 FrecRange=xFrec[Range[0]:Range[1]]
1302
1302
1303 '''****** Getting SCPC Slope ******'''
1303 '''****** Getting SCPC Slope ******'''
1304
1304
1305 for i in range(spc.shape[0]):
1305 for i in range(spc.shape[0]):
1306
1306
1307 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.5:
1307 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.5:
1308 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1308 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1309
1309
1310 print 'FrecRange', len(FrecRange) , FrecRange
1310 print 'FrecRange', len(FrecRange) , FrecRange
1311 print 'PhaseRange', len(PhaseRange), PhaseRange
1311 print 'PhaseRange', len(PhaseRange), PhaseRange
1312 print ' '
1312 print ' '
1313 if len(FrecRange) == len(PhaseRange):
1313 if len(FrecRange) == len(PhaseRange):
1314 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1314 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1315 PhaseSlope[i]=slope
1315 PhaseSlope[i]=slope
1316 PhaseInter[i]=intercept
1316 PhaseInter[i]=intercept
1317 else:
1317 else:
1318 PhaseSlope[i]=0
1318 PhaseSlope[i]=0
1319 PhaseInter[i]=0
1319 PhaseInter[i]=0
1320 else:
1320 else:
1321 PhaseSlope[i]=0
1321 PhaseSlope[i]=0
1322 PhaseInter[i]=0
1322 PhaseInter[i]=0
1323
1323
1324 '''Getting constant C'''
1324 '''Getting constant C'''
1325 cC=(Fij*numpy.pi)**2
1325 cC=(Fij*numpy.pi)**2
1326
1326
1327 '''****** Getting constants F and G ******'''
1327 '''****** Getting constants F and G ******'''
1328 MijEijNij=numpy.array([[E02,N02], [E12,N12]])
1328 MijEijNij=numpy.array([[E02,N02], [E12,N12]])
1329 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1329 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1330 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1330 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1331 MijResults=numpy.array([MijResult0,MijResult1])
1331 MijResults=numpy.array([MijResult0,MijResult1])
1332 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1332 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1333
1333
1334 '''****** Getting constants A, B and H ******'''
1334 '''****** Getting constants A, B and H ******'''
1335 W01=numpy.amax(coherence[0])
1335 W01=numpy.amax(coherence[0])
1336 W02=numpy.amax(coherence[1])
1336 W02=numpy.amax(coherence[1])
1337 W12=numpy.amax(coherence[2])
1337 W12=numpy.amax(coherence[2])
1338
1338
1339 WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1339 WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1340 WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1340 WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1341 WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1341 WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1342
1342
1343 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1343 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1344
1344
1345 WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
1345 WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
1346 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1346 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1347
1347
1348 VxVy=numpy.array([[cA,cH],[cH,cB]])
1348 VxVy=numpy.array([[cA,cH],[cH,cB]])
1349
1349
1350 VxVyResults=numpy.array([-cF,-cG])
1350 VxVyResults=numpy.array([-cF,-cG])
1351 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1351 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1352
1352
1353 Vzon = Vy
1353 Vzon = Vy
1354 Vmer = Vx
1354 Vmer = Vx
1355 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1355 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1356 Vang=numpy.arctan2(Vmer,Vzon)
1356 Vang=numpy.arctan2(Vmer,Vzon)
1357 Vver=xFrec[Vpos]
1357 Vver=xFrec[Vpos]
1358 print 'vzon y vmer', Vzon, Vmer
1358 print 'vzon y vmer', Vzon, Vmer
1359 return Vzon, Vmer, Vver, GaussCenter
1359 return Vzon, Vmer, Vver, GaussCenter
1360
1360
1361 class SpectralMoments(Operation):
1361 class SpectralMoments(Operation):
1362
1362
1363 '''
1363 '''
1364 Function SpectralMoments()
1364 Function SpectralMoments()
1365
1365
1366 Calculates moments (power, mean, standard deviation) and SNR of the signal
1366 Calculates moments (power, mean, standard deviation) and SNR of the signal
1367
1367
1368 Type of dataIn: Spectra
1368 Type of dataIn: Spectra
1369
1369
1370 Configuration Parameters:
1370 Configuration Parameters:
1371
1371
1372 dirCosx : Cosine director in X axis
1372 dirCosx : Cosine director in X axis
1373 dirCosy : Cosine director in Y axis
1373 dirCosy : Cosine director in Y axis
1374
1374
1375 elevation :
1375 elevation :
1376 azimuth :
1376 azimuth :
1377
1377
1378 Input:
1378 Input:
1379 channelList : simple channel list to select e.g. [2,3,7]
1379 channelList : simple channel list to select e.g. [2,3,7]
1380 self.dataOut.data_pre : Spectral data
1380 self.dataOut.data_pre : Spectral data
1381 self.dataOut.abscissaList : List of frequencies
1381 self.dataOut.abscissaList : List of frequencies
1382 self.dataOut.noise : Noise level per channel
1382 self.dataOut.noise : Noise level per channel
1383
1383
1384 Affected:
1384 Affected:
1385 self.dataOut.data_param : Parameters per channel
1385 self.dataOut.data_param : Parameters per channel
1386 self.dataOut.data_SNR : SNR per channel
1386 self.dataOut.data_SNR : SNR per channel
1387
1387
1388 '''
1388 '''
1389
1389
1390 def run(self, dataOut):
1390 def run(self, dataOut):
1391
1391
1392 #dataOut.data_pre = dataOut.data_pre[0]
1392 #dataOut.data_pre = dataOut.data_pre[0]
1393 data = dataOut.data_pre[0]
1393 data = dataOut.data_pre[0]
1394 absc = dataOut.abscissaList[:-1]
1394 absc = dataOut.abscissaList[:-1]
1395 noise = dataOut.noise
1395 noise = dataOut.noise
1396 nChannel = data.shape[0]
1396 nChannel = data.shape[0]
1397 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1397 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1398
1398
1399 for ind in range(nChannel):
1399 for ind in range(nChannel):
1400 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1400 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1401
1401
1402 dataOut.data_param = data_param[:,1:,:]
1402 dataOut.data_param = data_param[:,1:,:]
1403 dataOut.data_SNR = data_param[:,0]
1403 dataOut.data_SNR = data_param[:,0]
1404 dataOut.data_DOP = data_param[:,1]
1405 dataOut.data_MEAN = data_param[:,2]
1406 dataOut.data_STD = data_param[:,3]
1404 return
1407 return
1405
1408
1406 def __calculateMoments(self, oldspec, oldfreq, n0,
1409 def __calculateMoments(self, oldspec, oldfreq, n0,
1407 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1410 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1408
1411
1409 if (nicoh == None): nicoh = 1
1412 if (nicoh == None): nicoh = 1
1410 if (graph == None): graph = 0
1413 if (graph == None): graph = 0
1411 if (smooth == None): smooth = 0
1414 if (smooth == None): smooth = 0
1412 elif (self.smooth < 3): smooth = 0
1415 elif (self.smooth < 3): smooth = 0
1413
1416
1414 if (type1 == None): type1 = 0
1417 if (type1 == None): type1 = 0
1415 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
1418 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
1416 if (snrth == None): snrth = -3
1419 if (snrth == None): snrth = -3
1417 if (dc == None): dc = 0
1420 if (dc == None): dc = 0
1418 if (aliasing == None): aliasing = 0
1421 if (aliasing == None): aliasing = 0
1419 if (oldfd == None): oldfd = 0
1422 if (oldfd == None): oldfd = 0
1420 if (wwauto == None): wwauto = 0
1423 if (wwauto == None): wwauto = 0
1421
1424
1422 if (n0 < 1.e-20): n0 = 1.e-20
1425 if (n0 < 1.e-20): n0 = 1.e-20
1423
1426
1424 freq = oldfreq
1427 freq = oldfreq
1425 vec_power = numpy.zeros(oldspec.shape[1])
1428 vec_power = numpy.zeros(oldspec.shape[1])
1426 vec_fd = numpy.zeros(oldspec.shape[1])
1429 vec_fd = numpy.zeros(oldspec.shape[1])
1427 vec_w = numpy.zeros(oldspec.shape[1])
1430 vec_w = numpy.zeros(oldspec.shape[1])
1428 vec_snr = numpy.zeros(oldspec.shape[1])
1431 vec_snr = numpy.zeros(oldspec.shape[1])
1429
1432
1430 for ind in range(oldspec.shape[1]):
1433 for ind in range(oldspec.shape[1]):
1431
1434
1432 spec = oldspec[:,ind]
1435 spec = oldspec[:,ind]
1433 aux = spec*fwindow
1436 aux = spec*fwindow
1434 max_spec = aux.max()
1437 max_spec = aux.max()
1435 m = list(aux).index(max_spec)
1438 m = list(aux).index(max_spec)
1436
1439
1437 #Smooth
1440 #Smooth
1438 if (smooth == 0): spec2 = spec
1441 if (smooth == 0): spec2 = spec
1439 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1442 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1440
1443
1441 # Calculo de Momentos
1444 # Calculo de Momentos
1442 bb = spec2[range(m,spec2.size)]
1445 bb = spec2[range(m,spec2.size)]
1443 bb = (bb<n0).nonzero()
1446 bb = (bb<n0).nonzero()
1444 bb = bb[0]
1447 bb = bb[0]
1445
1448
1446 ss = spec2[range(0,m + 1)]
1449 ss = spec2[range(0,m + 1)]
1447 ss = (ss<n0).nonzero()
1450 ss = (ss<n0).nonzero()
1448 ss = ss[0]
1451 ss = ss[0]
1449
1452
1450 if (bb.size == 0):
1453 if (bb.size == 0):
1451 bb0 = spec.size - 1 - m
1454 bb0 = spec.size - 1 - m
1452 else:
1455 else:
1453 bb0 = bb[0] - 1
1456 bb0 = bb[0] - 1
1454 if (bb0 < 0):
1457 if (bb0 < 0):
1455 bb0 = 0
1458 bb0 = 0
1456
1459
1457 if (ss.size == 0): ss1 = 1
1460 if (ss.size == 0): ss1 = 1
1458 else: ss1 = max(ss) + 1
1461 else: ss1 = max(ss) + 1
1459
1462
1460 if (ss1 > m): ss1 = m
1463 if (ss1 > m): ss1 = m
1461
1464
1462 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
1465 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
1463 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1466 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1464 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1467 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1465 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1468 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1466 snr = (spec2.mean()-n0)/n0
1469 snr = (spec2.mean()-n0)/n0
1467
1470
1468 if (snr < 1.e-20) :
1471 if (snr < 1.e-20) :
1469 snr = 1.e-20
1472 snr = 1.e-20
1470
1473
1471 vec_power[ind] = power
1474 vec_power[ind] = power
1472 vec_fd[ind] = fd
1475 vec_fd[ind] = fd
1473 vec_w[ind] = w
1476 vec_w[ind] = w
1474 vec_snr[ind] = snr
1477 vec_snr[ind] = snr
1475
1478
1476 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1479 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1477 return moments
1480 return moments
1478
1481
1479 #------------------ Get SA Parameters --------------------------
1482 #------------------ Get SA Parameters --------------------------
1480
1483
1481 def GetSAParameters(self):
1484 def GetSAParameters(self):
1482 #SA en frecuencia
1485 #SA en frecuencia
1483 pairslist = self.dataOut.groupList
1486 pairslist = self.dataOut.groupList
1484 num_pairs = len(pairslist)
1487 num_pairs = len(pairslist)
1485
1488
1486 vel = self.dataOut.abscissaList
1489 vel = self.dataOut.abscissaList
1487 spectra = self.dataOut.data_pre
1490 spectra = self.dataOut.data_pre
1488 cspectra = self.dataIn.data_cspc
1491 cspectra = self.dataIn.data_cspc
1489 delta_v = vel[1] - vel[0]
1492 delta_v = vel[1] - vel[0]
1490
1493
1491 #Calculating the power spectrum
1494 #Calculating the power spectrum
1492 spc_pow = numpy.sum(spectra, 3)*delta_v
1495 spc_pow = numpy.sum(spectra, 3)*delta_v
1493 #Normalizing Spectra
1496 #Normalizing Spectra
1494 norm_spectra = spectra/spc_pow
1497 norm_spectra = spectra/spc_pow
1495 #Calculating the norm_spectra at peak
1498 #Calculating the norm_spectra at peak
1496 max_spectra = numpy.max(norm_spectra, 3)
1499 max_spectra = numpy.max(norm_spectra, 3)
1497
1500
1498 #Normalizing Cross Spectra
1501 #Normalizing Cross Spectra
1499 norm_cspectra = numpy.zeros(cspectra.shape)
1502 norm_cspectra = numpy.zeros(cspectra.shape)
1500
1503
1501 for i in range(num_chan):
1504 for i in range(num_chan):
1502 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1505 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1503
1506
1504 max_cspectra = numpy.max(norm_cspectra,2)
1507 max_cspectra = numpy.max(norm_cspectra,2)
1505 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1508 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1506
1509
1507 for i in range(num_pairs):
1510 for i in range(num_pairs):
1508 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1511 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1509 #------------------- Get Lags ----------------------------------
1512 #------------------- Get Lags ----------------------------------
1510
1513
1511 class SALags(Operation):
1514 class SALags(Operation):
1512 '''
1515 '''
1513 Function GetMoments()
1516 Function GetMoments()
1514
1517
1515 Input:
1518 Input:
1516 self.dataOut.data_pre
1519 self.dataOut.data_pre
1517 self.dataOut.abscissaList
1520 self.dataOut.abscissaList
1518 self.dataOut.noise
1521 self.dataOut.noise
1519 self.dataOut.normFactor
1522 self.dataOut.normFactor
1520 self.dataOut.data_SNR
1523 self.dataOut.data_SNR
1521 self.dataOut.groupList
1524 self.dataOut.groupList
1522 self.dataOut.nChannels
1525 self.dataOut.nChannels
1523
1526
1524 Affected:
1527 Affected:
1525 self.dataOut.data_param
1528 self.dataOut.data_param
1526
1529
1527 '''
1530 '''
1528 def run(self, dataOut):
1531 def run(self, dataOut):
1529 data_acf = dataOut.data_pre[0]
1532 data_acf = dataOut.data_pre[0]
1530 data_ccf = dataOut.data_pre[1]
1533 data_ccf = dataOut.data_pre[1]
1531 normFactor_acf = dataOut.normFactor[0]
1534 normFactor_acf = dataOut.normFactor[0]
1532 normFactor_ccf = dataOut.normFactor[1]
1535 normFactor_ccf = dataOut.normFactor[1]
1533 pairs_acf = dataOut.groupList[0]
1536 pairs_acf = dataOut.groupList[0]
1534 pairs_ccf = dataOut.groupList[1]
1537 pairs_ccf = dataOut.groupList[1]
1535
1538
1536 nHeights = dataOut.nHeights
1539 nHeights = dataOut.nHeights
1537 absc = dataOut.abscissaList
1540 absc = dataOut.abscissaList
1538 noise = dataOut.noise
1541 noise = dataOut.noise
1539 SNR = dataOut.data_SNR
1542 SNR = dataOut.data_SNR
1540 nChannels = dataOut.nChannels
1543 nChannels = dataOut.nChannels
1541 # pairsList = dataOut.groupList
1544 # pairsList = dataOut.groupList
1542 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1545 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1543
1546
1544 for l in range(len(pairs_acf)):
1547 for l in range(len(pairs_acf)):
1545 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1548 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1546
1549
1547 for l in range(len(pairs_ccf)):
1550 for l in range(len(pairs_ccf)):
1548 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1551 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1549
1552
1550 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1553 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1551 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1554 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1552 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1555 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1553 return
1556 return
1554
1557
1555 # def __getPairsAutoCorr(self, pairsList, nChannels):
1558 # def __getPairsAutoCorr(self, pairsList, nChannels):
1556 #
1559 #
1557 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1560 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1558 #
1561 #
1559 # for l in range(len(pairsList)):
1562 # for l in range(len(pairsList)):
1560 # firstChannel = pairsList[l][0]
1563 # firstChannel = pairsList[l][0]
1561 # secondChannel = pairsList[l][1]
1564 # secondChannel = pairsList[l][1]
1562 #
1565 #
1563 # #Obteniendo pares de Autocorrelacion
1566 # #Obteniendo pares de Autocorrelacion
1564 # if firstChannel == secondChannel:
1567 # if firstChannel == secondChannel:
1565 # pairsAutoCorr[firstChannel] = int(l)
1568 # pairsAutoCorr[firstChannel] = int(l)
1566 #
1569 #
1567 # pairsAutoCorr = pairsAutoCorr.astype(int)
1570 # pairsAutoCorr = pairsAutoCorr.astype(int)
1568 #
1571 #
1569 # pairsCrossCorr = range(len(pairsList))
1572 # pairsCrossCorr = range(len(pairsList))
1570 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1573 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1571 #
1574 #
1572 # return pairsAutoCorr, pairsCrossCorr
1575 # return pairsAutoCorr, pairsCrossCorr
1573
1576
1574 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1577 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1575
1578
1576 lag0 = data_acf.shape[1]/2
1579 lag0 = data_acf.shape[1]/2
1577 #Funcion de Autocorrelacion
1580 #Funcion de Autocorrelacion
1578 mean_acf = stats.nanmean(data_acf, axis = 0)
1581 mean_acf = stats.nanmean(data_acf, axis = 0)
1579
1582
1580 #Obtencion Indice de TauCross
1583 #Obtencion Indice de TauCross
1581 ind_ccf = data_ccf.argmax(axis = 1)
1584 ind_ccf = data_ccf.argmax(axis = 1)
1582 #Obtencion Indice de TauAuto
1585 #Obtencion Indice de TauAuto
1583 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1586 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1584 ccf_lag0 = data_ccf[:,lag0,:]
1587 ccf_lag0 = data_ccf[:,lag0,:]
1585
1588
1586 for i in range(ccf_lag0.shape[0]):
1589 for i in range(ccf_lag0.shape[0]):
1587 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1590 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1588
1591
1589 #Obtencion de TauCross y TauAuto
1592 #Obtencion de TauCross y TauAuto
1590 tau_ccf = lagRange[ind_ccf]
1593 tau_ccf = lagRange[ind_ccf]
1591 tau_acf = lagRange[ind_acf]
1594 tau_acf = lagRange[ind_acf]
1592
1595
1593 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1596 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1594
1597
1595 tau_ccf[Nan1,Nan2] = numpy.nan
1598 tau_ccf[Nan1,Nan2] = numpy.nan
1596 tau_acf[Nan1,Nan2] = numpy.nan
1599 tau_acf[Nan1,Nan2] = numpy.nan
1597 tau = numpy.vstack((tau_ccf,tau_acf))
1600 tau = numpy.vstack((tau_ccf,tau_acf))
1598
1601
1599 return tau
1602 return tau
1600
1603
1601 def __calculateLag1Phase(self, data, lagTRange):
1604 def __calculateLag1Phase(self, data, lagTRange):
1602 data1 = stats.nanmean(data, axis = 0)
1605 data1 = stats.nanmean(data, axis = 0)
1603 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1606 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1604
1607
1605 phase = numpy.angle(data1[lag1,:])
1608 phase = numpy.angle(data1[lag1,:])
1606
1609
1607 return phase
1610 return phase
1608
1611
1609 class SpectralFitting(Operation):
1612 class SpectralFitting(Operation):
1610 '''
1613 '''
1611 Function GetMoments()
1614 Function GetMoments()
1612
1615
1613 Input:
1616 Input:
1614 Output:
1617 Output:
1615 Variables modified:
1618 Variables modified:
1616 '''
1619 '''
1617
1620
1618 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1621 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1619
1622
1620
1623
1621 if path != None:
1624 if path != None:
1622 sys.path.append(path)
1625 sys.path.append(path)
1623 self.dataOut.library = importlib.import_module(file)
1626 self.dataOut.library = importlib.import_module(file)
1624
1627
1625 #To be inserted as a parameter
1628 #To be inserted as a parameter
1626 groupArray = numpy.array(groupList)
1629 groupArray = numpy.array(groupList)
1627 # groupArray = numpy.array([[0,1],[2,3]])
1630 # groupArray = numpy.array([[0,1],[2,3]])
1628 self.dataOut.groupList = groupArray
1631 self.dataOut.groupList = groupArray
1629
1632
1630 nGroups = groupArray.shape[0]
1633 nGroups = groupArray.shape[0]
1631 nChannels = self.dataIn.nChannels
1634 nChannels = self.dataIn.nChannels
1632 nHeights=self.dataIn.heightList.size
1635 nHeights=self.dataIn.heightList.size
1633
1636
1634 #Parameters Array
1637 #Parameters Array
1635 self.dataOut.data_param = None
1638 self.dataOut.data_param = None
1636
1639
1637 #Set constants
1640 #Set constants
1638 constants = self.dataOut.library.setConstants(self.dataIn)
1641 constants = self.dataOut.library.setConstants(self.dataIn)
1639 self.dataOut.constants = constants
1642 self.dataOut.constants = constants
1640 M = self.dataIn.normFactor
1643 M = self.dataIn.normFactor
1641 N = self.dataIn.nFFTPoints
1644 N = self.dataIn.nFFTPoints
1642 ippSeconds = self.dataIn.ippSeconds
1645 ippSeconds = self.dataIn.ippSeconds
1643 K = self.dataIn.nIncohInt
1646 K = self.dataIn.nIncohInt
1644 pairsArray = numpy.array(self.dataIn.pairsList)
1647 pairsArray = numpy.array(self.dataIn.pairsList)
1645
1648
1646 #List of possible combinations
1649 #List of possible combinations
1647 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1650 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1648 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1651 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1649
1652
1650 if getSNR:
1653 if getSNR:
1651 listChannels = groupArray.reshape((groupArray.size))
1654 listChannels = groupArray.reshape((groupArray.size))
1652 listChannels.sort()
1655 listChannels.sort()
1653 noise = self.dataIn.getNoise()
1656 noise = self.dataIn.getNoise()
1654 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1657 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1655
1658
1656 for i in range(nGroups):
1659 for i in range(nGroups):
1657 coord = groupArray[i,:]
1660 coord = groupArray[i,:]
1658
1661
1659 #Input data array
1662 #Input data array
1660 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1663 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1661 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1664 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1662
1665
1663 #Cross Spectra data array for Covariance Matrixes
1666 #Cross Spectra data array for Covariance Matrixes
1664 ind = 0
1667 ind = 0
1665 for pairs in listComb:
1668 for pairs in listComb:
1666 pairsSel = numpy.array([coord[x],coord[y]])
1669 pairsSel = numpy.array([coord[x],coord[y]])
1667 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1670 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1668 ind += 1
1671 ind += 1
1669 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1672 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1670 dataCross = dataCross**2/K
1673 dataCross = dataCross**2/K
1671
1674
1672 for h in range(nHeights):
1675 for h in range(nHeights):
1673 # print self.dataOut.heightList[h]
1676 # print self.dataOut.heightList[h]
1674
1677
1675 #Input
1678 #Input
1676 d = data[:,h]
1679 d = data[:,h]
1677
1680
1678 #Covariance Matrix
1681 #Covariance Matrix
1679 D = numpy.diag(d**2/K)
1682 D = numpy.diag(d**2/K)
1680 ind = 0
1683 ind = 0
1681 for pairs in listComb:
1684 for pairs in listComb:
1682 #Coordinates in Covariance Matrix
1685 #Coordinates in Covariance Matrix
1683 x = pairs[0]
1686 x = pairs[0]
1684 y = pairs[1]
1687 y = pairs[1]
1685 #Channel Index
1688 #Channel Index
1686 S12 = dataCross[ind,:,h]
1689 S12 = dataCross[ind,:,h]
1687 D12 = numpy.diag(S12)
1690 D12 = numpy.diag(S12)
1688 #Completing Covariance Matrix with Cross Spectras
1691 #Completing Covariance Matrix with Cross Spectras
1689 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1692 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1690 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1693 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1691 ind += 1
1694 ind += 1
1692 Dinv=numpy.linalg.inv(D)
1695 Dinv=numpy.linalg.inv(D)
1693 L=numpy.linalg.cholesky(Dinv)
1696 L=numpy.linalg.cholesky(Dinv)
1694 LT=L.T
1697 LT=L.T
1695
1698
1696 dp = numpy.dot(LT,d)
1699 dp = numpy.dot(LT,d)
1697
1700
1698 #Initial values
1701 #Initial values
1699 data_spc = self.dataIn.data_spc[coord,:,h]
1702 data_spc = self.dataIn.data_spc[coord,:,h]
1700
1703
1701 if (h>0)and(error1[3]<5):
1704 if (h>0)and(error1[3]<5):
1702 p0 = self.dataOut.data_param[i,:,h-1]
1705 p0 = self.dataOut.data_param[i,:,h-1]
1703 else:
1706 else:
1704 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1707 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1705
1708
1706 try:
1709 try:
1707 #Least Squares
1710 #Least Squares
1708 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1711 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1709 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1712 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1710 #Chi square error
1713 #Chi square error
1711 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1714 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1712 #Error with Jacobian
1715 #Error with Jacobian
1713 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1716 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1714 except:
1717 except:
1715 minp = p0*numpy.nan
1718 minp = p0*numpy.nan
1716 error0 = numpy.nan
1719 error0 = numpy.nan
1717 error1 = p0*numpy.nan
1720 error1 = p0*numpy.nan
1718
1721
1719 #Save
1722 #Save
1720 if self.dataOut.data_param == None:
1723 if self.dataOut.data_param == None:
1721 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1724 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1722 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1725 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1723
1726
1724 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1727 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1725 self.dataOut.data_param[i,:,h] = minp
1728 self.dataOut.data_param[i,:,h] = minp
1726 return
1729 return
1727
1730
1728 def __residFunction(self, p, dp, LT, constants):
1731 def __residFunction(self, p, dp, LT, constants):
1729
1732
1730 fm = self.dataOut.library.modelFunction(p, constants)
1733 fm = self.dataOut.library.modelFunction(p, constants)
1731 fmp=numpy.dot(LT,fm)
1734 fmp=numpy.dot(LT,fm)
1732
1735
1733 return dp-fmp
1736 return dp-fmp
1734
1737
1735 def __getSNR(self, z, noise):
1738 def __getSNR(self, z, noise):
1736
1739
1737 avg = numpy.average(z, axis=1)
1740 avg = numpy.average(z, axis=1)
1738 SNR = (avg.T-noise)/noise
1741 SNR = (avg.T-noise)/noise
1739 SNR = SNR.T
1742 SNR = SNR.T
1740 return SNR
1743 return SNR
1741
1744
1742 def __chisq(p,chindex,hindex):
1745 def __chisq(p,chindex,hindex):
1743 #similar to Resid but calculates CHI**2
1746 #similar to Resid but calculates CHI**2
1744 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1747 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1745 dp=numpy.dot(LT,d)
1748 dp=numpy.dot(LT,d)
1746 fmp=numpy.dot(LT,fm)
1749 fmp=numpy.dot(LT,fm)
1747 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1750 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1748 return chisq
1751 return chisq
1749
1752
1750 class WindProfiler(Operation):
1753 class WindProfiler(Operation):
1751
1754
1752 __isConfig = False
1755 __isConfig = False
1753
1756
1754 __initime = None
1757 __initime = None
1755 __lastdatatime = None
1758 __lastdatatime = None
1756 __integrationtime = None
1759 __integrationtime = None
1757
1760
1758 __buffer = None
1761 __buffer = None
1759
1762
1760 __dataReady = False
1763 __dataReady = False
1761
1764
1762 __firstdata = None
1765 __firstdata = None
1763
1766
1764 n = None
1767 n = None
1765
1768
1766 def __init__(self):
1769 def __init__(self):
1767 Operation.__init__(self)
1770 Operation.__init__(self)
1768
1771
1769 def __calculateCosDir(self, elev, azim):
1772 def __calculateCosDir(self, elev, azim):
1770 zen = (90 - elev)*numpy.pi/180
1773 zen = (90 - elev)*numpy.pi/180
1771 azim = azim*numpy.pi/180
1774 azim = azim*numpy.pi/180
1772 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1775 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1773 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1776 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1774
1777
1775 signX = numpy.sign(numpy.cos(azim))
1778 signX = numpy.sign(numpy.cos(azim))
1776 signY = numpy.sign(numpy.sin(azim))
1779 signY = numpy.sign(numpy.sin(azim))
1777
1780
1778 cosDirX = numpy.copysign(cosDirX, signX)
1781 cosDirX = numpy.copysign(cosDirX, signX)
1779 cosDirY = numpy.copysign(cosDirY, signY)
1782 cosDirY = numpy.copysign(cosDirY, signY)
1780 return cosDirX, cosDirY
1783 return cosDirX, cosDirY
1781
1784
1782 def __calculateAngles(self, theta_x, theta_y, azimuth):
1785 def __calculateAngles(self, theta_x, theta_y, azimuth):
1783
1786
1784 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1787 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1785 zenith_arr = numpy.arccos(dir_cosw)
1788 zenith_arr = numpy.arccos(dir_cosw)
1786 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1789 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1787
1790
1788 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1791 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1789 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1792 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1790
1793
1791 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1794 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1792
1795
1793 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1796 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1794
1797
1795 #
1798 #
1796 if horOnly:
1799 if horOnly:
1797 A = numpy.c_[dir_cosu,dir_cosv]
1800 A = numpy.c_[dir_cosu,dir_cosv]
1798 else:
1801 else:
1799 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1802 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1800 A = numpy.asmatrix(A)
1803 A = numpy.asmatrix(A)
1801 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1804 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1802
1805
1803 return A1
1806 return A1
1804
1807
1805 def __correctValues(self, heiRang, phi, velRadial, SNR):
1808 def __correctValues(self, heiRang, phi, velRadial, SNR):
1806 listPhi = phi.tolist()
1809 listPhi = phi.tolist()
1807 maxid = listPhi.index(max(listPhi))
1810 maxid = listPhi.index(max(listPhi))
1808 minid = listPhi.index(min(listPhi))
1811 minid = listPhi.index(min(listPhi))
1809
1812
1810 rango = range(len(phi))
1813 rango = range(len(phi))
1811 # rango = numpy.delete(rango,maxid)
1814 # rango = numpy.delete(rango,maxid)
1812
1815
1813 heiRang1 = heiRang*math.cos(phi[maxid])
1816 heiRang1 = heiRang*math.cos(phi[maxid])
1814 heiRangAux = heiRang*math.cos(phi[minid])
1817 heiRangAux = heiRang*math.cos(phi[minid])
1815 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1818 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1816 heiRang1 = numpy.delete(heiRang1,indOut)
1819 heiRang1 = numpy.delete(heiRang1,indOut)
1817
1820
1818 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1821 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1819 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1822 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1820
1823
1821 for i in rango:
1824 for i in rango:
1822 x = heiRang*math.cos(phi[i])
1825 x = heiRang*math.cos(phi[i])
1823 y1 = velRadial[i,:]
1826 y1 = velRadial[i,:]
1824 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1827 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1825
1828
1826 x1 = heiRang1
1829 x1 = heiRang1
1827 y11 = f1(x1)
1830 y11 = f1(x1)
1828
1831
1829 y2 = SNR[i,:]
1832 y2 = SNR[i,:]
1830 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1833 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1831 y21 = f2(x1)
1834 y21 = f2(x1)
1832
1835
1833 velRadial1[i,:] = y11
1836 velRadial1[i,:] = y11
1834 SNR1[i,:] = y21
1837 SNR1[i,:] = y21
1835
1838
1836 return heiRang1, velRadial1, SNR1
1839 return heiRang1, velRadial1, SNR1
1837
1840
1838 def __calculateVelUVW(self, A, velRadial):
1841 def __calculateVelUVW(self, A, velRadial):
1839
1842
1840 #Operacion Matricial
1843 #Operacion Matricial
1841 # velUVW = numpy.zeros((velRadial.shape[1],3))
1844 # velUVW = numpy.zeros((velRadial.shape[1],3))
1842 # for ind in range(velRadial.shape[1]):
1845 # for ind in range(velRadial.shape[1]):
1843 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1846 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1844 # velUVW = velUVW.transpose()
1847 # velUVW = velUVW.transpose()
1845 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1848 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1846 velUVW[:,:] = numpy.dot(A,velRadial)
1849 velUVW[:,:] = numpy.dot(A,velRadial)
1847
1850
1848
1851
1849 return velUVW
1852 return velUVW
1850
1853
1851 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1854 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1852
1855
1853 def techniqueDBS(self, kwargs):
1856 def techniqueDBS(self, kwargs):
1854 """
1857 """
1855 Function that implements Doppler Beam Swinging (DBS) technique.
1858 Function that implements Doppler Beam Swinging (DBS) technique.
1856
1859
1857 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1860 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1858 Direction correction (if necessary), Ranges and SNR
1861 Direction correction (if necessary), Ranges and SNR
1859
1862
1860 Output: Winds estimation (Zonal, Meridional and Vertical)
1863 Output: Winds estimation (Zonal, Meridional and Vertical)
1861
1864
1862 Parameters affected: Winds, height range, SNR
1865 Parameters affected: Winds, height range, SNR
1863 """
1866 """
1864 velRadial0 = kwargs['velRadial']
1867 velRadial0 = kwargs['velRadial']
1865 heiRang = kwargs['heightList']
1868 heiRang = kwargs['heightList']
1866 SNR0 = kwargs['SNR']
1869 SNR0 = kwargs['SNR']
1867
1870
1868 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1871 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1869 theta_x = numpy.array(kwargs['dirCosx'])
1872 theta_x = numpy.array(kwargs['dirCosx'])
1870 theta_y = numpy.array(kwargs['dirCosy'])
1873 theta_y = numpy.array(kwargs['dirCosy'])
1871 else:
1874 else:
1872 elev = numpy.array(kwargs['elevation'])
1875 elev = numpy.array(kwargs['elevation'])
1873 azim = numpy.array(kwargs['azimuth'])
1876 azim = numpy.array(kwargs['azimuth'])
1874 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1877 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1875 azimuth = kwargs['correctAzimuth']
1878 azimuth = kwargs['correctAzimuth']
1876 if kwargs.has_key('horizontalOnly'):
1879 if kwargs.has_key('horizontalOnly'):
1877 horizontalOnly = kwargs['horizontalOnly']
1880 horizontalOnly = kwargs['horizontalOnly']
1878 else: horizontalOnly = False
1881 else: horizontalOnly = False
1879 if kwargs.has_key('correctFactor'):
1882 if kwargs.has_key('correctFactor'):
1880 correctFactor = kwargs['correctFactor']
1883 correctFactor = kwargs['correctFactor']
1881 else: correctFactor = 1
1884 else: correctFactor = 1
1882 if kwargs.has_key('channelList'):
1885 if kwargs.has_key('channelList'):
1883 channelList = kwargs['channelList']
1886 channelList = kwargs['channelList']
1884 if len(channelList) == 2:
1887 if len(channelList) == 2:
1885 horizontalOnly = True
1888 horizontalOnly = True
1886 arrayChannel = numpy.array(channelList)
1889 arrayChannel = numpy.array(channelList)
1887 param = param[arrayChannel,:,:]
1890 param = param[arrayChannel,:,:]
1888 theta_x = theta_x[arrayChannel]
1891 theta_x = theta_x[arrayChannel]
1889 theta_y = theta_y[arrayChannel]
1892 theta_y = theta_y[arrayChannel]
1890
1893
1891 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1894 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1892 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1895 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1893 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1896 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1894
1897
1895 #Calculo de Componentes de la velocidad con DBS
1898 #Calculo de Componentes de la velocidad con DBS
1896 winds = self.__calculateVelUVW(A,velRadial1)
1899 winds = self.__calculateVelUVW(A,velRadial1)
1897
1900
1898 return winds, heiRang1, SNR1
1901 return winds, heiRang1, SNR1
1899
1902
1900 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1903 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1901
1904
1902 nPairs = len(pairs_ccf)
1905 nPairs = len(pairs_ccf)
1903 posx = numpy.asarray(posx)
1906 posx = numpy.asarray(posx)
1904 posy = numpy.asarray(posy)
1907 posy = numpy.asarray(posy)
1905
1908
1906 #Rotacion Inversa para alinear con el azimuth
1909 #Rotacion Inversa para alinear con el azimuth
1907 if azimuth!= None:
1910 if azimuth!= None:
1908 azimuth = azimuth*math.pi/180
1911 azimuth = azimuth*math.pi/180
1909 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1912 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1910 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1913 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1911 else:
1914 else:
1912 posx1 = posx
1915 posx1 = posx
1913 posy1 = posy
1916 posy1 = posy
1914
1917
1915 #Calculo de Distancias
1918 #Calculo de Distancias
1916 distx = numpy.zeros(nPairs)
1919 distx = numpy.zeros(nPairs)
1917 disty = numpy.zeros(nPairs)
1920 disty = numpy.zeros(nPairs)
1918 dist = numpy.zeros(nPairs)
1921 dist = numpy.zeros(nPairs)
1919 ang = numpy.zeros(nPairs)
1922 ang = numpy.zeros(nPairs)
1920
1923
1921 for i in range(nPairs):
1924 for i in range(nPairs):
1922 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1925 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1923 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1926 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1924 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1927 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1925 ang[i] = numpy.arctan2(disty[i],distx[i])
1928 ang[i] = numpy.arctan2(disty[i],distx[i])
1926
1929
1927 return distx, disty, dist, ang
1930 return distx, disty, dist, ang
1928 #Calculo de Matrices
1931 #Calculo de Matrices
1929 # nPairs = len(pairs)
1932 # nPairs = len(pairs)
1930 # ang1 = numpy.zeros((nPairs, 2, 1))
1933 # ang1 = numpy.zeros((nPairs, 2, 1))
1931 # dist1 = numpy.zeros((nPairs, 2, 1))
1934 # dist1 = numpy.zeros((nPairs, 2, 1))
1932 #
1935 #
1933 # for j in range(nPairs):
1936 # for j in range(nPairs):
1934 # dist1[j,0,0] = dist[pairs[j][0]]
1937 # dist1[j,0,0] = dist[pairs[j][0]]
1935 # dist1[j,1,0] = dist[pairs[j][1]]
1938 # dist1[j,1,0] = dist[pairs[j][1]]
1936 # ang1[j,0,0] = ang[pairs[j][0]]
1939 # ang1[j,0,0] = ang[pairs[j][0]]
1937 # ang1[j,1,0] = ang[pairs[j][1]]
1940 # ang1[j,1,0] = ang[pairs[j][1]]
1938 #
1941 #
1939 # return distx,disty, dist1,ang1
1942 # return distx,disty, dist1,ang1
1940
1943
1941
1944
1942 def __calculateVelVer(self, phase, lagTRange, _lambda):
1945 def __calculateVelVer(self, phase, lagTRange, _lambda):
1943
1946
1944 Ts = lagTRange[1] - lagTRange[0]
1947 Ts = lagTRange[1] - lagTRange[0]
1945 velW = -_lambda*phase/(4*math.pi*Ts)
1948 velW = -_lambda*phase/(4*math.pi*Ts)
1946
1949
1947 return velW
1950 return velW
1948
1951
1949 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1952 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1950 nPairs = tau1.shape[0]
1953 nPairs = tau1.shape[0]
1951 nHeights = tau1.shape[1]
1954 nHeights = tau1.shape[1]
1952 vel = numpy.zeros((nPairs,3,nHeights))
1955 vel = numpy.zeros((nPairs,3,nHeights))
1953 dist1 = numpy.reshape(dist, (dist.size,1))
1956 dist1 = numpy.reshape(dist, (dist.size,1))
1954
1957
1955 angCos = numpy.cos(ang)
1958 angCos = numpy.cos(ang)
1956 angSin = numpy.sin(ang)
1959 angSin = numpy.sin(ang)
1957
1960
1958 vel0 = dist1*tau1/(2*tau2**2)
1961 vel0 = dist1*tau1/(2*tau2**2)
1959 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1962 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1960 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1963 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1961
1964
1962 ind = numpy.where(numpy.isinf(vel))
1965 ind = numpy.where(numpy.isinf(vel))
1963 vel[ind] = numpy.nan
1966 vel[ind] = numpy.nan
1964
1967
1965 return vel
1968 return vel
1966
1969
1967 # def __getPairsAutoCorr(self, pairsList, nChannels):
1970 # def __getPairsAutoCorr(self, pairsList, nChannels):
1968 #
1971 #
1969 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1972 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1970 #
1973 #
1971 # for l in range(len(pairsList)):
1974 # for l in range(len(pairsList)):
1972 # firstChannel = pairsList[l][0]
1975 # firstChannel = pairsList[l][0]
1973 # secondChannel = pairsList[l][1]
1976 # secondChannel = pairsList[l][1]
1974 #
1977 #
1975 # #Obteniendo pares de Autocorrelacion
1978 # #Obteniendo pares de Autocorrelacion
1976 # if firstChannel == secondChannel:
1979 # if firstChannel == secondChannel:
1977 # pairsAutoCorr[firstChannel] = int(l)
1980 # pairsAutoCorr[firstChannel] = int(l)
1978 #
1981 #
1979 # pairsAutoCorr = pairsAutoCorr.astype(int)
1982 # pairsAutoCorr = pairsAutoCorr.astype(int)
1980 #
1983 #
1981 # pairsCrossCorr = range(len(pairsList))
1984 # pairsCrossCorr = range(len(pairsList))
1982 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1985 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1983 #
1986 #
1984 # return pairsAutoCorr, pairsCrossCorr
1987 # return pairsAutoCorr, pairsCrossCorr
1985
1988
1986 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1989 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1987 def techniqueSA(self, kwargs):
1990 def techniqueSA(self, kwargs):
1988
1991
1989 """
1992 """
1990 Function that implements Spaced Antenna (SA) technique.
1993 Function that implements Spaced Antenna (SA) technique.
1991
1994
1992 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1995 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1993 Direction correction (if necessary), Ranges and SNR
1996 Direction correction (if necessary), Ranges and SNR
1994
1997
1995 Output: Winds estimation (Zonal, Meridional and Vertical)
1998 Output: Winds estimation (Zonal, Meridional and Vertical)
1996
1999
1997 Parameters affected: Winds
2000 Parameters affected: Winds
1998 """
2001 """
1999 position_x = kwargs['positionX']
2002 position_x = kwargs['positionX']
2000 position_y = kwargs['positionY']
2003 position_y = kwargs['positionY']
2001 azimuth = kwargs['azimuth']
2004 azimuth = kwargs['azimuth']
2002
2005
2003 if kwargs.has_key('correctFactor'):
2006 if kwargs.has_key('correctFactor'):
2004 correctFactor = kwargs['correctFactor']
2007 correctFactor = kwargs['correctFactor']
2005 else:
2008 else:
2006 correctFactor = 1
2009 correctFactor = 1
2007
2010
2008 groupList = kwargs['groupList']
2011 groupList = kwargs['groupList']
2009 pairs_ccf = groupList[1]
2012 pairs_ccf = groupList[1]
2010 tau = kwargs['tau']
2013 tau = kwargs['tau']
2011 _lambda = kwargs['_lambda']
2014 _lambda = kwargs['_lambda']
2012
2015
2013 #Cross Correlation pairs obtained
2016 #Cross Correlation pairs obtained
2014 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
2017 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
2015 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
2018 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
2016 # pairsSelArray = numpy.array(pairsSelected)
2019 # pairsSelArray = numpy.array(pairsSelected)
2017 # pairs = []
2020 # pairs = []
2018 #
2021 #
2019 # #Wind estimation pairs obtained
2022 # #Wind estimation pairs obtained
2020 # for i in range(pairsSelArray.shape[0]/2):
2023 # for i in range(pairsSelArray.shape[0]/2):
2021 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
2024 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
2022 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
2025 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
2023 # pairs.append((ind1,ind2))
2026 # pairs.append((ind1,ind2))
2024
2027
2025 indtau = tau.shape[0]/2
2028 indtau = tau.shape[0]/2
2026 tau1 = tau[:indtau,:]
2029 tau1 = tau[:indtau,:]
2027 tau2 = tau[indtau:-1,:]
2030 tau2 = tau[indtau:-1,:]
2028 # tau1 = tau1[pairs,:]
2031 # tau1 = tau1[pairs,:]
2029 # tau2 = tau2[pairs,:]
2032 # tau2 = tau2[pairs,:]
2030 phase1 = tau[-1,:]
2033 phase1 = tau[-1,:]
2031
2034
2032 #---------------------------------------------------------------------
2035 #---------------------------------------------------------------------
2033 #Metodo Directo
2036 #Metodo Directo
2034 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
2037 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
2035 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
2038 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
2036 winds = stats.nanmean(winds, axis=0)
2039 winds = stats.nanmean(winds, axis=0)
2037 #---------------------------------------------------------------------
2040 #---------------------------------------------------------------------
2038 #Metodo General
2041 #Metodo General
2039 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2042 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2040 # #Calculo Coeficientes de Funcion de Correlacion
2043 # #Calculo Coeficientes de Funcion de Correlacion
2041 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2044 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2042 # #Calculo de Velocidades
2045 # #Calculo de Velocidades
2043 # winds = self.calculateVelUV(F,G,A,B,H)
2046 # winds = self.calculateVelUV(F,G,A,B,H)
2044
2047
2045 #---------------------------------------------------------------------
2048 #---------------------------------------------------------------------
2046 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2049 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2047 winds = correctFactor*winds
2050 winds = correctFactor*winds
2048 return winds
2051 return winds
2049
2052
2050 def __checkTime(self, currentTime, paramInterval, outputInterval):
2053 def __checkTime(self, currentTime, paramInterval, outputInterval):
2051
2054
2052 dataTime = currentTime + paramInterval
2055 dataTime = currentTime + paramInterval
2053 deltaTime = dataTime - self.__initime
2056 deltaTime = dataTime - self.__initime
2054
2057
2055 if deltaTime >= outputInterval or deltaTime < 0:
2058 if deltaTime >= outputInterval or deltaTime < 0:
2056 self.__dataReady = True
2059 self.__dataReady = True
2057 return
2060 return
2058
2061
2059 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2062 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2060 '''
2063 '''
2061 Function that implements winds estimation technique with detected meteors.
2064 Function that implements winds estimation technique with detected meteors.
2062
2065
2063 Input: Detected meteors, Minimum meteor quantity to wind estimation
2066 Input: Detected meteors, Minimum meteor quantity to wind estimation
2064
2067
2065 Output: Winds estimation (Zonal and Meridional)
2068 Output: Winds estimation (Zonal and Meridional)
2066
2069
2067 Parameters affected: Winds
2070 Parameters affected: Winds
2068 '''
2071 '''
2069 # print arrayMeteor.shape
2072 # print arrayMeteor.shape
2070 #Settings
2073 #Settings
2071 nInt = (heightMax - heightMin)/2
2074 nInt = (heightMax - heightMin)/2
2072 # print nInt
2075 # print nInt
2073 nInt = int(nInt)
2076 nInt = int(nInt)
2074 # print nInt
2077 # print nInt
2075 winds = numpy.zeros((2,nInt))*numpy.nan
2078 winds = numpy.zeros((2,nInt))*numpy.nan
2076
2079
2077 #Filter errors
2080 #Filter errors
2078 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2081 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2079 finalMeteor = arrayMeteor[error,:]
2082 finalMeteor = arrayMeteor[error,:]
2080
2083
2081 #Meteor Histogram
2084 #Meteor Histogram
2082 finalHeights = finalMeteor[:,2]
2085 finalHeights = finalMeteor[:,2]
2083 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2086 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2084 nMeteorsPerI = hist[0]
2087 nMeteorsPerI = hist[0]
2085 heightPerI = hist[1]
2088 heightPerI = hist[1]
2086
2089
2087 #Sort of meteors
2090 #Sort of meteors
2088 indSort = finalHeights.argsort()
2091 indSort = finalHeights.argsort()
2089 finalMeteor2 = finalMeteor[indSort,:]
2092 finalMeteor2 = finalMeteor[indSort,:]
2090
2093
2091 # Calculating winds
2094 # Calculating winds
2092 ind1 = 0
2095 ind1 = 0
2093 ind2 = 0
2096 ind2 = 0
2094
2097
2095 for i in range(nInt):
2098 for i in range(nInt):
2096 nMet = nMeteorsPerI[i]
2099 nMet = nMeteorsPerI[i]
2097 ind1 = ind2
2100 ind1 = ind2
2098 ind2 = ind1 + nMet
2101 ind2 = ind1 + nMet
2099
2102
2100 meteorAux = finalMeteor2[ind1:ind2,:]
2103 meteorAux = finalMeteor2[ind1:ind2,:]
2101
2104
2102 if meteorAux.shape[0] >= meteorThresh:
2105 if meteorAux.shape[0] >= meteorThresh:
2103 vel = meteorAux[:, 6]
2106 vel = meteorAux[:, 6]
2104 zen = meteorAux[:, 4]*numpy.pi/180
2107 zen = meteorAux[:, 4]*numpy.pi/180
2105 azim = meteorAux[:, 3]*numpy.pi/180
2108 azim = meteorAux[:, 3]*numpy.pi/180
2106
2109
2107 n = numpy.cos(zen)
2110 n = numpy.cos(zen)
2108 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2111 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2109 # l = m*numpy.tan(azim)
2112 # l = m*numpy.tan(azim)
2110 l = numpy.sin(zen)*numpy.sin(azim)
2113 l = numpy.sin(zen)*numpy.sin(azim)
2111 m = numpy.sin(zen)*numpy.cos(azim)
2114 m = numpy.sin(zen)*numpy.cos(azim)
2112
2115
2113 A = numpy.vstack((l, m)).transpose()
2116 A = numpy.vstack((l, m)).transpose()
2114 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2117 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2115 windsAux = numpy.dot(A1, vel)
2118 windsAux = numpy.dot(A1, vel)
2116
2119
2117 winds[0,i] = windsAux[0]
2120 winds[0,i] = windsAux[0]
2118 winds[1,i] = windsAux[1]
2121 winds[1,i] = windsAux[1]
2119
2122
2120 return winds, heightPerI[:-1]
2123 return winds, heightPerI[:-1]
2121
2124
2122 def techniqueNSM_SA(self, **kwargs):
2125 def techniqueNSM_SA(self, **kwargs):
2123 metArray = kwargs['metArray']
2126 metArray = kwargs['metArray']
2124 heightList = kwargs['heightList']
2127 heightList = kwargs['heightList']
2125 timeList = kwargs['timeList']
2128 timeList = kwargs['timeList']
2126
2129
2127 rx_location = kwargs['rx_location']
2130 rx_location = kwargs['rx_location']
2128 groupList = kwargs['groupList']
2131 groupList = kwargs['groupList']
2129 azimuth = kwargs['azimuth']
2132 azimuth = kwargs['azimuth']
2130 dfactor = kwargs['dfactor']
2133 dfactor = kwargs['dfactor']
2131 k = kwargs['k']
2134 k = kwargs['k']
2132
2135
2133 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2136 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2134 d = dist*dfactor
2137 d = dist*dfactor
2135 #Phase calculation
2138 #Phase calculation
2136 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2139 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2137
2140
2138 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2141 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2139
2142
2140 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2143 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2141 azimuth1 = azimuth1*numpy.pi/180
2144 azimuth1 = azimuth1*numpy.pi/180
2142
2145
2143 for i in range(heightList.size):
2146 for i in range(heightList.size):
2144 h = heightList[i]
2147 h = heightList[i]
2145 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2148 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2146 metHeight = metArray1[indH,:]
2149 metHeight = metArray1[indH,:]
2147 if metHeight.shape[0] >= 2:
2150 if metHeight.shape[0] >= 2:
2148 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2151 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2149 iazim = metHeight[:,1].astype(int)
2152 iazim = metHeight[:,1].astype(int)
2150 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2153 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2151 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2154 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2152 A = numpy.asmatrix(A)
2155 A = numpy.asmatrix(A)
2153 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2156 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2154 velHor = numpy.dot(A1,velAux)
2157 velHor = numpy.dot(A1,velAux)
2155
2158
2156 velEst[i,:] = numpy.squeeze(velHor)
2159 velEst[i,:] = numpy.squeeze(velHor)
2157 return velEst
2160 return velEst
2158
2161
2159 def __getPhaseSlope(self, metArray, heightList, timeList):
2162 def __getPhaseSlope(self, metArray, heightList, timeList):
2160 meteorList = []
2163 meteorList = []
2161 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2164 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2162 #Putting back together the meteor matrix
2165 #Putting back together the meteor matrix
2163 utctime = metArray[:,0]
2166 utctime = metArray[:,0]
2164 uniqueTime = numpy.unique(utctime)
2167 uniqueTime = numpy.unique(utctime)
2165
2168
2166 phaseDerThresh = 0.5
2169 phaseDerThresh = 0.5
2167 ippSeconds = timeList[1] - timeList[0]
2170 ippSeconds = timeList[1] - timeList[0]
2168 sec = numpy.where(timeList>1)[0][0]
2171 sec = numpy.where(timeList>1)[0][0]
2169 nPairs = metArray.shape[1] - 6
2172 nPairs = metArray.shape[1] - 6
2170 nHeights = len(heightList)
2173 nHeights = len(heightList)
2171
2174
2172 for t in uniqueTime:
2175 for t in uniqueTime:
2173 metArray1 = metArray[utctime==t,:]
2176 metArray1 = metArray[utctime==t,:]
2174 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2177 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2175 tmet = metArray1[:,1].astype(int)
2178 tmet = metArray1[:,1].astype(int)
2176 hmet = metArray1[:,2].astype(int)
2179 hmet = metArray1[:,2].astype(int)
2177
2180
2178 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2181 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2179 metPhase[:,:] = numpy.nan
2182 metPhase[:,:] = numpy.nan
2180 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2183 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2181
2184
2182 #Delete short trails
2185 #Delete short trails
2183 metBool = ~numpy.isnan(metPhase[0,:,:])
2186 metBool = ~numpy.isnan(metPhase[0,:,:])
2184 heightVect = numpy.sum(metBool, axis = 1)
2187 heightVect = numpy.sum(metBool, axis = 1)
2185 metBool[heightVect<sec,:] = False
2188 metBool[heightVect<sec,:] = False
2186 metPhase[:,heightVect<sec,:] = numpy.nan
2189 metPhase[:,heightVect<sec,:] = numpy.nan
2187
2190
2188 #Derivative
2191 #Derivative
2189 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2192 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2190 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2193 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2191 metPhase[phDerAux] = numpy.nan
2194 metPhase[phDerAux] = numpy.nan
2192
2195
2193 #--------------------------METEOR DETECTION -----------------------------------------
2196 #--------------------------METEOR DETECTION -----------------------------------------
2194 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2197 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2195
2198
2196 for p in numpy.arange(nPairs):
2199 for p in numpy.arange(nPairs):
2197 phase = metPhase[p,:,:]
2200 phase = metPhase[p,:,:]
2198 phDer = metDer[p,:,:]
2201 phDer = metDer[p,:,:]
2199
2202
2200 for h in indMet:
2203 for h in indMet:
2201 height = heightList[h]
2204 height = heightList[h]
2202 phase1 = phase[h,:] #82
2205 phase1 = phase[h,:] #82
2203 phDer1 = phDer[h,:]
2206 phDer1 = phDer[h,:]
2204
2207
2205 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2208 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2206
2209
2207 indValid = numpy.where(~numpy.isnan(phase1))[0]
2210 indValid = numpy.where(~numpy.isnan(phase1))[0]
2208 initMet = indValid[0]
2211 initMet = indValid[0]
2209 endMet = 0
2212 endMet = 0
2210
2213
2211 for i in range(len(indValid)-1):
2214 for i in range(len(indValid)-1):
2212
2215
2213 #Time difference
2216 #Time difference
2214 inow = indValid[i]
2217 inow = indValid[i]
2215 inext = indValid[i+1]
2218 inext = indValid[i+1]
2216 idiff = inext - inow
2219 idiff = inext - inow
2217 #Phase difference
2220 #Phase difference
2218 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2221 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2219
2222
2220 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2223 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2221 sizeTrail = inow - initMet + 1
2224 sizeTrail = inow - initMet + 1
2222 if sizeTrail>3*sec: #Too short meteors
2225 if sizeTrail>3*sec: #Too short meteors
2223 x = numpy.arange(initMet,inow+1)*ippSeconds
2226 x = numpy.arange(initMet,inow+1)*ippSeconds
2224 y = phase1[initMet:inow+1]
2227 y = phase1[initMet:inow+1]
2225 ynnan = ~numpy.isnan(y)
2228 ynnan = ~numpy.isnan(y)
2226 x = x[ynnan]
2229 x = x[ynnan]
2227 y = y[ynnan]
2230 y = y[ynnan]
2228 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2231 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2229 ylin = x*slope + intercept
2232 ylin = x*slope + intercept
2230 rsq = r_value**2
2233 rsq = r_value**2
2231 if rsq > 0.5:
2234 if rsq > 0.5:
2232 vel = slope#*height*1000/(k*d)
2235 vel = slope#*height*1000/(k*d)
2233 estAux = numpy.array([utctime,p,height, vel, rsq])
2236 estAux = numpy.array([utctime,p,height, vel, rsq])
2234 meteorList.append(estAux)
2237 meteorList.append(estAux)
2235 initMet = inext
2238 initMet = inext
2236 metArray2 = numpy.array(meteorList)
2239 metArray2 = numpy.array(meteorList)
2237
2240
2238 return metArray2
2241 return metArray2
2239
2242
2240 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2243 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2241
2244
2242 azimuth1 = numpy.zeros(len(pairslist))
2245 azimuth1 = numpy.zeros(len(pairslist))
2243 dist = numpy.zeros(len(pairslist))
2246 dist = numpy.zeros(len(pairslist))
2244
2247
2245 for i in range(len(rx_location)):
2248 for i in range(len(rx_location)):
2246 ch0 = pairslist[i][0]
2249 ch0 = pairslist[i][0]
2247 ch1 = pairslist[i][1]
2250 ch1 = pairslist[i][1]
2248
2251
2249 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2252 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2250 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2253 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2251 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2254 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2252 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2255 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2253
2256
2254 azimuth1 -= azimuth0
2257 azimuth1 -= azimuth0
2255 return azimuth1, dist
2258 return azimuth1, dist
2256
2259
2257 def techniqueNSM_DBS(self, **kwargs):
2260 def techniqueNSM_DBS(self, **kwargs):
2258 metArray = kwargs['metArray']
2261 metArray = kwargs['metArray']
2259 heightList = kwargs['heightList']
2262 heightList = kwargs['heightList']
2260 timeList = kwargs['timeList']
2263 timeList = kwargs['timeList']
2261 azimuth = kwargs['azimuth']
2264 azimuth = kwargs['azimuth']
2262 theta_x = numpy.array(kwargs['theta_x'])
2265 theta_x = numpy.array(kwargs['theta_x'])
2263 theta_y = numpy.array(kwargs['theta_y'])
2266 theta_y = numpy.array(kwargs['theta_y'])
2264
2267
2265 utctime = metArray[:,0]
2268 utctime = metArray[:,0]
2266 cmet = metArray[:,1].astype(int)
2269 cmet = metArray[:,1].astype(int)
2267 hmet = metArray[:,3].astype(int)
2270 hmet = metArray[:,3].astype(int)
2268 SNRmet = metArray[:,4]
2271 SNRmet = metArray[:,4]
2269 vmet = metArray[:,5]
2272 vmet = metArray[:,5]
2270 spcmet = metArray[:,6]
2273 spcmet = metArray[:,6]
2271
2274
2272 nChan = numpy.max(cmet) + 1
2275 nChan = numpy.max(cmet) + 1
2273 nHeights = len(heightList)
2276 nHeights = len(heightList)
2274
2277
2275 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2278 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2276 hmet = heightList[hmet]
2279 hmet = heightList[hmet]
2277 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2280 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2278
2281
2279 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2282 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2280
2283
2281 for i in range(nHeights - 1):
2284 for i in range(nHeights - 1):
2282 hmin = heightList[i]
2285 hmin = heightList[i]
2283 hmax = heightList[i + 1]
2286 hmax = heightList[i + 1]
2284
2287
2285 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2288 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2286 indthisH = numpy.where(thisH)
2289 indthisH = numpy.where(thisH)
2287
2290
2288 if numpy.size(indthisH) > 3:
2291 if numpy.size(indthisH) > 3:
2289
2292
2290 vel_aux = vmet[thisH]
2293 vel_aux = vmet[thisH]
2291 chan_aux = cmet[thisH]
2294 chan_aux = cmet[thisH]
2292 cosu_aux = dir_cosu[chan_aux]
2295 cosu_aux = dir_cosu[chan_aux]
2293 cosv_aux = dir_cosv[chan_aux]
2296 cosv_aux = dir_cosv[chan_aux]
2294 cosw_aux = dir_cosw[chan_aux]
2297 cosw_aux = dir_cosw[chan_aux]
2295
2298
2296 nch = numpy.size(numpy.unique(chan_aux))
2299 nch = numpy.size(numpy.unique(chan_aux))
2297 if nch > 1:
2300 if nch > 1:
2298 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2301 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2299 velEst[i,:] = numpy.dot(A,vel_aux)
2302 velEst[i,:] = numpy.dot(A,vel_aux)
2300
2303
2301 return velEst
2304 return velEst
2302
2305
2303 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2306 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2304
2307
2305 param = dataOut.data_param
2308 param = dataOut.data_param
2306 if dataOut.abscissaList != None:
2309 if dataOut.abscissaList != None:
2307 absc = dataOut.abscissaList[:-1]
2310 absc = dataOut.abscissaList[:-1]
2308 # noise = dataOut.noise
2311 # noise = dataOut.noise
2309 heightList = dataOut.heightList
2312 heightList = dataOut.heightList
2310 SNR = dataOut.data_SNR
2313 SNR = dataOut.data_SNR
2311
2314
2312 if technique == 'DBS':
2315 if technique == 'DBS':
2313
2316
2314 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2317 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2315 kwargs['heightList'] = heightList
2318 kwargs['heightList'] = heightList
2316 kwargs['SNR'] = SNR
2319 kwargs['SNR'] = SNR
2317
2320
2318 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2321 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2319 dataOut.utctimeInit = dataOut.utctime
2322 dataOut.utctimeInit = dataOut.utctime
2320 dataOut.outputInterval = dataOut.paramInterval
2323 dataOut.outputInterval = dataOut.paramInterval
2321
2324
2322 elif technique == 'SA':
2325 elif technique == 'SA':
2323
2326
2324 #Parameters
2327 #Parameters
2325 # position_x = kwargs['positionX']
2328 # position_x = kwargs['positionX']
2326 # position_y = kwargs['positionY']
2329 # position_y = kwargs['positionY']
2327 # azimuth = kwargs['azimuth']
2330 # azimuth = kwargs['azimuth']
2328 #
2331 #
2329 # if kwargs.has_key('crosspairsList'):
2332 # if kwargs.has_key('crosspairsList'):
2330 # pairs = kwargs['crosspairsList']
2333 # pairs = kwargs['crosspairsList']
2331 # else:
2334 # else:
2332 # pairs = None
2335 # pairs = None
2333 #
2336 #
2334 # if kwargs.has_key('correctFactor'):
2337 # if kwargs.has_key('correctFactor'):
2335 # correctFactor = kwargs['correctFactor']
2338 # correctFactor = kwargs['correctFactor']
2336 # else:
2339 # else:
2337 # correctFactor = 1
2340 # correctFactor = 1
2338
2341
2339 # tau = dataOut.data_param
2342 # tau = dataOut.data_param
2340 # _lambda = dataOut.C/dataOut.frequency
2343 # _lambda = dataOut.C/dataOut.frequency
2341 # pairsList = dataOut.groupList
2344 # pairsList = dataOut.groupList
2342 # nChannels = dataOut.nChannels
2345 # nChannels = dataOut.nChannels
2343
2346
2344 kwargs['groupList'] = dataOut.groupList
2347 kwargs['groupList'] = dataOut.groupList
2345 kwargs['tau'] = dataOut.data_param
2348 kwargs['tau'] = dataOut.data_param
2346 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2349 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2347 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2350 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2348 dataOut.data_output = self.techniqueSA(kwargs)
2351 dataOut.data_output = self.techniqueSA(kwargs)
2349 dataOut.utctimeInit = dataOut.utctime
2352 dataOut.utctimeInit = dataOut.utctime
2350 dataOut.outputInterval = dataOut.timeInterval
2353 dataOut.outputInterval = dataOut.timeInterval
2351
2354
2352 elif technique == 'Meteors':
2355 elif technique == 'Meteors':
2353 dataOut.flagNoData = True
2356 dataOut.flagNoData = True
2354 self.__dataReady = False
2357 self.__dataReady = False
2355
2358
2356 if kwargs.has_key('nHours'):
2359 if kwargs.has_key('nHours'):
2357 nHours = kwargs['nHours']
2360 nHours = kwargs['nHours']
2358 else:
2361 else:
2359 nHours = 1
2362 nHours = 1
2360
2363
2361 if kwargs.has_key('meteorsPerBin'):
2364 if kwargs.has_key('meteorsPerBin'):
2362 meteorThresh = kwargs['meteorsPerBin']
2365 meteorThresh = kwargs['meteorsPerBin']
2363 else:
2366 else:
2364 meteorThresh = 6
2367 meteorThresh = 6
2365
2368
2366 if kwargs.has_key('hmin'):
2369 if kwargs.has_key('hmin'):
2367 hmin = kwargs['hmin']
2370 hmin = kwargs['hmin']
2368 else: hmin = 70
2371 else: hmin = 70
2369 if kwargs.has_key('hmax'):
2372 if kwargs.has_key('hmax'):
2370 hmax = kwargs['hmax']
2373 hmax = kwargs['hmax']
2371 else: hmax = 110
2374 else: hmax = 110
2372
2375
2373 dataOut.outputInterval = nHours*3600
2376 dataOut.outputInterval = nHours*3600
2374
2377
2375 if self.__isConfig == False:
2378 if self.__isConfig == False:
2376 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2379 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2377 #Get Initial LTC time
2380 #Get Initial LTC time
2378 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2381 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2379 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2382 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2380
2383
2381 self.__isConfig = True
2384 self.__isConfig = True
2382
2385
2383 if self.__buffer == None:
2386 if self.__buffer == None:
2384 self.__buffer = dataOut.data_param
2387 self.__buffer = dataOut.data_param
2385 self.__firstdata = copy.copy(dataOut)
2388 self.__firstdata = copy.copy(dataOut)
2386
2389
2387 else:
2390 else:
2388 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2391 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2389
2392
2390 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2393 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2391
2394
2392 if self.__dataReady:
2395 if self.__dataReady:
2393 dataOut.utctimeInit = self.__initime
2396 dataOut.utctimeInit = self.__initime
2394
2397
2395 self.__initime += dataOut.outputInterval #to erase time offset
2398 self.__initime += dataOut.outputInterval #to erase time offset
2396
2399
2397 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2400 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2398 dataOut.flagNoData = False
2401 dataOut.flagNoData = False
2399 self.__buffer = None
2402 self.__buffer = None
2400
2403
2401 elif technique == 'Meteors1':
2404 elif technique == 'Meteors1':
2402 dataOut.flagNoData = True
2405 dataOut.flagNoData = True
2403 self.__dataReady = False
2406 self.__dataReady = False
2404
2407
2405 if kwargs.has_key('nMins'):
2408 if kwargs.has_key('nMins'):
2406 nMins = kwargs['nMins']
2409 nMins = kwargs['nMins']
2407 else: nMins = 20
2410 else: nMins = 20
2408 if kwargs.has_key('rx_location'):
2411 if kwargs.has_key('rx_location'):
2409 rx_location = kwargs['rx_location']
2412 rx_location = kwargs['rx_location']
2410 else: rx_location = [(0,1),(1,1),(1,0)]
2413 else: rx_location = [(0,1),(1,1),(1,0)]
2411 if kwargs.has_key('azimuth'):
2414 if kwargs.has_key('azimuth'):
2412 azimuth = kwargs['azimuth']
2415 azimuth = kwargs['azimuth']
2413 else: azimuth = 51.06
2416 else: azimuth = 51.06
2414 if kwargs.has_key('dfactor'):
2417 if kwargs.has_key('dfactor'):
2415 dfactor = kwargs['dfactor']
2418 dfactor = kwargs['dfactor']
2416 if kwargs.has_key('mode'):
2419 if kwargs.has_key('mode'):
2417 mode = kwargs['mode']
2420 mode = kwargs['mode']
2418 if kwargs.has_key('theta_x'):
2421 if kwargs.has_key('theta_x'):
2419 theta_x = kwargs['theta_x']
2422 theta_x = kwargs['theta_x']
2420 if kwargs.has_key('theta_y'):
2423 if kwargs.has_key('theta_y'):
2421 theta_y = kwargs['theta_y']
2424 theta_y = kwargs['theta_y']
2422 else: mode = 'SA'
2425 else: mode = 'SA'
2423
2426
2424 #Borrar luego esto
2427 #Borrar luego esto
2425 if dataOut.groupList == None:
2428 if dataOut.groupList == None:
2426 dataOut.groupList = [(0,1),(0,2),(1,2)]
2429 dataOut.groupList = [(0,1),(0,2),(1,2)]
2427 groupList = dataOut.groupList
2430 groupList = dataOut.groupList
2428 C = 3e8
2431 C = 3e8
2429 freq = 50e6
2432 freq = 50e6
2430 lamb = C/freq
2433 lamb = C/freq
2431 k = 2*numpy.pi/lamb
2434 k = 2*numpy.pi/lamb
2432
2435
2433 timeList = dataOut.abscissaList
2436 timeList = dataOut.abscissaList
2434 heightList = dataOut.heightList
2437 heightList = dataOut.heightList
2435
2438
2436 if self.__isConfig == False:
2439 if self.__isConfig == False:
2437 dataOut.outputInterval = nMins*60
2440 dataOut.outputInterval = nMins*60
2438 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2441 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2439 #Get Initial LTC time
2442 #Get Initial LTC time
2440 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2443 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2441 minuteAux = initime.minute
2444 minuteAux = initime.minute
2442 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2445 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2443 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2446 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2444
2447
2445 self.__isConfig = True
2448 self.__isConfig = True
2446
2449
2447 if self.__buffer == None:
2450 if self.__buffer == None:
2448 self.__buffer = dataOut.data_param
2451 self.__buffer = dataOut.data_param
2449 self.__firstdata = copy.copy(dataOut)
2452 self.__firstdata = copy.copy(dataOut)
2450
2453
2451 else:
2454 else:
2452 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2455 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2453
2456
2454 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2457 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2455
2458
2456 if self.__dataReady:
2459 if self.__dataReady:
2457 dataOut.utctimeInit = self.__initime
2460 dataOut.utctimeInit = self.__initime
2458 self.__initime += dataOut.outputInterval #to erase time offset
2461 self.__initime += dataOut.outputInterval #to erase time offset
2459
2462
2460 metArray = self.__buffer
2463 metArray = self.__buffer
2461 if mode == 'SA':
2464 if mode == 'SA':
2462 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2465 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2463 elif mode == 'DBS':
2466 elif mode == 'DBS':
2464 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2467 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2465 dataOut.data_output = dataOut.data_output.T
2468 dataOut.data_output = dataOut.data_output.T
2466 dataOut.flagNoData = False
2469 dataOut.flagNoData = False
2467 self.__buffer = None
2470 self.__buffer = None
2468
2471
2469 return
2472 return
2470
2473
2471 class EWDriftsEstimation(Operation):
2474 class EWDriftsEstimation(Operation):
2472
2475
2473 def __init__(self):
2476 def __init__(self):
2474 Operation.__init__(self)
2477 Operation.__init__(self)
2475
2478
2476 def __correctValues(self, heiRang, phi, velRadial, SNR):
2479 def __correctValues(self, heiRang, phi, velRadial, SNR):
2477 listPhi = phi.tolist()
2480 listPhi = phi.tolist()
2478 maxid = listPhi.index(max(listPhi))
2481 maxid = listPhi.index(max(listPhi))
2479 minid = listPhi.index(min(listPhi))
2482 minid = listPhi.index(min(listPhi))
2480
2483
2481 rango = range(len(phi))
2484 rango = range(len(phi))
2482 # rango = numpy.delete(rango,maxid)
2485 # rango = numpy.delete(rango,maxid)
2483
2486
2484 heiRang1 = heiRang*math.cos(phi[maxid])
2487 heiRang1 = heiRang*math.cos(phi[maxid])
2485 heiRangAux = heiRang*math.cos(phi[minid])
2488 heiRangAux = heiRang*math.cos(phi[minid])
2486 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2489 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2487 heiRang1 = numpy.delete(heiRang1,indOut)
2490 heiRang1 = numpy.delete(heiRang1,indOut)
2488
2491
2489 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2492 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2490 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2493 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2491
2494
2492 for i in rango:
2495 for i in rango:
2493 x = heiRang*math.cos(phi[i])
2496 x = heiRang*math.cos(phi[i])
2494 y1 = velRadial[i,:]
2497 y1 = velRadial[i,:]
2495 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2498 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2496
2499
2497 x1 = heiRang1
2500 x1 = heiRang1
2498 y11 = f1(x1)
2501 y11 = f1(x1)
2499
2502
2500 y2 = SNR[i,:]
2503 y2 = SNR[i,:]
2501 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2504 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2502 y21 = f2(x1)
2505 y21 = f2(x1)
2503
2506
2504 velRadial1[i,:] = y11
2507 velRadial1[i,:] = y11
2505 SNR1[i,:] = y21
2508 SNR1[i,:] = y21
2506
2509
2507 return heiRang1, velRadial1, SNR1
2510 return heiRang1, velRadial1, SNR1
2508
2511
2509 def run(self, dataOut, zenith, zenithCorrection):
2512 def run(self, dataOut, zenith, zenithCorrection):
2510 heiRang = dataOut.heightList
2513 heiRang = dataOut.heightList
2511 velRadial = dataOut.data_param[:,3,:]
2514 velRadial = dataOut.data_param[:,3,:]
2512 SNR = dataOut.data_SNR
2515 SNR = dataOut.data_SNR
2513
2516
2514 zenith = numpy.array(zenith)
2517 zenith = numpy.array(zenith)
2515 zenith -= zenithCorrection
2518 zenith -= zenithCorrection
2516 zenith *= numpy.pi/180
2519 zenith *= numpy.pi/180
2517
2520
2518 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2521 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2519
2522
2520 alp = zenith[0]
2523 alp = zenith[0]
2521 bet = zenith[1]
2524 bet = zenith[1]
2522
2525
2523 w_w = velRadial1[0,:]
2526 w_w = velRadial1[0,:]
2524 w_e = velRadial1[1,:]
2527 w_e = velRadial1[1,:]
2525
2528
2526 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2529 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2527 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2530 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2528
2531
2529 winds = numpy.vstack((u,w))
2532 winds = numpy.vstack((u,w))
2530
2533
2531 dataOut.heightList = heiRang1
2534 dataOut.heightList = heiRang1
2532 dataOut.data_output = winds
2535 dataOut.data_output = winds
2533 dataOut.data_SNR = SNR1
2536 dataOut.data_SNR = SNR1
2534
2537
2535 dataOut.utctimeInit = dataOut.utctime
2538 dataOut.utctimeInit = dataOut.utctime
2536 dataOut.outputInterval = dataOut.timeInterval
2539 dataOut.outputInterval = dataOut.timeInterval
2537 return
2540 return
2538
2541
2539 #--------------- Non Specular Meteor ----------------
2542 #--------------- Non Specular Meteor ----------------
2540
2543
2541 class NonSpecularMeteorDetection(Operation):
2544 class NonSpecularMeteorDetection(Operation):
2542
2545
2543 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2546 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2544 data_acf = dataOut.data_pre[0]
2547 data_acf = dataOut.data_pre[0]
2545 data_ccf = dataOut.data_pre[1]
2548 data_ccf = dataOut.data_pre[1]
2546 pairsList = dataOut.groupList[1]
2549 pairsList = dataOut.groupList[1]
2547
2550
2548 lamb = dataOut.C/dataOut.frequency
2551 lamb = dataOut.C/dataOut.frequency
2549 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2552 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2550 paramInterval = dataOut.paramInterval
2553 paramInterval = dataOut.paramInterval
2551
2554
2552 nChannels = data_acf.shape[0]
2555 nChannels = data_acf.shape[0]
2553 nLags = data_acf.shape[1]
2556 nLags = data_acf.shape[1]
2554 nProfiles = data_acf.shape[2]
2557 nProfiles = data_acf.shape[2]
2555 nHeights = dataOut.nHeights
2558 nHeights = dataOut.nHeights
2556 nCohInt = dataOut.nCohInt
2559 nCohInt = dataOut.nCohInt
2557 sec = numpy.round(nProfiles/dataOut.paramInterval)
2560 sec = numpy.round(nProfiles/dataOut.paramInterval)
2558 heightList = dataOut.heightList
2561 heightList = dataOut.heightList
2559 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2562 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2560 utctime = dataOut.utctime
2563 utctime = dataOut.utctime
2561
2564
2562 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2565 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2563
2566
2564 #------------------------ SNR --------------------------------------
2567 #------------------------ SNR --------------------------------------
2565 power = data_acf[:,0,:,:].real
2568 power = data_acf[:,0,:,:].real
2566 noise = numpy.zeros(nChannels)
2569 noise = numpy.zeros(nChannels)
2567 SNR = numpy.zeros(power.shape)
2570 SNR = numpy.zeros(power.shape)
2568 for i in range(nChannels):
2571 for i in range(nChannels):
2569 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2572 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2570 SNR[i] = (power[i]-noise[i])/noise[i]
2573 SNR[i] = (power[i]-noise[i])/noise[i]
2571 SNRm = numpy.nanmean(SNR, axis = 0)
2574 SNRm = numpy.nanmean(SNR, axis = 0)
2572 SNRdB = 10*numpy.log10(SNR)
2575 SNRdB = 10*numpy.log10(SNR)
2573
2576
2574 if mode == 'SA':
2577 if mode == 'SA':
2575 dataOut.groupList = dataOut.groupList[1]
2578 dataOut.groupList = dataOut.groupList[1]
2576 nPairs = data_ccf.shape[0]
2579 nPairs = data_ccf.shape[0]
2577 #---------------------- Coherence and Phase --------------------------
2580 #---------------------- Coherence and Phase --------------------------
2578 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2581 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2579 # phase1 = numpy.copy(phase)
2582 # phase1 = numpy.copy(phase)
2580 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2583 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2581
2584
2582 for p in range(nPairs):
2585 for p in range(nPairs):
2583 ch0 = pairsList[p][0]
2586 ch0 = pairsList[p][0]
2584 ch1 = pairsList[p][1]
2587 ch1 = pairsList[p][1]
2585 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2588 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2586 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2589 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2587 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2590 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2588 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2591 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2589 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2592 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2590 coh = numpy.nanmax(coh1, axis = 0)
2593 coh = numpy.nanmax(coh1, axis = 0)
2591 # struc = numpy.ones((5,1))
2594 # struc = numpy.ones((5,1))
2592 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2595 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2593 #---------------------- Radial Velocity ----------------------------
2596 #---------------------- Radial Velocity ----------------------------
2594 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2597 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2595 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2598 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2596
2599
2597 if allData:
2600 if allData:
2598 boolMetFin = ~numpy.isnan(SNRm)
2601 boolMetFin = ~numpy.isnan(SNRm)
2599 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2602 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2600 else:
2603 else:
2601 #------------------------ Meteor mask ---------------------------------
2604 #------------------------ Meteor mask ---------------------------------
2602 # #SNR mask
2605 # #SNR mask
2603 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2606 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2604 #
2607 #
2605 # #Erase small objects
2608 # #Erase small objects
2606 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2609 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2607 #
2610 #
2608 # auxEEJ = numpy.sum(boolMet1,axis=0)
2611 # auxEEJ = numpy.sum(boolMet1,axis=0)
2609 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2612 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2610 # indEEJ = numpy.where(indOver)[0]
2613 # indEEJ = numpy.where(indOver)[0]
2611 # indNEEJ = numpy.where(~indOver)[0]
2614 # indNEEJ = numpy.where(~indOver)[0]
2612 #
2615 #
2613 # boolMetFin = boolMet1
2616 # boolMetFin = boolMet1
2614 #
2617 #
2615 # if indEEJ.size > 0:
2618 # if indEEJ.size > 0:
2616 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2619 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2617 #
2620 #
2618 # boolMet2 = coh > cohThresh
2621 # boolMet2 = coh > cohThresh
2619 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2622 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2620 #
2623 #
2621 # #Final Meteor mask
2624 # #Final Meteor mask
2622 # boolMetFin = boolMet1|boolMet2
2625 # boolMetFin = boolMet1|boolMet2
2623
2626
2624 #Coherence mask
2627 #Coherence mask
2625 boolMet1 = coh > 0.75
2628 boolMet1 = coh > 0.75
2626 struc = numpy.ones((30,1))
2629 struc = numpy.ones((30,1))
2627 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2630 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2628
2631
2629 #Derivative mask
2632 #Derivative mask
2630 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2633 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2631 boolMet2 = derPhase < 0.2
2634 boolMet2 = derPhase < 0.2
2632 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2635 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2633 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2636 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2634 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2637 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2635 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2638 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2636 # #Final mask
2639 # #Final mask
2637 # boolMetFin = boolMet2
2640 # boolMetFin = boolMet2
2638 boolMetFin = boolMet1&boolMet2
2641 boolMetFin = boolMet1&boolMet2
2639 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2642 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2640 #Creating data_param
2643 #Creating data_param
2641 coordMet = numpy.where(boolMetFin)
2644 coordMet = numpy.where(boolMetFin)
2642
2645
2643 tmet = coordMet[0]
2646 tmet = coordMet[0]
2644 hmet = coordMet[1]
2647 hmet = coordMet[1]
2645
2648
2646 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2649 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2647 data_param[:,0] = utctime
2650 data_param[:,0] = utctime
2648 data_param[:,1] = tmet
2651 data_param[:,1] = tmet
2649 data_param[:,2] = hmet
2652 data_param[:,2] = hmet
2650 data_param[:,3] = SNRm[tmet,hmet]
2653 data_param[:,3] = SNRm[tmet,hmet]
2651 data_param[:,4] = velRad[tmet,hmet]
2654 data_param[:,4] = velRad[tmet,hmet]
2652 data_param[:,5] = coh[tmet,hmet]
2655 data_param[:,5] = coh[tmet,hmet]
2653 data_param[:,6:] = phase[:,tmet,hmet].T
2656 data_param[:,6:] = phase[:,tmet,hmet].T
2654
2657
2655 elif mode == 'DBS':
2658 elif mode == 'DBS':
2656 dataOut.groupList = numpy.arange(nChannels)
2659 dataOut.groupList = numpy.arange(nChannels)
2657
2660
2658 #Radial Velocities
2661 #Radial Velocities
2659 phase = numpy.angle(data_acf[:,1,:,:])
2662 phase = numpy.angle(data_acf[:,1,:,:])
2660 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2663 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2661 velRad = phase*lamb/(4*numpy.pi*tSamp)
2664 velRad = phase*lamb/(4*numpy.pi*tSamp)
2662
2665
2663 #Spectral width
2666 #Spectral width
2664 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2667 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2665 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2668 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2666 acf1 = data_acf[:,1,:,:]
2669 acf1 = data_acf[:,1,:,:]
2667 acf2 = data_acf[:,2,:,:]
2670 acf2 = data_acf[:,2,:,:]
2668
2671
2669 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2672 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2670 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2673 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2671 if allData:
2674 if allData:
2672 boolMetFin = ~numpy.isnan(SNRdB)
2675 boolMetFin = ~numpy.isnan(SNRdB)
2673 else:
2676 else:
2674 #SNR
2677 #SNR
2675 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2678 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2676 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2679 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2677
2680
2678 #Radial velocity
2681 #Radial velocity
2679 boolMet2 = numpy.abs(velRad) < 20
2682 boolMet2 = numpy.abs(velRad) < 20
2680 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2683 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2681
2684
2682 #Spectral Width
2685 #Spectral Width
2683 boolMet3 = spcWidth < 30
2686 boolMet3 = spcWidth < 30
2684 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2687 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2685 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2688 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2686 boolMetFin = boolMet1&boolMet2&boolMet3
2689 boolMetFin = boolMet1&boolMet2&boolMet3
2687
2690
2688 #Creating data_param
2691 #Creating data_param
2689 coordMet = numpy.where(boolMetFin)
2692 coordMet = numpy.where(boolMetFin)
2690
2693
2691 cmet = coordMet[0]
2694 cmet = coordMet[0]
2692 tmet = coordMet[1]
2695 tmet = coordMet[1]
2693 hmet = coordMet[2]
2696 hmet = coordMet[2]
2694
2697
2695 data_param = numpy.zeros((tmet.size, 7))
2698 data_param = numpy.zeros((tmet.size, 7))
2696 data_param[:,0] = utctime
2699 data_param[:,0] = utctime
2697 data_param[:,1] = cmet
2700 data_param[:,1] = cmet
2698 data_param[:,2] = tmet
2701 data_param[:,2] = tmet
2699 data_param[:,3] = hmet
2702 data_param[:,3] = hmet
2700 data_param[:,4] = SNR[cmet,tmet,hmet].T
2703 data_param[:,4] = SNR[cmet,tmet,hmet].T
2701 data_param[:,5] = velRad[cmet,tmet,hmet].T
2704 data_param[:,5] = velRad[cmet,tmet,hmet].T
2702 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2705 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2703
2706
2704 # self.dataOut.data_param = data_int
2707 # self.dataOut.data_param = data_int
2705 if len(data_param) == 0:
2708 if len(data_param) == 0:
2706 dataOut.flagNoData = True
2709 dataOut.flagNoData = True
2707 else:
2710 else:
2708 dataOut.data_param = data_param
2711 dataOut.data_param = data_param
2709
2712
2710 def __erase_small(self, binArray, threshX, threshY):
2713 def __erase_small(self, binArray, threshX, threshY):
2711 labarray, numfeat = ndimage.measurements.label(binArray)
2714 labarray, numfeat = ndimage.measurements.label(binArray)
2712 binArray1 = numpy.copy(binArray)
2715 binArray1 = numpy.copy(binArray)
2713
2716
2714 for i in range(1,numfeat + 1):
2717 for i in range(1,numfeat + 1):
2715 auxBin = (labarray==i)
2718 auxBin = (labarray==i)
2716 auxSize = auxBin.sum()
2719 auxSize = auxBin.sum()
2717
2720
2718 x,y = numpy.where(auxBin)
2721 x,y = numpy.where(auxBin)
2719 widthX = x.max() - x.min()
2722 widthX = x.max() - x.min()
2720 widthY = y.max() - y.min()
2723 widthY = y.max() - y.min()
2721
2724
2722 #width X: 3 seg -> 12.5*3
2725 #width X: 3 seg -> 12.5*3
2723 #width Y:
2726 #width Y:
2724
2727
2725 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2728 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2726 binArray1[auxBin] = False
2729 binArray1[auxBin] = False
2727
2730
2728 return binArray1
2731 return binArray1
2729
2732
2730 #--------------- Specular Meteor ----------------
2733 #--------------- Specular Meteor ----------------
2731
2734
2732 class SMDetection(Operation):
2735 class SMDetection(Operation):
2733 '''
2736 '''
2734 Function DetectMeteors()
2737 Function DetectMeteors()
2735 Project developed with paper:
2738 Project developed with paper:
2736 HOLDSWORTH ET AL. 2004
2739 HOLDSWORTH ET AL. 2004
2737
2740
2738 Input:
2741 Input:
2739 self.dataOut.data_pre
2742 self.dataOut.data_pre
2740
2743
2741 centerReceiverIndex: From the channels, which is the center receiver
2744 centerReceiverIndex: From the channels, which is the center receiver
2742
2745
2743 hei_ref: Height reference for the Beacon signal extraction
2746 hei_ref: Height reference for the Beacon signal extraction
2744 tauindex:
2747 tauindex:
2745 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2748 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2746
2749
2747 cohDetection: Whether to user Coherent detection or not
2750 cohDetection: Whether to user Coherent detection or not
2748 cohDet_timeStep: Coherent Detection calculation time step
2751 cohDet_timeStep: Coherent Detection calculation time step
2749 cohDet_thresh: Coherent Detection phase threshold to correct phases
2752 cohDet_thresh: Coherent Detection phase threshold to correct phases
2750
2753
2751 noise_timeStep: Noise calculation time step
2754 noise_timeStep: Noise calculation time step
2752 noise_multiple: Noise multiple to define signal threshold
2755 noise_multiple: Noise multiple to define signal threshold
2753
2756
2754 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2757 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2755 multDet_rangeLimit: Multiple Detection Removal range limit in km
2758 multDet_rangeLimit: Multiple Detection Removal range limit in km
2756
2759
2757 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2760 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2758 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2761 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2759
2762
2760 hmin: Minimum Height of the meteor to use it in the further wind estimations
2763 hmin: Minimum Height of the meteor to use it in the further wind estimations
2761 hmax: Maximum Height of the meteor to use it in the further wind estimations
2764 hmax: Maximum Height of the meteor to use it in the further wind estimations
2762 azimuth: Azimuth angle correction
2765 azimuth: Azimuth angle correction
2763
2766
2764 Affected:
2767 Affected:
2765 self.dataOut.data_param
2768 self.dataOut.data_param
2766
2769
2767 Rejection Criteria (Errors):
2770 Rejection Criteria (Errors):
2768 0: No error; analysis OK
2771 0: No error; analysis OK
2769 1: SNR < SNR threshold
2772 1: SNR < SNR threshold
2770 2: angle of arrival (AOA) ambiguously determined
2773 2: angle of arrival (AOA) ambiguously determined
2771 3: AOA estimate not feasible
2774 3: AOA estimate not feasible
2772 4: Large difference in AOAs obtained from different antenna baselines
2775 4: Large difference in AOAs obtained from different antenna baselines
2773 5: echo at start or end of time series
2776 5: echo at start or end of time series
2774 6: echo less than 5 examples long; too short for analysis
2777 6: echo less than 5 examples long; too short for analysis
2775 7: echo rise exceeds 0.3s
2778 7: echo rise exceeds 0.3s
2776 8: echo decay time less than twice rise time
2779 8: echo decay time less than twice rise time
2777 9: large power level before echo
2780 9: large power level before echo
2778 10: large power level after echo
2781 10: large power level after echo
2779 11: poor fit to amplitude for estimation of decay time
2782 11: poor fit to amplitude for estimation of decay time
2780 12: poor fit to CCF phase variation for estimation of radial drift velocity
2783 12: poor fit to CCF phase variation for estimation of radial drift velocity
2781 13: height unresolvable echo: not valid height within 70 to 110 km
2784 13: height unresolvable echo: not valid height within 70 to 110 km
2782 14: height ambiguous echo: more then one possible height within 70 to 110 km
2785 14: height ambiguous echo: more then one possible height within 70 to 110 km
2783 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2786 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2784 16: oscilatory echo, indicating event most likely not an underdense echo
2787 16: oscilatory echo, indicating event most likely not an underdense echo
2785
2788
2786 17: phase difference in meteor Reestimation
2789 17: phase difference in meteor Reestimation
2787
2790
2788 Data Storage:
2791 Data Storage:
2789 Meteors for Wind Estimation (8):
2792 Meteors for Wind Estimation (8):
2790 Utc Time | Range Height
2793 Utc Time | Range Height
2791 Azimuth Zenith errorCosDir
2794 Azimuth Zenith errorCosDir
2792 VelRad errorVelRad
2795 VelRad errorVelRad
2793 Phase0 Phase1 Phase2 Phase3
2796 Phase0 Phase1 Phase2 Phase3
2794 TypeError
2797 TypeError
2795
2798
2796 '''
2799 '''
2797
2800
2798 def run(self, dataOut, hei_ref = None, tauindex = 0,
2801 def run(self, dataOut, hei_ref = None, tauindex = 0,
2799 phaseOffsets = None,
2802 phaseOffsets = None,
2800 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2803 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2801 noise_timeStep = 4, noise_multiple = 4,
2804 noise_timeStep = 4, noise_multiple = 4,
2802 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2805 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2803 phaseThresh = 20, SNRThresh = 5,
2806 phaseThresh = 20, SNRThresh = 5,
2804 hmin = 50, hmax=150, azimuth = 0,
2807 hmin = 50, hmax=150, azimuth = 0,
2805 channelPositions = None) :
2808 channelPositions = None) :
2806
2809
2807
2810
2808 #Getting Pairslist
2811 #Getting Pairslist
2809 if channelPositions == None:
2812 if channelPositions == None:
2810 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2813 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2811 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2814 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2812 meteorOps = SMOperations()
2815 meteorOps = SMOperations()
2813 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2816 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2814 heiRang = dataOut.getHeiRange()
2817 heiRang = dataOut.getHeiRange()
2815 #Get Beacon signal - No Beacon signal anymore
2818 #Get Beacon signal - No Beacon signal anymore
2816 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2819 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2817 #
2820 #
2818 # if hei_ref != None:
2821 # if hei_ref != None:
2819 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2822 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2820 #
2823 #
2821
2824
2822
2825
2823 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2826 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2824 # see if the user put in pre defined phase shifts
2827 # see if the user put in pre defined phase shifts
2825 voltsPShift = dataOut.data_pre.copy()
2828 voltsPShift = dataOut.data_pre.copy()
2826
2829
2827 # if predefinedPhaseShifts != None:
2830 # if predefinedPhaseShifts != None:
2828 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2831 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2829 #
2832 #
2830 # # elif beaconPhaseShifts:
2833 # # elif beaconPhaseShifts:
2831 # # #get hardware phase shifts using beacon signal
2834 # # #get hardware phase shifts using beacon signal
2832 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2835 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2833 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2836 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2834 #
2837 #
2835 # else:
2838 # else:
2836 # hardwarePhaseShifts = numpy.zeros(5)
2839 # hardwarePhaseShifts = numpy.zeros(5)
2837 #
2840 #
2838 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2841 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2839 # for i in range(self.dataOut.data_pre.shape[0]):
2842 # for i in range(self.dataOut.data_pre.shape[0]):
2840 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2843 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2841
2844
2842 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2845 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2843
2846
2844 #Remove DC
2847 #Remove DC
2845 voltsDC = numpy.mean(voltsPShift,1)
2848 voltsDC = numpy.mean(voltsPShift,1)
2846 voltsDC = numpy.mean(voltsDC,1)
2849 voltsDC = numpy.mean(voltsDC,1)
2847 for i in range(voltsDC.shape[0]):
2850 for i in range(voltsDC.shape[0]):
2848 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2851 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2849
2852
2850 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2853 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2851 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2854 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2852
2855
2853 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2856 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2854 #Coherent Detection
2857 #Coherent Detection
2855 if cohDetection:
2858 if cohDetection:
2856 #use coherent detection to get the net power
2859 #use coherent detection to get the net power
2857 cohDet_thresh = cohDet_thresh*numpy.pi/180
2860 cohDet_thresh = cohDet_thresh*numpy.pi/180
2858 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2861 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2859
2862
2860 #Non-coherent detection!
2863 #Non-coherent detection!
2861 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2864 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2862 #********** END OF COH/NON-COH POWER CALCULATION**********************
2865 #********** END OF COH/NON-COH POWER CALCULATION**********************
2863
2866
2864 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2867 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2865 #Get noise
2868 #Get noise
2866 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2869 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2867 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2870 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2868 #Get signal threshold
2871 #Get signal threshold
2869 signalThresh = noise_multiple*noise
2872 signalThresh = noise_multiple*noise
2870 #Meteor echoes detection
2873 #Meteor echoes detection
2871 listMeteors = self.__findMeteors(powerNet, signalThresh)
2874 listMeteors = self.__findMeteors(powerNet, signalThresh)
2872 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2875 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2873
2876
2874 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2877 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2875 #Parameters
2878 #Parameters
2876 heiRange = dataOut.getHeiRange()
2879 heiRange = dataOut.getHeiRange()
2877 rangeInterval = heiRange[1] - heiRange[0]
2880 rangeInterval = heiRange[1] - heiRange[0]
2878 rangeLimit = multDet_rangeLimit/rangeInterval
2881 rangeLimit = multDet_rangeLimit/rangeInterval
2879 timeLimit = multDet_timeLimit/dataOut.timeInterval
2882 timeLimit = multDet_timeLimit/dataOut.timeInterval
2880 #Multiple detection removals
2883 #Multiple detection removals
2881 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2884 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2882 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2885 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2883
2886
2884 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2887 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2885 #Parameters
2888 #Parameters
2886 phaseThresh = phaseThresh*numpy.pi/180
2889 phaseThresh = phaseThresh*numpy.pi/180
2887 thresh = [phaseThresh, noise_multiple, SNRThresh]
2890 thresh = [phaseThresh, noise_multiple, SNRThresh]
2888 #Meteor reestimation (Errors N 1, 6, 12, 17)
2891 #Meteor reestimation (Errors N 1, 6, 12, 17)
2889 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2892 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2890 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2893 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2891 #Estimation of decay times (Errors N 7, 8, 11)
2894 #Estimation of decay times (Errors N 7, 8, 11)
2892 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2895 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2893 #******************* END OF METEOR REESTIMATION *******************
2896 #******************* END OF METEOR REESTIMATION *******************
2894
2897
2895 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2898 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2896 #Calculating Radial Velocity (Error N 15)
2899 #Calculating Radial Velocity (Error N 15)
2897 radialStdThresh = 10
2900 radialStdThresh = 10
2898 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2901 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2899
2902
2900 if len(listMeteors4) > 0:
2903 if len(listMeteors4) > 0:
2901 #Setting New Array
2904 #Setting New Array
2902 date = dataOut.utctime
2905 date = dataOut.utctime
2903 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2906 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2904
2907
2905 #Correcting phase offset
2908 #Correcting phase offset
2906 if phaseOffsets != None:
2909 if phaseOffsets != None:
2907 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2910 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2908 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2911 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2909
2912
2910 #Second Pairslist
2913 #Second Pairslist
2911 pairsList = []
2914 pairsList = []
2912 pairx = (0,1)
2915 pairx = (0,1)
2913 pairy = (2,3)
2916 pairy = (2,3)
2914 pairsList.append(pairx)
2917 pairsList.append(pairx)
2915 pairsList.append(pairy)
2918 pairsList.append(pairy)
2916
2919
2917 jph = numpy.array([0,0,0,0])
2920 jph = numpy.array([0,0,0,0])
2918 h = (hmin,hmax)
2921 h = (hmin,hmax)
2919 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2922 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2920
2923
2921 # #Calculate AOA (Error N 3, 4)
2924 # #Calculate AOA (Error N 3, 4)
2922 # #JONES ET AL. 1998
2925 # #JONES ET AL. 1998
2923 # error = arrayParameters[:,-1]
2926 # error = arrayParameters[:,-1]
2924 # AOAthresh = numpy.pi/8
2927 # AOAthresh = numpy.pi/8
2925 # phases = -arrayParameters[:,9:13]
2928 # phases = -arrayParameters[:,9:13]
2926 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2929 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2927 #
2930 #
2928 # #Calculate Heights (Error N 13 and 14)
2931 # #Calculate Heights (Error N 13 and 14)
2929 # error = arrayParameters[:,-1]
2932 # error = arrayParameters[:,-1]
2930 # Ranges = arrayParameters[:,2]
2933 # Ranges = arrayParameters[:,2]
2931 # zenith = arrayParameters[:,5]
2934 # zenith = arrayParameters[:,5]
2932 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2935 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2933 # error = arrayParameters[:,-1]
2936 # error = arrayParameters[:,-1]
2934 #********************* END OF PARAMETERS CALCULATION **************************
2937 #********************* END OF PARAMETERS CALCULATION **************************
2935
2938
2936 #***************************+ PASS DATA TO NEXT STEP **********************
2939 #***************************+ PASS DATA TO NEXT STEP **********************
2937 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2940 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2938 dataOut.data_param = arrayParameters
2941 dataOut.data_param = arrayParameters
2939
2942
2940 if arrayParameters == None:
2943 if arrayParameters == None:
2941 dataOut.flagNoData = True
2944 dataOut.flagNoData = True
2942 else:
2945 else:
2943 dataOut.flagNoData = True
2946 dataOut.flagNoData = True
2944
2947
2945 return
2948 return
2946
2949
2947 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2950 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2948
2951
2949 minIndex = min(newheis[0])
2952 minIndex = min(newheis[0])
2950 maxIndex = max(newheis[0])
2953 maxIndex = max(newheis[0])
2951
2954
2952 voltage = voltage0[:,:,minIndex:maxIndex+1]
2955 voltage = voltage0[:,:,minIndex:maxIndex+1]
2953 nLength = voltage.shape[1]/n
2956 nLength = voltage.shape[1]/n
2954 nMin = 0
2957 nMin = 0
2955 nMax = 0
2958 nMax = 0
2956 phaseOffset = numpy.zeros((len(pairslist),n))
2959 phaseOffset = numpy.zeros((len(pairslist),n))
2957
2960
2958 for i in range(n):
2961 for i in range(n):
2959 nMax += nLength
2962 nMax += nLength
2960 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2963 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2961 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2964 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2962 phaseOffset[:,i] = phaseCCF.transpose()
2965 phaseOffset[:,i] = phaseCCF.transpose()
2963 nMin = nMax
2966 nMin = nMax
2964 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2967 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2965
2968
2966 #Remove Outliers
2969 #Remove Outliers
2967 factor = 2
2970 factor = 2
2968 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2971 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2969 dw = numpy.std(wt,axis = 1)
2972 dw = numpy.std(wt,axis = 1)
2970 dw = dw.reshape((dw.size,1))
2973 dw = dw.reshape((dw.size,1))
2971 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2974 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2972 phaseOffset[ind] = numpy.nan
2975 phaseOffset[ind] = numpy.nan
2973 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2976 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2974
2977
2975 return phaseOffset
2978 return phaseOffset
2976
2979
2977 def __shiftPhase(self, data, phaseShift):
2980 def __shiftPhase(self, data, phaseShift):
2978 #this will shift the phase of a complex number
2981 #this will shift the phase of a complex number
2979 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2982 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2980 return dataShifted
2983 return dataShifted
2981
2984
2982 def __estimatePhaseDifference(self, array, pairslist):
2985 def __estimatePhaseDifference(self, array, pairslist):
2983 nChannel = array.shape[0]
2986 nChannel = array.shape[0]
2984 nHeights = array.shape[2]
2987 nHeights = array.shape[2]
2985 numPairs = len(pairslist)
2988 numPairs = len(pairslist)
2986 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2989 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2987 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2990 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2988
2991
2989 #Correct phases
2992 #Correct phases
2990 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2993 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2991 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2994 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2992
2995
2993 if indDer[0].shape[0] > 0:
2996 if indDer[0].shape[0] > 0:
2994 for i in range(indDer[0].shape[0]):
2997 for i in range(indDer[0].shape[0]):
2995 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2998 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2996 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2999 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2997
3000
2998 # for j in range(numSides):
3001 # for j in range(numSides):
2999 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
3002 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
3000 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
3003 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
3001 #
3004 #
3002 #Linear
3005 #Linear
3003 phaseInt = numpy.zeros((numPairs,1))
3006 phaseInt = numpy.zeros((numPairs,1))
3004 angAllCCF = phaseCCF[:,[0,1,3,4],0]
3007 angAllCCF = phaseCCF[:,[0,1,3,4],0]
3005 for j in range(numPairs):
3008 for j in range(numPairs):
3006 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
3009 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
3007 phaseInt[j] = fit[1]
3010 phaseInt[j] = fit[1]
3008 #Phase Differences
3011 #Phase Differences
3009 phaseDiff = phaseInt - phaseCCF[:,2,:]
3012 phaseDiff = phaseInt - phaseCCF[:,2,:]
3010 phaseArrival = phaseInt.reshape(phaseInt.size)
3013 phaseArrival = phaseInt.reshape(phaseInt.size)
3011
3014
3012 #Dealias
3015 #Dealias
3013 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
3016 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
3014 # indAlias = numpy.where(phaseArrival > numpy.pi)
3017 # indAlias = numpy.where(phaseArrival > numpy.pi)
3015 # phaseArrival[indAlias] -= 2*numpy.pi
3018 # phaseArrival[indAlias] -= 2*numpy.pi
3016 # indAlias = numpy.where(phaseArrival < -numpy.pi)
3019 # indAlias = numpy.where(phaseArrival < -numpy.pi)
3017 # phaseArrival[indAlias] += 2*numpy.pi
3020 # phaseArrival[indAlias] += 2*numpy.pi
3018
3021
3019 return phaseDiff, phaseArrival
3022 return phaseDiff, phaseArrival
3020
3023
3021 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
3024 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
3022 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
3025 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
3023 #find the phase shifts of each channel over 1 second intervals
3026 #find the phase shifts of each channel over 1 second intervals
3024 #only look at ranges below the beacon signal
3027 #only look at ranges below the beacon signal
3025 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3028 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3026 numBlocks = int(volts.shape[1]/numProfPerBlock)
3029 numBlocks = int(volts.shape[1]/numProfPerBlock)
3027 numHeights = volts.shape[2]
3030 numHeights = volts.shape[2]
3028 nChannel = volts.shape[0]
3031 nChannel = volts.shape[0]
3029 voltsCohDet = volts.copy()
3032 voltsCohDet = volts.copy()
3030
3033
3031 pairsarray = numpy.array(pairslist)
3034 pairsarray = numpy.array(pairslist)
3032 indSides = pairsarray[:,1]
3035 indSides = pairsarray[:,1]
3033 # indSides = numpy.array(range(nChannel))
3036 # indSides = numpy.array(range(nChannel))
3034 # indSides = numpy.delete(indSides, indCenter)
3037 # indSides = numpy.delete(indSides, indCenter)
3035 #
3038 #
3036 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
3039 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
3037 listBlocks = numpy.array_split(volts, numBlocks, 1)
3040 listBlocks = numpy.array_split(volts, numBlocks, 1)
3038
3041
3039 startInd = 0
3042 startInd = 0
3040 endInd = 0
3043 endInd = 0
3041
3044
3042 for i in range(numBlocks):
3045 for i in range(numBlocks):
3043 startInd = endInd
3046 startInd = endInd
3044 endInd = endInd + listBlocks[i].shape[1]
3047 endInd = endInd + listBlocks[i].shape[1]
3045
3048
3046 arrayBlock = listBlocks[i]
3049 arrayBlock = listBlocks[i]
3047 # arrayBlockCenter = listCenter[i]
3050 # arrayBlockCenter = listCenter[i]
3048
3051
3049 #Estimate the Phase Difference
3052 #Estimate the Phase Difference
3050 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3053 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3051 #Phase Difference RMS
3054 #Phase Difference RMS
3052 arrayPhaseRMS = numpy.abs(phaseDiff)
3055 arrayPhaseRMS = numpy.abs(phaseDiff)
3053 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3056 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3054 indPhase = numpy.where(phaseRMSaux==4)
3057 indPhase = numpy.where(phaseRMSaux==4)
3055 #Shifting
3058 #Shifting
3056 if indPhase[0].shape[0] > 0:
3059 if indPhase[0].shape[0] > 0:
3057 for j in range(indSides.size):
3060 for j in range(indSides.size):
3058 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3061 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3059 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3062 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3060
3063
3061 return voltsCohDet
3064 return voltsCohDet
3062
3065
3063 def __calculateCCF(self, volts, pairslist ,laglist):
3066 def __calculateCCF(self, volts, pairslist ,laglist):
3064
3067
3065 nHeights = volts.shape[2]
3068 nHeights = volts.shape[2]
3066 nPoints = volts.shape[1]
3069 nPoints = volts.shape[1]
3067 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3070 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3068
3071
3069 for i in range(len(pairslist)):
3072 for i in range(len(pairslist)):
3070 volts1 = volts[pairslist[i][0]]
3073 volts1 = volts[pairslist[i][0]]
3071 volts2 = volts[pairslist[i][1]]
3074 volts2 = volts[pairslist[i][1]]
3072
3075
3073 for t in range(len(laglist)):
3076 for t in range(len(laglist)):
3074 idxT = laglist[t]
3077 idxT = laglist[t]
3075 if idxT >= 0:
3078 if idxT >= 0:
3076 vStacked = numpy.vstack((volts2[idxT:,:],
3079 vStacked = numpy.vstack((volts2[idxT:,:],
3077 numpy.zeros((idxT, nHeights),dtype='complex')))
3080 numpy.zeros((idxT, nHeights),dtype='complex')))
3078 else:
3081 else:
3079 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3082 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3080 volts2[:(nPoints + idxT),:]))
3083 volts2[:(nPoints + idxT),:]))
3081 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3084 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3082
3085
3083 vStacked = None
3086 vStacked = None
3084 return voltsCCF
3087 return voltsCCF
3085
3088
3086 def __getNoise(self, power, timeSegment, timeInterval):
3089 def __getNoise(self, power, timeSegment, timeInterval):
3087 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3090 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3088 numBlocks = int(power.shape[0]/numProfPerBlock)
3091 numBlocks = int(power.shape[0]/numProfPerBlock)
3089 numHeights = power.shape[1]
3092 numHeights = power.shape[1]
3090
3093
3091 listPower = numpy.array_split(power, numBlocks, 0)
3094 listPower = numpy.array_split(power, numBlocks, 0)
3092 noise = numpy.zeros((power.shape[0], power.shape[1]))
3095 noise = numpy.zeros((power.shape[0], power.shape[1]))
3093 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3096 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3094
3097
3095 startInd = 0
3098 startInd = 0
3096 endInd = 0
3099 endInd = 0
3097
3100
3098 for i in range(numBlocks): #split por canal
3101 for i in range(numBlocks): #split por canal
3099 startInd = endInd
3102 startInd = endInd
3100 endInd = endInd + listPower[i].shape[0]
3103 endInd = endInd + listPower[i].shape[0]
3101
3104
3102 arrayBlock = listPower[i]
3105 arrayBlock = listPower[i]
3103 noiseAux = numpy.mean(arrayBlock, 0)
3106 noiseAux = numpy.mean(arrayBlock, 0)
3104 # noiseAux = numpy.median(noiseAux)
3107 # noiseAux = numpy.median(noiseAux)
3105 # noiseAux = numpy.mean(arrayBlock)
3108 # noiseAux = numpy.mean(arrayBlock)
3106 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3109 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3107
3110
3108 noiseAux1 = numpy.mean(arrayBlock)
3111 noiseAux1 = numpy.mean(arrayBlock)
3109 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3112 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3110
3113
3111 return noise, noise1
3114 return noise, noise1
3112
3115
3113 def __findMeteors(self, power, thresh):
3116 def __findMeteors(self, power, thresh):
3114 nProf = power.shape[0]
3117 nProf = power.shape[0]
3115 nHeights = power.shape[1]
3118 nHeights = power.shape[1]
3116 listMeteors = []
3119 listMeteors = []
3117
3120
3118 for i in range(nHeights):
3121 for i in range(nHeights):
3119 powerAux = power[:,i]
3122 powerAux = power[:,i]
3120 threshAux = thresh[:,i]
3123 threshAux = thresh[:,i]
3121
3124
3122 indUPthresh = numpy.where(powerAux > threshAux)[0]
3125 indUPthresh = numpy.where(powerAux > threshAux)[0]
3123 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3126 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3124
3127
3125 j = 0
3128 j = 0
3126
3129
3127 while (j < indUPthresh.size - 2):
3130 while (j < indUPthresh.size - 2):
3128 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3131 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3129 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3132 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3130 indDNthresh = indDNthresh[indDNAux]
3133 indDNthresh = indDNthresh[indDNAux]
3131
3134
3132 if (indDNthresh.size > 0):
3135 if (indDNthresh.size > 0):
3133 indEnd = indDNthresh[0] - 1
3136 indEnd = indDNthresh[0] - 1
3134 indInit = indUPthresh[j]
3137 indInit = indUPthresh[j]
3135
3138
3136 meteor = powerAux[indInit:indEnd + 1]
3139 meteor = powerAux[indInit:indEnd + 1]
3137 indPeak = meteor.argmax() + indInit
3140 indPeak = meteor.argmax() + indInit
3138 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3141 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3139
3142
3140 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3143 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3141 j = numpy.where(indUPthresh == indEnd)[0] + 1
3144 j = numpy.where(indUPthresh == indEnd)[0] + 1
3142 else: j+=1
3145 else: j+=1
3143 else: j+=1
3146 else: j+=1
3144
3147
3145 return listMeteors
3148 return listMeteors
3146
3149
3147 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3150 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3148
3151
3149 arrayMeteors = numpy.asarray(listMeteors)
3152 arrayMeteors = numpy.asarray(listMeteors)
3150 listMeteors1 = []
3153 listMeteors1 = []
3151
3154
3152 while arrayMeteors.shape[0] > 0:
3155 while arrayMeteors.shape[0] > 0:
3153 FLAs = arrayMeteors[:,4]
3156 FLAs = arrayMeteors[:,4]
3154 maxFLA = FLAs.argmax()
3157 maxFLA = FLAs.argmax()
3155 listMeteors1.append(arrayMeteors[maxFLA,:])
3158 listMeteors1.append(arrayMeteors[maxFLA,:])
3156
3159
3157 MeteorInitTime = arrayMeteors[maxFLA,1]
3160 MeteorInitTime = arrayMeteors[maxFLA,1]
3158 MeteorEndTime = arrayMeteors[maxFLA,3]
3161 MeteorEndTime = arrayMeteors[maxFLA,3]
3159 MeteorHeight = arrayMeteors[maxFLA,0]
3162 MeteorHeight = arrayMeteors[maxFLA,0]
3160
3163
3161 #Check neighborhood
3164 #Check neighborhood
3162 maxHeightIndex = MeteorHeight + rangeLimit
3165 maxHeightIndex = MeteorHeight + rangeLimit
3163 minHeightIndex = MeteorHeight - rangeLimit
3166 minHeightIndex = MeteorHeight - rangeLimit
3164 minTimeIndex = MeteorInitTime - timeLimit
3167 minTimeIndex = MeteorInitTime - timeLimit
3165 maxTimeIndex = MeteorEndTime + timeLimit
3168 maxTimeIndex = MeteorEndTime + timeLimit
3166
3169
3167 #Check Heights
3170 #Check Heights
3168 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3171 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3169 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3172 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3170 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3173 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3171
3174
3172 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3175 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3173
3176
3174 return listMeteors1
3177 return listMeteors1
3175
3178
3176 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3179 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3177 numHeights = volts.shape[2]
3180 numHeights = volts.shape[2]
3178 nChannel = volts.shape[0]
3181 nChannel = volts.shape[0]
3179
3182
3180 thresholdPhase = thresh[0]
3183 thresholdPhase = thresh[0]
3181 thresholdNoise = thresh[1]
3184 thresholdNoise = thresh[1]
3182 thresholdDB = float(thresh[2])
3185 thresholdDB = float(thresh[2])
3183
3186
3184 thresholdDB1 = 10**(thresholdDB/10)
3187 thresholdDB1 = 10**(thresholdDB/10)
3185 pairsarray = numpy.array(pairslist)
3188 pairsarray = numpy.array(pairslist)
3186 indSides = pairsarray[:,1]
3189 indSides = pairsarray[:,1]
3187
3190
3188 pairslist1 = list(pairslist)
3191 pairslist1 = list(pairslist)
3189 pairslist1.append((0,1))
3192 pairslist1.append((0,1))
3190 pairslist1.append((3,4))
3193 pairslist1.append((3,4))
3191
3194
3192 listMeteors1 = []
3195 listMeteors1 = []
3193 listPowerSeries = []
3196 listPowerSeries = []
3194 listVoltageSeries = []
3197 listVoltageSeries = []
3195 #volts has the war data
3198 #volts has the war data
3196
3199
3197 if frequency == 30e6:
3200 if frequency == 30e6:
3198 timeLag = 45*10**-3
3201 timeLag = 45*10**-3
3199 else:
3202 else:
3200 timeLag = 15*10**-3
3203 timeLag = 15*10**-3
3201 lag = numpy.ceil(timeLag/timeInterval)
3204 lag = numpy.ceil(timeLag/timeInterval)
3202
3205
3203 for i in range(len(listMeteors)):
3206 for i in range(len(listMeteors)):
3204
3207
3205 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3208 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3206 meteorAux = numpy.zeros(16)
3209 meteorAux = numpy.zeros(16)
3207
3210
3208 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3211 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3209 mHeight = listMeteors[i][0]
3212 mHeight = listMeteors[i][0]
3210 mStart = listMeteors[i][1]
3213 mStart = listMeteors[i][1]
3211 mPeak = listMeteors[i][2]
3214 mPeak = listMeteors[i][2]
3212 mEnd = listMeteors[i][3]
3215 mEnd = listMeteors[i][3]
3213
3216
3214 #get the volt data between the start and end times of the meteor
3217 #get the volt data between the start and end times of the meteor
3215 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3218 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3216 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3219 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3217
3220
3218 #3.6. Phase Difference estimation
3221 #3.6. Phase Difference estimation
3219 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3222 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3220
3223
3221 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3224 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3222 #meteorVolts0.- all Channels, all Profiles
3225 #meteorVolts0.- all Channels, all Profiles
3223 meteorVolts0 = volts[:,:,mHeight]
3226 meteorVolts0 = volts[:,:,mHeight]
3224 meteorThresh = noise[:,mHeight]*thresholdNoise
3227 meteorThresh = noise[:,mHeight]*thresholdNoise
3225 meteorNoise = noise[:,mHeight]
3228 meteorNoise = noise[:,mHeight]
3226 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3229 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3227 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3230 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3228
3231
3229 #Times reestimation
3232 #Times reestimation
3230 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3233 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3231 if mStart1.size > 0:
3234 if mStart1.size > 0:
3232 mStart1 = mStart1[-1] + 1
3235 mStart1 = mStart1[-1] + 1
3233
3236
3234 else:
3237 else:
3235 mStart1 = mPeak
3238 mStart1 = mPeak
3236
3239
3237 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3240 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3238 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3241 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3239 if mEndDecayTime1.size == 0:
3242 if mEndDecayTime1.size == 0:
3240 mEndDecayTime1 = powerNet0.size
3243 mEndDecayTime1 = powerNet0.size
3241 else:
3244 else:
3242 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3245 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3243 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3246 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3244
3247
3245 #meteorVolts1.- all Channels, from start to end
3248 #meteorVolts1.- all Channels, from start to end
3246 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3249 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3247 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3250 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3248 if meteorVolts2.shape[1] == 0:
3251 if meteorVolts2.shape[1] == 0:
3249 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3252 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3250 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3253 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3251 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3254 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3252 ##################### END PARAMETERS REESTIMATION #########################
3255 ##################### END PARAMETERS REESTIMATION #########################
3253
3256
3254 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3257 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3255 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3258 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3256 if meteorVolts2.shape[1] > 0:
3259 if meteorVolts2.shape[1] > 0:
3257 #Phase Difference re-estimation
3260 #Phase Difference re-estimation
3258 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3261 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3259 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3262 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3260 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3263 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3261 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3264 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3262 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3265 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3263
3266
3264 #Phase Difference RMS
3267 #Phase Difference RMS
3265 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3268 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3266 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3269 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3267 #Data from Meteor
3270 #Data from Meteor
3268 mPeak1 = powerNet1.argmax() + mStart1
3271 mPeak1 = powerNet1.argmax() + mStart1
3269 mPeakPower1 = powerNet1.max()
3272 mPeakPower1 = powerNet1.max()
3270 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3273 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3271 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3274 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3272 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3275 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3273 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3276 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3274 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3277 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3275 #Vectorize
3278 #Vectorize
3276 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3279 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3277 meteorAux[7:11] = phaseDiffint[0:4]
3280 meteorAux[7:11] = phaseDiffint[0:4]
3278
3281
3279 #Rejection Criterions
3282 #Rejection Criterions
3280 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3283 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3281 meteorAux[-1] = 17
3284 meteorAux[-1] = 17
3282 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3285 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3283 meteorAux[-1] = 1
3286 meteorAux[-1] = 1
3284
3287
3285
3288
3286 else:
3289 else:
3287 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3290 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3288 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3291 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3289 PowerSeries = 0
3292 PowerSeries = 0
3290
3293
3291 listMeteors1.append(meteorAux)
3294 listMeteors1.append(meteorAux)
3292 listPowerSeries.append(PowerSeries)
3295 listPowerSeries.append(PowerSeries)
3293 listVoltageSeries.append(meteorVolts1)
3296 listVoltageSeries.append(meteorVolts1)
3294
3297
3295 return listMeteors1, listPowerSeries, listVoltageSeries
3298 return listMeteors1, listPowerSeries, listVoltageSeries
3296
3299
3297 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3300 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3298
3301
3299 threshError = 10
3302 threshError = 10
3300 #Depending if it is 30 or 50 MHz
3303 #Depending if it is 30 or 50 MHz
3301 if frequency == 30e6:
3304 if frequency == 30e6:
3302 timeLag = 45*10**-3
3305 timeLag = 45*10**-3
3303 else:
3306 else:
3304 timeLag = 15*10**-3
3307 timeLag = 15*10**-3
3305 lag = numpy.ceil(timeLag/timeInterval)
3308 lag = numpy.ceil(timeLag/timeInterval)
3306
3309
3307 listMeteors1 = []
3310 listMeteors1 = []
3308
3311
3309 for i in range(len(listMeteors)):
3312 for i in range(len(listMeteors)):
3310 meteorPower = listPower[i]
3313 meteorPower = listPower[i]
3311 meteorAux = listMeteors[i]
3314 meteorAux = listMeteors[i]
3312
3315
3313 if meteorAux[-1] == 0:
3316 if meteorAux[-1] == 0:
3314
3317
3315 try:
3318 try:
3316 indmax = meteorPower.argmax()
3319 indmax = meteorPower.argmax()
3317 indlag = indmax + lag
3320 indlag = indmax + lag
3318
3321
3319 y = meteorPower[indlag:]
3322 y = meteorPower[indlag:]
3320 x = numpy.arange(0, y.size)*timeLag
3323 x = numpy.arange(0, y.size)*timeLag
3321
3324
3322 #first guess
3325 #first guess
3323 a = y[0]
3326 a = y[0]
3324 tau = timeLag
3327 tau = timeLag
3325 #exponential fit
3328 #exponential fit
3326 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3329 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3327 y1 = self.__exponential_function(x, *popt)
3330 y1 = self.__exponential_function(x, *popt)
3328 #error estimation
3331 #error estimation
3329 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3332 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3330
3333
3331 decayTime = popt[1]
3334 decayTime = popt[1]
3332 riseTime = indmax*timeInterval
3335 riseTime = indmax*timeInterval
3333 meteorAux[11:13] = [decayTime, error]
3336 meteorAux[11:13] = [decayTime, error]
3334
3337
3335 #Table items 7, 8 and 11
3338 #Table items 7, 8 and 11
3336 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3339 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3337 meteorAux[-1] = 7
3340 meteorAux[-1] = 7
3338 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3341 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3339 meteorAux[-1] = 8
3342 meteorAux[-1] = 8
3340 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3343 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3341 meteorAux[-1] = 11
3344 meteorAux[-1] = 11
3342
3345
3343
3346
3344 except:
3347 except:
3345 meteorAux[-1] = 11
3348 meteorAux[-1] = 11
3346
3349
3347
3350
3348 listMeteors1.append(meteorAux)
3351 listMeteors1.append(meteorAux)
3349
3352
3350 return listMeteors1
3353 return listMeteors1
3351
3354
3352 #Exponential Function
3355 #Exponential Function
3353
3356
3354 def __exponential_function(self, x, a, tau):
3357 def __exponential_function(self, x, a, tau):
3355 y = a*numpy.exp(-x/tau)
3358 y = a*numpy.exp(-x/tau)
3356 return y
3359 return y
3357
3360
3358 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3361 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3359
3362
3360 pairslist1 = list(pairslist)
3363 pairslist1 = list(pairslist)
3361 pairslist1.append((0,1))
3364 pairslist1.append((0,1))
3362 pairslist1.append((3,4))
3365 pairslist1.append((3,4))
3363 numPairs = len(pairslist1)
3366 numPairs = len(pairslist1)
3364 #Time Lag
3367 #Time Lag
3365 timeLag = 45*10**-3
3368 timeLag = 45*10**-3
3366 c = 3e8
3369 c = 3e8
3367 lag = numpy.ceil(timeLag/timeInterval)
3370 lag = numpy.ceil(timeLag/timeInterval)
3368 freq = 30e6
3371 freq = 30e6
3369
3372
3370 listMeteors1 = []
3373 listMeteors1 = []
3371
3374
3372 for i in range(len(listMeteors)):
3375 for i in range(len(listMeteors)):
3373 meteorAux = listMeteors[i]
3376 meteorAux = listMeteors[i]
3374 if meteorAux[-1] == 0:
3377 if meteorAux[-1] == 0:
3375 mStart = listMeteors[i][1]
3378 mStart = listMeteors[i][1]
3376 mPeak = listMeteors[i][2]
3379 mPeak = listMeteors[i][2]
3377 mLag = mPeak - mStart + lag
3380 mLag = mPeak - mStart + lag
3378
3381
3379 #get the volt data between the start and end times of the meteor
3382 #get the volt data between the start and end times of the meteor
3380 meteorVolts = listVolts[i]
3383 meteorVolts = listVolts[i]
3381 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3384 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3382
3385
3383 #Get CCF
3386 #Get CCF
3384 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3387 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3385
3388
3386 #Method 2
3389 #Method 2
3387 slopes = numpy.zeros(numPairs)
3390 slopes = numpy.zeros(numPairs)
3388 time = numpy.array([-2,-1,1,2])*timeInterval
3391 time = numpy.array([-2,-1,1,2])*timeInterval
3389 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3392 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3390
3393
3391 #Correct phases
3394 #Correct phases
3392 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3395 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3393 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3396 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3394
3397
3395 if indDer[0].shape[0] > 0:
3398 if indDer[0].shape[0] > 0:
3396 for i in range(indDer[0].shape[0]):
3399 for i in range(indDer[0].shape[0]):
3397 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3400 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3398 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3401 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3399
3402
3400 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3403 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3401 for j in range(numPairs):
3404 for j in range(numPairs):
3402 fit = stats.linregress(time, angAllCCF[j,:])
3405 fit = stats.linregress(time, angAllCCF[j,:])
3403 slopes[j] = fit[0]
3406 slopes[j] = fit[0]
3404
3407
3405 #Remove Outlier
3408 #Remove Outlier
3406 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3409 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3407 # slopes = numpy.delete(slopes,indOut)
3410 # slopes = numpy.delete(slopes,indOut)
3408 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3411 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3409 # slopes = numpy.delete(slopes,indOut)
3412 # slopes = numpy.delete(slopes,indOut)
3410
3413
3411 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3414 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3412 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3415 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3413 meteorAux[-2] = radialError
3416 meteorAux[-2] = radialError
3414 meteorAux[-3] = radialVelocity
3417 meteorAux[-3] = radialVelocity
3415
3418
3416 #Setting Error
3419 #Setting Error
3417 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3420 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3418 if numpy.abs(radialVelocity) > 200:
3421 if numpy.abs(radialVelocity) > 200:
3419 meteorAux[-1] = 15
3422 meteorAux[-1] = 15
3420 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3423 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3421 elif radialError > radialStdThresh:
3424 elif radialError > radialStdThresh:
3422 meteorAux[-1] = 12
3425 meteorAux[-1] = 12
3423
3426
3424 listMeteors1.append(meteorAux)
3427 listMeteors1.append(meteorAux)
3425 return listMeteors1
3428 return listMeteors1
3426
3429
3427 def __setNewArrays(self, listMeteors, date, heiRang):
3430 def __setNewArrays(self, listMeteors, date, heiRang):
3428
3431
3429 #New arrays
3432 #New arrays
3430 arrayMeteors = numpy.array(listMeteors)
3433 arrayMeteors = numpy.array(listMeteors)
3431 arrayParameters = numpy.zeros((len(listMeteors), 13))
3434 arrayParameters = numpy.zeros((len(listMeteors), 13))
3432
3435
3433 #Date inclusion
3436 #Date inclusion
3434 # date = re.findall(r'\((.*?)\)', date)
3437 # date = re.findall(r'\((.*?)\)', date)
3435 # date = date[0].split(',')
3438 # date = date[0].split(',')
3436 # date = map(int, date)
3439 # date = map(int, date)
3437 #
3440 #
3438 # if len(date)<6:
3441 # if len(date)<6:
3439 # date.append(0)
3442 # date.append(0)
3440 #
3443 #
3441 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3444 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3442 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3445 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3443 arrayDate = numpy.tile(date, (len(listMeteors)))
3446 arrayDate = numpy.tile(date, (len(listMeteors)))
3444
3447
3445 #Meteor array
3448 #Meteor array
3446 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3449 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3447 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3450 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3448
3451
3449 #Parameters Array
3452 #Parameters Array
3450 arrayParameters[:,0] = arrayDate #Date
3453 arrayParameters[:,0] = arrayDate #Date
3451 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3454 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3452 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3455 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3453 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3456 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3454 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3457 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3455
3458
3456
3459
3457 return arrayParameters
3460 return arrayParameters
3458
3461
3459 class CorrectSMPhases(Operation):
3462 class CorrectSMPhases(Operation):
3460
3463
3461 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3464 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3462
3465
3463 arrayParameters = dataOut.data_param
3466 arrayParameters = dataOut.data_param
3464 pairsList = []
3467 pairsList = []
3465 pairx = (0,1)
3468 pairx = (0,1)
3466 pairy = (2,3)
3469 pairy = (2,3)
3467 pairsList.append(pairx)
3470 pairsList.append(pairx)
3468 pairsList.append(pairy)
3471 pairsList.append(pairy)
3469 jph = numpy.zeros(4)
3472 jph = numpy.zeros(4)
3470
3473
3471 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3474 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3472 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3475 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3473 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3476 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3474
3477
3475 meteorOps = SMOperations()
3478 meteorOps = SMOperations()
3476 if channelPositions == None:
3479 if channelPositions == None:
3477 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3480 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3478 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3481 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3479
3482
3480 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3483 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3481 h = (hmin,hmax)
3484 h = (hmin,hmax)
3482
3485
3483 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3486 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3484
3487
3485 dataOut.data_param = arrayParameters
3488 dataOut.data_param = arrayParameters
3486 return
3489 return
3487
3490
3488 class SMPhaseCalibration(Operation):
3491 class SMPhaseCalibration(Operation):
3489
3492
3490 __buffer = None
3493 __buffer = None
3491
3494
3492 __initime = None
3495 __initime = None
3493
3496
3494 __dataReady = False
3497 __dataReady = False
3495
3498
3496 __isConfig = False
3499 __isConfig = False
3497
3500
3498 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3501 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3499
3502
3500 dataTime = currentTime + paramInterval
3503 dataTime = currentTime + paramInterval
3501 deltaTime = dataTime - initTime
3504 deltaTime = dataTime - initTime
3502
3505
3503 if deltaTime >= outputInterval or deltaTime < 0:
3506 if deltaTime >= outputInterval or deltaTime < 0:
3504 return True
3507 return True
3505
3508
3506 return False
3509 return False
3507
3510
3508 def __getGammas(self, pairs, d, phases):
3511 def __getGammas(self, pairs, d, phases):
3509 gammas = numpy.zeros(2)
3512 gammas = numpy.zeros(2)
3510
3513
3511 for i in range(len(pairs)):
3514 for i in range(len(pairs)):
3512
3515
3513 pairi = pairs[i]
3516 pairi = pairs[i]
3514
3517
3515 phip3 = phases[:,pairi[0]]
3518 phip3 = phases[:,pairi[0]]
3516 d3 = d[pairi[0]]
3519 d3 = d[pairi[0]]
3517 phip2 = phases[:,pairi[1]]
3520 phip2 = phases[:,pairi[1]]
3518 d2 = d[pairi[1]]
3521 d2 = d[pairi[1]]
3519 #Calculating gamma
3522 #Calculating gamma
3520 # jdcos = alp1/(k*d1)
3523 # jdcos = alp1/(k*d1)
3521 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3524 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3522 jgamma = -phip2*d3/d2 - phip3
3525 jgamma = -phip2*d3/d2 - phip3
3523 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3526 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3524 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3527 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3525 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3528 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3526
3529
3527 #Revised distribution
3530 #Revised distribution
3528 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3531 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3529
3532
3530 #Histogram
3533 #Histogram
3531 nBins = 64
3534 nBins = 64
3532 rmin = -0.5*numpy.pi
3535 rmin = -0.5*numpy.pi
3533 rmax = 0.5*numpy.pi
3536 rmax = 0.5*numpy.pi
3534 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3537 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3535
3538
3536 meteorsY = phaseHisto[0]
3539 meteorsY = phaseHisto[0]
3537 phasesX = phaseHisto[1][:-1]
3540 phasesX = phaseHisto[1][:-1]
3538 width = phasesX[1] - phasesX[0]
3541 width = phasesX[1] - phasesX[0]
3539 phasesX += width/2
3542 phasesX += width/2
3540
3543
3541 #Gaussian aproximation
3544 #Gaussian aproximation
3542 bpeak = meteorsY.argmax()
3545 bpeak = meteorsY.argmax()
3543 peak = meteorsY.max()
3546 peak = meteorsY.max()
3544 jmin = bpeak - 5
3547 jmin = bpeak - 5
3545 jmax = bpeak + 5 + 1
3548 jmax = bpeak + 5 + 1
3546
3549
3547 if jmin<0:
3550 if jmin<0:
3548 jmin = 0
3551 jmin = 0
3549 jmax = 6
3552 jmax = 6
3550 elif jmax > meteorsY.size:
3553 elif jmax > meteorsY.size:
3551 jmin = meteorsY.size - 6
3554 jmin = meteorsY.size - 6
3552 jmax = meteorsY.size
3555 jmax = meteorsY.size
3553
3556
3554 x0 = numpy.array([peak,bpeak,50])
3557 x0 = numpy.array([peak,bpeak,50])
3555 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3558 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3556
3559
3557 #Gammas
3560 #Gammas
3558 gammas[i] = coeff[0][1]
3561 gammas[i] = coeff[0][1]
3559
3562
3560 return gammas
3563 return gammas
3561
3564
3562 def __residualFunction(self, coeffs, y, t):
3565 def __residualFunction(self, coeffs, y, t):
3563
3566
3564 return y - self.__gauss_function(t, coeffs)
3567 return y - self.__gauss_function(t, coeffs)
3565
3568
3566 def __gauss_function(self, t, coeffs):
3569 def __gauss_function(self, t, coeffs):
3567
3570
3568 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3571 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3569
3572
3570 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3573 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3571 meteorOps = SMOperations()
3574 meteorOps = SMOperations()
3572 nchan = 4
3575 nchan = 4
3573 pairx = pairsList[0] #x es 0
3576 pairx = pairsList[0] #x es 0
3574 pairy = pairsList[1] #y es 1
3577 pairy = pairsList[1] #y es 1
3575 center_xangle = 0
3578 center_xangle = 0
3576 center_yangle = 0
3579 center_yangle = 0
3577 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3580 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3578 ntimes = len(range_angle)
3581 ntimes = len(range_angle)
3579
3582
3580 nstepsx = 20
3583 nstepsx = 20
3581 nstepsy = 20
3584 nstepsy = 20
3582
3585
3583 for iz in range(ntimes):
3586 for iz in range(ntimes):
3584 min_xangle = -range_angle[iz]/2 + center_xangle
3587 min_xangle = -range_angle[iz]/2 + center_xangle
3585 max_xangle = range_angle[iz]/2 + center_xangle
3588 max_xangle = range_angle[iz]/2 + center_xangle
3586 min_yangle = -range_angle[iz]/2 + center_yangle
3589 min_yangle = -range_angle[iz]/2 + center_yangle
3587 max_yangle = range_angle[iz]/2 + center_yangle
3590 max_yangle = range_angle[iz]/2 + center_yangle
3588
3591
3589 inc_x = (max_xangle-min_xangle)/nstepsx
3592 inc_x = (max_xangle-min_xangle)/nstepsx
3590 inc_y = (max_yangle-min_yangle)/nstepsy
3593 inc_y = (max_yangle-min_yangle)/nstepsy
3591
3594
3592 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3595 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3593 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3596 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3594 penalty = numpy.zeros((nstepsx,nstepsy))
3597 penalty = numpy.zeros((nstepsx,nstepsy))
3595 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3598 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3596 jph = numpy.zeros(nchan)
3599 jph = numpy.zeros(nchan)
3597
3600
3598 # Iterations looking for the offset
3601 # Iterations looking for the offset
3599 for iy in range(int(nstepsy)):
3602 for iy in range(int(nstepsy)):
3600 for ix in range(int(nstepsx)):
3603 for ix in range(int(nstepsx)):
3601 d3 = d[pairsList[1][0]]
3604 d3 = d[pairsList[1][0]]
3602 d2 = d[pairsList[1][1]]
3605 d2 = d[pairsList[1][1]]
3603 d5 = d[pairsList[0][0]]
3606 d5 = d[pairsList[0][0]]
3604 d4 = d[pairsList[0][1]]
3607 d4 = d[pairsList[0][1]]
3605
3608
3606 alp2 = alpha_y[iy] #gamma 1
3609 alp2 = alpha_y[iy] #gamma 1
3607 alp4 = alpha_x[ix] #gamma 0
3610 alp4 = alpha_x[ix] #gamma 0
3608
3611
3609 alp3 = -alp2*d3/d2 - gammas[1]
3612 alp3 = -alp2*d3/d2 - gammas[1]
3610 alp5 = -alp4*d5/d4 - gammas[0]
3613 alp5 = -alp4*d5/d4 - gammas[0]
3611 # jph[pairy[1]] = alpha_y[iy]
3614 # jph[pairy[1]] = alpha_y[iy]
3612 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3615 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3613
3616
3614 # jph[pairx[1]] = alpha_x[ix]
3617 # jph[pairx[1]] = alpha_x[ix]
3615 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3618 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3616 jph[pairsList[0][1]] = alp4
3619 jph[pairsList[0][1]] = alp4
3617 jph[pairsList[0][0]] = alp5
3620 jph[pairsList[0][0]] = alp5
3618 jph[pairsList[1][0]] = alp3
3621 jph[pairsList[1][0]] = alp3
3619 jph[pairsList[1][1]] = alp2
3622 jph[pairsList[1][1]] = alp2
3620 jph_array[:,ix,iy] = jph
3623 jph_array[:,ix,iy] = jph
3621 # d = [2.0,2.5,2.5,2.0]
3624 # d = [2.0,2.5,2.5,2.0]
3622 #falta chequear si va a leer bien los meteoros
3625 #falta chequear si va a leer bien los meteoros
3623 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3626 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3624 error = meteorsArray1[:,-1]
3627 error = meteorsArray1[:,-1]
3625 ind1 = numpy.where(error==0)[0]
3628 ind1 = numpy.where(error==0)[0]
3626 penalty[ix,iy] = ind1.size
3629 penalty[ix,iy] = ind1.size
3627
3630
3628 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3631 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3629 phOffset = jph_array[:,i,j]
3632 phOffset = jph_array[:,i,j]
3630
3633
3631 center_xangle = phOffset[pairx[1]]
3634 center_xangle = phOffset[pairx[1]]
3632 center_yangle = phOffset[pairy[1]]
3635 center_yangle = phOffset[pairy[1]]
3633
3636
3634 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3637 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3635 phOffset = phOffset*180/numpy.pi
3638 phOffset = phOffset*180/numpy.pi
3636 return phOffset
3639 return phOffset
3637
3640
3638
3641
3639 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3642 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3640
3643
3641 dataOut.flagNoData = True
3644 dataOut.flagNoData = True
3642 self.__dataReady = False
3645 self.__dataReady = False
3643 dataOut.outputInterval = nHours*3600
3646 dataOut.outputInterval = nHours*3600
3644
3647
3645 if self.__isConfig == False:
3648 if self.__isConfig == False:
3646 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3649 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3647 #Get Initial LTC time
3650 #Get Initial LTC time
3648 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3651 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3649 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3652 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3650
3653
3651 self.__isConfig = True
3654 self.__isConfig = True
3652
3655
3653 if self.__buffer == None:
3656 if self.__buffer == None:
3654 self.__buffer = dataOut.data_param.copy()
3657 self.__buffer = dataOut.data_param.copy()
3655
3658
3656 else:
3659 else:
3657 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3660 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3658
3661
3659 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3662 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3660
3663
3661 if self.__dataReady:
3664 if self.__dataReady:
3662 dataOut.utctimeInit = self.__initime
3665 dataOut.utctimeInit = self.__initime
3663 self.__initime += dataOut.outputInterval #to erase time offset
3666 self.__initime += dataOut.outputInterval #to erase time offset
3664
3667
3665 freq = dataOut.frequency
3668 freq = dataOut.frequency
3666 c = dataOut.C #m/s
3669 c = dataOut.C #m/s
3667 lamb = c/freq
3670 lamb = c/freq
3668 k = 2*numpy.pi/lamb
3671 k = 2*numpy.pi/lamb
3669 azimuth = 0
3672 azimuth = 0
3670 h = (hmin, hmax)
3673 h = (hmin, hmax)
3671 # pairs = ((0,1),(2,3)) #Estrella
3674 # pairs = ((0,1),(2,3)) #Estrella
3672 # pairs = ((1,0),(2,3)) #T
3675 # pairs = ((1,0),(2,3)) #T
3673
3676
3674 if channelPositions is None:
3677 if channelPositions is None:
3675 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3678 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3676 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3679 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3677 meteorOps = SMOperations()
3680 meteorOps = SMOperations()
3678 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3681 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3679
3682
3680 #Checking correct order of pairs
3683 #Checking correct order of pairs
3681 pairs = []
3684 pairs = []
3682 if distances[1] > distances[0]:
3685 if distances[1] > distances[0]:
3683 pairs.append((1,0))
3686 pairs.append((1,0))
3684 else:
3687 else:
3685 pairs.append((0,1))
3688 pairs.append((0,1))
3686
3689
3687 if distances[3] > distances[2]:
3690 if distances[3] > distances[2]:
3688 pairs.append((3,2))
3691 pairs.append((3,2))
3689 else:
3692 else:
3690 pairs.append((2,3))
3693 pairs.append((2,3))
3691 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3694 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3692
3695
3693 meteorsArray = self.__buffer
3696 meteorsArray = self.__buffer
3694 error = meteorsArray[:,-1]
3697 error = meteorsArray[:,-1]
3695 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3698 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3696 ind1 = numpy.where(boolError)[0]
3699 ind1 = numpy.where(boolError)[0]
3697 meteorsArray = meteorsArray[ind1,:]
3700 meteorsArray = meteorsArray[ind1,:]
3698 meteorsArray[:,-1] = 0
3701 meteorsArray[:,-1] = 0
3699 phases = meteorsArray[:,8:12]
3702 phases = meteorsArray[:,8:12]
3700
3703
3701 #Calculate Gammas
3704 #Calculate Gammas
3702 gammas = self.__getGammas(pairs, distances, phases)
3705 gammas = self.__getGammas(pairs, distances, phases)
3703 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3706 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3704 #Calculate Phases
3707 #Calculate Phases
3705 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3708 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3706 phasesOff = phasesOff.reshape((1,phasesOff.size))
3709 phasesOff = phasesOff.reshape((1,phasesOff.size))
3707 dataOut.data_output = -phasesOff
3710 dataOut.data_output = -phasesOff
3708 dataOut.flagNoData = False
3711 dataOut.flagNoData = False
3709 self.__buffer = None
3712 self.__buffer = None
3710
3713
3711
3714
3712 return
3715 return
3713
3716
3714 class SMOperations():
3717 class SMOperations():
3715
3718
3716 def __init__(self):
3719 def __init__(self):
3717
3720
3718 return
3721 return
3719
3722
3720 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3723 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3721
3724
3722 arrayParameters = arrayParameters0.copy()
3725 arrayParameters = arrayParameters0.copy()
3723 hmin = h[0]
3726 hmin = h[0]
3724 hmax = h[1]
3727 hmax = h[1]
3725
3728
3726 #Calculate AOA (Error N 3, 4)
3729 #Calculate AOA (Error N 3, 4)
3727 #JONES ET AL. 1998
3730 #JONES ET AL. 1998
3728 AOAthresh = numpy.pi/8
3731 AOAthresh = numpy.pi/8
3729 error = arrayParameters[:,-1]
3732 error = arrayParameters[:,-1]
3730 phases = -arrayParameters[:,8:12] + jph
3733 phases = -arrayParameters[:,8:12] + jph
3731 # phases = numpy.unwrap(phases)
3734 # phases = numpy.unwrap(phases)
3732 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3735 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3733
3736
3734 #Calculate Heights (Error N 13 and 14)
3737 #Calculate Heights (Error N 13 and 14)
3735 error = arrayParameters[:,-1]
3738 error = arrayParameters[:,-1]
3736 Ranges = arrayParameters[:,1]
3739 Ranges = arrayParameters[:,1]
3737 zenith = arrayParameters[:,4]
3740 zenith = arrayParameters[:,4]
3738 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3741 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3739
3742
3740 #----------------------- Get Final data ------------------------------------
3743 #----------------------- Get Final data ------------------------------------
3741 # error = arrayParameters[:,-1]
3744 # error = arrayParameters[:,-1]
3742 # ind1 = numpy.where(error==0)[0]
3745 # ind1 = numpy.where(error==0)[0]
3743 # arrayParameters = arrayParameters[ind1,:]
3746 # arrayParameters = arrayParameters[ind1,:]
3744
3747
3745 return arrayParameters
3748 return arrayParameters
3746
3749
3747 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3750 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3748
3751
3749 arrayAOA = numpy.zeros((phases.shape[0],3))
3752 arrayAOA = numpy.zeros((phases.shape[0],3))
3750 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3753 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3751
3754
3752 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3755 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3753 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3756 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3754 arrayAOA[:,2] = cosDirError
3757 arrayAOA[:,2] = cosDirError
3755
3758
3756 azimuthAngle = arrayAOA[:,0]
3759 azimuthAngle = arrayAOA[:,0]
3757 zenithAngle = arrayAOA[:,1]
3760 zenithAngle = arrayAOA[:,1]
3758
3761
3759 #Setting Error
3762 #Setting Error
3760 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3763 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3761 error[indError] = 0
3764 error[indError] = 0
3762 #Number 3: AOA not fesible
3765 #Number 3: AOA not fesible
3763 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3766 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3764 error[indInvalid] = 3
3767 error[indInvalid] = 3
3765 #Number 4: Large difference in AOAs obtained from different antenna baselines
3768 #Number 4: Large difference in AOAs obtained from different antenna baselines
3766 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3769 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3767 error[indInvalid] = 4
3770 error[indInvalid] = 4
3768 return arrayAOA, error
3771 return arrayAOA, error
3769
3772
3770 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3773 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3771
3774
3772 #Initializing some variables
3775 #Initializing some variables
3773 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3776 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3774 ang_aux = ang_aux.reshape(1,ang_aux.size)
3777 ang_aux = ang_aux.reshape(1,ang_aux.size)
3775
3778
3776 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3779 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3777 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3780 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3778
3781
3779
3782
3780 for i in range(2):
3783 for i in range(2):
3781 ph0 = arrayPhase[:,pairsList[i][0]]
3784 ph0 = arrayPhase[:,pairsList[i][0]]
3782 ph1 = arrayPhase[:,pairsList[i][1]]
3785 ph1 = arrayPhase[:,pairsList[i][1]]
3783 d0 = distances[pairsList[i][0]]
3786 d0 = distances[pairsList[i][0]]
3784 d1 = distances[pairsList[i][1]]
3787 d1 = distances[pairsList[i][1]]
3785
3788
3786 ph0_aux = ph0 + ph1
3789 ph0_aux = ph0 + ph1
3787 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3790 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3788 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3791 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3789 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3792 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3790 #First Estimation
3793 #First Estimation
3791 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3794 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3792
3795
3793 #Most-Accurate Second Estimation
3796 #Most-Accurate Second Estimation
3794 phi1_aux = ph0 - ph1
3797 phi1_aux = ph0 - ph1
3795 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3798 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3796 #Direction Cosine 1
3799 #Direction Cosine 1
3797 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3800 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3798
3801
3799 #Searching the correct Direction Cosine
3802 #Searching the correct Direction Cosine
3800 cosdir0_aux = cosdir0[:,i]
3803 cosdir0_aux = cosdir0[:,i]
3801 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3804 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3802 #Minimum Distance
3805 #Minimum Distance
3803 cosDiff = (cosdir1 - cosdir0_aux)**2
3806 cosDiff = (cosdir1 - cosdir0_aux)**2
3804 indcos = cosDiff.argmin(axis = 1)
3807 indcos = cosDiff.argmin(axis = 1)
3805 #Saving Value obtained
3808 #Saving Value obtained
3806 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3809 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3807
3810
3808 return cosdir0, cosdir
3811 return cosdir0, cosdir
3809
3812
3810 def __calculateAOA(self, cosdir, azimuth):
3813 def __calculateAOA(self, cosdir, azimuth):
3811 cosdirX = cosdir[:,0]
3814 cosdirX = cosdir[:,0]
3812 cosdirY = cosdir[:,1]
3815 cosdirY = cosdir[:,1]
3813
3816
3814 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3817 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3815 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3818 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3816 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3819 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3817
3820
3818 return angles
3821 return angles
3819
3822
3820 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3823 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3821
3824
3822 Ramb = 375 #Ramb = c/(2*PRF)
3825 Ramb = 375 #Ramb = c/(2*PRF)
3823 Re = 6371 #Earth Radius
3826 Re = 6371 #Earth Radius
3824 heights = numpy.zeros(Ranges.shape)
3827 heights = numpy.zeros(Ranges.shape)
3825
3828
3826 R_aux = numpy.array([0,1,2])*Ramb
3829 R_aux = numpy.array([0,1,2])*Ramb
3827 R_aux = R_aux.reshape(1,R_aux.size)
3830 R_aux = R_aux.reshape(1,R_aux.size)
3828
3831
3829 Ranges = Ranges.reshape(Ranges.size,1)
3832 Ranges = Ranges.reshape(Ranges.size,1)
3830
3833
3831 Ri = Ranges + R_aux
3834 Ri = Ranges + R_aux
3832 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3835 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3833
3836
3834 #Check if there is a height between 70 and 110 km
3837 #Check if there is a height between 70 and 110 km
3835 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3838 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3836 ind_h = numpy.where(h_bool == 1)[0]
3839 ind_h = numpy.where(h_bool == 1)[0]
3837
3840
3838 hCorr = hi[ind_h, :]
3841 hCorr = hi[ind_h, :]
3839 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3842 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3840
3843
3841 hCorr = hi[ind_hCorr][:len(ind_h)]
3844 hCorr = hi[ind_hCorr][:len(ind_h)]
3842 heights[ind_h] = hCorr
3845 heights[ind_h] = hCorr
3843
3846
3844 #Setting Error
3847 #Setting Error
3845 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3848 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3846 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3849 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3847 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3850 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3848 error[indError] = 0
3851 error[indError] = 0
3849 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3852 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3850 error[indInvalid2] = 14
3853 error[indInvalid2] = 14
3851 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3854 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3852 error[indInvalid1] = 13
3855 error[indInvalid1] = 13
3853
3856
3854 return heights, error
3857 return heights, error
3855
3858
3856 def getPhasePairs(self, channelPositions):
3859 def getPhasePairs(self, channelPositions):
3857 chanPos = numpy.array(channelPositions)
3860 chanPos = numpy.array(channelPositions)
3858 listOper = list(itertools.combinations(range(5),2))
3861 listOper = list(itertools.combinations(range(5),2))
3859
3862
3860 distances = numpy.zeros(4)
3863 distances = numpy.zeros(4)
3861 axisX = []
3864 axisX = []
3862 axisY = []
3865 axisY = []
3863 distX = numpy.zeros(3)
3866 distX = numpy.zeros(3)
3864 distY = numpy.zeros(3)
3867 distY = numpy.zeros(3)
3865 ix = 0
3868 ix = 0
3866 iy = 0
3869 iy = 0
3867
3870
3868 pairX = numpy.zeros((2,2))
3871 pairX = numpy.zeros((2,2))
3869 pairY = numpy.zeros((2,2))
3872 pairY = numpy.zeros((2,2))
3870
3873
3871 for i in range(len(listOper)):
3874 for i in range(len(listOper)):
3872 pairi = listOper[i]
3875 pairi = listOper[i]
3873
3876
3874 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3877 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3875
3878
3876 if posDif[0] == 0:
3879 if posDif[0] == 0:
3877 axisY.append(pairi)
3880 axisY.append(pairi)
3878 distY[iy] = posDif[1]
3881 distY[iy] = posDif[1]
3879 iy += 1
3882 iy += 1
3880 elif posDif[1] == 0:
3883 elif posDif[1] == 0:
3881 axisX.append(pairi)
3884 axisX.append(pairi)
3882 distX[ix] = posDif[0]
3885 distX[ix] = posDif[0]
3883 ix += 1
3886 ix += 1
3884
3887
3885 for i in range(2):
3888 for i in range(2):
3886 if i==0:
3889 if i==0:
3887 dist0 = distX
3890 dist0 = distX
3888 axis0 = axisX
3891 axis0 = axisX
3889 else:
3892 else:
3890 dist0 = distY
3893 dist0 = distY
3891 axis0 = axisY
3894 axis0 = axisY
3892
3895
3893 side = numpy.argsort(dist0)[:-1]
3896 side = numpy.argsort(dist0)[:-1]
3894 axis0 = numpy.array(axis0)[side,:]
3897 axis0 = numpy.array(axis0)[side,:]
3895 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3898 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3896 axis1 = numpy.unique(numpy.reshape(axis0,4))
3899 axis1 = numpy.unique(numpy.reshape(axis0,4))
3897 side = axis1[axis1 != chanC]
3900 side = axis1[axis1 != chanC]
3898 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3901 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3899 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3902 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3900 if diff1<0:
3903 if diff1<0:
3901 chan2 = side[0]
3904 chan2 = side[0]
3902 d2 = numpy.abs(diff1)
3905 d2 = numpy.abs(diff1)
3903 chan1 = side[1]
3906 chan1 = side[1]
3904 d1 = numpy.abs(diff2)
3907 d1 = numpy.abs(diff2)
3905 else:
3908 else:
3906 chan2 = side[1]
3909 chan2 = side[1]
3907 d2 = numpy.abs(diff2)
3910 d2 = numpy.abs(diff2)
3908 chan1 = side[0]
3911 chan1 = side[0]
3909 d1 = numpy.abs(diff1)
3912 d1 = numpy.abs(diff1)
3910
3913
3911 if i==0:
3914 if i==0:
3912 chanCX = chanC
3915 chanCX = chanC
3913 chan1X = chan1
3916 chan1X = chan1
3914 chan2X = chan2
3917 chan2X = chan2
3915 distances[0:2] = numpy.array([d1,d2])
3918 distances[0:2] = numpy.array([d1,d2])
3916 else:
3919 else:
3917 chanCY = chanC
3920 chanCY = chanC
3918 chan1Y = chan1
3921 chan1Y = chan1
3919 chan2Y = chan2
3922 chan2Y = chan2
3920 distances[2:4] = numpy.array([d1,d2])
3923 distances[2:4] = numpy.array([d1,d2])
3921 # axisXsides = numpy.reshape(axisX[ix,:],4)
3924 # axisXsides = numpy.reshape(axisX[ix,:],4)
3922 #
3925 #
3923 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3926 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3924 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3927 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3925 #
3928 #
3926 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3929 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3927 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3930 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3928 # channel25X = int(pairX[0,ind25X])
3931 # channel25X = int(pairX[0,ind25X])
3929 # channel20X = int(pairX[1,ind20X])
3932 # channel20X = int(pairX[1,ind20X])
3930 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3933 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3931 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3934 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3932 # channel25Y = int(pairY[0,ind25Y])
3935 # channel25Y = int(pairY[0,ind25Y])
3933 # channel20Y = int(pairY[1,ind20Y])
3936 # channel20Y = int(pairY[1,ind20Y])
3934
3937
3935 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3938 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3936 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3939 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3937
3940
3938 return pairslist, distances
3941 return pairslist, distances
3939 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3942 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3940 #
3943 #
3941 # arrayAOA = numpy.zeros((phases.shape[0],3))
3944 # arrayAOA = numpy.zeros((phases.shape[0],3))
3942 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3945 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3943 #
3946 #
3944 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3947 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3945 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3948 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3946 # arrayAOA[:,2] = cosDirError
3949 # arrayAOA[:,2] = cosDirError
3947 #
3950 #
3948 # azimuthAngle = arrayAOA[:,0]
3951 # azimuthAngle = arrayAOA[:,0]
3949 # zenithAngle = arrayAOA[:,1]
3952 # zenithAngle = arrayAOA[:,1]
3950 #
3953 #
3951 # #Setting Error
3954 # #Setting Error
3952 # #Number 3: AOA not fesible
3955 # #Number 3: AOA not fesible
3953 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3956 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3954 # error[indInvalid] = 3
3957 # error[indInvalid] = 3
3955 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3958 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3956 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3959 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3957 # error[indInvalid] = 4
3960 # error[indInvalid] = 4
3958 # return arrayAOA, error
3961 # return arrayAOA, error
3959 #
3962 #
3960 # def __getDirectionCosines(self, arrayPhase, pairsList):
3963 # def __getDirectionCosines(self, arrayPhase, pairsList):
3961 #
3964 #
3962 # #Initializing some variables
3965 # #Initializing some variables
3963 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3966 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3964 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3967 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3965 #
3968 #
3966 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3969 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3967 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3970 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3968 #
3971 #
3969 #
3972 #
3970 # for i in range(2):
3973 # for i in range(2):
3971 # #First Estimation
3974 # #First Estimation
3972 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3975 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3973 # #Dealias
3976 # #Dealias
3974 # indcsi = numpy.where(phi0_aux > numpy.pi)
3977 # indcsi = numpy.where(phi0_aux > numpy.pi)
3975 # phi0_aux[indcsi] -= 2*numpy.pi
3978 # phi0_aux[indcsi] -= 2*numpy.pi
3976 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3979 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3977 # phi0_aux[indcsi] += 2*numpy.pi
3980 # phi0_aux[indcsi] += 2*numpy.pi
3978 # #Direction Cosine 0
3981 # #Direction Cosine 0
3979 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3982 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3980 #
3983 #
3981 # #Most-Accurate Second Estimation
3984 # #Most-Accurate Second Estimation
3982 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3985 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3983 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3986 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3984 # #Direction Cosine 1
3987 # #Direction Cosine 1
3985 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3988 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3986 #
3989 #
3987 # #Searching the correct Direction Cosine
3990 # #Searching the correct Direction Cosine
3988 # cosdir0_aux = cosdir0[:,i]
3991 # cosdir0_aux = cosdir0[:,i]
3989 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3992 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3990 # #Minimum Distance
3993 # #Minimum Distance
3991 # cosDiff = (cosdir1 - cosdir0_aux)**2
3994 # cosDiff = (cosdir1 - cosdir0_aux)**2
3992 # indcos = cosDiff.argmin(axis = 1)
3995 # indcos = cosDiff.argmin(axis = 1)
3993 # #Saving Value obtained
3996 # #Saving Value obtained
3994 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3997 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3995 #
3998 #
3996 # return cosdir0, cosdir
3999 # return cosdir0, cosdir
3997 #
4000 #
3998 # def __calculateAOA(self, cosdir, azimuth):
4001 # def __calculateAOA(self, cosdir, azimuth):
3999 # cosdirX = cosdir[:,0]
4002 # cosdirX = cosdir[:,0]
4000 # cosdirY = cosdir[:,1]
4003 # cosdirY = cosdir[:,1]
4001 #
4004 #
4002 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
4005 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
4003 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
4006 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
4004 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
4007 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
4005 #
4008 #
4006 # return angles
4009 # return angles
4007 #
4010 #
4008 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
4011 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
4009 #
4012 #
4010 # Ramb = 375 #Ramb = c/(2*PRF)
4013 # Ramb = 375 #Ramb = c/(2*PRF)
4011 # Re = 6371 #Earth Radius
4014 # Re = 6371 #Earth Radius
4012 # heights = numpy.zeros(Ranges.shape)
4015 # heights = numpy.zeros(Ranges.shape)
4013 #
4016 #
4014 # R_aux = numpy.array([0,1,2])*Ramb
4017 # R_aux = numpy.array([0,1,2])*Ramb
4015 # R_aux = R_aux.reshape(1,R_aux.size)
4018 # R_aux = R_aux.reshape(1,R_aux.size)
4016 #
4019 #
4017 # Ranges = Ranges.reshape(Ranges.size,1)
4020 # Ranges = Ranges.reshape(Ranges.size,1)
4018 #
4021 #
4019 # Ri = Ranges + R_aux
4022 # Ri = Ranges + R_aux
4020 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
4023 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
4021 #
4024 #
4022 # #Check if there is a height between 70 and 110 km
4025 # #Check if there is a height between 70 and 110 km
4023 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
4026 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
4024 # ind_h = numpy.where(h_bool == 1)[0]
4027 # ind_h = numpy.where(h_bool == 1)[0]
4025 #
4028 #
4026 # hCorr = hi[ind_h, :]
4029 # hCorr = hi[ind_h, :]
4027 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
4030 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
4028 #
4031 #
4029 # hCorr = hi[ind_hCorr]
4032 # hCorr = hi[ind_hCorr]
4030 # heights[ind_h] = hCorr
4033 # heights[ind_h] = hCorr
4031 #
4034 #
4032 # #Setting Error
4035 # #Setting Error
4033 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
4036 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
4034 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
4037 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
4035 #
4038 #
4036 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
4039 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
4037 # error[indInvalid2] = 14
4040 # error[indInvalid2] = 14
4038 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
4041 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
4039 # error[indInvalid1] = 13
4042 # error[indInvalid1] = 13
4040 #
4043 #
4041 # return heights, error
4044 # return heights, error
4042 No newline at end of file
4045
@@ -1,604 +1,607
1 '''
1 '''
2 @author: Juan C. Espinoza
2 @author: Juan C. Espinoza
3 '''
3 '''
4
4
5 import time
5 import time
6 import json
6 import json
7 import numpy
7 import numpy
8 import paho.mqtt.client as mqtt
8 import paho.mqtt.client as mqtt
9 import zmq
9 import zmq
10 import datetime
10 import datetime
11 from zmq.utils.monitor import recv_monitor_message
11 from zmq.utils.monitor import recv_monitor_message
12 from functools import wraps
12 from functools import wraps
13 from threading import Thread
13 from threading import Thread
14 from multiprocessing import Process
14 from multiprocessing import Process
15
15
16 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
16 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
17 from schainpy.model.data.jrodata import JROData
17 from schainpy.model.data.jrodata import JROData
18 from schainpy.utils import log
18 from schainpy.utils import log
19
19
20 MAXNUMX = 100
20 MAXNUMX = 100
21 MAXNUMY = 100
21 MAXNUMY = 100
22
22
23 class PrettyFloat(float):
23 class PrettyFloat(float):
24 def __repr__(self):
24 def __repr__(self):
25 return '%.2f' % self
25 return '%.2f' % self
26
26
27 def roundFloats(obj):
27 def roundFloats(obj):
28 if isinstance(obj, list):
28 if isinstance(obj, list):
29 return map(roundFloats, obj)
29 return map(roundFloats, obj)
30 elif isinstance(obj, float):
30 elif isinstance(obj, float):
31 return round(obj, 2)
31 return round(obj, 2)
32
32
33 def decimate(z, MAXNUMY):
33 def decimate(z, MAXNUMY):
34 dy = int(len(z[0])/MAXNUMY) + 1
34 dy = int(len(z[0])/MAXNUMY) + 1
35
35
36 return z[::, ::dy]
36 return z[::, ::dy]
37
37
38 class throttle(object):
38 class throttle(object):
39 '''
39 '''
40 Decorator that prevents a function from being called more than once every
40 Decorator that prevents a function from being called more than once every
41 time period.
41 time period.
42 To create a function that cannot be called more than once a minute, but
42 To create a function that cannot be called more than once a minute, but
43 will sleep until it can be called:
43 will sleep until it can be called:
44 @throttle(minutes=1)
44 @throttle(minutes=1)
45 def foo():
45 def foo():
46 pass
46 pass
47
47
48 for i in range(10):
48 for i in range(10):
49 foo()
49 foo()
50 print "This function has run %s times." % i
50 print "This function has run %s times." % i
51 '''
51 '''
52
52
53 def __init__(self, seconds=0, minutes=0, hours=0):
53 def __init__(self, seconds=0, minutes=0, hours=0):
54 self.throttle_period = datetime.timedelta(
54 self.throttle_period = datetime.timedelta(
55 seconds=seconds, minutes=minutes, hours=hours
55 seconds=seconds, minutes=minutes, hours=hours
56 )
56 )
57
57
58 self.time_of_last_call = datetime.datetime.min
58 self.time_of_last_call = datetime.datetime.min
59
59
60 def __call__(self, fn):
60 def __call__(self, fn):
61 @wraps(fn)
61 @wraps(fn)
62 def wrapper(*args, **kwargs):
62 def wrapper(*args, **kwargs):
63 now = datetime.datetime.now()
63 now = datetime.datetime.now()
64 time_since_last_call = now - self.time_of_last_call
64 time_since_last_call = now - self.time_of_last_call
65 time_left = self.throttle_period - time_since_last_call
65 time_left = self.throttle_period - time_since_last_call
66
66
67 if time_left > datetime.timedelta(seconds=0):
67 if time_left > datetime.timedelta(seconds=0):
68 return
68 return
69
69
70 self.time_of_last_call = datetime.datetime.now()
70 self.time_of_last_call = datetime.datetime.now()
71 return fn(*args, **kwargs)
71 return fn(*args, **kwargs)
72
72
73 return wrapper
73 return wrapper
74
74
75 class Data(object):
75 class Data(object):
76 '''
76 '''
77 Object to hold data to be plotted
77 Object to hold data to be plotted
78 '''
78 '''
79
79
80 def __init__(self, plottypes, throttle_value):
80 def __init__(self, plottypes, throttle_value):
81 self.plottypes = plottypes
81 self.plottypes = plottypes
82 self.throttle = throttle_value
82 self.throttle = throttle_value
83 self.ended = False
83 self.ended = False
84 self.__times = []
84 self.__times = []
85
85
86 def __str__(self):
86 def __str__(self):
87 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
87 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
88 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
88 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
89
89
90 def __len__(self):
90 def __len__(self):
91 return len(self.__times)
91 return len(self.__times)
92
92
93 def __getitem__(self, key):
93 def __getitem__(self, key):
94 if key not in self.data:
94 if key not in self.data:
95 raise KeyError(log.error('Missing key: {}'.format(key)))
95 raise KeyError(log.error('Missing key: {}'.format(key)))
96
96
97 if 'spc' in key:
97 if 'spc' in key:
98 ret = self.data[key]
98 ret = self.data[key]
99 else:
99 else:
100 ret = numpy.array([self.data[key][x] for x in self.times])
100 ret = numpy.array([self.data[key][x] for x in self.times])
101 if ret.ndim > 1:
101 if ret.ndim > 1:
102 ret = numpy.swapaxes(ret, 0, 1)
102 ret = numpy.swapaxes(ret, 0, 1)
103 return ret
103 return ret
104
104
105 def setup(self):
105 def setup(self):
106 '''
106 '''
107 Configure object
107 Configure object
108 '''
108 '''
109
109
110 self.ended = False
110 self.ended = False
111 self.data = {}
111 self.data = {}
112 self.__times = []
112 self.__times = []
113 self.__heights = []
113 self.__heights = []
114 self.__all_heights = set()
114 self.__all_heights = set()
115 for plot in self.plottypes:
115 for plot in self.plottypes:
116 if 'snr' in plot:
117 plot = 'snr'
116 self.data[plot] = {}
118 self.data[plot] = {}
117
119
118 def shape(self, key):
120 def shape(self, key):
119 '''
121 '''
120 Get the shape of the one-element data for the given key
122 Get the shape of the one-element data for the given key
121 '''
123 '''
122
124
123 if len(self.data[key]):
125 if len(self.data[key]):
124 if 'spc' in key:
126 if 'spc' in key:
125 return self.data[key].shape
127 return self.data[key].shape
126 return self.data[key][self.__times[0]].shape
128 return self.data[key][self.__times[0]].shape
127 return (0,)
129 return (0,)
128
130
129 def update(self, dataOut):
131 def update(self, dataOut):
130 '''
132 '''
131 Update data object with new dataOut
133 Update data object with new dataOut
132 '''
134 '''
133
135
134 tm = dataOut.utctime
136 tm = dataOut.utctime
135 if tm in self.__times:
137 if tm in self.__times:
136 return
138 return
137
139
138 self.parameters = getattr(dataOut, 'parameters', [])
140 self.parameters = getattr(dataOut, 'parameters', [])
139 self.pairs = dataOut.pairsList
141 self.pairs = dataOut.pairsList
140 self.channels = dataOut.channelList
142 self.channels = dataOut.channelList
141 self.xrange = (dataOut.getFreqRange(1)/1000. , dataOut.getAcfRange(1) , dataOut.getVelRange(1))
142 self.interval = dataOut.getTimeInterval()
143 self.interval = dataOut.getTimeInterval()
144 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
145 self.xrange = (dataOut.getFreqRange(1)/1000. , dataOut.getAcfRange(1) , dataOut.getVelRange(1))
143 self.__heights.append(dataOut.heightList)
146 self.__heights.append(dataOut.heightList)
144 self.__all_heights.update(dataOut.heightList)
147 self.__all_heights.update(dataOut.heightList)
145 self.__times.append(tm)
148 self.__times.append(tm)
146
149
147 for plot in self.plottypes:
150 for plot in self.plottypes:
148 if plot == 'spc':
151 if plot == 'spc':
149 z = dataOut.data_spc/dataOut.normFactor
152 z = dataOut.data_spc/dataOut.normFactor
150 self.data[plot] = 10*numpy.log10(z)
153 self.data[plot] = 10*numpy.log10(z)
151 if plot == 'cspc':
154 if plot == 'cspc':
152 self.data[plot] = dataOut.data_cspc
155 self.data[plot] = dataOut.data_cspc
153 if plot == 'noise':
156 if plot == 'noise':
154 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
157 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
155 if plot == 'rti':
158 if plot == 'rti':
156 self.data[plot][tm] = dataOut.getPower()
159 self.data[plot][tm] = dataOut.getPower()
157 if plot == 'snr_db':
160 if plot == 'snr_db':
158 self.data['snr'][tm] = dataOut.data_SNR
161 self.data['snr'][tm] = dataOut.data_SNR
159 if plot == 'snr':
162 if plot == 'snr':
160 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
163 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
161 if plot == 'dop':
164 if plot == 'dop':
162 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
165 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
163 if plot == 'mean':
166 if plot == 'mean':
164 self.data[plot][tm] = dataOut.data_MEAN
167 self.data[plot][tm] = dataOut.data_MEAN
165 if plot == 'std':
168 if plot == 'std':
166 self.data[plot][tm] = dataOut.data_STD
169 self.data[plot][tm] = dataOut.data_STD
167 if plot == 'coh':
170 if plot == 'coh':
168 self.data[plot][tm] = dataOut.getCoherence()
171 self.data[plot][tm] = dataOut.getCoherence()
169 if plot == 'phase':
172 if plot == 'phase':
170 self.data[plot][tm] = dataOut.getCoherence(phase=True)
173 self.data[plot][tm] = dataOut.getCoherence(phase=True)
171 if plot == 'output':
174 if plot == 'output':
172 self.data[plot][tm] = dataOut.data_output
175 self.data[plot][tm] = dataOut.data_output
173 if plot == 'param':
176 if plot == 'param':
174 self.data[plot][tm] = dataOut.data_param
177 self.data[plot][tm] = dataOut.data_param
175
178
176 def normalize_heights(self):
179 def normalize_heights(self):
177 '''
180 '''
178 Ensure same-dimension of the data for different heighList
181 Ensure same-dimension of the data for different heighList
179 '''
182 '''
180
183
181 H = numpy.array(list(self.__all_heights))
184 H = numpy.array(list(self.__all_heights))
182 H.sort()
185 H.sort()
183 for key in self.data:
186 for key in self.data:
184 shape = self.shape(key)[:-1] + H.shape
187 shape = self.shape(key)[:-1] + H.shape
185 for tm, obj in self.data[key].items():
188 for tm, obj in self.data[key].items():
186 h = self.__heights[self.__times.index(tm)]
189 h = self.__heights[self.__times.index(tm)]
187 if H.size == h.size:
190 if H.size == h.size:
188 continue
191 continue
189 index = numpy.where(numpy.in1d(H, h))[0]
192 index = numpy.where(numpy.in1d(H, h))[0]
190 dummy = numpy.zeros(shape) + numpy.nan
193 dummy = numpy.zeros(shape) + numpy.nan
191 if len(shape) == 2:
194 if len(shape) == 2:
192 dummy[:, index] = obj
195 dummy[:, index] = obj
193 else:
196 else:
194 dummy[index] = obj
197 dummy[index] = obj
195 self.data[key][tm] = dummy
198 self.data[key][tm] = dummy
196
199
197 self.__heights = [H for tm in self.__times]
200 self.__heights = [H for tm in self.__times]
198
201
199 def jsonify(self, decimate=False):
202 def jsonify(self, decimate=False):
200 '''
203 '''
201 Convert data to json
204 Convert data to json
202 '''
205 '''
203
206
204 ret = {}
207 ret = {}
205 tm = self.times[-1]
208 tm = self.times[-1]
206
209
207 for key, value in self.data:
210 for key, value in self.data:
208 if key in ('spc', 'cspc'):
211 if key in ('spc', 'cspc'):
209 ret[key] = roundFloats(self.data[key].to_list())
212 ret[key] = roundFloats(self.data[key].to_list())
210 else:
213 else:
211 ret[key] = roundFloats(self.data[key][tm].to_list())
214 ret[key] = roundFloats(self.data[key][tm].to_list())
212
215
213 ret['timestamp'] = tm
216 ret['timestamp'] = tm
214 ret['interval'] = self.interval
217 ret['interval'] = self.interval
215
218
216 @property
219 @property
217 def times(self):
220 def times(self):
218 '''
221 '''
219 Return the list of times of the current data
222 Return the list of times of the current data
220 '''
223 '''
221
224
222 ret = numpy.array(self.__times)
225 ret = numpy.array(self.__times)
223 ret.sort()
226 ret.sort()
224 return ret
227 return ret
225
228
226 @property
229 @property
227 def heights(self):
230 def heights(self):
228 '''
231 '''
229 Return the list of heights of the current data
232 Return the list of heights of the current data
230 '''
233 '''
231
234
232 return numpy.array(self.__heights[-1])
235 return numpy.array(self.__heights[-1])
233
236
234 class PublishData(Operation):
237 class PublishData(Operation):
235 '''
238 '''
236 Operation to send data over zmq.
239 Operation to send data over zmq.
237 '''
240 '''
238
241
239 def __init__(self, **kwargs):
242 def __init__(self, **kwargs):
240 """Inicio."""
243 """Inicio."""
241 Operation.__init__(self, **kwargs)
244 Operation.__init__(self, **kwargs)
242 self.isConfig = False
245 self.isConfig = False
243 self.client = None
246 self.client = None
244 self.zeromq = None
247 self.zeromq = None
245 self.mqtt = None
248 self.mqtt = None
246
249
247 def on_disconnect(self, client, userdata, rc):
250 def on_disconnect(self, client, userdata, rc):
248 if rc != 0:
251 if rc != 0:
249 log.warning('Unexpected disconnection.')
252 log.warning('Unexpected disconnection.')
250 self.connect()
253 self.connect()
251
254
252 def connect(self):
255 def connect(self):
253 log.warning('trying to connect')
256 log.warning('trying to connect')
254 try:
257 try:
255 self.client.connect(
258 self.client.connect(
256 host=self.host,
259 host=self.host,
257 port=self.port,
260 port=self.port,
258 keepalive=60*10,
261 keepalive=60*10,
259 bind_address='')
262 bind_address='')
260 self.client.loop_start()
263 self.client.loop_start()
261 # self.client.publish(
264 # self.client.publish(
262 # self.topic + 'SETUP',
265 # self.topic + 'SETUP',
263 # json.dumps(setup),
266 # json.dumps(setup),
264 # retain=True
267 # retain=True
265 # )
268 # )
266 except:
269 except:
267 log.error('MQTT Conection error.')
270 log.error('MQTT Conection error.')
268 self.client = False
271 self.client = False
269
272
270 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
273 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
271 self.counter = 0
274 self.counter = 0
272 self.topic = kwargs.get('topic', 'schain')
275 self.topic = kwargs.get('topic', 'schain')
273 self.delay = kwargs.get('delay', 0)
276 self.delay = kwargs.get('delay', 0)
274 self.plottype = kwargs.get('plottype', 'spectra')
277 self.plottype = kwargs.get('plottype', 'spectra')
275 self.host = kwargs.get('host', "10.10.10.82")
278 self.host = kwargs.get('host', "10.10.10.82")
276 self.port = kwargs.get('port', 3000)
279 self.port = kwargs.get('port', 3000)
277 self.clientId = clientId
280 self.clientId = clientId
278 self.cnt = 0
281 self.cnt = 0
279 self.zeromq = zeromq
282 self.zeromq = zeromq
280 self.mqtt = kwargs.get('plottype', 0)
283 self.mqtt = kwargs.get('plottype', 0)
281 self.client = None
284 self.client = None
282 self.verbose = verbose
285 self.verbose = verbose
283 setup = []
286 setup = []
284 if mqtt is 1:
287 if mqtt is 1:
285 self.client = mqtt.Client(
288 self.client = mqtt.Client(
286 client_id=self.clientId + self.topic + 'SCHAIN',
289 client_id=self.clientId + self.topic + 'SCHAIN',
287 clean_session=True)
290 clean_session=True)
288 self.client.on_disconnect = self.on_disconnect
291 self.client.on_disconnect = self.on_disconnect
289 self.connect()
292 self.connect()
290 for plot in self.plottype:
293 for plot in self.plottype:
291 setup.append({
294 setup.append({
292 'plot': plot,
295 'plot': plot,
293 'topic': self.topic + plot,
296 'topic': self.topic + plot,
294 'title': getattr(self, plot + '_' + 'title', False),
297 'title': getattr(self, plot + '_' + 'title', False),
295 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
298 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
296 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
299 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
297 'xrange': getattr(self, plot + '_' + 'xrange', False),
300 'xrange': getattr(self, plot + '_' + 'xrange', False),
298 'yrange': getattr(self, plot + '_' + 'yrange', False),
301 'yrange': getattr(self, plot + '_' + 'yrange', False),
299 'zrange': getattr(self, plot + '_' + 'zrange', False),
302 'zrange': getattr(self, plot + '_' + 'zrange', False),
300 })
303 })
301 if zeromq is 1:
304 if zeromq is 1:
302 context = zmq.Context()
305 context = zmq.Context()
303 self.zmq_socket = context.socket(zmq.PUSH)
306 self.zmq_socket = context.socket(zmq.PUSH)
304 server = kwargs.get('server', 'zmq.pipe')
307 server = kwargs.get('server', 'zmq.pipe')
305
308
306 if 'tcp://' in server:
309 if 'tcp://' in server:
307 address = server
310 address = server
308 else:
311 else:
309 address = 'ipc:///tmp/%s' % server
312 address = 'ipc:///tmp/%s' % server
310
313
311 self.zmq_socket.connect(address)
314 self.zmq_socket.connect(address)
312 time.sleep(1)
315 time.sleep(1)
313
316
314
317
315 def publish_data(self):
318 def publish_data(self):
316 self.dataOut.finished = False
319 self.dataOut.finished = False
317 if self.mqtt is 1:
320 if self.mqtt is 1:
318 yData = self.dataOut.heightList[:2].tolist()
321 yData = self.dataOut.heightList[:2].tolist()
319 if self.plottype == 'spectra':
322 if self.plottype == 'spectra':
320 data = getattr(self.dataOut, 'data_spc')
323 data = getattr(self.dataOut, 'data_spc')
321 z = data/self.dataOut.normFactor
324 z = data/self.dataOut.normFactor
322 zdB = 10*numpy.log10(z)
325 zdB = 10*numpy.log10(z)
323 xlen, ylen = zdB[0].shape
326 xlen, ylen = zdB[0].shape
324 dx = int(xlen/MAXNUMX) + 1
327 dx = int(xlen/MAXNUMX) + 1
325 dy = int(ylen/MAXNUMY) + 1
328 dy = int(ylen/MAXNUMY) + 1
326 Z = [0 for i in self.dataOut.channelList]
329 Z = [0 for i in self.dataOut.channelList]
327 for i in self.dataOut.channelList:
330 for i in self.dataOut.channelList:
328 Z[i] = zdB[i][::dx, ::dy].tolist()
331 Z[i] = zdB[i][::dx, ::dy].tolist()
329 payload = {
332 payload = {
330 'timestamp': self.dataOut.utctime,
333 'timestamp': self.dataOut.utctime,
331 'data': roundFloats(Z),
334 'data': roundFloats(Z),
332 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
335 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
333 'interval': self.dataOut.getTimeInterval(),
336 'interval': self.dataOut.getTimeInterval(),
334 'type': self.plottype,
337 'type': self.plottype,
335 'yData': yData
338 'yData': yData
336 }
339 }
337
340
338 elif self.plottype in ('rti', 'power'):
341 elif self.plottype in ('rti', 'power'):
339 data = getattr(self.dataOut, 'data_spc')
342 data = getattr(self.dataOut, 'data_spc')
340 z = data/self.dataOut.normFactor
343 z = data/self.dataOut.normFactor
341 avg = numpy.average(z, axis=1)
344 avg = numpy.average(z, axis=1)
342 avgdB = 10*numpy.log10(avg)
345 avgdB = 10*numpy.log10(avg)
343 xlen, ylen = z[0].shape
346 xlen, ylen = z[0].shape
344 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
347 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
345 AVG = [0 for i in self.dataOut.channelList]
348 AVG = [0 for i in self.dataOut.channelList]
346 for i in self.dataOut.channelList:
349 for i in self.dataOut.channelList:
347 AVG[i] = avgdB[i][::dy].tolist()
350 AVG[i] = avgdB[i][::dy].tolist()
348 payload = {
351 payload = {
349 'timestamp': self.dataOut.utctime,
352 'timestamp': self.dataOut.utctime,
350 'data': roundFloats(AVG),
353 'data': roundFloats(AVG),
351 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
354 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
352 'interval': self.dataOut.getTimeInterval(),
355 'interval': self.dataOut.getTimeInterval(),
353 'type': self.plottype,
356 'type': self.plottype,
354 'yData': yData
357 'yData': yData
355 }
358 }
356 elif self.plottype == 'noise':
359 elif self.plottype == 'noise':
357 noise = self.dataOut.getNoise()/self.dataOut.normFactor
360 noise = self.dataOut.getNoise()/self.dataOut.normFactor
358 noisedB = 10*numpy.log10(noise)
361 noisedB = 10*numpy.log10(noise)
359 payload = {
362 payload = {
360 'timestamp': self.dataOut.utctime,
363 'timestamp': self.dataOut.utctime,
361 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
364 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
362 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
365 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
363 'interval': self.dataOut.getTimeInterval(),
366 'interval': self.dataOut.getTimeInterval(),
364 'type': self.plottype,
367 'type': self.plottype,
365 'yData': yData
368 'yData': yData
366 }
369 }
367 elif self.plottype == 'snr':
370 elif self.plottype == 'snr':
368 data = getattr(self.dataOut, 'data_SNR')
371 data = getattr(self.dataOut, 'data_SNR')
369 avgdB = 10*numpy.log10(data)
372 avgdB = 10*numpy.log10(data)
370
373
371 ylen = data[0].size
374 ylen = data[0].size
372 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
375 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
373 AVG = [0 for i in self.dataOut.channelList]
376 AVG = [0 for i in self.dataOut.channelList]
374 for i in self.dataOut.channelList:
377 for i in self.dataOut.channelList:
375 AVG[i] = avgdB[i][::dy].tolist()
378 AVG[i] = avgdB[i][::dy].tolist()
376 payload = {
379 payload = {
377 'timestamp': self.dataOut.utctime,
380 'timestamp': self.dataOut.utctime,
378 'data': roundFloats(AVG),
381 'data': roundFloats(AVG),
379 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
382 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
380 'type': self.plottype,
383 'type': self.plottype,
381 'yData': yData
384 'yData': yData
382 }
385 }
383 else:
386 else:
384 print "Tipo de grafico invalido"
387 print "Tipo de grafico invalido"
385 payload = {
388 payload = {
386 'data': 'None',
389 'data': 'None',
387 'timestamp': 'None',
390 'timestamp': 'None',
388 'type': None
391 'type': None
389 }
392 }
390
393
391 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
394 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
392
395
393 if self.zeromq is 1:
396 if self.zeromq is 1:
394 if self.verbose:
397 if self.verbose:
395 log.log(
398 log.log(
396 '{} - {}'.format(self.dataOut.type, self.dataOut.datatime),
399 '{} - {}'.format(self.dataOut.type, self.dataOut.datatime),
397 'Sending'
400 'Sending'
398 )
401 )
399 self.zmq_socket.send_pyobj(self.dataOut)
402 self.zmq_socket.send_pyobj(self.dataOut)
400
403
401 def run(self, dataOut, **kwargs):
404 def run(self, dataOut, **kwargs):
402 self.dataOut = dataOut
405 self.dataOut = dataOut
403 if not self.isConfig:
406 if not self.isConfig:
404 self.setup(**kwargs)
407 self.setup(**kwargs)
405 self.isConfig = True
408 self.isConfig = True
406
409
407 self.publish_data()
410 self.publish_data()
408 time.sleep(self.delay)
411 time.sleep(self.delay)
409
412
410 def close(self):
413 def close(self):
411 if self.zeromq is 1:
414 if self.zeromq is 1:
412 self.dataOut.finished = True
415 self.dataOut.finished = True
413 self.zmq_socket.send_pyobj(self.dataOut)
416 self.zmq_socket.send_pyobj(self.dataOut)
414 time.sleep(0.1)
417 time.sleep(0.1)
415 self.zmq_socket.close()
418 self.zmq_socket.close()
416 if self.client:
419 if self.client:
417 self.client.loop_stop()
420 self.client.loop_stop()
418 self.client.disconnect()
421 self.client.disconnect()
419
422
420
423
421 class ReceiverData(ProcessingUnit):
424 class ReceiverData(ProcessingUnit):
422
425
423 def __init__(self, **kwargs):
426 def __init__(self, **kwargs):
424
427
425 ProcessingUnit.__init__(self, **kwargs)
428 ProcessingUnit.__init__(self, **kwargs)
426
429
427 self.isConfig = False
430 self.isConfig = False
428 server = kwargs.get('server', 'zmq.pipe')
431 server = kwargs.get('server', 'zmq.pipe')
429 if 'tcp://' in server:
432 if 'tcp://' in server:
430 address = server
433 address = server
431 else:
434 else:
432 address = 'ipc:///tmp/%s' % server
435 address = 'ipc:///tmp/%s' % server
433
436
434 self.address = address
437 self.address = address
435 self.dataOut = JROData()
438 self.dataOut = JROData()
436
439
437 def setup(self):
440 def setup(self):
438
441
439 self.context = zmq.Context()
442 self.context = zmq.Context()
440 self.receiver = self.context.socket(zmq.PULL)
443 self.receiver = self.context.socket(zmq.PULL)
441 self.receiver.bind(self.address)
444 self.receiver.bind(self.address)
442 time.sleep(0.5)
445 time.sleep(0.5)
443 log.success('ReceiverData from {}'.format(self.address))
446 log.success('ReceiverData from {}'.format(self.address))
444
447
445
448
446 def run(self):
449 def run(self):
447
450
448 if not self.isConfig:
451 if not self.isConfig:
449 self.setup()
452 self.setup()
450 self.isConfig = True
453 self.isConfig = True
451
454
452 self.dataOut = self.receiver.recv_pyobj()
455 self.dataOut = self.receiver.recv_pyobj()
453 log.log('{} - {}'.format(self.dataOut.type,
456 log.log('{} - {}'.format(self.dataOut.type,
454 self.dataOut.datatime.ctime(),),
457 self.dataOut.datatime.ctime(),),
455 'Receiving')
458 'Receiving')
456
459
457
460
458 class PlotterReceiver(ProcessingUnit, Process):
461 class PlotterReceiver(ProcessingUnit, Process):
459
462
460 throttle_value = 5
463 throttle_value = 5
461
464
462 def __init__(self, **kwargs):
465 def __init__(self, **kwargs):
463
466
464 ProcessingUnit.__init__(self, **kwargs)
467 ProcessingUnit.__init__(self, **kwargs)
465 Process.__init__(self)
468 Process.__init__(self)
466 self.mp = False
469 self.mp = False
467 self.isConfig = False
470 self.isConfig = False
468 self.isWebConfig = False
471 self.isWebConfig = False
469 self.connections = 0
472 self.connections = 0
470 server = kwargs.get('server', 'zmq.pipe')
473 server = kwargs.get('server', 'zmq.pipe')
471 plot_server = kwargs.get('plot_server', 'zmq.web')
474 plot_server = kwargs.get('plot_server', 'zmq.web')
472 if 'tcp://' in server:
475 if 'tcp://' in server:
473 address = server
476 address = server
474 else:
477 else:
475 address = 'ipc:///tmp/%s' % server
478 address = 'ipc:///tmp/%s' % server
476
479
477 if 'tcp://' in plot_server:
480 if 'tcp://' in plot_server:
478 plot_address = plot_server
481 plot_address = plot_server
479 else:
482 else:
480 plot_address = 'ipc:///tmp/%s' % plot_server
483 plot_address = 'ipc:///tmp/%s' % plot_server
481
484
482 self.address = address
485 self.address = address
483 self.plot_address = plot_address
486 self.plot_address = plot_address
484 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
487 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
485 self.realtime = kwargs.get('realtime', False)
488 self.realtime = kwargs.get('realtime', False)
486 self.throttle_value = kwargs.get('throttle', 5)
489 self.throttle_value = kwargs.get('throttle', 5)
487 self.sendData = self.initThrottle(self.throttle_value)
490 self.sendData = self.initThrottle(self.throttle_value)
488 self.dates = []
491 self.dates = []
489 self.setup()
492 self.setup()
490
493
491 def setup(self):
494 def setup(self):
492
495
493 self.data = Data(self.plottypes, self.throttle_value)
496 self.data = Data(self.plottypes, self.throttle_value)
494 self.isConfig = True
497 self.isConfig = True
495
498
496 def event_monitor(self, monitor):
499 def event_monitor(self, monitor):
497
500
498 events = {}
501 events = {}
499
502
500 for name in dir(zmq):
503 for name in dir(zmq):
501 if name.startswith('EVENT_'):
504 if name.startswith('EVENT_'):
502 value = getattr(zmq, name)
505 value = getattr(zmq, name)
503 events[value] = name
506 events[value] = name
504
507
505 while monitor.poll():
508 while monitor.poll():
506 evt = recv_monitor_message(monitor)
509 evt = recv_monitor_message(monitor)
507 if evt['event'] == 32:
510 if evt['event'] == 32:
508 self.connections += 1
511 self.connections += 1
509 if evt['event'] == 512:
512 if evt['event'] == 512:
510 pass
513 pass
511
514
512 evt.update({'description': events[evt['event']]})
515 evt.update({'description': events[evt['event']]})
513
516
514 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
517 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
515 break
518 break
516 monitor.close()
519 monitor.close()
517 print('event monitor thread done!')
520 print('event monitor thread done!')
518
521
519 def initThrottle(self, throttle_value):
522 def initThrottle(self, throttle_value):
520
523
521 @throttle(seconds=throttle_value)
524 @throttle(seconds=throttle_value)
522 def sendDataThrottled(fn_sender, data):
525 def sendDataThrottled(fn_sender, data):
523 fn_sender(data)
526 fn_sender(data)
524
527
525 return sendDataThrottled
528 return sendDataThrottled
526
529
527 def send(self, data):
530 def send(self, data):
528 log.success('Sending {}'.format(data), self.name)
531 log.success('Sending {}'.format(data), self.name)
529 self.sender.send_pyobj(data)
532 self.sender.send_pyobj(data)
530
533
531 def run(self):
534 def run(self):
532
535
533 log.success(
536 log.success(
534 'Starting from {}'.format(self.address),
537 'Starting from {}'.format(self.address),
535 self.name
538 self.name
536 )
539 )
537
540
538 self.context = zmq.Context()
541 self.context = zmq.Context()
539 self.receiver = self.context.socket(zmq.PULL)
542 self.receiver = self.context.socket(zmq.PULL)
540 self.receiver.bind(self.address)
543 self.receiver.bind(self.address)
541 monitor = self.receiver.get_monitor_socket()
544 monitor = self.receiver.get_monitor_socket()
542 self.sender = self.context.socket(zmq.PUB)
545 self.sender = self.context.socket(zmq.PUB)
543 if self.realtime:
546 if self.realtime:
544 self.sender_web = self.context.socket(zmq.PUB)
547 self.sender_web = self.context.socket(zmq.PUB)
545 self.sender_web.connect(self.plot_address)
548 self.sender_web.connect(self.plot_address)
546 time.sleep(1)
549 time.sleep(1)
547
550
548 if 'server' in self.kwargs:
551 if 'server' in self.kwargs:
549 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
552 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
550 else:
553 else:
551 self.sender.bind("ipc:///tmp/zmq.plots")
554 self.sender.bind("ipc:///tmp/zmq.plots")
552
555
553 time.sleep(2)
556 time.sleep(2)
554
557
555 t = Thread(target=self.event_monitor, args=(monitor,))
558 t = Thread(target=self.event_monitor, args=(monitor,))
556 t.start()
559 t.start()
557
560
558 while True:
561 while True:
559 dataOut = self.receiver.recv_pyobj()
562 dataOut = self.receiver.recv_pyobj()
560 dt = datetime.datetime.fromtimestamp(dataOut.utctime).date()
563 dt = datetime.datetime.fromtimestamp(dataOut.utctime).date()
561 sended = False
564 sended = False
562 if dt not in self.dates:
565 if dt not in self.dates:
563 if self.data:
566 if self.data:
564 self.data.ended = True
567 self.data.ended = True
565 self.send(self.data)
568 self.send(self.data)
566 sended = True
569 sended = True
567 self.data.setup()
570 self.data.setup()
568 self.dates.append(dt)
571 self.dates.append(dt)
569
572
570 self.data.update(dataOut)
573 self.data.update(dataOut)
571
574
572 if dataOut.finished is True:
575 if dataOut.finished is True:
573 self.connections -= 1
576 self.connections -= 1
574 if self.connections == 0 and dt in self.dates:
577 if self.connections == 0 and dt in self.dates:
575 self.data.ended = True
578 self.data.ended = True
576 self.send(self.data)
579 self.send(self.data)
577 self.data.setup()
580 self.data.setup()
578 else:
581 else:
579 if self.realtime:
582 if self.realtime:
580 self.send(self.data)
583 self.send(self.data)
581 # self.sender_web.send_string(self.data.jsonify())
584 # self.sender_web.send_string(self.data.jsonify())
582 else:
585 else:
583 if not sended:
586 if not sended:
584 self.sendData(self.send, self.data)
587 self.sendData(self.send, self.data)
585
588
586 return
589 return
587
590
588 def sendToWeb(self):
591 def sendToWeb(self):
589
592
590 if not self.isWebConfig:
593 if not self.isWebConfig:
591 context = zmq.Context()
594 context = zmq.Context()
592 sender_web_config = context.socket(zmq.PUB)
595 sender_web_config = context.socket(zmq.PUB)
593 if 'tcp://' in self.plot_address:
596 if 'tcp://' in self.plot_address:
594 dum, address, port = self.plot_address.split(':')
597 dum, address, port = self.plot_address.split(':')
595 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
598 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
596 else:
599 else:
597 conf_address = self.plot_address + '.config'
600 conf_address = self.plot_address + '.config'
598 sender_web_config.bind(conf_address)
601 sender_web_config.bind(conf_address)
599 time.sleep(1)
602 time.sleep(1)
600 for kwargs in self.operationKwargs.values():
603 for kwargs in self.operationKwargs.values():
601 if 'plot' in kwargs:
604 if 'plot' in kwargs:
602 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
605 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
603 sender_web_config.send_string(json.dumps(kwargs))
606 sender_web_config.send_string(json.dumps(kwargs))
604 self.isWebConfig = True No newline at end of file
607 self.isWebConfig = True
@@ -1,34 +0,0
1 from schainpy.controller import Project
2
3 desc = "A schain project"
4
5 controller = Project()
6 controller.setup(id='191', name="project", description=desc)
7
8 readUnitConf = controller.addReadUnit(datatype='VoltageReader',
9 path="/home/nanosat/schain/schainpy",
10 startDate="1970/01/01",
11 endDate="2017/12/31",
12 startTime="00:00:00",
13 endTime="23:59:59",
14 online=0,
15 verbose=1,
16 walk=1,
17 )
18
19 procUnitConf1 = controller.addProcUnit(datatype='VoltageProc', inputId=readUnitConf.getId())
20
21 opObj11 = procUnitConf1.addOperation(name='ProfileSelector', optype='other')
22 opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist')
23
24 opObj11 = procUnitConf1.addOperation(name='RTIPlot', optype='other')
25 opObj11.addParameter(name='wintitle', value='Jicamarca Radio Observatory', format='str')
26 opObj11.addParameter(name='showprofile', value='0', format='int')
27 opObj11.addParameter(name='xmin', value='0', format='int')
28 opObj11.addParameter(name='xmax', value='24', format='int')
29 opObj11.addParameter(name='figpath', value="/home/nanosat/schain/schainpy/figs", format='str')
30 opObj11.addParameter(name='wr_period', value='5', format='int')
31 opObj11.addParameter(name='exp_code', value='22', format='int')
32
33
34 controller.start()
General Comments 0
You need to be logged in to leave comments. Login now