##// END OF EJS Templates
Fix Z colormap
Juan C. Espinoza -
r1487:35a8c79c6f91
parent child
Show More
@@ -1,732 +1,732
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,re
19 19
20 20 if 'BACKEND' in os.environ:
21 21 matplotlib.use(os.environ['BACKEND'])
22 22 elif 'linux' in sys.platform:
23 matplotlib.use("Agg")#TkAgg
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 .plotting_codes import *
37 37
38 38 from schainpy.model.data.jrodata import PlotterData
39 39 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
40 40 from schainpy.utils import log
41 41
42 42 for name, cb_table in sophy_cb_tables:
43 43 ncmap = matplotlib.colors.ListedColormap(cb_table, name=name)
44 44 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 45
46 46 EARTH_RADIUS = 6.3710e3
47 47
48 48 def ll2xy(lat1, lon1, lat2, lon2):
49 49
50 50 p = 0.017453292519943295
51 51 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
52 52 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
53 53 r = 12742 * numpy.arcsin(numpy.sqrt(a))
54 54 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
55 55 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
56 56 theta = -theta + numpy.pi/2
57 57 return r*numpy.cos(theta), r*numpy.sin(theta)
58 58
59 59
60 60 def km2deg(km):
61 61 '''
62 62 Convert distance in km to degrees
63 63 '''
64 64
65 65 return numpy.rad2deg(km/EARTH_RADIUS)
66 66
67 67
68 68 def figpause(interval):
69 69 backend = plt.rcParams['backend']
70 70 if backend in matplotlib.rcsetup.interactive_bk:
71 71 figManager = matplotlib._pylab_helpers.Gcf.get_active()
72 72 if figManager is not None:
73 73 canvas = figManager.canvas
74 74 if canvas.figure.stale:
75 75 canvas.draw()
76 76 try:
77 77 canvas.start_event_loop(interval)
78 78 except:
79 79 pass
80 80 return
81 81
82 82 def popup(message):
83 83 '''
84 84 '''
85 85
86 86 fig = plt.figure(figsize=(12, 8), facecolor='r')
87 87 text = '\n'.join([s.strip() for s in message.split(':')])
88 88 fig.text(0.01, 0.5, text, ha='left', va='center',
89 89 size='20', weight='heavy', color='w')
90 90 fig.show()
91 91 figpause(1000)
92 92
93 93
94 94 class Throttle(object):
95 95 '''
96 96 Decorator that prevents a function from being called more than once every
97 97 time period.
98 98 To create a function that cannot be called more than once a minute, but
99 99 will sleep until it can be called:
100 100 @Throttle(minutes=1)
101 101 def foo():
102 102 pass
103 103
104 104 for i in range(10):
105 105 foo()
106 106 print "This function has run %s times." % i
107 107 '''
108 108
109 109 def __init__(self, seconds=0, minutes=0, hours=0):
110 110 self.throttle_period = datetime.timedelta(
111 111 seconds=seconds, minutes=minutes, hours=hours
112 112 )
113 113
114 114 self.time_of_last_call = datetime.datetime.min
115 115
116 116 def __call__(self, fn):
117 117 @wraps(fn)
118 118 def wrapper(*args, **kwargs):
119 119 coerce = kwargs.pop('coerce', None)
120 120 if coerce:
121 121 self.time_of_last_call = datetime.datetime.now()
122 122 return fn(*args, **kwargs)
123 123 else:
124 124 now = datetime.datetime.now()
125 125 time_since_last_call = now - self.time_of_last_call
126 126 time_left = self.throttle_period - time_since_last_call
127 127
128 128 if time_left > datetime.timedelta(seconds=0):
129 129 return
130 130
131 131 self.time_of_last_call = datetime.datetime.now()
132 132 return fn(*args, **kwargs)
133 133
134 134 return wrapper
135 135
136 136 def apply_throttle(value):
137 137
138 138 @Throttle(seconds=value)
139 139 def fnThrottled(fn):
140 140 fn()
141 141
142 142 return fnThrottled
143 143
144 144
145 145 @MPDecorator
146 146 class Plot(Operation):
147 147 """Base class for Schain plotting operations
148 148
149 149 This class should never be use directtly you must subclass a new operation,
150 150 children classes must be defined as follow:
151 151
152 152 ExamplePlot(Plot):
153 153
154 154 CODE = 'code'
155 155 colormap = 'jet'
156 156 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
157 157
158 158 def setup(self):
159 159 pass
160 160
161 161 def plot(self):
162 162 pass
163 163
164 164 """
165 165
166 166 CODE = 'Figure'
167 167 colormap = 'jet'
168 168 bgcolor = 'white'
169 169 buffering = True
170 170 __missing = 1E30
171 171
172 172 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
173 173 'showprofile']
174 174
175 175 def __init__(self):
176 176
177 177 Operation.__init__(self)
178 178 self.isConfig = False
179 179 self.isPlotConfig = False
180 180 self.save_time = 0
181 181 self.sender_time = 0
182 182 self.data = None
183 183 self.firsttime = True
184 184 self.sender_queue = deque(maxlen=10)
185 185 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
186 186
187 187 def __fmtTime(self, x, pos):
188 188 '''
189 189 '''
190 190
191 191 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
192 192
193 193 def __setup(self, **kwargs):
194 194 '''
195 195 Initialize variables
196 196 '''
197 197
198 198 self.figures = []
199 199 self.axes = []
200 200 self.cb_axes = []
201 201 self.localtime = kwargs.pop('localtime', True)
202 202 self.show = kwargs.get('show', True)
203 203 self.save = kwargs.get('save', False)
204 204 self.save_period = kwargs.get('save_period', 0)
205 205 self.colormap = kwargs.get('colormap', self.colormap)
206 206 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
207 207 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
208 208 self.colormaps = kwargs.get('colormaps', None)
209 209 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
210 210 self.showprofile = kwargs.get('showprofile', False)
211 211 self.title = kwargs.get('wintitle', self.CODE.upper())
212 212 self.cb_label = kwargs.get('cb_label', None)
213 213 self.cb_labels = kwargs.get('cb_labels', None)
214 214 self.labels = kwargs.get('labels', None)
215 215 self.xaxis = kwargs.get('xaxis', 'frequency')
216 216 self.zmin = kwargs.get('zmin', None)
217 217 self.zmax = kwargs.get('zmax', None)
218 218 self.zlimits = kwargs.get('zlimits', None)
219 219 self.xmin = kwargs.get('xmin', None)
220 220 self.xmax = kwargs.get('xmax', None)
221 221 self.xrange = kwargs.get('xrange', 12)
222 222 self.xscale = kwargs.get('xscale', None)
223 223 self.ymin = kwargs.get('ymin', None)
224 224 self.ymax = kwargs.get('ymax', None)
225 225 self.yscale = kwargs.get('yscale', None)
226 226 self.xlabel = kwargs.get('xlabel', None)
227 227 self.attr_time = kwargs.get('attr_time', 'utctime')
228 228 self.attr_data = kwargs.get('attr_data', 'data_param')
229 229 self.decimation = kwargs.get('decimation', None)
230 230 self.oneFigure = kwargs.get('oneFigure', True)
231 231 self.width = kwargs.get('width', None)
232 232 self.height = kwargs.get('height', None)
233 233 self.colorbar = kwargs.get('colorbar', True)
234 234 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
235 235 self.channels = kwargs.get('channels', None)
236 236 self.titles = kwargs.get('titles', [])
237 237 self.polar = False
238 238 self.type = kwargs.get('type', 'iq')
239 239 self.grid = kwargs.get('grid', False)
240 240 self.pause = kwargs.get('pause', False)
241 241 self.save_code = kwargs.get('save_code', self.CODE)
242 242 self.throttle = kwargs.get('throttle', 0)
243 243 self.exp_code = kwargs.get('exp_code', None)
244 244 self.server = kwargs.get('server', False)
245 245 self.sender_period = kwargs.get('sender_period', 60)
246 246 self.tag = kwargs.get('tag', '')
247 247 self.height_index = kwargs.get('height_index', None)
248 248 self.__throttle_plot = apply_throttle(self.throttle)
249 249 code = self.attr_data if self.attr_data else self.CODE
250 250 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
251 251 self.ang_min = kwargs.get('ang_min', None)
252 252 self.ang_max = kwargs.get('ang_max', None)
253 253 self.mode = kwargs.get('mode', None)
254 254
255 255
256 256
257 257 if self.server:
258 258 if not self.server.startswith('tcp://'):
259 259 self.server = 'tcp://{}'.format(self.server)
260 260 log.success(
261 261 'Sending to server: {}'.format(self.server),
262 262 self.name
263 263 )
264 264
265 265 if isinstance(self.attr_data, str):
266 266 self.attr_data = [self.attr_data]
267 267
268 268 def __setup_plot(self):
269 269 '''
270 270 Common setup for all figures, here figures and axes are created
271 271 '''
272 272
273 273 self.setup()
274 274
275 275 self.time_label = 'LT' if self.localtime else 'UTC'
276 276
277 277 if self.width is None:
278 278 self.width = 8
279 279
280 280 self.figures = []
281 281 self.axes = []
282 282 self.cb_axes = []
283 283 self.pf_axes = []
284 284 self.cmaps = []
285 285
286 286 size = '15%' if self.ncols == 1 else '30%'
287 287 pad = '4%' if self.ncols == 1 else '8%'
288 288
289 289 if self.oneFigure:
290 290 if self.height is None:
291 291 self.height = 1.4 * self.nrows + 1
292 292 fig = plt.figure(figsize=(self.width, self.height),
293 293 edgecolor='k',
294 294 facecolor='w')
295 295 self.figures.append(fig)
296 296 for n in range(self.nplots):
297 297 ax = fig.add_subplot(self.nrows, self.ncols,
298 298 n + 1, polar=self.polar)
299 299 ax.tick_params(labelsize=8)
300 300 ax.firsttime = True
301 301 ax.index = 0
302 302 ax.press = None
303 303 self.axes.append(ax)
304 304 if self.showprofile:
305 305 cax = self.__add_axes(ax, size=size, pad=pad)
306 306 cax.tick_params(labelsize=8)
307 307 self.pf_axes.append(cax)
308 308 else:
309 309 if self.height is None:
310 310 self.height = 3
311 311 for n in range(self.nplots):
312 312 fig = plt.figure(figsize=(self.width, self.height),
313 313 edgecolor='k',
314 314 facecolor='w')
315 315 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
316 316 ax.tick_params(labelsize=8)
317 317 ax.firsttime = True
318 318 ax.index = 0
319 319 ax.press = None
320 320 self.figures.append(fig)
321 321 self.axes.append(ax)
322 322 if self.showprofile:
323 323 cax = self.__add_axes(ax, size=size, pad=pad)
324 324 cax.tick_params(labelsize=8)
325 325 self.pf_axes.append(cax)
326 326
327 327 for n in range(self.nrows):
328 328 if self.colormaps is not None:
329 329 cmap = plt.get_cmap(self.colormaps[n])
330 330 else:
331 331 cmap = plt.get_cmap(self.colormap)
332 332 cmap.set_bad(self.bgcolor, 1.)
333 333 self.cmaps.append(cmap)
334 334
335 335 def __add_axes(self, ax, size='30%', pad='8%'):
336 336 '''
337 337 Add new axes to the given figure
338 338 '''
339 339 divider = make_axes_locatable(ax)
340 340 nax = divider.new_horizontal(size=size, pad=pad)
341 341 ax.figure.add_axes(nax)
342 342 return nax
343 343
344 344 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
345 345 '''
346 346 Create a masked array for missing data
347 347 '''
348 348 if x_buffer.shape[0] < 2:
349 349 return x_buffer, y_buffer, z_buffer
350 350
351 351 deltas = x_buffer[1:] - x_buffer[0:-1]
352 352 x_median = numpy.median(deltas)
353 353
354 354 index = numpy.where(deltas > 5 * x_median)
355 355
356 356 if len(index[0]) != 0:
357 357 z_buffer[::, index[0], ::] = self.__missing
358 358 z_buffer = numpy.ma.masked_inside(z_buffer,
359 359 0.99 * self.__missing,
360 360 1.01 * self.__missing)
361 361
362 362 return x_buffer, y_buffer, z_buffer
363 363
364 364 def decimate(self):
365 365
366 366 # dx = int(len(self.x)/self.__MAXNUMX) + 1
367 367 dy = int(len(self.y) / self.decimation) + 1
368 368
369 369 # x = self.x[::dx]
370 370 x = self.x
371 371 y = self.y[::dy]
372 372 z = self.z[::, ::, ::dy]
373 373
374 374 return x, y, z
375 375
376 376 def format(self):
377 377 '''
378 378 Set min and max values, labels, ticks and titles
379 379 '''
380 380
381 381 for n, ax in enumerate(self.axes):
382 382 if ax.firsttime:
383 383 if self.xaxis != 'time':
384 384 xmin = self.xmin
385 385 xmax = self.xmax
386 386 else:
387 387 xmin = self.tmin
388 388 xmax = self.tmin + self.xrange*60*60
389 389 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
390 390 ax.xaxis.set_major_locator(LinearLocator(9))
391 391 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
392 392 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
393 393 ax.set_facecolor(self.bgcolor)
394 394 if self.xscale:
395 395 ax.xaxis.set_major_formatter(FuncFormatter(
396 396 lambda x, pos: '{0:g}'.format(x*self.xscale)))
397 397 if self.yscale:
398 398 ax.yaxis.set_major_formatter(FuncFormatter(
399 399 lambda x, pos: '{0:g}'.format(x*self.yscale)))
400 400 if self.xlabel is not None:
401 401 ax.set_xlabel(self.xlabel)
402 402 if self.ylabel is not None:
403 403 ax.set_ylabel(self.ylabel)
404 404 if self.showprofile:
405 405 self.pf_axes[n].set_ylim(ymin, ymax)
406 406 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
407 407 self.pf_axes[n].set_xlabel('dB')
408 408 self.pf_axes[n].grid(b=True, axis='x')
409 409 [tick.set_visible(False)
410 410 for tick in self.pf_axes[n].get_yticklabels()]
411 411 if self.colorbar:
412 412 ax.cbar = plt.colorbar(
413 413 ax.plt, ax=ax, fraction=0.05, pad=0.06, aspect=10)
414 414 ax.cbar.ax.tick_params(labelsize=8)
415 415 ax.cbar.ax.press = None
416 416 if self.cb_label:
417 417 ax.cbar.set_label(self.cb_label, size=8)
418 418 elif self.cb_labels:
419 419 ax.cbar.set_label(self.cb_labels[n], size=8)
420 420 else:
421 421 ax.cbar = None
422 422 ax.set_xlim(xmin, xmax)
423 423 ax.set_ylim(ymin, ymax)
424 424 ax.firsttime = False
425 425 if self.grid:
426 426 ax.grid(True)
427 427 if not self.polar:
428 428 ax.set_title('{} {} {}'.format(
429 429 self.titles[n],
430 430 self.getDateTime(self.data.max_time).strftime(
431 431 '%Y-%m-%d %H:%M:%S'),
432 432 self.time_label),
433 433 size=8)
434 434 else:
435 435 #ax.set_title('{}'.format(self.titles[n]), size=8)
436 436 ax.set_title('{} {} {}'.format(
437 437 self.titles[n],
438 438 self.getDateTime(self.data.max_time).strftime(
439 439 '%Y-%m-%d %H:%M:%S'),
440 440 self.time_label),
441 441 size=8)
442 442 ax.set_ylim(0, self.ymax)
443 443 #ax.set_yticks(numpy.arange(0, self.ymax, 20))
444 444 ax.yaxis.labelpad = 28
445 445
446 446 if self.firsttime:
447 447 for n, fig in enumerate(self.figures):
448 448 fig.subplots_adjust(**self.plots_adjust)
449 449 self.firsttime = False
450 450
451 451 def clear_figures(self):
452 452 '''
453 453 Reset axes for redraw plots
454 454 '''
455 455
456 456 for ax in self.axes+self.pf_axes+self.cb_axes:
457 457 ax.clear()
458 458 ax.firsttime = True
459 459 if hasattr(ax, 'cbar') and ax.cbar:
460 460 ax.cbar.remove()
461 461
462 462 def __plot(self):
463 463 '''
464 464 Main function to plot, format and save figures
465 465 '''
466 466
467 467 self.plot()
468 468 self.format()
469 469
470 470 for n, fig in enumerate(self.figures):
471 471 if self.nrows == 0 or self.nplots == 0:
472 472 log.warning('No data', self.name)
473 473 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
474 474 fig.canvas.manager.set_window_title(self.CODE)
475 475 continue
476 476
477 477 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
478 478 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
479 479 fig.canvas.draw()
480 480 if self.show:
481 481 fig.show()
482 482 figpause(0.01)
483 483
484 484 if self.save:
485 485 if self.CODE=="PPI" or self.CODE=="RHI":
486 486 self.save_figure(n,stitle =self.titles)
487 487 else:
488 488 self.save_figure(n)
489 489
490 490 if self.server:
491 491 self.send_to_server()
492 492
493 493 def __update(self, dataOut, timestamp):
494 494 '''
495 495 '''
496 496
497 497 metadata = {
498 498 'yrange': dataOut.heightList,
499 499 'interval': dataOut.timeInterval,
500 500 'channels': dataOut.channelList
501 501 }
502 502
503 503 data, meta = self.update(dataOut)
504 504 metadata.update(meta)
505 505 self.data.update(data, timestamp, metadata)
506 506
507 507 def save_figure(self, n,stitle=None):
508 508 '''
509 509 '''
510 510 if stitle is not None:
511 511 s_string = re.sub(r"[^A-Z0-9.]","",str(stitle))
512 512 new_string=s_string[:3]+"_"+s_string[4:6]+"_"+s_string[6:]
513 513
514 514 if self.oneFigure:
515 515 if (self.data.max_time - self.save_time) <= self.save_period:
516 516 return
517 517
518 518 self.save_time = self.data.max_time
519 519
520 520 fig = self.figures[n]
521 521
522 522 if self.throttle == 0:
523 523 if self.oneFigure:
524 524 if stitle is not None:
525 525 figname = os.path.join(
526 526 self.save,
527 527 self.save_code + '_' + new_string,
528 528 '{}_{}_{}.png'.format(
529 529 self.save_code,
530 530 new_string,
531 531 self.getDateTime(self.data.max_time).strftime(
532 532 '%Y%m%d_%H%M%S',
533 533 ),
534 534 )
535 535 )
536 536 else:
537 537 figname = os.path.join(
538 538 self.save,
539 539 self.save_code,
540 540 '{}_{}.png'.format(
541 541 self.save_code,
542 542 self.getDateTime(self.data.max_time).strftime(
543 543 '%Y%m%d_%H%M%S'
544 544 ),
545 545 )
546 546 )
547 547 else:
548 548 figname = os.path.join(
549 549 self.save,
550 550 self.save_code,
551 551 '{}_ch{}_{}.png'.format(
552 552 self.save_code,n,
553 553 self.getDateTime(self.data.max_time).strftime(
554 554 '%Y%m%d_%H%M%S'
555 555 ),
556 556 )
557 557 )
558 558 log.log('Saving figure: {}'.format(figname), self.name)
559 559 if not os.path.isdir(os.path.dirname(figname)):
560 560 os.makedirs(os.path.dirname(figname))
561 561 fig.savefig(figname)
562 562
563 563 figname = os.path.join(
564 564 self.save,
565 565 '{}_{}.png'.format(
566 566 self.save_code,
567 567 self.getDateTime(self.data.min_time).strftime(
568 568 '%Y%m%d'
569 569 ),
570 570 )
571 571 )
572 572
573 573 log.log('Saving figure: {}'.format(figname), self.name)
574 574 if not os.path.isdir(os.path.dirname(figname)):
575 575 os.makedirs(os.path.dirname(figname))
576 576 fig.savefig(figname)
577 577
578 578 def send_to_server(self):
579 579 '''
580 580 '''
581 581
582 582 if self.exp_code == None:
583 583 log.warning('Missing `exp_code` skipping sending to server...')
584 584
585 585 last_time = self.data.max_time
586 586 interval = last_time - self.sender_time
587 587 if interval < self.sender_period:
588 588 return
589 589
590 590 self.sender_time = last_time
591 591
592 592 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
593 593 for attr in attrs:
594 594 value = getattr(self, attr)
595 595 if value:
596 596 if isinstance(value, (numpy.float32, numpy.float64)):
597 597 value = round(float(value), 2)
598 598 self.data.meta[attr] = value
599 599 if self.colormap == 'jet':
600 600 self.data.meta['colormap'] = 'Jet'
601 601 elif 'RdBu' in self.colormap:
602 602 self.data.meta['colormap'] = 'RdBu'
603 603 else:
604 604 self.data.meta['colormap'] = 'Viridis'
605 605 self.data.meta['interval'] = int(interval)
606 606
607 607 self.sender_queue.append(last_time)
608 608
609 609 while True:
610 610 try:
611 611 tm = self.sender_queue.popleft()
612 612 except IndexError:
613 613 break
614 614 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
615 615 self.socket.send_string(msg)
616 616 socks = dict(self.poll.poll(2000))
617 617 if socks.get(self.socket) == zmq.POLLIN:
618 618 reply = self.socket.recv_string()
619 619 if reply == 'ok':
620 620 log.log("Response from server ok", self.name)
621 621 time.sleep(0.1)
622 622 continue
623 623 else:
624 624 log.warning(
625 625 "Malformed reply from server: {}".format(reply), self.name)
626 626 else:
627 627 log.warning(
628 628 "No response from server, retrying...", self.name)
629 629 self.sender_queue.appendleft(tm)
630 630 self.socket.setsockopt(zmq.LINGER, 0)
631 631 self.socket.close()
632 632 self.poll.unregister(self.socket)
633 633 self.socket = self.context.socket(zmq.REQ)
634 634 self.socket.connect(self.server)
635 635 self.poll.register(self.socket, zmq.POLLIN)
636 636 break
637 637
638 638 def setup(self):
639 639 '''
640 640 This method should be implemented in the child class, the following
641 641 attributes should be set:
642 642
643 643 self.nrows: number of rows
644 644 self.ncols: number of cols
645 645 self.nplots: number of plots (channels or pairs)
646 646 self.ylabel: label for Y axes
647 647 self.titles: list of axes title
648 648
649 649 '''
650 650 raise NotImplementedError
651 651
652 652 def plot(self):
653 653 '''
654 654 Must be defined in the child class, the actual plotting method
655 655 '''
656 656 raise NotImplementedError
657 657
658 658 def update(self, dataOut):
659 659 '''
660 660 Must be defined in the child class, update self.data with new data
661 661 '''
662 662
663 663 data = {
664 664 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
665 665 }
666 666 meta = {}
667 667
668 668 return data, meta
669 669
670 670 def run(self, dataOut, **kwargs):
671 671 '''
672 672 Main plotting routine
673 673 '''
674 674
675 675 if self.isConfig is False:
676 676 self.__setup(**kwargs)
677 677
678 678 if self.localtime:
679 679 self.getDateTime = datetime.datetime.fromtimestamp
680 680 else:
681 681 self.getDateTime = datetime.datetime.utcfromtimestamp
682 682
683 683 self.data.setup()
684 684 self.isConfig = True
685 685 if self.server:
686 686 self.context = zmq.Context()
687 687 self.socket = self.context.socket(zmq.REQ)
688 688 self.socket.connect(self.server)
689 689 self.poll = zmq.Poller()
690 690 self.poll.register(self.socket, zmq.POLLIN)
691 691
692 692 tm = getattr(dataOut, self.attr_time)
693 693
694 694 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
695 695 self.save_time = tm
696 696 self.__plot()
697 697 self.tmin += self.xrange*60*60
698 698 self.data.setup()
699 699 self.clear_figures()
700 700
701 701 self.__update(dataOut, tm)
702 702
703 703 if self.isPlotConfig is False:
704 704 self.__setup_plot()
705 705 self.isPlotConfig = True
706 706 if self.xaxis == 'time':
707 707 dt = self.getDateTime(tm)
708 708 if self.xmin is None:
709 709 self.tmin = tm
710 710 self.xmin = dt.hour
711 711 minutes = (self.xmin-int(self.xmin)) * 60
712 712 seconds = (minutes - int(minutes)) * 60
713 713 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
714 714 datetime.datetime(1970, 1, 1)).total_seconds()
715 715 if self.localtime:
716 716 self.tmin += time.timezone
717 717
718 718 if self.xmin is not None and self.xmax is not None:
719 719 self.xrange = self.xmax - self.xmin
720 720
721 721 if self.throttle == 0:
722 722 self.__plot()
723 723 else:
724 724 self.__throttle_plot(self.__plot)#, coerce=coerce)
725 725
726 726 def close(self):
727 727
728 728 if self.data and not self.data.flagNoData:
729 729 self.save_time = 0
730 730 self.__plot()
731 731 if self.data and not self.data.flagNoData and self.pause:
732 732 figpause(10)
@@ -1,78 +1,77
1 1 '''
2 2 @author: roj-idl71
3 3 '''
4 4 #USED IN jroplot_spectra.py
5 5 RTI_CODE = 0 #Range time intensity (RTI).
6 6 SPEC_CODE = 1 #Spectra (and Cross-spectra) information.
7 7 CROSS_CODE = 2 #Cross-Correlation information.
8 8 COH_CODE = 3 #Coherence map.
9 9 BASE_CODE = 4 #Base lines graphic.
10 10 ROW_CODE = 5 #Row Spectra.
11 11 TOTAL_CODE = 6 #Total Power.
12 12 DRIFT_CODE = 7 #Drifts graphics.
13 13 HEIGHT_CODE = 8 #Height profile.
14 14 PHASE_CODE = 9 #Signal Phase.
15 15
16 16 POWER_CODE = 16
17 17 NOISE_CODE = 17
18 18 BEACON_CODE = 18
19 19
20 20 #USED IN jroplot_parameters.py
21 21 WIND_CODE = 22
22 22 MSKYMAP_CODE = 23
23 23 MPHASE_CODE = 24
24 24
25 25 MOMENTS_CODE = 25
26 26 PARMS_CODE = 26
27 27 SPECFIT_CODE = 27
28 28 EWDRIFT_CODE = 28
29 29
30 30
31 31 #COLOR TABLES
32 32
33 33 reflectivity = [
34 34 "#000000", # -30
35 35 "#15191d", # -25
36 36 "#2a323b", # -20
37 37 "#3f4c59", # -15
38 38 "#556576", # -10
39 39 "#6a7f94", # -5
40 40 "#7f99b2", # 0
41 41 "#00ffff", # 5
42 42 "#007fff", # 10
43 43 "#0000ff", # 15
44 44 "#00ff00", # 20
45 45 "#00bf00", # 25
46 46 "#007f00", # 30
47 47 "#ffff00", # 35
48 48 "#ffbf00", # 40
49 49 "#ff7f00", # 45
50 50 "#ff0000", # 50
51 51 "#bf0000", # 55
52 52 "#7f0000", # 60
53 53 "#fe00fe", # 65
54 54 "#8e59ff", # 70
55 55 "#f0f0f0", # 75
56 "#cccccc" # 80
57 56 ]
58 57
59 58 velocity = [
60 59 "#003300", "#005500", "#007700", "#009900", "#00bb00", "#24ce24", "#6cd26c", "#b4d6b4",
61 60 "#d6b4b4", "#d26c6c", "#ce2424", "#bb0000", "#980000", "#760000", "#540000", "#330000",
62 61 ]
63 62
64 63 spc_width = [
65 64 "#00ffff", "#00aaf2", "#0055e5", "#0000d8",
66 65 "#007f00", "#00aa00", "#00d400", "#00ff00",
67 66 "#ffff00", "#ffd400", "#ffaa00", "#ff7f00",
68 67 "#ff0000", "#d40000", "#aa0000", "#7f0000",
69 68 "#ff00ff", "#d400d4", "#aa00aa", "#7f007f",
70 69 "#9938ff", "#832ed8", "#6e25b2", "#591c8c",
71 70 "#aaaaaa", "#8e8e8e"
72 71 ]
73 72
74 73 sophy_cb_tables = [
75 74 ('sophy_r', reflectivity),
76 75 ('sophy_v', velocity),
77 76 ('sophy_w', spc_width),
78 77 ] No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now