##// END OF EJS Templates
Fix publish and plots operations issue #929
Juan C. Espinoza -
r1062:8048843f4edf
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
NO CONTENT: modified file
This diff has been collapsed as it changes many lines, (1122 lines changed) Show them Hide them
@@ -1,964 +1,782
1
1
2 import os
2 import os
3 import zmq
4 import time
3 import time
5 import numpy
4 import glob
6 import datetime
5 import datetime
7 import numpy as np
6 from multiprocessing import Process
7
8 import zmq
9 import numpy
8 import matplotlib
10 import matplotlib
9 import glob
10 matplotlib.use('TkAgg')
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
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
14 from multiprocessing import Process
15
14
16 from schainpy.model.proc.jroproc_base import Operation
15 from schainpy.model.proc.jroproc_base import Operation
17
16 from schainpy.utils import log
18 plt.ion()
19
17
20 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'))
21 fromtimestamp = lambda x, mintime : (datetime.datetime.utcfromtimestamp(mintime).replace(hour=(x + 5), minute=0) - d1970).total_seconds()
22
23
19
24 d1970 = datetime.datetime(1970,1,1)
20 d1970 = datetime.datetime(1970, 1, 1)
25
21
22
26 class PlotData(Operation, Process):
23 class PlotData(Operation, Process):
24 '''
25 Base class for Schain plotting operations
26 '''
27
27
28 CODE = 'Figure'
28 CODE = 'Figure'
29 colormap = 'jro'
29 colormap = 'jro'
30 bgcolor = 'white'
30 CONFLATE = False
31 CONFLATE = False
31 __MAXNUMX = 80
32 __MAXNUMX = 80
32 __missing = 1E30
33 __missing = 1E30
33
34
34 def __init__(self, **kwargs):
35 def __init__(self, **kwargs):
35
36
36 Operation.__init__(self, plot=True, **kwargs)
37 Operation.__init__(self, plot=True, **kwargs)
37 Process.__init__(self)
38 Process.__init__(self)
38 self.kwargs['code'] = self.CODE
39 self.kwargs['code'] = self.CODE
39 self.mp = False
40 self.mp = False
40 self.dataOut = None
41 self.data = None
41 self.isConfig = False
42 self.isConfig = False
42 self.figure = None
43 self.figures = []
43 self.axes = []
44 self.axes = []
45 self.cb_axes = []
44 self.localtime = kwargs.pop('localtime', True)
46 self.localtime = kwargs.pop('localtime', True)
45 self.show = kwargs.get('show', True)
47 self.show = kwargs.get('show', True)
46 self.save = kwargs.get('save', False)
48 self.save = kwargs.get('save', False)
47 self.colormap = kwargs.get('colormap', self.colormap)
49 self.colormap = kwargs.get('colormap', self.colormap)
48 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
50 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
49 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
51 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
50 self.showprofile = kwargs.get('showprofile', True)
52 self.colormaps = kwargs.get('colormaps', None)
51 self.title = kwargs.get('wintitle', '')
53 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
54 self.showprofile = kwargs.get('showprofile', False)
55 self.title = kwargs.get('wintitle', self.CODE.upper())
56 self.cb_label = kwargs.get('cb_label', None)
57 self.cb_labels = kwargs.get('cb_labels', None)
52 self.xaxis = kwargs.get('xaxis', 'frequency')
58 self.xaxis = kwargs.get('xaxis', 'frequency')
53 self.zmin = kwargs.get('zmin', None)
59 self.zmin = kwargs.get('zmin', None)
54 self.zmax = kwargs.get('zmax', None)
60 self.zmax = kwargs.get('zmax', None)
61 self.zlimits = kwargs.get('zlimits', None)
55 self.xmin = kwargs.get('xmin', None)
62 self.xmin = kwargs.get('xmin', None)
63 if self.xmin is not None:
64 self.xmin += 5
56 self.xmax = kwargs.get('xmax', None)
65 self.xmax = kwargs.get('xmax', None)
57 self.xrange = kwargs.get('xrange', 24)
66 self.xrange = kwargs.get('xrange', 24)
58 self.ymin = kwargs.get('ymin', None)
67 self.ymin = kwargs.get('ymin', None)
59 self.ymax = kwargs.get('ymax', None)
68 self.ymax = kwargs.get('ymax', None)
60 self.__MAXNUMY = kwargs.get('decimation', 5000)
69 self.xlabel = kwargs.get('xlabel', None)
61 self.throttle_value = 5
70 self.__MAXNUMY = kwargs.get('decimation', 100)
62 self.times = []
71 self.showSNR = kwargs.get('showSNR', False)
63 #self.interactive = self.kwargs['parent']
72 self.oneFigure = kwargs.get('oneFigure', True)
73 self.width = kwargs.get('width', None)
74 self.height = kwargs.get('height', None)
75 self.colorbar = kwargs.get('colorbar', True)
76 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
77 self.titles = ['' for __ in range(16)]
78
79 def __setup(self):
80 '''
81 Common setup for all figures, here figures and axes are created
82 '''
83
84 self.setup()
85
86 if self.width is None:
87 self.width = 8
88
89 self.figures = []
90 self.axes = []
91 self.cb_axes = []
92 self.pf_axes = []
93 self.cmaps = []
64
94
95 size = '15%' if self.ncols==1 else '30%'
96 pad = '4%' if self.ncols==1 else '8%'
97
98 if self.oneFigure:
99 if self.height is None:
100 self.height = 1.4*self.nrows + 1
101 fig = plt.figure(figsize=(self.width, self.height),
102 edgecolor='k',
103 facecolor='w')
104 self.figures.append(fig)
105 for n in range(self.nplots):
106 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
107 ax.tick_params(labelsize=8)
108 ax.firsttime = True
109 self.axes.append(ax)
110 if self.showprofile:
111 cax = self.__add_axes(ax, size=size, pad=pad)
112 cax.tick_params(labelsize=8)
113 self.pf_axes.append(cax)
114 else:
115 if self.height is None:
116 self.height = 3
117 for n in range(self.nplots):
118 fig = plt.figure(figsize=(self.width, self.height),
119 edgecolor='k',
120 facecolor='w')
121 ax = fig.add_subplot(1, 1, 1)
122 ax.tick_params(labelsize=8)
123 ax.firsttime = True
124 self.figures.append(fig)
125 self.axes.append(ax)
126 if self.showprofile:
127 cax = self.__add_axes(ax, size=size, pad=pad)
128 cax.tick_params(labelsize=8)
129 self.pf_axes.append(cax)
130
131 for n in range(self.nrows):
132 if self.colormaps is not None:
133 cmap = plt.get_cmap(self.colormaps[n])
134 else:
135 cmap = plt.get_cmap(self.colormap)
136 cmap.set_bad(self.bgcolor, 1.)
137 self.cmaps.append(cmap)
138
139 def __add_axes(self, ax, size='30%', pad='8%'):
65 '''
140 '''
66 this new parameter is created to plot data from varius channels at different figures
141 Add new axes to the given figure
67 1. crear una lista de figuras donde se puedan plotear las figuras,
68 2. dar las opciones de configuracion a cada figura, estas opciones son iguales para ambas figuras
69 3. probar?
70 '''
142 '''
71 self.ind_plt_ch = kwargs.get('ind_plt_ch', False)
143 divider = make_axes_locatable(ax)
72 self.figurelist = None
144 nax = divider.new_horizontal(size=size, pad=pad)
145 ax.figure.add_axes(nax)
146 return nax
73
147
74
148
75 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
149 def setup(self):
150 '''
151 This method should be implemented in the child class, the following
152 attributes should be set:
76
153
154 self.nrows: number of rows
155 self.ncols: number of cols
156 self.nplots: number of plots (channels or pairs)
157 self.ylabel: label for Y axes
158 self.titles: list of axes title
159
160 '''
161 raise(NotImplementedError, 'Implement this method in child class')
162
163 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
164 '''
165 Create a masked array for missing data
166 '''
77 if x_buffer.shape[0] < 2:
167 if x_buffer.shape[0] < 2:
78 return x_buffer, y_buffer, z_buffer
168 return x_buffer, y_buffer, z_buffer
79
169
80 deltas = x_buffer[1:] - x_buffer[0:-1]
170 deltas = x_buffer[1:] - x_buffer[0:-1]
81 x_median = np.median(deltas)
171 x_median = numpy.median(deltas)
82
172
83 index = np.where(deltas > 5*x_median)
173 index = numpy.where(deltas > 5*x_median)
84
174
85 if len(index[0]) != 0:
175 if len(index[0]) != 0:
86 z_buffer[::, index[0], ::] = self.__missing
176 z_buffer[::, index[0], ::] = self.__missing
87 z_buffer = np.ma.masked_inside(z_buffer,
177 z_buffer = numpy.ma.masked_inside(z_buffer,
88 0.99*self.__missing,
178 0.99*self.__missing,
89 1.01*self.__missing)
179 1.01*self.__missing)
90
180
91 return x_buffer, y_buffer, z_buffer
181 return x_buffer, y_buffer, z_buffer
92
182
93 def decimate(self):
183 def decimate(self):
94
184
95 # dx = int(len(self.x)/self.__MAXNUMX) + 1
185 # dx = int(len(self.x)/self.__MAXNUMX) + 1
96 dy = int(len(self.y)/self.__MAXNUMY) + 1
186 dy = int(len(self.y)/self.__MAXNUMY) + 1
97
187
98 # x = self.x[::dx]
188 # x = self.x[::dx]
99 x = self.x
189 x = self.x
100 y = self.y[::dy]
190 y = self.y[::dy]
101 z = self.z[::, ::, ::dy]
191 z = self.z[::, ::, ::dy]
102
192
103 return x, y, z
193 return x, y, z
104
194
195 def format(self):
105 '''
196 '''
106 JM:
197 Set min and max values, labels, ticks and titles
107 elimana las otras imagenes generadas debido a que lso workers no llegan en orden y le pueden
108 poner otro tiempo a la figura q no necesariamente es el ultimo.
109 Solo se realiza cuando termina la imagen.
110 Problemas:
111
112 File "/home/ci-81/workspace/schainv2.3/schainpy/model/graphics/jroplot_data.py", line 145, in __plot
113 for n, eachfigure in enumerate(self.figurelist):
114 TypeError: 'NoneType' object is not iterable
115
116 '''
198 '''
117 def deleteanotherfiles(self):
118 figurenames=[]
119 if self.figurelist != None:
120 for n, eachfigure in enumerate(self.figurelist):
121 #add specific name for each channel in channelList
122 ghostfigname = os.path.join(self.save, '{}_{}_{}'.format(self.titles[n].replace(' ',''),self.CODE,
123 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d')))
124 figname = os.path.join(self.save, '{}_{}_{}.png'.format(self.titles[n].replace(' ',''),self.CODE,
125 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')))
126
199
127 for ghostfigure in glob.glob(ghostfigname+'*'): #ghostfigure will adopt all posible names of figures
200 if self.xmin is None:
128 if ghostfigure != figname:
201 xmin = self.min_time
129 os.remove(ghostfigure)
202 else:
130 print 'Removing GhostFigures:' , figname
203 if self.xaxis is 'time':
204 dt = datetime.datetime.fromtimestamp(self.min_time)
205 xmin = (datetime.datetime.combine(dt.date(),
206 datetime.time(int(self.xmin), 0, 0))-d1970).total_seconds()
131 else :
207 else:
132 '''Erasing ghost images for just on******************'''
208 xmin = self.xmin
133 ghostfigname = os.path.join(self.save, '{}_{}'.format(self.CODE,datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d')))
209
134 figname = os.path.join(self.save, '{}_{}.png'.format(self.CODE,datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')))
210 if self.xmax is None:
135 for ghostfigure in glob.glob(ghostfigname+'*'): #ghostfigure will adopt all posible names of figures
211 xmax = xmin+self.xrange*60*60
136 if ghostfigure != figname:
212 else:
137 os.remove(ghostfigure)
213 if self.xaxis is 'time':
138 print 'Removing GhostFigures:' , figname
214 dt = datetime.datetime.fromtimestamp(self.min_time)
215 xmax = (datetime.datetime.combine(dt.date(),
216 datetime.time(int(self.xmax), 0, 0))-d1970).total_seconds()
217 else:
218 xmax = self.xmax
219
220 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
221 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
222
223 ystep = 200 if ymax>= 800 else 100 if ymax>=400 else 50 if ymax>=200 else 20
224
225 for n, ax in enumerate(self.axes):
226 if ax.firsttime:
227 ax.set_facecolor(self.bgcolor)
228 ax.yaxis.set_major_locator(MultipleLocator(ystep))
229 if self.xaxis is 'time':
230 ax.xaxis.set_major_formatter(FuncFormatter(func))
231 ax.xaxis.set_major_locator(LinearLocator(9))
232 if self.xlabel is not None:
233 ax.set_xlabel(self.xlabel)
234 ax.set_ylabel(self.ylabel)
235 ax.firsttime = False
236 if self.showprofile:
237 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_xlabel('dB')
240 self.pf_axes[n].grid(b=True, axis='x')
241 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
242 if self.colorbar:
243 cb = plt.colorbar(ax.plt, ax=ax, pad=0.02)
244 cb.ax.tick_params(labelsize=8)
245 if self.cb_label:
246 cb.set_label(self.cb_label, size=8)
247 elif self.cb_labels:
248 cb.set_label(self.cb_labels[n], size=8)
249
250 ax.set_title('{} - {} UTC'.format(
251 self.titles[n],
252 datetime.datetime.fromtimestamp(self.max_time).strftime('%H:%M:%S')),
253 size=8)
254 ax.set_xlim(xmin, xmax)
255 ax.set_ylim(ymin, ymax)
256
139
257
140 def __plot(self):
258 def __plot(self):
259 '''
260 '''
261 log.success('Plotting', self.name)
141
262
142 print 'plotting...{}'.format(self.CODE)
143 if self.ind_plt_ch is False : #standard
144 if self.show:
145 self.figure.show()
146 self.plot()
263 self.plot()
147 plt.tight_layout()
264 self.format()
148 self.figure.canvas.manager.set_window_title('{} {} - {}'.format(self.title, self.CODE.upper(),
265
149 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
266 for n, fig in enumerate(self.figures):
150 else :
267 if self.nrows == 0 or self.nplots == 0:
151 print 'len(self.figurelist): ',len(self.figurelist)
268 log.warning('No data', self.name)
152 for n, eachfigure in enumerate(self.figurelist):
269 continue
153 if self.show:
270 if self.show:
154 eachfigure.show()
271 fig.show()
155
272
156 self.plot()
273 fig.tight_layout()
157 eachfigure.tight_layout() # ajuste de cada subplot
274 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
158 eachfigure.canvas.manager.set_window_title('{} {} - {}'.format(self.title[n], self.CODE.upper(),
159 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
275 datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
276 # fig.canvas.draw()
160
277
161 # if self.save:
278 if self.save and self.data.ended:
162 # if self.ind_plt_ch is False : #standard
279 channels = range(self.nrows)
163 # figname = os.path.join(self.save, '{}_{}.png'.format(self.CODE,
280 if self.oneFigure:
164 # datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')))
281 label = ''
165 # print 'Saving figure: {}'.format(figname)
166 # self.figure.savefig(figname)
167 # else :
168 # for n, eachfigure in enumerate(self.figurelist):
169 # #add specific name for each channel in channelList
170 # figname = os.path.join(self.save, '{}_{}_{}.png'.format(self.titles[n],self.CODE,
171 # datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')))
172 #
173 # print 'Saving figure: {}'.format(figname)
174 # eachfigure.savefig(figname)
175
176 if self.ind_plt_ch is False :
177 self.figure.canvas.draw()
178 else :
179 for eachfigure in self.figurelist:
180 eachfigure.canvas.draw()
181
182 if self.save:
183 if self.ind_plt_ch is False : #standard
184 figname = os.path.join(self.save, '{}_{}.png'.format(self.CODE,
185 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')))
186 print 'Saving figure: {}'.format(figname)
187 self.figure.savefig(figname)
188 else :
282 else:
189 for n, eachfigure in enumerate(self.figurelist):
283 label = '_{}'.format(channels[n])
190 #add specific name for each channel in channelList
284 figname = os.path.join(
191 figname = os.path.join(self.save, '{}_{}_{}.png'.format(self.titles[n].replace(' ',''),self.CODE,
285 self.save,
192 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')))
286 '{}{}_{}.png'.format(
193
287 self.CODE,
288 label,
289 datetime.datetime.fromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')
290 )
291 )
194 print 'Saving figure: {}'.format(figname)
292 print 'Saving figure: {}'.format(figname)
195 eachfigure.savefig(figname)
293 fig.savefig(figname)
196
197
294
198 def plot(self):
295 def plot(self):
199
296 '''
200 print 'plotting...{}'.format(self.CODE.upper())
297 '''
201 return
298 raise(NotImplementedError, 'Implement this method in child class')
202
299
203 def run(self):
300 def run(self):
204
301
205 print '[Starting] {}'.format(self.name)
302 log.success('Starting', self.name)
206
303
207 context = zmq.Context()
304 context = zmq.Context()
208 receiver = context.socket(zmq.SUB)
305 receiver = context.socket(zmq.SUB)
209 receiver.setsockopt(zmq.SUBSCRIBE, '')
306 receiver.setsockopt(zmq.SUBSCRIBE, '')
210 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
307 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
211
308
212 if 'server' in self.kwargs['parent']:
309 if 'server' in self.kwargs['parent']:
213 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
310 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
214 else:
311 else:
215 receiver.connect("ipc:///tmp/zmq.plots")
312 receiver.connect("ipc:///tmp/zmq.plots")
216
313
217 seconds_passed = 0
218
219 while True:
314 while True:
220 try:
315 try:
221 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)#flags=zmq.NOBLOCK
316 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
222 self.started = self.data['STARTED']
223 self.dataOut = self.data['dataOut']
224
317
225 if (len(self.times) < len(self.data['times']) and not self.started and self.data['ENDED']):
318 self.min_time = self.data.times[0]
226 continue
319 self.max_time = self.data.times[-1]
227
228 self.times = self.data['times']
229 self.times.sort()
230 self.throttle_value = self.data['throttle']
231 self.min_time = self.times[0]
232 self.max_time = self.times[-1]
233
320
234 if self.isConfig is False:
321 if self.isConfig is False:
235 print 'setting up'
322 self.__setup()
236 self.setup()
237 self.isConfig = True
323 self.isConfig = True
238 self.__plot()
239
324
240 if self.data['ENDED'] is True:
241 print '********GRAPHIC ENDED********'
242 self.ended = True
243 self.isConfig = False
244 self.__plot()
325 self.__plot()
245 self.deleteanotherfiles() #CLPDG
246 elif seconds_passed >= self.data['throttle']:
247 print 'passed', seconds_passed
248 self.__plot()
249 seconds_passed = 0
250
326
251 except zmq.Again as e:
327 except zmq.Again as e:
252 print 'Waiting for data...'
328 log.log('Waiting for data...')
253 plt.pause(2)
329 if self.data:
254 seconds_passed += 2
330 plt.pause(self.data.throttle)
331 else:
332 time.sleep(2)
255
333
256 def close(self):
334 def close(self):
257 if self.dataOut:
335 if self.data:
258 self.__plot()
336 self.__plot()
259
337
260
338
261 class PlotSpectraData(PlotData):
339 class PlotSpectraData(PlotData):
340 '''
341 Plot for Spectra data
342 '''
262
343
263 CODE = 'spc'
344 CODE = 'spc'
264 colormap = 'jro'
345 colormap = 'jro'
265 CONFLATE = False
266
346
267 def setup(self):
347 def setup(self):
268
348 self.nplots = len(self.data.channels)
269 ncolspan = 1
349 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
270 colspan = 1
350 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
271 self.ncols = int(numpy.sqrt(self.dataOut.nChannels)+0.9)
351 self.width = 3.4*self.ncols
272 self.nrows = int(self.dataOut.nChannels*1./self.ncols + 0.9)
352 self.height = 3*self.nrows
273 self.width = 3.6*self.ncols
353 self.cb_label = 'dB'
274 self.height = 3.2*self.nrows
275 if self.showprofile:
354 if self.showprofile:
276 ncolspan = 3
355 self.width += 0.8*self.ncols
277 colspan = 2
278 self.width += 1.2*self.ncols
279
356
280 self.ylabel = 'Range [Km]'
357 self.ylabel = 'Range [Km]'
281 self.titles = ['Channel {}'.format(x) for x in self.dataOut.channelList]
282
283 if self.figure is None:
284 self.figure = plt.figure(figsize=(self.width, self.height),
285 edgecolor='k',
286 facecolor='w')
287 else:
288 self.figure.clf()
289
290 n = 0
291 for y in range(self.nrows):
292 for x in range(self.ncols):
293 if n >= self.dataOut.nChannels:
294 break
295 ax = plt.subplot2grid((self.nrows, self.ncols*ncolspan), (y, x*ncolspan), 1, colspan)
296 if self.showprofile:
297 ax.ax_profile = plt.subplot2grid((self.nrows, self.ncols*ncolspan), (y, x*ncolspan+colspan), 1, 1)
298
299 ax.firsttime = True
300 self.axes.append(ax)
301 n += 1
302
358
303 def plot(self):
359 def plot(self):
304
305 if self.xaxis == "frequency":
360 if self.xaxis == "frequency":
306 x = self.dataOut.getFreqRange(1)/1000.
361 x = self.data.xrange[0]
307 xlabel = "Frequency (kHz)"
362 self.xlabel = "Frequency (kHz)"
308 elif self.xaxis == "time":
363 elif self.xaxis == "time":
309 x = self.dataOut.getAcfRange(1)
364 x = self.data.xrange[1]
310 xlabel = "Time (ms)"
365 self.xlabel = "Time (ms)"
311 else:
366 else:
312 x = self.dataOut.getVelRange(1)
367 x = self.data.xrange[2]
313 xlabel = "Velocity (m/s)"
368 self.xlabel = "Velocity (m/s)"
369
370 if self.CODE == 'spc_mean':
371 x = self.data.xrange[2]
372 self.xlabel = "Velocity (m/s)"
314
373
315 y = self.dataOut.getHeiRange()
374 self.titles = []
316 z = self.data[self.CODE]
375
376 y = self.data.heights
377 self.y = y
378 z = self.data['spc']
317
379
318 for n, ax in enumerate(self.axes):
380 for n, ax in enumerate(self.axes):
381 noise = self.data['noise'][n][-1]
382 if self.CODE == 'spc_mean':
383 mean = self.data['mean'][n][-1]
319 if ax.firsttime:
384 if ax.firsttime:
320 self.xmax = self.xmax if self.xmax else np.nanmax(x)
385 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
321 self.xmin = self.xmin if self.xmin else -self.xmax
386 self.xmin = self.xmin if self.xmin else -self.xmax
322 self.ymin = self.ymin if self.ymin else np.nanmin(y)
387 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
323 self.ymax = self.ymax if self.ymax else np.nanmax(y)
388 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
324 self.zmin = self.zmin if self.zmin else np.nanmin(z)
389 ax.plt = ax.pcolormesh(x, y, z[n].T,
325 self.zmax = self.zmax if self.zmax else np.nanmax(z)
326 ax.plot = ax.pcolormesh(x, y, z[n].T,
327 vmin=self.zmin,
390 vmin=self.zmin,
328 vmax=self.zmax,
391 vmax=self.zmax,
329 cmap=plt.get_cmap(self.colormap)
392 cmap=plt.get_cmap(self.colormap)
330 )
393 )
331 divider = make_axes_locatable(ax)
332 cax = divider.new_horizontal(size='3%', pad=0.05)
333 self.figure.add_axes(cax)
334 plt.colorbar(ax.plot, cax)
335
336 ax.set_xlim(self.xmin, self.xmax)
337 ax.set_ylim(self.ymin, self.ymax)
338
339 ax.set_ylabel(self.ylabel)
340 ax.set_xlabel(xlabel)
341
342 ax.firsttime = False
343
394
344 if self.showprofile:
395 if self.showprofile:
345 ax.plot_profile= ax.ax_profile.plot(self.data['rti'][self.max_time][n], y)[0]
396 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
346 ax.ax_profile.set_xlim(self.zmin, self.zmax)
397 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
347 ax.ax_profile.set_ylim(self.ymin, self.ymax)
398 color="k", linestyle="dashed", lw=1)[0]
348 ax.ax_profile.set_xlabel('dB')
399 if self.CODE == 'spc_mean':
349 ax.ax_profile.grid(b=True, axis='x')
400 ax.plt_mean = ax.plot(mean, y, color='k')[0]
350 ax.plot_noise = ax.ax_profile.plot(numpy.repeat(self.data['noise'][self.max_time][n], len(y)), y,
351 color="k", linestyle="dashed", lw=2)[0]
352 [tick.set_visible(False) for tick in ax.ax_profile.get_yticklabels()]
353 else:
401 else:
354 ax.plot.set_array(z[n].T.ravel())
402 ax.plt.set_array(z[n].T.ravel())
355 if self.showprofile:
403 if self.showprofile:
356 ax.plot_profile.set_data(self.data['rti'][self.max_time][n], y)
404 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
357 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][self.max_time][n], len(y)), y)
405 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
406 if self.CODE == 'spc_mean':
407 ax.plt_mean.set_data(mean, y)
358
408
359 ax.set_title('{} - Noise: {:.2f} dB'.format(self.titles[n], self.data['noise'][self.max_time][n]),
409 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
360 size=8)
361 self.saveTime = self.max_time
410 self.saveTime = self.max_time
362
411
363
412
364 class PlotCrossSpectraData(PlotData):
413 class PlotCrossSpectraData(PlotData):
365
414
366 CODE = 'cspc'
415 CODE = 'cspc'
367 zmin_coh = None
416 zmin_coh = None
368 zmax_coh = None
417 zmax_coh = None
369 zmin_phase = None
418 zmin_phase = None
370 zmax_phase = None
419 zmax_phase = None
371 CONFLATE = False
372
420
373 def setup(self):
421 def setup(self):
374
422
375 ncolspan = 1
423 self.ncols = 4
376 colspan = 1
424 self.nrows = len(self.data.pairs)
377 self.ncols = 2
425 self.nplots = self.nrows*4
378 self.nrows = self.dataOut.nPairs
426 self.width = 3.4*self.ncols
379 self.width = 3.6*self.ncols
427 self.height = 3*self.nrows
380 self.height = 3.2*self.nrows
381
382 self.ylabel = 'Range [Km]'
428 self.ylabel = 'Range [Km]'
383 self.titles = ['Channel {}'.format(x) for x in self.dataOut.channelList]
429 self.showprofile = False
384
385 if self.figure is None:
386 self.figure = plt.figure(figsize=(self.width, self.height),
387 edgecolor='k',
388 facecolor='w')
389 else:
390 self.figure.clf()
391
392 for y in range(self.nrows):
393 for x in range(self.ncols):
394 ax = plt.subplot2grid((self.nrows, self.ncols), (y, x), 1, 1)
395 ax.firsttime = True
396 self.axes.append(ax)
397
430
398 def plot(self):
431 def plot(self):
399
432
400 if self.xaxis == "frequency":
433 if self.xaxis == "frequency":
401 x = self.dataOut.getFreqRange(1)/1000.
434 x = self.data.xrange[0]
402 xlabel = "Frequency (kHz)"
435 self.xlabel = "Frequency (kHz)"
403 elif self.xaxis == "time":
436 elif self.xaxis == "time":
404 x = self.dataOut.getAcfRange(1)
437 x = self.data.xrange[1]
405 xlabel = "Time (ms)"
438 self.xlabel = "Time (ms)"
406 else:
439 else:
407 x = self.dataOut.getVelRange(1)
440 x = self.data.xrange[2]
408 xlabel = "Velocity (m/s)"
441 self.xlabel = "Velocity (m/s)"
442
443 self.titles = []
409
444
410 y = self.dataOut.getHeiRange()
445 y = self.data.heights
411 z_coh = self.data['cspc_coh']
446 self.y = y
412 z_phase = self.data['cspc_phase']
447 spc = self.data['spc']
448 cspc = self.data['cspc']
413
449
414 for n in range(self.nrows):
450 for n in range(self.nrows):
415 ax = self.axes[2*n]
451 noise = self.data['noise'][n][-1]
416 ax1 = self.axes[2*n+1]
452 pair = self.data.pairs[n]
453 ax = self.axes[4*n]
454 ax3 = self.axes[4*n+3]
417 if ax.firsttime:
455 if ax.firsttime:
418 self.xmax = self.xmax if self.xmax else np.nanmax(x)
456 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
419 self.xmin = self.xmin if self.xmin else -self.xmax
457 self.xmin = self.xmin if self.xmin else -self.xmax
420 self.ymin = self.ymin if self.ymin else np.nanmin(y)
458 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
421 self.ymax = self.ymax if self.ymax else np.nanmax(y)
459 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
422 self.zmin_coh = self.zmin_coh if self.zmin_coh else 0.0
460 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
423 self.zmax_coh = self.zmax_coh if self.zmax_coh else 1.0
461 vmin=self.zmin,
424 self.zmin_phase = self.zmin_phase if self.zmin_phase else -180
462 vmax=self.zmax,
425 self.zmax_phase = self.zmax_phase if self.zmax_phase else 180
463 cmap=plt.get_cmap(self.colormap)
426
427 ax.plot = ax.pcolormesh(x, y, z_coh[n].T,
428 vmin=self.zmin_coh,
429 vmax=self.zmax_coh,
430 cmap=plt.get_cmap(self.colormap_coh)
431 )
432 divider = make_axes_locatable(ax)
433 cax = divider.new_horizontal(size='3%', pad=0.05)
434 self.figure.add_axes(cax)
435 plt.colorbar(ax.plot, cax)
436
437 ax.set_xlim(self.xmin, self.xmax)
438 ax.set_ylim(self.ymin, self.ymax)
439
440 ax.set_ylabel(self.ylabel)
441 ax.set_xlabel(xlabel)
442 ax.firsttime = False
443
444 ax1.plot = ax1.pcolormesh(x, y, z_phase[n].T,
445 vmin=self.zmin_phase,
446 vmax=self.zmax_phase,
447 cmap=plt.get_cmap(self.colormap_phase)
448 )
464 )
449 divider = make_axes_locatable(ax1)
450 cax = divider.new_horizontal(size='3%', pad=0.05)
451 self.figure.add_axes(cax)
452 plt.colorbar(ax1.plot, cax)
453
454 ax1.set_xlim(self.xmin, self.xmax)
455 ax1.set_ylim(self.ymin, self.ymax)
456
457 ax1.set_ylabel(self.ylabel)
458 ax1.set_xlabel(xlabel)
459 ax1.firsttime = False
460 else:
465 else:
461 ax.plot.set_array(z_coh[n].T.ravel())
466 ax.plt.set_array(spc[pair[0]].T.ravel())
462 ax1.plot.set_array(z_phase[n].T.ravel())
467 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
463
464 ax.set_title('Coherence Ch{} * Ch{}'.format(self.dataOut.pairsList[n][0], self.dataOut.pairsList[n][1]), size=8)
465 ax1.set_title('Phase Ch{} * Ch{}'.format(self.dataOut.pairsList[n][0], self.dataOut.pairsList[n][1]), size=8)
466 self.saveTime = self.max_time
467
468
469 class PlotSpectraMeanData(PlotSpectraData):
470
471 CODE = 'spc_mean'
472 colormap = 'jet'
473
474 def plot(self):
475
476 if self.xaxis == "frequency":
477 x = self.dataOut.getFreqRange(1)/1000.
478 xlabel = "Frequency (kHz)"
479 elif self.xaxis == "time":
480 x = self.dataOut.getAcfRange(1)
481 xlabel = "Time (ms)"
482 else:
483 x = self.dataOut.getVelRange(1)
484 xlabel = "Velocity (m/s)"
485
486 y = self.dataOut.getHeiRange()
487 z = self.data['spc']
488 mean = self.data['mean'][self.max_time]
489
490 for n, ax in enumerate(self.axes):
491
468
469 ax = self.axes[4*n+1]
492 if ax.firsttime:
470 if ax.firsttime:
493 self.xmax = self.xmax if self.xmax else np.nanmax(x)
471 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
494 self.xmin = self.xmin if self.xmin else -self.xmax
495 self.ymin = self.ymin if self.ymin else np.nanmin(y)
496 self.ymax = self.ymax if self.ymax else np.nanmax(y)
497 self.zmin = self.zmin if self.zmin else np.nanmin(z)
498 self.zmax = self.zmax if self.zmax else np.nanmax(z)
499 ax.plt = ax.pcolormesh(x, y, z[n].T,
500 vmin=self.zmin,
472 vmin=self.zmin,
501 vmax=self.zmax,
473 vmax=self.zmax,
502 cmap=plt.get_cmap(self.colormap)
474 cmap=plt.get_cmap(self.colormap)
503 )
475 )
504 ax.plt_dop = ax.plot(mean[n], y,
476 else:
505 color='k')[0]
477 ax.plt.set_array(spc[pair[1]].T.ravel())
506
478 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
507 divider = make_axes_locatable(ax)
508 cax = divider.new_horizontal(size='3%', pad=0.05)
509 self.figure.add_axes(cax)
510 plt.colorbar(ax.plt, cax)
511
512 ax.set_xlim(self.xmin, self.xmax)
513 ax.set_ylim(self.ymin, self.ymax)
514
479
515 ax.set_ylabel(self.ylabel)
480 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
516 ax.set_xlabel(xlabel)
481 coh = numpy.abs(out)
482 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
517
483
518 ax.firsttime = False
484 ax = self.axes[4*n+2]
485 if ax.firsttime:
486 ax.plt = ax.pcolormesh(x, y, coh.T,
487 vmin=0,
488 vmax=1,
489 cmap=plt.get_cmap(self.colormap_coh)
490 )
491 else:
492 ax.plt.set_array(coh.T.ravel())
493 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
519
494
520 if self.showprofile:
495 ax = self.axes[4*n+3]
521 ax.plt_profile= ax.ax_profile.plot(self.data['rti'][self.max_time][n], y)[0]
496 if ax.firsttime:
522 ax.ax_profile.set_xlim(self.zmin, self.zmax)
497 ax.plt = ax.pcolormesh(x, y, phase.T,
523 ax.ax_profile.set_ylim(self.ymin, self.ymax)
498 vmin=-180,
524 ax.ax_profile.set_xlabel('dB')
499 vmax=180,
525 ax.ax_profile.grid(b=True, axis='x')
500 cmap=plt.get_cmap(self.colormap_phase)
526 ax.plt_noise = ax.ax_profile.plot(numpy.repeat(self.data['noise'][self.max_time][n], len(y)), y,
501 )
527 color="k", linestyle="dashed", lw=2)[0]
528 [tick.set_visible(False) for tick in ax.ax_profile.get_yticklabels()]
529 else:
502 else:
530 ax.plt.set_array(z[n].T.ravel())
503 ax.plt.set_array(phase.T.ravel())
531 ax.plt_dop.set_data(mean[n], y)
504 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
532 if self.showprofile:
533 ax.plt_profile.set_data(self.data['rti'][self.max_time][n], y)
534 ax.plt_noise.set_data(numpy.repeat(self.data['noise'][self.max_time][n], len(y)), y)
535
505
536 ax.set_title('{} - Noise: {:.2f} dB'.format(self.titles[n], self.data['noise'][self.max_time][n]),
537 size=8)
538 self.saveTime = self.max_time
506 self.saveTime = self.max_time
539
507
540
508
509 class PlotSpectraMeanData(PlotSpectraData):
510 '''
511 Plot for Spectra and Mean
512 '''
513 CODE = 'spc_mean'
514 colormap = 'jro'
515
516
541 class PlotRTIData(PlotData):
517 class PlotRTIData(PlotData):
518 '''
519 Plot for RTI data
520 '''
542
521
543 CODE = 'rti'
522 CODE = 'rti'
544 colormap = 'jro'
523 colormap = 'jro'
545
524
546 def setup(self):
525 def setup(self):
526 self.xaxis = 'time'
547 self.ncols = 1
527 self.ncols = 1
548 self.nrows = self.dataOut.nChannels
528 self.nrows = len(self.data.channels)
549 self.width = 10
529 self.nplots = len(self.data.channels)
550 #TODO : arreglar la altura de la figura, esta hardcodeada.
551 #Se arreglo, testear!
552 if self.ind_plt_ch:
553 self.height = 3.2#*self.nrows if self.nrows<6 else 12
554 else:
555 self.height = 2.2*self.nrows if self.nrows<6 else 12
556
557 '''
558 if self.nrows==1:
559 self.height += 1
560 '''
561 self.ylabel = 'Range [Km]'
530 self.ylabel = 'Range [Km]'
562 self.titles = ['Channel {}'.format(x) for x in self.dataOut.channelList]
531 self.cb_label = 'dB'
563
532 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
564 '''
565 Logica:
566 1) Si la variable ind_plt_ch es True, va a crear mas de 1 figura
567 2) guardamos "Figures" en una lista y "axes" en otra, quizas se deberia guardar el
568 axis dentro de "Figures" como un diccionario.
569 '''
570 if self.ind_plt_ch is False: #standard mode
571
572 if self.figure is None: #solo para la priemra vez
573 self.figure = plt.figure(figsize=(self.width, self.height),
574 edgecolor='k',
575 facecolor='w')
576 else:
577 self.figure.clf()
578 self.axes = []
579
580
581 for n in range(self.nrows):
582 ax = self.figure.add_subplot(self.nrows, self.ncols, n+1)
583 #ax = self.figure(n+1)
584 ax.firsttime = True
585 self.axes.append(ax)
586
587 else : #append one figure foreach channel in channelList
588 if self.figurelist == None:
589 self.figurelist = []
590 for n in range(self.nrows):
591 self.figure = plt.figure(figsize=(self.width, self.height),
592 edgecolor='k',
593 facecolor='w')
594 #add always one subplot
595 self.figurelist.append(self.figure)
596
597 else : # cada dia nuevo limpia el axes, pero mantiene el figure
598 for eachfigure in self.figurelist:
599 eachfigure.clf() # eliminaria todas las figuras de la lista?
600 self.axes = []
601
602 for eachfigure in self.figurelist:
603 ax = eachfigure.add_subplot(1,1,1) #solo 1 axis por figura
604 #ax = self.figure(n+1)
605 ax.firsttime = True
606 #Cada figura tiene un distinto puntero
607 self.axes.append(ax)
608 #plt.close(eachfigure)
609
610
533
611 def plot(self):
534 def plot(self):
535 self.x = self.data.times
536 self.y = self.data.heights
537 self.z = self.data[self.CODE]
538 self.z = numpy.ma.masked_invalid(self.z)
612
539
613 if self.ind_plt_ch is False: #standard mode
614 self.x = np.array(self.times)
615 self.y = self.dataOut.getHeiRange()
616 self.z = []
617
618 for ch in range(self.nrows):
619 self.z.append([self.data[self.CODE][t][ch] for t in self.times])
620
621 self.z = np.array(self.z)
622 for n, ax in enumerate(self.axes):
540 for n, ax in enumerate(self.axes):
623 x, y, z = self.fill_gaps(*self.decimate())
541 x, y, z = self.fill_gaps(*self.decimate())
624 if self.xmin is None:
542 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
625 xmin = self.min_time
543 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
626 else:
627 xmin = fromtimestamp(int(self.xmin), self.min_time)
628 if self.xmax is None:
629 xmax = xmin + self.xrange*60*60
630 else:
631 xmax = xmin + (self.xmax - self.xmin) * 60 * 60
632 self.zmin = self.zmin if self.zmin else np.min(self.z)
633 self.zmax = self.zmax if self.zmax else np.max(self.z)
634 if ax.firsttime:
544 if ax.firsttime:
635 self.ymin = self.ymin if self.ymin else np.nanmin(self.y)
545 ax.plt = ax.pcolormesh(x, y, z[n].T,
636 self.ymax = self.ymax if self.ymax else np.nanmax(self.y)
637 plot = ax.pcolormesh(x, y, z[n].T,
638 vmin=self.zmin,
546 vmin=self.zmin,
639 vmax=self.zmax,
547 vmax=self.zmax,
640 cmap=plt.get_cmap(self.colormap)
548 cmap=plt.get_cmap(self.colormap)
641 )
549 )
642 divider = make_axes_locatable(ax)
550 if self.showprofile:
643 cax = divider.new_horizontal(size='2%', pad=0.05)
551 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
644 self.figure.add_axes(cax)
552 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
645 plt.colorbar(plot, cax)
553 color="k", linestyle="dashed", lw=1)[0]
646 ax.set_ylim(self.ymin, self.ymax)
647 ax.xaxis.set_major_formatter(FuncFormatter(func))
648 ax.xaxis.set_major_locator(LinearLocator(6))
649 ax.set_ylabel(self.ylabel)
650 # if self.xmin is None:
651 # xmin = self.min_time
652 # else:
653 # xmin = (datetime.datetime.combine(self.dataOut.datatime.date(),
654 # datetime.time(self.xmin, 0, 0))-d1970).total_seconds()
655
656 ax.set_xlim(xmin, xmax)
657 ax.firsttime = False
658 else:
554 else:
659 ax.collections.remove(ax.collections[0])
555 ax.collections.remove(ax.collections[0])
660 ax.set_xlim(xmin, xmax)
556 ax.plt = ax.pcolormesh(x, y, z[n].T,
661 plot = ax.pcolormesh(x, y, z[n].T,
662 vmin=self.zmin,
663 vmax=self.zmax,
664 cmap=plt.get_cmap(self.colormap)
665 )
666 ax.set_title('{} {}'.format(self.titles[n],
667 datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')),
668 size=8)
669
670 self.saveTime = self.min_time
671 else :
672 self.x = np.array(self.times)
673 self.y = self.dataOut.getHeiRange()
674 self.z = []
675
676 for ch in range(self.nrows):
677 self.z.append([self.data[self.CODE][t][ch] for t in self.times])
678
679 self.z = np.array(self.z)
680 for n, eachfigure in enumerate(self.figurelist): #estaba ax in axes
681
682 x, y, z = self.fill_gaps(*self.decimate())
683 xmin = self.min_time
684 xmax = xmin+self.xrange*60*60
685 self.zmin = self.zmin if self.zmin else np.min(self.z)
686 self.zmax = self.zmax if self.zmax else np.max(self.z)
687 if self.axes[n].firsttime:
688 self.ymin = self.ymin if self.ymin else np.nanmin(self.y)
689 self.ymax = self.ymax if self.ymax else np.nanmax(self.y)
690 plot = self.axes[n].pcolormesh(x, y, z[n].T,
691 vmin=self.zmin,
692 vmax=self.zmax,
693 cmap=plt.get_cmap(self.colormap)
694 )
695 divider = make_axes_locatable(self.axes[n])
696 cax = divider.new_horizontal(size='2%', pad=0.05)
697 eachfigure.add_axes(cax)
698 #self.figure2.add_axes(cax)
699 plt.colorbar(plot, cax)
700 self.axes[n].set_ylim(self.ymin, self.ymax)
701
702 self.axes[n].xaxis.set_major_formatter(FuncFormatter(func))
703 self.axes[n].xaxis.set_major_locator(LinearLocator(6))
704
705 self.axes[n].set_ylabel(self.ylabel)
706
707 if self.xmin is None:
708 xmin = self.min_time
709 else:
710 xmin = (datetime.datetime.combine(self.dataOut.datatime.date(),
711 datetime.time(self.xmin, 0, 0))-d1970).total_seconds()
712
713 self.axes[n].set_xlim(xmin, xmax)
714 self.axes[n].firsttime = False
715 else:
716 self.axes[n].collections.remove(self.axes[n].collections[0])
717 self.axes[n].set_xlim(xmin, xmax)
718 plot = self.axes[n].pcolormesh(x, y, z[n].T,
719 vmin=self.zmin,
557 vmin=self.zmin,
720 vmax=self.zmax,
558 vmax=self.zmax,
721 cmap=plt.get_cmap(self.colormap)
559 cmap=plt.get_cmap(self.colormap)
722 )
560 )
723 self.axes[n].set_title('{} {}'.format(self.titles[n],
561 if self.showprofile:
724 datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')),
562 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
725 size=8)
563 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
726
564
727 self.saveTime = self.min_time
565 self.saveTime = self.min_time
728
566
729
567
730 class PlotCOHData(PlotRTIData):
568 class PlotCOHData(PlotRTIData):
569 '''
570 Plot for Coherence data
571 '''
731
572
732 CODE = 'coh'
573 CODE = 'coh'
733
574
734 def setup(self):
575 def setup(self):
735
576 self.xaxis = 'time'
736 self.ncols = 1
577 self.ncols = 1
737 self.nrows = self.dataOut.nPairs
578 self.nrows = len(self.data.pairs)
738 self.width = 10
579 self.nplots = len(self.data.pairs)
739 self.height = 2.2*self.nrows if self.nrows<6 else 12
740 self.ind_plt_ch = False #just for coherence and phase
741 if self.nrows==1:
742 self.height += 1
743 self.ylabel = 'Range [Km]'
580 self.ylabel = 'Range [Km]'
744 self.titles = ['{} Ch{} * Ch{}'.format(self.CODE.upper(), x[0], x[1]) for x in self.dataOut.pairsList]
581 if self.CODE == 'coh':
745
582 self.cb_label = ''
746 if self.figure is None:
583 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
747 self.figure = plt.figure(figsize=(self.width, self.height),
748 edgecolor='k',
749 facecolor='w')
750 else:
584 else:
751 self.figure.clf()
585 self.cb_label = 'Degrees'
752 self.axes = []
586 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
753
587
754 for n in range(self.nrows):
588
755 ax = self.figure.add_subplot(self.nrows, self.ncols, n+1)
589 class PlotPHASEData(PlotCOHData):
756 ax.firsttime = True
590 '''
757 self.axes.append(ax)
591 Plot for Phase map data
592 '''
593
594 CODE = 'phase'
595 colormap = 'seismic'
758
596
759
597
760 class PlotNoiseData(PlotData):
598 class PlotNoiseData(PlotData):
599 '''
600 Plot for noise
601 '''
602
761 CODE = 'noise'
603 CODE = 'noise'
762
604
763 def setup(self):
605 def setup(self):
764
606 self.xaxis = 'time'
765 self.ncols = 1
607 self.ncols = 1
766 self.nrows = 1
608 self.nrows = 1
767 self.width = 10
609 self.nplots = 1
768 self.height = 3.2
769 self.ylabel = 'Intensity [dB]'
610 self.ylabel = 'Intensity [dB]'
770 self.titles = ['Noise']
611 self.titles = ['Noise']
771
612 self.colorbar = False
772 if self.figure is None:
773 self.figure = plt.figure(figsize=(self.width, self.height),
774 edgecolor='k',
775 facecolor='w')
776 else:
777 self.figure.clf()
778 self.axes = []
779
780 self.ax = self.figure.add_subplot(self.nrows, self.ncols, 1)
781 self.ax.firsttime = True
782
783 def plot(self):
784
785 x = self.times
786 xmin = self.min_time
787 xmax = xmin+self.xrange*60*60
788 if self.ax.firsttime:
789 for ch in self.dataOut.channelList:
790 y = [self.data[self.CODE][t][ch] for t in self.times]
791 self.ax.plot(x, y, lw=1, label='Ch{}'.format(ch))
792 self.ax.firsttime = False
793 self.ax.xaxis.set_major_formatter(FuncFormatter(func))
794 self.ax.xaxis.set_major_locator(LinearLocator(6))
795 self.ax.set_ylabel(self.ylabel)
796 plt.legend()
797 else:
798 for ch in self.dataOut.channelList:
799 y = [self.data[self.CODE][t][ch] for t in self.times]
800 self.ax.lines[ch].set_data(x, y)
801
802 self.ax.set_xlim(xmin, xmax)
803 self.ax.set_ylim(min(y)-5, max(y)+5)
804 self.saveTime = self.min_time
805
806
807 class PlotWindProfilerData(PlotRTIData):
808
809 CODE = 'wind'
810 colormap = 'seismic'
811
812 def setup(self):
813 self.ncols = 1
814 self.nrows = self.dataOut.data_output.shape[0]
815 self.width = 10
816 self.height = 2.2*self.nrows
817 self.ylabel = 'Height [Km]'
818 self.titles = ['Zonal Wind' ,'Meridional Wind', 'Vertical Wind']
819 self.clabels = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
820 self.windFactor = [1, 1, 100]
821
822 if self.figure is None:
823 self.figure = plt.figure(figsize=(self.width, self.height),
824 edgecolor='k',
825 facecolor='w')
826 else:
827 self.figure.clf()
828 self.axes = []
829
830 for n in range(self.nrows):
831 ax = self.figure.add_subplot(self.nrows, self.ncols, n+1)
832 ax.firsttime = True
833 self.axes.append(ax)
834
613
835 def plot(self):
614 def plot(self):
836
615
837 self.x = np.array(self.times)
616 x = self.data.times
838 self.y = self.dataOut.heightList
839 self.z = []
840
841 for ch in range(self.nrows):
842 self.z.append([self.data['output'][t][ch] for t in self.times])
843
844 self.z = np.array(self.z)
845 self.z = numpy.ma.masked_invalid(self.z)
846
847 cmap=plt.get_cmap(self.colormap)
848 cmap.set_bad('black', 1.)
849
850 for n, ax in enumerate(self.axes):
851 x, y, z = self.fill_gaps(*self.decimate())
852 xmin = self.min_time
617 xmin = self.min_time
853 xmax = xmin+self.xrange*60*60
618 xmax = xmin+self.xrange*60*60
854 if ax.firsttime:
619 Y = self.data[self.CODE]
855 self.ymin = self.ymin if self.ymin else np.nanmin(self.y)
856 self.ymax = self.ymax if self.ymax else np.nanmax(self.y)
857 self.zmax = self.zmax if self.zmax else numpy.nanmax(abs(self.z[:-1, :]))
858 self.zmin = self.zmin if self.zmin else -self.zmax
859
860 plot = ax.pcolormesh(x, y, z[n].T*self.windFactor[n],
861 vmin=self.zmin,
862 vmax=self.zmax,
863 cmap=cmap
864 )
865 divider = make_axes_locatable(ax)
866 cax = divider.new_horizontal(size='2%', pad=0.05)
867 self.figure.add_axes(cax)
868 cb = plt.colorbar(plot, cax)
869 cb.set_label(self.clabels[n])
870 ax.set_ylim(self.ymin, self.ymax)
871
620
872 ax.xaxis.set_major_formatter(FuncFormatter(func))
621 if self.axes[0].firsttime:
873 ax.xaxis.set_major_locator(LinearLocator(6))
622 for ch in self.data.channels:
874
623 y = Y[ch]
875 ax.set_ylabel(self.ylabel)
624 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
876
625 plt.legend()
877 ax.set_xlim(xmin, xmax)
878 ax.firsttime = False
879 else:
626 else:
880 ax.collections.remove(ax.collections[0])
627 for ch in self.data.channels:
881 ax.set_xlim(xmin, xmax)
628 y = Y[ch]
882 plot = ax.pcolormesh(x, y, z[n].T*self.windFactor[n],
629 self.axes[0].lines[ch].set_data(x, y)
883 vmin=self.zmin,
884 vmax=self.zmax,
885 cmap=plt.get_cmap(self.colormap)
886 )
887 ax.set_title('{} {}'.format(self.titles[n],
888 datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')),
889 size=8)
890
630
631 self.ymin = numpy.nanmin(Y) - 5
632 self.ymax = numpy.nanmax(Y) + 5
891 self.saveTime = self.min_time
633 self.saveTime = self.min_time
892
634
893
635
894 class PlotSNRData(PlotRTIData):
636 class PlotSNRData(PlotRTIData):
637 '''
638 Plot for SNR Data
639 '''
640
895 CODE = 'snr'
641 CODE = 'snr'
896 colormap = 'jet'
642 colormap = 'jet'
897
643
644
898 class PlotDOPData(PlotRTIData):
645 class PlotDOPData(PlotRTIData):
646 '''
647 Plot for DOPPLER Data
648 '''
649
899 CODE = 'dop'
650 CODE = 'dop'
900 colormap = 'jet'
651 colormap = 'jet'
901
652
902
653
903 class PlotPHASEData(PlotCOHData):
904 CODE = 'phase'
905 colormap = 'seismic'
906
907
908 class PlotSkyMapData(PlotData):
654 class PlotSkyMapData(PlotData):
655 '''
656 Plot for meteors detection data
657 '''
909
658
910 CODE = 'met'
659 CODE = 'met'
911
660
912 def setup(self):
661 def setup(self):
913
662
914 self.ncols = 1
663 self.ncols = 1
915 self.nrows = 1
664 self.nrows = 1
916 self.width = 7.2
665 self.width = 7.2
917 self.height = 7.2
666 self.height = 7.2
918
667
919 self.xlabel = 'Zonal Zenith Angle (deg)'
668 self.xlabel = 'Zonal Zenith Angle (deg)'
920 self.ylabel = 'Meridional Zenith Angle (deg)'
669 self.ylabel = 'Meridional Zenith Angle (deg)'
921
670
922 if self.figure is None:
671 if self.figure is None:
923 self.figure = plt.figure(figsize=(self.width, self.height),
672 self.figure = plt.figure(figsize=(self.width, self.height),
924 edgecolor='k',
673 edgecolor='k',
925 facecolor='w')
674 facecolor='w')
926 else:
675 else:
927 self.figure.clf()
676 self.figure.clf()
928
677
929 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)
930 self.ax.firsttime = True
679 self.ax.firsttime = True
931
680
932
681
933 def plot(self):
682 def plot(self):
934
683
935 arrayParameters = np.concatenate([self.data['param'][t] for t in self.times])
684 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.data.times])
936 error = arrayParameters[:,-1]
685 error = arrayParameters[:,-1]
937 indValid = numpy.where(error == 0)[0]
686 indValid = numpy.where(error == 0)[0]
938 finalMeteor = arrayParameters[indValid,:]
687 finalMeteor = arrayParameters[indValid,:]
939 finalAzimuth = finalMeteor[:,3]
688 finalAzimuth = finalMeteor[:,3]
940 finalZenith = finalMeteor[:,4]
689 finalZenith = finalMeteor[:,4]
941
690
942 x = finalAzimuth*numpy.pi/180
691 x = finalAzimuth*numpy.pi/180
943 y = finalZenith
692 y = finalZenith
944
693
945 if self.ax.firsttime:
694 if self.ax.firsttime:
946 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]
947 self.ax.set_ylim(0,90)
696 self.ax.set_ylim(0,90)
948 self.ax.set_yticks(numpy.arange(0,90,20))
697 self.ax.set_yticks(numpy.arange(0,90,20))
949 self.ax.set_xlabel(self.xlabel)
698 self.ax.set_xlabel(self.xlabel)
950 self.ax.set_ylabel(self.ylabel)
699 self.ax.set_ylabel(self.ylabel)
951 self.ax.yaxis.labelpad = 40
700 self.ax.yaxis.labelpad = 40
952 self.ax.firsttime = False
701 self.ax.firsttime = False
953 else:
702 else:
954 self.ax.plot.set_data(x, y)
703 self.ax.plot.set_data(x, y)
955
704
956
705
957 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')
958 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')
959 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,
960 dt2,
709 dt2,
961 len(x))
710 len(x))
962 self.ax.set_title(title, size=8)
711 self.ax.set_title(title, size=8)
963
712
964 self.saveTime = self.max_time
713 self.saveTime = self.max_time
714
715 class PlotParamData(PlotRTIData):
716 '''
717 Plot for data_param object
718 '''
719
720 CODE = 'param'
721 colormap = 'seismic'
722
723 def setup(self):
724 self.xaxis = 'time'
725 self.ncols = 1
726 self.nrows = self.data.shape(self.CODE)[0]
727 self.nplots = self.nrows
728 if self.showSNR:
729 self.nrows += 1
730
731 self.ylabel = 'Height [Km]'
732 self.titles = self.data.parameters \
733 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
734 if self.showSNR:
735 self.titles.append('SNR')
736
737 def plot(self):
738 self.data.normalize_heights()
739 self.x = self.data.times
740 self.y = self.data.heights
741 if self.showSNR:
742 self.z = numpy.concatenate(
743 (self.data[self.CODE], self.data['snr'])
744 )
745 else:
746 self.z = self.data[self.CODE]
747
748 self.z = numpy.ma.masked_invalid(self.z)
749
750 for n, ax in enumerate(self.axes):
751
752 x, y, z = self.fill_gaps(*self.decimate())
753
754 if ax.firsttime:
755 if self.zlimits is not None:
756 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.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 vmin=self.zmin,
761 vmax=self.zmax,
762 cmap=self.cmaps[n]
763 )
764 else:
765 if self.zlimits is not None:
766 self.zmin, self.zmax = self.zlimits[n]
767 ax.collections.remove(ax.collections[0])
768 ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n],
769 vmin=self.zmin,
770 vmax=self.zmax,
771 cmap=self.cmaps[n]
772 )
773
774 self.saveTime = self.min_time
775
776 class PlotOuputData(PlotParamData):
777 '''
778 Plot data_output object
779 '''
780
781 CODE = 'output'
782 colormap = 'seismic' No newline at end of file
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,904 +1,903
1 import itertools
2
1 import numpy
3 import numpy
2
4
3 from jroproc_base import ProcessingUnit, Operation
5 from jroproc_base import ProcessingUnit, Operation
4 from schainpy.model.data.jrodata import Spectra
6 from schainpy.model.data.jrodata import Spectra
5 from schainpy.model.data.jrodata import hildebrand_sekhon
7 from schainpy.model.data.jrodata import hildebrand_sekhon
6
8
7 class SpectraProc(ProcessingUnit):
9 class SpectraProc(ProcessingUnit):
8
10
9 def __init__(self, **kwargs):
11 def __init__(self, **kwargs):
10
12
11 ProcessingUnit.__init__(self, **kwargs)
13 ProcessingUnit.__init__(self, **kwargs)
12
14
13 self.buffer = None
15 self.buffer = None
14 self.firstdatatime = None
16 self.firstdatatime = None
15 self.profIndex = 0
17 self.profIndex = 0
16 self.dataOut = Spectra()
18 self.dataOut = Spectra()
17 self.id_min = None
19 self.id_min = None
18 self.id_max = None
20 self.id_max = None
19
21
20 def __updateSpecFromVoltage(self):
22 def __updateSpecFromVoltage(self):
21
23
22 self.dataOut.timeZone = self.dataIn.timeZone
24 self.dataOut.timeZone = self.dataIn.timeZone
23 self.dataOut.dstFlag = self.dataIn.dstFlag
25 self.dataOut.dstFlag = self.dataIn.dstFlag
24 self.dataOut.errorCount = self.dataIn.errorCount
26 self.dataOut.errorCount = self.dataIn.errorCount
25 self.dataOut.useLocalTime = self.dataIn.useLocalTime
27 self.dataOut.useLocalTime = self.dataIn.useLocalTime
26
28
27 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
29 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
28 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
30 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
29 self.dataOut.channelList = self.dataIn.channelList
31 self.dataOut.channelList = self.dataIn.channelList
30 self.dataOut.heightList = self.dataIn.heightList
32 self.dataOut.heightList = self.dataIn.heightList
31 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
33 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
32
34
33 self.dataOut.nBaud = self.dataIn.nBaud
35 self.dataOut.nBaud = self.dataIn.nBaud
34 self.dataOut.nCode = self.dataIn.nCode
36 self.dataOut.nCode = self.dataIn.nCode
35 self.dataOut.code = self.dataIn.code
37 self.dataOut.code = self.dataIn.code
36 self.dataOut.nProfiles = self.dataOut.nFFTPoints
38 self.dataOut.nProfiles = self.dataOut.nFFTPoints
37
39
38 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
40 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
39 self.dataOut.utctime = self.firstdatatime
41 self.dataOut.utctime = self.firstdatatime
40 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
42 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
41 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
43 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
42 self.dataOut.flagShiftFFT = False
44 self.dataOut.flagShiftFFT = False
43
45
44 self.dataOut.nCohInt = self.dataIn.nCohInt
46 self.dataOut.nCohInt = self.dataIn.nCohInt
45 self.dataOut.nIncohInt = 1
47 self.dataOut.nIncohInt = 1
46
48
47 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
49 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
48
50
49 self.dataOut.frequency = self.dataIn.frequency
51 self.dataOut.frequency = self.dataIn.frequency
50 self.dataOut.realtime = self.dataIn.realtime
52 self.dataOut.realtime = self.dataIn.realtime
51
53
52 self.dataOut.azimuth = self.dataIn.azimuth
54 self.dataOut.azimuth = self.dataIn.azimuth
53 self.dataOut.zenith = self.dataIn.zenith
55 self.dataOut.zenith = self.dataIn.zenith
54
56
55 self.dataOut.beam.codeList = self.dataIn.beam.codeList
57 self.dataOut.beam.codeList = self.dataIn.beam.codeList
56 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
58 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
57 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
59 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
58
60
59 def __getFft(self):
61 def __getFft(self):
60 """
62 """
61 Convierte valores de Voltaje a Spectra
63 Convierte valores de Voltaje a Spectra
62
64
63 Affected:
65 Affected:
64 self.dataOut.data_spc
66 self.dataOut.data_spc
65 self.dataOut.data_cspc
67 self.dataOut.data_cspc
66 self.dataOut.data_dc
68 self.dataOut.data_dc
67 self.dataOut.heightList
69 self.dataOut.heightList
68 self.profIndex
70 self.profIndex
69 self.buffer
71 self.buffer
70 self.dataOut.flagNoData
72 self.dataOut.flagNoData
71 """
73 """
72 fft_volt = numpy.fft.fft(self.buffer,n=self.dataOut.nFFTPoints,axis=1)
74 fft_volt = numpy.fft.fft(self.buffer,n=self.dataOut.nFFTPoints,axis=1)
73 fft_volt = fft_volt.astype(numpy.dtype('complex'))
75 fft_volt = fft_volt.astype(numpy.dtype('complex'))
74 dc = fft_volt[:,0,:]
76 dc = fft_volt[:,0,:]
75
77
76 #calculo de self-spectra
78 #calculo de self-spectra
77 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
79 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
78 spc = fft_volt * numpy.conjugate(fft_volt)
80 spc = fft_volt * numpy.conjugate(fft_volt)
79 spc = spc.real
81 spc = spc.real
80
82
81 blocksize = 0
83 blocksize = 0
82 blocksize += dc.size
84 blocksize += dc.size
83 blocksize += spc.size
85 blocksize += spc.size
84
86
85 cspc = None
87 cspc = None
86 pairIndex = 0
88 pairIndex = 0
87 if self.dataOut.pairsList != None:
89 if self.dataOut.pairsList != None:
88 #calculo de cross-spectra
90 #calculo de cross-spectra
89 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
91 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
90 for pair in self.dataOut.pairsList:
92 for pair in self.dataOut.pairsList:
91 if pair[0] not in self.dataOut.channelList:
93 if pair[0] not in self.dataOut.channelList:
92 raise ValueError, "Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" %(str(pair), str(self.dataOut.channelList))
94 raise ValueError, "Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" %(str(pair), str(self.dataOut.channelList))
93 if pair[1] not in self.dataOut.channelList:
95 if pair[1] not in self.dataOut.channelList:
94 raise ValueError, "Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" %(str(pair), str(self.dataOut.channelList))
96 raise ValueError, "Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" %(str(pair), str(self.dataOut.channelList))
95
97
96 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
98 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
97 pairIndex += 1
99 pairIndex += 1
98 blocksize += cspc.size
100 blocksize += cspc.size
99
101
100 self.dataOut.data_spc = spc
102 self.dataOut.data_spc = spc
101 self.dataOut.data_cspc = cspc
103 self.dataOut.data_cspc = cspc
102 self.dataOut.data_dc = dc
104 self.dataOut.data_dc = dc
103 self.dataOut.blockSize = blocksize
105 self.dataOut.blockSize = blocksize
104 self.dataOut.flagShiftFFT = True
106 self.dataOut.flagShiftFFT = True
105
107
106 def run(self, nProfiles=None, nFFTPoints=None, pairsList=[], ippFactor=None):
108 def run(self, nProfiles=None, nFFTPoints=None, pairsList=[], ippFactor=None):
107
109
108 self.dataOut.flagNoData = True
110 self.dataOut.flagNoData = True
109
111
110 if self.dataIn.type == "Spectra":
112 if self.dataIn.type == "Spectra":
111 self.dataOut.copy(self.dataIn)
113 self.dataOut.copy(self.dataIn)
112 # self.__selectPairs(pairsList)
114 if not pairsList:
115 pairsList = itertools.combinations(self.dataOut.channelList, 2)
116 if self.dataOut.data_cspc is not None:
117 self.__selectPairs(pairsList)
113 return True
118 return True
114
119
115 if self.dataIn.type == "Voltage":
120 if self.dataIn.type == "Voltage":
116
121
117 if nFFTPoints == None:
122 if nFFTPoints == None:
118 raise ValueError, "This SpectraProc.run() need nFFTPoints input variable"
123 raise ValueError, "This SpectraProc.run() need nFFTPoints input variable"
119
124
120 if nProfiles == None:
125 if nProfiles == None:
121 nProfiles = nFFTPoints
126 nProfiles = nFFTPoints
122
127
123 if ippFactor == None:
128 if ippFactor == None:
124 ippFactor = 1
129 ippFactor = 1
125
130
126 self.dataOut.ippFactor = ippFactor
131 self.dataOut.ippFactor = ippFactor
127
132
128 self.dataOut.nFFTPoints = nFFTPoints
133 self.dataOut.nFFTPoints = nFFTPoints
129 self.dataOut.pairsList = pairsList
134 self.dataOut.pairsList = pairsList
130
135
131 if self.buffer is None:
136 if self.buffer is None:
132 self.buffer = numpy.zeros( (self.dataIn.nChannels,
137 self.buffer = numpy.zeros( (self.dataIn.nChannels,
133 nProfiles,
138 nProfiles,
134 self.dataIn.nHeights),
139 self.dataIn.nHeights),
135 dtype='complex')
140 dtype='complex')
136
141
137 if self.dataIn.flagDataAsBlock:
142 if self.dataIn.flagDataAsBlock:
138 #data dimension: [nChannels, nProfiles, nSamples]
143 #data dimension: [nChannels, nProfiles, nSamples]
139 nVoltProfiles = self.dataIn.data.shape[1]
144 nVoltProfiles = self.dataIn.data.shape[1]
140 # nVoltProfiles = self.dataIn.nProfiles
145 # nVoltProfiles = self.dataIn.nProfiles
141
146
142 if nVoltProfiles == nProfiles:
147 if nVoltProfiles == nProfiles:
143 self.buffer = self.dataIn.data.copy()
148 self.buffer = self.dataIn.data.copy()
144 self.profIndex = nVoltProfiles
149 self.profIndex = nVoltProfiles
145
150
146 elif nVoltProfiles < nProfiles:
151 elif nVoltProfiles < nProfiles:
147
152
148 if self.profIndex == 0:
153 if self.profIndex == 0:
149 self.id_min = 0
154 self.id_min = 0
150 self.id_max = nVoltProfiles
155 self.id_max = nVoltProfiles
151
156
152 self.buffer[:,self.id_min:self.id_max,:] = self.dataIn.data
157 self.buffer[:,self.id_min:self.id_max,:] = self.dataIn.data
153 self.profIndex += nVoltProfiles
158 self.profIndex += nVoltProfiles
154 self.id_min += nVoltProfiles
159 self.id_min += nVoltProfiles
155 self.id_max += nVoltProfiles
160 self.id_max += nVoltProfiles
156 else:
161 else:
157 raise ValueError, "The type object %s has %d profiles, it should just has %d profiles"%(self.dataIn.type,self.dataIn.data.shape[1],nProfiles)
162 raise ValueError, "The type object %s has %d profiles, it should just has %d profiles"%(self.dataIn.type,self.dataIn.data.shape[1],nProfiles)
158 self.dataOut.flagNoData = True
163 self.dataOut.flagNoData = True
159 return 0
164 return 0
160 else:
165 else:
161 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
166 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
162 self.profIndex += 1
167 self.profIndex += 1
163
168
164 if self.firstdatatime == None:
169 if self.firstdatatime == None:
165 self.firstdatatime = self.dataIn.utctime
170 self.firstdatatime = self.dataIn.utctime
166
171
167 if self.profIndex == nProfiles:
172 if self.profIndex == nProfiles:
168 self.__updateSpecFromVoltage()
173 self.__updateSpecFromVoltage()
169 self.__getFft()
174 self.__getFft()
170
175
171 self.dataOut.flagNoData = False
176 self.dataOut.flagNoData = False
172 self.firstdatatime = None
177 self.firstdatatime = None
173 self.profIndex = 0
178 self.profIndex = 0
174
179
175 return True
180 return True
176
181
177 raise ValueError, "The type of input object '%s' is not valid"%(self.dataIn.type)
182 raise ValueError, "The type of input object '%s' is not valid"%(self.dataIn.type)
178
183
179 def __selectPairs(self, pairsList):
184 def __selectPairs(self, pairsList):
180
185
181 if channelList == None:
186 if not pairsList:
182 return
187 return
183
188
184 pairsIndexListSelected = []
189 pairs = []
185
190 pairsIndex = []
186 for thisPair in pairsList:
187
191
188 if thisPair not in self.dataOut.pairsList:
192 for pair in pairsList:
193 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
189 continue
194 continue
195 pairs.append(pair)
196 pairsIndex.append(pairs.index(pair))
190
197
191 pairIndex = self.dataOut.pairsList.index(thisPair)
198 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
192
199 self.dataOut.pairsList = pairs
193 pairsIndexListSelected.append(pairIndex)
200 self.dataOut.pairsIndexList = pairsIndex
194
195 if not pairsIndexListSelected:
196 self.dataOut.data_cspc = None
197 self.dataOut.pairsList = []
198 return
199
200 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
201 self.dataOut.pairsList = [self.dataOut.pairsList[i] for i in pairsIndexListSelected]
202
201
203 return
202 return
204
203
205 def __selectPairsByChannel(self, channelList=None):
204 def __selectPairsByChannel(self, channelList=None):
206
205
207 if channelList == None:
206 if channelList == None:
208 return
207 return
209
208
210 pairsIndexListSelected = []
209 pairsIndexListSelected = []
211 for pairIndex in self.dataOut.pairsIndexList:
210 for pairIndex in self.dataOut.pairsIndexList:
212 #First pair
211 #First pair
213 if self.dataOut.pairsList[pairIndex][0] not in channelList:
212 if self.dataOut.pairsList[pairIndex][0] not in channelList:
214 continue
213 continue
215 #Second pair
214 #Second pair
216 if self.dataOut.pairsList[pairIndex][1] not in channelList:
215 if self.dataOut.pairsList[pairIndex][1] not in channelList:
217 continue
216 continue
218
217
219 pairsIndexListSelected.append(pairIndex)
218 pairsIndexListSelected.append(pairIndex)
220
219
221 if not pairsIndexListSelected:
220 if not pairsIndexListSelected:
222 self.dataOut.data_cspc = None
221 self.dataOut.data_cspc = None
223 self.dataOut.pairsList = []
222 self.dataOut.pairsList = []
224 return
223 return
225
224
226 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
225 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
227 self.dataOut.pairsList = [self.dataOut.pairsList[i] for i in pairsIndexListSelected]
226 self.dataOut.pairsList = [self.dataOut.pairsList[i] for i in pairsIndexListSelected]
228
227
229 return
228 return
230
229
231 def selectChannels(self, channelList):
230 def selectChannels(self, channelList):
232
231
233 channelIndexList = []
232 channelIndexList = []
234
233
235 for channel in channelList:
234 for channel in channelList:
236 if channel not in self.dataOut.channelList:
235 if channel not in self.dataOut.channelList:
237 raise ValueError, "Error selecting channels, Channel %d is not valid.\nAvailable channels = %s" %(channel, str(self.dataOut.channelList))
236 raise ValueError, "Error selecting channels, Channel %d is not valid.\nAvailable channels = %s" %(channel, str(self.dataOut.channelList))
238
237
239 index = self.dataOut.channelList.index(channel)
238 index = self.dataOut.channelList.index(channel)
240 channelIndexList.append(index)
239 channelIndexList.append(index)
241
240
242 self.selectChannelsByIndex(channelIndexList)
241 self.selectChannelsByIndex(channelIndexList)
243
242
244 def selectChannelsByIndex(self, channelIndexList):
243 def selectChannelsByIndex(self, channelIndexList):
245 """
244 """
246 Selecciona un bloque de datos en base a canales segun el channelIndexList
245 Selecciona un bloque de datos en base a canales segun el channelIndexList
247
246
248 Input:
247 Input:
249 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
248 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
250
249
251 Affected:
250 Affected:
252 self.dataOut.data_spc
251 self.dataOut.data_spc
253 self.dataOut.channelIndexList
252 self.dataOut.channelIndexList
254 self.dataOut.nChannels
253 self.dataOut.nChannels
255
254
256 Return:
255 Return:
257 None
256 None
258 """
257 """
259
258
260 for channelIndex in channelIndexList:
259 for channelIndex in channelIndexList:
261 if channelIndex not in self.dataOut.channelIndexList:
260 if channelIndex not in self.dataOut.channelIndexList:
262 raise ValueError, "Error selecting channels: The value %d in channelIndexList is not valid.\nAvailable channel indexes = " %(channelIndex, self.dataOut.channelIndexList)
261 raise ValueError, "Error selecting channels: The value %d in channelIndexList is not valid.\nAvailable channel indexes = " %(channelIndex, self.dataOut.channelIndexList)
263
262
264 # nChannels = len(channelIndexList)
263 # nChannels = len(channelIndexList)
265
264
266 data_spc = self.dataOut.data_spc[channelIndexList,:]
265 data_spc = self.dataOut.data_spc[channelIndexList,:]
267 data_dc = self.dataOut.data_dc[channelIndexList,:]
266 data_dc = self.dataOut.data_dc[channelIndexList,:]
268
267
269 self.dataOut.data_spc = data_spc
268 self.dataOut.data_spc = data_spc
270 self.dataOut.data_dc = data_dc
269 self.dataOut.data_dc = data_dc
271
270
272 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
271 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
273 # self.dataOut.nChannels = nChannels
272 # self.dataOut.nChannels = nChannels
274
273
275 self.__selectPairsByChannel(self.dataOut.channelList)
274 self.__selectPairsByChannel(self.dataOut.channelList)
276
275
277 return 1
276 return 1
278
277
279 def selectHeights(self, minHei, maxHei):
278 def selectHeights(self, minHei, maxHei):
280 """
279 """
281 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
280 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
282 minHei <= height <= maxHei
281 minHei <= height <= maxHei
283
282
284 Input:
283 Input:
285 minHei : valor minimo de altura a considerar
284 minHei : valor minimo de altura a considerar
286 maxHei : valor maximo de altura a considerar
285 maxHei : valor maximo de altura a considerar
287
286
288 Affected:
287 Affected:
289 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
288 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
290
289
291 Return:
290 Return:
292 1 si el metodo se ejecuto con exito caso contrario devuelve 0
291 1 si el metodo se ejecuto con exito caso contrario devuelve 0
293 """
292 """
294
293
295 if (minHei > maxHei):
294 if (minHei > maxHei):
296 raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei)
295 raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei)
297
296
298 if (minHei < self.dataOut.heightList[0]):
297 if (minHei < self.dataOut.heightList[0]):
299 minHei = self.dataOut.heightList[0]
298 minHei = self.dataOut.heightList[0]
300
299
301 if (maxHei > self.dataOut.heightList[-1]):
300 if (maxHei > self.dataOut.heightList[-1]):
302 maxHei = self.dataOut.heightList[-1]
301 maxHei = self.dataOut.heightList[-1]
303
302
304 minIndex = 0
303 minIndex = 0
305 maxIndex = 0
304 maxIndex = 0
306 heights = self.dataOut.heightList
305 heights = self.dataOut.heightList
307
306
308 inda = numpy.where(heights >= minHei)
307 inda = numpy.where(heights >= minHei)
309 indb = numpy.where(heights <= maxHei)
308 indb = numpy.where(heights <= maxHei)
310
309
311 try:
310 try:
312 minIndex = inda[0][0]
311 minIndex = inda[0][0]
313 except:
312 except:
314 minIndex = 0
313 minIndex = 0
315
314
316 try:
315 try:
317 maxIndex = indb[0][-1]
316 maxIndex = indb[0][-1]
318 except:
317 except:
319 maxIndex = len(heights)
318 maxIndex = len(heights)
320
319
321 self.selectHeightsByIndex(minIndex, maxIndex)
320 self.selectHeightsByIndex(minIndex, maxIndex)
322
321
323 return 1
322 return 1
324
323
325 def getBeaconSignal(self, tauindex = 0, channelindex = 0, hei_ref=None):
324 def getBeaconSignal(self, tauindex = 0, channelindex = 0, hei_ref=None):
326 newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
325 newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
327
326
328 if hei_ref != None:
327 if hei_ref != None:
329 newheis = numpy.where(self.dataOut.heightList>hei_ref)
328 newheis = numpy.where(self.dataOut.heightList>hei_ref)
330
329
331 minIndex = min(newheis[0])
330 minIndex = min(newheis[0])
332 maxIndex = max(newheis[0])
331 maxIndex = max(newheis[0])
333 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
332 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
334 heightList = self.dataOut.heightList[minIndex:maxIndex+1]
333 heightList = self.dataOut.heightList[minIndex:maxIndex+1]
335
334
336 # determina indices
335 # determina indices
337 nheis = int(self.dataOut.radarControllerHeaderObj.txB/(self.dataOut.heightList[1]-self.dataOut.heightList[0]))
336 nheis = int(self.dataOut.radarControllerHeaderObj.txB/(self.dataOut.heightList[1]-self.dataOut.heightList[0]))
338 avg_dB = 10*numpy.log10(numpy.sum(data_spc[channelindex,:,:],axis=0))
337 avg_dB = 10*numpy.log10(numpy.sum(data_spc[channelindex,:,:],axis=0))
339 beacon_dB = numpy.sort(avg_dB)[-nheis:]
338 beacon_dB = numpy.sort(avg_dB)[-nheis:]
340 beacon_heiIndexList = []
339 beacon_heiIndexList = []
341 for val in avg_dB.tolist():
340 for val in avg_dB.tolist():
342 if val >= beacon_dB[0]:
341 if val >= beacon_dB[0]:
343 beacon_heiIndexList.append(avg_dB.tolist().index(val))
342 beacon_heiIndexList.append(avg_dB.tolist().index(val))
344
343
345 #data_spc = data_spc[:,:,beacon_heiIndexList]
344 #data_spc = data_spc[:,:,beacon_heiIndexList]
346 data_cspc = None
345 data_cspc = None
347 if self.dataOut.data_cspc is not None:
346 if self.dataOut.data_cspc is not None:
348 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
347 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
349 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
348 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
350
349
351 data_dc = None
350 data_dc = None
352 if self.dataOut.data_dc is not None:
351 if self.dataOut.data_dc is not None:
353 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
352 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
354 #data_dc = data_dc[:,beacon_heiIndexList]
353 #data_dc = data_dc[:,beacon_heiIndexList]
355
354
356 self.dataOut.data_spc = data_spc
355 self.dataOut.data_spc = data_spc
357 self.dataOut.data_cspc = data_cspc
356 self.dataOut.data_cspc = data_cspc
358 self.dataOut.data_dc = data_dc
357 self.dataOut.data_dc = data_dc
359 self.dataOut.heightList = heightList
358 self.dataOut.heightList = heightList
360 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
359 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
361
360
362 return 1
361 return 1
363
362
364
363
365 def selectHeightsByIndex(self, minIndex, maxIndex):
364 def selectHeightsByIndex(self, minIndex, maxIndex):
366 """
365 """
367 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
366 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
368 minIndex <= index <= maxIndex
367 minIndex <= index <= maxIndex
369
368
370 Input:
369 Input:
371 minIndex : valor de indice minimo de altura a considerar
370 minIndex : valor de indice minimo de altura a considerar
372 maxIndex : valor de indice maximo de altura a considerar
371 maxIndex : valor de indice maximo de altura a considerar
373
372
374 Affected:
373 Affected:
375 self.dataOut.data_spc
374 self.dataOut.data_spc
376 self.dataOut.data_cspc
375 self.dataOut.data_cspc
377 self.dataOut.data_dc
376 self.dataOut.data_dc
378 self.dataOut.heightList
377 self.dataOut.heightList
379
378
380 Return:
379 Return:
381 1 si el metodo se ejecuto con exito caso contrario devuelve 0
380 1 si el metodo se ejecuto con exito caso contrario devuelve 0
382 """
381 """
383
382
384 if (minIndex < 0) or (minIndex > maxIndex):
383 if (minIndex < 0) or (minIndex > maxIndex):
385 raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex)
384 raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex)
386
385
387 if (maxIndex >= self.dataOut.nHeights):
386 if (maxIndex >= self.dataOut.nHeights):
388 maxIndex = self.dataOut.nHeights-1
387 maxIndex = self.dataOut.nHeights-1
389
388
390 #Spectra
389 #Spectra
391 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
390 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
392
391
393 data_cspc = None
392 data_cspc = None
394 if self.dataOut.data_cspc is not None:
393 if self.dataOut.data_cspc is not None:
395 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
394 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
396
395
397 data_dc = None
396 data_dc = None
398 if self.dataOut.data_dc is not None:
397 if self.dataOut.data_dc is not None:
399 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
398 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
400
399
401 self.dataOut.data_spc = data_spc
400 self.dataOut.data_spc = data_spc
402 self.dataOut.data_cspc = data_cspc
401 self.dataOut.data_cspc = data_cspc
403 self.dataOut.data_dc = data_dc
402 self.dataOut.data_dc = data_dc
404
403
405 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
404 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
406
405
407 return 1
406 return 1
408
407
409 def removeDC(self, mode = 2):
408 def removeDC(self, mode = 2):
410 jspectra = self.dataOut.data_spc
409 jspectra = self.dataOut.data_spc
411 jcspectra = self.dataOut.data_cspc
410 jcspectra = self.dataOut.data_cspc
412
411
413
412
414 num_chan = jspectra.shape[0]
413 num_chan = jspectra.shape[0]
415 num_hei = jspectra.shape[2]
414 num_hei = jspectra.shape[2]
416
415
417 if jcspectra is not None:
416 if jcspectra is not None:
418 jcspectraExist = True
417 jcspectraExist = True
419 num_pairs = jcspectra.shape[0]
418 num_pairs = jcspectra.shape[0]
420 else: jcspectraExist = False
419 else: jcspectraExist = False
421
420
422 freq_dc = jspectra.shape[1]/2
421 freq_dc = jspectra.shape[1]/2
423 ind_vel = numpy.array([-2,-1,1,2]) + freq_dc
422 ind_vel = numpy.array([-2,-1,1,2]) + freq_dc
424
423
425 if ind_vel[0]<0:
424 if ind_vel[0]<0:
426 ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof
425 ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof
427
426
428 if mode == 1:
427 if mode == 1:
429 jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION
428 jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION
430
429
431 if jcspectraExist:
430 if jcspectraExist:
432 jcspectra[:,freq_dc,:] = (jcspectra[:,ind_vel[1],:] + jcspectra[:,ind_vel[2],:])/2
431 jcspectra[:,freq_dc,:] = (jcspectra[:,ind_vel[1],:] + jcspectra[:,ind_vel[2],:])/2
433
432
434 if mode == 2:
433 if mode == 2:
435
434
436 vel = numpy.array([-2,-1,1,2])
435 vel = numpy.array([-2,-1,1,2])
437 xx = numpy.zeros([4,4])
436 xx = numpy.zeros([4,4])
438
437
439 for fil in range(4):
438 for fil in range(4):
440 xx[fil,:] = vel[fil]**numpy.asarray(range(4))
439 xx[fil,:] = vel[fil]**numpy.asarray(range(4))
441
440
442 xx_inv = numpy.linalg.inv(xx)
441 xx_inv = numpy.linalg.inv(xx)
443 xx_aux = xx_inv[0,:]
442 xx_aux = xx_inv[0,:]
444
443
445 for ich in range(num_chan):
444 for ich in range(num_chan):
446 yy = jspectra[ich,ind_vel,:]
445 yy = jspectra[ich,ind_vel,:]
447 jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy)
446 jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy)
448
447
449 junkid = jspectra[ich,freq_dc,:]<=0
448 junkid = jspectra[ich,freq_dc,:]<=0
450 cjunkid = sum(junkid)
449 cjunkid = sum(junkid)
451
450
452 if cjunkid.any():
451 if cjunkid.any():
453 jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2
452 jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2
454
453
455 if jcspectraExist:
454 if jcspectraExist:
456 for ip in range(num_pairs):
455 for ip in range(num_pairs):
457 yy = jcspectra[ip,ind_vel,:]
456 yy = jcspectra[ip,ind_vel,:]
458 jcspectra[ip,freq_dc,:] = numpy.dot(xx_aux,yy)
457 jcspectra[ip,freq_dc,:] = numpy.dot(xx_aux,yy)
459
458
460
459
461 self.dataOut.data_spc = jspectra
460 self.dataOut.data_spc = jspectra
462 self.dataOut.data_cspc = jcspectra
461 self.dataOut.data_cspc = jcspectra
463
462
464 return 1
463 return 1
465
464
466 def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None):
465 def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None):
467
466
468 jspectra = self.dataOut.data_spc
467 jspectra = self.dataOut.data_spc
469 jcspectra = self.dataOut.data_cspc
468 jcspectra = self.dataOut.data_cspc
470 jnoise = self.dataOut.getNoise()
469 jnoise = self.dataOut.getNoise()
471 num_incoh = self.dataOut.nIncohInt
470 num_incoh = self.dataOut.nIncohInt
472
471
473 num_channel = jspectra.shape[0]
472 num_channel = jspectra.shape[0]
474 num_prof = jspectra.shape[1]
473 num_prof = jspectra.shape[1]
475 num_hei = jspectra.shape[2]
474 num_hei = jspectra.shape[2]
476
475
477 #hei_interf
476 #hei_interf
478 if hei_interf is None:
477 if hei_interf is None:
479 count_hei = num_hei/2 #Como es entero no importa
478 count_hei = num_hei/2 #Como es entero no importa
480 hei_interf = numpy.asmatrix(range(count_hei)) + num_hei - count_hei
479 hei_interf = numpy.asmatrix(range(count_hei)) + num_hei - count_hei
481 hei_interf = numpy.asarray(hei_interf)[0]
480 hei_interf = numpy.asarray(hei_interf)[0]
482 #nhei_interf
481 #nhei_interf
483 if (nhei_interf == None):
482 if (nhei_interf == None):
484 nhei_interf = 5
483 nhei_interf = 5
485 if (nhei_interf < 1):
484 if (nhei_interf < 1):
486 nhei_interf = 1
485 nhei_interf = 1
487 if (nhei_interf > count_hei):
486 if (nhei_interf > count_hei):
488 nhei_interf = count_hei
487 nhei_interf = count_hei
489 if (offhei_interf == None):
488 if (offhei_interf == None):
490 offhei_interf = 0
489 offhei_interf = 0
491
490
492 ind_hei = range(num_hei)
491 ind_hei = range(num_hei)
493 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
492 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
494 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
493 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
495 mask_prof = numpy.asarray(range(num_prof))
494 mask_prof = numpy.asarray(range(num_prof))
496 num_mask_prof = mask_prof.size
495 num_mask_prof = mask_prof.size
497 comp_mask_prof = [0, num_prof/2]
496 comp_mask_prof = [0, num_prof/2]
498
497
499
498
500 #noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
499 #noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
501 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
500 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
502 jnoise = numpy.nan
501 jnoise = numpy.nan
503 noise_exist = jnoise[0] < numpy.Inf
502 noise_exist = jnoise[0] < numpy.Inf
504
503
505 #Subrutina de Remocion de la Interferencia
504 #Subrutina de Remocion de la Interferencia
506 for ich in range(num_channel):
505 for ich in range(num_channel):
507 #Se ordena los espectros segun su potencia (menor a mayor)
506 #Se ordena los espectros segun su potencia (menor a mayor)
508 power = jspectra[ich,mask_prof,:]
507 power = jspectra[ich,mask_prof,:]
509 power = power[:,hei_interf]
508 power = power[:,hei_interf]
510 power = power.sum(axis = 0)
509 power = power.sum(axis = 0)
511 psort = power.ravel().argsort()
510 psort = power.ravel().argsort()
512
511
513 #Se estima la interferencia promedio en los Espectros de Potencia empleando
512 #Se estima la interferencia promedio en los Espectros de Potencia empleando
514 junkspc_interf = jspectra[ich,:,hei_interf[psort[range(offhei_interf, nhei_interf + offhei_interf)]]]
513 junkspc_interf = jspectra[ich,:,hei_interf[psort[range(offhei_interf, nhei_interf + offhei_interf)]]]
515
514
516 if noise_exist:
515 if noise_exist:
517 # tmp_noise = jnoise[ich] / num_prof
516 # tmp_noise = jnoise[ich] / num_prof
518 tmp_noise = jnoise[ich]
517 tmp_noise = jnoise[ich]
519 junkspc_interf = junkspc_interf - tmp_noise
518 junkspc_interf = junkspc_interf - tmp_noise
520 #junkspc_interf[:,comp_mask_prof] = 0
519 #junkspc_interf[:,comp_mask_prof] = 0
521
520
522 jspc_interf = junkspc_interf.sum(axis = 0) / nhei_interf
521 jspc_interf = junkspc_interf.sum(axis = 0) / nhei_interf
523 jspc_interf = jspc_interf.transpose()
522 jspc_interf = jspc_interf.transpose()
524 #Calculando el espectro de interferencia promedio
523 #Calculando el espectro de interferencia promedio
525 noiseid = numpy.where(jspc_interf <= tmp_noise/ numpy.sqrt(num_incoh))
524 noiseid = numpy.where(jspc_interf <= tmp_noise/ numpy.sqrt(num_incoh))
526 noiseid = noiseid[0]
525 noiseid = noiseid[0]
527 cnoiseid = noiseid.size
526 cnoiseid = noiseid.size
528 interfid = numpy.where(jspc_interf > tmp_noise/ numpy.sqrt(num_incoh))
527 interfid = numpy.where(jspc_interf > tmp_noise/ numpy.sqrt(num_incoh))
529 interfid = interfid[0]
528 interfid = interfid[0]
530 cinterfid = interfid.size
529 cinterfid = interfid.size
531
530
532 if (cnoiseid > 0): jspc_interf[noiseid] = 0
531 if (cnoiseid > 0): jspc_interf[noiseid] = 0
533
532
534 #Expandiendo los perfiles a limpiar
533 #Expandiendo los perfiles a limpiar
535 if (cinterfid > 0):
534 if (cinterfid > 0):
536 new_interfid = (numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof)%num_prof
535 new_interfid = (numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof)%num_prof
537 new_interfid = numpy.asarray(new_interfid)
536 new_interfid = numpy.asarray(new_interfid)
538 new_interfid = {x for x in new_interfid}
537 new_interfid = {x for x in new_interfid}
539 new_interfid = numpy.array(list(new_interfid))
538 new_interfid = numpy.array(list(new_interfid))
540 new_cinterfid = new_interfid.size
539 new_cinterfid = new_interfid.size
541 else: new_cinterfid = 0
540 else: new_cinterfid = 0
542
541
543 for ip in range(new_cinterfid):
542 for ip in range(new_cinterfid):
544 ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort()
543 ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort()
545 jspc_interf[new_interfid[ip]] = junkspc_interf[ind[nhei_interf/2],new_interfid[ip]]
544 jspc_interf[new_interfid[ip]] = junkspc_interf[ind[nhei_interf/2],new_interfid[ip]]
546
545
547
546
548 jspectra[ich,:,ind_hei] = jspectra[ich,:,ind_hei] - jspc_interf #Corregir indices
547 jspectra[ich,:,ind_hei] = jspectra[ich,:,ind_hei] - jspc_interf #Corregir indices
549
548
550 #Removiendo la interferencia del punto de mayor interferencia
549 #Removiendo la interferencia del punto de mayor interferencia
551 ListAux = jspc_interf[mask_prof].tolist()
550 ListAux = jspc_interf[mask_prof].tolist()
552 maxid = ListAux.index(max(ListAux))
551 maxid = ListAux.index(max(ListAux))
553
552
554
553
555 if cinterfid > 0:
554 if cinterfid > 0:
556 for ip in range(cinterfid*(interf == 2) - 1):
555 for ip in range(cinterfid*(interf == 2) - 1):
557 ind = (jspectra[ich,interfid[ip],:] < tmp_noise*(1 + 1/numpy.sqrt(num_incoh))).nonzero()
556 ind = (jspectra[ich,interfid[ip],:] < tmp_noise*(1 + 1/numpy.sqrt(num_incoh))).nonzero()
558 cind = len(ind)
557 cind = len(ind)
559
558
560 if (cind > 0):
559 if (cind > 0):
561 jspectra[ich,interfid[ip],ind] = tmp_noise*(1 + (numpy.random.uniform(cind) - 0.5)/numpy.sqrt(num_incoh))
560 jspectra[ich,interfid[ip],ind] = tmp_noise*(1 + (numpy.random.uniform(cind) - 0.5)/numpy.sqrt(num_incoh))
562
561
563 ind = numpy.array([-2,-1,1,2])
562 ind = numpy.array([-2,-1,1,2])
564 xx = numpy.zeros([4,4])
563 xx = numpy.zeros([4,4])
565
564
566 for id1 in range(4):
565 for id1 in range(4):
567 xx[:,id1] = ind[id1]**numpy.asarray(range(4))
566 xx[:,id1] = ind[id1]**numpy.asarray(range(4))
568
567
569 xx_inv = numpy.linalg.inv(xx)
568 xx_inv = numpy.linalg.inv(xx)
570 xx = xx_inv[:,0]
569 xx = xx_inv[:,0]
571 ind = (ind + maxid + num_mask_prof)%num_mask_prof
570 ind = (ind + maxid + num_mask_prof)%num_mask_prof
572 yy = jspectra[ich,mask_prof[ind],:]
571 yy = jspectra[ich,mask_prof[ind],:]
573 jspectra[ich,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx)
572 jspectra[ich,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx)
574
573
575
574
576 indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero()
575 indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero()
577 jspectra[ich,indAux[0],indAux[1]] = tmp_noise * (1 - 1/numpy.sqrt(num_incoh))
576 jspectra[ich,indAux[0],indAux[1]] = tmp_noise * (1 - 1/numpy.sqrt(num_incoh))
578
577
579 #Remocion de Interferencia en el Cross Spectra
578 #Remocion de Interferencia en el Cross Spectra
580 if jcspectra is None: return jspectra, jcspectra
579 if jcspectra is None: return jspectra, jcspectra
581 num_pairs = jcspectra.size/(num_prof*num_hei)
580 num_pairs = jcspectra.size/(num_prof*num_hei)
582 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
581 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
583
582
584 for ip in range(num_pairs):
583 for ip in range(num_pairs):
585
584
586 #-------------------------------------------
585 #-------------------------------------------
587
586
588 cspower = numpy.abs(jcspectra[ip,mask_prof,:])
587 cspower = numpy.abs(jcspectra[ip,mask_prof,:])
589 cspower = cspower[:,hei_interf]
588 cspower = cspower[:,hei_interf]
590 cspower = cspower.sum(axis = 0)
589 cspower = cspower.sum(axis = 0)
591
590
592 cspsort = cspower.ravel().argsort()
591 cspsort = cspower.ravel().argsort()
593 junkcspc_interf = jcspectra[ip,:,hei_interf[cspsort[range(offhei_interf, nhei_interf + offhei_interf)]]]
592 junkcspc_interf = jcspectra[ip,:,hei_interf[cspsort[range(offhei_interf, nhei_interf + offhei_interf)]]]
594 junkcspc_interf = junkcspc_interf.transpose()
593 junkcspc_interf = junkcspc_interf.transpose()
595 jcspc_interf = junkcspc_interf.sum(axis = 1)/nhei_interf
594 jcspc_interf = junkcspc_interf.sum(axis = 1)/nhei_interf
596
595
597 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
596 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
598
597
599 median_real = numpy.median(numpy.real(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:]))
598 median_real = numpy.median(numpy.real(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:]))
600 median_imag = numpy.median(numpy.imag(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:]))
599 median_imag = numpy.median(numpy.imag(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:]))
601 junkcspc_interf[comp_mask_prof,:] = numpy.complex(median_real, median_imag)
600 junkcspc_interf[comp_mask_prof,:] = numpy.complex(median_real, median_imag)
602
601
603 for iprof in range(num_prof):
602 for iprof in range(num_prof):
604 ind = numpy.abs(junkcspc_interf[iprof,:]).ravel().argsort()
603 ind = numpy.abs(junkcspc_interf[iprof,:]).ravel().argsort()
605 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf/2]]
604 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf/2]]
606
605
607 #Removiendo la Interferencia
606 #Removiendo la Interferencia
608 jcspectra[ip,:,ind_hei] = jcspectra[ip,:,ind_hei] - jcspc_interf
607 jcspectra[ip,:,ind_hei] = jcspectra[ip,:,ind_hei] - jcspc_interf
609
608
610 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
609 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
611 maxid = ListAux.index(max(ListAux))
610 maxid = ListAux.index(max(ListAux))
612
611
613 ind = numpy.array([-2,-1,1,2])
612 ind = numpy.array([-2,-1,1,2])
614 xx = numpy.zeros([4,4])
613 xx = numpy.zeros([4,4])
615
614
616 for id1 in range(4):
615 for id1 in range(4):
617 xx[:,id1] = ind[id1]**numpy.asarray(range(4))
616 xx[:,id1] = ind[id1]**numpy.asarray(range(4))
618
617
619 xx_inv = numpy.linalg.inv(xx)
618 xx_inv = numpy.linalg.inv(xx)
620 xx = xx_inv[:,0]
619 xx = xx_inv[:,0]
621
620
622 ind = (ind + maxid + num_mask_prof)%num_mask_prof
621 ind = (ind + maxid + num_mask_prof)%num_mask_prof
623 yy = jcspectra[ip,mask_prof[ind],:]
622 yy = jcspectra[ip,mask_prof[ind],:]
624 jcspectra[ip,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx)
623 jcspectra[ip,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx)
625
624
626 #Guardar Resultados
625 #Guardar Resultados
627 self.dataOut.data_spc = jspectra
626 self.dataOut.data_spc = jspectra
628 self.dataOut.data_cspc = jcspectra
627 self.dataOut.data_cspc = jcspectra
629
628
630 return 1
629 return 1
631
630
632 def setRadarFrequency(self, frequency=None):
631 def setRadarFrequency(self, frequency=None):
633
632
634 if frequency != None:
633 if frequency != None:
635 self.dataOut.frequency = frequency
634 self.dataOut.frequency = frequency
636
635
637 return 1
636 return 1
638
637
639 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
638 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
640 #validacion de rango
639 #validacion de rango
641 if minHei == None:
640 if minHei == None:
642 minHei = self.dataOut.heightList[0]
641 minHei = self.dataOut.heightList[0]
643
642
644 if maxHei == None:
643 if maxHei == None:
645 maxHei = self.dataOut.heightList[-1]
644 maxHei = self.dataOut.heightList[-1]
646
645
647 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
646 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
648 print 'minHei: %.2f is out of the heights range'%(minHei)
647 print 'minHei: %.2f is out of the heights range'%(minHei)
649 print 'minHei is setting to %.2f'%(self.dataOut.heightList[0])
648 print 'minHei is setting to %.2f'%(self.dataOut.heightList[0])
650 minHei = self.dataOut.heightList[0]
649 minHei = self.dataOut.heightList[0]
651
650
652 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
651 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
653 print 'maxHei: %.2f is out of the heights range'%(maxHei)
652 print 'maxHei: %.2f is out of the heights range'%(maxHei)
654 print 'maxHei is setting to %.2f'%(self.dataOut.heightList[-1])
653 print 'maxHei is setting to %.2f'%(self.dataOut.heightList[-1])
655 maxHei = self.dataOut.heightList[-1]
654 maxHei = self.dataOut.heightList[-1]
656
655
657 # validacion de velocidades
656 # validacion de velocidades
658 velrange = self.dataOut.getVelRange(1)
657 velrange = self.dataOut.getVelRange(1)
659
658
660 if minVel == None:
659 if minVel == None:
661 minVel = velrange[0]
660 minVel = velrange[0]
662
661
663 if maxVel == None:
662 if maxVel == None:
664 maxVel = velrange[-1]
663 maxVel = velrange[-1]
665
664
666 if (minVel < velrange[0]) or (minVel > maxVel):
665 if (minVel < velrange[0]) or (minVel > maxVel):
667 print 'minVel: %.2f is out of the velocity range'%(minVel)
666 print 'minVel: %.2f is out of the velocity range'%(minVel)
668 print 'minVel is setting to %.2f'%(velrange[0])
667 print 'minVel is setting to %.2f'%(velrange[0])
669 minVel = velrange[0]
668 minVel = velrange[0]
670
669
671 if (maxVel > velrange[-1]) or (maxVel < minVel):
670 if (maxVel > velrange[-1]) or (maxVel < minVel):
672 print 'maxVel: %.2f is out of the velocity range'%(maxVel)
671 print 'maxVel: %.2f is out of the velocity range'%(maxVel)
673 print 'maxVel is setting to %.2f'%(velrange[-1])
672 print 'maxVel is setting to %.2f'%(velrange[-1])
674 maxVel = velrange[-1]
673 maxVel = velrange[-1]
675
674
676 # seleccion de indices para rango
675 # seleccion de indices para rango
677 minIndex = 0
676 minIndex = 0
678 maxIndex = 0
677 maxIndex = 0
679 heights = self.dataOut.heightList
678 heights = self.dataOut.heightList
680
679
681 inda = numpy.where(heights >= minHei)
680 inda = numpy.where(heights >= minHei)
682 indb = numpy.where(heights <= maxHei)
681 indb = numpy.where(heights <= maxHei)
683
682
684 try:
683 try:
685 minIndex = inda[0][0]
684 minIndex = inda[0][0]
686 except:
685 except:
687 minIndex = 0
686 minIndex = 0
688
687
689 try:
688 try:
690 maxIndex = indb[0][-1]
689 maxIndex = indb[0][-1]
691 except:
690 except:
692 maxIndex = len(heights)
691 maxIndex = len(heights)
693
692
694 if (minIndex < 0) or (minIndex > maxIndex):
693 if (minIndex < 0) or (minIndex > maxIndex):
695 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
694 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
696
695
697 if (maxIndex >= self.dataOut.nHeights):
696 if (maxIndex >= self.dataOut.nHeights):
698 maxIndex = self.dataOut.nHeights-1
697 maxIndex = self.dataOut.nHeights-1
699
698
700 # seleccion de indices para velocidades
699 # seleccion de indices para velocidades
701 indminvel = numpy.where(velrange >= minVel)
700 indminvel = numpy.where(velrange >= minVel)
702 indmaxvel = numpy.where(velrange <= maxVel)
701 indmaxvel = numpy.where(velrange <= maxVel)
703 try:
702 try:
704 minIndexVel = indminvel[0][0]
703 minIndexVel = indminvel[0][0]
705 except:
704 except:
706 minIndexVel = 0
705 minIndexVel = 0
707
706
708 try:
707 try:
709 maxIndexVel = indmaxvel[0][-1]
708 maxIndexVel = indmaxvel[0][-1]
710 except:
709 except:
711 maxIndexVel = len(velrange)
710 maxIndexVel = len(velrange)
712
711
713 #seleccion del espectro
712 #seleccion del espectro
714 data_spc = self.dataOut.data_spc[:,minIndexVel:maxIndexVel+1,minIndex:maxIndex+1]
713 data_spc = self.dataOut.data_spc[:,minIndexVel:maxIndexVel+1,minIndex:maxIndex+1]
715 #estimacion de ruido
714 #estimacion de ruido
716 noise = numpy.zeros(self.dataOut.nChannels)
715 noise = numpy.zeros(self.dataOut.nChannels)
717
716
718 for channel in range(self.dataOut.nChannels):
717 for channel in range(self.dataOut.nChannels):
719 daux = data_spc[channel,:,:]
718 daux = data_spc[channel,:,:]
720 noise[channel] = hildebrand_sekhon(daux, self.dataOut.nIncohInt)
719 noise[channel] = hildebrand_sekhon(daux, self.dataOut.nIncohInt)
721
720
722 self.dataOut.noise_estimation = noise.copy()
721 self.dataOut.noise_estimation = noise.copy()
723
722
724 return 1
723 return 1
725
724
726 class IncohInt(Operation):
725 class IncohInt(Operation):
727
726
728
727
729 __profIndex = 0
728 __profIndex = 0
730 __withOverapping = False
729 __withOverapping = False
731
730
732 __byTime = False
731 __byTime = False
733 __initime = None
732 __initime = None
734 __lastdatatime = None
733 __lastdatatime = None
735 __integrationtime = None
734 __integrationtime = None
736
735
737 __buffer_spc = None
736 __buffer_spc = None
738 __buffer_cspc = None
737 __buffer_cspc = None
739 __buffer_dc = None
738 __buffer_dc = None
740
739
741 __dataReady = False
740 __dataReady = False
742
741
743 __timeInterval = None
742 __timeInterval = None
744
743
745 n = None
744 n = None
746
745
747
746
748
747
749 def __init__(self, **kwargs):
748 def __init__(self, **kwargs):
750
749
751 Operation.__init__(self, **kwargs)
750 Operation.__init__(self, **kwargs)
752 # self.isConfig = False
751 # self.isConfig = False
753
752
754 def setup(self, n=None, timeInterval=None, overlapping=False):
753 def setup(self, n=None, timeInterval=None, overlapping=False):
755 """
754 """
756 Set the parameters of the integration class.
755 Set the parameters of the integration class.
757
756
758 Inputs:
757 Inputs:
759
758
760 n : Number of coherent integrations
759 n : Number of coherent integrations
761 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
760 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
762 overlapping :
761 overlapping :
763
762
764 """
763 """
765
764
766 self.__initime = None
765 self.__initime = None
767 self.__lastdatatime = 0
766 self.__lastdatatime = 0
768
767
769 self.__buffer_spc = 0
768 self.__buffer_spc = 0
770 self.__buffer_cspc = 0
769 self.__buffer_cspc = 0
771 self.__buffer_dc = 0
770 self.__buffer_dc = 0
772
771
773 self.__profIndex = 0
772 self.__profIndex = 0
774 self.__dataReady = False
773 self.__dataReady = False
775 self.__byTime = False
774 self.__byTime = False
776
775
777 if n is None and timeInterval is None:
776 if n is None and timeInterval is None:
778 raise ValueError, "n or timeInterval should be specified ..."
777 raise ValueError, "n or timeInterval should be specified ..."
779
778
780 if n is not None:
779 if n is not None:
781 self.n = int(n)
780 self.n = int(n)
782 else:
781 else:
783 self.__integrationtime = int(timeInterval) #if (type(timeInterval)!=integer) -> change this line
782 self.__integrationtime = int(timeInterval) #if (type(timeInterval)!=integer) -> change this line
784 self.n = None
783 self.n = None
785 self.__byTime = True
784 self.__byTime = True
786
785
787 def putData(self, data_spc, data_cspc, data_dc):
786 def putData(self, data_spc, data_cspc, data_dc):
788
787
789 """
788 """
790 Add a profile to the __buffer_spc and increase in one the __profileIndex
789 Add a profile to the __buffer_spc and increase in one the __profileIndex
791
790
792 """
791 """
793
792
794 self.__buffer_spc += data_spc
793 self.__buffer_spc += data_spc
795
794
796 if data_cspc is None:
795 if data_cspc is None:
797 self.__buffer_cspc = None
796 self.__buffer_cspc = None
798 else:
797 else:
799 self.__buffer_cspc += data_cspc
798 self.__buffer_cspc += data_cspc
800
799
801 if data_dc is None:
800 if data_dc is None:
802 self.__buffer_dc = None
801 self.__buffer_dc = None
803 else:
802 else:
804 self.__buffer_dc += data_dc
803 self.__buffer_dc += data_dc
805
804
806 self.__profIndex += 1
805 self.__profIndex += 1
807
806
808 return
807 return
809
808
810 def pushData(self):
809 def pushData(self):
811 """
810 """
812 Return the sum of the last profiles and the profiles used in the sum.
811 Return the sum of the last profiles and the profiles used in the sum.
813
812
814 Affected:
813 Affected:
815
814
816 self.__profileIndex
815 self.__profileIndex
817
816
818 """
817 """
819
818
820 data_spc = self.__buffer_spc
819 data_spc = self.__buffer_spc
821 data_cspc = self.__buffer_cspc
820 data_cspc = self.__buffer_cspc
822 data_dc = self.__buffer_dc
821 data_dc = self.__buffer_dc
823 n = self.__profIndex
822 n = self.__profIndex
824
823
825 self.__buffer_spc = 0
824 self.__buffer_spc = 0
826 self.__buffer_cspc = 0
825 self.__buffer_cspc = 0
827 self.__buffer_dc = 0
826 self.__buffer_dc = 0
828 self.__profIndex = 0
827 self.__profIndex = 0
829
828
830 return data_spc, data_cspc, data_dc, n
829 return data_spc, data_cspc, data_dc, n
831
830
832 def byProfiles(self, *args):
831 def byProfiles(self, *args):
833
832
834 self.__dataReady = False
833 self.__dataReady = False
835 avgdata_spc = None
834 avgdata_spc = None
836 avgdata_cspc = None
835 avgdata_cspc = None
837 avgdata_dc = None
836 avgdata_dc = None
838
837
839 self.putData(*args)
838 self.putData(*args)
840
839
841 if self.__profIndex == self.n:
840 if self.__profIndex == self.n:
842
841
843 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
842 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
844 self.n = n
843 self.n = n
845 self.__dataReady = True
844 self.__dataReady = True
846
845
847 return avgdata_spc, avgdata_cspc, avgdata_dc
846 return avgdata_spc, avgdata_cspc, avgdata_dc
848
847
849 def byTime(self, datatime, *args):
848 def byTime(self, datatime, *args):
850
849
851 self.__dataReady = False
850 self.__dataReady = False
852 avgdata_spc = None
851 avgdata_spc = None
853 avgdata_cspc = None
852 avgdata_cspc = None
854 avgdata_dc = None
853 avgdata_dc = None
855
854
856 self.putData(*args)
855 self.putData(*args)
857
856
858 if (datatime - self.__initime) >= self.__integrationtime:
857 if (datatime - self.__initime) >= self.__integrationtime:
859 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
858 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
860 self.n = n
859 self.n = n
861 self.__dataReady = True
860 self.__dataReady = True
862
861
863 return avgdata_spc, avgdata_cspc, avgdata_dc
862 return avgdata_spc, avgdata_cspc, avgdata_dc
864
863
865 def integrate(self, datatime, *args):
864 def integrate(self, datatime, *args):
866
865
867 if self.__profIndex == 0:
866 if self.__profIndex == 0:
868 self.__initime = datatime
867 self.__initime = datatime
869
868
870 if self.__byTime:
869 if self.__byTime:
871 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
870 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
872 else:
871 else:
873 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
872 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
874
873
875 if not self.__dataReady:
874 if not self.__dataReady:
876 return None, None, None, None
875 return None, None, None, None
877
876
878 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
877 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
879
878
880 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
879 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
881
880
882 if n==1:
881 if n==1:
883 return
882 return
884
883
885 dataOut.flagNoData = True
884 dataOut.flagNoData = True
886
885
887 if not self.isConfig:
886 if not self.isConfig:
888 self.setup(n, timeInterval, overlapping)
887 self.setup(n, timeInterval, overlapping)
889 self.isConfig = True
888 self.isConfig = True
890
889
891 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
890 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
892 dataOut.data_spc,
891 dataOut.data_spc,
893 dataOut.data_cspc,
892 dataOut.data_cspc,
894 dataOut.data_dc)
893 dataOut.data_dc)
895
894
896 if self.__dataReady:
895 if self.__dataReady:
897
896
898 dataOut.data_spc = avgdata_spc
897 dataOut.data_spc = avgdata_spc
899 dataOut.data_cspc = avgdata_cspc
898 dataOut.data_cspc = avgdata_cspc
900 dataOut.data_dc = avgdata_dc
899 dataOut.data_dc = avgdata_dc
901
900
902 dataOut.nIncohInt *= self.n
901 dataOut.nIncohInt *= self.n
903 dataOut.utctime = avgdatatime
902 dataOut.utctime = avgdatatime
904 dataOut.flagNoData = False
903 dataOut.flagNoData = False
@@ -1,501 +1,604
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
19
19 MAXNUMX = 100
20 MAXNUMX = 100
20 MAXNUMY = 100
21 MAXNUMY = 100
21
22
22 class PrettyFloat(float):
23 class PrettyFloat(float):
23 def __repr__(self):
24 def __repr__(self):
24 return '%.2f' % self
25 return '%.2f' % self
25
26
26 def roundFloats(obj):
27 def roundFloats(obj):
27 if isinstance(obj, list):
28 if isinstance(obj, list):
28 return map(roundFloats, obj)
29 return map(roundFloats, obj)
29 elif isinstance(obj, float):
30 elif isinstance(obj, float):
30 return round(obj, 2)
31 return round(obj, 2)
31
32
32 def decimate(z, MAXNUMY):
33 def decimate(z, MAXNUMY):
33 # dx = int(len(self.x)/self.__MAXNUMX) + 1
34
35 dy = int(len(z[0])/MAXNUMY) + 1
34 dy = int(len(z[0])/MAXNUMY) + 1
36
35
37 return z[::, ::dy]
36 return z[::, ::dy]
38
37
39 class throttle(object):
38 class throttle(object):
40 """Decorator that prevents a function from being called more than once every
39 '''
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):
76 '''
77 Object to hold data to be plotted
78 '''
79
80 def __init__(self, plottypes, throttle_value):
81 self.plottypes = plottypes
82 self.throttle = throttle_value
83 self.ended = False
84 self.__times = []
85
86 def __str__(self):
87 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
88 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
89
90 def __len__(self):
91 return len(self.__times)
92
93 def __getitem__(self, key):
94 if key not in self.data:
95 raise KeyError(log.error('Missing key: {}'.format(key)))
96
97 if 'spc' in key:
98 ret = self.data[key]
99 else:
100 ret = numpy.array([self.data[key][x] for x in self.times])
101 if ret.ndim > 1:
102 ret = numpy.swapaxes(ret, 0, 1)
103 return ret
104
105 def setup(self):
106 '''
107 Configure object
108 '''
109
110 self.ended = False
111 self.data = {}
112 self.__times = []
113 self.__heights = []
114 self.__all_heights = set()
115 for plot in self.plottypes:
116 self.data[plot] = {}
117
118 def shape(self, key):
119 '''
120 Get the shape of the one-element data for the given key
121 '''
122
123 if len(self.data[key]):
124 if 'spc' in key:
125 return self.data[key].shape
126 return self.data[key][self.__times[0]].shape
127 return (0,)
128
129 def update(self, dataOut):
130 '''
131 Update data object with new dataOut
132 '''
133
134 tm = dataOut.utctime
135 if tm in self.__times:
136 return
137
138 self.parameters = getattr(dataOut, 'parameters', [])
139 self.pairs = dataOut.pairsList
140 self.channels = dataOut.channelList
141 self.xrange = (dataOut.getFreqRange(1)/1000. , dataOut.getAcfRange(1) , dataOut.getVelRange(1))
142 self.interval = dataOut.getTimeInterval()
143 self.__heights.append(dataOut.heightList)
144 self.__all_heights.update(dataOut.heightList)
145 self.__times.append(tm)
146
147 for plot in self.plottypes:
148 if plot == 'spc':
149 z = dataOut.data_spc/dataOut.normFactor
150 self.data[plot] = 10*numpy.log10(z)
151 if plot == 'cspc':
152 self.data[plot] = dataOut.data_cspc
153 if plot == 'noise':
154 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
155 if plot == 'rti':
156 self.data[plot][tm] = dataOut.getPower()
157 if plot == 'snr_db':
158 self.data['snr'][tm] = dataOut.data_SNR
159 if plot == 'snr':
160 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
161 if plot == 'dop':
162 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
163 if plot == 'mean':
164 self.data[plot][tm] = dataOut.data_MEAN
165 if plot == 'std':
166 self.data[plot][tm] = dataOut.data_STD
167 if plot == 'coh':
168 self.data[plot][tm] = dataOut.getCoherence()
169 if plot == 'phase':
170 self.data[plot][tm] = dataOut.getCoherence(phase=True)
171 if plot == 'output':
172 self.data[plot][tm] = dataOut.data_output
173 if plot == 'param':
174 self.data[plot][tm] = dataOut.data_param
175
176 def normalize_heights(self):
177 '''
178 Ensure same-dimension of the data for different heighList
179 '''
180
181 H = numpy.array(list(self.__all_heights))
182 H.sort()
183 for key in self.data:
184 shape = self.shape(key)[:-1] + H.shape
185 for tm, obj in self.data[key].items():
186 h = self.__heights[self.__times.index(tm)]
187 if H.size == h.size:
188 continue
189 index = numpy.where(numpy.in1d(H, h))[0]
190 dummy = numpy.zeros(shape) + numpy.nan
191 if len(shape) == 2:
192 dummy[:, index] = obj
193 else:
194 dummy[index] = obj
195 self.data[key][tm] = dummy
196
197 self.__heights = [H for tm in self.__times]
198
199 def jsonify(self, decimate=False):
200 '''
201 Convert data to json
202 '''
203
204 ret = {}
205 tm = self.times[-1]
206
207 for key, value in self.data:
208 if key in ('spc', 'cspc'):
209 ret[key] = roundFloats(self.data[key].to_list())
210 else:
211 ret[key] = roundFloats(self.data[key][tm].to_list())
212
213 ret['timestamp'] = tm
214 ret['interval'] = self.interval
215
216 @property
217 def times(self):
218 '''
219 Return the list of times of the current data
220 '''
221
222 ret = numpy.array(self.__times)
223 ret.sort()
224 return ret
225
226 @property
227 def heights(self):
228 '''
229 Return the list of heights of the current data
230 '''
231
232 return numpy.array(self.__heights[-1])
75
233
76 class PublishData(Operation):
234 class PublishData(Operation):
77 """Clase publish."""
235 '''
236 Operation to send data over zmq.
237 '''
78
238
79 def __init__(self, **kwargs):
239 def __init__(self, **kwargs):
80 """Inicio."""
240 """Inicio."""
81 Operation.__init__(self, **kwargs)
241 Operation.__init__(self, **kwargs)
82 self.isConfig = False
242 self.isConfig = False
83 self.client = None
243 self.client = None
84 self.zeromq = None
244 self.zeromq = None
85 self.mqtt = None
245 self.mqtt = None
86
246
87 def on_disconnect(self, client, userdata, rc):
247 def on_disconnect(self, client, userdata, rc):
88 if rc != 0:
248 if rc != 0:
89 print("Unexpected disconnection.")
249 log.warning('Unexpected disconnection.')
90 self.connect()
250 self.connect()
91
251
92 def connect(self):
252 def connect(self):
93 print 'trying to connect'
253 log.warning('trying to connect')
94 try:
254 try:
95 self.client.connect(
255 self.client.connect(
96 host=self.host,
256 host=self.host,
97 port=self.port,
257 port=self.port,
98 keepalive=60*10,
258 keepalive=60*10,
99 bind_address='')
259 bind_address='')
100 self.client.loop_start()
260 self.client.loop_start()
101 # self.client.publish(
261 # self.client.publish(
102 # self.topic + 'SETUP',
262 # self.topic + 'SETUP',
103 # json.dumps(setup),
263 # json.dumps(setup),
104 # retain=True
264 # retain=True
105 # )
265 # )
106 except:
266 except:
107 print "MQTT Conection error."
267 log.error('MQTT Conection error.')
108 self.client = False
268 self.client = False
109
269
110 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
270 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
111 self.counter = 0
271 self.counter = 0
112 self.topic = kwargs.get('topic', 'schain')
272 self.topic = kwargs.get('topic', 'schain')
113 self.delay = kwargs.get('delay', 0)
273 self.delay = kwargs.get('delay', 0)
114 self.plottype = kwargs.get('plottype', 'spectra')
274 self.plottype = kwargs.get('plottype', 'spectra')
115 self.host = kwargs.get('host', "10.10.10.82")
275 self.host = kwargs.get('host', "10.10.10.82")
116 self.port = kwargs.get('port', 3000)
276 self.port = kwargs.get('port', 3000)
117 self.clientId = clientId
277 self.clientId = clientId
118 self.cnt = 0
278 self.cnt = 0
119 self.zeromq = zeromq
279 self.zeromq = zeromq
120 self.mqtt = kwargs.get('plottype', 0)
280 self.mqtt = kwargs.get('plottype', 0)
121 self.client = None
281 self.client = None
122 self.verbose = verbose
282 self.verbose = verbose
123 self.dataOut.firstdata = True
124 setup = []
283 setup = []
125 if mqtt is 1:
284 if mqtt is 1:
126 self.client = mqtt.Client(
285 self.client = mqtt.Client(
127 client_id=self.clientId + self.topic + 'SCHAIN',
286 client_id=self.clientId + self.topic + 'SCHAIN',
128 clean_session=True)
287 clean_session=True)
129 self.client.on_disconnect = self.on_disconnect
288 self.client.on_disconnect = self.on_disconnect
130 self.connect()
289 self.connect()
131 for plot in self.plottype:
290 for plot in self.plottype:
132 setup.append({
291 setup.append({
133 'plot': plot,
292 'plot': plot,
134 'topic': self.topic + plot,
293 'topic': self.topic + plot,
135 'title': getattr(self, plot + '_' + 'title', False),
294 'title': getattr(self, plot + '_' + 'title', False),
136 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
295 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
137 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
296 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
138 'xrange': getattr(self, plot + '_' + 'xrange', False),
297 'xrange': getattr(self, plot + '_' + 'xrange', False),
139 'yrange': getattr(self, plot + '_' + 'yrange', False),
298 'yrange': getattr(self, plot + '_' + 'yrange', False),
140 'zrange': getattr(self, plot + '_' + 'zrange', False),
299 'zrange': getattr(self, plot + '_' + 'zrange', False),
141 })
300 })
142 if zeromq is 1:
301 if zeromq is 1:
143 context = zmq.Context()
302 context = zmq.Context()
144 self.zmq_socket = context.socket(zmq.PUSH)
303 self.zmq_socket = context.socket(zmq.PUSH)
145 server = kwargs.get('server', 'zmq.pipe')
304 server = kwargs.get('server', 'zmq.pipe')
146
305
147 if 'tcp://' in server:
306 if 'tcp://' in server:
148 address = server
307 address = server
149 else:
308 else:
150 address = 'ipc:///tmp/%s' % server
309 address = 'ipc:///tmp/%s' % server
151
310
152 self.zmq_socket.connect(address)
311 self.zmq_socket.connect(address)
153 time.sleep(1)
312 time.sleep(1)
154
313
155
314
156 def publish_data(self):
315 def publish_data(self):
157 self.dataOut.finished = False
316 self.dataOut.finished = False
158 if self.mqtt is 1:
317 if self.mqtt is 1:
159 yData = self.dataOut.heightList[:2].tolist()
318 yData = self.dataOut.heightList[:2].tolist()
160 if self.plottype == 'spectra':
319 if self.plottype == 'spectra':
161 data = getattr(self.dataOut, 'data_spc')
320 data = getattr(self.dataOut, 'data_spc')
162 z = data/self.dataOut.normFactor
321 z = data/self.dataOut.normFactor
163 zdB = 10*numpy.log10(z)
322 zdB = 10*numpy.log10(z)
164 xlen, ylen = zdB[0].shape
323 xlen, ylen = zdB[0].shape
165 dx = int(xlen/MAXNUMX) + 1
324 dx = int(xlen/MAXNUMX) + 1
166 dy = int(ylen/MAXNUMY) + 1
325 dy = int(ylen/MAXNUMY) + 1
167 Z = [0 for i in self.dataOut.channelList]
326 Z = [0 for i in self.dataOut.channelList]
168 for i in self.dataOut.channelList:
327 for i in self.dataOut.channelList:
169 Z[i] = zdB[i][::dx, ::dy].tolist()
328 Z[i] = zdB[i][::dx, ::dy].tolist()
170 payload = {
329 payload = {
171 'timestamp': self.dataOut.utctime,
330 'timestamp': self.dataOut.utctime,
172 'data': roundFloats(Z),
331 'data': roundFloats(Z),
173 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
332 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
174 'interval': self.dataOut.getTimeInterval(),
333 'interval': self.dataOut.getTimeInterval(),
175 'type': self.plottype,
334 'type': self.plottype,
176 'yData': yData
335 'yData': yData
177 }
336 }
178 # print payload
179
337
180 elif self.plottype in ('rti', 'power'):
338 elif self.plottype in ('rti', 'power'):
181 data = getattr(self.dataOut, 'data_spc')
339 data = getattr(self.dataOut, 'data_spc')
182 z = data/self.dataOut.normFactor
340 z = data/self.dataOut.normFactor
183 avg = numpy.average(z, axis=1)
341 avg = numpy.average(z, axis=1)
184 avgdB = 10*numpy.log10(avg)
342 avgdB = 10*numpy.log10(avg)
185 xlen, ylen = z[0].shape
343 xlen, ylen = z[0].shape
186 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
344 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
187 AVG = [0 for i in self.dataOut.channelList]
345 AVG = [0 for i in self.dataOut.channelList]
188 for i in self.dataOut.channelList:
346 for i in self.dataOut.channelList:
189 AVG[i] = avgdB[i][::dy].tolist()
347 AVG[i] = avgdB[i][::dy].tolist()
190 payload = {
348 payload = {
191 'timestamp': self.dataOut.utctime,
349 'timestamp': self.dataOut.utctime,
192 'data': roundFloats(AVG),
350 'data': roundFloats(AVG),
193 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
351 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
194 'interval': self.dataOut.getTimeInterval(),
352 'interval': self.dataOut.getTimeInterval(),
195 'type': self.plottype,
353 'type': self.plottype,
196 'yData': yData
354 'yData': yData
197 }
355 }
198 elif self.plottype == 'noise':
356 elif self.plottype == 'noise':
199 noise = self.dataOut.getNoise()/self.dataOut.normFactor
357 noise = self.dataOut.getNoise()/self.dataOut.normFactor
200 noisedB = 10*numpy.log10(noise)
358 noisedB = 10*numpy.log10(noise)
201 payload = {
359 payload = {
202 'timestamp': self.dataOut.utctime,
360 'timestamp': self.dataOut.utctime,
203 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
361 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
204 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
362 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
205 'interval': self.dataOut.getTimeInterval(),
363 'interval': self.dataOut.getTimeInterval(),
206 'type': self.plottype,
364 'type': self.plottype,
207 'yData': yData
365 'yData': yData
208 }
366 }
209 elif self.plottype == 'snr':
367 elif self.plottype == 'snr':
210 data = getattr(self.dataOut, 'data_SNR')
368 data = getattr(self.dataOut, 'data_SNR')
211 avgdB = 10*numpy.log10(data)
369 avgdB = 10*numpy.log10(data)
212
370
213 ylen = data[0].size
371 ylen = data[0].size
214 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
372 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
215 AVG = [0 for i in self.dataOut.channelList]
373 AVG = [0 for i in self.dataOut.channelList]
216 for i in self.dataOut.channelList:
374 for i in self.dataOut.channelList:
217 AVG[i] = avgdB[i][::dy].tolist()
375 AVG[i] = avgdB[i][::dy].tolist()
218 payload = {
376 payload = {
219 'timestamp': self.dataOut.utctime,
377 'timestamp': self.dataOut.utctime,
220 'data': roundFloats(AVG),
378 'data': roundFloats(AVG),
221 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
379 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
222 'type': self.plottype,
380 'type': self.plottype,
223 'yData': yData
381 'yData': yData
224 }
382 }
225 else:
383 else:
226 print "Tipo de grafico invalido"
384 print "Tipo de grafico invalido"
227 payload = {
385 payload = {
228 'data': 'None',
386 'data': 'None',
229 'timestamp': 'None',
387 'timestamp': 'None',
230 'type': None
388 'type': None
231 }
389 }
232 # print 'Publishing data to {}'.format(self.host)
390
233 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
391 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
234
392
235 if self.zeromq is 1:
393 if self.zeromq is 1:
236 if self.verbose:
394 if self.verbose:
237 print '[Sending] {} - {}'.format(self.dataOut.type, self.dataOut.datatime)
395 log.log(
396 '{} - {}'.format(self.dataOut.type, self.dataOut.datatime),
397 'Sending'
398 )
238 self.zmq_socket.send_pyobj(self.dataOut)
399 self.zmq_socket.send_pyobj(self.dataOut)
239 self.dataOut.firstdata = False
240
241
400
242 def run(self, dataOut, **kwargs):
401 def run(self, dataOut, **kwargs):
243 self.dataOut = dataOut
402 self.dataOut = dataOut
244 if not self.isConfig:
403 if not self.isConfig:
245 self.setup(**kwargs)
404 self.setup(**kwargs)
246 self.isConfig = True
405 self.isConfig = True
247
406
248 self.publish_data()
407 self.publish_data()
249 time.sleep(self.delay)
408 time.sleep(self.delay)
250
409
251 def close(self):
410 def close(self):
252 if self.zeromq is 1:
411 if self.zeromq is 1:
253 self.dataOut.finished = True
412 self.dataOut.finished = True
254 self.zmq_socket.send_pyobj(self.dataOut)
413 self.zmq_socket.send_pyobj(self.dataOut)
414 time.sleep(0.1)
255 self.zmq_socket.close()
415 self.zmq_socket.close()
256 if self.client:
416 if self.client:
257 self.client.loop_stop()
417 self.client.loop_stop()
258 self.client.disconnect()
418 self.client.disconnect()
259
419
260
420
261 class ReceiverData(ProcessingUnit):
421 class ReceiverData(ProcessingUnit):
262
422
263 def __init__(self, **kwargs):
423 def __init__(self, **kwargs):
264
424
265 ProcessingUnit.__init__(self, **kwargs)
425 ProcessingUnit.__init__(self, **kwargs)
266
426
267 self.isConfig = False
427 self.isConfig = False
268 server = kwargs.get('server', 'zmq.pipe')
428 server = kwargs.get('server', 'zmq.pipe')
269 if 'tcp://' in server:
429 if 'tcp://' in server:
270 address = server
430 address = server
271 else:
431 else:
272 address = 'ipc:///tmp/%s' % server
432 address = 'ipc:///tmp/%s' % server
273
433
274 self.address = address
434 self.address = address
275 self.dataOut = JROData()
435 self.dataOut = JROData()
276
436
277 def setup(self):
437 def setup(self):
278
438
279 self.context = zmq.Context()
439 self.context = zmq.Context()
280 self.receiver = self.context.socket(zmq.PULL)
440 self.receiver = self.context.socket(zmq.PULL)
281 self.receiver.bind(self.address)
441 self.receiver.bind(self.address)
282 time.sleep(0.5)
442 time.sleep(0.5)
283 print '[Starting] ReceiverData from {}'.format(self.address)
443 log.success('ReceiverData from {}'.format(self.address))
284
444
285
445
286 def run(self):
446 def run(self):
287
447
288 if not self.isConfig:
448 if not self.isConfig:
289 self.setup()
449 self.setup()
290 self.isConfig = True
450 self.isConfig = True
291
451
292 self.dataOut = self.receiver.recv_pyobj()
452 self.dataOut = self.receiver.recv_pyobj()
293 print '[Receiving] {} - {}'.format(self.dataOut.type,
453 log.log('{} - {}'.format(self.dataOut.type,
294 self.dataOut.datatime.ctime())
454 self.dataOut.datatime.ctime(),),
455 'Receiving')
295
456
296
457
297 class PlotterReceiver(ProcessingUnit, Process):
458 class PlotterReceiver(ProcessingUnit, Process):
298
459
299 throttle_value = 5
460 throttle_value = 5
300
461
301 def __init__(self, **kwargs):
462 def __init__(self, **kwargs):
302
463
303 ProcessingUnit.__init__(self, **kwargs)
464 ProcessingUnit.__init__(self, **kwargs)
304 Process.__init__(self)
465 Process.__init__(self)
305 self.mp = False
466 self.mp = False
306 self.isConfig = False
467 self.isConfig = False
307 self.isWebConfig = False
468 self.isWebConfig = False
308 self.plottypes = []
309 self.connections = 0
469 self.connections = 0
310 server = kwargs.get('server', 'zmq.pipe')
470 server = kwargs.get('server', 'zmq.pipe')
311 plot_server = kwargs.get('plot_server', 'zmq.web')
471 plot_server = kwargs.get('plot_server', 'zmq.web')
312 if 'tcp://' in server:
472 if 'tcp://' in server:
313 address = server
473 address = server
314 else:
474 else:
315 address = 'ipc:///tmp/%s' % server
475 address = 'ipc:///tmp/%s' % server
316
476
317 if 'tcp://' in plot_server:
477 if 'tcp://' in plot_server:
318 plot_address = plot_server
478 plot_address = plot_server
319 else:
479 else:
320 plot_address = 'ipc:///tmp/%s' % plot_server
480 plot_address = 'ipc:///tmp/%s' % plot_server
321
481
322 self.address = address
482 self.address = address
323 self.plot_address = plot_address
483 self.plot_address = plot_address
324 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
484 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
325 self.realtime = kwargs.get('realtime', False)
485 self.realtime = kwargs.get('realtime', False)
326 self.throttle_value = kwargs.get('throttle', 5)
486 self.throttle_value = kwargs.get('throttle', 5)
327 self.sendData = self.initThrottle(self.throttle_value)
487 self.sendData = self.initThrottle(self.throttle_value)
488 self.dates = []
328 self.setup()
489 self.setup()
329
490
330 def setup(self):
491 def setup(self):
331
492
332 self.data = {}
493 self.data = Data(self.plottypes, self.throttle_value)
333 self.data['times'] = []
334 for plottype in self.plottypes:
335 self.data[plottype] = {}
336 self.data['noise'] = {}
337 self.data['throttle'] = self.throttle_value
338 self.data['ENDED'] = False
339 self.isConfig = True
494 self.isConfig = True
340 self.data_web = {}
341
495
342 def event_monitor(self, monitor):
496 def event_monitor(self, monitor):
343
497
344 events = {}
498 events = {}
345
499
346 for name in dir(zmq):
500 for name in dir(zmq):
347 if name.startswith('EVENT_'):
501 if name.startswith('EVENT_'):
348 value = getattr(zmq, name)
502 value = getattr(zmq, name)
349 events[value] = name
503 events[value] = name
350
504
351 while monitor.poll():
505 while monitor.poll():
352 evt = recv_monitor_message(monitor)
506 evt = recv_monitor_message(monitor)
353 if evt['event'] == 32:
507 if evt['event'] == 32:
354 self.connections += 1
508 self.connections += 1
355 if evt['event'] == 512:
509 if evt['event'] == 512:
356 pass
510 pass
357 if self.connections == 0 and self.started is True:
358 self.ended = True
359
511
360 evt.update({'description': events[evt['event']]})
512 evt.update({'description': events[evt['event']]})
361
513
362 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
514 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
363 break
515 break
364 monitor.close()
516 monitor.close()
365 print("event monitor thread done!")
517 print('event monitor thread done!')
366
518
367 def initThrottle(self, throttle_value):
519 def initThrottle(self, throttle_value):
368
520
369 @throttle(seconds=throttle_value)
521 @throttle(seconds=throttle_value)
370 def sendDataThrottled(fn_sender, data):
522 def sendDataThrottled(fn_sender, data):
371 fn_sender(data)
523 fn_sender(data)
372
524
373 return sendDataThrottled
525 return sendDataThrottled
374
526
375
376 def send(self, data):
527 def send(self, data):
377 # print '[sending] data=%s size=%s' % (data.keys(), len(data['times']))
528 log.success('Sending {}'.format(data), self.name)
378 self.sender.send_pyobj(data)
529 self.sender.send_pyobj(data)
379
530
380
381 def update(self):
382 t = self.dataOut.utctime
383
384 if t in self.data['times']:
385 return
386
387 self.data['times'].append(t)
388 self.data['dataOut'] = self.dataOut
389
390 for plottype in self.plottypes:
391 if plottype == 'spc':
392 z = self.dataOut.data_spc/self.dataOut.normFactor
393 self.data[plottype] = 10*numpy.log10(z)
394 self.data['noise'][t] = 10*numpy.log10(self.dataOut.getNoise()/self.dataOut.normFactor)
395 if plottype == 'cspc':
396 jcoherence = self.dataOut.data_cspc/numpy.sqrt(self.dataOut.data_spc*self.dataOut.data_spc)
397 self.data['cspc_coh'] = numpy.abs(jcoherence)
398 self.data['cspc_phase'] = numpy.arctan2(jcoherence.imag, jcoherence.real)*180/numpy.pi
399 if plottype == 'rti':
400 self.data[plottype][t] = self.dataOut.getPower()
401 if plottype == 'snr':
402 self.data[plottype][t] = 10*numpy.log10(self.dataOut.data_SNR)
403 if plottype == 'dop':
404 self.data[plottype][t] = 10*numpy.log10(self.dataOut.data_DOP)
405 if plottype == 'mean':
406 self.data[plottype][t] = self.dataOut.data_MEAN
407 if plottype == 'std':
408 self.data[plottype][t] = self.dataOut.data_STD
409 if plottype == 'coh':
410 self.data[plottype][t] = self.dataOut.getCoherence()
411 if plottype == 'phase':
412 self.data[plottype][t] = self.dataOut.getCoherence(phase=True)
413 if plottype == 'output':
414 self.data[plottype][t] = self.dataOut.data_output
415 if plottype == 'param':
416 self.data[plottype][t] = self.dataOut.data_param
417 if self.realtime:
418 self.data_web['timestamp'] = t
419 if plottype == 'spc':
420 self.data_web[plottype] = roundFloats(decimate(self.data[plottype]).tolist())
421 elif plottype == 'cspc':
422 self.data_web['cspc_coh'] = roundFloats(decimate(self.data['cspc_coh']).tolist())
423 self.data_web['cspc_phase'] = roundFloats(decimate(self.data['cspc_phase']).tolist())
424 elif plottype == 'noise':
425 self.data_web['noise'] = roundFloats(self.data['noise'][t].tolist())
426 else:
427 self.data_web[plottype] = roundFloats(decimate(self.data[plottype][t]).tolist())
428 self.data_web['interval'] = self.dataOut.getTimeInterval()
429 self.data_web['type'] = plottype
430
431 def run(self):
531 def run(self):
432
532
433 print '[Starting] {} from {}'.format(self.name, self.address)
533 log.success(
534 'Starting from {}'.format(self.address),
535 self.name
536 )
434
537
435 self.context = zmq.Context()
538 self.context = zmq.Context()
436 self.receiver = self.context.socket(zmq.PULL)
539 self.receiver = self.context.socket(zmq.PULL)
437 self.receiver.bind(self.address)
540 self.receiver.bind(self.address)
438 monitor = self.receiver.get_monitor_socket()
541 monitor = self.receiver.get_monitor_socket()
439 self.sender = self.context.socket(zmq.PUB)
542 self.sender = self.context.socket(zmq.PUB)
440 if self.realtime:
543 if self.realtime:
441 self.sender_web = self.context.socket(zmq.PUB)
544 self.sender_web = self.context.socket(zmq.PUB)
442 self.sender_web.connect(self.plot_address)
545 self.sender_web.connect(self.plot_address)
443 time.sleep(1)
546 time.sleep(1)
444
547
445 if 'server' in self.kwargs:
548 if 'server' in self.kwargs:
446 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
549 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
447 else:
550 else:
448 self.sender.bind("ipc:///tmp/zmq.plots")
551 self.sender.bind("ipc:///tmp/zmq.plots")
449
552
450 time.sleep(3)
553 time.sleep(2)
451
554
452 t = Thread(target=self.event_monitor, args=(monitor,))
555 t = Thread(target=self.event_monitor, args=(monitor,))
453 t.start()
556 t.start()
454
557
455 while True:
558 while True:
456 self.dataOut = self.receiver.recv_pyobj()
559 dataOut = self.receiver.recv_pyobj()
457 # print '[Receiving] {} - {}'.format(self.dataOut.type,
560 dt = datetime.datetime.fromtimestamp(dataOut.utctime).date()
458 # self.dataOut.datatime.ctime())
561 sended = False
459
562 if dt not in self.dates:
460 self.update()
563 if self.data:
564 self.data.ended = True
565 self.send(self.data)
566 sended = True
567 self.data.setup()
568 self.dates.append(dt)
461
569
462 if self.dataOut.firstdata is True:
570 self.data.update(dataOut)
463 self.data['STARTED'] = True
464
571
465 if self.dataOut.finished is True:
572 if dataOut.finished is True:
466 self.send(self.data)
467 self.connections -= 1
573 self.connections -= 1
468 if self.connections == 0 and self.started:
574 if self.connections == 0 and dt in self.dates:
469 self.ended = True
575 self.data.ended = True
470 self.data['ENDED'] = True
471 self.send(self.data)
576 self.send(self.data)
472 self.setup()
577 self.data.setup()
473 self.started = False
474 else:
578 else:
475 if self.realtime:
579 if self.realtime:
476 self.send(self.data)
580 self.send(self.data)
477 self.sender_web.send_string(json.dumps(self.data_web))
581 # self.sender_web.send_string(self.data.jsonify())
478 else:
582 else:
583 if not sended:
479 self.sendData(self.send, self.data)
584 self.sendData(self.send, self.data)
480 self.started = True
481
585
482 self.data['STARTED'] = False
483 return
586 return
484
587
485 def sendToWeb(self):
588 def sendToWeb(self):
486
589
487 if not self.isWebConfig:
590 if not self.isWebConfig:
488 context = zmq.Context()
591 context = zmq.Context()
489 sender_web_config = context.socket(zmq.PUB)
592 sender_web_config = context.socket(zmq.PUB)
490 if 'tcp://' in self.plot_address:
593 if 'tcp://' in self.plot_address:
491 dum, address, port = self.plot_address.split(':')
594 dum, address, port = self.plot_address.split(':')
492 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
595 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
493 else:
596 else:
494 conf_address = self.plot_address + '.config'
597 conf_address = self.plot_address + '.config'
495 sender_web_config.bind(conf_address)
598 sender_web_config.bind(conf_address)
496 time.sleep(1)
599 time.sleep(1)
497 for kwargs in self.operationKwargs.values():
600 for kwargs in self.operationKwargs.values():
498 if 'plot' in kwargs:
601 if 'plot' in kwargs:
499 print '[Sending] Config data to web for {}'.format(kwargs['code'].upper())
602 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
500 sender_web_config.send_string(json.dumps(kwargs))
603 sender_web_config.send_string(json.dumps(kwargs))
501 self.isWebConfig = True No newline at end of file
604 self.isWebConfig = True
General Comments 0
You need to be logged in to leave comments. Login now