##// END OF EJS Templates
New RHI Plot and Block 360 stores more parameters
rflores -
r1442:f9eef645eb53
parent child
Show More

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

@@ -1,707 +1,714
1 1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 2 # All rights reserved.
3 3 #
4 4 # Distributed under the terms of the BSD 3-clause license.
5 5 """Base class to create plot operations
6 6
7 7 """
8 8
9 9 import os
10 10 import sys
11 11 import zmq
12 12 import time
13 13 import numpy
14 14 import datetime
15 15 from collections import deque
16 16 from functools import wraps
17 17 from threading import Thread
18 18 import matplotlib
19 19
20 20 if 'BACKEND' in os.environ:
21 21 matplotlib.use(os.environ['BACKEND'])
22 22 elif 'linux' in sys.platform:
23 23 matplotlib.use("TkAgg")
24 24 elif 'darwin' in sys.platform:
25 25 matplotlib.use('MacOSX')
26 26 else:
27 27 from schainpy.utils import log
28 28 log.warning('Using default Backend="Agg"', 'INFO')
29 29 matplotlib.use('Agg')
30 30
31 31 import matplotlib.pyplot as plt
32 32 from matplotlib.patches import Polygon
33 33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35 35
36 36 from schainpy.model.data.jrodata import PlotterData
37 37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 38 from schainpy.utils import log
39 39
40 40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 41 blu_values = matplotlib.pyplot.get_cmap(
42 42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 44 'jro', numpy.vstack((blu_values, jet_values)))
45 45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46 46
47 47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49 49
50 50 EARTH_RADIUS = 6.3710e3
51 51
52 52 def ll2xy(lat1, lon1, lat2, lon2):
53 53
54 54 p = 0.017453292519943295
55 55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 60 theta = -theta + numpy.pi/2
61 61 return r*numpy.cos(theta), r*numpy.sin(theta)
62 62
63 63
64 64 def km2deg(km):
65 65 '''
66 66 Convert distance in km to degrees
67 67 '''
68 68
69 69 return numpy.rad2deg(km/EARTH_RADIUS)
70 70
71 71
72 72 def figpause(interval):
73 73 backend = plt.rcParams['backend']
74 74 if backend in matplotlib.rcsetup.interactive_bk:
75 75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 76 if figManager is not None:
77 77 canvas = figManager.canvas
78 78 if canvas.figure.stale:
79 79 canvas.draw()
80 80 try:
81 81 canvas.start_event_loop(interval)
82 82 except:
83 83 pass
84 84 return
85 85
86 86 def popup(message):
87 87 '''
88 88 '''
89 89
90 90 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 91 text = '\n'.join([s.strip() for s in message.split(':')])
92 92 fig.text(0.01, 0.5, text, ha='left', va='center',
93 93 size='20', weight='heavy', color='w')
94 94 fig.show()
95 95 figpause(1000)
96 96
97 97
98 98 class Throttle(object):
99 99 '''
100 100 Decorator that prevents a function from being called more than once every
101 101 time period.
102 102 To create a function that cannot be called more than once a minute, but
103 103 will sleep until it can be called:
104 104 @Throttle(minutes=1)
105 105 def foo():
106 106 pass
107 107
108 108 for i in range(10):
109 109 foo()
110 110 print "This function has run %s times." % i
111 111 '''
112 112
113 113 def __init__(self, seconds=0, minutes=0, hours=0):
114 114 self.throttle_period = datetime.timedelta(
115 115 seconds=seconds, minutes=minutes, hours=hours
116 116 )
117 117
118 118 self.time_of_last_call = datetime.datetime.min
119 119
120 120 def __call__(self, fn):
121 121 @wraps(fn)
122 122 def wrapper(*args, **kwargs):
123 123 coerce = kwargs.pop('coerce', None)
124 124 if coerce:
125 125 self.time_of_last_call = datetime.datetime.now()
126 126 return fn(*args, **kwargs)
127 127 else:
128 128 now = datetime.datetime.now()
129 129 time_since_last_call = now - self.time_of_last_call
130 130 time_left = self.throttle_period - time_since_last_call
131 131
132 132 if time_left > datetime.timedelta(seconds=0):
133 133 return
134 134
135 135 self.time_of_last_call = datetime.datetime.now()
136 136 return fn(*args, **kwargs)
137 137
138 138 return wrapper
139 139
140 140 def apply_throttle(value):
141 141
142 142 @Throttle(seconds=value)
143 143 def fnThrottled(fn):
144 144 fn()
145 145
146 146 return fnThrottled
147 147
148 148
149 149 @MPDecorator
150 150 class Plot(Operation):
151 151 """Base class for Schain plotting operations
152 152
153 153 This class should never be use directtly you must subclass a new operation,
154 154 children classes must be defined as follow:
155 155
156 156 ExamplePlot(Plot):
157 157
158 158 CODE = 'code'
159 159 colormap = 'jet'
160 160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161 161
162 162 def setup(self):
163 163 pass
164 164
165 165 def plot(self):
166 166 pass
167 167
168 168 """
169 169
170 170 CODE = 'Figure'
171 171 colormap = 'jet'
172 172 bgcolor = 'white'
173 173 buffering = True
174 174 __missing = 1E30
175 175
176 176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 177 'showprofile']
178 178
179 179 def __init__(self):
180 180
181 181 Operation.__init__(self)
182 182 self.isConfig = False
183 183 self.isPlotConfig = False
184 184 self.save_time = 0
185 185 self.sender_time = 0
186 186 self.data = None
187 187 self.firsttime = True
188 188 self.sender_queue = deque(maxlen=10)
189 189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190 190
191 191 def __fmtTime(self, x, pos):
192 192 '''
193 193 '''
194 194
195 195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196 196
197 197 def __setup(self, **kwargs):
198 198 '''
199 199 Initialize variables
200 200 '''
201 201
202 202 self.figures = []
203 203 self.axes = []
204 204 self.cb_axes = []
205 205 self.localtime = kwargs.pop('localtime', True)
206 206 self.show = kwargs.get('show', True)
207 207 self.save = kwargs.get('save', False)
208 208 self.save_period = kwargs.get('save_period', 0)
209 209 self.colormap = kwargs.get('colormap', self.colormap)
210 210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
211 211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
212 212 self.colormaps = kwargs.get('colormaps', None)
213 213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
214 214 self.showprofile = kwargs.get('showprofile', False)
215 215 self.title = kwargs.get('wintitle', self.CODE.upper())
216 216 self.cb_label = kwargs.get('cb_label', None)
217 217 self.cb_labels = kwargs.get('cb_labels', None)
218 218 self.labels = kwargs.get('labels', None)
219 219 self.xaxis = kwargs.get('xaxis', 'frequency')
220 220 self.zmin = kwargs.get('zmin', None)
221 221 self.zmax = kwargs.get('zmax', None)
222 222 self.zlimits = kwargs.get('zlimits', None)
223 223 self.xmin = kwargs.get('xmin', None)
224 224 self.xmax = kwargs.get('xmax', None)
225 225 self.xrange = kwargs.get('xrange', 12)
226 226 self.xscale = kwargs.get('xscale', None)
227 227 self.ymin = kwargs.get('ymin', None)
228 228 self.ymax = kwargs.get('ymax', None)
229 229 self.yscale = kwargs.get('yscale', None)
230 230 self.xlabel = kwargs.get('xlabel', None)
231 231 self.attr_time = kwargs.get('attr_time', 'utctime')
232 232 self.attr_data = kwargs.get('attr_data', 'data_param')
233 233 self.decimation = kwargs.get('decimation', None)
234 234 self.oneFigure = kwargs.get('oneFigure', True)
235 235 self.width = kwargs.get('width', None)
236 236 self.height = kwargs.get('height', None)
237 237 self.colorbar = kwargs.get('colorbar', True)
238 238 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
239 239 self.channels = kwargs.get('channels', None)
240 240 self.titles = kwargs.get('titles', [])
241 241 self.polar = False
242 242 self.type = kwargs.get('type', 'iq')
243 243 self.grid = kwargs.get('grid', False)
244 244 self.pause = kwargs.get('pause', False)
245 245 self.save_code = kwargs.get('save_code', self.CODE)
246 246 self.throttle = kwargs.get('throttle', 0)
247 247 self.exp_code = kwargs.get('exp_code', None)
248 248 self.server = kwargs.get('server', False)
249 249 self.sender_period = kwargs.get('sender_period', 60)
250 250 self.tag = kwargs.get('tag', '')
251 251 self.height_index = kwargs.get('height_index', None)
252 252 self.__throttle_plot = apply_throttle(self.throttle)
253 253 code = self.attr_data if self.attr_data else self.CODE
254 254 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
255 255 self.ang_min = kwargs.get('ang_min', None)
256 256 self.ang_max = kwargs.get('ang_max', None)
257 self.mode = kwargs.get('mode', None)
257 258
258 259
259 260 if self.server:
260 261 if not self.server.startswith('tcp://'):
261 262 self.server = 'tcp://{}'.format(self.server)
262 263 log.success(
263 264 'Sending to server: {}'.format(self.server),
264 265 self.name
265 266 )
266 267
267 268 if isinstance(self.attr_data, str):
268 269 self.attr_data = [self.attr_data]
269 270
270 271 def __setup_plot(self):
271 272 '''
272 273 Common setup for all figures, here figures and axes are created
273 274 '''
274 275
275 276 self.setup()
276 277
277 278 self.time_label = 'LT' if self.localtime else 'UTC'
278 279
279 280 if self.width is None:
280 281 self.width = 8
281 282
282 283 self.figures = []
283 284 self.axes = []
284 285 self.cb_axes = []
285 286 self.pf_axes = []
286 287 self.cmaps = []
287 288
288 289 size = '15%' if self.ncols == 1 else '30%'
289 290 pad = '4%' if self.ncols == 1 else '8%'
290 291
291 292 if self.oneFigure:
292 293 if self.height is None:
293 294 self.height = 1.4 * self.nrows + 1
294 295 fig = plt.figure(figsize=(self.width, self.height),
295 296 edgecolor='k',
296 297 facecolor='w')
297 298 self.figures.append(fig)
298 299 for n in range(self.nplots):
299 300 ax = fig.add_subplot(self.nrows, self.ncols,
300 301 n + 1, polar=self.polar)
301 302 ax.tick_params(labelsize=8)
302 303 ax.firsttime = True
303 304 ax.index = 0
304 305 ax.press = None
305 306 self.axes.append(ax)
306 307 if self.showprofile:
307 308 cax = self.__add_axes(ax, size=size, pad=pad)
308 309 cax.tick_params(labelsize=8)
309 310 self.pf_axes.append(cax)
310 311 else:
311 312 if self.height is None:
312 313 self.height = 3
313 314 for n in range(self.nplots):
314 315 fig = plt.figure(figsize=(self.width, self.height),
315 316 edgecolor='k',
316 317 facecolor='w')
317 318 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
318 319 ax.tick_params(labelsize=8)
319 320 ax.firsttime = True
320 321 ax.index = 0
321 322 ax.press = None
322 323 self.figures.append(fig)
323 324 self.axes.append(ax)
324 325 if self.showprofile:
325 326 cax = self.__add_axes(ax, size=size, pad=pad)
326 327 cax.tick_params(labelsize=8)
327 328 self.pf_axes.append(cax)
328 329
329 330 for n in range(self.nrows):
330 331 if self.colormaps is not None:
331 332 cmap = plt.get_cmap(self.colormaps[n])
332 333 else:
333 334 cmap = plt.get_cmap(self.colormap)
334 335 cmap.set_bad(self.bgcolor, 1.)
335 336 self.cmaps.append(cmap)
336 337
337 338 def __add_axes(self, ax, size='30%', pad='8%'):
338 339 '''
339 340 Add new axes to the given figure
340 341 '''
341 342 divider = make_axes_locatable(ax)
342 343 nax = divider.new_horizontal(size=size, pad=pad)
343 344 ax.figure.add_axes(nax)
344 345 return nax
345 346
346 347 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
347 348 '''
348 349 Create a masked array for missing data
349 350 '''
350 351 if x_buffer.shape[0] < 2:
351 352 return x_buffer, y_buffer, z_buffer
352 353
353 354 deltas = x_buffer[1:] - x_buffer[0:-1]
354 355 x_median = numpy.median(deltas)
355 356
356 357 index = numpy.where(deltas > 5 * x_median)
357 358
358 359 if len(index[0]) != 0:
359 360 z_buffer[::, index[0], ::] = self.__missing
360 361 z_buffer = numpy.ma.masked_inside(z_buffer,
361 362 0.99 * self.__missing,
362 363 1.01 * self.__missing)
363 364
364 365 return x_buffer, y_buffer, z_buffer
365 366
366 367 def decimate(self):
367 368
368 369 # dx = int(len(self.x)/self.__MAXNUMX) + 1
369 370 dy = int(len(self.y) / self.decimation) + 1
370 371
371 372 # x = self.x[::dx]
372 373 x = self.x
373 374 y = self.y[::dy]
374 375 z = self.z[::, ::, ::dy]
375 376
376 377 return x, y, z
377 378
378 379 def format(self):
379 380 '''
380 381 Set min and max values, labels, ticks and titles
381 382 '''
382 383
383 384 for n, ax in enumerate(self.axes):
384 385 if ax.firsttime:
385 386 if self.xaxis != 'time':
386 387 xmin = self.xmin
387 388 xmax = self.xmax
388 389 else:
389 390 xmin = self.tmin
390 391 xmax = self.tmin + self.xrange*60*60
391 392 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
392 393 ax.xaxis.set_major_locator(LinearLocator(9))
393 394 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
394 395 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
395 396 ax.set_facecolor(self.bgcolor)
396 397 if self.xscale:
397 398 ax.xaxis.set_major_formatter(FuncFormatter(
398 399 lambda x, pos: '{0:g}'.format(x*self.xscale)))
399 400 if self.yscale:
400 401 ax.yaxis.set_major_formatter(FuncFormatter(
401 402 lambda x, pos: '{0:g}'.format(x*self.yscale)))
402 403 if self.xlabel is not None:
403 404 ax.set_xlabel(self.xlabel)
404 405 if self.ylabel is not None:
405 406 ax.set_ylabel(self.ylabel)
406 407 if self.showprofile:
407 408 self.pf_axes[n].set_ylim(ymin, ymax)
408 409 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
409 410 self.pf_axes[n].set_xlabel('dB')
410 411 self.pf_axes[n].grid(b=True, axis='x')
411 412 [tick.set_visible(False)
412 413 for tick in self.pf_axes[n].get_yticklabels()]
413 414 if self.colorbar:
414 415 ax.cbar = plt.colorbar(
415 416 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
416 417 ax.cbar.ax.tick_params(labelsize=8)
417 418 ax.cbar.ax.press = None
418 419 if self.cb_label:
419 420 ax.cbar.set_label(self.cb_label, size=8)
420 421 elif self.cb_labels:
421 422 ax.cbar.set_label(self.cb_labels[n], size=8)
422 423 else:
423 424 ax.cbar = None
424 425 ax.set_xlim(xmin, xmax)
425 426 ax.set_ylim(ymin, ymax)
426 427 ax.firsttime = False
427 428 if self.grid:
428 429 ax.grid(True)
429 430 if not self.polar:
430 431 ax.set_title('{} {} {}'.format(
431 432 self.titles[n],
432 433 self.getDateTime(self.data.max_time).strftime(
433 434 '%Y-%m-%d %H:%M:%S'),
434 435 self.time_label),
435 436 size=8)
436 437 else:
437 ax.set_title('{}'.format(self.titles[n]), size=8)
438 ax.set_ylim(0, 90)
439 ax.set_yticks(numpy.arange(0, 90, 20))
438 #ax.set_title('{}'.format(self.titles[n]), size=8)
439 ax.set_title('{} {} {}'.format(
440 self.titles[n],
441 self.getDateTime(self.data.max_time).strftime(
442 '%Y-%m-%d %H:%M:%S'),
443 self.time_label),
444 size=8)
445 ax.set_ylim(0, self.ymax)
446 #ax.set_yticks(numpy.arange(0, self.ymax, 20))
440 447 ax.yaxis.labelpad = 40
441 448
442 449 if self.firsttime:
443 450 for n, fig in enumerate(self.figures):
444 451 fig.subplots_adjust(**self.plots_adjust)
445 452 self.firsttime = False
446 453
447 454 def clear_figures(self):
448 455 '''
449 456 Reset axes for redraw plots
450 457 '''
451 458
452 459 for ax in self.axes+self.pf_axes+self.cb_axes:
453 460 ax.clear()
454 461 ax.firsttime = True
455 462 if hasattr(ax, 'cbar') and ax.cbar:
456 463 ax.cbar.remove()
457 464
458 465 def __plot(self):
459 466 '''
460 467 Main function to plot, format and save figures
461 468 '''
462 469
463 470 self.plot()
464 471 self.format()
465 472
466 473 for n, fig in enumerate(self.figures):
467 474 if self.nrows == 0 or self.nplots == 0:
468 475 log.warning('No data', self.name)
469 476 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
470 477 fig.canvas.manager.set_window_title(self.CODE)
471 478 continue
472 479
473 480 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
474 481 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
475 482 fig.canvas.draw()
476 483 if self.show:
477 484 fig.show()
478 485 figpause(0.01)
479 486
480 487 if self.save:
481 488 self.save_figure(n)
482 489
483 490 if self.server:
484 491 self.send_to_server()
485 492
486 493 def __update(self, dataOut, timestamp):
487 494 '''
488 495 '''
489 496
490 497 metadata = {
491 498 'yrange': dataOut.heightList,
492 499 'interval': dataOut.timeInterval,
493 500 'channels': dataOut.channelList
494 501 }
495 502
496 503 data, meta = self.update(dataOut)
497 504 metadata.update(meta)
498 505 self.data.update(data, timestamp, metadata)
499 506
500 507 def save_figure(self, n):
501 508 '''
502 509 '''
503 510 if self.oneFigure:
504 511 if (self.data.max_time - self.save_time) <= self.save_period:
505 512 return
506 513
507 514 self.save_time = self.data.max_time
508 515
509 516 fig = self.figures[n]
510 517 if self.throttle == 0:
511 518 if self.oneFigure:
512 519 figname = os.path.join(
513 520 self.save,
514 521 self.save_code,
515 522 '{}_{}.png'.format(
516 523 self.save_code,
517 524 self.getDateTime(self.data.max_time).strftime(
518 525 '%Y%m%d_%H%M%S'
519 526 ),
520 527 )
521 528 )
522 529 else:
523 530 figname = os.path.join(
524 531 self.save,
525 532 self.save_code,
526 533 '{}_ch{}_{}.png'.format(
527 534 self.save_code,n,
528 535 self.getDateTime(self.data.max_time).strftime(
529 536 '%Y%m%d_%H%M%S'
530 537 ),
531 538 )
532 539 )
533 540 log.log('Saving figure: {}'.format(figname), self.name)
534 541 if not os.path.isdir(os.path.dirname(figname)):
535 542 os.makedirs(os.path.dirname(figname))
536 543 fig.savefig(figname)
537 544
538 545 figname = os.path.join(
539 546 self.save,
540 547 '{}_{}.png'.format(
541 548 self.save_code,
542 549 self.getDateTime(self.data.min_time).strftime(
543 550 '%Y%m%d'
544 551 ),
545 552 )
546 553 )
547 554
548 555 log.log('Saving figure: {}'.format(figname), self.name)
549 556 if not os.path.isdir(os.path.dirname(figname)):
550 557 os.makedirs(os.path.dirname(figname))
551 558 fig.savefig(figname)
552 559
553 560 def send_to_server(self):
554 561 '''
555 562 '''
556 563
557 564 if self.exp_code == None:
558 565 log.warning('Missing `exp_code` skipping sending to server...')
559 566
560 567 last_time = self.data.max_time
561 568 interval = last_time - self.sender_time
562 569 if interval < self.sender_period:
563 570 return
564 571
565 572 self.sender_time = last_time
566 573
567 574 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
568 575 for attr in attrs:
569 576 value = getattr(self, attr)
570 577 if value:
571 578 if isinstance(value, (numpy.float32, numpy.float64)):
572 579 value = round(float(value), 2)
573 580 self.data.meta[attr] = value
574 581 if self.colormap == 'jet':
575 582 self.data.meta['colormap'] = 'Jet'
576 583 elif 'RdBu' in self.colormap:
577 584 self.data.meta['colormap'] = 'RdBu'
578 585 else:
579 586 self.data.meta['colormap'] = 'Viridis'
580 587 self.data.meta['interval'] = int(interval)
581 588
582 589 self.sender_queue.append(last_time)
583 590
584 591 while True:
585 592 try:
586 593 tm = self.sender_queue.popleft()
587 594 except IndexError:
588 595 break
589 596 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
590 597 self.socket.send_string(msg)
591 598 socks = dict(self.poll.poll(2000))
592 599 if socks.get(self.socket) == zmq.POLLIN:
593 600 reply = self.socket.recv_string()
594 601 if reply == 'ok':
595 602 log.log("Response from server ok", self.name)
596 603 time.sleep(0.1)
597 604 continue
598 605 else:
599 606 log.warning(
600 607 "Malformed reply from server: {}".format(reply), self.name)
601 608 else:
602 609 log.warning(
603 610 "No response from server, retrying...", self.name)
604 611 self.sender_queue.appendleft(tm)
605 612 self.socket.setsockopt(zmq.LINGER, 0)
606 613 self.socket.close()
607 614 self.poll.unregister(self.socket)
608 615 self.socket = self.context.socket(zmq.REQ)
609 616 self.socket.connect(self.server)
610 617 self.poll.register(self.socket, zmq.POLLIN)
611 618 break
612 619
613 620 def setup(self):
614 621 '''
615 622 This method should be implemented in the child class, the following
616 623 attributes should be set:
617 624
618 625 self.nrows: number of rows
619 626 self.ncols: number of cols
620 627 self.nplots: number of plots (channels or pairs)
621 628 self.ylabel: label for Y axes
622 629 self.titles: list of axes title
623 630
624 631 '''
625 632 raise NotImplementedError
626 633
627 634 def plot(self):
628 635 '''
629 636 Must be defined in the child class, the actual plotting method
630 637 '''
631 638 raise NotImplementedError
632 639
633 640 def update(self, dataOut):
634 641 '''
635 642 Must be defined in the child class, update self.data with new data
636 643 '''
637 644
638 645 data = {
639 646 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
640 647 }
641 648 meta = {}
642 649
643 650 return data, meta
644 651
645 652 def run(self, dataOut, **kwargs):
646 653 '''
647 654 Main plotting routine
648 655 '''
649 656
650 657 if self.isConfig is False:
651 658 self.__setup(**kwargs)
652 659
653 660 if self.localtime:
654 661 self.getDateTime = datetime.datetime.fromtimestamp
655 662 else:
656 663 self.getDateTime = datetime.datetime.utcfromtimestamp
657 664
658 665 self.data.setup()
659 666 self.isConfig = True
660 667 if self.server:
661 668 self.context = zmq.Context()
662 669 self.socket = self.context.socket(zmq.REQ)
663 670 self.socket.connect(self.server)
664 671 self.poll = zmq.Poller()
665 672 self.poll.register(self.socket, zmq.POLLIN)
666 673
667 674 tm = getattr(dataOut, self.attr_time)
668 675
669 676 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
670 677 self.save_time = tm
671 678 self.__plot()
672 679 self.tmin += self.xrange*60*60
673 680 self.data.setup()
674 681 self.clear_figures()
675 682
676 683 self.__update(dataOut, tm)
677 684
678 685 if self.isPlotConfig is False:
679 686 self.__setup_plot()
680 687 self.isPlotConfig = True
681 688 if self.xaxis == 'time':
682 689 dt = self.getDateTime(tm)
683 690 if self.xmin is None:
684 691 self.tmin = tm
685 692 self.xmin = dt.hour
686 693 minutes = (self.xmin-int(self.xmin)) * 60
687 694 seconds = (minutes - int(minutes)) * 60
688 695 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
689 696 datetime.datetime(1970, 1, 1)).total_seconds()
690 697 if self.localtime:
691 698 self.tmin += time.timezone
692 699
693 700 if self.xmin is not None and self.xmax is not None:
694 701 self.xrange = self.xmax - self.xmin
695 702
696 703 if self.throttle == 0:
697 704 self.__plot()
698 705 else:
699 706 self.__throttle_plot(self.__plot)#, coerce=coerce)
700 707
701 708 def close(self):
702 709
703 710 if self.data and not self.data.flagNoData:
704 711 self.save_time = 0
705 712 self.__plot()
706 713 if self.data and not self.data.flagNoData and self.pause:
707 714 figpause(10)
@@ -1,2378 +1,2522
1 1 import os
2 2 import datetime
3 3 import numpy
4 4 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
5 5
6 6 from schainpy.model.graphics.jroplot_base import Plot, plt
7 7 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
8 8 from schainpy.utils import log
9 9 # libreria wradlib
10 10 import wradlib as wrl
11 11
12 12 EARTH_RADIUS = 6.3710e3
13 13
14 14
15 15 def ll2xy(lat1, lon1, lat2, lon2):
16 16
17 17 p = 0.017453292519943295
18 18 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
19 19 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
20 20 r = 12742 * numpy.arcsin(numpy.sqrt(a))
21 21 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
22 22 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
23 23 theta = -theta + numpy.pi/2
24 24 return r*numpy.cos(theta), r*numpy.sin(theta)
25 25
26 26
27 27 def km2deg(km):
28 28 '''
29 29 Convert distance in km to degrees
30 30 '''
31 31
32 32 return numpy.rad2deg(km/EARTH_RADIUS)
33 33
34 34
35 35
36 36 class SpectralMomentsPlot(SpectraPlot):
37 37 '''
38 38 Plot for Spectral Moments
39 39 '''
40 40 CODE = 'spc_moments'
41 41 # colormap = 'jet'
42 42 # plot_type = 'pcolor'
43 43
44 44 class DobleGaussianPlot(SpectraPlot):
45 45 '''
46 46 Plot for Double Gaussian Plot
47 47 '''
48 48 CODE = 'gaussian_fit'
49 49 # colormap = 'jet'
50 50 # plot_type = 'pcolor'
51 51
52 52 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
53 53 '''
54 54 Plot SpectraCut with Double Gaussian Fit
55 55 '''
56 56 CODE = 'cut_gaussian_fit'
57 57
58 58 class SnrPlot(RTIPlot):
59 59 '''
60 60 Plot for SNR Data
61 61 '''
62 62
63 63 CODE = 'snr'
64 64 colormap = 'jet'
65 65
66 66 def update(self, dataOut):
67 67
68 68 data = {
69 69 'snr': 10*numpy.log10(dataOut.data_snr)
70 70 }
71 71
72 72 return data, {}
73 73
74 74 class DopplerPlot(RTIPlot):
75 75 '''
76 76 Plot for DOPPLER Data (1st moment)
77 77 '''
78 78
79 79 CODE = 'dop'
80 80 colormap = 'jet'
81 81
82 82 def update(self, dataOut):
83 83
84 84 data = {
85 85 'dop': 10*numpy.log10(dataOut.data_dop)
86 86 }
87 87
88 88 return data, {}
89 89
90 90 class PowerPlot(RTIPlot):
91 91 '''
92 92 Plot for Power Data (0 moment)
93 93 '''
94 94
95 95 CODE = 'pow'
96 96 colormap = 'jet'
97 97
98 98 def update(self, dataOut):
99 99 data = {
100 100 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
101 101 }
102 102 return data, {}
103 103
104 104 class SpectralWidthPlot(RTIPlot):
105 105 '''
106 106 Plot for Spectral Width Data (2nd moment)
107 107 '''
108 108
109 109 CODE = 'width'
110 110 colormap = 'jet'
111 111
112 112 def update(self, dataOut):
113 113
114 114 data = {
115 115 'width': dataOut.data_width
116 116 }
117 117
118 118 return data, {}
119 119
120 120 class SkyMapPlot(Plot):
121 121 '''
122 122 Plot for meteors detection data
123 123 '''
124 124
125 125 CODE = 'param'
126 126
127 127 def setup(self):
128 128
129 129 self.ncols = 1
130 130 self.nrows = 1
131 131 self.width = 7.2
132 132 self.height = 7.2
133 133 self.nplots = 1
134 134 self.xlabel = 'Zonal Zenith Angle (deg)'
135 135 self.ylabel = 'Meridional Zenith Angle (deg)'
136 136 self.polar = True
137 137 self.ymin = -180
138 138 self.ymax = 180
139 139 self.colorbar = False
140 140
141 141 def plot(self):
142 142
143 143 arrayParameters = numpy.concatenate(self.data['param'])
144 144 error = arrayParameters[:, -1]
145 145 indValid = numpy.where(error == 0)[0]
146 146 finalMeteor = arrayParameters[indValid, :]
147 147 finalAzimuth = finalMeteor[:, 3]
148 148 finalZenith = finalMeteor[:, 4]
149 149
150 150 x = finalAzimuth * numpy.pi / 180
151 151 y = finalZenith
152 152
153 153 ax = self.axes[0]
154 154
155 155 if ax.firsttime:
156 156 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
157 157 else:
158 158 ax.plot.set_data(x, y)
159 159
160 160 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
161 161 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
162 162 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
163 163 dt2,
164 164 len(x))
165 165 self.titles[0] = title
166 166
167 167
168 168 class GenericRTIPlot(Plot):
169 169 '''
170 170 Plot for data_xxxx object
171 171 '''
172 172
173 173 CODE = 'param'
174 174 colormap = 'viridis'
175 175 plot_type = 'pcolorbuffer'
176 176
177 177 def setup(self):
178 178 self.xaxis = 'time'
179 179 self.ncols = 1
180 180 self.nrows = self.data.shape('param')[0]
181 181 self.nplots = self.nrows
182 182 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
183 183
184 184 if not self.xlabel:
185 185 self.xlabel = 'Time'
186 186
187 187 self.ylabel = 'Range [km]'
188 188 if not self.titles:
189 189 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
190 190
191 191 def update(self, dataOut):
192 192
193 193 data = {
194 194 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
195 195 }
196 196
197 197 meta = {}
198 198
199 199 return data, meta
200 200
201 201 def plot(self):
202 202 # self.data.normalize_heights()
203 203 self.x = self.data.times
204 204 self.y = self.data.yrange
205 205 self.z = self.data['param']
206 206 self.z = 10*numpy.log10(self.z)
207 207 self.z = numpy.ma.masked_invalid(self.z)
208 208
209 209 if self.decimation is None:
210 210 x, y, z = self.fill_gaps(self.x, self.y, self.z)
211 211 else:
212 212 x, y, z = self.fill_gaps(*self.decimate())
213 213
214 214 for n, ax in enumerate(self.axes):
215 215
216 216 self.zmax = self.zmax if self.zmax is not None else numpy.max(
217 217 self.z[n])
218 218 self.zmin = self.zmin if self.zmin is not None else numpy.min(
219 219 self.z[n])
220 220
221 221 if ax.firsttime:
222 222 if self.zlimits is not None:
223 223 self.zmin, self.zmax = self.zlimits[n]
224 224
225 225 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
226 226 vmin=self.zmin,
227 227 vmax=self.zmax,
228 228 cmap=self.cmaps[n]
229 229 )
230 230 else:
231 231 if self.zlimits is not None:
232 232 self.zmin, self.zmax = self.zlimits[n]
233 233 ax.collections.remove(ax.collections[0])
234 234 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
235 235 vmin=self.zmin,
236 236 vmax=self.zmax,
237 237 cmap=self.cmaps[n]
238 238 )
239 239
240 240
241 241 class PolarMapPlot(Plot):
242 242 '''
243 243 Plot for weather radar
244 244 '''
245 245
246 246 CODE = 'param'
247 247 colormap = 'seismic'
248 248
249 249 def setup(self):
250 250 self.ncols = 1
251 251 self.nrows = 1
252 252 self.width = 9
253 253 self.height = 8
254 254 self.mode = self.data.meta['mode']
255 255 if self.channels is not None:
256 256 self.nplots = len(self.channels)
257 257 self.nrows = len(self.channels)
258 258 else:
259 259 self.nplots = self.data.shape(self.CODE)[0]
260 260 self.nrows = self.nplots
261 261 self.channels = list(range(self.nplots))
262 262 if self.mode == 'E':
263 263 self.xlabel = 'Longitude'
264 264 self.ylabel = 'Latitude'
265 265 else:
266 266 self.xlabel = 'Range (km)'
267 267 self.ylabel = 'Height (km)'
268 268 self.bgcolor = 'white'
269 269 self.cb_labels = self.data.meta['units']
270 270 self.lat = self.data.meta['latitude']
271 271 self.lon = self.data.meta['longitude']
272 272 self.xmin, self.xmax = float(
273 273 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
274 274 self.ymin, self.ymax = float(
275 275 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
276 276 # self.polar = True
277 277
278 278 def plot(self):
279 279
280 280 for n, ax in enumerate(self.axes):
281 281 data = self.data['param'][self.channels[n]]
282 282
283 283 zeniths = numpy.linspace(
284 284 0, self.data.meta['max_range'], data.shape[1])
285 285 if self.mode == 'E':
286 286 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
287 287 r, theta = numpy.meshgrid(zeniths, azimuths)
288 288 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
289 289 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
290 290 x = km2deg(x) + self.lon
291 291 y = km2deg(y) + self.lat
292 292 else:
293 293 azimuths = numpy.radians(self.data.yrange)
294 294 r, theta = numpy.meshgrid(zeniths, azimuths)
295 295 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
296 296 self.y = zeniths
297 297
298 298 if ax.firsttime:
299 299 if self.zlimits is not None:
300 300 self.zmin, self.zmax = self.zlimits[n]
301 301 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
302 302 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
303 303 vmin=self.zmin,
304 304 vmax=self.zmax,
305 305 cmap=self.cmaps[n])
306 306 else:
307 307 if self.zlimits is not None:
308 308 self.zmin, self.zmax = self.zlimits[n]
309 309 ax.collections.remove(ax.collections[0])
310 310 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
311 311 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
312 312 vmin=self.zmin,
313 313 vmax=self.zmax,
314 314 cmap=self.cmaps[n])
315 315
316 316 if self.mode == 'A':
317 317 continue
318 318
319 319 # plot district names
320 320 f = open('/data/workspace/schain_scripts/distrito.csv')
321 321 for line in f:
322 322 label, lon, lat = [s.strip() for s in line.split(',') if s]
323 323 lat = float(lat)
324 324 lon = float(lon)
325 325 # ax.plot(lon, lat, '.b', ms=2)
326 326 ax.text(lon, lat, label.decode('utf8'), ha='center',
327 327 va='bottom', size='8', color='black')
328 328
329 329 # plot limites
330 330 limites = []
331 331 tmp = []
332 332 for line in open('/data/workspace/schain_scripts/lima.csv'):
333 333 if '#' in line:
334 334 if tmp:
335 335 limites.append(tmp)
336 336 tmp = []
337 337 continue
338 338 values = line.strip().split(',')
339 339 tmp.append((float(values[0]), float(values[1])))
340 340 for points in limites:
341 341 ax.add_patch(
342 342 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
343 343
344 344 # plot Cuencas
345 345 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
346 346 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
347 347 values = [line.strip().split(',') for line in f]
348 348 points = [(float(s[0]), float(s[1])) for s in values]
349 349 ax.add_patch(Polygon(points, ec='b', fc='none'))
350 350
351 351 # plot grid
352 352 for r in (15, 30, 45, 60):
353 353 ax.add_artist(plt.Circle((self.lon, self.lat),
354 354 km2deg(r), color='0.6', fill=False, lw=0.2))
355 355 ax.text(
356 356 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
357 357 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
358 358 '{}km'.format(r),
359 359 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
360 360
361 361 if self.mode == 'E':
362 362 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
363 363 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
364 364 else:
365 365 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
366 366 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
367 367
368 368 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
369 369 self.titles = ['{} {}'.format(
370 370 self.data.parameters[x], title) for x in self.channels]
371 371
372 372 class WeatherPlot(Plot):
373 373 CODE = 'weather'
374 374 plot_name = 'weather'
375 375 plot_type = 'ppistyle'
376 376 buffering = False
377 377
378 378 def setup(self):
379 379 self.ncols = 1
380 380 self.nrows = 1
381 381 self.width =8
382 382 self.height =8
383 383 self.nplots= 1
384 384 self.ylabel= 'Range [Km]'
385 385 self.titles= ['Weather']
386 386 self.colorbar=False
387 387 self.ini =0
388 388 self.len_azi =0
389 389 self.buffer_ini = None
390 390 self.buffer_azi = None
391 391 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
392 392 self.flag =0
393 393 self.indicador= 0
394 394 self.last_data_azi = None
395 395 self.val_mean = None
396 396
397 397 def update(self, dataOut):
398 398
399 399 data = {}
400 400 meta = {}
401 401 if hasattr(dataOut, 'dataPP_POWER'):
402 402 factor = 1
403 403 if hasattr(dataOut, 'nFFTPoints'):
404 404 factor = dataOut.normFactor
405 405 #print("DIME EL SHAPE PORFAVOR",dataOut.data_360.shape)
406 406 data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
407 407 data['azi'] = dataOut.data_azi
408 408 data['ele'] = dataOut.data_ele
409 409 return data, meta
410 410
411 411 def get2List(self,angulos):
412 412 list1=[]
413 413 list2=[]
414 414 for i in reversed(range(len(angulos))):
415 415 diff_ = angulos[i]-angulos[i-1]
416 416 if diff_ >1.5:
417 417 list1.append(i-1)
418 418 list2.append(diff_)
419 419 return list(reversed(list1)),list(reversed(list2))
420 420
421 421 def fixData360(self,list_,ang_):
422 422 if list_[0]==-1:
423 423 vec = numpy.where(ang_<ang_[0])
424 424 ang_[vec] = ang_[vec]+360
425 425 return ang_
426 426 return ang_
427 427
428 428 def fixData360HL(self,angulos):
429 429 vec = numpy.where(angulos>=360)
430 430 angulos[vec]=angulos[vec]-360
431 431 return angulos
432 432
433 433 def search_pos(self,pos,list_):
434 434 for i in range(len(list_)):
435 435 if pos == list_[i]:
436 436 return True,i
437 437 i=None
438 438 return False,i
439 439
440 440 def fixDataComp(self,ang_,list1_,list2_):
441 441 size = len(ang_)
442 442 size2 = 0
443 443 for i in range(len(list2_)):
444 444 size2=size2+round(list2_[i])-1
445 445 new_size= size+size2
446 446 ang_new = numpy.zeros(new_size)
447 447 ang_new2 = numpy.zeros(new_size)
448 448
449 449 tmp = 0
450 450 c = 0
451 451 for i in range(len(ang_)):
452 452 ang_new[tmp +c] = ang_[i]
453 453 ang_new2[tmp+c] = ang_[i]
454 454 condition , value = self.search_pos(i,list1_)
455 455 if condition:
456 456 pos = tmp + c + 1
457 457 for k in range(round(list2_[value])-1):
458 458 ang_new[pos+k] = ang_new[pos+k-1]+1
459 459 ang_new2[pos+k] = numpy.nan
460 460 tmp = pos +k
461 461 c = 0
462 462 c=c+1
463 463 return ang_new,ang_new2
464 464
465 465 def globalCheckPED(self,angulos):
466 466 l1,l2 = self.get2List(angulos)
467 467 if len(l1)>0:
468 468 angulos2 = self.fixData360(list_=l1,ang_=angulos)
469 469 l1,l2 = self.get2List(angulos2)
470 470
471 471 ang1_,ang2_ = self.fixDataComp(ang_=angulos2,list1_=l1,list2_=l2)
472 472 ang1_ = self.fixData360HL(ang1_)
473 473 ang2_ = self.fixData360HL(ang2_)
474 474 else:
475 475 ang1_= angulos
476 476 ang2_= angulos
477 477 return ang1_,ang2_
478 478
479 479 def analizeDATA(self,data_azi):
480 480 list1 = []
481 481 list2 = []
482 482 dat = data_azi
483 483 for i in reversed(range(1,len(dat))):
484 484 if dat[i]>dat[i-1]:
485 485 diff = int(dat[i])-int(dat[i-1])
486 486 else:
487 487 diff = 360+int(dat[i])-int(dat[i-1])
488 488 if diff > 1:
489 489 list1.append(i-1)
490 490 list2.append(diff-1)
491 491 return list1,list2
492 492
493 493 def fixDATANEW(self,data_azi,data_weather):
494 494 list1,list2 = self.analizeDATA(data_azi)
495 495 if len(list1)== 0:
496 496 return data_azi,data_weather
497 497 else:
498 498 resize = 0
499 499 for i in range(len(list2)):
500 500 resize= resize + list2[i]
501 501 new_data_azi = numpy.resize(data_azi,resize)
502 502 new_data_weather= numpy.resize(date_weather,resize)
503 503
504 504 for i in range(len(list2)):
505 505 j=0
506 506 position=list1[i]+1
507 507 for j in range(list2[i]):
508 508 new_data_azi[position+j]=new_data_azi[position+j-1]+1
509 509 return new_data_azi
510 510
511 511 def fixDATA(self,data_azi):
512 512 data=data_azi
513 513 for i in range(len(data)):
514 514 if numpy.isnan(data[i]):
515 515 data[i]=data[i-1]+1
516 516 return data
517 517
518 518 def replaceNAN(self,data_weather,data_azi,val):
519 519 data= data_azi
520 520 data_T= data_weather
521 521 if data.shape[0]> data_T.shape[0]:
522 522 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
523 523 c = 0
524 524 for i in range(len(data)):
525 525 if numpy.isnan(data[i]):
526 526 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
527 527 else:
528 528 data_N[i,:]=data_T[c,:]
529 529 c=c+1
530 530 return data_N
531 531 else:
532 532 for i in range(len(data)):
533 533 if numpy.isnan(data[i]):
534 534 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
535 535 return data_T
536 536
537 537 def const_ploteo(self,data_weather,data_azi,step,res):
538 538 if self.ini==0:
539 539 #-------
540 540 n = (360/res)-len(data_azi)
541 541 #--------------------- new -------------------------
542 542 data_azi_new ,data_azi_old= self.globalCheckPED(data_azi)
543 543 #------------------------
544 544 start = data_azi_new[-1] + res
545 545 end = data_azi_new[0] - res
546 546 #------ new
547 547 self.last_data_azi = end
548 548 if start>end:
549 549 end = end + 360
550 550 azi_vacia = numpy.linspace(start,end,int(n))
551 551 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
552 552 data_azi = numpy.hstack((data_azi_new,azi_vacia))
553 553 # RADAR
554 554 val_mean = numpy.mean(data_weather[:,-1])
555 555 self.val_mean = val_mean
556 556 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*val_mean
557 557 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
558 558 data_weather = numpy.vstack((data_weather,data_weather_cmp))
559 559 else:
560 560 # azimuth
561 561 flag=0
562 562 start_azi = self.res_azi[0]
563 563 #-----------new------------
564 564 data_azi ,data_azi_old= self.globalCheckPED(data_azi)
565 565 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
566 566 #--------------------------
567 567 start = data_azi[0]
568 568 end = data_azi[-1]
569 569 self.last_data_azi= end
570 570 if start< start_azi:
571 571 start = start +360
572 572 if end <start_azi:
573 573 end = end +360
574 574
575 575 pos_ini = int((start-start_azi)/res)
576 576 len_azi = len(data_azi)
577 577 if (360-pos_ini)<len_azi:
578 578 if pos_ini+1==360:
579 579 pos_ini=0
580 580 else:
581 581 flag=1
582 582 dif= 360-pos_ini
583 583 comp= len_azi-dif
584 584 #-----------------
585 585 if flag==0:
586 586 # AZIMUTH
587 587 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
588 588 # RADAR
589 589 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
590 590 else:
591 591 # AZIMUTH
592 592 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
593 593 self.res_azi[0:comp] = data_azi[dif:]
594 594 # RADAR
595 595 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
596 596 self.res_weather[0:comp,:] = data_weather[dif:,:]
597 597 flag=0
598 598 data_azi = self.res_azi
599 599 data_weather = self.res_weather
600 600
601 601 return data_weather,data_azi
602 602
603 603 def plot(self):
604 604 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
605 605 data = self.data[-1]
606 606 r = self.data.yrange
607 607 delta_height = r[1]-r[0]
608 608 r_mask = numpy.where(r>=0)[0]
609 609 r = numpy.arange(len(r_mask))*delta_height
610 610 self.y = 2*r
611 611 # RADAR
612 612 #data_weather = data['weather']
613 613 # PEDESTAL
614 614 #data_azi = data['azi']
615 615 res = 1
616 616 # STEP
617 617 step = (360/(res*data['weather'].shape[0]))
618 618
619 619 self.res_weather, self.res_azi = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_azi=data['azi'],step=step,res=res)
620 620 self.res_ele = numpy.mean(data['ele'])
621 621 ################# PLOTEO ###################
622 622 for i,ax in enumerate(self.axes):
623 623 if ax.firsttime:
624 624 plt.clf()
625 625 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=20, vmax=80)
626 626 else:
627 627 plt.clf()
628 628 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=20, vmax=80)
629 629 caax = cgax.parasites[0]
630 630 paax = cgax.parasites[1]
631 631 cbar = plt.gcf().colorbar(pm, pad=0.075)
632 632 caax.set_xlabel('x_range [km]')
633 633 caax.set_ylabel('y_range [km]')
634 634 plt.text(1.0, 1.05, 'Azimuth '+str(thisDatetime)+" Step "+str(self.ini)+ " Elev: "+str(round(self.res_ele,2)), transform=caax.transAxes, va='bottom',ha='right')
635 635
636 636 self.ini= self.ini+1
637 637
638 638
639 639 class WeatherRHIPlot(Plot):
640 640 CODE = 'weather'
641 641 plot_name = 'weather'
642 642 plot_type = 'rhistyle'
643 643 buffering = False
644 644 data_ele_tmp = None
645 645
646 646 def setup(self):
647 647 print("********************")
648 648 print("********************")
649 649 print("********************")
650 650 print("SETUP WEATHER PLOT")
651 651 self.ncols = 1
652 652 self.nrows = 1
653 653 self.nplots= 1
654 654 self.ylabel= 'Range [Km]'
655 655 self.titles= ['Weather']
656 656 if self.channels is not None:
657 657 self.nplots = len(self.channels)
658 658 self.nrows = len(self.channels)
659 659 else:
660 660 self.nplots = self.data.shape(self.CODE)[0]
661 661 self.nrows = self.nplots
662 662 self.channels = list(range(self.nplots))
663 663 print("channels",self.channels)
664 664 print("que saldra", self.data.shape(self.CODE)[0])
665 665 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
666 666 print("self.titles",self.titles)
667 667 self.colorbar=False
668 668 self.width =8
669 669 self.height =8
670 670 self.ini =0
671 671 self.len_azi =0
672 672 self.buffer_ini = None
673 673 self.buffer_ele = None
674 674 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
675 675 self.flag =0
676 676 self.indicador= 0
677 677 self.last_data_ele = None
678 678 self.val_mean = None
679 679
680 680 def update(self, dataOut):
681 681
682 682 data = {}
683 683 meta = {}
684 684 if hasattr(dataOut, 'dataPP_POWER'):
685 685 factor = 1
686 686 if hasattr(dataOut, 'nFFTPoints'):
687 687 factor = dataOut.normFactor
688 688 print("dataOut",dataOut.data_360.shape)
689 689 #
690 690 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
691 691 #
692 692 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
693 693 data['azi'] = dataOut.data_azi
694 694 data['ele'] = dataOut.data_ele
695 695 #print("UPDATE")
696 696 #print("data[weather]",data['weather'].shape)
697 697 #print("data[azi]",data['azi'])
698 698 return data, meta
699 699
700 700 def get2List(self,angulos):
701 701 list1=[]
702 702 list2=[]
703 703 for i in reversed(range(len(angulos))):
704 704 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
705 705 diff_ = angulos[i]-angulos[i-1]
706 706 if abs(diff_) >1.5:
707 707 list1.append(i-1)
708 708 list2.append(diff_)
709 709 return list(reversed(list1)),list(reversed(list2))
710 710
711 711 def fixData90(self,list_,ang_):
712 712 if list_[0]==-1:
713 713 vec = numpy.where(ang_<ang_[0])
714 714 ang_[vec] = ang_[vec]+90
715 715 return ang_
716 716 return ang_
717 717
718 718 def fixData90HL(self,angulos):
719 719 vec = numpy.where(angulos>=90)
720 720 angulos[vec]=angulos[vec]-90
721 721 return angulos
722 722
723 723
724 724 def search_pos(self,pos,list_):
725 725 for i in range(len(list_)):
726 726 if pos == list_[i]:
727 727 return True,i
728 728 i=None
729 729 return False,i
730 730
731 731 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
732 732 size = len(ang_)
733 733 size2 = 0
734 734 for i in range(len(list2_)):
735 735 size2=size2+round(abs(list2_[i]))-1
736 736 new_size= size+size2
737 737 ang_new = numpy.zeros(new_size)
738 738 ang_new2 = numpy.zeros(new_size)
739 739
740 740 tmp = 0
741 741 c = 0
742 742 for i in range(len(ang_)):
743 743 ang_new[tmp +c] = ang_[i]
744 744 ang_new2[tmp+c] = ang_[i]
745 745 condition , value = self.search_pos(i,list1_)
746 746 if condition:
747 747 pos = tmp + c + 1
748 748 for k in range(round(abs(list2_[value]))-1):
749 749 if tipo_case==0 or tipo_case==3:#subida
750 750 ang_new[pos+k] = ang_new[pos+k-1]+1
751 751 ang_new2[pos+k] = numpy.nan
752 752 elif tipo_case==1 or tipo_case==2:#bajada
753 753 ang_new[pos+k] = ang_new[pos+k-1]-1
754 754 ang_new2[pos+k] = numpy.nan
755 755
756 756 tmp = pos +k
757 757 c = 0
758 758 c=c+1
759 759 return ang_new,ang_new2
760 760
761 761 def globalCheckPED(self,angulos,tipo_case):
762 762 l1,l2 = self.get2List(angulos)
763 763 ##print("l1",l1)
764 764 ##print("l2",l2)
765 765 if len(l1)>0:
766 766 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
767 767 #l1,l2 = self.get2List(angulos2)
768 768 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
769 769 #ang1_ = self.fixData90HL(ang1_)
770 770 #ang2_ = self.fixData90HL(ang2_)
771 771 else:
772 772 ang1_= angulos
773 773 ang2_= angulos
774 774 return ang1_,ang2_
775 775
776 776
777 777 def replaceNAN(self,data_weather,data_ele,val):
778 778 data= data_ele
779 779 data_T= data_weather
780 780 if data.shape[0]> data_T.shape[0]:
781 781 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
782 782 c = 0
783 783 for i in range(len(data)):
784 784 if numpy.isnan(data[i]):
785 785 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
786 786 else:
787 787 data_N[i,:]=data_T[c,:]
788 788 c=c+1
789 789 return data_N
790 790 else:
791 791 for i in range(len(data)):
792 792 if numpy.isnan(data[i]):
793 793 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
794 794 return data_T
795 795
796 796 def check_case(self,data_ele,ang_max,ang_min):
797 797 start = data_ele[0]
798 798 end = data_ele[-1]
799 799 number = (end-start)
800 800 len_ang=len(data_ele)
801 801 print("start",start)
802 802 print("end",end)
803 803 print("number",number)
804 804
805 805 print("len_ang",len_ang)
806 806
807 807 #exit(1)
808 808
809 809 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
810 810 return 0
811 811 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
812 812 # return 1
813 813 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
814 814 return 1
815 815 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
816 816 return 2
817 817 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
818 818 return 3
819 819
820 820
821 821 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min):
822 822 ang_max= ang_max
823 823 ang_min= ang_min
824 824 data_weather=data_weather
825 825 val_ch=val_ch
826 826 ##print("*********************DATA WEATHER**************************************")
827 827 ##print(data_weather)
828 828 if self.ini==0:
829 829 '''
830 830 print("**********************************************")
831 831 print("**********************************************")
832 832 print("***************ini**************")
833 833 print("**********************************************")
834 834 print("**********************************************")
835 835 '''
836 836 #print("data_ele",data_ele)
837 837 #----------------------------------------------------------
838 838 tipo_case = self.check_case(data_ele,ang_max,ang_min)
839 839 print("check_case",tipo_case)
840 840 #exit(1)
841 841 #--------------------- new -------------------------
842 842 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
843 843
844 844 #-------------------------CAMBIOS RHI---------------------------------
845 845 start= ang_min
846 846 end = ang_max
847 847 n= (ang_max-ang_min)/res
848 848 #------ new
849 849 self.start_data_ele = data_ele_new[0]
850 850 self.end_data_ele = data_ele_new[-1]
851 851 if tipo_case==0 or tipo_case==3: # SUBIDA
852 852 n1= round(self.start_data_ele)- start
853 853 n2= end - round(self.end_data_ele)
854 854 print(self.start_data_ele)
855 855 print(self.end_data_ele)
856 856 if n1>0:
857 857 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
858 858 ele1_nan= numpy.ones(n1)*numpy.nan
859 859 data_ele = numpy.hstack((ele1,data_ele_new))
860 860 print("ele1_nan",ele1_nan.shape)
861 861 print("data_ele_old",data_ele_old.shape)
862 862 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
863 863 if n2>0:
864 864 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
865 865 ele2_nan= numpy.ones(n2)*numpy.nan
866 866 data_ele = numpy.hstack((data_ele,ele2))
867 867 print("ele2_nan",ele2_nan.shape)
868 868 print("data_ele_old",data_ele_old.shape)
869 869 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
870 870
871 871 if tipo_case==1 or tipo_case==2: # BAJADA
872 872 data_ele_new = data_ele_new[::-1] # reversa
873 873 data_ele_old = data_ele_old[::-1]# reversa
874 874 data_weather = data_weather[::-1,:]# reversa
875 875 vec= numpy.where(data_ele_new<ang_max)
876 876 data_ele_new = data_ele_new[vec]
877 877 data_ele_old = data_ele_old[vec]
878 878 data_weather = data_weather[vec[0]]
879 879 vec2= numpy.where(0<data_ele_new)
880 880 data_ele_new = data_ele_new[vec2]
881 881 data_ele_old = data_ele_old[vec2]
882 882 data_weather = data_weather[vec2[0]]
883 883 self.start_data_ele = data_ele_new[0]
884 884 self.end_data_ele = data_ele_new[-1]
885 885
886 886 n1= round(self.start_data_ele)- start
887 887 n2= end - round(self.end_data_ele)-1
888 888 print(self.start_data_ele)
889 889 print(self.end_data_ele)
890 890 if n1>0:
891 891 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
892 892 ele1_nan= numpy.ones(n1)*numpy.nan
893 893 data_ele = numpy.hstack((ele1,data_ele_new))
894 894 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
895 895 if n2>0:
896 896 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
897 897 ele2_nan= numpy.ones(n2)*numpy.nan
898 898 data_ele = numpy.hstack((data_ele,ele2))
899 899 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
900 900 # RADAR
901 901 # NOTA data_ele y data_weather es la variable que retorna
902 902 val_mean = numpy.mean(data_weather[:,-1])
903 903 self.val_mean = val_mean
904 904 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
905 905 self.data_ele_tmp[val_ch]= data_ele_old
906 906 else:
907 907 #print("**********************************************")
908 908 #print("****************VARIABLE**********************")
909 909 #-------------------------CAMBIOS RHI---------------------------------
910 910 #---------------------------------------------------------------------
911 911 ##print("INPUT data_ele",data_ele)
912 912 flag=0
913 913 start_ele = self.res_ele[0]
914 914 tipo_case = self.check_case(data_ele,ang_max,ang_min)
915 915 #print("TIPO DE DATA",tipo_case)
916 916 #-----------new------------
917 917 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
918 918 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
919 919
920 920 #-------------------------------NEW RHI ITERATIVO-------------------------
921 921
922 922 if tipo_case==0 : # SUBIDA
923 923 vec = numpy.where(data_ele<ang_max)
924 924 data_ele = data_ele[vec]
925 925 data_ele_old = data_ele_old[vec]
926 926 data_weather = data_weather[vec[0]]
927 927
928 928 vec2 = numpy.where(0<data_ele)
929 929 data_ele= data_ele[vec2]
930 930 data_ele_old= data_ele_old[vec2]
931 931 ##print(data_ele_new)
932 932 data_weather= data_weather[vec2[0]]
933 933
934 934 new_i_ele = int(round(data_ele[0]))
935 935 new_f_ele = int(round(data_ele[-1]))
936 936 #print(new_i_ele)
937 937 #print(new_f_ele)
938 938 #print(data_ele,len(data_ele))
939 939 #print(data_ele_old,len(data_ele_old))
940 940 if new_i_ele< 2:
941 941 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
942 942 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
943 943 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
944 944 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
945 945 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
946 946 data_ele = self.res_ele
947 947 data_weather = self.res_weather[val_ch]
948 948
949 949 elif tipo_case==1 : #BAJADA
950 950 data_ele = data_ele[::-1] # reversa
951 951 data_ele_old = data_ele_old[::-1]# reversa
952 952 data_weather = data_weather[::-1,:]# reversa
953 953 vec= numpy.where(data_ele<ang_max)
954 954 data_ele = data_ele[vec]
955 955 data_ele_old = data_ele_old[vec]
956 956 data_weather = data_weather[vec[0]]
957 957 vec2= numpy.where(0<data_ele)
958 958 data_ele = data_ele[vec2]
959 959 data_ele_old = data_ele_old[vec2]
960 960 data_weather = data_weather[vec2[0]]
961 961
962 962
963 963 new_i_ele = int(round(data_ele[0]))
964 964 new_f_ele = int(round(data_ele[-1]))
965 965 #print(data_ele)
966 966 #print(ang_max)
967 967 #print(data_ele_old)
968 968 if new_i_ele <= 1:
969 969 new_i_ele = 1
970 970 if round(data_ele[-1])>=ang_max-1:
971 971 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
972 972 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
973 973 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
974 974 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
975 975 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
976 976 data_ele = self.res_ele
977 977 data_weather = self.res_weather[val_ch]
978 978
979 979 elif tipo_case==2: #bajada
980 980 vec = numpy.where(data_ele<ang_max)
981 981 data_ele = data_ele[vec]
982 982 data_weather= data_weather[vec[0]]
983 983
984 984 len_vec = len(vec)
985 985 data_ele_new = data_ele[::-1] # reversa
986 986 data_weather = data_weather[::-1,:]
987 987 new_i_ele = int(data_ele_new[0])
988 988 new_f_ele = int(data_ele_new[-1])
989 989
990 990 n1= new_i_ele- ang_min
991 991 n2= ang_max - new_f_ele-1
992 992 if n1>0:
993 993 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
994 994 ele1_nan= numpy.ones(n1)*numpy.nan
995 995 data_ele = numpy.hstack((ele1,data_ele_new))
996 996 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
997 997 if n2>0:
998 998 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
999 999 ele2_nan= numpy.ones(n2)*numpy.nan
1000 1000 data_ele = numpy.hstack((data_ele,ele2))
1001 1001 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1002 1002
1003 1003 self.data_ele_tmp[val_ch] = data_ele_old
1004 1004 self.res_ele = data_ele
1005 1005 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1006 1006 data_ele = self.res_ele
1007 1007 data_weather = self.res_weather[val_ch]
1008 1008
1009 1009 elif tipo_case==3:#subida
1010 1010 vec = numpy.where(0<data_ele)
1011 1011 data_ele= data_ele[vec]
1012 1012 data_ele_new = data_ele
1013 1013 data_ele_old= data_ele_old[vec]
1014 1014 data_weather= data_weather[vec[0]]
1015 1015 pos_ini = numpy.argmin(data_ele)
1016 1016 if pos_ini>0:
1017 1017 len_vec= len(data_ele)
1018 1018 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1019 1019 #print(vec3)
1020 1020 data_ele= data_ele[vec3]
1021 1021 data_ele_new = data_ele
1022 1022 data_ele_old= data_ele_old[vec3]
1023 1023 data_weather= data_weather[vec3]
1024 1024
1025 1025 new_i_ele = int(data_ele_new[0])
1026 1026 new_f_ele = int(data_ele_new[-1])
1027 1027 n1= new_i_ele- ang_min
1028 1028 n2= ang_max - new_f_ele-1
1029 1029 if n1>0:
1030 1030 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1031 1031 ele1_nan= numpy.ones(n1)*numpy.nan
1032 1032 data_ele = numpy.hstack((ele1,data_ele_new))
1033 1033 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1034 1034 if n2>0:
1035 1035 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1036 1036 ele2_nan= numpy.ones(n2)*numpy.nan
1037 1037 data_ele = numpy.hstack((data_ele,ele2))
1038 1038 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1039 1039
1040 1040 self.data_ele_tmp[val_ch] = data_ele_old
1041 1041 self.res_ele = data_ele
1042 1042 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1043 1043 data_ele = self.res_ele
1044 1044 data_weather = self.res_weather[val_ch]
1045 1045 #print("self.data_ele_tmp",self.data_ele_tmp)
1046 1046 return data_weather,data_ele
1047 1047
1048 1048
1049 1049 def plot(self):
1050 1050 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1051 1051 data = self.data[-1]
1052 1052 r = self.data.yrange
1053 1053 delta_height = r[1]-r[0]
1054 1054 r_mask = numpy.where(r>=0)[0]
1055 1055 ##print("delta_height",delta_height)
1056 1056 #print("r_mask",r_mask,len(r_mask))
1057 1057 r = numpy.arange(len(r_mask))*delta_height
1058 1058 self.y = 2*r
1059 1059 res = 1
1060 1060 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1061 1061 ang_max = self.ang_max
1062 1062 ang_min = self.ang_min
1063 1063 var_ang =ang_max - ang_min
1064 1064 step = (int(var_ang)/(res*data['weather'].shape[0]))
1065 1065 ###print("step",step)
1066 1066 #--------------------------------------------------------
1067 1067 ##print('weather',data['weather'].shape)
1068 1068 ##print('ele',data['ele'].shape)
1069 1069
1070 1070 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1071 1071 ###self.res_azi = numpy.mean(data['azi'])
1072 1072 ###print("self.res_ele",self.res_ele)
1073 1073 plt.clf()
1074 1074 subplots = [121, 122]
1075 1075 if self.ini==0:
1076 1076 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1077 1077 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1078 1078 print("SHAPE",self.data_ele_tmp.shape)
1079 1079
1080 1080 for i,ax in enumerate(self.axes):
1081 1081 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1082 1082 self.res_azi = numpy.mean(data['azi'])
1083 1083 if i==0:
1084 1084 print("*****************************************************************************to plot**************************",self.res_weather[i].shape)
1085 1085 if ax.firsttime:
1086 1086 #plt.clf()
1087 1087 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1088 1088 #fig=self.figures[0]
1089 1089 else:
1090 1090 #plt.clf()
1091 1091 if i==0:
1092 1092 print(self.res_weather[i])
1093 1093 print(self.res_ele)
1094 1094 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1095 1095 caax = cgax.parasites[0]
1096 1096 paax = cgax.parasites[1]
1097 1097 cbar = plt.gcf().colorbar(pm, pad=0.075)
1098 1098 caax.set_xlabel('x_range [km]')
1099 1099 caax.set_ylabel('y_range [km]')
1100 1100 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1101 1101 print("***************************self.ini****************************",self.ini)
1102 1102 self.ini= self.ini+1
1103 1103
1104 1104 class WeatherRHI_vRF2_Plot(Plot):
1105 1105 CODE = 'weather'
1106 1106 plot_name = 'weather'
1107 1107 plot_type = 'rhistyle'
1108 1108 buffering = False
1109 1109 data_ele_tmp = None
1110 1110
1111 1111 def setup(self):
1112 1112 print("********************")
1113 1113 print("********************")
1114 1114 print("********************")
1115 1115 print("SETUP WEATHER PLOT")
1116 1116 self.ncols = 1
1117 1117 self.nrows = 1
1118 1118 self.nplots= 1
1119 1119 self.ylabel= 'Range [Km]'
1120 1120 self.titles= ['Weather']
1121 1121 if self.channels is not None:
1122 1122 self.nplots = len(self.channels)
1123 1123 self.nrows = len(self.channels)
1124 1124 else:
1125 1125 self.nplots = self.data.shape(self.CODE)[0]
1126 1126 self.nrows = self.nplots
1127 1127 self.channels = list(range(self.nplots))
1128 1128 print("channels",self.channels)
1129 1129 print("que saldra", self.data.shape(self.CODE)[0])
1130 1130 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1131 1131 print("self.titles",self.titles)
1132 1132 self.colorbar=False
1133 1133 self.width =8
1134 1134 self.height =8
1135 1135 self.ini =0
1136 1136 self.len_azi =0
1137 1137 self.buffer_ini = None
1138 1138 self.buffer_ele = None
1139 1139 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1140 1140 self.flag =0
1141 1141 self.indicador= 0
1142 1142 self.last_data_ele = None
1143 1143 self.val_mean = None
1144 1144
1145 1145 def update(self, dataOut):
1146 1146
1147 1147 data = {}
1148 1148 meta = {}
1149 1149 if hasattr(dataOut, 'dataPP_POWER'):
1150 1150 factor = 1
1151 1151 if hasattr(dataOut, 'nFFTPoints'):
1152 1152 factor = dataOut.normFactor
1153 1153 print("dataOut",dataOut.data_360.shape)
1154 1154 #
1155 1155 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1156 1156 #
1157 1157 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1158 1158 data['azi'] = dataOut.data_azi
1159 1159 data['ele'] = dataOut.data_ele
1160 1160 data['case_flag'] = dataOut.case_flag
1161 1161 #print("UPDATE")
1162 1162 #print("data[weather]",data['weather'].shape)
1163 1163 #print("data[azi]",data['azi'])
1164 1164 return data, meta
1165 1165
1166 1166 def get2List(self,angulos):
1167 1167 list1=[]
1168 1168 list2=[]
1169 1169 for i in reversed(range(len(angulos))):
1170 1170 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1171 1171 diff_ = angulos[i]-angulos[i-1]
1172 1172 if abs(diff_) >1.5:
1173 1173 list1.append(i-1)
1174 1174 list2.append(diff_)
1175 1175 return list(reversed(list1)),list(reversed(list2))
1176 1176
1177 1177 def fixData90(self,list_,ang_):
1178 1178 if list_[0]==-1:
1179 1179 vec = numpy.where(ang_<ang_[0])
1180 1180 ang_[vec] = ang_[vec]+90
1181 1181 return ang_
1182 1182 return ang_
1183 1183
1184 1184 def fixData90HL(self,angulos):
1185 1185 vec = numpy.where(angulos>=90)
1186 1186 angulos[vec]=angulos[vec]-90
1187 1187 return angulos
1188 1188
1189 1189
1190 1190 def search_pos(self,pos,list_):
1191 1191 for i in range(len(list_)):
1192 1192 if pos == list_[i]:
1193 1193 return True,i
1194 1194 i=None
1195 1195 return False,i
1196 1196
1197 1197 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1198 1198 size = len(ang_)
1199 1199 size2 = 0
1200 1200 for i in range(len(list2_)):
1201 1201 size2=size2+round(abs(list2_[i]))-1
1202 1202 new_size= size+size2
1203 1203 ang_new = numpy.zeros(new_size)
1204 1204 ang_new2 = numpy.zeros(new_size)
1205 1205
1206 1206 tmp = 0
1207 1207 c = 0
1208 1208 for i in range(len(ang_)):
1209 1209 ang_new[tmp +c] = ang_[i]
1210 1210 ang_new2[tmp+c] = ang_[i]
1211 1211 condition , value = self.search_pos(i,list1_)
1212 1212 if condition:
1213 1213 pos = tmp + c + 1
1214 1214 for k in range(round(abs(list2_[value]))-1):
1215 1215 if tipo_case==0 or tipo_case==3:#subida
1216 1216 ang_new[pos+k] = ang_new[pos+k-1]+1
1217 1217 ang_new2[pos+k] = numpy.nan
1218 1218 elif tipo_case==1 or tipo_case==2:#bajada
1219 1219 ang_new[pos+k] = ang_new[pos+k-1]-1
1220 1220 ang_new2[pos+k] = numpy.nan
1221 1221
1222 1222 tmp = pos +k
1223 1223 c = 0
1224 1224 c=c+1
1225 1225 return ang_new,ang_new2
1226 1226
1227 1227 def globalCheckPED(self,angulos,tipo_case):
1228 1228 l1,l2 = self.get2List(angulos)
1229 1229 ##print("l1",l1)
1230 1230 ##print("l2",l2)
1231 1231 if len(l1)>0:
1232 1232 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1233 1233 #l1,l2 = self.get2List(angulos2)
1234 1234 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1235 1235 #ang1_ = self.fixData90HL(ang1_)
1236 1236 #ang2_ = self.fixData90HL(ang2_)
1237 1237 else:
1238 1238 ang1_= angulos
1239 1239 ang2_= angulos
1240 1240 return ang1_,ang2_
1241 1241
1242 1242
1243 1243 def replaceNAN(self,data_weather,data_ele,val):
1244 1244 data= data_ele
1245 1245 data_T= data_weather
1246 1246 if data.shape[0]> data_T.shape[0]:
1247 1247 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1248 1248 c = 0
1249 1249 for i in range(len(data)):
1250 1250 if numpy.isnan(data[i]):
1251 1251 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1252 1252 else:
1253 1253 data_N[i,:]=data_T[c,:]
1254 1254 c=c+1
1255 1255 return data_N
1256 1256 else:
1257 1257 for i in range(len(data)):
1258 1258 if numpy.isnan(data[i]):
1259 1259 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1260 1260 return data_T
1261 1261
1262 1262 def check_case(self,data_ele,ang_max,ang_min):
1263 1263 start = data_ele[0]
1264 1264 end = data_ele[-1]
1265 1265 number = (end-start)
1266 1266 len_ang=len(data_ele)
1267 1267 print("start",start)
1268 1268 print("end",end)
1269 1269 print("number",number)
1270 1270
1271 1271 print("len_ang",len_ang)
1272 1272
1273 1273 #exit(1)
1274 1274
1275 1275 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
1276 1276 return 0
1277 1277 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
1278 1278 # return 1
1279 1279 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
1280 1280 return 1
1281 1281 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
1282 1282 return 2
1283 1283 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
1284 1284 return 3
1285 1285
1286 1286
1287 1287 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1288 1288 ang_max= ang_max
1289 1289 ang_min= ang_min
1290 1290 data_weather=data_weather
1291 1291 val_ch=val_ch
1292 1292 ##print("*********************DATA WEATHER**************************************")
1293 1293 ##print(data_weather)
1294 1294 if self.ini==0:
1295 1295 '''
1296 1296 print("**********************************************")
1297 1297 print("**********************************************")
1298 1298 print("***************ini**************")
1299 1299 print("**********************************************")
1300 1300 print("**********************************************")
1301 1301 '''
1302 1302 #print("data_ele",data_ele)
1303 1303 #----------------------------------------------------------
1304 1304 tipo_case = case_flag[-1]
1305 1305 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1306 1306 print("check_case",tipo_case)
1307 1307 #exit(1)
1308 1308 #--------------------- new -------------------------
1309 1309 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1310 1310
1311 1311 #-------------------------CAMBIOS RHI---------------------------------
1312 1312 start= ang_min
1313 1313 end = ang_max
1314 1314 n= (ang_max-ang_min)/res
1315 1315 #------ new
1316 1316 self.start_data_ele = data_ele_new[0]
1317 1317 self.end_data_ele = data_ele_new[-1]
1318 1318 if tipo_case==0 or tipo_case==3: # SUBIDA
1319 1319 n1= round(self.start_data_ele)- start
1320 1320 n2= end - round(self.end_data_ele)
1321 1321 print(self.start_data_ele)
1322 1322 print(self.end_data_ele)
1323 1323 if n1>0:
1324 1324 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1325 1325 ele1_nan= numpy.ones(n1)*numpy.nan
1326 1326 data_ele = numpy.hstack((ele1,data_ele_new))
1327 1327 print("ele1_nan",ele1_nan.shape)
1328 1328 print("data_ele_old",data_ele_old.shape)
1329 1329 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1330 1330 if n2>0:
1331 1331 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1332 1332 ele2_nan= numpy.ones(n2)*numpy.nan
1333 1333 data_ele = numpy.hstack((data_ele,ele2))
1334 1334 print("ele2_nan",ele2_nan.shape)
1335 1335 print("data_ele_old",data_ele_old.shape)
1336 1336 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1337 1337
1338 1338 if tipo_case==1 or tipo_case==2: # BAJADA
1339 1339 data_ele_new = data_ele_new[::-1] # reversa
1340 1340 data_ele_old = data_ele_old[::-1]# reversa
1341 1341 data_weather = data_weather[::-1,:]# reversa
1342 1342 vec= numpy.where(data_ele_new<ang_max)
1343 1343 data_ele_new = data_ele_new[vec]
1344 1344 data_ele_old = data_ele_old[vec]
1345 1345 data_weather = data_weather[vec[0]]
1346 1346 vec2= numpy.where(0<data_ele_new)
1347 1347 data_ele_new = data_ele_new[vec2]
1348 1348 data_ele_old = data_ele_old[vec2]
1349 1349 data_weather = data_weather[vec2[0]]
1350 1350 self.start_data_ele = data_ele_new[0]
1351 1351 self.end_data_ele = data_ele_new[-1]
1352 1352
1353 1353 n1= round(self.start_data_ele)- start
1354 1354 n2= end - round(self.end_data_ele)-1
1355 1355 print(self.start_data_ele)
1356 1356 print(self.end_data_ele)
1357 1357 if n1>0:
1358 1358 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1359 1359 ele1_nan= numpy.ones(n1)*numpy.nan
1360 1360 data_ele = numpy.hstack((ele1,data_ele_new))
1361 1361 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1362 1362 if n2>0:
1363 1363 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1364 1364 ele2_nan= numpy.ones(n2)*numpy.nan
1365 1365 data_ele = numpy.hstack((data_ele,ele2))
1366 1366 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1367 1367 # RADAR
1368 1368 # NOTA data_ele y data_weather es la variable que retorna
1369 1369 val_mean = numpy.mean(data_weather[:,-1])
1370 1370 self.val_mean = val_mean
1371 1371 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1372 1372 print("eleold",data_ele_old)
1373 1373 print(self.data_ele_tmp[val_ch])
1374 1374 print(data_ele_old.shape[0])
1375 1375 print(self.data_ele_tmp[val_ch].shape[0])
1376 1376 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
1377 1377 import sys
1378 1378 print("EXIT",self.ini)
1379 1379
1380 1380 sys.exit(1)
1381 1381 self.data_ele_tmp[val_ch]= data_ele_old
1382 1382 else:
1383 1383 #print("**********************************************")
1384 1384 #print("****************VARIABLE**********************")
1385 1385 #-------------------------CAMBIOS RHI---------------------------------
1386 1386 #---------------------------------------------------------------------
1387 1387 ##print("INPUT data_ele",data_ele)
1388 1388 flag=0
1389 1389 start_ele = self.res_ele[0]
1390 1390 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1391 1391 tipo_case = case_flag[-1]
1392 1392 #print("TIPO DE DATA",tipo_case)
1393 1393 #-----------new------------
1394 1394 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
1395 1395 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1396 1396
1397 1397 #-------------------------------NEW RHI ITERATIVO-------------------------
1398 1398
1399 1399 if tipo_case==0 : # SUBIDA
1400 1400 vec = numpy.where(data_ele<ang_max)
1401 1401 data_ele = data_ele[vec]
1402 1402 data_ele_old = data_ele_old[vec]
1403 1403 data_weather = data_weather[vec[0]]
1404 1404
1405 1405 vec2 = numpy.where(0<data_ele)
1406 1406 data_ele= data_ele[vec2]
1407 1407 data_ele_old= data_ele_old[vec2]
1408 1408 ##print(data_ele_new)
1409 1409 data_weather= data_weather[vec2[0]]
1410 1410
1411 1411 new_i_ele = int(round(data_ele[0]))
1412 1412 new_f_ele = int(round(data_ele[-1]))
1413 1413 #print(new_i_ele)
1414 1414 #print(new_f_ele)
1415 1415 #print(data_ele,len(data_ele))
1416 1416 #print(data_ele_old,len(data_ele_old))
1417 1417 if new_i_ele< 2:
1418 1418 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1419 1419 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1420 1420 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
1421 1421 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
1422 1422 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
1423 1423 data_ele = self.res_ele
1424 1424 data_weather = self.res_weather[val_ch]
1425 1425
1426 1426 elif tipo_case==1 : #BAJADA
1427 1427 data_ele = data_ele[::-1] # reversa
1428 1428 data_ele_old = data_ele_old[::-1]# reversa
1429 1429 data_weather = data_weather[::-1,:]# reversa
1430 1430 vec= numpy.where(data_ele<ang_max)
1431 1431 data_ele = data_ele[vec]
1432 1432 data_ele_old = data_ele_old[vec]
1433 1433 data_weather = data_weather[vec[0]]
1434 1434 vec2= numpy.where(0<data_ele)
1435 1435 data_ele = data_ele[vec2]
1436 1436 data_ele_old = data_ele_old[vec2]
1437 1437 data_weather = data_weather[vec2[0]]
1438 1438
1439 1439
1440 1440 new_i_ele = int(round(data_ele[0]))
1441 1441 new_f_ele = int(round(data_ele[-1]))
1442 1442 #print(data_ele)
1443 1443 #print(ang_max)
1444 1444 #print(data_ele_old)
1445 1445 if new_i_ele <= 1:
1446 1446 new_i_ele = 1
1447 1447 if round(data_ele[-1])>=ang_max-1:
1448 1448 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1449 1449 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1450 1450 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
1451 1451 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
1452 1452 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
1453 1453 data_ele = self.res_ele
1454 1454 data_weather = self.res_weather[val_ch]
1455 1455
1456 1456 elif tipo_case==2: #bajada
1457 1457 vec = numpy.where(data_ele<ang_max)
1458 1458 data_ele = data_ele[vec]
1459 1459 data_weather= data_weather[vec[0]]
1460 1460
1461 1461 len_vec = len(vec)
1462 1462 data_ele_new = data_ele[::-1] # reversa
1463 1463 data_weather = data_weather[::-1,:]
1464 1464 new_i_ele = int(data_ele_new[0])
1465 1465 new_f_ele = int(data_ele_new[-1])
1466 1466
1467 1467 n1= new_i_ele- ang_min
1468 1468 n2= ang_max - new_f_ele-1
1469 1469 if n1>0:
1470 1470 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1471 1471 ele1_nan= numpy.ones(n1)*numpy.nan
1472 1472 data_ele = numpy.hstack((ele1,data_ele_new))
1473 1473 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1474 1474 if n2>0:
1475 1475 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1476 1476 ele2_nan= numpy.ones(n2)*numpy.nan
1477 1477 data_ele = numpy.hstack((data_ele,ele2))
1478 1478 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1479 1479
1480 1480 self.data_ele_tmp[val_ch] = data_ele_old
1481 1481 self.res_ele = data_ele
1482 1482 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1483 1483 data_ele = self.res_ele
1484 1484 data_weather = self.res_weather[val_ch]
1485 1485
1486 1486 elif tipo_case==3:#subida
1487 1487 vec = numpy.where(0<data_ele)
1488 1488 data_ele= data_ele[vec]
1489 1489 data_ele_new = data_ele
1490 1490 data_ele_old= data_ele_old[vec]
1491 1491 data_weather= data_weather[vec[0]]
1492 1492 pos_ini = numpy.argmin(data_ele)
1493 1493 if pos_ini>0:
1494 1494 len_vec= len(data_ele)
1495 1495 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1496 1496 #print(vec3)
1497 1497 data_ele= data_ele[vec3]
1498 1498 data_ele_new = data_ele
1499 1499 data_ele_old= data_ele_old[vec3]
1500 1500 data_weather= data_weather[vec3]
1501 1501
1502 1502 new_i_ele = int(data_ele_new[0])
1503 1503 new_f_ele = int(data_ele_new[-1])
1504 1504 n1= new_i_ele- ang_min
1505 1505 n2= ang_max - new_f_ele-1
1506 1506 if n1>0:
1507 1507 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1508 1508 ele1_nan= numpy.ones(n1)*numpy.nan
1509 1509 data_ele = numpy.hstack((ele1,data_ele_new))
1510 1510 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1511 1511 if n2>0:
1512 1512 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1513 1513 ele2_nan= numpy.ones(n2)*numpy.nan
1514 1514 data_ele = numpy.hstack((data_ele,ele2))
1515 1515 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1516 1516
1517 1517 self.data_ele_tmp[val_ch] = data_ele_old
1518 1518 self.res_ele = data_ele
1519 1519 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1520 1520 data_ele = self.res_ele
1521 1521 data_weather = self.res_weather[val_ch]
1522 1522 #print("self.data_ele_tmp",self.data_ele_tmp)
1523 1523 return data_weather,data_ele
1524 1524
1525 1525
1526 1526 def plot(self):
1527 1527 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1528 1528 data = self.data[-1]
1529 1529 r = self.data.yrange
1530 1530 delta_height = r[1]-r[0]
1531 1531 r_mask = numpy.where(r>=0)[0]
1532 1532 ##print("delta_height",delta_height)
1533 1533 #print("r_mask",r_mask,len(r_mask))
1534 1534 r = numpy.arange(len(r_mask))*delta_height
1535 1535 self.y = 2*r
1536 1536 res = 1
1537 1537 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1538 1538 ang_max = self.ang_max
1539 1539 ang_min = self.ang_min
1540 1540 var_ang =ang_max - ang_min
1541 1541 step = (int(var_ang)/(res*data['weather'].shape[0]))
1542 1542 ###print("step",step)
1543 1543 #--------------------------------------------------------
1544 1544 ##print('weather',data['weather'].shape)
1545 1545 ##print('ele',data['ele'].shape)
1546 1546
1547 1547 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1548 1548 ###self.res_azi = numpy.mean(data['azi'])
1549 1549 ###print("self.res_ele",self.res_ele)
1550 1550 plt.clf()
1551 1551 subplots = [121, 122]
1552 1552 try:
1553 1553 if self.data[-2]['ele'].max()<data['ele'].max():
1554 1554 self.ini=0
1555 1555 except:
1556 1556 pass
1557 1557 if self.ini==0:
1558 1558 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1559 1559 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1560 1560 print("SHAPE",self.data_ele_tmp.shape)
1561 1561
1562 1562 for i,ax in enumerate(self.axes):
1563 1563 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min,case_flag=self.data['case_flag'])
1564 1564 self.res_azi = numpy.mean(data['azi'])
1565 1565
1566 1566 if ax.firsttime:
1567 1567 #plt.clf()
1568 1568 print("Frist Plot")
1569 1569 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1570 1570 #fig=self.figures[0]
1571 1571 else:
1572 1572 #plt.clf()
1573 1573 print("ELSE PLOT")
1574 1574 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1575 1575 caax = cgax.parasites[0]
1576 1576 paax = cgax.parasites[1]
1577 1577 cbar = plt.gcf().colorbar(pm, pad=0.075)
1578 1578 caax.set_xlabel('x_range [km]')
1579 1579 caax.set_ylabel('y_range [km]')
1580 1580 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1581 1581 print("***************************self.ini****************************",self.ini)
1582 1582 self.ini= self.ini+1
1583 1583
1584 1584 class WeatherRHI_vRF_Plot(Plot):
1585 1585 CODE = 'weather'
1586 1586 plot_name = 'weather'
1587 1587 plot_type = 'rhistyle'
1588 1588 buffering = False
1589 1589 data_ele_tmp = None
1590 1590
1591 1591 def setup(self):
1592 1592 print("********************")
1593 1593 print("********************")
1594 1594 print("********************")
1595 1595 print("SETUP WEATHER PLOT")
1596 1596 self.ncols = 1
1597 1597 self.nrows = 1
1598 1598 self.nplots= 1
1599 1599 self.ylabel= 'Range [Km]'
1600 1600 self.titles= ['Weather']
1601 1601 if self.channels is not None:
1602 1602 self.nplots = len(self.channels)
1603 1603 self.nrows = len(self.channels)
1604 1604 else:
1605 1605 self.nplots = self.data.shape(self.CODE)[0]
1606 1606 self.nrows = self.nplots
1607 1607 self.channels = list(range(self.nplots))
1608 1608 print("channels",self.channels)
1609 1609 print("que saldra", self.data.shape(self.CODE)[0])
1610 1610 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1611 1611 print("self.titles",self.titles)
1612 1612 self.colorbar=False
1613 1613 self.width =8
1614 1614 self.height =8
1615 1615 self.ini =0
1616 1616 self.len_azi =0
1617 1617 self.buffer_ini = None
1618 1618 self.buffer_ele = None
1619 1619 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1620 1620 self.flag =0
1621 1621 self.indicador= 0
1622 1622 self.last_data_ele = None
1623 1623 self.val_mean = None
1624 1624
1625 1625 def update(self, dataOut):
1626 1626
1627 1627 data = {}
1628 1628 meta = {}
1629 1629 if hasattr(dataOut, 'dataPP_POWER'):
1630 1630 factor = 1
1631 1631 if hasattr(dataOut, 'nFFTPoints'):
1632 1632 factor = dataOut.normFactor
1633 1633 print("dataOut",dataOut.data_360.shape)
1634 1634 #
1635 1635 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1636 1636 #
1637 1637 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1638 1638 data['azi'] = dataOut.data_azi
1639 1639 data['ele'] = dataOut.data_ele
1640 1640 data['case_flag'] = dataOut.case_flag
1641 1641 #print("UPDATE")
1642 1642 #print("data[weather]",data['weather'].shape)
1643 1643 #print("data[azi]",data['azi'])
1644 1644 return data, meta
1645 1645
1646 1646 def get2List(self,angulos):
1647 1647 list1=[]
1648 1648 list2=[]
1649 1649 #print(angulos)
1650 1650 #exit(1)
1651 1651 for i in reversed(range(len(angulos))):
1652 1652 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1653 1653 diff_ = angulos[i]-angulos[i-1]
1654 1654 if abs(diff_) >1.5:
1655 1655 list1.append(i-1)
1656 1656 list2.append(diff_)
1657 1657 return list(reversed(list1)),list(reversed(list2))
1658 1658
1659 1659 def fixData90(self,list_,ang_):
1660 1660 if list_[0]==-1:
1661 1661 vec = numpy.where(ang_<ang_[0])
1662 1662 ang_[vec] = ang_[vec]+90
1663 1663 return ang_
1664 1664 return ang_
1665 1665
1666 1666 def fixData90HL(self,angulos):
1667 1667 vec = numpy.where(angulos>=90)
1668 1668 angulos[vec]=angulos[vec]-90
1669 1669 return angulos
1670 1670
1671 1671
1672 1672 def search_pos(self,pos,list_):
1673 1673 for i in range(len(list_)):
1674 1674 if pos == list_[i]:
1675 1675 return True,i
1676 1676 i=None
1677 1677 return False,i
1678 1678
1679 1679 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1680 1680 size = len(ang_)
1681 1681 size2 = 0
1682 1682 for i in range(len(list2_)):
1683 1683 size2=size2+round(abs(list2_[i]))-1
1684 1684 new_size= size+size2
1685 1685 ang_new = numpy.zeros(new_size)
1686 1686 ang_new2 = numpy.zeros(new_size)
1687 1687
1688 1688 tmp = 0
1689 1689 c = 0
1690 1690 for i in range(len(ang_)):
1691 1691 ang_new[tmp +c] = ang_[i]
1692 1692 ang_new2[tmp+c] = ang_[i]
1693 1693 condition , value = self.search_pos(i,list1_)
1694 1694 if condition:
1695 1695 pos = tmp + c + 1
1696 1696 for k in range(round(abs(list2_[value]))-1):
1697 1697 if tipo_case==0 or tipo_case==3:#subida
1698 1698 ang_new[pos+k] = ang_new[pos+k-1]+1
1699 1699 ang_new2[pos+k] = numpy.nan
1700 1700 elif tipo_case==1 or tipo_case==2:#bajada
1701 1701 ang_new[pos+k] = ang_new[pos+k-1]-1
1702 1702 ang_new2[pos+k] = numpy.nan
1703 1703
1704 1704 tmp = pos +k
1705 1705 c = 0
1706 1706 c=c+1
1707 1707 return ang_new,ang_new2
1708 1708
1709 1709 def globalCheckPED(self,angulos,tipo_case):
1710 1710 l1,l2 = self.get2List(angulos)
1711 1711 print("l1",l1)
1712 1712 print("l2",l2)
1713 1713 if len(l1)>0:
1714 1714 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1715 1715 #l1,l2 = self.get2List(angulos2)
1716 1716 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1717 1717 #ang1_ = self.fixData90HL(ang1_)
1718 1718 #ang2_ = self.fixData90HL(ang2_)
1719 1719 else:
1720 1720 ang1_= angulos
1721 1721 ang2_= angulos
1722 1722 return ang1_,ang2_
1723 1723
1724 1724
1725 1725 def replaceNAN(self,data_weather,data_ele,val):
1726 1726 data= data_ele
1727 1727 data_T= data_weather
1728 1728 #print(data.shape[0])
1729 1729 #print(data_T.shape[0])
1730 1730 #exit(1)
1731 1731 if data.shape[0]> data_T.shape[0]:
1732 1732 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1733 1733 c = 0
1734 1734 for i in range(len(data)):
1735 1735 if numpy.isnan(data[i]):
1736 1736 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1737 1737 else:
1738 1738 data_N[i,:]=data_T[c,:]
1739 1739 c=c+1
1740 1740 return data_N
1741 1741 else:
1742 1742 for i in range(len(data)):
1743 1743 if numpy.isnan(data[i]):
1744 1744 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1745 1745 return data_T
1746 1746
1747 1747
1748 1748 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1749 1749 ang_max= ang_max
1750 1750 ang_min= ang_min
1751 1751 data_weather=data_weather
1752 1752 val_ch=val_ch
1753 1753 ##print("*********************DATA WEATHER**************************************")
1754 1754 ##print(data_weather)
1755 1755
1756 1756 '''
1757 1757 print("**********************************************")
1758 1758 print("**********************************************")
1759 1759 print("***************ini**************")
1760 1760 print("**********************************************")
1761 1761 print("**********************************************")
1762 1762 '''
1763 1763 #print("data_ele",data_ele)
1764 1764 #----------------------------------------------------------
1765 1765
1766 1766 #exit(1)
1767 1767 tipo_case = case_flag[-1]
1768 1768 print("tipo_case",tipo_case)
1769 1769 #--------------------- new -------------------------
1770 1770 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1771 1771
1772 1772 #-------------------------CAMBIOS RHI---------------------------------
1773 1773
1774 1774 vec = numpy.where(data_ele<ang_max)
1775 1775 data_ele = data_ele[vec]
1776 1776 data_weather= data_weather[vec[0]]
1777 1777
1778 1778 len_vec = len(vec)
1779 1779 data_ele_new = data_ele[::-1] # reversa
1780 1780 data_weather = data_weather[::-1,:]
1781 1781 new_i_ele = int(data_ele_new[0])
1782 1782 new_f_ele = int(data_ele_new[-1])
1783 1783
1784 1784 n1= new_i_ele- ang_min
1785 1785 n2= ang_max - new_f_ele-1
1786 1786 if n1>0:
1787 1787 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1788 1788 ele1_nan= numpy.ones(n1)*numpy.nan
1789 1789 data_ele = numpy.hstack((ele1,data_ele_new))
1790 1790 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1791 1791 if n2>0:
1792 1792 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1793 1793 ele2_nan= numpy.ones(n2)*numpy.nan
1794 1794 data_ele = numpy.hstack((data_ele,ele2))
1795 1795 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1796 1796
1797 1797
1798 1798 print("ele shape",data_ele.shape)
1799 1799 print(data_ele)
1800 1800
1801 1801 #print("self.data_ele_tmp",self.data_ele_tmp)
1802 1802 val_mean = numpy.mean(data_weather[:,-1])
1803 1803 self.val_mean = val_mean
1804 1804 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1805 1805 self.data_ele_tmp[val_ch]= data_ele_old
1806 1806
1807 1807
1808 1808 print("data_weather shape",data_weather.shape)
1809 1809 print(data_weather)
1810 1810 #exit(1)
1811 1811 return data_weather,data_ele
1812 1812
1813 1813
1814 1814 def plot(self):
1815 1815 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1816 1816 data = self.data[-1]
1817 1817 r = self.data.yrange
1818 1818 delta_height = r[1]-r[0]
1819 1819 r_mask = numpy.where(r>=0)[0]
1820 1820 ##print("delta_height",delta_height)
1821 1821 #print("r_mask",r_mask,len(r_mask))
1822 1822 r = numpy.arange(len(r_mask))*delta_height
1823 1823 self.y = 2*r
1824 1824 res = 1
1825 1825 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1826 1826 ang_max = self.ang_max
1827 1827 ang_min = self.ang_min
1828 1828 var_ang =ang_max - ang_min
1829 1829 step = (int(var_ang)/(res*data['weather'].shape[0]))
1830 1830 ###print("step",step)
1831 1831 #--------------------------------------------------------
1832 1832 ##print('weather',data['weather'].shape)
1833 1833 ##print('ele',data['ele'].shape)
1834 1834
1835 1835 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1836 1836 ###self.res_azi = numpy.mean(data['azi'])
1837 1837 ###print("self.res_ele",self.res_ele)
1838 1838 plt.clf()
1839 1839 subplots = [121, 122]
1840 1840 if self.ini==0:
1841 1841 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1842 1842 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1843 1843 print("SHAPE",self.data_ele_tmp.shape)
1844 1844
1845 1845 for i,ax in enumerate(self.axes):
1846 1846 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min,case_flag=self.data['case_flag'])
1847 1847 self.res_azi = numpy.mean(data['azi'])
1848 1848
1849 1849 print(self.res_ele)
1850 1850 #exit(1)
1851 1851 if ax.firsttime:
1852 1852 #plt.clf()
1853 1853 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1854 1854 #fig=self.figures[0]
1855 1855 else:
1856 1856
1857 1857 #plt.clf()
1858 1858 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1859 1859 caax = cgax.parasites[0]
1860 1860 paax = cgax.parasites[1]
1861 1861 cbar = plt.gcf().colorbar(pm, pad=0.075)
1862 1862 caax.set_xlabel('x_range [km]')
1863 1863 caax.set_ylabel('y_range [km]')
1864 1864 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1865 1865 print("***************************self.ini****************************",self.ini)
1866 1866 self.ini= self.ini+1
1867 1867
1868 1868 class WeatherRHI_vRF3_Plot(Plot):
1869 1869 CODE = 'weather'
1870 1870 plot_name = 'weather'
1871 1871 plot_type = 'rhistyle'
1872 1872 buffering = False
1873 1873 data_ele_tmp = None
1874 1874
1875 1875 def setup(self):
1876 1876 print("********************")
1877 1877 print("********************")
1878 1878 print("********************")
1879 1879 print("SETUP WEATHER PLOT")
1880 1880 self.ncols = 1
1881 1881 self.nrows = 1
1882 1882 self.nplots= 1
1883 1883 self.ylabel= 'Range [Km]'
1884 1884 self.titles= ['Weather']
1885 1885 if self.channels is not None:
1886 1886 self.nplots = len(self.channels)
1887 1887 self.nrows = len(self.channels)
1888 1888 else:
1889 1889 self.nplots = self.data.shape(self.CODE)[0]
1890 1890 self.nrows = self.nplots
1891 1891 self.channels = list(range(self.nplots))
1892 1892 print("channels",self.channels)
1893 1893 print("que saldra", self.data.shape(self.CODE)[0])
1894 1894 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1895 1895 print("self.titles",self.titles)
1896 1896 self.colorbar=False
1897 1897 self.width =8
1898 1898 self.height =8
1899 1899 self.ini =0
1900 1900 self.len_azi =0
1901 1901 self.buffer_ini = None
1902 1902 self.buffer_ele = None
1903 1903 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1904 1904 self.flag =0
1905 1905 self.indicador= 0
1906 1906 self.last_data_ele = None
1907 1907 self.val_mean = None
1908 1908
1909 1909 def update(self, dataOut):
1910 1910
1911 1911 data = {}
1912 1912 meta = {}
1913 1913 if hasattr(dataOut, 'dataPP_POWER'):
1914 1914 factor = 1
1915 1915 if hasattr(dataOut, 'nFFTPoints'):
1916 1916 factor = dataOut.normFactor
1917 1917 print("dataOut",dataOut.data_360.shape)
1918 1918 #
1919 1919 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1920 1920 #
1921 1921 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1922 1922 data['azi'] = dataOut.data_azi
1923 1923 data['ele'] = dataOut.data_ele
1924 1924 #data['case_flag'] = dataOut.case_flag
1925 1925 #print("UPDATE")
1926 1926 #print("data[weather]",data['weather'].shape)
1927 1927 #print("data[azi]",data['azi'])
1928 1928 return data, meta
1929 1929
1930 1930 def get2List(self,angulos):
1931 1931 list1=[]
1932 1932 list2=[]
1933 1933 for i in reversed(range(len(angulos))):
1934 1934 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1935 1935 diff_ = angulos[i]-angulos[i-1]
1936 1936 if abs(diff_) >1.5:
1937 1937 list1.append(i-1)
1938 1938 list2.append(diff_)
1939 1939 return list(reversed(list1)),list(reversed(list2))
1940 1940
1941 1941 def fixData90(self,list_,ang_):
1942 1942 if list_[0]==-1:
1943 1943 vec = numpy.where(ang_<ang_[0])
1944 1944 ang_[vec] = ang_[vec]+90
1945 1945 return ang_
1946 1946 return ang_
1947 1947
1948 1948 def fixData90HL(self,angulos):
1949 1949 vec = numpy.where(angulos>=90)
1950 1950 angulos[vec]=angulos[vec]-90
1951 1951 return angulos
1952 1952
1953 1953
1954 1954 def search_pos(self,pos,list_):
1955 1955 for i in range(len(list_)):
1956 1956 if pos == list_[i]:
1957 1957 return True,i
1958 1958 i=None
1959 1959 return False,i
1960 1960
1961 1961 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1962 1962 size = len(ang_)
1963 1963 size2 = 0
1964 1964 for i in range(len(list2_)):
1965 1965 size2=size2+round(abs(list2_[i]))-1
1966 1966 new_size= size+size2
1967 1967 ang_new = numpy.zeros(new_size)
1968 1968 ang_new2 = numpy.zeros(new_size)
1969 1969
1970 1970 tmp = 0
1971 1971 c = 0
1972 1972 for i in range(len(ang_)):
1973 1973 ang_new[tmp +c] = ang_[i]
1974 1974 ang_new2[tmp+c] = ang_[i]
1975 1975 condition , value = self.search_pos(i,list1_)
1976 1976 if condition:
1977 1977 pos = tmp + c + 1
1978 1978 for k in range(round(abs(list2_[value]))-1):
1979 1979 if tipo_case==0 or tipo_case==3:#subida
1980 1980 ang_new[pos+k] = ang_new[pos+k-1]+1
1981 1981 ang_new2[pos+k] = numpy.nan
1982 1982 elif tipo_case==1 or tipo_case==2:#bajada
1983 1983 ang_new[pos+k] = ang_new[pos+k-1]-1
1984 1984 ang_new2[pos+k] = numpy.nan
1985 1985
1986 1986 tmp = pos +k
1987 1987 c = 0
1988 1988 c=c+1
1989 1989 return ang_new,ang_new2
1990 1990
1991 1991 def globalCheckPED(self,angulos,tipo_case):
1992 1992 l1,l2 = self.get2List(angulos)
1993 1993 ##print("l1",l1)
1994 1994 ##print("l2",l2)
1995 1995 if len(l1)>0:
1996 1996 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1997 1997 #l1,l2 = self.get2List(angulos2)
1998 1998 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1999 1999 #ang1_ = self.fixData90HL(ang1_)
2000 2000 #ang2_ = self.fixData90HL(ang2_)
2001 2001 else:
2002 2002 ang1_= angulos
2003 2003 ang2_= angulos
2004 2004 return ang1_,ang2_
2005 2005
2006 2006
2007 2007 def replaceNAN(self,data_weather,data_ele,val):
2008 2008 data= data_ele
2009 2009 data_T= data_weather
2010 2010
2011 2011 if data.shape[0]> data_T.shape[0]:
2012 2012 print("IF")
2013 2013 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
2014 2014 c = 0
2015 2015 for i in range(len(data)):
2016 2016 if numpy.isnan(data[i]):
2017 2017 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
2018 2018 else:
2019 2019 data_N[i,:]=data_T[c,:]
2020 2020 c=c+1
2021 2021 return data_N
2022 2022 else:
2023 2023 print("else")
2024 2024 for i in range(len(data)):
2025 2025 if numpy.isnan(data[i]):
2026 2026 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
2027 2027 return data_T
2028 2028
2029 2029 def check_case(self,data_ele,ang_max,ang_min):
2030 2030 start = data_ele[0]
2031 2031 end = data_ele[-1]
2032 2032 number = (end-start)
2033 2033 len_ang=len(data_ele)
2034 2034 print("start",start)
2035 2035 print("end",end)
2036 2036 print("number",number)
2037 2037
2038 2038 print("len_ang",len_ang)
2039 2039
2040 2040 #exit(1)
2041 2041
2042 2042 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
2043 2043 return 0
2044 2044 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
2045 2045 # return 1
2046 2046 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
2047 2047 return 1
2048 2048 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
2049 2049 return 2
2050 2050 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
2051 2051 return 3
2052 2052
2053 2053
2054 2054 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
2055 2055 ang_max= ang_max
2056 2056 ang_min= ang_min
2057 2057 data_weather=data_weather
2058 2058 val_ch=val_ch
2059 2059 ##print("*********************DATA WEATHER**************************************")
2060 2060 ##print(data_weather)
2061 2061 if self.ini==0:
2062 2062
2063 2063 #--------------------- new -------------------------
2064 2064 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
2065 2065
2066 2066 #-------------------------CAMBIOS RHI---------------------------------
2067 2067 start= ang_min
2068 2068 end = ang_max
2069 2069 n= (ang_max-ang_min)/res
2070 2070 #------ new
2071 2071 self.start_data_ele = data_ele_new[0]
2072 2072 self.end_data_ele = data_ele_new[-1]
2073 2073 if tipo_case==0 or tipo_case==3: # SUBIDA
2074 2074 n1= round(self.start_data_ele)- start
2075 2075 n2= end - round(self.end_data_ele)
2076 2076 print(self.start_data_ele)
2077 2077 print(self.end_data_ele)
2078 2078 if n1>0:
2079 2079 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
2080 2080 ele1_nan= numpy.ones(n1)*numpy.nan
2081 2081 data_ele = numpy.hstack((ele1,data_ele_new))
2082 2082 print("ele1_nan",ele1_nan.shape)
2083 2083 print("data_ele_old",data_ele_old.shape)
2084 2084 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
2085 2085 if n2>0:
2086 2086 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
2087 2087 ele2_nan= numpy.ones(n2)*numpy.nan
2088 2088 data_ele = numpy.hstack((data_ele,ele2))
2089 2089 print("ele2_nan",ele2_nan.shape)
2090 2090 print("data_ele_old",data_ele_old.shape)
2091 2091 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
2092 2092
2093 2093 if tipo_case==1 or tipo_case==2: # BAJADA
2094 2094 data_ele_new = data_ele_new[::-1] # reversa
2095 2095 data_ele_old = data_ele_old[::-1]# reversa
2096 2096 data_weather = data_weather[::-1,:]# reversa
2097 2097 vec= numpy.where(data_ele_new<ang_max)
2098 2098 data_ele_new = data_ele_new[vec]
2099 2099 data_ele_old = data_ele_old[vec]
2100 2100 data_weather = data_weather[vec[0]]
2101 2101 vec2= numpy.where(0<data_ele_new)
2102 2102 data_ele_new = data_ele_new[vec2]
2103 2103 data_ele_old = data_ele_old[vec2]
2104 2104 data_weather = data_weather[vec2[0]]
2105 2105 self.start_data_ele = data_ele_new[0]
2106 2106 self.end_data_ele = data_ele_new[-1]
2107 2107
2108 2108 n1= round(self.start_data_ele)- start
2109 2109 n2= end - round(self.end_data_ele)-1
2110 2110 print(self.start_data_ele)
2111 2111 print(self.end_data_ele)
2112 2112 if n1>0:
2113 2113 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
2114 2114 ele1_nan= numpy.ones(n1)*numpy.nan
2115 2115 data_ele = numpy.hstack((ele1,data_ele_new))
2116 2116 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
2117 2117 if n2>0:
2118 2118 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
2119 2119 ele2_nan= numpy.ones(n2)*numpy.nan
2120 2120 data_ele = numpy.hstack((data_ele,ele2))
2121 2121 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
2122 2122 # RADAR
2123 2123 # NOTA data_ele y data_weather es la variable que retorna
2124 2124 val_mean = numpy.mean(data_weather[:,-1])
2125 2125 self.val_mean = val_mean
2126 2126 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
2127 2127 print("eleold",data_ele_old)
2128 2128 print(self.data_ele_tmp[val_ch])
2129 2129 print(data_ele_old.shape[0])
2130 2130 print(self.data_ele_tmp[val_ch].shape[0])
2131 2131 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
2132 2132 import sys
2133 2133 print("EXIT",self.ini)
2134 2134
2135 2135 sys.exit(1)
2136 2136 self.data_ele_tmp[val_ch]= data_ele_old
2137 2137 else:
2138 2138 #print("**********************************************")
2139 2139 #print("****************VARIABLE**********************")
2140 2140 #-------------------------CAMBIOS RHI---------------------------------
2141 2141 #---------------------------------------------------------------------
2142 2142 ##print("INPUT data_ele",data_ele)
2143 2143 flag=0
2144 2144 start_ele = self.res_ele[0]
2145 2145 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
2146 2146 tipo_case = case_flag[-1]
2147 2147 #print("TIPO DE DATA",tipo_case)
2148 2148 #-----------new------------
2149 2149 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
2150 2150 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
2151 2151
2152 2152 #-------------------------------NEW RHI ITERATIVO-------------------------
2153 2153
2154 2154 if tipo_case==0 : # SUBIDA
2155 2155 vec = numpy.where(data_ele<ang_max)
2156 2156 data_ele = data_ele[vec]
2157 2157 data_ele_old = data_ele_old[vec]
2158 2158 data_weather = data_weather[vec[0]]
2159 2159
2160 2160 vec2 = numpy.where(0<data_ele)
2161 2161 data_ele= data_ele[vec2]
2162 2162 data_ele_old= data_ele_old[vec2]
2163 2163 ##print(data_ele_new)
2164 2164 data_weather= data_weather[vec2[0]]
2165 2165
2166 2166 new_i_ele = int(round(data_ele[0]))
2167 2167 new_f_ele = int(round(data_ele[-1]))
2168 2168 #print(new_i_ele)
2169 2169 #print(new_f_ele)
2170 2170 #print(data_ele,len(data_ele))
2171 2171 #print(data_ele_old,len(data_ele_old))
2172 2172 if new_i_ele< 2:
2173 2173 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
2174 2174 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
2175 2175 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
2176 2176 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
2177 2177 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
2178 2178 data_ele = self.res_ele
2179 2179 data_weather = self.res_weather[val_ch]
2180 2180
2181 2181 elif tipo_case==1 : #BAJADA
2182 2182 data_ele = data_ele[::-1] # reversa
2183 2183 data_ele_old = data_ele_old[::-1]# reversa
2184 2184 data_weather = data_weather[::-1,:]# reversa
2185 2185 vec= numpy.where(data_ele<ang_max)
2186 2186 data_ele = data_ele[vec]
2187 2187 data_ele_old = data_ele_old[vec]
2188 2188 data_weather = data_weather[vec[0]]
2189 2189 vec2= numpy.where(0<data_ele)
2190 2190 data_ele = data_ele[vec2]
2191 2191 data_ele_old = data_ele_old[vec2]
2192 2192 data_weather = data_weather[vec2[0]]
2193 2193
2194 2194
2195 2195 new_i_ele = int(round(data_ele[0]))
2196 2196 new_f_ele = int(round(data_ele[-1]))
2197 2197 #print(data_ele)
2198 2198 #print(ang_max)
2199 2199 #print(data_ele_old)
2200 2200 if new_i_ele <= 1:
2201 2201 new_i_ele = 1
2202 2202 if round(data_ele[-1])>=ang_max-1:
2203 2203 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
2204 2204 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
2205 2205 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
2206 2206 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
2207 2207 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
2208 2208 data_ele = self.res_ele
2209 2209 data_weather = self.res_weather[val_ch]
2210 2210
2211 2211 elif tipo_case==2: #bajada
2212 2212 vec = numpy.where(data_ele<ang_max)
2213 2213 data_ele = data_ele[vec]
2214 2214 data_weather= data_weather[vec[0]]
2215 2215
2216 2216 len_vec = len(vec)
2217 2217 data_ele_new = data_ele[::-1] # reversa
2218 2218 data_weather = data_weather[::-1,:]
2219 2219 new_i_ele = int(data_ele_new[0])
2220 2220 new_f_ele = int(data_ele_new[-1])
2221 2221
2222 2222 n1= new_i_ele- ang_min
2223 2223 n2= ang_max - new_f_ele-1
2224 2224 if n1>0:
2225 2225 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
2226 2226 ele1_nan= numpy.ones(n1)*numpy.nan
2227 2227 data_ele = numpy.hstack((ele1,data_ele_new))
2228 2228 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
2229 2229 if n2>0:
2230 2230 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
2231 2231 ele2_nan= numpy.ones(n2)*numpy.nan
2232 2232 data_ele = numpy.hstack((data_ele,ele2))
2233 2233 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
2234 2234
2235 2235 self.data_ele_tmp[val_ch] = data_ele_old
2236 2236 self.res_ele = data_ele
2237 2237 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
2238 2238 data_ele = self.res_ele
2239 2239 data_weather = self.res_weather[val_ch]
2240 2240
2241 2241 elif tipo_case==3:#subida
2242 2242 vec = numpy.where(0<data_ele)
2243 2243 data_ele= data_ele[vec]
2244 2244 data_ele_new = data_ele
2245 2245 data_ele_old= data_ele_old[vec]
2246 2246 data_weather= data_weather[vec[0]]
2247 2247 pos_ini = numpy.argmin(data_ele)
2248 2248 if pos_ini>0:
2249 2249 len_vec= len(data_ele)
2250 2250 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
2251 2251 #print(vec3)
2252 2252 data_ele= data_ele[vec3]
2253 2253 data_ele_new = data_ele
2254 2254 data_ele_old= data_ele_old[vec3]
2255 2255 data_weather= data_weather[vec3]
2256 2256
2257 2257 new_i_ele = int(data_ele_new[0])
2258 2258 new_f_ele = int(data_ele_new[-1])
2259 2259 n1= new_i_ele- ang_min
2260 2260 n2= ang_max - new_f_ele-1
2261 2261 if n1>0:
2262 2262 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
2263 2263 ele1_nan= numpy.ones(n1)*numpy.nan
2264 2264 data_ele = numpy.hstack((ele1,data_ele_new))
2265 2265 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
2266 2266 if n2>0:
2267 2267 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
2268 2268 ele2_nan= numpy.ones(n2)*numpy.nan
2269 2269 data_ele = numpy.hstack((data_ele,ele2))
2270 2270 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
2271 2271
2272 2272 self.data_ele_tmp[val_ch] = data_ele_old
2273 2273 self.res_ele = data_ele
2274 2274 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
2275 2275 data_ele = self.res_ele
2276 2276 data_weather = self.res_weather[val_ch]
2277 2277 #print("self.data_ele_tmp",self.data_ele_tmp)
2278 2278 return data_weather,data_ele
2279 2279
2280 2280 def const_ploteo_vRF(self,val_ch,data_weather,data_ele,res,ang_max,ang_min):
2281 2281
2282 2282 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,1)
2283 2283
2284 2284 data_ele = data_ele_old.copy()
2285 2285
2286 2286 diff_1 = ang_max - data_ele[0]
2287 2287 angles_1_nan = numpy.linspace(ang_max,data_ele[0]+1,int(diff_1)-1)#*numpy.nan
2288 2288
2289 2289 diff_2 = data_ele[-1]-ang_min
2290 2290 angles_2_nan = numpy.linspace(data_ele[-1]-1,ang_min,int(diff_2)-1)#*numpy.nan
2291 2291
2292 2292 angles_filled = numpy.concatenate((angles_1_nan,data_ele,angles_2_nan))
2293 2293
2294 2294 print(angles_filled)
2295 2295
2296 2296 data_1_nan = numpy.ones([angles_1_nan.shape[0],len(self.r_mask)])*numpy.nan
2297 2297 data_2_nan = numpy.ones([angles_2_nan.shape[0],len(self.r_mask)])*numpy.nan
2298 2298
2299 2299 data_filled = numpy.concatenate((data_1_nan,data_weather,data_2_nan),axis=0)
2300 2300 #val_mean = numpy.mean(data_weather[:,-1])
2301 2301 #self.val_mean = val_mean
2302 2302 print(data_filled)
2303 2303 data_filled = self.replaceNAN(data_weather=data_filled,data_ele=angles_filled,val=numpy.nan)
2304 2304
2305 2305 print(data_filled)
2306 2306 print(data_filled.shape)
2307 2307 print(angles_filled.shape)
2308 2308
2309 2309 return data_filled,angles_filled
2310 2310
2311 2311 def plot(self):
2312 2312 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
2313 2313 data = self.data[-1]
2314 2314 r = self.data.yrange
2315 2315 delta_height = r[1]-r[0]
2316 2316 r_mask = numpy.where(r>=0)[0]
2317 2317 self.r_mask =r_mask
2318 2318 ##print("delta_height",delta_height)
2319 2319 #print("r_mask",r_mask,len(r_mask))
2320 2320 r = numpy.arange(len(r_mask))*delta_height
2321 2321 self.y = 2*r
2322 2322 res = 1
2323 2323 ###print("data['weather'].shape[0]",data['weather'].shape[0])
2324 2324 ang_max = self.ang_max
2325 2325 ang_min = self.ang_min
2326 2326 var_ang =ang_max - ang_min
2327 2327 step = (int(var_ang)/(res*data['weather'].shape[0]))
2328 2328 ###print("step",step)
2329 2329 #--------------------------------------------------------
2330 2330 ##print('weather',data['weather'].shape)
2331 2331 ##print('ele',data['ele'].shape)
2332 2332
2333 2333 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
2334 2334 ###self.res_azi = numpy.mean(data['azi'])
2335 2335 ###print("self.res_ele",self.res_ele)
2336 2336
2337 2337 plt.clf()
2338 2338 subplots = [121, 122]
2339 2339 #if self.ini==0:
2340 2340 #self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
2341 2341 #print("SHAPE",self.data_ele_tmp.shape)
2342 2342
2343 2343 for i,ax in enumerate(self.axes):
2344 2344 res_weather, self.res_ele = self.const_ploteo_vRF(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],res=res,ang_max=ang_max,ang_min=ang_min)
2345 2345 self.res_azi = numpy.mean(data['azi'])
2346 2346
2347 2347 if ax.firsttime:
2348 2348 #plt.clf()
2349 2349 print("Frist Plot")
2350 2350 print(data['weather'][i][:,r_mask].shape)
2351 2351 print(data['ele'].shape)
2352 2352 cgax, pm = wrl.vis.plot_rhi(res_weather,r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
2353 2353 #cgax, pm = wrl.vis.plot_rhi(data['weather'][i][:,r_mask],r=r,th=data['ele'],ax=subplots[i], proj='cg',vmin=20, vmax=80)
2354 2354 gh = cgax.get_grid_helper()
2355 2355 locs = numpy.linspace(ang_min,ang_max,var_ang+1)
2356 2356 gh.grid_finder.grid_locator1 = FixedLocator(locs)
2357 2357 gh.grid_finder.tick_formatter1 = DictFormatter(dict([(i, r"${0:.0f}^\circ$".format(i)) for i in locs]))
2358 2358
2359 2359
2360 2360 #fig=self.figures[0]
2361 2361 else:
2362 2362 #plt.clf()
2363 2363 print("ELSE PLOT")
2364 2364 cgax, pm = wrl.vis.plot_rhi(res_weather,r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
2365 2365 #cgax, pm = wrl.vis.plot_rhi(data['weather'][i][:,r_mask],r=r,th=data['ele'],ax=subplots[i], proj='cg',vmin=20, vmax=80)
2366 2366 gh = cgax.get_grid_helper()
2367 2367 locs = numpy.linspace(ang_min,ang_max,var_ang+1)
2368 2368 gh.grid_finder.grid_locator1 = FixedLocator(locs)
2369 2369 gh.grid_finder.tick_formatter1 = DictFormatter(dict([(i, r"${0:.0f}^\circ$".format(i)) for i in locs]))
2370 2370
2371 2371 caax = cgax.parasites[0]
2372 2372 paax = cgax.parasites[1]
2373 2373 cbar = plt.gcf().colorbar(pm, pad=0.075)
2374 2374 caax.set_xlabel('x_range [km]')
2375 2375 caax.set_ylabel('y_range [km]')
2376 2376 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
2377 2377 print("***************************self.ini****************************",self.ini)
2378 2378 self.ini= self.ini+1
2379
2380 class WeatherRHI_vRF4_Plot(Plot):
2381 CODE = 'weather'
2382 plot_name = 'weather'
2383 #plot_type = 'rhistyle'
2384 buffering = False
2385 data_ele_tmp = None
2386
2387 def setup(self):
2388
2389 self.ncols = 1
2390 self.nrows = 1
2391 self.nplots= 1
2392 self.ylabel= 'Range [Km]'
2393 self.titles= ['Weather']
2394 self.polar = True
2395 if self.channels is not None:
2396 self.nplots = len(self.channels)
2397 self.nrows = len(self.channels)
2398 else:
2399 self.nplots = self.data.shape(self.CODE)[0]
2400 self.nrows = self.nplots
2401 self.channels = list(range(self.nplots))
2402 #print("JERE")
2403 #exit(1)
2404 #print("channels",self.channels)
2405 #print("que saldra", self.data.shape(self.CODE)[0])
2406 #self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
2407
2408 #print("self.titles",self.titles)
2409 if self.CODE == 'Power':
2410 self.cb_label = r'Power (dB)'
2411 elif self.CODE == 'Doppler':
2412 self.cb_label = r'Velocity (m/s)'
2413 self.colorbar=True
2414 self.width =8
2415 self.height =8
2416 self.ini =0
2417 self.len_azi =0
2418 self.buffer_ini = None
2419 self.buffer_ele = None
2420 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
2421 self.flag =0
2422 self.indicador= 0
2423 self.last_data_ele = None
2424 self.val_mean = None
2425
2426 def update(self, dataOut):
2427
2428 if self.mode == 'Power':
2429 self.CODE = 'Power'
2430 elif self.mode == 'Doppler':
2431 self.CODE = 'Doppler'
2432
2433 data = {}
2434 meta = {}
2435 if hasattr(dataOut, 'dataPP_POWER'):
2436 factor = 1
2437 if hasattr(dataOut, 'nFFTPoints'):
2438 factor = dataOut.normFactor
2439
2440 if self.CODE == 'Power':
2441 data[self.CODE] = 10*numpy.log10(dataOut.data_360_Power/(factor))
2442 elif self.CODE == 'Doppler':
2443 data[self.CODE] = dataOut.data_360_Velocity/(factor)
2444
2445 data['azi'] = dataOut.data_azi
2446 data['ele'] = dataOut.data_ele
2447
2448 return data, meta
2449
2450 def plot(self):
2451 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
2452 data = self.data[-1]
2453 r = self.data.yrange
2454 delta_height = r[1]-r[0]
2455 r_mask = numpy.where(r>=0)[0]
2456 self.r_mask =r_mask
2457 r = numpy.arange(len(r_mask))*delta_height
2458 self.y = 2*r
2459 res = 1
2460 ang_max = self.ang_max
2461 ang_min = self.ang_min
2462 var_ang =ang_max - ang_min
2463 step = (int(var_ang)/(res*data[self.CODE].shape[0]))
2464
2465 z = data[self.CODE][self.channels[0]][:,r_mask]
2466
2467 #print(z[2,:])
2468 self.titles = []
2469
2470 #exit(1)
2471
2472 if self.CODE == 'Power':
2473 cmap = 'jet'
2474 elif self.CODE == 'Doppler':
2475 cmap = 'RdBu'
2476
2477 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
2478 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
2479 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
2480 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
2481
2482 #plt.clf()
2483 subplots = [121, 122]
2484
2485 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
2486
2487 points_cb = 200
2488 mylevs_cbar = list(numpy.linspace(self.zmin,self.zmax,points_cb)) #niveles de la barra de colores
2489
2490 for i,ax in enumerate(self.axes):
2491
2492 if ax.firsttime:
2493 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
2494 ax.plt = ax.contourf(theta, r, z, points_cb, cmap=cmap, vmin=self.zmin, vmax=self.zmax, levels=mylevs_cbar)
2495 #print(ax.plt)
2496 #exit(1)
2497 '''
2498 self.figures[-1].colorbar(plt, orientation="vertical", fraction=0.025, pad=0.07)
2499 print(self.figures[0])
2500 print(self.figures)
2501 print(plt)
2502 print(ax)
2503 exit(1)
2504 '''
2505
2506 else:
2507 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
2508 ax.plt = ax.contourf(theta, r, z, points_cb, cmap=cmap, vmin=self.zmin, vmax=self.zmax, levels=mylevs_cbar)
2509 #self.figures[0].colorbar(plt, orientation="vertical", fraction=0.025, pad=0.07)
2510
2511 #print(self.titles)
2512 if len(self.channels) !=1:
2513 self.titles = ['{} Azi: {} Channel {}'.format(self.CODE.upper(), str(round(numpy.mean(data['azi']),2)), x) for x in range(self.nrows)]
2514 else:
2515 self.titles = ['{} Azi: {} Channel {}'.format(self.CODE.upper(), str(round(numpy.mean(data['azi']),2)), self.channels[0])]
2516 #self.titles.append('Azi: {}'.format(str(round(numpy.mean(data['azi']),2))))
2517 #self.titles.append(str(round(numpy.mean(data['azi']),2)))
2518 #print(self.titles)
2519 #plt.text(1.0, 1.05, str(thisDatetime)+ " Azi: "+str(round(numpy.mean(data['azi']),2)), transform=caax.transAxes, va='bottom',ha='right')
2520 #print("***************************self.ini****************************",self.ini)
2521 #self.figures[-1].colorbar(plt, orientation="vertical", fraction=0.025, pad=0.07)
2522 #self.ini= self.ini+1
@@ -1,703 +1,714
1 1 import os
2 2 import time
3 3 import datetime
4 4
5 5 import numpy
6 6 import h5py
7 7
8 8 import schainpy.admin
9 9 from schainpy.model.data.jrodata import *
10 10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
11 11 from schainpy.model.io.jroIO_base import *
12 12 from schainpy.utils import log
13 13
14 14
15 15 class HDFReader(Reader, ProcessingUnit):
16 16 """Processing unit to read HDF5 format files
17 17
18 18 This unit reads HDF5 files created with `HDFWriter` operation contains
19 19 by default two groups Data and Metadata all variables would be saved as `dataOut`
20 20 attributes.
21 21 It is possible to read any HDF5 file by given the structure in the `description`
22 22 parameter, also you can add extra values to metadata with the parameter `extras`.
23 23
24 24 Parameters:
25 25 -----------
26 26 path : str
27 27 Path where files are located.
28 28 startDate : date
29 29 Start date of the files
30 30 endDate : list
31 31 End date of the files
32 32 startTime : time
33 33 Start time of the files
34 34 endTime : time
35 35 End time of the files
36 36 description : dict, optional
37 37 Dictionary with the description of the HDF5 file
38 38 extras : dict, optional
39 39 Dictionary with extra metadata to be be added to `dataOut`
40 40
41 41 Examples
42 42 --------
43 43
44 44 desc = {
45 45 'Data': {
46 46 'data_output': ['u', 'v', 'w'],
47 47 'utctime': 'timestamps',
48 48 } ,
49 49 'Metadata': {
50 50 'heightList': 'heights'
51 51 }
52 52 }
53 53
54 54 desc = {
55 55 'Data': {
56 56 'data_output': 'winds',
57 57 'utctime': 'timestamps'
58 58 },
59 59 'Metadata': {
60 60 'heightList': 'heights'
61 61 }
62 62 }
63 63
64 64 extras = {
65 65 'timeZone': 300
66 66 }
67 67
68 68 reader = project.addReadUnit(
69 69 name='HDFReader',
70 70 path='/path/to/files',
71 71 startDate='2019/01/01',
72 72 endDate='2019/01/31',
73 73 startTime='00:00:00',
74 74 endTime='23:59:59',
75 75 # description=json.dumps(desc),
76 76 # extras=json.dumps(extras),
77 77 )
78 78
79 79 """
80 80
81 81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
82 82
83 83 def __init__(self):
84 84 ProcessingUnit.__init__(self)
85 85 self.dataOut = Parameters()
86 86 self.ext = ".hdf5"
87 87 self.optchar = "D"
88 88 self.meta = {}
89 89 self.data = {}
90 90 self.open_file = h5py.File
91 91 self.open_mode = 'r'
92 92 self.description = {}
93 93 self.extras = {}
94 94 self.filefmt = "*%Y%j***"
95 95 self.folderfmt = "*%Y%j"
96 96 self.utcoffset = 0
97 97
98 98 def setup(self, **kwargs):
99 99
100 100 self.set_kwargs(**kwargs)
101 101 if not self.ext.startswith('.'):
102 102 self.ext = '.{}'.format(self.ext)
103 103
104 104 if self.online:
105 105 log.log("Searching files in online mode...", self.name)
106 106
107 107 for nTries in range(self.nTries):
108 108 fullpath = self.searchFilesOnLine(self.path, self.startDate,
109 109 self.endDate, self.expLabel, self.ext, self.walk,
110 110 self.filefmt, self.folderfmt)
111 111 try:
112 112 fullpath = next(fullpath)
113 113 except:
114 114 fullpath = None
115 115
116 116 if fullpath:
117 117 break
118 118
119 119 log.warning(
120 120 'Waiting {} sec for a valid file in {}: try {} ...'.format(
121 121 self.delay, self.path, nTries + 1),
122 122 self.name)
123 123 time.sleep(self.delay)
124 124
125 125 if not(fullpath):
126 126 raise schainpy.admin.SchainError(
127 127 'There isn\'t any valid file in {}'.format(self.path))
128 128
129 129 pathname, filename = os.path.split(fullpath)
130 130 self.year = int(filename[1:5])
131 131 self.doy = int(filename[5:8])
132 132 self.set = int(filename[8:11]) - 1
133 133 else:
134 134 log.log("Searching files in {}".format(self.path), self.name)
135 135 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
136 136 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
137 137
138 138 self.setNextFile()
139 139
140 140 return
141 141
142 142 def readFirstHeader(self):
143 143 '''Read metadata and data'''
144 144
145 145 self.__readMetadata()
146 146 self.__readData()
147 147 self.__setBlockList()
148 148
149 149 if 'type' in self.meta:
150 150 self.dataOut = eval(self.meta['type'])()
151 151
152 152 for attr in self.meta:
153 153 setattr(self.dataOut, attr, self.meta[attr])
154 154
155 155 self.blockIndex = 0
156 156
157 157 return
158 158
159 159 def __setBlockList(self):
160 160 '''
161 161 Selects the data within the times defined
162 162
163 163 self.fp
164 164 self.startTime
165 165 self.endTime
166 166 self.blockList
167 167 self.blocksPerFile
168 168
169 169 '''
170 170
171 171 startTime = self.startTime
172 172 endTime = self.endTime
173 173 thisUtcTime = self.data['utctime'] + self.utcoffset
174 174 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
175 175 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
176 176
177 177 thisDate = thisDatetime.date()
178 178 thisTime = thisDatetime.time()
179 179
180 180 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
181 181 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
182 182
183 183 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
184 184
185 185 self.blockList = ind
186 186 self.blocksPerFile = len(ind)
187 187 return
188 188
189 189 def __readMetadata(self):
190 190 '''
191 191 Reads Metadata
192 192 '''
193 193
194 194 meta = {}
195 195
196 196 if self.description:
197 197 for key, value in self.description['Metadata'].items():
198 198 meta[key] = self.fp[value][()]
199 199 else:
200 200 grp = self.fp['Metadata']
201 201 for name in grp:
202 202 meta[name] = grp[name][()]
203 203
204 204 if self.extras:
205 205 for key, value in self.extras.items():
206 206 meta[key] = value
207 207 self.meta = meta
208 208
209 209 return
210 210
211 211 def __readData(self):
212 212
213 213 data = {}
214 214
215 215 if self.description:
216 216 for key, value in self.description['Data'].items():
217 217 if isinstance(value, str):
218 218 if isinstance(self.fp[value], h5py.Dataset):
219 219 data[key] = self.fp[value][()]
220 220 elif isinstance(self.fp[value], h5py.Group):
221 221 array = []
222 222 for ch in self.fp[value]:
223 223 array.append(self.fp[value][ch][()])
224 224 data[key] = numpy.array(array)
225 225 elif isinstance(value, list):
226 226 array = []
227 227 for ch in value:
228 228 array.append(self.fp[ch][()])
229 229 data[key] = numpy.array(array)
230 230 else:
231 231 grp = self.fp['Data']
232 232 for name in grp:
233 233 if isinstance(grp[name], h5py.Dataset):
234 234 array = grp[name][()]
235 235 elif isinstance(grp[name], h5py.Group):
236 236 array = []
237 237 for ch in grp[name]:
238 238 array.append(grp[name][ch][()])
239 239 array = numpy.array(array)
240 240 else:
241 241 log.warning('Unknown type: {}'.format(name))
242 242
243 243 if name in self.description:
244 244 key = self.description[name]
245 245 else:
246 246 key = name
247 247 data[key] = array
248 248
249 249 self.data = data
250 250 return
251 251
252 252 def getData(self):
253 253
254 254 for attr in self.data:
255 255 if self.data[attr].ndim == 1:
256 256 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
257 257 else:
258 258 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
259 259
260 260 self.dataOut.flagNoData = False
261 261 self.blockIndex += 1
262 262
263 263 log.log("Block No. {}/{} -> {}".format(
264 264 self.blockIndex,
265 265 self.blocksPerFile,
266 266 self.dataOut.datatime.ctime()), self.name)
267 267
268 268 return
269 269
270 270 def run(self, **kwargs):
271 271
272 272 if not(self.isConfig):
273 273 self.setup(**kwargs)
274 274 self.isConfig = True
275 275
276 276 if self.blockIndex == self.blocksPerFile:
277 277 self.setNextFile()
278 278
279 279 self.getData()
280 280
281 281 return
282 282
283 283 @MPDecorator
284 284 class HDFWriter(Operation):
285 285 """Operation to write HDF5 files.
286 286
287 287 The HDF5 file contains by default two groups Data and Metadata where
288 288 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
289 289 parameters, data attributes are normaly time dependent where the metadata
290 290 are not.
291 291 It is possible to customize the structure of the HDF5 file with the
292 292 optional description parameter see the examples.
293 293
294 294 Parameters:
295 295 -----------
296 296 path : str
297 297 Path where files will be saved.
298 298 blocksPerFile : int
299 299 Number of blocks per file
300 300 metadataList : list
301 301 List of the dataOut attributes that will be saved as metadata
302 302 dataList : int
303 303 List of the dataOut attributes that will be saved as data
304 304 setType : bool
305 305 If True the name of the files corresponds to the timestamp of the data
306 306 description : dict, optional
307 307 Dictionary with the desired description of the HDF5 file
308 308
309 309 Examples
310 310 --------
311 311
312 312 desc = {
313 313 'data_output': {'winds': ['z', 'w', 'v']},
314 314 'utctime': 'timestamps',
315 315 'heightList': 'heights'
316 316 }
317 317 desc = {
318 318 'data_output': ['z', 'w', 'v'],
319 319 'utctime': 'timestamps',
320 320 'heightList': 'heights'
321 321 }
322 322 desc = {
323 323 'Data': {
324 324 'data_output': 'winds',
325 325 'utctime': 'timestamps'
326 326 },
327 327 'Metadata': {
328 328 'heightList': 'heights'
329 329 }
330 330 }
331 331
332 332 writer = proc_unit.addOperation(name='HDFWriter')
333 333 writer.addParameter(name='path', value='/path/to/file')
334 334 writer.addParameter(name='blocksPerFile', value='32')
335 335 writer.addParameter(name='metadataList', value='heightList,timeZone')
336 336 writer.addParameter(name='dataList',value='data_output,utctime')
337 337 # writer.addParameter(name='description',value=json.dumps(desc))
338 338
339 339 """
340 340
341 341 ext = ".hdf5"
342 342 optchar = "D"
343 343 filename = None
344 344 path = None
345 345 setFile = None
346 346 fp = None
347 347 firsttime = True
348 348 #Configurations
349 349 blocksPerFile = None
350 350 blockIndex = None
351 351 dataOut = None
352 352 #Data Arrays
353 353 dataList = None
354 354 metadataList = None
355 355 currentDay = None
356 356 lastTime = None
357 357 last_Azipos = None
358 358 last_Elepos = None
359 359 mode = None
360 360 #-----------------------
361 361 Typename = None
362 362
363 363
364 364
365 365 def __init__(self):
366 366
367 367 Operation.__init__(self)
368 368 return
369 369
370 370
371 371 def set_kwargs(self, **kwargs):
372 372
373 373 for key, value in kwargs.items():
374 374 setattr(self, key, value)
375 375
376 376 def set_kwargs_obj(self,obj, **kwargs):
377 377
378 378 for key, value in kwargs.items():
379 379 setattr(obj, key, value)
380 380
381 381 def generalFlag(self):
382 382 ####rint("GENERALFLAG")
383 383 if self.mode== "weather":
384 384 if self.last_Azipos == None:
385 385 tmp = self.dataOut.azimuth
386 386 ####print("ang azimuth writer",tmp)
387 387 self.last_Azipos = tmp
388 388 flag = False
389 389 return flag
390 390 ####print("ang_azimuth writer",self.dataOut.azimuth)
391 391 result = self.dataOut.azimuth - self.last_Azipos
392 392 self.last_Azipos = self.dataOut.azimuth
393 393 if result<0:
394 394 flag = True
395 395 return flag
396 396
397 def generalFlag_vRF(self):
398 ####rint("GENERALFLAG")
399
400 try:
401 self.dataOut.flagBlock360Done
402 return self.dataOut.flagBlock360Done
403 except:
404 return 0
405
406
397 407 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None, description=None,type_data=None,**kwargs):
398 408 self.path = path
399 409 self.blocksPerFile = blocksPerFile
400 410 self.metadataList = metadataList
401 411 self.dataList = [s.strip() for s in dataList]
412 self.setType = setType
402 413 if self.mode == "weather":
403 414 self.setType = "weather"
404 415 #----------------------------------------
405 416 self.set_kwargs(**kwargs)
406 417 self.set_kwargs_obj(self.dataOut,**kwargs)
407 418 #print("-----------------------------------------------------------",self.Typename)
408 419 #print("hola",self.ContactInformation)
409 420
410 421 self.description = description
411 422 self.type_data=type_data
412 423
413 424 if self.metadataList is None:
414 425 self.metadataList = self.dataOut.metadata_list
415 426
416 427 tableList = []
417 428 dsList = []
418 429
419 430 for i in range(len(self.dataList)):
420 431 dsDict = {}
421 432 if hasattr(self.dataOut, self.dataList[i]):
422 433 dataAux = getattr(self.dataOut, self.dataList[i])
423 434 dsDict['variable'] = self.dataList[i]
424 435 else:
425 436 log.warning('Attribute {} not found in dataOut', self.name)
426 437 continue
427 438
428 439 if dataAux is None:
429 440 continue
430 441 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
431 442 dsDict['nDim'] = 0
432 443 else:
433 444 dsDict['nDim'] = len(dataAux.shape)
434 445 dsDict['shape'] = dataAux.shape
435 446 dsDict['dsNumber'] = dataAux.shape[0]
436 447 dsDict['dtype'] = dataAux.dtype
437 448
438 449 dsList.append(dsDict)
439 450
440 451 self.dsList = dsList
441 452 self.currentDay = self.dataOut.datatime.date()
442 453
443 454 def timeFlag(self):
444 455 currentTime = self.dataOut.utctime
445 456 timeTuple = time.localtime(currentTime)
446 457 dataDay = timeTuple.tm_yday
447 458
448 459 if self.lastTime is None:
449 460 self.lastTime = currentTime
450 461 self.currentDay = dataDay
451 462 return False
452 463
453 464 timeDiff = currentTime - self.lastTime
454 465
455 466 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
456 467 if dataDay != self.currentDay:
457 468 self.currentDay = dataDay
458 469 return True
459 470 elif timeDiff > 3*60*60:
460 471 self.lastTime = currentTime
461 472 return True
462 473 else:
463 474 self.lastTime = currentTime
464 475 return False
465 476
466 477 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
467 478 dataList=[], setType=None, description={},mode= None,type_data=None,**kwargs):
468 479
469 480 ###print("VOY A ESCRIBIR----------------------")
470 481 #print("CHECKTHIS------------------------------------------------------------------*****---",**kwargs)
471 482 self.dataOut = dataOut
472 483 self.mode = mode
473 484 if not(self.isConfig):
474 485 self.setup(path=path, blocksPerFile=blocksPerFile,
475 486 metadataList=metadataList, dataList=dataList,
476 487 setType=setType, description=description,type_data=type_data,**kwargs)
477 488
478 489 self.isConfig = True
479 490 self.setNextFile()
480 491
481 492 self.putData()
482 493 return
483 494
484 495 def setNextFile(self):
485 496 ###print("HELLO WORLD--------------------------------")
486 497 ext = self.ext
487 498 path = self.path
488 499 setFile = self.setFile
489 500 type_data = self.type_data
490 501
491 502 timeTuple = time.localtime(self.dataOut.utctime)
492 503 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
493 504 fullpath = os.path.join(path, subfolder)
494 505
495 506 if os.path.exists(fullpath):
496 507 filesList = os.listdir(fullpath)
497 508 filesList = [k for k in filesList if k.startswith(self.optchar)]
498 509 if len( filesList ) > 0:
499 510 filesList = sorted(filesList, key=str.lower)
500 511 filen = filesList[-1]
501 512 # el filename debera tener el siguiente formato
502 513 # 0 1234 567 89A BCDE (hex)
503 514 # x YYYY DDD SSS .ext
504 515 if isNumber(filen[8:11]):
505 516 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
506 517 else:
507 518 setFile = -1
508 519 else:
509 520 setFile = -1 #inicializo mi contador de seteo
510 521 else:
511 522 os.makedirs(fullpath)
512 523 setFile = -1 #inicializo mi contador de seteo
513 524
514 525 ###print("**************************",self.setType)
515 526 if self.setType is None:
516 527 setFile += 1
517 528 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
518 529 timeTuple.tm_year,
519 530 timeTuple.tm_yday,
520 531 setFile,
521 532 ext )
522 533 elif self.setType == "weather":
523 534 print("HOLA AMIGOS")
524 535 wr_exp = self.dataOut.wr_exp
525 536 if wr_exp== "PPI":
526 537 wr_type = 'E'
527 538 ang_ = numpy.mean(self.dataOut.elevation)
528 539 else:
529 540 wr_type = 'A'
530 541 ang_ = numpy.mean(self.dataOut.azimuth)
531 542
532 543 wr_writer = '%s%s%2.1f%s'%('-',
533 544 wr_type,
534 545 ang_,
535 546 '-')
536 547 ###print("wr_writer********************",wr_writer)
537 548 file = '%s%4.4d%2.2d%2.2d%s%2.2d%2.2d%2.2d%s%s%s' % (self.optchar,
538 549 timeTuple.tm_year,
539 550 timeTuple.tm_mon,
540 551 timeTuple.tm_mday,
541 552 '-',
542 553 timeTuple.tm_hour,
543 554 timeTuple.tm_min,
544 555 timeTuple.tm_sec,
545 556 wr_writer,
546 557 type_data,
547 558 ext )
548 559 ###print("FILENAME", file)
549 560
550 561
551 562 else:
552 563 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
553 564 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
554 565 timeTuple.tm_year,
555 566 timeTuple.tm_yday,
556 567 setFile,
557 568 ext )
558 569
559 570 self.filename = os.path.join( path, subfolder, file )
560 571
561 572 #Setting HDF5 File
562 573
563 574 self.fp = h5py.File(self.filename, 'w')
564 575 #write metadata
565 576 self.writeMetadata(self.fp)
566 577 #Write data
567 578 self.writeData(self.fp)
568 579
569 580 def getLabel(self, name, x=None):
570 581
571 582 if x is None:
572 583 if 'Data' in self.description:
573 584 data = self.description['Data']
574 585 if 'Metadata' in self.description:
575 586 data.update(self.description['Metadata'])
576 587 else:
577 588 data = self.description
578 589 if name in data:
579 590 if isinstance(data[name], str):
580 591 return data[name]
581 592 elif isinstance(data[name], list):
582 593 return None
583 594 elif isinstance(data[name], dict):
584 595 for key, value in data[name].items():
585 596 return key
586 597 return name
587 598 else:
588 599 if 'Metadata' in self.description:
589 600 meta = self.description['Metadata']
590 601 else:
591 602 meta = self.description
592 603 if name in meta:
593 604 if isinstance(meta[name], list):
594 605 return meta[name][x]
595 606 elif isinstance(meta[name], dict):
596 607 for key, value in meta[name].items():
597 608 return value[x]
598 609 if 'cspc' in name:
599 610 return 'pair{:02d}'.format(x)
600 611 else:
601 612 return 'channel{:02d}'.format(x)
602 613
603 614 def writeMetadata(self, fp):
604 615
605 616 if self.description:
606 617 if 'Metadata' in self.description:
607 618 grp = fp.create_group('Metadata')
608 619 else:
609 620 grp = fp
610 621 else:
611 622 grp = fp.create_group('Metadata')
612 623
613 624 for i in range(len(self.metadataList)):
614 625 if not hasattr(self.dataOut, self.metadataList[i]):
615 626 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
616 627 continue
617 628 value = getattr(self.dataOut, self.metadataList[i])
618 629 if isinstance(value, bool):
619 630 if value is True:
620 631 value = 1
621 632 else:
622 633 value = 0
623 634 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
624 635 return
625 636
626 637 def writeData(self, fp):
627
638 print("writing data")
628 639 if self.description:
629 640 if 'Data' in self.description:
630 641 grp = fp.create_group('Data')
631 642 else:
632 643 grp = fp
633 644 else:
634 645 grp = fp.create_group('Data')
635 646
636 647 dtsets = []
637 648 data = []
638 649
639 650 for dsInfo in self.dsList:
640 651 if dsInfo['nDim'] == 0:
641 652 ds = grp.create_dataset(
642 653 self.getLabel(dsInfo['variable']),
643 654 (self.blocksPerFile, ),
644 655 chunks=True,
645 656 dtype=numpy.float64)
646 657 dtsets.append(ds)
647 658 data.append((dsInfo['variable'], -1))
648 659 else:
649 660 label = self.getLabel(dsInfo['variable'])
650 661 if label is not None:
651 662 sgrp = grp.create_group(label)
652 663 else:
653 664 sgrp = grp
654 665 for i in range(dsInfo['dsNumber']):
655 666 ds = sgrp.create_dataset(
656 667 self.getLabel(dsInfo['variable'], i),
657 668 (self.blocksPerFile, ) + dsInfo['shape'][1:],
658 669 chunks=True,
659 670 dtype=dsInfo['dtype'])
660 671 dtsets.append(ds)
661 672 data.append((dsInfo['variable'], i))
662 673 fp.flush()
663 674
664 675 log.log('Creating file: {}'.format(fp.filename), self.name)
665 676
666 677 self.ds = dtsets
667 678 self.data = data
668 679 self.firsttime = True
669 680 self.blockIndex = 0
670 681 return
671 682
672 683 def putData(self):
673 684 ###print("**************************PUT DATA***************************************************")
674 if (self.blockIndex == self.blocksPerFile) or self.timeFlag() or self.generalFlag():
685 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():# or self.generalFlag_vRF():
675 686 self.closeFile()
676 687 self.setNextFile()
677 688
678 689 for i, ds in enumerate(self.ds):
679 690 attr, ch = self.data[i]
680 691 if ch == -1:
681 692 ds[self.blockIndex] = getattr(self.dataOut, attr)
682 693 else:
683 694 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
684 695
685 696 self.fp.flush()
686 697 self.blockIndex += 1
687 698 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
688 699
689 700 return
690 701
691 702 def closeFile(self):
692 703
693 704 if self.blockIndex != self.blocksPerFile:
694 705 for ds in self.ds:
695 706 ds.resize(self.blockIndex, axis=0)
696 707
697 708 if self.fp:
698 709 self.fp.flush()
699 710 self.fp.close()
700 711
701 712 def close(self):
702 713
703 714 self.closeFile()
@@ -1,206 +1,208
1 1 '''
2 2 Base clases to create Processing units and operations, the MPDecorator
3 3 must be used in plotting and writing operations to allow to run as an
4 4 external process.
5 5 '''
6 6
7 import os
7 8 import inspect
8 9 import zmq
9 10 import time
10 11 import pickle
11 12 import traceback
12 13 from threading import Thread
13 14 from multiprocessing import Process, Queue
14 15 from schainpy.utils import log
15 16
17 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
16 18
17 19 class ProcessingUnit(object):
18 20 '''
19 21 Base class to create Signal Chain Units
20 22 '''
21 23
22 24 proc_type = 'processing'
23 25
24 26 def __init__(self):
25 27
26 28 self.dataIn = None
27 29 self.dataOut = None
28 30 self.isConfig = False
29 31 self.operations = []
30 32
31 33 def setInput(self, unit):
32 34
33 35 self.dataIn = unit.dataOut
34 36
35 37 def getAllowedArgs(self):
36 38 if hasattr(self, '__attrs__'):
37 39 return self.__attrs__
38 40 else:
39 41 return inspect.getargspec(self.run).args
40 42
41 43 def addOperation(self, conf, operation):
42 44 '''
43 45 '''
44 46
45 47 self.operations.append((operation, conf.type, conf.getKwargs()))
46 48
47 49 def getOperationObj(self, objId):
48 50
49 51 if objId not in list(self.operations.keys()):
50 52 return None
51 53
52 54 return self.operations[objId]
53 55
54 56 def call(self, **kwargs):
55 57 '''
56 58 '''
57 59
58 60 try:
59 61 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
60 62 return self.dataIn.isReady()
61 63 elif self.dataIn is None or not self.dataIn.error:
62 64 self.run(**kwargs)
63 65 elif self.dataIn.error:
64 66 self.dataOut.error = self.dataIn.error
65 67 self.dataOut.flagNoData = True
66 68 except:
67 69 err = traceback.format_exc()
68 70 if 'SchainWarning' in err:
69 71 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
70 72 elif 'SchainError' in err:
71 73 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
72 74 else:
73 75 log.error(err, self.name)
74 76 self.dataOut.error = True
75 77 ##### correcion de la declaracion Out
76 78 for op, optype, opkwargs in self.operations:
77 79 aux = self.dataOut.copy()
78 80 if optype == 'other' and not self.dataOut.flagNoData:
79 81 self.dataOut = op.run(self.dataOut, **opkwargs)
80 82 elif optype == 'external' and not self.dataOut.flagNoData:
81 83 #op.queue.put(self.dataOut)
82 84 op.queue.put(aux)
83 85 elif optype == 'external' and self.dataOut.error:
84 86 #op.queue.put(self.dataOut)
85 87 op.queue.put(aux)
86 88
87 89 return 'Error' if self.dataOut.error else self.dataOut.isReady()
88 90
89 91 def setup(self):
90 92
91 93 raise NotImplementedError
92 94
93 95 def run(self):
94 96
95 97 raise NotImplementedError
96 98
97 99 def close(self):
98 100
99 101 return
100 102
101 103
102 104 class Operation(object):
103 105
104 106 '''
105 107 '''
106 108
107 109 proc_type = 'operation'
108 110
109 111 def __init__(self):
110 112
111 113 self.id = None
112 114 self.isConfig = False
113 115
114 116 if not hasattr(self, 'name'):
115 117 self.name = self.__class__.__name__
116 118
117 119 def getAllowedArgs(self):
118 120 if hasattr(self, '__attrs__'):
119 121 return self.__attrs__
120 122 else:
121 123 return inspect.getargspec(self.run).args
122 124
123 125 def setup(self):
124 126
125 127 self.isConfig = True
126 128
127 129 raise NotImplementedError
128 130
129 131 def run(self, dataIn, **kwargs):
130 132 """
131 133 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
132 134 atributos del objeto dataIn.
133 135
134 136 Input:
135 137
136 138 dataIn : objeto del tipo JROData
137 139
138 140 Return:
139 141
140 142 None
141 143
142 144 Affected:
143 145 __buffer : buffer de recepcion de datos.
144 146
145 147 """
146 148 if not self.isConfig:
147 149 self.setup(**kwargs)
148 150
149 151 raise NotImplementedError
150 152
151 153 def close(self):
152 154
153 155 return
154 156
155 157
156 158 def MPDecorator(BaseClass):
157 159 """
158 160 Multiprocessing class decorator
159 161
160 162 This function add multiprocessing features to a BaseClass.
161 163 """
162 164
163 165 class MPClass(BaseClass, Process):
164 166
165 167 def __init__(self, *args, **kwargs):
166 168 super(MPClass, self).__init__()
167 169 Process.__init__(self)
168 170
169 171 self.args = args
170 172 self.kwargs = kwargs
171 173 self.t = time.time()
172 174 self.op_type = 'external'
173 175 self.name = BaseClass.__name__
174 176 self.__doc__ = BaseClass.__doc__
175 177
176 178 if 'plot' in self.name.lower() and not self.name.endswith('_'):
177 179 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
178 180
179 181 self.start_time = time.time()
180 182 self.err_queue = args[3]
181 self.queue = Queue(maxsize=1)
183 self.queue = Queue(maxsize=QUEUE_SIZE)
182 184 self.myrun = BaseClass.run
183 185
184 186 def run(self):
185 187
186 188 while True:
187 189
188 190 dataOut = self.queue.get()
189 191
190 192 if not dataOut.error:
191 193 try:
192 194 BaseClass.run(self, dataOut, **self.kwargs)
193 195 except:
194 196 err = traceback.format_exc()
195 197 log.error(err, self.name)
196 198 else:
197 199 break
198 200
199 201 self.close()
200 202
201 203 def close(self):
202 204
203 205 BaseClass.close(self)
204 206 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
205 207
206 208 return MPClass
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now