##// END OF EJS Templates
Se modifican 3 metodos: format,clear_figures and run, revisar correo de Joab, bug recorte de graficos en Signal Chain
Alexander Valdez -
r1659:fed278fd2497
parent child
Show More
@@ -1,693 +1,693
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
256 256 if self.server:
257 257 if not self.server.startswith('tcp://'):
258 258 self.server = 'tcp://{}'.format(self.server)
259 259 log.success(
260 260 'Sending to server: {}'.format(self.server),
261 261 self.name
262 262 )
263 263
264 264 if isinstance(self.attr_data, str):
265 265 self.attr_data = [self.attr_data]
266 266
267 267 def __setup_plot(self):
268 268 '''
269 269 Common setup for all figures, here figures and axes are created
270 270 '''
271 271
272 272 self.setup()
273 273
274 274 self.time_label = 'LT' if self.localtime else 'UTC'
275 275
276 276 if self.width is None:
277 277 self.width = 8
278 278
279 279 self.figures = []
280 280 self.axes = []
281 281 self.cb_axes = []
282 282 self.pf_axes = []
283 283 self.cmaps = []
284 284
285 285 size = '15%' if self.ncols == 1 else '30%'
286 286 pad = '4%' if self.ncols == 1 else '8%'
287 287
288 288 if self.oneFigure:
289 289 if self.height is None:
290 290 self.height = 1.4 * self.nrows + 1
291 291 fig = plt.figure(figsize=(self.width, self.height),
292 292 edgecolor='k',
293 293 facecolor='w')
294 294 self.figures.append(fig)
295 295 for n in range(self.nplots):
296 296 ax = fig.add_subplot(self.nrows, self.ncols,
297 297 n + 1, polar=self.polar)
298 298 ax.tick_params(labelsize=8)
299 299 ax.firsttime = True
300 300 ax.index = 0
301 301 ax.press = None
302 302 self.axes.append(ax)
303 303 if self.showprofile:
304 304 cax = self.__add_axes(ax, size=size, pad=pad)
305 305 cax.tick_params(labelsize=8)
306 306 self.pf_axes.append(cax)
307 307 else:
308 308 if self.height is None:
309 309 self.height = 3
310 310 for n in range(self.nplots):
311 311 fig = plt.figure(figsize=(self.width, self.height),
312 312 edgecolor='k',
313 313 facecolor='w')
314 314 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
315 315 ax.tick_params(labelsize=8)
316 316 ax.firsttime = True
317 317 ax.index = 0
318 318 ax.press = None
319 319 self.figures.append(fig)
320 320 self.axes.append(ax)
321 321 if self.showprofile:
322 322 cax = self.__add_axes(ax, size=size, pad=pad)
323 323 cax.tick_params(labelsize=8)
324 324 self.pf_axes.append(cax)
325 325
326 326 for n in range(self.nrows):
327 327 if self.colormaps is not None:
328 328 cmap = plt.get_cmap(self.colormaps[n])
329 329 else:
330 330 cmap = plt.get_cmap(self.colormap)
331 331 cmap.set_bad(self.bgcolor, 1.)
332 332 self.cmaps.append(cmap)
333 333
334 334 def __add_axes(self, ax, size='30%', pad='8%'):
335 335 '''
336 336 Add new axes to the given figure
337 337 '''
338 338 divider = make_axes_locatable(ax)
339 339 nax = divider.new_horizontal(size=size, pad=pad)
340 340 ax.figure.add_axes(nax)
341 341 return nax
342 342
343 343 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
344 344 '''
345 345 Create a masked array for missing data
346 346 '''
347 347 if x_buffer.shape[0] < 2:
348 348 return x_buffer, y_buffer, z_buffer
349 349
350 350 deltas = x_buffer[1:] - x_buffer[0:-1]
351 351 x_median = numpy.median(deltas)
352 352
353 353 index = numpy.where(deltas > 5 * x_median)
354 354
355 355 if len(index[0]) != 0:
356 356 z_buffer[::, index[0], ::] = self.__missing
357 357 z_buffer = numpy.ma.masked_inside(z_buffer,
358 358 0.99 * self.__missing,
359 359 1.01 * self.__missing)
360 360
361 361 return x_buffer, y_buffer, z_buffer
362 362
363 363 def decimate(self):
364 364
365 365 # dx = int(len(self.x)/self.__MAXNUMX) + 1
366 366 dy = int(len(self.y) / self.decimation) + 1
367 367
368 368 # x = self.x[::dx]
369 369 x = self.x
370 370 y = self.y[::dy]
371 371 z = self.z[::, ::, ::dy]
372 372
373 373 return x, y, z
374 374
375 375 def format(self):
376 376 '''
377 377 Set min and max values, labels, ticks and titles
378 378 '''
379 379
380 380 for n, ax in enumerate(self.axes):
381 381 if ax.firsttime:
382 382 if self.xaxis != 'time':
383 383 xmin = self.xmin
384 384 xmax = self.xmax
385 385 else:
386 386 xmin = self.tmin
387 387 xmax = self.tmin + self.xrange*60*60
388 388 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
389 389 ax.xaxis.set_major_locator(LinearLocator(9))
390 390 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
391 391 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
392 392 ax.set_facecolor(self.bgcolor)
393 393 if self.xscale:
394 394 ax.xaxis.set_major_formatter(FuncFormatter(
395 395 lambda x, pos: '{0:g}'.format(x*self.xscale)))
396 396 if self.yscale:
397 397 ax.yaxis.set_major_formatter(FuncFormatter(
398 398 lambda x, pos: '{0:g}'.format(x*self.yscale)))
399 399 if self.xlabel is not None:
400 400 ax.set_xlabel(self.xlabel)
401 401 if self.ylabel is not None:
402 402 ax.set_ylabel(self.ylabel)
403 403 if self.showprofile:
404 404 self.pf_axes[n].set_ylim(ymin, ymax)
405 405 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
406 406 self.pf_axes[n].set_xlabel('dB')
407 407 self.pf_axes[n].grid(b=True, axis='x')
408 408 [tick.set_visible(False)
409 409 for tick in self.pf_axes[n].get_yticklabels()]
410 if self.colorbar:
410 if self.colorbar and not(hasattr(ax, 'cbar')):
411 411 ax.cbar = plt.colorbar(
412 412 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
413 413 ax.cbar.ax.tick_params(labelsize=8)
414 414 ax.cbar.ax.press = None
415 415 if self.cb_label:
416 416 ax.cbar.set_label(self.cb_label, size=8)
417 417 elif self.cb_labels:
418 418 ax.cbar.set_label(self.cb_labels[n], size=8)
419 419 else:
420 420 ax.cbar = None
421 421 ax.set_xlim(xmin, xmax)
422 422 ax.set_ylim(ymin, ymax)
423 423 ax.firsttime = False
424 424 if self.grid:
425 425 ax.grid(True)
426 426 if not self.polar:
427 427 ax.set_title('{} {} {}'.format(
428 428 self.titles[n],
429 429 self.getDateTime(self.data.max_time).strftime(
430 430 '%Y-%m-%d %H:%M:%S'),
431 431 self.time_label),
432 432 size=8)
433 433 else:
434 434 ax.set_title('{}'.format(self.titles[n]), size=8)
435 435 ax.set_ylim(0, 90)
436 436 ax.set_yticks(numpy.arange(0, 90, 20))
437 437 ax.yaxis.labelpad = 40
438 438
439 439 if self.firsttime:
440 440 for n, fig in enumerate(self.figures):
441 441 fig.subplots_adjust(**self.plots_adjust)
442 442 self.firsttime = False
443 443
444 444 def clear_figures(self):
445 445 '''
446 446 Reset axes for redraw plots
447 447 '''
448 448
449 449 for ax in self.axes+self.pf_axes+self.cb_axes:
450 450 ax.clear()
451 451 ax.firsttime = True
452 if hasattr(ax, 'cbar') and ax.cbar:
453 ax.cbar.remove()
452 #if hasattr(ax, 'cbar') and ax.cbar:
453 # ax.cbar.remove()
454 454
455 455 def __plot(self):
456 456 '''
457 457 Main function to plot, format and save figures
458 458 '''
459 459
460 460 self.plot()
461 461 self.format()
462 462
463 463 for n, fig in enumerate(self.figures):
464 464 if self.nrows == 0 or self.nplots == 0:
465 465 log.warning('No data', self.name)
466 466 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
467 467 fig.canvas.manager.set_window_title(self.CODE)
468 468 continue
469 469
470 470 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
471 471 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
472 472 fig.canvas.draw()
473 473 if self.show:
474 474 fig.show()
475 475 figpause(0.01)
476 476
477 477 if self.save:
478 478 self.save_figure(n)
479 479
480 480 if self.server:
481 481 self.send_to_server()
482 482
483 483 def __update(self, dataOut, timestamp):
484 484 '''
485 485 '''
486 486
487 487 metadata = {
488 488 'yrange': dataOut.heightList,
489 489 'interval': dataOut.timeInterval,
490 490 'channels': dataOut.channelList
491 491 }
492 492
493 493 data, meta = self.update(dataOut)
494 494 metadata.update(meta)
495 495 self.data.update(data, timestamp, metadata)
496 496
497 497 def save_figure(self, n):
498 498 '''
499 499 '''
500 500
501 501 if (self.data.max_time - self.save_time) <= self.save_period:
502 502 return
503 503
504 504 self.save_time = self.data.max_time
505 505
506 506 fig = self.figures[n]
507 507
508 508 if self.throttle == 0:
509 509 figname = os.path.join(
510 510 self.save,
511 511 self.save_code,
512 512 '{}_{}.png'.format(
513 513 self.save_code,
514 514 self.getDateTime(self.data.max_time).strftime(
515 515 '%Y%m%d_%H%M%S'
516 516 ),
517 517 )
518 518 )
519 519 log.log('Saving figure: {}'.format(figname), self.name)
520 520 if not os.path.isdir(os.path.dirname(figname)):
521 521 os.makedirs(os.path.dirname(figname))
522 522 fig.savefig(figname)
523 523
524 524 figname = os.path.join(
525 525 self.save,
526 526 '{}_{}.png'.format(
527 527 self.save_code,
528 528 self.getDateTime(self.data.min_time).strftime(
529 529 '%Y%m%d'
530 530 ),
531 531 )
532 532 )
533 533 log.log('Saving figure: {}'.format(figname), self.name)
534 534 if not os.path.isdir(os.path.dirname(figname)):
535 535 os.makedirs(os.path.dirname(figname))
536 536 fig.savefig(figname)
537 537
538 538 def send_to_server(self):
539 539 '''
540 540 '''
541 541
542 542 if self.exp_code == None:
543 543 log.warning('Missing `exp_code` skipping sending to server...')
544 544
545 545 last_time = self.data.max_time
546 546 interval = last_time - self.sender_time
547 547 if interval < self.sender_period:
548 548 return
549 549
550 550 self.sender_time = last_time
551 551
552 552 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
553 553 for attr in attrs:
554 554 value = getattr(self, attr)
555 555 if value:
556 556 if isinstance(value, (numpy.float32, numpy.float64)):
557 557 value = round(float(value), 2)
558 558 self.data.meta[attr] = value
559 559 if self.colormap == 'jet':
560 560 self.data.meta['colormap'] = 'Jet'
561 561 elif 'RdBu' in self.colormap:
562 562 self.data.meta['colormap'] = 'RdBu'
563 563 else:
564 564 self.data.meta['colormap'] = 'Viridis'
565 565 self.data.meta['interval'] = int(interval)
566 566
567 567 self.sender_queue.append(last_time)
568 568
569 569 while True:
570 570 try:
571 571 tm = self.sender_queue.popleft()
572 572 except IndexError:
573 573 break
574 574 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
575 575 self.socket.send_string(msg)
576 576 socks = dict(self.poll.poll(2000))
577 577 if socks.get(self.socket) == zmq.POLLIN:
578 578 reply = self.socket.recv_string()
579 579 if reply == 'ok':
580 580 log.log("Response from server ok", self.name)
581 581 time.sleep(0.1)
582 582 continue
583 583 else:
584 584 log.warning(
585 585 "Malformed reply from server: {}".format(reply), self.name)
586 586 else:
587 587 log.warning(
588 588 "No response from server, retrying...", self.name)
589 589 self.sender_queue.appendleft(tm)
590 590 self.socket.setsockopt(zmq.LINGER, 0)
591 591 self.socket.close()
592 592 self.poll.unregister(self.socket)
593 593 self.socket = self.context.socket(zmq.REQ)
594 594 self.socket.connect(self.server)
595 595 self.poll.register(self.socket, zmq.POLLIN)
596 596 break
597 597
598 598 def setup(self):
599 599 '''
600 600 This method should be implemented in the child class, the following
601 601 attributes should be set:
602 602
603 603 self.nrows: number of rows
604 604 self.ncols: number of cols
605 605 self.nplots: number of plots (channels or pairs)
606 606 self.ylabel: label for Y axes
607 607 self.titles: list of axes title
608 608
609 609 '''
610 610 raise NotImplementedError
611 611
612 612 def plot(self):
613 613 '''
614 614 Must be defined in the child class, the actual plotting method
615 615 '''
616 616 raise NotImplementedError
617 617
618 618 def update(self, dataOut):
619 619 '''
620 620 Must be defined in the child class, update self.data with new data
621 621 '''
622 622
623 623 data = {
624 624 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
625 625 }
626 626 meta = {}
627 627
628 628 return data, meta
629 629
630 630 def run(self, dataOut, **kwargs):
631 631 '''
632 632 Main plotting routine
633 633 '''
634 634
635 635 if self.isConfig is False:
636 636 self.__setup(**kwargs)
637 637
638 638 if self.localtime:
639 639 self.getDateTime = datetime.datetime.fromtimestamp
640 640 else:
641 641 self.getDateTime = datetime.datetime.utcfromtimestamp
642 642
643 643 self.data.setup()
644 644 self.isConfig = True
645 645 if self.server:
646 646 self.context = zmq.Context()
647 647 self.socket = self.context.socket(zmq.REQ)
648 648 self.socket.connect(self.server)
649 649 self.poll = zmq.Poller()
650 650 self.poll.register(self.socket, zmq.POLLIN)
651 651
652 652 tm = getattr(dataOut, self.attr_time)
653 653
654 654 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
655 self.clear_figures()
655 656 self.save_time = tm
656 self.__plot()
657 657 self.tmin += self.xrange*60*60
658 self.__plot()
658 659 self.data.setup()
659 self.clear_figures()
660 660
661 661 self.__update(dataOut, tm)
662 662
663 663 if self.isPlotConfig is False:
664 664 self.__setup_plot()
665 665 self.isPlotConfig = True
666 666 if self.xaxis == 'time':
667 667 dt = self.getDateTime(tm)
668 668 if self.xmin is None:
669 669 self.tmin = tm
670 670 self.xmin = dt.hour
671 671 minutes = (self.xmin-int(self.xmin)) * 60
672 672 seconds = (minutes - int(minutes)) * 60
673 673 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
674 674 datetime.datetime(1970, 1, 1)).total_seconds()
675 675 if self.localtime:
676 676 self.tmin += time.timezone
677 677
678 678 if self.xmin is not None and self.xmax is not None:
679 679 self.xrange = self.xmax - self.xmin
680 680
681 681 if self.throttle == 0:
682 682 self.__plot()
683 683 else:
684 684 self.__throttle_plot(self.__plot)#, coerce=coerce)
685 685
686 686 def close(self):
687 687
688 688 if self.data and not self.data.flagNoData:
689 689 self.save_time = 0
690 690 self.__plot()
691 691 if self.data and not self.data.flagNoData and self.pause:
692 692 figpause(10)
693 693
General Comments 0
You need to be logged in to leave comments. Login now