##// END OF EJS Templates
New plotting architecture with buffering/throttle capabilities
Juan C. Espinoza -
r1187:66a3db7e736d
parent child
Show More
This diff has been collapsed as it changes many lines, (803 lines changed) Show them Hide them
@@ -0,0 +1,803
1
2 import os
3 import sys
4 import zmq
5 import time
6 import datetime
7 from functools import wraps
8 import numpy
9 import matplotlib
10
11 if 'BACKEND' in os.environ:
12 matplotlib.use(os.environ['BACKEND'])
13 elif 'linux' in sys.platform:
14 matplotlib.use("TkAgg")
15 elif 'darwin' in sys.platform:
16 matplotlib.use('TkAgg')
17 else:
18 from schainpy.utils import log
19 log.warning('Using default Backend="Agg"', 'INFO')
20 matplotlib.use('Agg')
21
22 import matplotlib.pyplot as plt
23 from matplotlib.patches import Polygon
24 from mpl_toolkits.axes_grid1 import make_axes_locatable
25 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
26
27 from schainpy.model.data.jrodata import PlotterData
28 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
29 from schainpy.utils import log
30
31 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
32 blu_values = matplotlib.pyplot.get_cmap(
33 'seismic_r', 20)(numpy.arange(20))[10:15]
34 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
35 'jro', numpy.vstack((blu_values, jet_values)))
36 matplotlib.pyplot.register_cmap(cmap=ncmap)
37
38 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
39 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
40
41 EARTH_RADIUS = 6.3710e3
42
43
44 def ll2xy(lat1, lon1, lat2, lon2):
45
46 p = 0.017453292519943295
47 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
48 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
49 r = 12742 * numpy.arcsin(numpy.sqrt(a))
50 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
51 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
52 theta = -theta + numpy.pi/2
53 return r*numpy.cos(theta), r*numpy.sin(theta)
54
55
56 def km2deg(km):
57 '''
58 Convert distance in km to degrees
59 '''
60
61 return numpy.rad2deg(km/EARTH_RADIUS)
62
63
64 def figpause(interval):
65 backend = plt.rcParams['backend']
66 if backend in matplotlib.rcsetup.interactive_bk:
67 figManager = matplotlib._pylab_helpers.Gcf.get_active()
68 if figManager is not None:
69 canvas = figManager.canvas
70 if canvas.figure.stale:
71 canvas.draw()
72 try:
73 canvas.start_event_loop(interval)
74 except:
75 pass
76 return
77
78
79 def popup(message):
80 '''
81 '''
82
83 fig = plt.figure(figsize=(12, 8), facecolor='r')
84 text = '\n'.join([s.strip() for s in message.split(':')])
85 fig.text(0.01, 0.5, text, ha='left', va='center',
86 size='20', weight='heavy', color='w')
87 fig.show()
88 figpause(1000)
89
90
91 class Throttle(object):
92 '''
93 Decorator that prevents a function from being called more than once every
94 time period.
95 To create a function that cannot be called more than once a minute, but
96 will sleep until it can be called:
97 @Throttle(minutes=1)
98 def foo():
99 pass
100
101 for i in range(10):
102 foo()
103 print "This function has run %s times." % i
104 '''
105
106 def __init__(self, seconds=0, minutes=0, hours=0):
107 self.throttle_period = datetime.timedelta(
108 seconds=seconds, minutes=minutes, hours=hours
109 )
110
111 self.time_of_last_call = datetime.datetime.min
112
113 def __call__(self, fn):
114 @wraps(fn)
115 def wrapper(*args, **kwargs):
116 coerce = kwargs.pop('coerce', None)
117 if coerce:
118 self.time_of_last_call = datetime.datetime.now()
119 return fn(*args, **kwargs)
120 else:
121 now = datetime.datetime.now()
122 time_since_last_call = now - self.time_of_last_call
123 time_left = self.throttle_period - time_since_last_call
124
125 if time_left > datetime.timedelta(seconds=0):
126 return
127
128 self.time_of_last_call = datetime.datetime.now()
129 return fn(*args, **kwargs)
130
131 return wrapper
132
133 def apply_throttle(value):
134
135 @Throttle(seconds=value)
136 def fnThrottled(fn):
137 fn()
138
139 return fnThrottled
140
141 @MPDecorator
142 class Plotter(ProcessingUnit):
143 '''
144 Proccessing unit to handle plot operations
145 '''
146
147 def __init__(self):
148
149 ProcessingUnit.__init__(self)
150
151 def setup(self, **kwargs):
152
153 self.connections = 0
154 self.web_address = kwargs.get('web_server', False)
155 self.realtime = kwargs.get('realtime', False)
156 self.localtime = kwargs.get('localtime', True)
157 self.buffering = kwargs.get('buffering', True)
158 self.throttle = kwargs.get('throttle', 2)
159 self.exp_code = kwargs.get('exp_code', None)
160 self.set_ready = apply_throttle(self.throttle)
161 self.dates = []
162 self.data = PlotterData(
163 self.plots, self.throttle, self.exp_code, self.buffering)
164 self.isConfig = True
165
166 def ready(self):
167 '''
168 Set dataOut ready
169 '''
170
171 self.data.ready = True
172 self.dataOut.data_plt = self.data
173
174 def run(self, realtime=True, localtime=True, buffering=True,
175 throttle=2, exp_code=None, web_server=None):
176
177 if not self.isConfig:
178 self.setup(realtime=realtime, localtime=localtime,
179 buffering=buffering, throttle=throttle, exp_code=exp_code,
180 web_server=web_server)
181
182 if self.web_address:
183 log.success(
184 'Sending to web: {}'.format(self.web_address),
185 self.name
186 )
187 self.context = zmq.Context()
188 self.sender_web = self.context.socket(zmq.REQ)
189 self.sender_web.connect(self.web_address)
190 self.poll = zmq.Poller()
191 self.poll.register(self.sender_web, zmq.POLLIN)
192 time.sleep(1)
193
194 # t = Thread(target=self.event_monitor, args=(monitor,))
195 # t.start()
196
197 self.dataOut = self.dataIn
198 self.data.ready = False
199
200 if self.dataOut.flagNoData:
201 coerce = True
202 else:
203 coerce = False
204
205 if self.dataOut.type == 'Parameters':
206 tm = self.dataOut.utctimeInit
207 else:
208 tm = self.dataOut.utctime
209 if self.dataOut.useLocalTime:
210 if not self.localtime:
211 tm += time.timezone
212 dt = datetime.datetime.fromtimestamp(tm).date()
213 else:
214 if self.localtime:
215 tm -= time.timezone
216 dt = datetime.datetime.utcfromtimestamp(tm).date()
217 if dt not in self.dates:
218 if self.data:
219 self.ready()
220 self.data.setup()
221 self.dates.append(dt)
222
223 self.data.update(self.dataOut, tm)
224
225 if False: # TODO check when publishers ends
226 self.connections -= 1
227 if self.connections == 0 and dt in self.dates:
228 self.data.ended = True
229 self.ready()
230 time.sleep(1)
231 else:
232 if self.realtime:
233 self.ready()
234 if self.web_address:
235 retries = 5
236 while True:
237 self.sender_web.send(self.data.jsonify())
238 socks = dict(self.poll.poll(5000))
239 if socks.get(self.sender_web) == zmq.POLLIN:
240 reply = self.sender_web.recv_string()
241 if reply == 'ok':
242 log.log("Response from server ok", self.name)
243 break
244 else:
245 log.warning(
246 "Malformed reply from server: {}".format(reply), self.name)
247
248 else:
249 log.warning(
250 "No response from server, retrying...", self.name)
251 self.sender_web.setsockopt(zmq.LINGER, 0)
252 self.sender_web.close()
253 self.poll.unregister(self.sender_web)
254 retries -= 1
255 if retries == 0:
256 log.error(
257 "Server seems to be offline, abandoning", self.name)
258 self.sender_web = self.context.socket(zmq.REQ)
259 self.sender_web.connect(self.web_address)
260 self.poll.register(self.sender_web, zmq.POLLIN)
261 time.sleep(1)
262 break
263 self.sender_web = self.context.socket(zmq.REQ)
264 self.sender_web.connect(self.web_address)
265 self.poll.register(self.sender_web, zmq.POLLIN)
266 time.sleep(1)
267 else:
268 self.set_ready(self.ready, coerce=coerce)
269
270 return
271
272 def close(self):
273 pass
274
275
276 @MPDecorator
277 class Plot(Operation):
278 '''
279 Base class for Schain plotting operations
280 '''
281
282 CODE = 'Figure'
283 colormap = 'jro'
284 bgcolor = 'white'
285 __missing = 1E30
286
287 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
288 'zlimits', 'xlabel', 'ylabel', 'xaxis', 'cb_label', 'title',
289 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
290 'showprofile', 'decimation', 'pause']
291
292 def __init__(self):
293
294 Operation.__init__(self)
295 self.isConfig = False
296 self.isPlotConfig = False
297
298 def __fmtTime(self, x, pos):
299 '''
300 '''
301
302 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
303
304 def __setup(self, **kwargs):
305 '''
306 Initialize variables
307 '''
308
309 self.figures = []
310 self.axes = []
311 self.cb_axes = []
312 self.localtime = kwargs.pop('localtime', True)
313 self.show = kwargs.get('show', True)
314 self.save = kwargs.get('save', False)
315 self.ftp = kwargs.get('ftp', False)
316 self.colormap = kwargs.get('colormap', self.colormap)
317 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
318 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
319 self.colormaps = kwargs.get('colormaps', None)
320 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
321 self.showprofile = kwargs.get('showprofile', False)
322 self.title = kwargs.get('wintitle', self.CODE.upper())
323 self.cb_label = kwargs.get('cb_label', None)
324 self.cb_labels = kwargs.get('cb_labels', None)
325 self.labels = kwargs.get('labels', None)
326 self.xaxis = kwargs.get('xaxis', 'frequency')
327 self.zmin = kwargs.get('zmin', None)
328 self.zmax = kwargs.get('zmax', None)
329 self.zlimits = kwargs.get('zlimits', None)
330 self.xmin = kwargs.get('xmin', None)
331 self.xmax = kwargs.get('xmax', None)
332 self.xrange = kwargs.get('xrange', 12)
333 self.xscale = kwargs.get('xscale', None)
334 self.ymin = kwargs.get('ymin', None)
335 self.ymax = kwargs.get('ymax', None)
336 self.yscale = kwargs.get('yscale', None)
337 self.xlabel = kwargs.get('xlabel', None)
338 self.decimation = kwargs.get('decimation', None)
339 self.showSNR = kwargs.get('showSNR', False)
340 self.oneFigure = kwargs.get('oneFigure', True)
341 self.width = kwargs.get('width', None)
342 self.height = kwargs.get('height', None)
343 self.colorbar = kwargs.get('colorbar', True)
344 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
345 self.channels = kwargs.get('channels', None)
346 self.titles = kwargs.get('titles', [])
347 self.polar = False
348 self.grid = kwargs.get('grid', False)
349 self.pause = kwargs.get('pause', False)
350 self.save_labels = kwargs.get('save_labels', None)
351 self.realtime = kwargs.get('realtime', True)
352 self.buffering = kwargs.get('buffering', True)
353 self.throttle = kwargs.get('throttle', 2)
354 self.exp_code = kwargs.get('exp_code', None)
355 self.__throttle_plot = apply_throttle(self.throttle)
356 self.data = PlotterData(
357 self.CODE, self.throttle, self.exp_code, self.buffering)
358
359 def __setup_plot(self):
360 '''
361 Common setup for all figures, here figures and axes are created
362 '''
363
364 self.setup()
365
366 self.time_label = 'LT' if self.localtime else 'UTC'
367 if self.data.localtime:
368 self.getDateTime = datetime.datetime.fromtimestamp
369 else:
370 self.getDateTime = datetime.datetime.utcfromtimestamp
371
372 if self.width is None:
373 self.width = 8
374
375 self.figures = []
376 self.axes = []
377 self.cb_axes = []
378 self.pf_axes = []
379 self.cmaps = []
380
381 size = '15%' if self.ncols == 1 else '30%'
382 pad = '4%' if self.ncols == 1 else '8%'
383
384 if self.oneFigure:
385 if self.height is None:
386 self.height = 1.4 * self.nrows + 1
387 fig = plt.figure(figsize=(self.width, self.height),
388 edgecolor='k',
389 facecolor='w')
390 self.figures.append(fig)
391 for n in range(self.nplots):
392 ax = fig.add_subplot(self.nrows, self.ncols,
393 n + 1, polar=self.polar)
394 ax.tick_params(labelsize=8)
395 ax.firsttime = True
396 ax.index = 0
397 ax.press = None
398 self.axes.append(ax)
399 if self.showprofile:
400 cax = self.__add_axes(ax, size=size, pad=pad)
401 cax.tick_params(labelsize=8)
402 self.pf_axes.append(cax)
403 else:
404 if self.height is None:
405 self.height = 3
406 for n in range(self.nplots):
407 fig = plt.figure(figsize=(self.width, self.height),
408 edgecolor='k',
409 facecolor='w')
410 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
411 ax.tick_params(labelsize=8)
412 ax.firsttime = True
413 ax.index = 0
414 ax.press = None
415 self.figures.append(fig)
416 self.axes.append(ax)
417 if self.showprofile:
418 cax = self.__add_axes(ax, size=size, pad=pad)
419 cax.tick_params(labelsize=8)
420 self.pf_axes.append(cax)
421
422 for n in range(self.nrows):
423 if self.colormaps is not None:
424 cmap = plt.get_cmap(self.colormaps[n])
425 else:
426 cmap = plt.get_cmap(self.colormap)
427 cmap.set_bad(self.bgcolor, 1.)
428 self.cmaps.append(cmap)
429
430 for fig in self.figures:
431 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
432 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
433 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
434 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
435 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
436 if self.show:
437 fig.show()
438
439 def OnKeyPress(self, event):
440 '''
441 Event for pressing keys (up, down) change colormap
442 '''
443 ax = event.inaxes
444 if ax in self.axes:
445 if event.key == 'down':
446 ax.index += 1
447 elif event.key == 'up':
448 ax.index -= 1
449 if ax.index < 0:
450 ax.index = len(CMAPS) - 1
451 elif ax.index == len(CMAPS):
452 ax.index = 0
453 cmap = CMAPS[ax.index]
454 ax.cbar.set_cmap(cmap)
455 ax.cbar.draw_all()
456 ax.plt.set_cmap(cmap)
457 ax.cbar.patch.figure.canvas.draw()
458 self.colormap = cmap.name
459
460 def OnBtnScroll(self, event):
461 '''
462 Event for scrolling, scale figure
463 '''
464 cb_ax = event.inaxes
465 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
466 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
467 pt = ax.cbar.ax.bbox.get_points()[:, 1]
468 nrm = ax.cbar.norm
469 vmin, vmax, p0, p1, pS = (
470 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
471 scale = 2 if event.step == 1 else 0.5
472 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
473 ax.cbar.norm.vmin = point - scale * (point - vmin)
474 ax.cbar.norm.vmax = point - scale * (point - vmax)
475 ax.plt.set_norm(ax.cbar.norm)
476 ax.cbar.draw_all()
477 ax.cbar.patch.figure.canvas.draw()
478
479 def onBtnPress(self, event):
480 '''
481 Event for mouse button press
482 '''
483 cb_ax = event.inaxes
484 if cb_ax is None:
485 return
486
487 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
488 cb_ax.press = event.x, event.y
489 else:
490 cb_ax.press = None
491
492 def onMotion(self, event):
493 '''
494 Event for move inside colorbar
495 '''
496 cb_ax = event.inaxes
497 if cb_ax is None:
498 return
499 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
500 return
501 if cb_ax.press is None:
502 return
503
504 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
505 xprev, yprev = cb_ax.press
506 dx = event.x - xprev
507 dy = event.y - yprev
508 cb_ax.press = event.x, event.y
509 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
510 perc = 0.03
511
512 if event.button == 1:
513 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
514 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
515 elif event.button == 3:
516 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
517 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
518
519 ax.cbar.draw_all()
520 ax.plt.set_norm(ax.cbar.norm)
521 ax.cbar.patch.figure.canvas.draw()
522
523 def onBtnRelease(self, event):
524 '''
525 Event for mouse button release
526 '''
527 cb_ax = event.inaxes
528 if cb_ax is not None:
529 cb_ax.press = None
530
531 def __add_axes(self, ax, size='30%', pad='8%'):
532 '''
533 Add new axes to the given figure
534 '''
535 divider = make_axes_locatable(ax)
536 nax = divider.new_horizontal(size=size, pad=pad)
537 ax.figure.add_axes(nax)
538 return nax
539
540 def setup(self):
541 '''
542 This method should be implemented in the child class, the following
543 attributes should be set:
544
545 self.nrows: number of rows
546 self.ncols: number of cols
547 self.nplots: number of plots (channels or pairs)
548 self.ylabel: label for Y axes
549 self.titles: list of axes title
550
551 '''
552 raise NotImplementedError
553
554 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
555 '''
556 Create a masked array for missing data
557 '''
558 if x_buffer.shape[0] < 2:
559 return x_buffer, y_buffer, z_buffer
560
561 deltas = x_buffer[1:] - x_buffer[0:-1]
562 x_median = numpy.median(deltas)
563
564 index = numpy.where(deltas > 5 * x_median)
565
566 if len(index[0]) != 0:
567 z_buffer[::, index[0], ::] = self.__missing
568 z_buffer = numpy.ma.masked_inside(z_buffer,
569 0.99 * self.__missing,
570 1.01 * self.__missing)
571
572 return x_buffer, y_buffer, z_buffer
573
574 def decimate(self):
575
576 # dx = int(len(self.x)/self.__MAXNUMX) + 1
577 dy = int(len(self.y) / self.decimation) + 1
578
579 # x = self.x[::dx]
580 x = self.x
581 y = self.y[::dy]
582 z = self.z[::, ::, ::dy]
583
584 return x, y, z
585
586 def format(self):
587 '''
588 Set min and max values, labels, ticks and titles
589 '''
590
591 if self.xmin is None:
592 xmin = self.data.min_time
593 else:
594 if self.xaxis is 'time':
595 dt = self.getDateTime(self.data.min_time)
596 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
597 datetime.datetime(1970, 1, 1)).total_seconds()
598 if self.data.localtime:
599 xmin += time.timezone
600 else:
601 xmin = self.xmin
602
603 if self.xmax is None:
604 xmax = xmin + self.xrange * 60 * 60
605 else:
606 if self.xaxis is 'time':
607 dt = self.getDateTime(self.data.max_time)
608 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
609 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
610 if self.data.localtime:
611 xmax += time.timezone
612 else:
613 xmax = self.xmax
614
615 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
616 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
617
618 Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000])
619 i = 1 if numpy.where(
620 abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
621 ystep = Y[i] / 10.
622
623 if self.xaxis is not 'time':
624 X = numpy.array([1, 2, 5, 10, 20, 50, 100,
625 200, 500, 1000, 2000, 5000])/2.
626 i = 1 if numpy.where(
627 abs(xmax-xmin) <= X)[0][0] < 0 else numpy.where(abs(xmax-xmin) <= X)[0][0]
628 xstep = X[i] / 10.
629
630 for n, ax in enumerate(self.axes):
631 if ax.firsttime:
632 ax.set_facecolor(self.bgcolor)
633 ax.yaxis.set_major_locator(MultipleLocator(ystep))
634 if self.xscale:
635 ax.xaxis.set_major_formatter(FuncFormatter(
636 lambda x, pos: '{0:g}'.format(x*self.xscale)))
637 if self.xscale:
638 ax.yaxis.set_major_formatter(FuncFormatter(
639 lambda x, pos: '{0:g}'.format(x*self.yscale)))
640 if self.xaxis is 'time':
641 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
642 ax.xaxis.set_major_locator(LinearLocator(9))
643 else:
644 ax.xaxis.set_major_locator(MultipleLocator(xstep))
645 if self.xlabel is not None:
646 ax.set_xlabel(self.xlabel)
647 ax.set_ylabel(self.ylabel)
648 ax.firsttime = False
649 if self.showprofile:
650 self.pf_axes[n].set_ylim(ymin, ymax)
651 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
652 self.pf_axes[n].set_xlabel('dB')
653 self.pf_axes[n].grid(b=True, axis='x')
654 [tick.set_visible(False)
655 for tick in self.pf_axes[n].get_yticklabels()]
656 if self.colorbar:
657 ax.cbar = plt.colorbar(
658 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
659 ax.cbar.ax.tick_params(labelsize=8)
660 ax.cbar.ax.press = None
661 if self.cb_label:
662 ax.cbar.set_label(self.cb_label, size=8)
663 elif self.cb_labels:
664 ax.cbar.set_label(self.cb_labels[n], size=8)
665 else:
666 ax.cbar = None
667 if self.grid:
668 ax.grid(True)
669
670 if not self.polar:
671 ax.set_xlim(xmin, xmax)
672 ax.set_ylim(ymin, ymax)
673 ax.set_title('{} {} {}'.format(
674 self.titles[n],
675 self.getDateTime(self.data.max_time).strftime(
676 '%Y-%m-%dT%H:%M:%S'),
677 self.time_label),
678 size=8)
679 else:
680 ax.set_title('{}'.format(self.titles[n]), size=8)
681 ax.set_ylim(0, 90)
682 ax.set_yticks(numpy.arange(0, 90, 20))
683 ax.yaxis.labelpad = 40
684
685 def clear_figures(self):
686 '''
687 Reset axes for redraw plots
688 '''
689
690 for ax in self.axes:
691 ax.clear()
692 ax.firsttime = True
693 if ax.cbar:
694 ax.cbar.remove()
695
696 def __plot(self):
697 '''
698 Main function to plot, format and save figures
699 '''
700
701 #try:
702 self.plot()
703 self.format()
704 #except Exception as e:
705 # log.warning('{} Plot could not be updated... check data'.format(
706 # self.CODE), self.name)
707 # log.error(str(e), '')
708 # return
709
710 for n, fig in enumerate(self.figures):
711 if self.nrows == 0 or self.nplots == 0:
712 log.warning('No data', self.name)
713 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
714 fig.canvas.manager.set_window_title(self.CODE)
715 continue
716
717 fig.tight_layout()
718 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
719 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
720 fig.canvas.draw()
721
722 if self.save:
723
724 if self.save_labels:
725 labels = self.save_labels
726 else:
727 labels = list(range(self.nrows))
728
729 if self.oneFigure:
730 label = ''
731 else:
732 label = '-{}'.format(labels[n])
733 figname = os.path.join(
734 self.save,
735 self.CODE,
736 '{}{}_{}.png'.format(
737 self.CODE,
738 label,
739 self.getDateTime(self.data.max_time).strftime(
740 '%Y%m%d_%H%M%S'),
741 )
742 )
743 log.log('Saving figure: {}'.format(figname), self.name)
744 if not os.path.isdir(os.path.dirname(figname)):
745 os.makedirs(os.path.dirname(figname))
746 fig.savefig(figname)
747
748 def plot(self):
749 '''
750 Must be defined in the child class
751 '''
752 raise NotImplementedError
753
754 def run(self, dataOut, **kwargs):
755
756 if dataOut.flagNoData and not dataOut.error:
757 return dataOut
758
759 if dataOut.error:
760 coerce = True
761 else:
762 coerce = False
763
764 if self.isConfig is False:
765 self.__setup(**kwargs)
766 self.data.setup()
767 self.isConfig = True
768
769 if dataOut.type == 'Parameters':
770 tm = dataOut.utctimeInit
771 else:
772 tm = dataOut.utctime
773
774 if dataOut.useLocalTime:
775 if not self.localtime:
776 tm += time.timezone
777 else:
778 if self.localtime:
779 tm -= time.timezone
780
781 if self.data and (tm - self.data.min_time) >= self.xrange*60*60:
782 self.__plot()
783 self.data.setup()
784 self.clear_figures()
785
786 self.data.update(dataOut, tm)
787
788 if self.isPlotConfig is False:
789 self.__setup_plot()
790 self.isPlotConfig = True
791
792 if self.realtime:
793 self.__plot()
794 else:
795 self.__throttle_plot(self.__plot, coerce=coerce)
796
797 figpause(0.001)
798
799 def close(self):
800
801 if self.data and self.pause:
802 figpause(10)
803
@@ -1,112 +1,119
1 ## CHANGELOG:
1 ## CHANGELOG:
2
2
3 ### 3.0
4 * Python 3.x compatible
5 * New architecture with multiprocessing and IPC communication
6 * Add @MPDecorator for multiprocessing Units and Operations
7 * Added new type of operation `external` for non-locking operations
8 * New plotting architecture with buffering/throttle capabilities to speed up plots
9
3 ### 2.3
10 ### 2.3
4 * Added support for Madrigal formats (reading/writing).
11 * Added support for Madrigal formats (reading/writing).
5 * Added support for reading BLTR parameters (*.sswma).
12 * Added support for reading BLTR parameters (*.sswma).
6 * Added support for reading Julia format (*.dat).
13 * Added support for reading Julia format (*.dat).
7 * Added high order function `MPProject` for multiprocessing scripts.
14 * Added high order function `MPProject` for multiprocessing scripts.
8 * Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc).
15 * Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc).
9 * Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts.
16 * Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts.
10 * Added support for sending realtime graphic to web server.
17 * Added support for sending realtime graphic to web server.
11 * GUI command `schain` is now `schainGUI`.
18 * GUI command `schain` is now `schainGUI`.
12 * Added a CLI tool named `schain`.
19 * Added a CLI tool named `schain`.
13 * Scripts templates can be now generated with `schain generate`.
20 * Scripts templates can be now generated with `schain generate`.
14 * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters.
21 * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters.
15 * `schain xml` to run xml scripts.
22 * `schain xml` to run xml scripts.
16 * Added suggestions when parameters are poorly written.
23 * Added suggestions when parameters are poorly written.
17 * `Controller.start()` now runs in a different process than the process calling it.
24 * `Controller.start()` now runs in a different process than the process calling it.
18 * Added `schainpy.utils.log` for log standarization.
25 * Added `schainpy.utils.log` for log standarization.
19 * Running script on online mode no longer ignores date and hour. Issue #1109.
26 * Running script on online mode no longer ignores date and hour. Issue #1109.
20 * Added support for receving voltage data directly from JARS (tcp, ipc).
27 * Added support for receving voltage data directly from JARS (tcp, ipc).
21 * Updated README for MAC OS GUI installation.
28 * Updated README for MAC OS GUI installation.
22 * Setup now installs numpy.
29 * Setup now installs numpy.
23
30
24 ### 2.2.6
31 ### 2.2.6
25 * Graphics generated by the GUI are now the same as generated by scripts. Issue #1074.
32 * Graphics generated by the GUI are now the same as generated by scripts. Issue #1074.
26 * Added support for C extensions.
33 * Added support for C extensions.
27 * Function `hildebrand_sehkon` optimized with a C wrapper.
34 * Function `hildebrand_sehkon` optimized with a C wrapper.
28 * Numpy version updated.
35 * Numpy version updated.
29 * Migration to GIT.
36 * Migration to GIT.
30
37
31 ### 2.2.5:
38 ### 2.2.5:
32 * splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI.
39 * splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI.
33 * nProfiles of USRP data (hdf5) is the number of profiles thera are in one second.
40 * nProfiles of USRP data (hdf5) is the number of profiles thera are in one second.
34 * jroPlotter works directly with data objects instead of dictionaries
41 * jroPlotter works directly with data objects instead of dictionaries
35 * script "schain" was added to Signal Chain installer
42 * script "schain" was added to Signal Chain installer
36
43
37 ### 2.2.4.1:
44 ### 2.2.4.1:
38 * jroIO_usrp.py is update to read Sandra's data
45 * jroIO_usrp.py is update to read Sandra's data
39 * decimation in Spectra and RTI plots is always enabled.
46 * decimation in Spectra and RTI plots is always enabled.
40 * time* window option added to GUI
47 * time* window option added to GUI
41
48
42 ### 2.2.4:
49 ### 2.2.4:
43 * jroproc_spectra_lags.py added to schainpy
50 * jroproc_spectra_lags.py added to schainpy
44 * Bug fixed in schainGUI: ProcUnit was created with the same id in some cases.
51 * Bug fixed in schainGUI: ProcUnit was created with the same id in some cases.
45 * Bug fixed in jroHeaderIO: Header size validation.
52 * Bug fixed in jroHeaderIO: Header size validation.
46
53
47 ### 2.2.3.1:
54 ### 2.2.3.1:
48 * Filtering block by time has been added.
55 * Filtering block by time has been added.
49 * Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked
56 * Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked
50 properly but the next days did not.
57 properly but the next days did not.
51
58
52 ### 2.2.3:
59 ### 2.2.3:
53 * Bug fixed in GUI: Error getting(reading) Code value
60 * Bug fixed in GUI: Error getting(reading) Code value
54 * Bug fixed in GUI: Flip option always needs channelList field
61 * Bug fixed in GUI: Flip option always needs channelList field
55 * Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value
62 * Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value
56 was modified for every branch (because this was a reference). It was modified in data.copy()
63 was modified for every branch (because this was a reference). It was modified in data.copy()
57 * Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList.
64 * Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList.
58
65
59 ### 2.2.2:
66 ### 2.2.2:
60 * VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested
67 * VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested
61 * Rawdata and testRawdata.py added to Signal Chain project
68 * Rawdata and testRawdata.py added to Signal Chain project
62
69
63 ### 2.2.1:
70 ### 2.2.1:
64 * Bugs fixed in GUI
71 * Bugs fixed in GUI
65 * Views were improved in GUI
72 * Views were improved in GUI
66 * Support to MST* ISR experiments
73 * Support to MST* ISR experiments
67 * Bug fixed getting noise using hyldebrant. (minimum number of points > 20%)
74 * Bug fixed getting noise using hyldebrant. (minimum number of points > 20%)
68 * handleError added to jroplotter.py
75 * handleError added to jroplotter.py
69
76
70 ### 2.2.0:
77 ### 2.2.0:
71 * GUI: use of external plotter
78 * GUI: use of external plotter
72 * Compatible with matplotlib 1.5.0
79 * Compatible with matplotlib 1.5.0
73
80
74 ### 2.1.5:
81 ### 2.1.5:
75 * serializer module added to Signal Chain
82 * serializer module added to Signal Chain
76 * jroplotter.py added to Signal Chain
83 * jroplotter.py added to Signal Chain
77
84
78 ### 2.1.4.2:
85 ### 2.1.4.2:
79 * A new Plotter Class was added
86 * A new Plotter Class was added
80 * Project.start() does not accept filename as a parameter anymore
87 * Project.start() does not accept filename as a parameter anymore
81
88
82 ### 2.1.4.1:
89 ### 2.1.4.1:
83 * Send notifications when an error different to ValueError is detected
90 * Send notifications when an error different to ValueError is detected
84
91
85 ### 2.1.4:
92 ### 2.1.4:
86 * Sending error notifications to signal chain administrator
93 * Sending error notifications to signal chain administrator
87 * Login to email server added
94 * Login to email server added
88
95
89 ### 2.1.3.3:
96 ### 2.1.3.3:
90 * Colored Button Icons were added to GUI
97 * Colored Button Icons were added to GUI
91
98
92 ### 2.1.3.2:
99 ### 2.1.3.2:
93 * GUI: user interaction enhanced
100 * GUI: user interaction enhanced
94 * controller_api.py: Safe access to ControllerThead
101 * controller_api.py: Safe access to ControllerThead
95
102
96 ### 2.1.3.1:
103 ### 2.1.3.1:
97 * GUI: every icon were resized
104 * GUI: every icon were resized
98 * jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file
105 * jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file
99
106
100 ### 2.1.3:
107 ### 2.1.3:
101 * jroplot_heispectra.py: SpectraHeisScope was not showing the right channels
108 * jroplot_heispectra.py: SpectraHeisScope was not showing the right channels
102 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value),
109 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value),
103 Bug fixed selecting heights by block (selecting profiles instead heights)
110 Bug fixed selecting heights by block (selecting profiles instead heights)
104 * jroproc_voltage.py: New feature added: decoding data by block using FFT.
111 * jroproc_voltage.py: New feature added: decoding data by block using FFT.
105 * jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits.
112 * jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits.
106 * jroIO_heispectra.py: Channel index list does not exist.
113 * jroIO_heispectra.py: Channel index list does not exist.
107
114
108 ### 2.1.2:
115 ### 2.1.2:
109 * jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread
116 * jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread
110 Server thread opens and closes remote server each time file list is sent
117 Server thread opens and closes remote server each time file list is sent
111 * jroplot_spectra.py: Noise path was not being created when noise data is saved.
118 * jroplot_spectra.py: Noise path was not being created when noise data is saved.
112 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00] No newline at end of file
119 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00]
@@ -1,506 +1,506
1 """
1 """
2 The admin module contains all administrative classes relating to the schain python api.
2 The admin module contains all administrative classes relating to the schain python api.
3
3
4 The main role of this module is to send some reports. It contains a
4 The main role of this module is to send some reports. It contains a
5 notification class and a standard error handing class.
5 notification class and a standard error handing class.
6
6
7 $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
7 $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
8 """
8 """
9 import os
9 import os
10 import sys
10 import sys
11 import time
11 import time
12 import traceback
12 import traceback
13 import smtplib
13 import smtplib
14 if sys.version[0] == '3':
14 if sys.version[0] == '3':
15 from configparser import ConfigParser
15 from configparser import ConfigParser
16 else:
16 else:
17 from ConfigParser import ConfigParser
17 from ConfigParser import ConfigParser
18 import io
18 import io
19 from threading import Thread
19 from threading import Thread
20 from multiprocessing import Process
20 from multiprocessing import Process
21 from email.mime.text import MIMEText
21 from email.mime.text import MIMEText
22 from email.mime.application import MIMEApplication
22 from email.mime.application import MIMEApplication
23 from email.mime.multipart import MIMEMultipart
23 from email.mime.multipart import MIMEMultipart
24
24
25 import schainpy
25 import schainpy
26 from schainpy.utils import log
26 from schainpy.utils import log
27 from schainpy.model.graphics.jroplot_data import popup
27 from schainpy.model.graphics.jroplot_base import popup
28
28
29 def get_path():
29 def get_path():
30 '''
30 '''
31 Return schainpy path
31 Return schainpy path
32 '''
32 '''
33
33
34 try:
34 try:
35 root = __file__
35 root = __file__
36 if os.path.islink(root):
36 if os.path.islink(root):
37 root = os.path.realpath(root)
37 root = os.path.realpath(root)
38
38
39 return os.path.dirname(os.path.abspath(root))
39 return os.path.dirname(os.path.abspath(root))
40 except:
40 except:
41 log.error('I am sorry, but something is wrong... __file__ not found')
41 log.error('I am sorry, but something is wrong... __file__ not found')
42
42
43 class Alarm(Process):
43 class Alarm(Process):
44 '''
44 '''
45 modes:
45 modes:
46 0 - All
46 0 - All
47 1 - Send email
47 1 - Send email
48 2 - Popup message
48 2 - Popup message
49 3 - Sound alarm
49 3 - Sound alarm
50 4 - Send to alarm system TODO
50 4 - Send to alarm system TODO
51 '''
51 '''
52
52
53 def __init__(self, modes=[], **kwargs):
53 def __init__(self, modes=[], **kwargs):
54 Process.__init__(self)
54 Process.__init__(self)
55 self.modes = modes
55 self.modes = modes
56 self.kwargs = kwargs
56 self.kwargs = kwargs
57
57
58 @staticmethod
58 @staticmethod
59 def play_sound():
59 def play_sound():
60 sound = os.path.join(get_path(), 'alarm1.oga')
60 sound = os.path.join(get_path(), 'alarm1.oga')
61 if os.path.exists(sound):
61 if os.path.exists(sound):
62 for __ in range(2):
62 for __ in range(2):
63 os.system('paplay {}'.format(sound))
63 os.system('paplay {}'.format(sound))
64 time.sleep(0.5)
64 time.sleep(0.5)
65 else:
65 else:
66 log.warning('Unable to play alarm, sound file not found', 'ADMIN')
66 log.warning('Unable to play alarm, sound file not found', 'ADMIN')
67
67
68 @staticmethod
68 @staticmethod
69 def send_email(**kwargs):
69 def send_email(**kwargs):
70 notifier = SchainNotify()
70 notifier = SchainNotify()
71 print(kwargs)
71 print(kwargs)
72 notifier.notify(**kwargs)
72 notifier.notify(**kwargs)
73
73
74 @staticmethod
74 @staticmethod
75 def show_popup(message):
75 def show_popup(message):
76 if isinstance(message, list):
76 if isinstance(message, list):
77 message = message[-1]
77 message = message[-1]
78 popup(message)
78 popup(message)
79
79
80 @staticmethod
80 @staticmethod
81 def send_alarm():
81 def send_alarm():
82 pass
82 pass
83
83
84 @staticmethod
84 @staticmethod
85 def get_kwargs(kwargs, keys):
85 def get_kwargs(kwargs, keys):
86 ret = {}
86 ret = {}
87 for key in keys:
87 for key in keys:
88 ret[key] = kwargs[key]
88 ret[key] = kwargs[key]
89 return ret
89 return ret
90
90
91 def run(self):
91 def run(self):
92 tasks = {
92 tasks = {
93 1 : self.send_email,
93 1 : self.send_email,
94 2 : self.show_popup,
94 2 : self.show_popup,
95 3 : self.play_sound,
95 3 : self.play_sound,
96 4 : self.send_alarm,
96 4 : self.send_alarm,
97 }
97 }
98
98
99 tasks_args = {
99 tasks_args = {
100 1: ['email', 'message', 'subject', 'subtitle', 'filename'],
100 1: ['email', 'message', 'subject', 'subtitle', 'filename'],
101 2: ['message'],
101 2: ['message'],
102 3: [],
102 3: [],
103 4: [],
103 4: [],
104 }
104 }
105 procs = []
105 procs = []
106 for mode in self.modes:
106 for mode in self.modes:
107 if 0 in self.modes:
107 if 0 in self.modes:
108 for x in tasks:
108 for x in tasks:
109 t = Thread(target=tasks[x], kwargs=self.get_kwargs(self.kwargs, tasks_args[x]))
109 t = Thread(target=tasks[x], kwargs=self.get_kwargs(self.kwargs, tasks_args[x]))
110 t.start()
110 t.start()
111 procs.append(t)
111 procs.append(t)
112 break
112 break
113 else:
113 else:
114 t = Thread(target=tasks[mode], kwargs=self.get_kwargs(self.kwargs, tasks_args[mode]))
114 t = Thread(target=tasks[mode], kwargs=self.get_kwargs(self.kwargs, tasks_args[mode]))
115 t.start()
115 t.start()
116 procs.append(t)
116 procs.append(t)
117 for t in procs:
117 for t in procs:
118 t.join()
118 t.join()
119
119
120
120
121 class SchainConfigure():
121 class SchainConfigure():
122
122
123 __DEFAULT_ADMINISTRATOR_EMAIL = "juan.espinoza@jro.igp.gob.pe"
123 __DEFAULT_ADMINISTRATOR_EMAIL = "juan.espinoza@jro.igp.gob.pe"
124 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
124 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
125 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
125 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
126 __DEFAULT_SENDER_PASS = ""
126 __DEFAULT_SENDER_PASS = ""
127
127
128 __SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
128 __SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
129 __SCHAIN_EMAIL_SERVER = "MAILSERVER"
129 __SCHAIN_EMAIL_SERVER = "MAILSERVER"
130 __SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
130 __SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
131 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
131 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
132
132
133 def __init__(self, initFile = None):
133 def __init__(self, initFile = None):
134
134
135 # Set configuration file
135 # Set configuration file
136 if (initFile == None):
136 if (initFile == None):
137 self.__confFilePath = "/etc/schain.conf"
137 self.__confFilePath = "/etc/schain.conf"
138 else:
138 else:
139 self.__confFilePath = initFile
139 self.__confFilePath = initFile
140
140
141 # open configuration file
141 # open configuration file
142 try:
142 try:
143 self.__confFile = open(self.__confFilePath, "r")
143 self.__confFile = open(self.__confFilePath, "r")
144 except IOError:
144 except IOError:
145 # can't read from file - use all hard-coded values
145 # can't read from file - use all hard-coded values
146 self.__initFromHardCode()
146 self.__initFromHardCode()
147 return
147 return
148
148
149 # create Parser using standard module ConfigParser
149 # create Parser using standard module ConfigParser
150 self.__parser = ConfigParser()
150 self.__parser = ConfigParser()
151
151
152 # read conf file into a StringIO with "[madrigal]\n" section heading prepended
152 # read conf file into a StringIO with "[madrigal]\n" section heading prepended
153 strConfFile = io.StringIO("[schain]\n" + self.__confFile.read())
153 strConfFile = io.StringIO("[schain]\n" + self.__confFile.read())
154
154
155 # parse StringIO configuration file
155 # parse StringIO configuration file
156 self.__parser.readfp(strConfFile)
156 self.__parser.readfp(strConfFile)
157
157
158 # read information from configuration file
158 # read information from configuration file
159 self.__readConfFile()
159 self.__readConfFile()
160
160
161 # close conf file
161 # close conf file
162 self.__confFile.close()
162 self.__confFile.close()
163
163
164
164
165 def __initFromHardCode(self):
165 def __initFromHardCode(self):
166
166
167 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
167 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
168 self.__sender_pass = self.__DEFAULT_SENDER_PASS
168 self.__sender_pass = self.__DEFAULT_SENDER_PASS
169 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
169 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
170 self.__email_server = self.__DEFAULT_EMAIL_SERVER
170 self.__email_server = self.__DEFAULT_EMAIL_SERVER
171
171
172 def __readConfFile(self):
172 def __readConfFile(self):
173 """__readConfFile is a private helper function that reads information from the parsed config file.
173 """__readConfFile is a private helper function that reads information from the parsed config file.
174
174
175 Inputs: None
175 Inputs: None
176
176
177 Returns: Void.
177 Returns: Void.
178
178
179 Affects: Initializes class member variables that are found in the config file.
179 Affects: Initializes class member variables that are found in the config file.
180
180
181 Exceptions: MadrigalError thrown if any key not found.
181 Exceptions: MadrigalError thrown if any key not found.
182 """
182 """
183
183
184 # get the sender email
184 # get the sender email
185 try:
185 try:
186 self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
186 self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
187 except:
187 except:
188 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
188 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
189
189
190 # get the sender password
190 # get the sender password
191 try:
191 try:
192 self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
192 self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
193 except:
193 except:
194 self.__sender_pass = self.__DEFAULT_SENDER_PASS
194 self.__sender_pass = self.__DEFAULT_SENDER_PASS
195
195
196 # get the administrator email
196 # get the administrator email
197 try:
197 try:
198 self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
198 self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
199 except:
199 except:
200 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
200 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
201
201
202 # get the server email
202 # get the server email
203 try:
203 try:
204 self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
204 self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
205 except:
205 except:
206 self.__email_server = self.__DEFAULT_EMAIL_SERVER
206 self.__email_server = self.__DEFAULT_EMAIL_SERVER
207
207
208 def getEmailServer(self):
208 def getEmailServer(self):
209
209
210 return self.__email_server
210 return self.__email_server
211
211
212 def getSenderEmail(self):
212 def getSenderEmail(self):
213
213
214 return self.__sender_email
214 return self.__sender_email
215
215
216 def getSenderPass(self):
216 def getSenderPass(self):
217
217
218 return self.__sender_pass
218 return self.__sender_pass
219
219
220 def getAdminEmail(self):
220 def getAdminEmail(self):
221
221
222 return self.__admin_email
222 return self.__admin_email
223
223
224 class SchainNotify:
224 class SchainNotify:
225 """SchainNotify is an object used to send messages to an administrator about a Schain software.
225 """SchainNotify is an object used to send messages to an administrator about a Schain software.
226
226
227 This object provides functions needed to send messages to an administrator about a Schain , for now
227 This object provides functions needed to send messages to an administrator about a Schain , for now
228 only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
228 only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
229
229
230 Usage example:
230 Usage example:
231
231
232 import schainpy.admin
232 import schainpy.admin
233
233
234 try:
234 try:
235
235
236 adminObj = schainpy.admin.SchainNotify()
236 adminObj = schainpy.admin.SchainNotify()
237 adminObj.sendAlert('This is important!', 'Important Message')
237 adminObj.sendAlert('This is important!', 'Important Message')
238
238
239 except schainpy.admin.SchainError, e:
239 except schainpy.admin.SchainError, e:
240
240
241 print e.getExceptionStr()
241 print e.getExceptionStr()
242
242
243
243
244 Non-standard Python modules used:
244 Non-standard Python modules used:
245 None
245 None
246
246
247 Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
247 Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
248 throwing exceptions, since this is the class that will generally be called when there is a problem.
248 throwing exceptions, since this is the class that will generally be called when there is a problem.
249
249
250 Change history:
250 Change history:
251
251
252 Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
252 Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
253 """
253 """
254
254
255 #constants
255 #constants
256
256
257 def __init__(self):
257 def __init__(self):
258 """__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
258 """__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
259
259
260 Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
260 Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
261 this is the class that will generally be called when there is a problem.
261 this is the class that will generally be called when there is a problem.
262
262
263 Inputs: Existing SchainDB object, by default = None.
263 Inputs: Existing SchainDB object, by default = None.
264
264
265 Returns: void
265 Returns: void
266
266
267 Affects: Initializes self.__binDir.
267 Affects: Initializes self.__binDir.
268
268
269 Exceptions: None.
269 Exceptions: None.
270 """
270 """
271
271
272 # note that the main configuration file is unavailable
272 # note that the main configuration file is unavailable
273 # the best that can be done is send an email to root using localhost mailserver
273 # the best that can be done is send an email to root using localhost mailserver
274 confObj = SchainConfigure()
274 confObj = SchainConfigure()
275
275
276 self.__emailFromAddress = confObj.getSenderEmail()
276 self.__emailFromAddress = confObj.getSenderEmail()
277 self.__emailPass = confObj.getSenderPass()
277 self.__emailPass = confObj.getSenderPass()
278 self.__emailToAddress = confObj.getAdminEmail()
278 self.__emailToAddress = confObj.getAdminEmail()
279 self.__emailServer = confObj.getEmailServer()
279 self.__emailServer = confObj.getEmailServer()
280
280
281 def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
281 def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
282
282
283 if not email_to:
283 if not email_to:
284 return 0
284 return 0
285
285
286 if not self.__emailServer:
286 if not self.__emailServer:
287 return 0
287 return 0
288
288
289 log.success('Sending email to {}...'.format(email_to), 'System')
289 log.success('Sending email to {}...'.format(email_to), 'System')
290
290
291 msg = MIMEMultipart()
291 msg = MIMEMultipart()
292 msg['Subject'] = subject
292 msg['Subject'] = subject
293 msg['From'] = "(Python SChain API): " + email_from
293 msg['From'] = "(Python SChain API): " + email_from
294 msg['Reply-to'] = email_from
294 msg['Reply-to'] = email_from
295 msg['To'] = email_to
295 msg['To'] = email_to
296
296
297 # That is what u see if dont have an email reader:
297 # That is what u see if dont have an email reader:
298 msg.preamble = 'SChainPy'
298 msg.preamble = 'SChainPy'
299
299
300 if html_format:
300 if html_format:
301 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
301 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
302 message = "<html>\n" + message + '</html>'
302 message = "<html>\n" + message + '</html>'
303
303
304 # This is the textual part:
304 # This is the textual part:
305 part = MIMEText(message, "html")
305 part = MIMEText(message, "html")
306 else:
306 else:
307 message = subject + "\n" + subtitle + "\n" + message
307 message = subject + "\n" + subtitle + "\n" + message
308 part = MIMEText(message)
308 part = MIMEText(message)
309
309
310 msg.attach(part)
310 msg.attach(part)
311
311
312 if filename and os.path.isfile(filename):
312 if filename and os.path.isfile(filename):
313 # This is the binary part(The Attachment):
313 # This is the binary part(The Attachment):
314 part = MIMEApplication(open(filename,"rb").read())
314 part = MIMEApplication(open(filename,"rb").read())
315 part.add_header('Content-Disposition',
315 part.add_header('Content-Disposition',
316 'attachment',
316 'attachment',
317 filename=os.path.basename(filename))
317 filename=os.path.basename(filename))
318 msg.attach(part)
318 msg.attach(part)
319
319
320 # Create an instance in SMTP server
320 # Create an instance in SMTP server
321 try:
321 try:
322 smtp = smtplib.SMTP(self.__emailServer)
322 smtp = smtplib.SMTP(self.__emailServer)
323 except:
323 except:
324 log.error('Could not connect to server {}'.format(self.__emailServer), 'System')
324 log.error('Could not connect to server {}'.format(self.__emailServer), 'System')
325 return 0
325 return 0
326
326
327 # Start the server:
327 # Start the server:
328 # smtp.ehlo()
328 # smtp.ehlo()
329 if self.__emailPass:
329 if self.__emailPass:
330 smtp.login(self.__emailFromAddress, self.__emailPass)
330 smtp.login(self.__emailFromAddress, self.__emailPass)
331
331
332 # Send the email
332 # Send the email
333 try:
333 try:
334 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
334 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
335 except:
335 except:
336 log.error('Could not send the email to {}'.format(msg['To']), 'System')
336 log.error('Could not send the email to {}'.format(msg['To']), 'System')
337 smtp.quit()
337 smtp.quit()
338 return 0
338 return 0
339
339
340 smtp.quit()
340 smtp.quit()
341
341
342 log.success('Email sent ', 'System')
342 log.success('Email sent ', 'System')
343
343
344 return 1
344 return 1
345
345
346 def sendAlert(self, message, subject = "", subtitle="", filename=""):
346 def sendAlert(self, message, subject = "", subtitle="", filename=""):
347 """sendAlert sends an email with the given message and optional title.
347 """sendAlert sends an email with the given message and optional title.
348
348
349 Inputs: message (string), and optional title (string)
349 Inputs: message (string), and optional title (string)
350
350
351 Returns: void
351 Returns: void
352
352
353 Affects: none
353 Affects: none
354
354
355 Exceptions: None.
355 Exceptions: None.
356 """
356 """
357
357
358 if not self.__emailToAddress:
358 if not self.__emailToAddress:
359 return 0
359 return 0
360
360
361 print("***** Sending alert to %s *****" %self.__emailToAddress)
361 print("***** Sending alert to %s *****" %self.__emailToAddress)
362 # set up message
362 # set up message
363
363
364 sent=self.sendEmail(email_from=self.__emailFromAddress,
364 sent=self.sendEmail(email_from=self.__emailFromAddress,
365 email_to=self.__emailToAddress,
365 email_to=self.__emailToAddress,
366 subject=subject,
366 subject=subject,
367 message=message,
367 message=message,
368 subtitle=subtitle,
368 subtitle=subtitle,
369 filename=filename)
369 filename=filename)
370
370
371 if not sent:
371 if not sent:
372 return 0
372 return 0
373
373
374 return 1
374 return 1
375
375
376 def notify(self, email, message, subject = "", subtitle="", filename=""):
376 def notify(self, email, message, subject = "", subtitle="", filename=""):
377 """notify sends an email with the given message and title to email.
377 """notify sends an email with the given message and title to email.
378
378
379 Inputs: email (string), message (string), and subject (string)
379 Inputs: email (string), message (string), and subject (string)
380
380
381 Returns: void
381 Returns: void
382
382
383 Affects: none
383 Affects: none
384
384
385 Exceptions: None.
385 Exceptions: None.
386 """
386 """
387
387
388 if email is None:
388 if email is None:
389 email = self.__emailToAddress
389 email = self.__emailToAddress
390
390
391 self.sendEmail(
391 self.sendEmail(
392 email_from=self.__emailFromAddress,
392 email_from=self.__emailFromAddress,
393 email_to=email,
393 email_to=email,
394 subject=subject,
394 subject=subject,
395 message=message,
395 message=message,
396 subtitle=subtitle,
396 subtitle=subtitle,
397 filename=filename
397 filename=filename
398 )
398 )
399
399
400
400
401 class SchainError(Exception):
401 class SchainError(Exception):
402 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
402 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
403
403
404 Usage example:
404 Usage example:
405
405
406 import sys, traceback
406 import sys, traceback
407 import schainpy.admin
407 import schainpy.admin
408
408
409 try:
409 try:
410
410
411 test = open('ImportantFile.txt', 'r')
411 test = open('ImportantFile.txt', 'r')
412
412
413 except:
413 except:
414
414
415 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
415 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
416 traceback.format_exception(sys.exc_info()[0],
416 traceback.format_exception(sys.exc_info()[0],
417 sys.exc_info()[1],
417 sys.exc_info()[1],
418 sys.exc_info()[2]))
418 sys.exc_info()[2]))
419 """
419 """
420
420
421
421
422 def __init__(self, strInterpretation, exceptionList=None):
422 def __init__(self, strInterpretation, exceptionList=None):
423 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
423 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
424
424
425 Inputs:
425 Inputs:
426 strIntepretation - A string representing the programmer's interpretation of
426 strIntepretation - A string representing the programmer's interpretation of
427 why the exception occurred
427 why the exception occurred
428
428
429 exceptionList - a list of strings completely describing the exception.
429 exceptionList - a list of strings completely describing the exception.
430 Generated by traceback.format_exception(sys.exc_info()[0],
430 Generated by traceback.format_exception(sys.exc_info()[0],
431 sys.exc_info()[1],
431 sys.exc_info()[1],
432 sys.exc_info()[2])
432 sys.exc_info()[2])
433
433
434 Returns: Void.
434 Returns: Void.
435
435
436 Affects: Initializes class member variables _strInterp, _strExcList.
436 Affects: Initializes class member variables _strInterp, _strExcList.
437
437
438 Exceptions: None.
438 Exceptions: None.
439 """
439 """
440
440
441 if not exceptionList:
441 if not exceptionList:
442 exceptionList = traceback.format_exception(sys.exc_info()[0],
442 exceptionList = traceback.format_exception(sys.exc_info()[0],
443 sys.exc_info()[1],
443 sys.exc_info()[1],
444 sys.exc_info()[2])
444 sys.exc_info()[2])
445
445
446 self._strInterp = strInterpretation
446 self._strInterp = strInterpretation
447 self._strExcList = exceptionList
447 self._strExcList = exceptionList
448
448
449
449
450 def getExceptionStr(self):
450 def getExceptionStr(self):
451 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
451 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
452
452
453 Inputs: None
453 Inputs: None
454
454
455 Returns: A formatted string ready for printing completely describing the exception.
455 Returns: A formatted string ready for printing completely describing the exception.
456
456
457 Affects: None
457 Affects: None
458
458
459 Exceptions: None.
459 Exceptions: None.
460 """
460 """
461 excStr = ''
461 excStr = ''
462 excStr = excStr + self._strInterp + '\n\n'
462 excStr = excStr + self._strInterp + '\n\n'
463
463
464 if self._strExcList != None:
464 if self._strExcList != None:
465 for item in self._strExcList:
465 for item in self._strExcList:
466 excStr = excStr + str(item) + '\n'
466 excStr = excStr + str(item) + '\n'
467
467
468 return excStr
468 return excStr
469
469
470 def __str__(self):
470 def __str__(self):
471
471
472 return(self.getExceptionStr())
472 return(self.getExceptionStr())
473
473
474
474
475 def getExceptionHtml(self):
475 def getExceptionHtml(self):
476 """ getExceptionHtml returns an Html formatted string completely describing the exception.
476 """ getExceptionHtml returns an Html formatted string completely describing the exception.
477
477
478 Inputs: None
478 Inputs: None
479
479
480 Returns: A formatted string ready for printing completely describing the exception.
480 Returns: A formatted string ready for printing completely describing the exception.
481
481
482 Affects: None
482 Affects: None
483
483
484 Exceptions: None.
484 Exceptions: None.
485 """
485 """
486
486
487 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
487 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
488 excStr = excStr + self._strInterp + '\n<BR>\n'
488 excStr = excStr + self._strInterp + '\n<BR>\n'
489
489
490 if self._strExcList != None:
490 if self._strExcList != None:
491 for item in self._strExcList:
491 for item in self._strExcList:
492 excStr = excStr + str(item) + '\n<BR>'
492 excStr = excStr + str(item) + '\n<BR>'
493
493
494 return excStr
494 return excStr
495
495
496 class SchainWarning(Exception):
496 class SchainWarning(Exception):
497 pass
497 pass
498
498
499
499
500 if __name__ == '__main__':
500 if __name__ == '__main__':
501
501
502 test = SchainNotify()
502 test = SchainNotify()
503
503
504 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
504 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
505
505
506 print('Hopefully message sent - check.') No newline at end of file
506 print('Hopefully message sent - check.')
@@ -1,1265 +1,1263
1 '''
1 '''
2 Updated on January , 2018, for multiprocessing purposes
2 Updated on January , 2018, for multiprocessing purposes
3 Author: Sergio Cortez
3 Author: Sergio Cortez
4 Created on September , 2012
4 Created on September , 2012
5 '''
5 '''
6 from platform import python_version
6 from platform import python_version
7 import sys
7 import sys
8 import ast
8 import ast
9 import datetime
9 import datetime
10 import traceback
10 import traceback
11 import math
11 import math
12 import time
12 import time
13 import zmq
13 import zmq
14 from multiprocessing import Process, cpu_count
14 from multiprocessing import Process, cpu_count
15 from threading import Thread
15 from threading import Thread
16 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
16 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
17 from xml.dom import minidom
17 from xml.dom import minidom
18
18
19
19
20 from schainpy.admin import Alarm, SchainWarning
20 from schainpy.admin import Alarm, SchainWarning
21
21
22 ### Temporary imports!!!
22 ### Temporary imports!!!
23 # from schainpy.model import *
23 # from schainpy.model import *
24 from schainpy.model.io import *
24 from schainpy.model.io import *
25 from schainpy.model.graphics import *
25 from schainpy.model.graphics import *
26 from schainpy.model.proc.jroproc_base import *
26 from schainpy.model.proc.jroproc_base import *
27 from schainpy.model.proc.bltrproc_parameters import *
27 from schainpy.model.proc.bltrproc_parameters import *
28 from schainpy.model.proc.jroproc_spectra import *
28 from schainpy.model.proc.jroproc_spectra import *
29 from schainpy.model.proc.jroproc_voltage import *
29 from schainpy.model.proc.jroproc_voltage import *
30 from schainpy.model.proc.jroproc_parameters import *
30 from schainpy.model.proc.jroproc_parameters import *
31 from schainpy.model.utils.jroutils_publish import *
31 from schainpy.model.utils.jroutils_publish import *
32 from schainpy.utils import log
32 from schainpy.utils import log
33 ###
33 ###
34
34
35 DTYPES = {
35 DTYPES = {
36 'Voltage': '.r',
36 'Voltage': '.r',
37 'Spectra': '.pdata'
37 'Spectra': '.pdata'
38 }
38 }
39
39
40
40
41 def MPProject(project, n=cpu_count()):
41 def MPProject(project, n=cpu_count()):
42 '''
42 '''
43 Project wrapper to run schain in n processes
43 Project wrapper to run schain in n processes
44 '''
44 '''
45
45
46 rconf = project.getReadUnitObj()
46 rconf = project.getReadUnitObj()
47 op = rconf.getOperationObj('run')
47 op = rconf.getOperationObj('run')
48 dt1 = op.getParameterValue('startDate')
48 dt1 = op.getParameterValue('startDate')
49 dt2 = op.getParameterValue('endDate')
49 dt2 = op.getParameterValue('endDate')
50 tm1 = op.getParameterValue('startTime')
50 tm1 = op.getParameterValue('startTime')
51 tm2 = op.getParameterValue('endTime')
51 tm2 = op.getParameterValue('endTime')
52 days = (dt2 - dt1).days
52 days = (dt2 - dt1).days
53
53
54 for day in range(days + 1):
54 for day in range(days + 1):
55 skip = 0
55 skip = 0
56 cursor = 0
56 cursor = 0
57 processes = []
57 processes = []
58 dt = dt1 + datetime.timedelta(day)
58 dt = dt1 + datetime.timedelta(day)
59 dt_str = dt.strftime('%Y/%m/%d')
59 dt_str = dt.strftime('%Y/%m/%d')
60 reader = JRODataReader()
60 reader = JRODataReader()
61 paths, files = reader.searchFilesOffLine(path=rconf.path,
61 paths, files = reader.searchFilesOffLine(path=rconf.path,
62 startDate=dt,
62 startDate=dt,
63 endDate=dt,
63 endDate=dt,
64 startTime=tm1,
64 startTime=tm1,
65 endTime=tm2,
65 endTime=tm2,
66 ext=DTYPES[rconf.datatype])
66 ext=DTYPES[rconf.datatype])
67 nFiles = len(files)
67 nFiles = len(files)
68 if nFiles == 0:
68 if nFiles == 0:
69 continue
69 continue
70 skip = int(math.ceil(nFiles / n))
70 skip = int(math.ceil(nFiles / n))
71 while nFiles > cursor * skip:
71 while nFiles > cursor * skip:
72 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
72 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
73 skip=skip)
73 skip=skip)
74 p = project.clone()
74 p = project.clone()
75 p.start()
75 p.start()
76 processes.append(p)
76 processes.append(p)
77 cursor += 1
77 cursor += 1
78
78
79 def beforeExit(exctype, value, trace):
79 def beforeExit(exctype, value, trace):
80 for process in processes:
80 for process in processes:
81 process.terminate()
81 process.terminate()
82 process.join()
82 process.join()
83 print(traceback.print_tb(trace))
83 print(traceback.print_tb(trace))
84
84
85 sys.excepthook = beforeExit
85 sys.excepthook = beforeExit
86
86
87 for process in processes:
87 for process in processes:
88 process.join()
88 process.join()
89 process.terminate()
89 process.terminate()
90
90
91 time.sleep(3)
91 time.sleep(3)
92
92
93 def wait(context):
93 def wait(context):
94
94
95 time.sleep(1)
95 time.sleep(1)
96 c = zmq.Context()
96 c = zmq.Context()
97 receiver = c.socket(zmq.SUB)
97 receiver = c.socket(zmq.SUB)
98 receiver.connect('ipc:///tmp/schain_{}_pub'.format(self.id))
98 receiver.connect('ipc:///tmp/schain_{}_pub'.format(self.id))
99 receiver.setsockopt(zmq.SUBSCRIBE, self.id.encode())
99 receiver.setsockopt(zmq.SUBSCRIBE, self.id.encode())
100 log.error('startinggg')
101 msg = receiver.recv_multipart()[1]
100 msg = receiver.recv_multipart()[1]
102 #log.error(msg)
103 context.terminate()
101 context.terminate()
104
102
105 class ParameterConf():
103 class ParameterConf():
106
104
107 id = None
105 id = None
108 name = None
106 name = None
109 value = None
107 value = None
110 format = None
108 format = None
111
109
112 __formated_value = None
110 __formated_value = None
113
111
114 ELEMENTNAME = 'Parameter'
112 ELEMENTNAME = 'Parameter'
115
113
116 def __init__(self):
114 def __init__(self):
117
115
118 self.format = 'str'
116 self.format = 'str'
119
117
120 def getElementName(self):
118 def getElementName(self):
121
119
122 return self.ELEMENTNAME
120 return self.ELEMENTNAME
123
121
124 def getValue(self):
122 def getValue(self):
125
123
126 value = self.value
124 value = self.value
127 format = self.format
125 format = self.format
128
126
129 if self.__formated_value != None:
127 if self.__formated_value != None:
130
128
131 return self.__formated_value
129 return self.__formated_value
132
130
133 if format == 'obj':
131 if format == 'obj':
134 return value
132 return value
135
133
136 if format == 'str':
134 if format == 'str':
137 self.__formated_value = str(value)
135 self.__formated_value = str(value)
138 return self.__formated_value
136 return self.__formated_value
139
137
140 if value == '':
138 if value == '':
141 raise ValueError('%s: This parameter value is empty' % self.name)
139 raise ValueError('%s: This parameter value is empty' % self.name)
142
140
143 if format == 'list':
141 if format == 'list':
144 strList = value.split(',')
142 strList = value.split(',')
145
143
146 self.__formated_value = strList
144 self.__formated_value = strList
147
145
148 return self.__formated_value
146 return self.__formated_value
149
147
150 if format == 'intlist':
148 if format == 'intlist':
151 '''
149 '''
152 Example:
150 Example:
153 value = (0,1,2)
151 value = (0,1,2)
154 '''
152 '''
155
153
156 new_value = ast.literal_eval(value)
154 new_value = ast.literal_eval(value)
157
155
158 if type(new_value) not in (tuple, list):
156 if type(new_value) not in (tuple, list):
159 new_value = [int(new_value)]
157 new_value = [int(new_value)]
160
158
161 self.__formated_value = new_value
159 self.__formated_value = new_value
162
160
163 return self.__formated_value
161 return self.__formated_value
164
162
165 if format == 'floatlist':
163 if format == 'floatlist':
166 '''
164 '''
167 Example:
165 Example:
168 value = (0.5, 1.4, 2.7)
166 value = (0.5, 1.4, 2.7)
169 '''
167 '''
170
168
171 new_value = ast.literal_eval(value)
169 new_value = ast.literal_eval(value)
172
170
173 if type(new_value) not in (tuple, list):
171 if type(new_value) not in (tuple, list):
174 new_value = [float(new_value)]
172 new_value = [float(new_value)]
175
173
176 self.__formated_value = new_value
174 self.__formated_value = new_value
177
175
178 return self.__formated_value
176 return self.__formated_value
179
177
180 if format == 'date':
178 if format == 'date':
181 strList = value.split('/')
179 strList = value.split('/')
182 intList = [int(x) for x in strList]
180 intList = [int(x) for x in strList]
183 date = datetime.date(intList[0], intList[1], intList[2])
181 date = datetime.date(intList[0], intList[1], intList[2])
184
182
185 self.__formated_value = date
183 self.__formated_value = date
186
184
187 return self.__formated_value
185 return self.__formated_value
188
186
189 if format == 'time':
187 if format == 'time':
190 strList = value.split(':')
188 strList = value.split(':')
191 intList = [int(x) for x in strList]
189 intList = [int(x) for x in strList]
192 time = datetime.time(intList[0], intList[1], intList[2])
190 time = datetime.time(intList[0], intList[1], intList[2])
193
191
194 self.__formated_value = time
192 self.__formated_value = time
195
193
196 return self.__formated_value
194 return self.__formated_value
197
195
198 if format == 'pairslist':
196 if format == 'pairslist':
199 '''
197 '''
200 Example:
198 Example:
201 value = (0,1),(1,2)
199 value = (0,1),(1,2)
202 '''
200 '''
203
201
204 new_value = ast.literal_eval(value)
202 new_value = ast.literal_eval(value)
205
203
206 if type(new_value) not in (tuple, list):
204 if type(new_value) not in (tuple, list):
207 raise ValueError('%s has to be a tuple or list of pairs' % value)
205 raise ValueError('%s has to be a tuple or list of pairs' % value)
208
206
209 if type(new_value[0]) not in (tuple, list):
207 if type(new_value[0]) not in (tuple, list):
210 if len(new_value) != 2:
208 if len(new_value) != 2:
211 raise ValueError('%s has to be a tuple or list of pairs' % value)
209 raise ValueError('%s has to be a tuple or list of pairs' % value)
212 new_value = [new_value]
210 new_value = [new_value]
213
211
214 for thisPair in new_value:
212 for thisPair in new_value:
215 if len(thisPair) != 2:
213 if len(thisPair) != 2:
216 raise ValueError('%s has to be a tuple or list of pairs' % value)
214 raise ValueError('%s has to be a tuple or list of pairs' % value)
217
215
218 self.__formated_value = new_value
216 self.__formated_value = new_value
219
217
220 return self.__formated_value
218 return self.__formated_value
221
219
222 if format == 'multilist':
220 if format == 'multilist':
223 '''
221 '''
224 Example:
222 Example:
225 value = (0,1,2),(3,4,5)
223 value = (0,1,2),(3,4,5)
226 '''
224 '''
227 multiList = ast.literal_eval(value)
225 multiList = ast.literal_eval(value)
228
226
229 if type(multiList[0]) == int:
227 if type(multiList[0]) == int:
230 multiList = ast.literal_eval('(' + value + ')')
228 multiList = ast.literal_eval('(' + value + ')')
231
229
232 self.__formated_value = multiList
230 self.__formated_value = multiList
233
231
234 return self.__formated_value
232 return self.__formated_value
235
233
236 if format == 'bool':
234 if format == 'bool':
237 value = int(value)
235 value = int(value)
238
236
239 if format == 'int':
237 if format == 'int':
240 value = float(value)
238 value = float(value)
241
239
242 format_func = eval(format)
240 format_func = eval(format)
243
241
244 self.__formated_value = format_func(value)
242 self.__formated_value = format_func(value)
245
243
246 return self.__formated_value
244 return self.__formated_value
247
245
248 def updateId(self, new_id):
246 def updateId(self, new_id):
249
247
250 self.id = str(new_id)
248 self.id = str(new_id)
251
249
252 def setup(self, id, name, value, format='str'):
250 def setup(self, id, name, value, format='str'):
253 self.id = str(id)
251 self.id = str(id)
254 self.name = name
252 self.name = name
255 if format == 'obj':
253 if format == 'obj':
256 self.value = value
254 self.value = value
257 else:
255 else:
258 self.value = str(value)
256 self.value = str(value)
259 self.format = str.lower(format)
257 self.format = str.lower(format)
260
258
261 self.getValue()
259 self.getValue()
262
260
263 return 1
261 return 1
264
262
265 def update(self, name, value, format='str'):
263 def update(self, name, value, format='str'):
266
264
267 self.name = name
265 self.name = name
268 self.value = str(value)
266 self.value = str(value)
269 self.format = format
267 self.format = format
270
268
271 def makeXml(self, opElement):
269 def makeXml(self, opElement):
272 if self.name not in ('queue',):
270 if self.name not in ('queue',):
273 parmElement = SubElement(opElement, self.ELEMENTNAME)
271 parmElement = SubElement(opElement, self.ELEMENTNAME)
274 parmElement.set('id', str(self.id))
272 parmElement.set('id', str(self.id))
275 parmElement.set('name', self.name)
273 parmElement.set('name', self.name)
276 parmElement.set('value', self.value)
274 parmElement.set('value', self.value)
277 parmElement.set('format', self.format)
275 parmElement.set('format', self.format)
278
276
279 def readXml(self, parmElement):
277 def readXml(self, parmElement):
280
278
281 self.id = parmElement.get('id')
279 self.id = parmElement.get('id')
282 self.name = parmElement.get('name')
280 self.name = parmElement.get('name')
283 self.value = parmElement.get('value')
281 self.value = parmElement.get('value')
284 self.format = str.lower(parmElement.get('format'))
282 self.format = str.lower(parmElement.get('format'))
285
283
286 # Compatible with old signal chain version
284 # Compatible with old signal chain version
287 if self.format == 'int' and self.name == 'idfigure':
285 if self.format == 'int' and self.name == 'idfigure':
288 self.name = 'id'
286 self.name = 'id'
289
287
290 def printattr(self):
288 def printattr(self):
291
289
292 print('Parameter[%s]: name = %s, value = %s, format = %s, project_id = %s' % (self.id, self.name, self.value, self.format, self.project_id))
290 print('Parameter[%s]: name = %s, value = %s, format = %s, project_id = %s' % (self.id, self.name, self.value, self.format, self.project_id))
293
291
294 class OperationConf():
292 class OperationConf():
295
293
296 ELEMENTNAME = 'Operation'
294 ELEMENTNAME = 'Operation'
297
295
298 def __init__(self):
296 def __init__(self):
299
297
300 self.id = '0'
298 self.id = '0'
301 self.name = None
299 self.name = None
302 self.priority = None
300 self.priority = None
303 self.topic = None
301 self.topic = None
304
302
305 def __getNewId(self):
303 def __getNewId(self):
306
304
307 return int(self.id) * 10 + len(self.parmConfObjList) + 1
305 return int(self.id) * 10 + len(self.parmConfObjList) + 1
308
306
309 def getId(self):
307 def getId(self):
310 return self.id
308 return self.id
311
309
312 def updateId(self, new_id):
310 def updateId(self, new_id):
313
311
314 self.id = str(new_id)
312 self.id = str(new_id)
315
313
316 n = 1
314 n = 1
317 for parmObj in self.parmConfObjList:
315 for parmObj in self.parmConfObjList:
318
316
319 idParm = str(int(new_id) * 10 + n)
317 idParm = str(int(new_id) * 10 + n)
320 parmObj.updateId(idParm)
318 parmObj.updateId(idParm)
321
319
322 n += 1
320 n += 1
323
321
324 def getElementName(self):
322 def getElementName(self):
325
323
326 return self.ELEMENTNAME
324 return self.ELEMENTNAME
327
325
328 def getParameterObjList(self):
326 def getParameterObjList(self):
329
327
330 return self.parmConfObjList
328 return self.parmConfObjList
331
329
332 def getParameterObj(self, parameterName):
330 def getParameterObj(self, parameterName):
333
331
334 for parmConfObj in self.parmConfObjList:
332 for parmConfObj in self.parmConfObjList:
335
333
336 if parmConfObj.name != parameterName:
334 if parmConfObj.name != parameterName:
337 continue
335 continue
338
336
339 return parmConfObj
337 return parmConfObj
340
338
341 return None
339 return None
342
340
343 def getParameterObjfromValue(self, parameterValue):
341 def getParameterObjfromValue(self, parameterValue):
344
342
345 for parmConfObj in self.parmConfObjList:
343 for parmConfObj in self.parmConfObjList:
346
344
347 if parmConfObj.getValue() != parameterValue:
345 if parmConfObj.getValue() != parameterValue:
348 continue
346 continue
349
347
350 return parmConfObj.getValue()
348 return parmConfObj.getValue()
351
349
352 return None
350 return None
353
351
354 def getParameterValue(self, parameterName):
352 def getParameterValue(self, parameterName):
355
353
356 parameterObj = self.getParameterObj(parameterName)
354 parameterObj = self.getParameterObj(parameterName)
357
355
358 # if not parameterObj:
356 # if not parameterObj:
359 # return None
357 # return None
360
358
361 value = parameterObj.getValue()
359 value = parameterObj.getValue()
362
360
363 return value
361 return value
364
362
365 def getKwargs(self):
363 def getKwargs(self):
366
364
367 kwargs = {}
365 kwargs = {}
368
366
369 for parmConfObj in self.parmConfObjList:
367 for parmConfObj in self.parmConfObjList:
370 if self.name == 'run' and parmConfObj.name == 'datatype':
368 if self.name == 'run' and parmConfObj.name == 'datatype':
371 continue
369 continue
372
370
373 kwargs[parmConfObj.name] = parmConfObj.getValue()
371 kwargs[parmConfObj.name] = parmConfObj.getValue()
374
372
375 return kwargs
373 return kwargs
376
374
377 def setup(self, id, name, priority, type, project_id):
375 def setup(self, id, name, priority, type, project_id):
378
376
379 self.id = str(id)
377 self.id = str(id)
380 self.project_id = project_id
378 self.project_id = project_id
381 self.name = name
379 self.name = name
382 self.type = type
380 self.type = type
383 self.priority = priority
381 self.priority = priority
384 self.parmConfObjList = []
382 self.parmConfObjList = []
385
383
386 def removeParameters(self):
384 def removeParameters(self):
387
385
388 for obj in self.parmConfObjList:
386 for obj in self.parmConfObjList:
389 del obj
387 del obj
390
388
391 self.parmConfObjList = []
389 self.parmConfObjList = []
392
390
393 def addParameter(self, name, value, format='str'):
391 def addParameter(self, name, value, format='str'):
394
392
395 if value is None:
393 if value is None:
396 return None
394 return None
397 id = self.__getNewId()
395 id = self.__getNewId()
398
396
399 parmConfObj = ParameterConf()
397 parmConfObj = ParameterConf()
400 if not parmConfObj.setup(id, name, value, format):
398 if not parmConfObj.setup(id, name, value, format):
401 return None
399 return None
402
400
403 self.parmConfObjList.append(parmConfObj)
401 self.parmConfObjList.append(parmConfObj)
404
402
405 return parmConfObj
403 return parmConfObj
406
404
407 def changeParameter(self, name, value, format='str'):
405 def changeParameter(self, name, value, format='str'):
408
406
409 parmConfObj = self.getParameterObj(name)
407 parmConfObj = self.getParameterObj(name)
410 parmConfObj.update(name, value, format)
408 parmConfObj.update(name, value, format)
411
409
412 return parmConfObj
410 return parmConfObj
413
411
414 def makeXml(self, procUnitElement):
412 def makeXml(self, procUnitElement):
415
413
416 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
414 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
417 opElement.set('id', str(self.id))
415 opElement.set('id', str(self.id))
418 opElement.set('name', self.name)
416 opElement.set('name', self.name)
419 opElement.set('type', self.type)
417 opElement.set('type', self.type)
420 opElement.set('priority', str(self.priority))
418 opElement.set('priority', str(self.priority))
421
419
422 for parmConfObj in self.parmConfObjList:
420 for parmConfObj in self.parmConfObjList:
423 parmConfObj.makeXml(opElement)
421 parmConfObj.makeXml(opElement)
424
422
425 def readXml(self, opElement, project_id):
423 def readXml(self, opElement, project_id):
426
424
427 self.id = opElement.get('id')
425 self.id = opElement.get('id')
428 self.name = opElement.get('name')
426 self.name = opElement.get('name')
429 self.type = opElement.get('type')
427 self.type = opElement.get('type')
430 self.priority = opElement.get('priority')
428 self.priority = opElement.get('priority')
431 self.project_id = str(project_id) #yong
429 self.project_id = str(project_id) #yong
432
430
433 # Compatible with old signal chain version
431 # Compatible with old signal chain version
434 # Use of 'run' method instead 'init'
432 # Use of 'run' method instead 'init'
435 if self.type == 'self' and self.name == 'init':
433 if self.type == 'self' and self.name == 'init':
436 self.name = 'run'
434 self.name = 'run'
437
435
438 self.parmConfObjList = []
436 self.parmConfObjList = []
439
437
440 parmElementList = opElement.iter(ParameterConf().getElementName())
438 parmElementList = opElement.iter(ParameterConf().getElementName())
441
439
442 for parmElement in parmElementList:
440 for parmElement in parmElementList:
443 parmConfObj = ParameterConf()
441 parmConfObj = ParameterConf()
444 parmConfObj.readXml(parmElement)
442 parmConfObj.readXml(parmElement)
445
443
446 # Compatible with old signal chain version
444 # Compatible with old signal chain version
447 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
445 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
448 if self.type != 'self' and self.name == 'Plot':
446 if self.type != 'self' and self.name == 'Plot':
449 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
447 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
450 self.name = parmConfObj.value
448 self.name = parmConfObj.value
451 continue
449 continue
452
450
453 self.parmConfObjList.append(parmConfObj)
451 self.parmConfObjList.append(parmConfObj)
454
452
455 def printattr(self):
453 def printattr(self):
456
454
457 print('%s[%s]: name = %s, type = %s, priority = %s, project_id = %s' % (self.ELEMENTNAME,
455 print('%s[%s]: name = %s, type = %s, priority = %s, project_id = %s' % (self.ELEMENTNAME,
458 self.id,
456 self.id,
459 self.name,
457 self.name,
460 self.type,
458 self.type,
461 self.priority,
459 self.priority,
462 self.project_id))
460 self.project_id))
463
461
464 for parmConfObj in self.parmConfObjList:
462 for parmConfObj in self.parmConfObjList:
465 parmConfObj.printattr()
463 parmConfObj.printattr()
466
464
467 def createObject(self):
465 def createObject(self):
468
466
469 className = eval(self.name)
467 className = eval(self.name)
470
468
471 if self.type == 'other':
469 if self.type == 'other':
472 opObj = className()
470 opObj = className()
473 elif self.type == 'external':
471 elif self.type == 'external':
474 kwargs = self.getKwargs()
472 kwargs = self.getKwargs()
475 opObj = className(self.id, self.project_id, **kwargs)
473 opObj = className(self.id, self.project_id, **kwargs)
476 opObj.start()
474 opObj.start()
477
475
478 return opObj
476 return opObj
479
477
480 class ProcUnitConf():
478 class ProcUnitConf():
481
479
482 ELEMENTNAME = 'ProcUnit'
480 ELEMENTNAME = 'ProcUnit'
483
481
484 def __init__(self):
482 def __init__(self):
485
483
486 self.id = None
484 self.id = None
487 self.datatype = None
485 self.datatype = None
488 self.name = None
486 self.name = None
489 self.inputId = None
487 self.inputId = None
490 self.opConfObjList = []
488 self.opConfObjList = []
491 self.procUnitObj = None
489 self.procUnitObj = None
492 self.opObjDict = {}
490 self.opObjDict = {}
493
491
494 def __getPriority(self):
492 def __getPriority(self):
495
493
496 return len(self.opConfObjList) + 1
494 return len(self.opConfObjList) + 1
497
495
498 def __getNewId(self):
496 def __getNewId(self):
499
497
500 return int(self.id) * 10 + len(self.opConfObjList) + 1
498 return int(self.id) * 10 + len(self.opConfObjList) + 1
501
499
502 def getElementName(self):
500 def getElementName(self):
503
501
504 return self.ELEMENTNAME
502 return self.ELEMENTNAME
505
503
506 def getId(self):
504 def getId(self):
507
505
508 return self.id
506 return self.id
509
507
510 def updateId(self, new_id):
508 def updateId(self, new_id):
511 '''
509 '''
512 new_id = int(parentId) * 10 + (int(self.id) % 10)
510 new_id = int(parentId) * 10 + (int(self.id) % 10)
513 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
511 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
514
512
515 # If this proc unit has not inputs
513 # If this proc unit has not inputs
516 #if self.inputId == '0':
514 #if self.inputId == '0':
517 #new_inputId = 0
515 #new_inputId = 0
518
516
519 n = 1
517 n = 1
520 for opConfObj in self.opConfObjList:
518 for opConfObj in self.opConfObjList:
521
519
522 idOp = str(int(new_id) * 10 + n)
520 idOp = str(int(new_id) * 10 + n)
523 opConfObj.updateId(idOp)
521 opConfObj.updateId(idOp)
524
522
525 n += 1
523 n += 1
526
524
527 self.parentId = str(parentId)
525 self.parentId = str(parentId)
528 self.id = str(new_id)
526 self.id = str(new_id)
529 #self.inputId = str(new_inputId)
527 #self.inputId = str(new_inputId)
530 '''
528 '''
531 n = 1
529 n = 1
532
530
533 def getInputId(self):
531 def getInputId(self):
534
532
535 return self.inputId
533 return self.inputId
536
534
537 def getOperationObjList(self):
535 def getOperationObjList(self):
538
536
539 return self.opConfObjList
537 return self.opConfObjList
540
538
541 def getOperationObj(self, name=None):
539 def getOperationObj(self, name=None):
542
540
543 for opConfObj in self.opConfObjList:
541 for opConfObj in self.opConfObjList:
544
542
545 if opConfObj.name != name:
543 if opConfObj.name != name:
546 continue
544 continue
547
545
548 return opConfObj
546 return opConfObj
549
547
550 return None
548 return None
551
549
552 def getOpObjfromParamValue(self, value=None):
550 def getOpObjfromParamValue(self, value=None):
553
551
554 for opConfObj in self.opConfObjList:
552 for opConfObj in self.opConfObjList:
555 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
553 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
556 continue
554 continue
557 return opConfObj
555 return opConfObj
558 return None
556 return None
559
557
560 def getProcUnitObj(self):
558 def getProcUnitObj(self):
561
559
562 return self.procUnitObj
560 return self.procUnitObj
563
561
564 def setup(self, project_id, id, name, datatype, inputId):
562 def setup(self, project_id, id, name, datatype, inputId):
565 '''
563 '''
566 id sera el topico a publicar
564 id sera el topico a publicar
567 inputId sera el topico a subscribirse
565 inputId sera el topico a subscribirse
568 '''
566 '''
569
567
570 # Compatible with old signal chain version
568 # Compatible with old signal chain version
571 if datatype == None and name == None:
569 if datatype == None and name == None:
572 raise ValueError('datatype or name should be defined')
570 raise ValueError('datatype or name should be defined')
573
571
574 #Definir una condicion para inputId cuando sea 0
572 #Definir una condicion para inputId cuando sea 0
575
573
576 if name == None:
574 if name == None:
577 if 'Proc' in datatype:
575 if 'Proc' in datatype:
578 name = datatype
576 name = datatype
579 else:
577 else:
580 name = '%sProc' % (datatype)
578 name = '%sProc' % (datatype)
581
579
582 if datatype == None:
580 if datatype == None:
583 datatype = name.replace('Proc', '')
581 datatype = name.replace('Proc', '')
584
582
585 self.id = str(id)
583 self.id = str(id)
586 self.project_id = project_id
584 self.project_id = project_id
587 self.name = name
585 self.name = name
588 self.datatype = datatype
586 self.datatype = datatype
589 self.inputId = inputId
587 self.inputId = inputId
590 self.opConfObjList = []
588 self.opConfObjList = []
591
589
592 self.addOperation(name='run', optype='self')
590 self.addOperation(name='run', optype='self')
593
591
594 def removeOperations(self):
592 def removeOperations(self):
595
593
596 for obj in self.opConfObjList:
594 for obj in self.opConfObjList:
597 del obj
595 del obj
598
596
599 self.opConfObjList = []
597 self.opConfObjList = []
600 self.addOperation(name='run')
598 self.addOperation(name='run')
601
599
602 def addParameter(self, **kwargs):
600 def addParameter(self, **kwargs):
603 '''
601 '''
604 Add parameters to 'run' operation
602 Add parameters to 'run' operation
605 '''
603 '''
606 opObj = self.opConfObjList[0]
604 opObj = self.opConfObjList[0]
607
605
608 opObj.addParameter(**kwargs)
606 opObj.addParameter(**kwargs)
609
607
610 return opObj
608 return opObj
611
609
612 def addOperation(self, name, optype='self'):
610 def addOperation(self, name, optype='self'):
613 '''
611 '''
614 Actualizacion - > proceso comunicacion
612 Actualizacion - > proceso comunicacion
615 En el caso de optype='self', elminar. DEfinir comuncacion IPC -> Topic
613 En el caso de optype='self', elminar. DEfinir comuncacion IPC -> Topic
616 definir el tipoc de socket o comunicacion ipc++
614 definir el tipoc de socket o comunicacion ipc++
617
615
618 '''
616 '''
619
617
620 id = self.__getNewId()
618 id = self.__getNewId()
621 priority = self.__getPriority() # Sin mucho sentido, pero puede usarse
619 priority = self.__getPriority() # Sin mucho sentido, pero puede usarse
622 opConfObj = OperationConf()
620 opConfObj = OperationConf()
623 opConfObj.setup(id, name=name, priority=priority, type=optype, project_id=self.project_id)
621 opConfObj.setup(id, name=name, priority=priority, type=optype, project_id=self.project_id)
624 self.opConfObjList.append(opConfObj)
622 self.opConfObjList.append(opConfObj)
625
623
626 return opConfObj
624 return opConfObj
627
625
628 def makeXml(self, projectElement):
626 def makeXml(self, projectElement):
629
627
630 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
628 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
631 procUnitElement.set('id', str(self.id))
629 procUnitElement.set('id', str(self.id))
632 procUnitElement.set('name', self.name)
630 procUnitElement.set('name', self.name)
633 procUnitElement.set('datatype', self.datatype)
631 procUnitElement.set('datatype', self.datatype)
634 procUnitElement.set('inputId', str(self.inputId))
632 procUnitElement.set('inputId', str(self.inputId))
635
633
636 for opConfObj in self.opConfObjList:
634 for opConfObj in self.opConfObjList:
637 opConfObj.makeXml(procUnitElement)
635 opConfObj.makeXml(procUnitElement)
638
636
639 def readXml(self, upElement, project_id):
637 def readXml(self, upElement, project_id):
640
638
641 self.id = upElement.get('id')
639 self.id = upElement.get('id')
642 self.name = upElement.get('name')
640 self.name = upElement.get('name')
643 self.datatype = upElement.get('datatype')
641 self.datatype = upElement.get('datatype')
644 self.inputId = upElement.get('inputId')
642 self.inputId = upElement.get('inputId')
645 self.project_id = str(project_id)
643 self.project_id = str(project_id)
646
644
647 if self.ELEMENTNAME == 'ReadUnit':
645 if self.ELEMENTNAME == 'ReadUnit':
648 self.datatype = self.datatype.replace('Reader', '')
646 self.datatype = self.datatype.replace('Reader', '')
649
647
650 if self.ELEMENTNAME == 'ProcUnit':
648 if self.ELEMENTNAME == 'ProcUnit':
651 self.datatype = self.datatype.replace('Proc', '')
649 self.datatype = self.datatype.replace('Proc', '')
652
650
653 if self.inputId == 'None':
651 if self.inputId == 'None':
654 self.inputId = '0'
652 self.inputId = '0'
655
653
656 self.opConfObjList = []
654 self.opConfObjList = []
657
655
658 opElementList = upElement.iter(OperationConf().getElementName())
656 opElementList = upElement.iter(OperationConf().getElementName())
659
657
660 for opElement in opElementList:
658 for opElement in opElementList:
661 opConfObj = OperationConf()
659 opConfObj = OperationConf()
662 opConfObj.readXml(opElement, project_id)
660 opConfObj.readXml(opElement, project_id)
663 self.opConfObjList.append(opConfObj)
661 self.opConfObjList.append(opConfObj)
664
662
665 def printattr(self):
663 def printattr(self):
666
664
667 print('%s[%s]: name = %s, datatype = %s, inputId = %s, project_id = %s' % (self.ELEMENTNAME,
665 print('%s[%s]: name = %s, datatype = %s, inputId = %s, project_id = %s' % (self.ELEMENTNAME,
668 self.id,
666 self.id,
669 self.name,
667 self.name,
670 self.datatype,
668 self.datatype,
671 self.inputId,
669 self.inputId,
672 self.project_id))
670 self.project_id))
673
671
674 for opConfObj in self.opConfObjList:
672 for opConfObj in self.opConfObjList:
675 opConfObj.printattr()
673 opConfObj.printattr()
676
674
677 def getKwargs(self):
675 def getKwargs(self):
678
676
679 opObj = self.opConfObjList[0]
677 opObj = self.opConfObjList[0]
680 kwargs = opObj.getKwargs()
678 kwargs = opObj.getKwargs()
681
679
682 return kwargs
680 return kwargs
683
681
684 def createObjects(self):
682 def createObjects(self):
685 '''
683 '''
686 Instancia de unidades de procesamiento.
684 Instancia de unidades de procesamiento.
687 '''
685 '''
688 className = eval(self.name)
686 className = eval(self.name)
689 kwargs = self.getKwargs()
687 kwargs = self.getKwargs()
690 procUnitObj = className(self.id, self.inputId, self.project_id, **kwargs) # necesitan saber su id y su entrada por fines de ipc
688 procUnitObj = className(self.id, self.inputId, self.project_id, **kwargs) # necesitan saber su id y su entrada por fines de ipc
691 log.success('creating process...', self.name)
689 log.success('creating process...', self.name)
692
690
693 for opConfObj in self.opConfObjList:
691 for opConfObj in self.opConfObjList:
694
692
695 if opConfObj.type == 'self' and opConfObj.name == 'run':
693 if opConfObj.type == 'self' and opConfObj.name == 'run':
696 continue
694 continue
697 elif opConfObj.type == 'self':
695 elif opConfObj.type == 'self':
698 opObj = getattr(procUnitObj, opConfObj.name)
696 opObj = getattr(procUnitObj, opConfObj.name)
699 else:
697 else:
700 opObj = opConfObj.createObject()
698 opObj = opConfObj.createObject()
701
699
702 log.success('creating operation: {}, type:{}'.format(
700 log.success('creating operation: {}, type:{}'.format(
703 opConfObj.name,
701 opConfObj.name,
704 opConfObj.type), self.name)
702 opConfObj.type), self.name)
705
703
706 procUnitObj.addOperation(opConfObj, opObj)
704 procUnitObj.addOperation(opConfObj, opObj)
707
705
708 procUnitObj.start()
706 procUnitObj.start()
709 self.procUnitObj = procUnitObj
707 self.procUnitObj = procUnitObj
710
708
711 def close(self):
709 def close(self):
712
710
713 for opConfObj in self.opConfObjList:
711 for opConfObj in self.opConfObjList:
714 if opConfObj.type == 'self':
712 if opConfObj.type == 'self':
715 continue
713 continue
716
714
717 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
715 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
718 opObj.close()
716 opObj.close()
719
717
720 self.procUnitObj.close()
718 self.procUnitObj.close()
721
719
722 return
720 return
723
721
724
722
725 class ReadUnitConf(ProcUnitConf):
723 class ReadUnitConf(ProcUnitConf):
726
724
727 ELEMENTNAME = 'ReadUnit'
725 ELEMENTNAME = 'ReadUnit'
728
726
729 def __init__(self):
727 def __init__(self):
730
728
731 self.id = None
729 self.id = None
732 self.datatype = None
730 self.datatype = None
733 self.name = None
731 self.name = None
734 self.inputId = None
732 self.inputId = None
735 self.opConfObjList = []
733 self.opConfObjList = []
736
734
737 def getElementName(self):
735 def getElementName(self):
738
736
739 return self.ELEMENTNAME
737 return self.ELEMENTNAME
740
738
741 def setup(self, project_id, id, name, datatype, path='', startDate='', endDate='',
739 def setup(self, project_id, id, name, datatype, path='', startDate='', endDate='',
742 startTime='', endTime='', server=None, **kwargs):
740 startTime='', endTime='', server=None, **kwargs):
743
741
744
742
745 '''
743 '''
746 *****el id del proceso sera el Topico
744 *****el id del proceso sera el Topico
747
745
748 Adicion de {topic}, si no esta presente -> error
746 Adicion de {topic}, si no esta presente -> error
749 kwargs deben ser trasmitidos en la instanciacion
747 kwargs deben ser trasmitidos en la instanciacion
750
748
751 '''
749 '''
752
750
753 # Compatible with old signal chain version
751 # Compatible with old signal chain version
754 if datatype == None and name == None:
752 if datatype == None and name == None:
755 raise ValueError('datatype or name should be defined')
753 raise ValueError('datatype or name should be defined')
756 if name == None:
754 if name == None:
757 if 'Reader' in datatype:
755 if 'Reader' in datatype:
758 name = datatype
756 name = datatype
759 datatype = name.replace('Reader','')
757 datatype = name.replace('Reader','')
760 else:
758 else:
761 name = '{}Reader'.format(datatype)
759 name = '{}Reader'.format(datatype)
762 if datatype == None:
760 if datatype == None:
763 if 'Reader' in name:
761 if 'Reader' in name:
764 datatype = name.replace('Reader','')
762 datatype = name.replace('Reader','')
765 else:
763 else:
766 datatype = name
764 datatype = name
767 name = '{}Reader'.format(name)
765 name = '{}Reader'.format(name)
768
766
769 self.id = id
767 self.id = id
770 self.project_id = project_id
768 self.project_id = project_id
771 self.name = name
769 self.name = name
772 self.datatype = datatype
770 self.datatype = datatype
773 if path != '':
771 if path != '':
774 self.path = os.path.abspath(path)
772 self.path = os.path.abspath(path)
775 self.startDate = startDate
773 self.startDate = startDate
776 self.endDate = endDate
774 self.endDate = endDate
777 self.startTime = startTime
775 self.startTime = startTime
778 self.endTime = endTime
776 self.endTime = endTime
779 self.server = server
777 self.server = server
780 self.addRunOperation(**kwargs)
778 self.addRunOperation(**kwargs)
781
779
782 def update(self, **kwargs):
780 def update(self, **kwargs):
783
781
784 if 'datatype' in kwargs:
782 if 'datatype' in kwargs:
785 datatype = kwargs.pop('datatype')
783 datatype = kwargs.pop('datatype')
786 if 'Reader' in datatype:
784 if 'Reader' in datatype:
787 self.name = datatype
785 self.name = datatype
788 else:
786 else:
789 self.name = '%sReader' % (datatype)
787 self.name = '%sReader' % (datatype)
790 self.datatype = self.name.replace('Reader', '')
788 self.datatype = self.name.replace('Reader', '')
791
789
792 attrs = ('path', 'startDate', 'endDate',
790 attrs = ('path', 'startDate', 'endDate',
793 'startTime', 'endTime')
791 'startTime', 'endTime')
794
792
795 for attr in attrs:
793 for attr in attrs:
796 if attr in kwargs:
794 if attr in kwargs:
797 setattr(self, attr, kwargs.pop(attr))
795 setattr(self, attr, kwargs.pop(attr))
798
796
799 self.updateRunOperation(**kwargs)
797 self.updateRunOperation(**kwargs)
800
798
801 def removeOperations(self):
799 def removeOperations(self):
802
800
803 for obj in self.opConfObjList:
801 for obj in self.opConfObjList:
804 del obj
802 del obj
805
803
806 self.opConfObjList = []
804 self.opConfObjList = []
807
805
808 def addRunOperation(self, **kwargs):
806 def addRunOperation(self, **kwargs):
809
807
810 opObj = self.addOperation(name='run', optype='self')
808 opObj = self.addOperation(name='run', optype='self')
811
809
812 if self.server is None:
810 if self.server is None:
813 opObj.addParameter(
811 opObj.addParameter(
814 name='datatype', value=self.datatype, format='str')
812 name='datatype', value=self.datatype, format='str')
815 opObj.addParameter(name='path', value=self.path, format='str')
813 opObj.addParameter(name='path', value=self.path, format='str')
816 opObj.addParameter(
814 opObj.addParameter(
817 name='startDate', value=self.startDate, format='date')
815 name='startDate', value=self.startDate, format='date')
818 opObj.addParameter(
816 opObj.addParameter(
819 name='endDate', value=self.endDate, format='date')
817 name='endDate', value=self.endDate, format='date')
820 opObj.addParameter(
818 opObj.addParameter(
821 name='startTime', value=self.startTime, format='time')
819 name='startTime', value=self.startTime, format='time')
822 opObj.addParameter(
820 opObj.addParameter(
823 name='endTime', value=self.endTime, format='time')
821 name='endTime', value=self.endTime, format='time')
824
822
825 for key, value in list(kwargs.items()):
823 for key, value in list(kwargs.items()):
826 opObj.addParameter(name=key, value=value,
824 opObj.addParameter(name=key, value=value,
827 format=type(value).__name__)
825 format=type(value).__name__)
828 else:
826 else:
829 opObj.addParameter(name='server', value=self.server, format='str')
827 opObj.addParameter(name='server', value=self.server, format='str')
830
828
831 return opObj
829 return opObj
832
830
833 def updateRunOperation(self, **kwargs):
831 def updateRunOperation(self, **kwargs):
834
832
835 opObj = self.getOperationObj(name='run')
833 opObj = self.getOperationObj(name='run')
836 opObj.removeParameters()
834 opObj.removeParameters()
837
835
838 opObj.addParameter(name='datatype', value=self.datatype, format='str')
836 opObj.addParameter(name='datatype', value=self.datatype, format='str')
839 opObj.addParameter(name='path', value=self.path, format='str')
837 opObj.addParameter(name='path', value=self.path, format='str')
840 opObj.addParameter(
838 opObj.addParameter(
841 name='startDate', value=self.startDate, format='date')
839 name='startDate', value=self.startDate, format='date')
842 opObj.addParameter(name='endDate', value=self.endDate, format='date')
840 opObj.addParameter(name='endDate', value=self.endDate, format='date')
843 opObj.addParameter(
841 opObj.addParameter(
844 name='startTime', value=self.startTime, format='time')
842 name='startTime', value=self.startTime, format='time')
845 opObj.addParameter(name='endTime', value=self.endTime, format='time')
843 opObj.addParameter(name='endTime', value=self.endTime, format='time')
846
844
847 for key, value in list(kwargs.items()):
845 for key, value in list(kwargs.items()):
848 opObj.addParameter(name=key, value=value,
846 opObj.addParameter(name=key, value=value,
849 format=type(value).__name__)
847 format=type(value).__name__)
850
848
851 return opObj
849 return opObj
852
850
853 def readXml(self, upElement, project_id):
851 def readXml(self, upElement, project_id):
854
852
855 self.id = upElement.get('id')
853 self.id = upElement.get('id')
856 self.name = upElement.get('name')
854 self.name = upElement.get('name')
857 self.datatype = upElement.get('datatype')
855 self.datatype = upElement.get('datatype')
858 self.project_id = str(project_id) #yong
856 self.project_id = str(project_id) #yong
859
857
860 if self.ELEMENTNAME == 'ReadUnit':
858 if self.ELEMENTNAME == 'ReadUnit':
861 self.datatype = self.datatype.replace('Reader', '')
859 self.datatype = self.datatype.replace('Reader', '')
862
860
863 self.opConfObjList = []
861 self.opConfObjList = []
864
862
865 opElementList = upElement.iter(OperationConf().getElementName())
863 opElementList = upElement.iter(OperationConf().getElementName())
866
864
867 for opElement in opElementList:
865 for opElement in opElementList:
868 opConfObj = OperationConf()
866 opConfObj = OperationConf()
869 opConfObj.readXml(opElement, project_id)
867 opConfObj.readXml(opElement, project_id)
870 self.opConfObjList.append(opConfObj)
868 self.opConfObjList.append(opConfObj)
871
869
872 if opConfObj.name == 'run':
870 if opConfObj.name == 'run':
873 self.path = opConfObj.getParameterValue('path')
871 self.path = opConfObj.getParameterValue('path')
874 self.startDate = opConfObj.getParameterValue('startDate')
872 self.startDate = opConfObj.getParameterValue('startDate')
875 self.endDate = opConfObj.getParameterValue('endDate')
873 self.endDate = opConfObj.getParameterValue('endDate')
876 self.startTime = opConfObj.getParameterValue('startTime')
874 self.startTime = opConfObj.getParameterValue('startTime')
877 self.endTime = opConfObj.getParameterValue('endTime')
875 self.endTime = opConfObj.getParameterValue('endTime')
878
876
879
877
880 class Project(Process):
878 class Project(Process):
881
879
882 ELEMENTNAME = 'Project'
880 ELEMENTNAME = 'Project'
883
881
884 def __init__(self):
882 def __init__(self):
885
883
886 Process.__init__(self)
884 Process.__init__(self)
887 self.id = None
885 self.id = None
888 self.filename = None
886 self.filename = None
889 self.description = None
887 self.description = None
890 self.email = None
888 self.email = None
891 self.alarm = None
889 self.alarm = None
892 self.procUnitConfObjDict = {}
890 self.procUnitConfObjDict = {}
893
891
894 def __getNewId(self):
892 def __getNewId(self):
895
893
896 idList = list(self.procUnitConfObjDict.keys())
894 idList = list(self.procUnitConfObjDict.keys())
897 id = int(self.id) * 10
895 id = int(self.id) * 10
898
896
899 while True:
897 while True:
900 id += 1
898 id += 1
901
899
902 if str(id) in idList:
900 if str(id) in idList:
903 continue
901 continue
904
902
905 break
903 break
906
904
907 return str(id)
905 return str(id)
908
906
909 def getElementName(self):
907 def getElementName(self):
910
908
911 return self.ELEMENTNAME
909 return self.ELEMENTNAME
912
910
913 def getId(self):
911 def getId(self):
914
912
915 return self.id
913 return self.id
916
914
917 def updateId(self, new_id):
915 def updateId(self, new_id):
918
916
919 self.id = str(new_id)
917 self.id = str(new_id)
920
918
921 keyList = list(self.procUnitConfObjDict.keys())
919 keyList = list(self.procUnitConfObjDict.keys())
922 keyList.sort()
920 keyList.sort()
923
921
924 n = 1
922 n = 1
925 newProcUnitConfObjDict = {}
923 newProcUnitConfObjDict = {}
926
924
927 for procKey in keyList:
925 for procKey in keyList:
928
926
929 procUnitConfObj = self.procUnitConfObjDict[procKey]
927 procUnitConfObj = self.procUnitConfObjDict[procKey]
930 idProcUnit = str(int(self.id) * 10 + n)
928 idProcUnit = str(int(self.id) * 10 + n)
931 procUnitConfObj.updateId(idProcUnit)
929 procUnitConfObj.updateId(idProcUnit)
932 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
930 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
933 n += 1
931 n += 1
934
932
935 self.procUnitConfObjDict = newProcUnitConfObjDict
933 self.procUnitConfObjDict = newProcUnitConfObjDict
936
934
937 def setup(self, id=1, name='', description='', email=None, alarm=[]):
935 def setup(self, id=1, name='', description='', email=None, alarm=[]):
938
936
939 print(' ')
937 print(' ')
940 print('*' * 60)
938 print('*' * 60)
941 print('* Starting SIGNAL CHAIN PROCESSING (Multiprocessing) v%s *' % schainpy.__version__)
939 print('* Starting SIGNAL CHAIN PROCESSING (Multiprocessing) v%s *' % schainpy.__version__)
942 print('*' * 60)
940 print('*' * 60)
943 print("* Python " + python_version() + " *")
941 print("* Python " + python_version() + " *")
944 print('*' * 19)
942 print('*' * 19)
945 print(' ')
943 print(' ')
946 self.id = str(id)
944 self.id = str(id)
947 self.description = description
945 self.description = description
948 self.email = email
946 self.email = email
949 self.alarm = alarm
947 self.alarm = alarm
950
948
951 def update(self, **kwargs):
949 def update(self, **kwargs):
952
950
953 for key, value in list(kwargs.items()):
951 for key, value in list(kwargs.items()):
954 setattr(self, key, value)
952 setattr(self, key, value)
955
953
956 def clone(self):
954 def clone(self):
957
955
958 p = Project()
956 p = Project()
959 p.procUnitConfObjDict = self.procUnitConfObjDict
957 p.procUnitConfObjDict = self.procUnitConfObjDict
960 return p
958 return p
961
959
962 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
960 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
963
961
964 '''
962 '''
965 Actualizacion:
963 Actualizacion:
966 Se agrego un nuevo argumento: topic -relativo a la forma de comunicar los procesos simultaneos
964 Se agrego un nuevo argumento: topic -relativo a la forma de comunicar los procesos simultaneos
967
965
968 * El id del proceso sera el topico al que se deben subscribir los procUnits para recibir la informacion(data)
966 * El id del proceso sera el topico al que se deben subscribir los procUnits para recibir la informacion(data)
969
967
970 '''
968 '''
971
969
972 if id is None:
970 if id is None:
973 idReadUnit = self.__getNewId()
971 idReadUnit = self.__getNewId()
974 else:
972 else:
975 idReadUnit = str(id)
973 idReadUnit = str(id)
976
974
977 readUnitConfObj = ReadUnitConf()
975 readUnitConfObj = ReadUnitConf()
978 readUnitConfObj.setup(self.id, idReadUnit, name, datatype, **kwargs)
976 readUnitConfObj.setup(self.id, idReadUnit, name, datatype, **kwargs)
979 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
977 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
980
978
981 return readUnitConfObj
979 return readUnitConfObj
982
980
983 def addProcUnit(self, inputId='0', datatype=None, name=None):
981 def addProcUnit(self, inputId='0', datatype=None, name=None):
984
982
985 '''
983 '''
986 Actualizacion:
984 Actualizacion:
987 Se agrego dos nuevos argumentos: topic_read (lee data de otro procUnit) y topic_write(escribe o envia data a otro procUnit)
985 Se agrego dos nuevos argumentos: topic_read (lee data de otro procUnit) y topic_write(escribe o envia data a otro procUnit)
988 Deberia reemplazar a "inputId"
986 Deberia reemplazar a "inputId"
989
987
990 ** A fin de mantener el inputID, este sera la representaacion del topicoal que deben subscribirse. El ID propio de la intancia
988 ** A fin de mantener el inputID, este sera la representaacion del topicoal que deben subscribirse. El ID propio de la intancia
991 (proceso) sera el topico de la publicacion, todo sera asignado de manera dinamica.
989 (proceso) sera el topico de la publicacion, todo sera asignado de manera dinamica.
992
990
993 '''
991 '''
994
992
995 idProcUnit = self.__getNewId() #Topico para subscripcion
993 idProcUnit = self.__getNewId() #Topico para subscripcion
996 procUnitConfObj = ProcUnitConf()
994 procUnitConfObj = ProcUnitConf()
997 procUnitConfObj.setup(self.id, idProcUnit, name, datatype, inputId) #topic_read, topic_write,
995 procUnitConfObj.setup(self.id, idProcUnit, name, datatype, inputId) #topic_read, topic_write,
998 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
996 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
999
997
1000 return procUnitConfObj
998 return procUnitConfObj
1001
999
1002 def removeProcUnit(self, id):
1000 def removeProcUnit(self, id):
1003
1001
1004 if id in list(self.procUnitConfObjDict.keys()):
1002 if id in list(self.procUnitConfObjDict.keys()):
1005 self.procUnitConfObjDict.pop(id)
1003 self.procUnitConfObjDict.pop(id)
1006
1004
1007 def getReadUnitId(self):
1005 def getReadUnitId(self):
1008
1006
1009 readUnitConfObj = self.getReadUnitObj()
1007 readUnitConfObj = self.getReadUnitObj()
1010
1008
1011 return readUnitConfObj.id
1009 return readUnitConfObj.id
1012
1010
1013 def getReadUnitObj(self):
1011 def getReadUnitObj(self):
1014
1012
1015 for obj in list(self.procUnitConfObjDict.values()):
1013 for obj in list(self.procUnitConfObjDict.values()):
1016 if obj.getElementName() == 'ReadUnit':
1014 if obj.getElementName() == 'ReadUnit':
1017 return obj
1015 return obj
1018
1016
1019 return None
1017 return None
1020
1018
1021 def getProcUnitObj(self, id=None, name=None):
1019 def getProcUnitObj(self, id=None, name=None):
1022
1020
1023 if id != None:
1021 if id != None:
1024 return self.procUnitConfObjDict[id]
1022 return self.procUnitConfObjDict[id]
1025
1023
1026 if name != None:
1024 if name != None:
1027 return self.getProcUnitObjByName(name)
1025 return self.getProcUnitObjByName(name)
1028
1026
1029 return None
1027 return None
1030
1028
1031 def getProcUnitObjByName(self, name):
1029 def getProcUnitObjByName(self, name):
1032
1030
1033 for obj in list(self.procUnitConfObjDict.values()):
1031 for obj in list(self.procUnitConfObjDict.values()):
1034 if obj.name == name:
1032 if obj.name == name:
1035 return obj
1033 return obj
1036
1034
1037 return None
1035 return None
1038
1036
1039 def procUnitItems(self):
1037 def procUnitItems(self):
1040
1038
1041 return list(self.procUnitConfObjDict.items())
1039 return list(self.procUnitConfObjDict.items())
1042
1040
1043 def makeXml(self):
1041 def makeXml(self):
1044
1042
1045 projectElement = Element('Project')
1043 projectElement = Element('Project')
1046 projectElement.set('id', str(self.id))
1044 projectElement.set('id', str(self.id))
1047 projectElement.set('name', self.name)
1045 projectElement.set('name', self.name)
1048 projectElement.set('description', self.description)
1046 projectElement.set('description', self.description)
1049
1047
1050 for procUnitConfObj in list(self.procUnitConfObjDict.values()):
1048 for procUnitConfObj in list(self.procUnitConfObjDict.values()):
1051 procUnitConfObj.makeXml(projectElement)
1049 procUnitConfObj.makeXml(projectElement)
1052
1050
1053 self.projectElement = projectElement
1051 self.projectElement = projectElement
1054
1052
1055 def writeXml(self, filename=None):
1053 def writeXml(self, filename=None):
1056
1054
1057 if filename == None:
1055 if filename == None:
1058 if self.filename:
1056 if self.filename:
1059 filename = self.filename
1057 filename = self.filename
1060 else:
1058 else:
1061 filename = 'schain.xml'
1059 filename = 'schain.xml'
1062
1060
1063 if not filename:
1061 if not filename:
1064 print('filename has not been defined. Use setFilename(filename) for do it.')
1062 print('filename has not been defined. Use setFilename(filename) for do it.')
1065 return 0
1063 return 0
1066
1064
1067 abs_file = os.path.abspath(filename)
1065 abs_file = os.path.abspath(filename)
1068
1066
1069 if not os.access(os.path.dirname(abs_file), os.W_OK):
1067 if not os.access(os.path.dirname(abs_file), os.W_OK):
1070 print('No write permission on %s' % os.path.dirname(abs_file))
1068 print('No write permission on %s' % os.path.dirname(abs_file))
1071 return 0
1069 return 0
1072
1070
1073 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1071 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1074 print('File %s already exists and it could not be overwriten' % abs_file)
1072 print('File %s already exists and it could not be overwriten' % abs_file)
1075 return 0
1073 return 0
1076
1074
1077 self.makeXml()
1075 self.makeXml()
1078
1076
1079 ElementTree(self.projectElement).write(abs_file, method='xml')
1077 ElementTree(self.projectElement).write(abs_file, method='xml')
1080
1078
1081 self.filename = abs_file
1079 self.filename = abs_file
1082
1080
1083 return 1
1081 return 1
1084
1082
1085 def readXml(self, filename=None):
1083 def readXml(self, filename=None):
1086
1084
1087 if not filename:
1085 if not filename:
1088 print('filename is not defined')
1086 print('filename is not defined')
1089 return 0
1087 return 0
1090
1088
1091 abs_file = os.path.abspath(filename)
1089 abs_file = os.path.abspath(filename)
1092
1090
1093 if not os.path.isfile(abs_file):
1091 if not os.path.isfile(abs_file):
1094 print('%s file does not exist' % abs_file)
1092 print('%s file does not exist' % abs_file)
1095 return 0
1093 return 0
1096
1094
1097 self.projectElement = None
1095 self.projectElement = None
1098 self.procUnitConfObjDict = {}
1096 self.procUnitConfObjDict = {}
1099
1097
1100 try:
1098 try:
1101 self.projectElement = ElementTree().parse(abs_file)
1099 self.projectElement = ElementTree().parse(abs_file)
1102 except:
1100 except:
1103 print('Error reading %s, verify file format' % filename)
1101 print('Error reading %s, verify file format' % filename)
1104 return 0
1102 return 0
1105
1103
1106 self.project = self.projectElement.tag
1104 self.project = self.projectElement.tag
1107
1105
1108 self.id = self.projectElement.get('id')
1106 self.id = self.projectElement.get('id')
1109 self.name = self.projectElement.get('name')
1107 self.name = self.projectElement.get('name')
1110 self.description = self.projectElement.get('description')
1108 self.description = self.projectElement.get('description')
1111
1109
1112 readUnitElementList = self.projectElement.iter(
1110 readUnitElementList = self.projectElement.iter(
1113 ReadUnitConf().getElementName())
1111 ReadUnitConf().getElementName())
1114
1112
1115 for readUnitElement in readUnitElementList:
1113 for readUnitElement in readUnitElementList:
1116 readUnitConfObj = ReadUnitConf()
1114 readUnitConfObj = ReadUnitConf()
1117 readUnitConfObj.readXml(readUnitElement, self.id)
1115 readUnitConfObj.readXml(readUnitElement, self.id)
1118 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1116 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1119
1117
1120 procUnitElementList = self.projectElement.iter(
1118 procUnitElementList = self.projectElement.iter(
1121 ProcUnitConf().getElementName())
1119 ProcUnitConf().getElementName())
1122
1120
1123 for procUnitElement in procUnitElementList:
1121 for procUnitElement in procUnitElementList:
1124 procUnitConfObj = ProcUnitConf()
1122 procUnitConfObj = ProcUnitConf()
1125 procUnitConfObj.readXml(procUnitElement, self.id)
1123 procUnitConfObj.readXml(procUnitElement, self.id)
1126 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1124 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1127
1125
1128 self.filename = abs_file
1126 self.filename = abs_file
1129
1127
1130 return 1
1128 return 1
1131
1129
1132 def __str__(self):
1130 def __str__(self):
1133
1131
1134 print('Project[%s]: name = %s, description = %s, project_id = %s' % (self.id,
1132 print('Project[%s]: name = %s, description = %s, project_id = %s' % (self.id,
1135 self.name,
1133 self.name,
1136 self.description,
1134 self.description,
1137 self.project_id))
1135 self.project_id))
1138
1136
1139 for procUnitConfObj in self.procUnitConfObjDict.values():
1137 for procUnitConfObj in self.procUnitConfObjDict.values():
1140 print(procUnitConfObj)
1138 print(procUnitConfObj)
1141
1139
1142 def createObjects(self):
1140 def createObjects(self):
1143
1141
1144 for procUnitConfObj in self.procUnitConfObjDict.values():
1142 for procUnitConfObj in self.procUnitConfObjDict.values():
1145 procUnitConfObj.createObjects()
1143 procUnitConfObj.createObjects()
1146
1144
1147 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1145 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1148
1146
1149 import socket
1147 import socket
1150
1148
1151 if modes is None:
1149 if modes is None:
1152 modes = self.alarm
1150 modes = self.alarm
1153
1151
1154 if not self.alarm:
1152 if not self.alarm:
1155 modes = []
1153 modes = []
1156
1154
1157 err = traceback.format_exception(sys.exc_info()[0],
1155 err = traceback.format_exception(sys.exc_info()[0],
1158 sys.exc_info()[1],
1156 sys.exc_info()[1],
1159 sys.exc_info()[2])
1157 sys.exc_info()[2])
1160
1158
1161 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1159 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1162
1160
1163 message = ''.join(err)
1161 message = ''.join(err)
1164
1162
1165 if stdout:
1163 if stdout:
1166 sys.stderr.write(message)
1164 sys.stderr.write(message)
1167
1165
1168 subject = 'SChain v%s: Error running %s\n' % (
1166 subject = 'SChain v%s: Error running %s\n' % (
1169 schainpy.__version__, procUnitConfObj.name)
1167 schainpy.__version__, procUnitConfObj.name)
1170
1168
1171 subtitle = '%s: %s\n' % (
1169 subtitle = '%s: %s\n' % (
1172 procUnitConfObj.getElementName(), procUnitConfObj.name)
1170 procUnitConfObj.getElementName(), procUnitConfObj.name)
1173 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1171 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1174 socket.gethostname())
1172 socket.gethostname())
1175 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1173 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1176 subtitle += 'Configuration file: %s\n' % self.filename
1174 subtitle += 'Configuration file: %s\n' % self.filename
1177 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1175 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1178
1176
1179 readUnitConfObj = self.getReadUnitObj()
1177 readUnitConfObj = self.getReadUnitObj()
1180 if readUnitConfObj:
1178 if readUnitConfObj:
1181 subtitle += '\nInput parameters:\n'
1179 subtitle += '\nInput parameters:\n'
1182 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1180 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1183 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1181 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1184 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1182 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1185 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1183 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1186 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1184 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1187 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1185 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1188
1186
1189 a = Alarm(
1187 a = Alarm(
1190 modes=modes,
1188 modes=modes,
1191 email=self.email,
1189 email=self.email,
1192 message=message,
1190 message=message,
1193 subject=subject,
1191 subject=subject,
1194 subtitle=subtitle,
1192 subtitle=subtitle,
1195 filename=self.filename
1193 filename=self.filename
1196 )
1194 )
1197
1195
1198 return a
1196 return a
1199
1197
1200 def isPaused(self):
1198 def isPaused(self):
1201 return 0
1199 return 0
1202
1200
1203 def isStopped(self):
1201 def isStopped(self):
1204 return 0
1202 return 0
1205
1203
1206 def runController(self):
1204 def runController(self):
1207 '''
1205 '''
1208 returns 0 when this process has been stopped, 1 otherwise
1206 returns 0 when this process has been stopped, 1 otherwise
1209 '''
1207 '''
1210
1208
1211 if self.isPaused():
1209 if self.isPaused():
1212 print('Process suspended')
1210 print('Process suspended')
1213
1211
1214 while True:
1212 while True:
1215 time.sleep(0.1)
1213 time.sleep(0.1)
1216
1214
1217 if not self.isPaused():
1215 if not self.isPaused():
1218 break
1216 break
1219
1217
1220 if self.isStopped():
1218 if self.isStopped():
1221 break
1219 break
1222
1220
1223 print('Process reinitialized')
1221 print('Process reinitialized')
1224
1222
1225 if self.isStopped():
1223 if self.isStopped():
1226 print('Process stopped')
1224 print('Process stopped')
1227 return 0
1225 return 0
1228
1226
1229 return 1
1227 return 1
1230
1228
1231 def setFilename(self, filename):
1229 def setFilename(self, filename):
1232
1230
1233 self.filename = filename
1231 self.filename = filename
1234
1232
1235 def setProxyCom(self):
1233 def setProxyCom(self):
1236
1234
1237 if not os.path.exists('/tmp/schain'):
1235 if not os.path.exists('/tmp/schain'):
1238 os.mkdir('/tmp/schain')
1236 os.mkdir('/tmp/schain')
1239
1237
1240 self.ctx = zmq.Context()
1238 self.ctx = zmq.Context()
1241 xpub = self.ctx.socket(zmq.XPUB)
1239 xpub = self.ctx.socket(zmq.XPUB)
1242 xpub.bind('ipc:///tmp/schain/{}_pub'.format(self.id))
1240 xpub.bind('ipc:///tmp/schain/{}_pub'.format(self.id))
1243 xsub = self.ctx.socket(zmq.XSUB)
1241 xsub = self.ctx.socket(zmq.XSUB)
1244 xsub.bind('ipc:///tmp/schain/{}_sub'.format(self.id))
1242 xsub.bind('ipc:///tmp/schain/{}_sub'.format(self.id))
1245
1243
1246 try:
1244 try:
1247 zmq.proxy(xpub, xsub)
1245 zmq.proxy(xpub, xsub)
1248 except zmq.ContextTerminated:
1246 except: # zmq.ContextTerminated:
1249 xpub.close()
1247 xpub.close()
1250 xsub.close()
1248 xsub.close()
1251
1249
1252 def run(self):
1250 def run(self):
1253
1251
1254 log.success('Starting {}: {}'.format(self.name, self.id), tag='')
1252 log.success('Starting {}: {}'.format(self.name, self.id), tag='')
1255 self.start_time = time.time()
1253 self.start_time = time.time()
1256 self.createObjects()
1254 self.createObjects()
1257 # t = Thread(target=wait, args=(self.ctx, ))
1255 # t = Thread(target=wait, args=(self.ctx, ))
1258 # t.start()
1256 # t.start()
1259 self.setProxyCom()
1257 self.setProxyCom()
1260
1258
1261 # Iniciar todos los procesos .start(), monitoreo de procesos. ELiminar lo de abajo
1259 # Iniciar todos los procesos .start(), monitoreo de procesos. ELiminar lo de abajo
1262
1260
1263 log.success('{} finished (time: {}s)'.format(
1261 log.success('{} Done (time: {}s)'.format(
1264 self.name,
1262 self.name,
1265 time.time()-self.start_time))
1263 time.time()-self.start_time))
@@ -1,1251 +1,1342
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
5 '''
5 '''
6
6
7 import copy
7 import copy
8 import numpy
8 import numpy
9 import datetime
9 import datetime
10 import json
10
11
12 from schainpy.utils import log
11 from .jroheaderIO import SystemHeader, RadarControllerHeader
13 from .jroheaderIO import SystemHeader, RadarControllerHeader
12
14
13
15
14 def getNumpyDtype(dataTypeCode):
16 def getNumpyDtype(dataTypeCode):
15
17
16 if dataTypeCode == 0:
18 if dataTypeCode == 0:
17 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
19 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
18 elif dataTypeCode == 1:
20 elif dataTypeCode == 1:
19 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
21 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
20 elif dataTypeCode == 2:
22 elif dataTypeCode == 2:
21 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
23 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
22 elif dataTypeCode == 3:
24 elif dataTypeCode == 3:
23 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
25 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
24 elif dataTypeCode == 4:
26 elif dataTypeCode == 4:
25 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
27 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
26 elif dataTypeCode == 5:
28 elif dataTypeCode == 5:
27 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
29 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
28 else:
30 else:
29 raise ValueError('dataTypeCode was not defined')
31 raise ValueError('dataTypeCode was not defined')
30
32
31 return numpyDtype
33 return numpyDtype
32
34
33
35
34 def getDataTypeCode(numpyDtype):
36 def getDataTypeCode(numpyDtype):
35
37
36 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
38 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
37 datatype = 0
39 datatype = 0
38 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
40 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
39 datatype = 1
41 datatype = 1
40 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
42 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
41 datatype = 2
43 datatype = 2
42 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
44 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
43 datatype = 3
45 datatype = 3
44 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
46 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
45 datatype = 4
47 datatype = 4
46 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
48 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
47 datatype = 5
49 datatype = 5
48 else:
50 else:
49 datatype = None
51 datatype = None
50
52
51 return datatype
53 return datatype
52
54
53
55
54 def hildebrand_sekhon(data, navg):
56 def hildebrand_sekhon(data, navg):
55 """
57 """
56 This method is for the objective determination of the noise level in Doppler spectra. This
58 This method is for the objective determination of the noise level in Doppler spectra. This
57 implementation technique is based on the fact that the standard deviation of the spectral
59 implementation technique is based on the fact that the standard deviation of the spectral
58 densities is equal to the mean spectral density for white Gaussian noise
60 densities is equal to the mean spectral density for white Gaussian noise
59
61
60 Inputs:
62 Inputs:
61 Data : heights
63 Data : heights
62 navg : numbers of averages
64 navg : numbers of averages
63
65
64 Return:
66 Return:
65 mean : noise's level
67 mean : noise's level
66 """
68 """
67
69
68 sortdata = numpy.sort(data, axis=None)
70 sortdata = numpy.sort(data, axis=None)
69 lenOfData = len(sortdata)
71 lenOfData = len(sortdata)
70 nums_min = lenOfData*0.2
72 nums_min = lenOfData*0.2
71
73
72 if nums_min <= 5:
74 if nums_min <= 5:
73
75
74 nums_min = 5
76 nums_min = 5
75
77
76 sump = 0.
78 sump = 0.
77 sumq = 0.
79 sumq = 0.
78
80
79 j = 0
81 j = 0
80 cont = 1
82 cont = 1
81
83
82 while((cont==1)and(j<lenOfData)):
84 while((cont == 1)and(j < lenOfData)):
83
85
84 sump += sortdata[j]
86 sump += sortdata[j]
85 sumq += sortdata[j]**2
87 sumq += sortdata[j]**2
86
88
87 if j > nums_min:
89 if j > nums_min:
88 rtest = float(j)/(j-1) + 1.0/navg
90 rtest = float(j)/(j-1) + 1.0/navg
89 if ((sumq*j) > (rtest*sump**2)):
91 if ((sumq*j) > (rtest*sump**2)):
90 j = j - 1
92 j = j - 1
91 sump = sump - sortdata[j]
93 sump = sump - sortdata[j]
92 sumq = sumq - sortdata[j]**2
94 sumq = sumq - sortdata[j]**2
93 cont = 0
95 cont = 0
94
96
95 j += 1
97 j += 1
96
98
97 lnoise = sump /j
99 lnoise = sump / j
98
100
99 return lnoise
101 return lnoise
100
102
101
103
102 class Beam:
104 class Beam:
103
105
104 def __init__(self):
106 def __init__(self):
105 self.codeList = []
107 self.codeList = []
106 self.azimuthList = []
108 self.azimuthList = []
107 self.zenithList = []
109 self.zenithList = []
108
110
109
111
110 class GenericData(object):
112 class GenericData(object):
111
113
112 flagNoData = True
114 flagNoData = True
113
115
114 def copy(self, inputObj=None):
116 def copy(self, inputObj=None):
115
117
116 if inputObj == None:
118 if inputObj == None:
117 return copy.deepcopy(self)
119 return copy.deepcopy(self)
118
120
119 for key in list(inputObj.__dict__.keys()):
121 for key in list(inputObj.__dict__.keys()):
120
122
121 attribute = inputObj.__dict__[key]
123 attribute = inputObj.__dict__[key]
122
124
123 # If this attribute is a tuple or list
125 # If this attribute is a tuple or list
124 if type(inputObj.__dict__[key]) in (tuple, list):
126 if type(inputObj.__dict__[key]) in (tuple, list):
125 self.__dict__[key] = attribute[:]
127 self.__dict__[key] = attribute[:]
126 continue
128 continue
127
129
128 # If this attribute is another object or instance
130 # If this attribute is another object or instance
129 if hasattr(attribute, '__dict__'):
131 if hasattr(attribute, '__dict__'):
130 self.__dict__[key] = attribute.copy()
132 self.__dict__[key] = attribute.copy()
131 continue
133 continue
132
134
133 self.__dict__[key] = inputObj.__dict__[key]
135 self.__dict__[key] = inputObj.__dict__[key]
134
136
135 def deepcopy(self):
137 def deepcopy(self):
136
138
137 return copy.deepcopy(self)
139 return copy.deepcopy(self)
138
140
139 def isEmpty(self):
141 def isEmpty(self):
140
142
141 return self.flagNoData
143 return self.flagNoData
142
144
143
145
144 class JROData(GenericData):
146 class JROData(GenericData):
145
147
146 # m_BasicHeader = BasicHeader()
148 # m_BasicHeader = BasicHeader()
147 # m_ProcessingHeader = ProcessingHeader()
149 # m_ProcessingHeader = ProcessingHeader()
148
150
149 systemHeaderObj = SystemHeader()
151 systemHeaderObj = SystemHeader()
150
151 radarControllerHeaderObj = RadarControllerHeader()
152 radarControllerHeaderObj = RadarControllerHeader()
152
153 # data = None
153 # data = None
154
155 type = None
154 type = None
156
157 datatype = None # dtype but in string
155 datatype = None # dtype but in string
158
159 # dtype = None
156 # dtype = None
160
161 # nChannels = None
157 # nChannels = None
162
163 # nHeights = None
158 # nHeights = None
164
165 nProfiles = None
159 nProfiles = None
166
167 heightList = None
160 heightList = None
168
169 channelList = None
161 channelList = None
170
171 flagDiscontinuousBlock = False
162 flagDiscontinuousBlock = False
172
173 useLocalTime = False
163 useLocalTime = False
174
175 utctime = None
164 utctime = None
176
177 timeZone = None
165 timeZone = None
178
179 dstFlag = None
166 dstFlag = None
180
181 errorCount = None
167 errorCount = None
182
183 blocksize = None
168 blocksize = None
184
185 # nCode = None
169 # nCode = None
186 #
187 # nBaud = None
170 # nBaud = None
188 #
189 # code = None
171 # code = None
190
191 flagDecodeData = False # asumo q la data no esta decodificada
172 flagDecodeData = False # asumo q la data no esta decodificada
192
193 flagDeflipData = False # asumo q la data no esta sin flip
173 flagDeflipData = False # asumo q la data no esta sin flip
194
195 flagShiftFFT = False
174 flagShiftFFT = False
196
197 # ippSeconds = None
175 # ippSeconds = None
198
199 # timeInterval = None
176 # timeInterval = None
200
201 nCohInt = None
177 nCohInt = None
202
203 # noise = None
178 # noise = None
204
205 windowOfFilter = 1
179 windowOfFilter = 1
206
207 # Speed of ligth
180 # Speed of ligth
208 C = 3e8
181 C = 3e8
209
210 frequency = 49.92e6
182 frequency = 49.92e6
211
212 realtime = False
183 realtime = False
213
214 beacon_heiIndexList = None
184 beacon_heiIndexList = None
215
216 last_block = None
185 last_block = None
217
218 blocknow = None
186 blocknow = None
219
220 azimuth = None
187 azimuth = None
221
222 zenith = None
188 zenith = None
223
224 beam = Beam()
189 beam = Beam()
225
226 profileIndex = None
190 profileIndex = None
191 error = None
192 data = None
193 data_plt = None
227
194
228 error = (0, '')
229
195
230 def __str__(self):
196 def __str__(self):
231
197
232 return '{} - {}'.format(self.type, self.getDatatime())
198 return '{} - {}'.format(self.type, self.getDatatime())
233
199
234 def getNoise(self):
200 def getNoise(self):
235
201
236 raise NotImplementedError
202 raise NotImplementedError
237
203
238 def getNChannels(self):
204 def getNChannels(self):
239
205
240 return len(self.channelList)
206 return len(self.channelList)
241
207
242 def getChannelIndexList(self):
208 def getChannelIndexList(self):
243
209
244 return list(range(self.nChannels))
210 return list(range(self.nChannels))
245
211
246 def getNHeights(self):
212 def getNHeights(self):
247
213
248 return len(self.heightList)
214 return len(self.heightList)
249
215
250 def getHeiRange(self, extrapoints=0):
216 def getHeiRange(self, extrapoints=0):
251
217
252 heis = self.heightList
218 heis = self.heightList
253 # deltah = self.heightList[1] - self.heightList[0]
219 # deltah = self.heightList[1] - self.heightList[0]
254 #
220 #
255 # heis.append(self.heightList[-1])
221 # heis.append(self.heightList[-1])
256
222
257 return heis
223 return heis
258
224
259 def getDeltaH(self):
225 def getDeltaH(self):
260
226
261 delta = self.heightList[1] - self.heightList[0]
227 delta = self.heightList[1] - self.heightList[0]
262
228
263 return delta
229 return delta
264
230
265 def getltctime(self):
231 def getltctime(self):
266
232
267 if self.useLocalTime:
233 if self.useLocalTime:
268 return self.utctime - self.timeZone * 60
234 return self.utctime - self.timeZone * 60
269
235
270 return self.utctime
236 return self.utctime
271
237
272 def getDatatime(self):
238 def getDatatime(self):
273
239
274 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
240 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
275 return datatimeValue
241 return datatimeValue
276
242
277 def getTimeRange(self):
243 def getTimeRange(self):
278
244
279 datatime = []
245 datatime = []
280
246
281 datatime.append(self.ltctime)
247 datatime.append(self.ltctime)
282 datatime.append(self.ltctime + self.timeInterval + 1)
248 datatime.append(self.ltctime + self.timeInterval + 1)
283
249
284 datatime = numpy.array(datatime)
250 datatime = numpy.array(datatime)
285
251
286 return datatime
252 return datatime
287
253
288 def getFmaxTimeResponse(self):
254 def getFmaxTimeResponse(self):
289
255
290 period = (10**-6) * self.getDeltaH() / (0.15)
256 period = (10**-6) * self.getDeltaH() / (0.15)
291
257
292 PRF = 1. / (period * self.nCohInt)
258 PRF = 1. / (period * self.nCohInt)
293
259
294 fmax = PRF
260 fmax = PRF
295
261
296 return fmax
262 return fmax
297
263
298 def getFmax(self):
264 def getFmax(self):
299 PRF = 1. / (self.ippSeconds * self.nCohInt)
265 PRF = 1. / (self.ippSeconds * self.nCohInt)
300
266
301 fmax = PRF
267 fmax = PRF
302 return fmax
268 return fmax
303
269
304 def getVmax(self):
270 def getVmax(self):
305
271
306 _lambda = self.C / self.frequency
272 _lambda = self.C / self.frequency
307
273
308 vmax = self.getFmax() * _lambda / 2
274 vmax = self.getFmax() * _lambda / 2
309
275
310 return vmax
276 return vmax
311
277
312 def get_ippSeconds(self):
278 def get_ippSeconds(self):
313 '''
279 '''
314 '''
280 '''
315 return self.radarControllerHeaderObj.ippSeconds
281 return self.radarControllerHeaderObj.ippSeconds
316
282
317 def set_ippSeconds(self, ippSeconds):
283 def set_ippSeconds(self, ippSeconds):
318 '''
284 '''
319 '''
285 '''
320
286
321 self.radarControllerHeaderObj.ippSeconds = ippSeconds
287 self.radarControllerHeaderObj.ippSeconds = ippSeconds
322
288
323 return
289 return
324
290
325 def get_dtype(self):
291 def get_dtype(self):
326 '''
292 '''
327 '''
293 '''
328 return getNumpyDtype(self.datatype)
294 return getNumpyDtype(self.datatype)
329
295
330 def set_dtype(self, numpyDtype):
296 def set_dtype(self, numpyDtype):
331 '''
297 '''
332 '''
298 '''
333
299
334 self.datatype = getDataTypeCode(numpyDtype)
300 self.datatype = getDataTypeCode(numpyDtype)
335
301
336 def get_code(self):
302 def get_code(self):
337 '''
303 '''
338 '''
304 '''
339 return self.radarControllerHeaderObj.code
305 return self.radarControllerHeaderObj.code
340
306
341 def set_code(self, code):
307 def set_code(self, code):
342 '''
308 '''
343 '''
309 '''
344 self.radarControllerHeaderObj.code = code
310 self.radarControllerHeaderObj.code = code
345
311
346 return
312 return
347
313
348 def get_ncode(self):
314 def get_ncode(self):
349 '''
315 '''
350 '''
316 '''
351 return self.radarControllerHeaderObj.nCode
317 return self.radarControllerHeaderObj.nCode
352
318
353 def set_ncode(self, nCode):
319 def set_ncode(self, nCode):
354 '''
320 '''
355 '''
321 '''
356 self.radarControllerHeaderObj.nCode = nCode
322 self.radarControllerHeaderObj.nCode = nCode
357
323
358 return
324 return
359
325
360 def get_nbaud(self):
326 def get_nbaud(self):
361 '''
327 '''
362 '''
328 '''
363 return self.radarControllerHeaderObj.nBaud
329 return self.radarControllerHeaderObj.nBaud
364
330
365 def set_nbaud(self, nBaud):
331 def set_nbaud(self, nBaud):
366 '''
332 '''
367 '''
333 '''
368 self.radarControllerHeaderObj.nBaud = nBaud
334 self.radarControllerHeaderObj.nBaud = nBaud
369
335
370 return
336 return
371
337
372 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
338 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
373 channelIndexList = property(
339 channelIndexList = property(
374 getChannelIndexList, "I'm the 'channelIndexList' property.")
340 getChannelIndexList, "I'm the 'channelIndexList' property.")
375 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
341 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
376 #noise = property(getNoise, "I'm the 'nHeights' property.")
342 #noise = property(getNoise, "I'm the 'nHeights' property.")
377 datatime = property(getDatatime, "I'm the 'datatime' property")
343 datatime = property(getDatatime, "I'm the 'datatime' property")
378 ltctime = property(getltctime, "I'm the 'ltctime' property")
344 ltctime = property(getltctime, "I'm the 'ltctime' property")
379 ippSeconds = property(get_ippSeconds, set_ippSeconds)
345 ippSeconds = property(get_ippSeconds, set_ippSeconds)
380 dtype = property(get_dtype, set_dtype)
346 dtype = property(get_dtype, set_dtype)
381 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
347 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
382 code = property(get_code, set_code)
348 code = property(get_code, set_code)
383 nCode = property(get_ncode, set_ncode)
349 nCode = property(get_ncode, set_ncode)
384 nBaud = property(get_nbaud, set_nbaud)
350 nBaud = property(get_nbaud, set_nbaud)
385
351
386
352
387 class Voltage(JROData):
353 class Voltage(JROData):
388
354
389 # data es un numpy array de 2 dmensiones (canales, alturas)
355 # data es un numpy array de 2 dmensiones (canales, alturas)
390 data = None
356 data = None
391
357
392 def __init__(self):
358 def __init__(self):
393 '''
359 '''
394 Constructor
360 Constructor
395 '''
361 '''
396
362
397 self.useLocalTime = True
363 self.useLocalTime = True
398
399 self.radarControllerHeaderObj = RadarControllerHeader()
364 self.radarControllerHeaderObj = RadarControllerHeader()
400
401 self.systemHeaderObj = SystemHeader()
365 self.systemHeaderObj = SystemHeader()
402
403 self.type = "Voltage"
366 self.type = "Voltage"
404
405 self.data = None
367 self.data = None
406
407 # self.dtype = None
368 # self.dtype = None
408
409 # self.nChannels = 0
369 # self.nChannels = 0
410
411 # self.nHeights = 0
370 # self.nHeights = 0
412
413 self.nProfiles = None
371 self.nProfiles = None
414
372 self.heightList = Non
415 self.heightList = None
416
417 self.channelList = None
373 self.channelList = None
418
419 # self.channelIndexList = None
374 # self.channelIndexList = None
420
421 self.flagNoData = True
375 self.flagNoData = True
422
423 self.flagDiscontinuousBlock = False
376 self.flagDiscontinuousBlock = False
424
425 self.utctime = None
377 self.utctime = None
426
427 self.timeZone = None
378 self.timeZone = None
428
429 self.dstFlag = None
379 self.dstFlag = None
430
431 self.errorCount = None
380 self.errorCount = None
432
433 self.nCohInt = None
381 self.nCohInt = None
434
435 self.blocksize = None
382 self.blocksize = None
436
437 self.flagDecodeData = False # asumo q la data no esta decodificada
383 self.flagDecodeData = False # asumo q la data no esta decodificada
438
439 self.flagDeflipData = False # asumo q la data no esta sin flip
384 self.flagDeflipData = False # asumo q la data no esta sin flip
440
441 self.flagShiftFFT = False
385 self.flagShiftFFT = False
442
443 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
386 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
444
445 self.profileIndex = 0
387 self.profileIndex = 0
446
388
447 def getNoisebyHildebrand(self, channel=None):
389 def getNoisebyHildebrand(self, channel=None):
448 """
390 """
449 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
391 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
450
392
451 Return:
393 Return:
452 noiselevel
394 noiselevel
453 """
395 """
454
396
455 if channel != None:
397 if channel != None:
456 data = self.data[channel]
398 data = self.data[channel]
457 nChannels = 1
399 nChannels = 1
458 else:
400 else:
459 data = self.data
401 data = self.data
460 nChannels = self.nChannels
402 nChannels = self.nChannels
461
403
462 noise = numpy.zeros(nChannels)
404 noise = numpy.zeros(nChannels)
463 power = data * numpy.conjugate(data)
405 power = data * numpy.conjugate(data)
464
406
465 for thisChannel in range(nChannels):
407 for thisChannel in range(nChannels):
466 if nChannels == 1:
408 if nChannels == 1:
467 daux = power[:].real
409 daux = power[:].real
468 else:
410 else:
469 daux = power[thisChannel, :].real
411 daux = power[thisChannel, :].real
470 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
412 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
471
413
472 return noise
414 return noise
473
415
474 def getNoise(self, type=1, channel=None):
416 def getNoise(self, type=1, channel=None):
475
417
476 if type == 1:
418 if type == 1:
477 noise = self.getNoisebyHildebrand(channel)
419 noise = self.getNoisebyHildebrand(channel)
478
420
479 return noise
421 return noise
480
422
481 def getPower(self, channel=None):
423 def getPower(self, channel=None):
482
424
483 if channel != None:
425 if channel != None:
484 data = self.data[channel]
426 data = self.data[channel]
485 else:
427 else:
486 data = self.data
428 data = self.data
487
429
488 power = data * numpy.conjugate(data)
430 power = data * numpy.conjugate(data)
489 powerdB = 10 * numpy.log10(power.real)
431 powerdB = 10 * numpy.log10(power.real)
490 powerdB = numpy.squeeze(powerdB)
432 powerdB = numpy.squeeze(powerdB)
491
433
492 return powerdB
434 return powerdB
493
435
494 def getTimeInterval(self):
436 def getTimeInterval(self):
495
437
496 timeInterval = self.ippSeconds * self.nCohInt
438 timeInterval = self.ippSeconds * self.nCohInt
497
439
498 return timeInterval
440 return timeInterval
499
441
500 noise = property(getNoise, "I'm the 'nHeights' property.")
442 noise = property(getNoise, "I'm the 'nHeights' property.")
501 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
443 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
502
444
503
445
504 class Spectra(JROData):
446 class Spectra(JROData):
505
447
506 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
448 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
507 data_spc = None
449 data_spc = None
508
509 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
450 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
510 data_cspc = None
451 data_cspc = None
511
512 # data dc es un numpy array de 2 dmensiones (canales, alturas)
452 # data dc es un numpy array de 2 dmensiones (canales, alturas)
513 data_dc = None
453 data_dc = None
514
515 # data power
454 # data power
516 data_pwr = None
455 data_pwr = None
517
518 nFFTPoints = None
456 nFFTPoints = None
519
520 # nPairs = None
457 # nPairs = None
521
522 pairsList = None
458 pairsList = None
523
524 nIncohInt = None
459 nIncohInt = None
525
526 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
460 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
527
528 nCohInt = None # se requiere para determinar el valor de timeInterval
461 nCohInt = None # se requiere para determinar el valor de timeInterval
529
530 ippFactor = None
462 ippFactor = None
531
532 profileIndex = 0
463 profileIndex = 0
533
534 plotting = "spectra"
464 plotting = "spectra"
535
536 def __init__(self):
465 def __init__(self):
537 '''
466 '''
538 Constructor
467 Constructor
539 '''
468 '''
540
469
541 self.useLocalTime = True
470 self.useLocalTime = True
542
543 self.radarControllerHeaderObj = RadarControllerHeader()
471 self.radarControllerHeaderObj = RadarControllerHeader()
544
545 self.systemHeaderObj = SystemHeader()
472 self.systemHeaderObj = SystemHeader()
546
547 self.type = "Spectra"
473 self.type = "Spectra"
548
549 # self.data = None
474 # self.data = None
550
551 # self.dtype = None
475 # self.dtype = None
552
553 # self.nChannels = 0
476 # self.nChannels = 0
554
555 # self.nHeights = 0
477 # self.nHeights = 0
556
557 self.nProfiles = None
478 self.nProfiles = None
558
559 self.heightList = None
479 self.heightList = None
560
561 self.channelList = None
480 self.channelList = None
562
563 # self.channelIndexList = None
481 # self.channelIndexList = None
564
565 self.pairsList = None
482 self.pairsList = None
566
567 self.flagNoData = True
483 self.flagNoData = True
568
569 self.flagDiscontinuousBlock = False
484 self.flagDiscontinuousBlock = False
570
571 self.utctime = None
485 self.utctime = None
572
573 self.nCohInt = None
486 self.nCohInt = None
574
575 self.nIncohInt = None
487 self.nIncohInt = None
576
577 self.blocksize = None
488 self.blocksize = None
578
579 self.nFFTPoints = None
489 self.nFFTPoints = None
580
581 self.wavelength = None
490 self.wavelength = None
582
583 self.flagDecodeData = False # asumo q la data no esta decodificada
491 self.flagDecodeData = False # asumo q la data no esta decodificada
584
585 self.flagDeflipData = False # asumo q la data no esta sin flip
492 self.flagDeflipData = False # asumo q la data no esta sin flip
586
587 self.flagShiftFFT = False
493 self.flagShiftFFT = False
588
589 self.ippFactor = 1
494 self.ippFactor = 1
590
591 #self.noise = None
495 #self.noise = None
592
593 self.beacon_heiIndexList = []
496 self.beacon_heiIndexList = []
594
595 self.noise_estimation = None
497 self.noise_estimation = None
596
498
597 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
499 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
598 """
500 """
599 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
501 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
600
502
601 Return:
503 Return:
602 noiselevel
504 noiselevel
603 """
505 """
604
506
605 noise = numpy.zeros(self.nChannels)
507 noise = numpy.zeros(self.nChannels)
606
508
607 for channel in range(self.nChannels):
509 for channel in range(self.nChannels):
608 daux = self.data_spc[channel,
510 daux = self.data_spc[channel,
609 xmin_index:xmax_index, ymin_index:ymax_index]
511 xmin_index:xmax_index, ymin_index:ymax_index]
610 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
512 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
611
513
612 return noise
514 return noise
613
515
614 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
516 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
615
517
616 if self.noise_estimation is not None:
518 if self.noise_estimation is not None:
617 # this was estimated by getNoise Operation defined in jroproc_spectra.py
519 # this was estimated by getNoise Operation defined in jroproc_spectra.py
618 return self.noise_estimation
520 return self.noise_estimation
619 else:
521 else:
620 noise = self.getNoisebyHildebrand(
522 noise = self.getNoisebyHildebrand(
621 xmin_index, xmax_index, ymin_index, ymax_index)
523 xmin_index, xmax_index, ymin_index, ymax_index)
622 return noise
524 return noise
623
525
624 def getFreqRangeTimeResponse(self, extrapoints=0):
526 def getFreqRangeTimeResponse(self, extrapoints=0):
625
527
626 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
528 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
627 freqrange = deltafreq * \
529 freqrange = deltafreq * \
628 (numpy.arange(self.nFFTPoints + extrapoints) -
530 (numpy.arange(self.nFFTPoints + extrapoints) -
629 self.nFFTPoints / 2.) - deltafreq / 2
531 self.nFFTPoints / 2.) - deltafreq / 2
630
532
631 return freqrange
533 return freqrange
632
534
633 def getAcfRange(self, extrapoints=0):
535 def getAcfRange(self, extrapoints=0):
634
536
635 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
537 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
636 freqrange = deltafreq * \
538 freqrange = deltafreq * \
637 (numpy.arange(self.nFFTPoints + extrapoints) -
539 (numpy.arange(self.nFFTPoints + extrapoints) -
638 self.nFFTPoints / 2.) - deltafreq / 2
540 self.nFFTPoints / 2.) - deltafreq / 2
639
541
640 return freqrange
542 return freqrange
641
543
642 def getFreqRange(self, extrapoints=0):
544 def getFreqRange(self, extrapoints=0):
643
545
644 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
546 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
645 freqrange = deltafreq * \
547 freqrange = deltafreq * \
646 (numpy.arange(self.nFFTPoints + extrapoints) -
548 (numpy.arange(self.nFFTPoints + extrapoints) -
647 self.nFFTPoints / 2.) - deltafreq / 2
549 self.nFFTPoints / 2.) - deltafreq / 2
648
550
649 return freqrange
551 return freqrange
650
552
651 def getVelRange(self, extrapoints=0):
553 def getVelRange(self, extrapoints=0):
652
554
653 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
555 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
654 velrange = deltav * (numpy.arange(self.nFFTPoints +
556 velrange = deltav * (numpy.arange(self.nFFTPoints +
655 extrapoints) - self.nFFTPoints / 2.) # - deltav/2
557 extrapoints) - self.nFFTPoints / 2.) # - deltav/2
656
558
657 return velrange
559 return velrange
658
560
659 def getNPairs(self):
561 def getNPairs(self):
660
562
661 return len(self.pairsList)
563 return len(self.pairsList)
662
564
663 def getPairsIndexList(self):
565 def getPairsIndexList(self):
664
566
665 return list(range(self.nPairs))
567 return list(range(self.nPairs))
666
568
667 def getNormFactor(self):
569 def getNormFactor(self):
668
570
669 pwcode = 1
571 pwcode = 1
670
572
671 if self.flagDecodeData:
573 if self.flagDecodeData:
672 pwcode = numpy.sum(self.code[0]**2)
574 pwcode = numpy.sum(self.code[0]**2)
673 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
575 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
674 normFactor = self.nProfiles * self.nIncohInt * \
576 normFactor = self.nProfiles * self.nIncohInt * \
675 self.nCohInt * pwcode * self.windowOfFilter
577 self.nCohInt * pwcode * self.windowOfFilter
676
578
677 return normFactor
579 return normFactor
678
580
679 def getFlagCspc(self):
581 def getFlagCspc(self):
680
582
681 if self.data_cspc is None:
583 if self.data_cspc is None:
682 return True
584 return True
683
585
684 return False
586 return False
685
587
686 def getFlagDc(self):
588 def getFlagDc(self):
687
589
688 if self.data_dc is None:
590 if self.data_dc is None:
689 return True
591 return True
690
592
691 return False
593 return False
692
594
693 def getTimeInterval(self):
595 def getTimeInterval(self):
694
596
695 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
597 timeInterval = self.ippSeconds * self.nCohInt * \
598 self.nIncohInt * self.nProfiles * self.ippFactor
696
599
697 return timeInterval
600 return timeInterval
698
601
699 def getPower(self):
602 def getPower(self):
700
603
701 factor = self.normFactor
604 factor = self.normFactor
702 z = self.data_spc / factor
605 z = self.data_spc / factor
703 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
606 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
704 avg = numpy.average(z, axis=1)
607 avg = numpy.average(z, axis=1)
705
608
706 return 10 * numpy.log10(avg)
609 return 10 * numpy.log10(avg)
707
610
708 def getCoherence(self, pairsList=None, phase=False):
611 def getCoherence(self, pairsList=None, phase=False):
709
612
710 z = []
613 z = []
711 if pairsList is None:
614 if pairsList is None:
712 pairsIndexList = self.pairsIndexList
615 pairsIndexList = self.pairsIndexList
713 else:
616 else:
714 pairsIndexList = []
617 pairsIndexList = []
715 for pair in pairsList:
618 for pair in pairsList:
716 if pair not in self.pairsList:
619 if pair not in self.pairsList:
717 raise ValueError("Pair %s is not in dataOut.pairsList" % (
620 raise ValueError("Pair %s is not in dataOut.pairsList" % (
718 pair))
621 pair))
719 pairsIndexList.append(self.pairsList.index(pair))
622 pairsIndexList.append(self.pairsList.index(pair))
720 for i in range(len(pairsIndexList)):
623 for i in range(len(pairsIndexList)):
721 pair = self.pairsList[pairsIndexList[i]]
624 pair = self.pairsList[pairsIndexList[i]]
722 ccf = numpy.average(
625 ccf = numpy.average(
723 self.data_cspc[pairsIndexList[i], :, :], axis=0)
626 self.data_cspc[pairsIndexList[i], :, :], axis=0)
724 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
627 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
725 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
628 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
726 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
629 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
727 if phase:
630 if phase:
728 data = numpy.arctan2(avgcoherenceComplex.imag,
631 data = numpy.arctan2(avgcoherenceComplex.imag,
729 avgcoherenceComplex.real) * 180 / numpy.pi
632 avgcoherenceComplex.real) * 180 / numpy.pi
730 else:
633 else:
731 data = numpy.abs(avgcoherenceComplex)
634 data = numpy.abs(avgcoherenceComplex)
732
635
733 z.append(data)
636 z.append(data)
734
637
735 return numpy.array(z)
638 return numpy.array(z)
736
639
737 def setValue(self, value):
640 def setValue(self, value):
738
641
739 print("This property should not be initialized")
642 print("This property should not be initialized")
740
643
741 return
644 return
742
645
743 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
646 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
744 pairsIndexList = property(
647 pairsIndexList = property(
745 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
648 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
746 normFactor = property(getNormFactor, setValue,
649 normFactor = property(getNormFactor, setValue,
747 "I'm the 'getNormFactor' property.")
650 "I'm the 'getNormFactor' property.")
748 flag_cspc = property(getFlagCspc, setValue)
651 flag_cspc = property(getFlagCspc, setValue)
749 flag_dc = property(getFlagDc, setValue)
652 flag_dc = property(getFlagDc, setValue)
750 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
653 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
751 timeInterval = property(getTimeInterval, setValue,
654 timeInterval = property(getTimeInterval, setValue,
752 "I'm the 'timeInterval' property")
655 "I'm the 'timeInterval' property")
753
656
754
657
755 class SpectraHeis(Spectra):
658 class SpectraHeis(Spectra):
756
659
757 data_spc = None
660 data_spc = None
758
759 data_cspc = None
661 data_cspc = None
760
761 data_dc = None
662 data_dc = None
762
763 nFFTPoints = None
663 nFFTPoints = None
764
765 # nPairs = None
664 # nPairs = None
766
767 pairsList = None
665 pairsList = None
768
769 nCohInt = None
666 nCohInt = None
770
771 nIncohInt = None
667 nIncohInt = None
772
668
773 def __init__(self):
669 def __init__(self):
774
670
775 self.radarControllerHeaderObj = RadarControllerHeader()
671 self.radarControllerHeaderObj = RadarControllerHeader()
776
672
777 self.systemHeaderObj = SystemHeader()
673 self.systemHeaderObj = SystemHeader()
778
674
779 self.type = "SpectraHeis"
675 self.type = "SpectraHeis"
780
676
781 # self.dtype = None
677 # self.dtype = None
782
678
783 # self.nChannels = 0
679 # self.nChannels = 0
784
680
785 # self.nHeights = 0
681 # self.nHeights = 0
786
682
787 self.nProfiles = None
683 self.nProfiles = None
788
684
789 self.heightList = None
685 self.heightList = None
790
686
791 self.channelList = None
687 self.channelList = None
792
688
793 # self.channelIndexList = None
689 # self.channelIndexList = None
794
690
795 self.flagNoData = True
691 self.flagNoData = True
796
692
797 self.flagDiscontinuousBlock = False
693 self.flagDiscontinuousBlock = False
798
694
799 # self.nPairs = 0
695 # self.nPairs = 0
800
696
801 self.utctime = None
697 self.utctime = None
802
698
803 self.blocksize = None
699 self.blocksize = None
804
700
805 self.profileIndex = 0
701 self.profileIndex = 0
806
702
807 self.nCohInt = 1
703 self.nCohInt = 1
808
704
809 self.nIncohInt = 1
705 self.nIncohInt = 1
810
706
811 def getNormFactor(self):
707 def getNormFactor(self):
812 pwcode = 1
708 pwcode = 1
813 if self.flagDecodeData:
709 if self.flagDecodeData:
814 pwcode = numpy.sum(self.code[0]**2)
710 pwcode = numpy.sum(self.code[0]**2)
815
711
816 normFactor = self.nIncohInt * self.nCohInt * pwcode
712 normFactor = self.nIncohInt * self.nCohInt * pwcode
817
713
818 return normFactor
714 return normFactor
819
715
820 def getTimeInterval(self):
716 def getTimeInterval(self):
821
717
822 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
718 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
823
719
824 return timeInterval
720 return timeInterval
825
721
826 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
722 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
827 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
723 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
828
724
829
725
830 class Fits(JROData):
726 class Fits(JROData):
831
727
832 heightList = None
728 heightList = None
833
834 channelList = None
729 channelList = None
835
836 flagNoData = True
730 flagNoData = True
837
838 flagDiscontinuousBlock = False
731 flagDiscontinuousBlock = False
839
840 useLocalTime = False
732 useLocalTime = False
841
842 utctime = None
733 utctime = None
843
844 timeZone = None
734 timeZone = None
845
846 # ippSeconds = None
735 # ippSeconds = None
847
848 # timeInterval = None
736 # timeInterval = None
849
850 nCohInt = None
737 nCohInt = None
851
852 nIncohInt = None
738 nIncohInt = None
853
854 noise = None
739 noise = None
855
856 windowOfFilter = 1
740 windowOfFilter = 1
857
858 # Speed of ligth
741 # Speed of ligth
859 C = 3e8
742 C = 3e8
860
861 frequency = 49.92e6
743 frequency = 49.92e6
862
863 realtime = False
744 realtime = False
864
745
865 def __init__(self):
746 def __init__(self):
866
747
867 self.type = "Fits"
748 self.type = "Fits"
868
749
869 self.nProfiles = None
750 self.nProfiles = None
870
751
871 self.heightList = None
752 self.heightList = None
872
753
873 self.channelList = None
754 self.channelList = None
874
755
875 # self.channelIndexList = None
756 # self.channelIndexList = None
876
757
877 self.flagNoData = True
758 self.flagNoData = True
878
759
879 self.utctime = None
760 self.utctime = None
880
761
881 self.nCohInt = 1
762 self.nCohInt = 1
882
763
883 self.nIncohInt = 1
764 self.nIncohInt = 1
884
765
885 self.useLocalTime = True
766 self.useLocalTime = True
886
767
887 self.profileIndex = 0
768 self.profileIndex = 0
888
769
889 # self.utctime = None
770 # self.utctime = None
890 # self.timeZone = None
771 # self.timeZone = None
891 # self.ltctime = None
772 # self.ltctime = None
892 # self.timeInterval = None
773 # self.timeInterval = None
893 # self.header = None
774 # self.header = None
894 # self.data_header = None
775 # self.data_header = None
895 # self.data = None
776 # self.data = None
896 # self.datatime = None
777 # self.datatime = None
897 # self.flagNoData = False
778 # self.flagNoData = False
898 # self.expName = ''
779 # self.expName = ''
899 # self.nChannels = None
780 # self.nChannels = None
900 # self.nSamples = None
781 # self.nSamples = None
901 # self.dataBlocksPerFile = None
782 # self.dataBlocksPerFile = None
902 # self.comments = ''
783 # self.comments = ''
903 #
784 #
904
785
905 def getltctime(self):
786 def getltctime(self):
906
787
907 if self.useLocalTime:
788 if self.useLocalTime:
908 return self.utctime - self.timeZone * 60
789 return self.utctime - self.timeZone * 60
909
790
910 return self.utctime
791 return self.utctime
911
792
912 def getDatatime(self):
793 def getDatatime(self):
913
794
914 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
795 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
915 return datatime
796 return datatime
916
797
917 def getTimeRange(self):
798 def getTimeRange(self):
918
799
919 datatime = []
800 datatime = []
920
801
921 datatime.append(self.ltctime)
802 datatime.append(self.ltctime)
922 datatime.append(self.ltctime + self.timeInterval)
803 datatime.append(self.ltctime + self.timeInterval)
923
804
924 datatime = numpy.array(datatime)
805 datatime = numpy.array(datatime)
925
806
926 return datatime
807 return datatime
927
808
928 def getHeiRange(self):
809 def getHeiRange(self):
929
810
930 heis = self.heightList
811 heis = self.heightList
931
812
932 return heis
813 return heis
933
814
934 def getNHeights(self):
815 def getNHeights(self):
935
816
936 return len(self.heightList)
817 return len(self.heightList)
937
818
938 def getNChannels(self):
819 def getNChannels(self):
939
820
940 return len(self.channelList)
821 return len(self.channelList)
941
822
942 def getChannelIndexList(self):
823 def getChannelIndexList(self):
943
824
944 return list(range(self.nChannels))
825 return list(range(self.nChannels))
945
826
946 def getNoise(self, type=1):
827 def getNoise(self, type=1):
947
828
948 #noise = numpy.zeros(self.nChannels)
829 #noise = numpy.zeros(self.nChannels)
949
830
950 if type == 1:
831 if type == 1:
951 noise = self.getNoisebyHildebrand()
832 noise = self.getNoisebyHildebrand()
952
833
953 if type == 2:
834 if type == 2:
954 noise = self.getNoisebySort()
835 noise = self.getNoisebySort()
955
836
956 if type == 3:
837 if type == 3:
957 noise = self.getNoisebyWindow()
838 noise = self.getNoisebyWindow()
958
839
959 return noise
840 return noise
960
841
961 def getTimeInterval(self):
842 def getTimeInterval(self):
962
843
963 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
844 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
964
845
965 return timeInterval
846 return timeInterval
966
847
967 datatime = property(getDatatime, "I'm the 'datatime' property")
848 datatime = property(getDatatime, "I'm the 'datatime' property")
968 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
849 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
969 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
850 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
970 channelIndexList = property(
851 channelIndexList = property(
971 getChannelIndexList, "I'm the 'channelIndexList' property.")
852 getChannelIndexList, "I'm the 'channelIndexList' property.")
972 noise = property(getNoise, "I'm the 'nHeights' property.")
853 noise = property(getNoise, "I'm the 'nHeights' property.")
973
854
974 ltctime = property(getltctime, "I'm the 'ltctime' property")
855 ltctime = property(getltctime, "I'm the 'ltctime' property")
975 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
856 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
976
857
977
858
978 class Correlation(JROData):
859 class Correlation(JROData):
979
860
980 noise = None
861 noise = None
981
982 SNR = None
862 SNR = None
983
984 #--------------------------------------------------
863 #--------------------------------------------------
985
986 mode = None
864 mode = None
987
988 split = False
865 split = False
989
990 data_cf = None
866 data_cf = None
991
992 lags = None
867 lags = None
993
994 lagRange = None
868 lagRange = None
995
996 pairsList = None
869 pairsList = None
997
998 normFactor = None
870 normFactor = None
999
1000 #--------------------------------------------------
871 #--------------------------------------------------
1001
1002 # calculateVelocity = None
872 # calculateVelocity = None
1003
1004 nLags = None
873 nLags = None
1005
1006 nPairs = None
874 nPairs = None
1007
1008 nAvg = None
875 nAvg = None
1009
876
1010 def __init__(self):
877 def __init__(self):
1011 '''
878 '''
1012 Constructor
879 Constructor
1013 '''
880 '''
1014 self.radarControllerHeaderObj = RadarControllerHeader()
881 self.radarControllerHeaderObj = RadarControllerHeader()
1015
882
1016 self.systemHeaderObj = SystemHeader()
883 self.systemHeaderObj = SystemHeader()
1017
884
1018 self.type = "Correlation"
885 self.type = "Correlation"
1019
886
1020 self.data = None
887 self.data = None
1021
888
1022 self.dtype = None
889 self.dtype = None
1023
890
1024 self.nProfiles = None
891 self.nProfiles = None
1025
892
1026 self.heightList = None
893 self.heightList = None
1027
894
1028 self.channelList = None
895 self.channelList = None
1029
896
1030 self.flagNoData = True
897 self.flagNoData = True
1031
898
1032 self.flagDiscontinuousBlock = False
899 self.flagDiscontinuousBlock = False
1033
900
1034 self.utctime = None
901 self.utctime = None
1035
902
1036 self.timeZone = None
903 self.timeZone = None
1037
904
1038 self.dstFlag = None
905 self.dstFlag = None
1039
906
1040 self.errorCount = None
907 self.errorCount = None
1041
908
1042 self.blocksize = None
909 self.blocksize = None
1043
910
1044 self.flagDecodeData = False # asumo q la data no esta decodificada
911 self.flagDecodeData = False # asumo q la data no esta decodificada
1045
912
1046 self.flagDeflipData = False # asumo q la data no esta sin flip
913 self.flagDeflipData = False # asumo q la data no esta sin flip
1047
914
1048 self.pairsList = None
915 self.pairsList = None
1049
916
1050 self.nPoints = None
917 self.nPoints = None
1051
918
1052 def getPairsList(self):
919 def getPairsList(self):
1053
920
1054 return self.pairsList
921 return self.pairsList
1055
922
1056 def getNoise(self, mode=2):
923 def getNoise(self, mode=2):
1057
924
1058 indR = numpy.where(self.lagR == 0)[0][0]
925 indR = numpy.where(self.lagR == 0)[0][0]
1059 indT = numpy.where(self.lagT == 0)[0][0]
926 indT = numpy.where(self.lagT == 0)[0][0]
1060
927
1061 jspectra0 = self.data_corr[:, :, indR, :]
928 jspectra0 = self.data_corr[:, :, indR, :]
1062 jspectra = copy.copy(jspectra0)
929 jspectra = copy.copy(jspectra0)
1063
930
1064 num_chan = jspectra.shape[0]
931 num_chan = jspectra.shape[0]
1065 num_hei = jspectra.shape[2]
932 num_hei = jspectra.shape[2]
1066
933
1067 freq_dc = jspectra.shape[1] / 2
934 freq_dc = jspectra.shape[1] / 2
1068 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
935 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
1069
936
1070 if ind_vel[0] < 0:
937 if ind_vel[0] < 0:
1071 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
938 ind_vel[list(range(0, 1))] = ind_vel[list(
939 range(0, 1))] + self.num_prof
1072
940
1073 if mode == 1:
941 if mode == 1:
1074 jspectra[:, freq_dc, :] = (
942 jspectra[:, freq_dc, :] = (
1075 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
943 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
1076
944
1077 if mode == 2:
945 if mode == 2:
1078
946
1079 vel = numpy.array([-2, -1, 1, 2])
947 vel = numpy.array([-2, -1, 1, 2])
1080 xx = numpy.zeros([4, 4])
948 xx = numpy.zeros([4, 4])
1081
949
1082 for fil in range(4):
950 for fil in range(4):
1083 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
951 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
1084
952
1085 xx_inv = numpy.linalg.inv(xx)
953 xx_inv = numpy.linalg.inv(xx)
1086 xx_aux = xx_inv[0, :]
954 xx_aux = xx_inv[0, :]
1087
955
1088 for ich in range(num_chan):
956 for ich in range(num_chan):
1089 yy = jspectra[ich, ind_vel, :]
957 yy = jspectra[ich, ind_vel, :]
1090 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
958 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
1091
959
1092 junkid = jspectra[ich, freq_dc, :] <= 0
960 junkid = jspectra[ich, freq_dc, :] <= 0
1093 cjunkid = sum(junkid)
961 cjunkid = sum(junkid)
1094
962
1095 if cjunkid.any():
963 if cjunkid.any():
1096 jspectra[ich, freq_dc, junkid.nonzero()] = (
964 jspectra[ich, freq_dc, junkid.nonzero()] = (
1097 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
965 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
1098
966
1099 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
967 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
1100
968
1101 return noise
969 return noise
1102
970
1103 def getTimeInterval(self):
971 def getTimeInterval(self):
1104
972
1105 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
973 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
1106
974
1107 return timeInterval
975 return timeInterval
1108
976
1109 def splitFunctions(self):
977 def splitFunctions(self):
1110
978
1111 pairsList = self.pairsList
979 pairsList = self.pairsList
1112 ccf_pairs = []
980 ccf_pairs = []
1113 acf_pairs = []
981 acf_pairs = []
1114 ccf_ind = []
982 ccf_ind = []
1115 acf_ind = []
983 acf_ind = []
1116 for l in range(len(pairsList)):
984 for l in range(len(pairsList)):
1117 chan0 = pairsList[l][0]
985 chan0 = pairsList[l][0]
1118 chan1 = pairsList[l][1]
986 chan1 = pairsList[l][1]
1119
987
1120 # Obteniendo pares de Autocorrelacion
988 # Obteniendo pares de Autocorrelacion
1121 if chan0 == chan1:
989 if chan0 == chan1:
1122 acf_pairs.append(chan0)
990 acf_pairs.append(chan0)
1123 acf_ind.append(l)
991 acf_ind.append(l)
1124 else:
992 else:
1125 ccf_pairs.append(pairsList[l])
993 ccf_pairs.append(pairsList[l])
1126 ccf_ind.append(l)
994 ccf_ind.append(l)
1127
995
1128 data_acf = self.data_cf[acf_ind]
996 data_acf = self.data_cf[acf_ind]
1129 data_ccf = self.data_cf[ccf_ind]
997 data_ccf = self.data_cf[ccf_ind]
1130
998
1131 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
999 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1132
1000
1133 def getNormFactor(self):
1001 def getNormFactor(self):
1134 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1002 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1135 acf_pairs = numpy.array(acf_pairs)
1003 acf_pairs = numpy.array(acf_pairs)
1136 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1004 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1137
1005
1138 for p in range(self.nPairs):
1006 for p in range(self.nPairs):
1139 pair = self.pairsList[p]
1007 pair = self.pairsList[p]
1140
1008
1141 ch0 = pair[0]
1009 ch0 = pair[0]
1142 ch1 = pair[1]
1010 ch1 = pair[1]
1143
1011
1144 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1012 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1145 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1013 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1146 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1014 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1147
1015
1148 return normFactor
1016 return normFactor
1149
1017
1150 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1018 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1151 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1019 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1152
1020
1153
1021
1154 class Parameters(Spectra):
1022 class Parameters(Spectra):
1155
1023
1156 experimentInfo = None # Information about the experiment
1024 experimentInfo = None # Information about the experiment
1157
1158 # Information from previous data
1025 # Information from previous data
1159
1160 inputUnit = None # Type of data to be processed
1026 inputUnit = None # Type of data to be processed
1161
1162 operation = None # Type of operation to parametrize
1027 operation = None # Type of operation to parametrize
1163
1164 # normFactor = None #Normalization Factor
1028 # normFactor = None #Normalization Factor
1165
1166 groupList = None # List of Pairs, Groups, etc
1029 groupList = None # List of Pairs, Groups, etc
1167
1168 # Parameters
1030 # Parameters
1169
1170 data_param = None # Parameters obtained
1031 data_param = None # Parameters obtained
1171
1172 data_pre = None # Data Pre Parametrization
1032 data_pre = None # Data Pre Parametrization
1173
1174 data_SNR = None # Signal to Noise Ratio
1033 data_SNR = None # Signal to Noise Ratio
1175
1176 # heightRange = None #Heights
1034 # heightRange = None #Heights
1177
1178 abscissaList = None # Abscissa, can be velocities, lags or time
1035 abscissaList = None # Abscissa, can be velocities, lags or time
1179
1180 # noise = None #Noise Potency
1036 # noise = None #Noise Potency
1181
1182 utctimeInit = None # Initial UTC time
1037 utctimeInit = None # Initial UTC time
1183
1184 paramInterval = None # Time interval to calculate Parameters in seconds
1038 paramInterval = None # Time interval to calculate Parameters in seconds
1185
1186 useLocalTime = True
1039 useLocalTime = True
1187
1188 # Fitting
1040 # Fitting
1189
1190 data_error = None # Error of the estimation
1041 data_error = None # Error of the estimation
1191
1192 constants = None
1042 constants = None
1193
1194 library = None
1043 library = None
1195
1196 # Output signal
1044 # Output signal
1197
1198 outputInterval = None # Time interval to calculate output signal in seconds
1045 outputInterval = None # Time interval to calculate output signal in seconds
1199
1200 data_output = None # Out signal
1046 data_output = None # Out signal
1201
1202 nAvg = None
1047 nAvg = None
1203
1204 noise_estimation = None
1048 noise_estimation = None
1205
1206 GauSPC = None # Fit gaussian SPC
1049 GauSPC = None # Fit gaussian SPC
1207
1050
1208 def __init__(self):
1051 def __init__(self):
1209 '''
1052 '''
1210 Constructor
1053 Constructor
1211 '''
1054 '''
1212 self.radarControllerHeaderObj = RadarControllerHeader()
1055 self.radarControllerHeaderObj = RadarControllerHeader()
1213
1056
1214 self.systemHeaderObj = SystemHeader()
1057 self.systemHeaderObj = SystemHeader()
1215
1058
1216 self.type = "Parameters"
1059 self.type = "Parameters"
1217
1060
1218 def getTimeRange1(self, interval):
1061 def getTimeRange1(self, interval):
1219
1062
1220 datatime = []
1063 datatime = []
1221
1064
1222 if self.useLocalTime:
1065 if self.useLocalTime:
1223 time1 = self.utctimeInit - self.timeZone * 60
1066 time1 = self.utctimeInit - self.timeZone * 60
1224 else:
1067 else:
1225 time1 = self.utctimeInit
1068 time1 = self.utctimeInit
1226
1069
1227 datatime.append(time1)
1070 datatime.append(time1)
1228 datatime.append(time1 + interval)
1071 datatime.append(time1 + interval)
1229 datatime = numpy.array(datatime)
1072 datatime = numpy.array(datatime)
1230
1073
1231 return datatime
1074 return datatime
1232
1075
1233 def getTimeInterval(self):
1076 def getTimeInterval(self):
1234
1077
1235 if hasattr(self, 'timeInterval1'):
1078 if hasattr(self, 'timeInterval1'):
1236 return self.timeInterval1
1079 return self.timeInterval1
1237 else:
1080 else:
1238 return self.paramInterval
1081 return self.paramInterval
1239
1082
1240 def setValue(self, value):
1083 def setValue(self, value):
1241
1084
1242 print("This property should not be initialized")
1085 print("This property should not be initialized")
1243
1086
1244 return
1087 return
1245
1088
1246 def getNoise(self):
1089 def getNoise(self):
1247
1090
1248 return self.spc_noise
1091 return self.spc_noise
1249
1092
1250 timeInterval = property(getTimeInterval)
1093 timeInterval = property(getTimeInterval)
1251 noise = property(getNoise, setValue, "I'm the 'Noise' property.") No newline at end of file
1094 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1095
1096
1097 class PlotterData(object):
1098 '''
1099 Object to hold data to be plotted
1100 '''
1101
1102 MAXNUMX = 100
1103 MAXNUMY = 100
1104
1105 def __init__(self, code, throttle_value, exp_code, buffering=True):
1106
1107 self.throttle = throttle_value
1108 self.exp_code = exp_code
1109 self.buffering = buffering
1110 self.ready = False
1111 self.localtime = False
1112 self.data = {}
1113 self.meta = {}
1114 self.__times = []
1115 self.__heights = []
1116
1117 if 'snr' in code:
1118 self.plottypes = ['snr']
1119 elif code == 'spc':
1120 self.plottypes = ['spc', 'noise', 'rti']
1121 elif code == 'rti':
1122 self.plottypes = ['noise', 'rti']
1123 else:
1124 self.plottypes = [code]
1125
1126 for plot in self.plottypes:
1127 self.data[plot] = {}
1128
1129 def __str__(self):
1130 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1131 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
1132
1133 def __len__(self):
1134 return len(self.__times)
1135
1136 def __getitem__(self, key):
1137
1138 if key not in self.data:
1139 raise KeyError(log.error('Missing key: {}'.format(key)))
1140 if 'spc' in key or not self.buffering:
1141 ret = self.data[key]
1142 else:
1143 ret = numpy.array([self.data[key][x] for x in self.times])
1144 if ret.ndim > 1:
1145 ret = numpy.swapaxes(ret, 0, 1)
1146 return ret
1147
1148 def __contains__(self, key):
1149 return key in self.data
1150
1151 def setup(self):
1152 '''
1153 Configure object
1154 '''
1155
1156 self.type = ''
1157 self.ready = False
1158 self.data = {}
1159 self.__times = []
1160 self.__heights = []
1161 self.__all_heights = set()
1162 for plot in self.plottypes:
1163 if 'snr' in plot:
1164 plot = 'snr'
1165 self.data[plot] = {}
1166
1167 if 'spc' in self.data or 'rti' in self.data:
1168 self.data['noise'] = {}
1169 if 'noise' not in self.plottypes:
1170 self.plottypes.append('noise')
1171
1172 def shape(self, key):
1173 '''
1174 Get the shape of the one-element data for the given key
1175 '''
1176
1177 if len(self.data[key]):
1178 if 'spc' in key or not self.buffering:
1179 return self.data[key].shape
1180 return self.data[key][self.__times[0]].shape
1181 return (0,)
1182
1183 def update(self, dataOut, tm):
1184 '''
1185 Update data object with new dataOut
1186 '''
1187
1188 if tm in self.__times:
1189 return
1190
1191 self.type = dataOut.type
1192 self.parameters = getattr(dataOut, 'parameters', [])
1193 if hasattr(dataOut, 'pairsList'):
1194 self.pairs = dataOut.pairsList
1195 if hasattr(dataOut, 'meta'):
1196 self.meta = dataOut.meta
1197 self.channels = dataOut.channelList
1198 self.interval = dataOut.getTimeInterval()
1199 self.localtime = dataOut.useLocalTime
1200 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
1201 self.xrange = (dataOut.getFreqRange(1)/1000.,
1202 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1203 self.__heights.append(dataOut.heightList)
1204 self.__all_heights.update(dataOut.heightList)
1205 self.__times.append(tm)
1206
1207 for plot in self.plottypes:
1208 if plot == 'spc':
1209 z = dataOut.data_spc/dataOut.normFactor
1210 buffer = 10*numpy.log10(z)
1211 if plot == 'cspc':
1212 buffer = dataOut.data_cspc
1213 if plot == 'noise':
1214 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1215 if plot == 'rti':
1216 buffer = dataOut.getPower()
1217 if plot == 'snr_db':
1218 buffer = dataOut.data_SNR
1219 if plot == 'snr':
1220 buffer = 10*numpy.log10(dataOut.data_SNR)
1221 if plot == 'dop':
1222 buffer = 10*numpy.log10(dataOut.data_DOP)
1223 if plot == 'mean':
1224 buffer = dataOut.data_MEAN
1225 if plot == 'std':
1226 buffer = dataOut.data_STD
1227 if plot == 'coh':
1228 buffer = dataOut.getCoherence()
1229 if plot == 'phase':
1230 buffer = dataOut.getCoherence(phase=True)
1231 if plot == 'output':
1232 buffer = dataOut.data_output
1233 if plot == 'param':
1234 buffer = dataOut.data_param
1235
1236 if 'spc' in plot:
1237 self.data[plot] = buffer
1238 else:
1239 if self.buffering:
1240 self.data[plot][tm] = buffer
1241 else:
1242 self.data[plot] = buffer
1243
1244 def normalize_heights(self):
1245 '''
1246 Ensure same-dimension of the data for different heighList
1247 '''
1248
1249 H = numpy.array(list(self.__all_heights))
1250 H.sort()
1251 for key in self.data:
1252 shape = self.shape(key)[:-1] + H.shape
1253 for tm, obj in list(self.data[key].items()):
1254 h = self.__heights[self.__times.index(tm)]
1255 if H.size == h.size:
1256 continue
1257 index = numpy.where(numpy.in1d(H, h))[0]
1258 dummy = numpy.zeros(shape) + numpy.nan
1259 if len(shape) == 2:
1260 dummy[:, index] = obj
1261 else:
1262 dummy[index] = obj
1263 self.data[key][tm] = dummy
1264
1265 self.__heights = [H for tm in self.__times]
1266
1267 def jsonify(self, decimate=False):
1268 '''
1269 Convert data to json
1270 '''
1271
1272 data = {}
1273 tm = self.times[-1]
1274 dy = int(self.heights.size/self.MAXNUMY) + 1
1275 for key in self.data:
1276 if key in ('spc', 'cspc') or not self.buffering:
1277 dx = int(self.data[key].shape[1]/self.MAXNUMX) + 1
1278 data[key] = self.roundFloats(
1279 self.data[key][::, ::dx, ::dy].tolist())
1280 else:
1281 data[key] = self.roundFloats(self.data[key][tm].tolist())
1282
1283 ret = {'data': data}
1284 ret['exp_code'] = self.exp_code
1285 ret['time'] = float(tm)
1286 ret['interval'] = float(self.interval)
1287 ret['localtime'] = self.localtime
1288 ret['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1289 if 'spc' in self.data or 'cspc' in self.data:
1290 ret['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1291 else:
1292 ret['xrange'] = []
1293 if hasattr(self, 'pairs'):
1294 ret['pairs'] = [(int(p[0]), int(p[1])) for p in self.pairs]
1295 else:
1296 ret['pairs'] = []
1297
1298 for key, value in list(self.meta.items()):
1299 ret[key] = value
1300
1301 return json.dumps(ret)
1302
1303 @property
1304 def times(self):
1305 '''
1306 Return the list of times of the current data
1307 '''
1308
1309 ret = numpy.array(self.__times)
1310 ret.sort()
1311 return ret
1312
1313 @property
1314 def min_time(self):
1315 '''
1316 Return the minimun time value
1317 '''
1318
1319 return self.times[0]
1320
1321 @property
1322 def max_time(self):
1323 '''
1324 Return the maximun time value
1325 '''
1326
1327 return self.times[-1]
1328
1329 @property
1330 def heights(self):
1331 '''
1332 Return the list of heights of the current data
1333 '''
1334
1335 return numpy.array(self.__heights[-1])
1336
1337 @staticmethod
1338 def roundFloats(obj):
1339 if isinstance(obj, list):
1340 return list(map(PlotterData.roundFloats, obj))
1341 elif isinstance(obj, float):
1342 return round(obj, 2)
@@ -1,7 +1,6
1 from .jroplot_voltage import *
1 from .jroplot_voltage import *
2 from .jroplot_spectra import *
2 from .jroplot_spectra import *
3 from .jroplot_heispectra import *
3 from .jroplot_heispectra import *
4 from .jroplot_correlation import *
4 from .jroplot_correlation import *
5 from .jroplot_parameters import *
5 from .jroplot_parameters import *
6 from .jroplot_data import *
6 from .jroplot_data import *
7 from .jroplotter import *
@@ -1,187 +1,187
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4 import copy
4 import copy
5 from schainpy.model import *
5 from schainpy.model import *
6 from .figure import Figure, isRealtime
6 from .figure import Figure, isRealtime
7
7
8 class CorrelationPlot(Figure):
8 class CorrelationPlot_(Figure):
9 isConfig = None
9 isConfig = None
10 __nsubplots = None
10 __nsubplots = None
11
11
12 WIDTHPROF = None
12 WIDTHPROF = None
13 HEIGHTPROF = None
13 HEIGHTPROF = None
14 PREFIX = 'corr'
14 PREFIX = 'corr'
15
15
16 def __init__(self, **kwargs):
16 def __init__(self, **kwargs):
17 Figure.__init__(self, **kwargs)
17 Figure.__init__(self, **kwargs)
18 self.isConfig = False
18 self.isConfig = False
19 self.__nsubplots = 1
19 self.__nsubplots = 1
20
20
21 self.WIDTH = 280
21 self.WIDTH = 280
22 self.HEIGHT = 250
22 self.HEIGHT = 250
23 self.WIDTHPROF = 120
23 self.WIDTHPROF = 120
24 self.HEIGHTPROF = 0
24 self.HEIGHTPROF = 0
25 self.counter_imagwr = 0
25 self.counter_imagwr = 0
26
26
27 self.PLOT_CODE = 1
27 self.PLOT_CODE = 1
28 self.FTP_WEI = None
28 self.FTP_WEI = None
29 self.EXP_CODE = None
29 self.EXP_CODE = None
30 self.SUB_EXP_CODE = None
30 self.SUB_EXP_CODE = None
31 self.PLOT_POS = None
31 self.PLOT_POS = None
32
32
33 def getSubplots(self):
33 def getSubplots(self):
34
34
35 ncol = int(numpy.sqrt(self.nplots)+0.9)
35 ncol = int(numpy.sqrt(self.nplots)+0.9)
36 nrow = int(self.nplots*1./ncol + 0.9)
36 nrow = int(self.nplots*1./ncol + 0.9)
37
37
38 return nrow, ncol
38 return nrow, ncol
39
39
40 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
40 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
41
41
42 showprofile = False
42 showprofile = False
43 self.__showprofile = showprofile
43 self.__showprofile = showprofile
44 self.nplots = nplots
44 self.nplots = nplots
45
45
46 ncolspan = 1
46 ncolspan = 1
47 colspan = 1
47 colspan = 1
48 if showprofile:
48 if showprofile:
49 ncolspan = 3
49 ncolspan = 3
50 colspan = 2
50 colspan = 2
51 self.__nsubplots = 2
51 self.__nsubplots = 2
52
52
53 self.createFigure(id = id,
53 self.createFigure(id = id,
54 wintitle = wintitle,
54 wintitle = wintitle,
55 widthplot = self.WIDTH + self.WIDTHPROF,
55 widthplot = self.WIDTH + self.WIDTHPROF,
56 heightplot = self.HEIGHT + self.HEIGHTPROF,
56 heightplot = self.HEIGHT + self.HEIGHTPROF,
57 show=show)
57 show=show)
58
58
59 nrow, ncol = self.getSubplots()
59 nrow, ncol = self.getSubplots()
60
60
61 counter = 0
61 counter = 0
62 for y in range(nrow):
62 for y in range(nrow):
63 for x in range(ncol):
63 for x in range(ncol):
64
64
65 if counter >= self.nplots:
65 if counter >= self.nplots:
66 break
66 break
67
67
68 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
68 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
69
69
70 if showprofile:
70 if showprofile:
71 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
71 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
72
72
73 counter += 1
73 counter += 1
74
74
75 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
75 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
76 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
76 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
77 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
77 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
78 server=None, folder=None, username=None, password=None,
78 server=None, folder=None, username=None, password=None,
79 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
79 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
80
80
81 """
81 """
82
82
83 Input:
83 Input:
84 dataOut :
84 dataOut :
85 id :
85 id :
86 wintitle :
86 wintitle :
87 channelList :
87 channelList :
88 showProfile :
88 showProfile :
89 xmin : None,
89 xmin : None,
90 xmax : None,
90 xmax : None,
91 ymin : None,
91 ymin : None,
92 ymax : None,
92 ymax : None,
93 zmin : None,
93 zmin : None,
94 zmax : None
94 zmax : None
95 """
95 """
96
96
97 if dataOut.flagNoData:
97 if dataOut.flagNoData:
98 return None
98 return None
99
99
100 if realtime:
100 if realtime:
101 if not(isRealtime(utcdatatime = dataOut.utctime)):
101 if not(isRealtime(utcdatatime = dataOut.utctime)):
102 print('Skipping this plot function')
102 print('Skipping this plot function')
103 return
103 return
104
104
105 if channelList == None:
105 if channelList == None:
106 channelIndexList = dataOut.channelIndexList
106 channelIndexList = dataOut.channelIndexList
107 else:
107 else:
108 channelIndexList = []
108 channelIndexList = []
109 for channel in channelList:
109 for channel in channelList:
110 if channel not in dataOut.channelList:
110 if channel not in dataOut.channelList:
111 raise ValueError("Channel %d is not in dataOut.channelList")
111 raise ValueError("Channel %d is not in dataOut.channelList")
112 channelIndexList.append(dataOut.channelList.index(channel))
112 channelIndexList.append(dataOut.channelList.index(channel))
113
113
114 factor = dataOut.normFactor
114 factor = dataOut.normFactor
115 lenfactor = factor.shape[1]
115 lenfactor = factor.shape[1]
116 x = dataOut.getLagTRange(1)
116 x = dataOut.getLagTRange(1)
117 y = dataOut.getHeiRange()
117 y = dataOut.getHeiRange()
118
118
119 z = copy.copy(dataOut.data_corr[:,:,0,:])
119 z = copy.copy(dataOut.data_corr[:,:,0,:])
120 for i in range(dataOut.data_corr.shape[0]):
120 for i in range(dataOut.data_corr.shape[0]):
121 z[i,:,:] = z[i,:,:]/factor[i,:]
121 z[i,:,:] = z[i,:,:]/factor[i,:]
122 zdB = numpy.abs(z)
122 zdB = numpy.abs(z)
123
123
124 avg = numpy.average(z, axis=1)
124 avg = numpy.average(z, axis=1)
125 # avg = numpy.nanmean(z, axis=1)
125 # avg = numpy.nanmean(z, axis=1)
126 # noise = dataOut.noise/factor
126 # noise = dataOut.noise/factor
127
127
128 #thisDatetime = dataOut.datatime
128 #thisDatetime = dataOut.datatime
129 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
129 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
130 title = wintitle + " Correlation"
130 title = wintitle + " Correlation"
131 xlabel = "Lag T (s)"
131 xlabel = "Lag T (s)"
132 ylabel = "Range (Km)"
132 ylabel = "Range (Km)"
133
133
134 if not self.isConfig:
134 if not self.isConfig:
135
135
136 nplots = dataOut.data_corr.shape[0]
136 nplots = dataOut.data_corr.shape[0]
137
137
138 self.setup(id=id,
138 self.setup(id=id,
139 nplots=nplots,
139 nplots=nplots,
140 wintitle=wintitle,
140 wintitle=wintitle,
141 showprofile=showprofile,
141 showprofile=showprofile,
142 show=show)
142 show=show)
143
143
144 if xmin == None: xmin = numpy.nanmin(x)
144 if xmin == None: xmin = numpy.nanmin(x)
145 if xmax == None: xmax = numpy.nanmax(x)
145 if xmax == None: xmax = numpy.nanmax(x)
146 if ymin == None: ymin = numpy.nanmin(y)
146 if ymin == None: ymin = numpy.nanmin(y)
147 if ymax == None: ymax = numpy.nanmax(y)
147 if ymax == None: ymax = numpy.nanmax(y)
148 if zmin == None: zmin = 0
148 if zmin == None: zmin = 0
149 if zmax == None: zmax = 1
149 if zmax == None: zmax = 1
150
150
151 self.FTP_WEI = ftp_wei
151 self.FTP_WEI = ftp_wei
152 self.EXP_CODE = exp_code
152 self.EXP_CODE = exp_code
153 self.SUB_EXP_CODE = sub_exp_code
153 self.SUB_EXP_CODE = sub_exp_code
154 self.PLOT_POS = plot_pos
154 self.PLOT_POS = plot_pos
155
155
156 self.isConfig = True
156 self.isConfig = True
157
157
158 self.setWinTitle(title)
158 self.setWinTitle(title)
159
159
160 for i in range(self.nplots):
160 for i in range(self.nplots):
161 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
161 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
162 title = "Channel %d and %d: : %s" %(dataOut.pairsList[i][0],dataOut.pairsList[i][1] , str_datetime)
162 title = "Channel %d and %d: : %s" %(dataOut.pairsList[i][0],dataOut.pairsList[i][1] , str_datetime)
163 axes = self.axesList[i*self.__nsubplots]
163 axes = self.axesList[i*self.__nsubplots]
164 axes.pcolor(x, y, zdB[i,:,:],
164 axes.pcolor(x, y, zdB[i,:,:],
165 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
165 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
166 xlabel=xlabel, ylabel=ylabel, title=title,
166 xlabel=xlabel, ylabel=ylabel, title=title,
167 ticksize=9, cblabel='')
167 ticksize=9, cblabel='')
168
168
169 # if self.__showprofile:
169 # if self.__showprofile:
170 # axes = self.axesList[i*self.__nsubplots +1]
170 # axes = self.axesList[i*self.__nsubplots +1]
171 # axes.pline(avgdB[i], y,
171 # axes.pline(avgdB[i], y,
172 # xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
172 # xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
173 # xlabel='dB', ylabel='', title='',
173 # xlabel='dB', ylabel='', title='',
174 # ytick_visible=False,
174 # ytick_visible=False,
175 # grid='x')
175 # grid='x')
176 #
176 #
177 # noiseline = numpy.repeat(noisedB[i], len(y))
177 # noiseline = numpy.repeat(noisedB[i], len(y))
178 # axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
178 # axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
179
179
180 self.draw()
180 self.draw()
181
181
182 self.save(figpath=figpath,
182 self.save(figpath=figpath,
183 figfile=figfile,
183 figfile=figfile,
184 save=save,
184 save=save,
185 ftp=ftp,
185 ftp=ftp,
186 wr_period=wr_period,
186 wr_period=wr_period,
187 thisDatetime=thisDatetime) No newline at end of file
187 thisDatetime=thisDatetime)
This diff has been collapsed as it changes many lines, (685 lines changed) Show them Hide them
@@ -1,1154 +1,613
1 '''
2 New Plots Operations
3
4 @author: juan.espinoza@jro.igp.gob.pe
5 '''
6
1
7
2 import os
3 import time
8 import time
4 import glob
5 import datetime
9 import datetime
6 from multiprocessing import Process
7
8 import zmq
9 import numpy
10 import numpy
10 import matplotlib
11 import matplotlib.pyplot as plt
12 from matplotlib.patches import Polygon
13 from mpl_toolkits.axes_grid1 import make_axes_locatable
14 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
15
11
16 from schainpy.model.proc.jroproc_base import Operation
12 from schainpy.model.graphics.jroplot_base import Plot, plt
17 from schainpy.utils import log
13 from schainpy.utils import log
18
14
19 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
20 blu_values = matplotlib.pyplot.get_cmap(
21 'seismic_r', 20)(numpy.arange(20))[10:15]
22 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
23 'jro', numpy.vstack((blu_values, jet_values)))
24 matplotlib.pyplot.register_cmap(cmap=ncmap)
25
26 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis', 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
27
28 EARTH_RADIUS = 6.3710e3
15 EARTH_RADIUS = 6.3710e3
29
16
17
30 def ll2xy(lat1, lon1, lat2, lon2):
18 def ll2xy(lat1, lon1, lat2, lon2):
31
19
32 p = 0.017453292519943295
20 p = 0.017453292519943295
33 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
21 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
22 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
34 r = 12742 * numpy.arcsin(numpy.sqrt(a))
23 r = 12742 * numpy.arcsin(numpy.sqrt(a))
35 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)*numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
24 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
25 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
36 theta = -theta + numpy.pi/2
26 theta = -theta + numpy.pi/2
37 return r*numpy.cos(theta), r*numpy.sin(theta)
27 return r*numpy.cos(theta), r*numpy.sin(theta)
38
28
29
39 def km2deg(km):
30 def km2deg(km):
40 '''
31 '''
41 Convert distance in km to degrees
32 Convert distance in km to degrees
42 '''
33 '''
43
34
44 return numpy.rad2deg(km/EARTH_RADIUS)
35 return numpy.rad2deg(km/EARTH_RADIUS)
45
36
46 def figpause(interval):
47 backend = plt.rcParams['backend']
48 if backend in matplotlib.rcsetup.interactive_bk:
49 figManager = matplotlib._pylab_helpers.Gcf.get_active()
50 if figManager is not None:
51 canvas = figManager.canvas
52 if canvas.figure.stale:
53 canvas.draw()
54 try:
55 canvas.start_event_loop(interval)
56 except:
57 pass
58 return
59
60 def popup(message):
61 '''
62 '''
63
64 fig = plt.figure(figsize=(12, 8), facecolor='r')
65 text = '\n'.join([s.strip() for s in message.split(':')])
66 fig.text(0.01, 0.5, text, ha='left', va='center', size='20', weight='heavy', color='w')
67 fig.show()
68 figpause(1000)
69
70
71 class PlotData(Operation, Process):
72 '''
73 Base class for Schain plotting operations
74 '''
75
76 CODE = 'Figure'
77 colormap = 'jro'
78 bgcolor = 'white'
79 CONFLATE = False
80 __missing = 1E30
81
82 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
83 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title',
84 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
85 'showprofile', 'decimation', 'ftp']
86
87 def __init__(self, **kwargs):
88
89 Operation.__init__(self, plot=True, **kwargs)
90 Process.__init__(self)
91
92 self.kwargs['code'] = self.CODE
93 self.mp = False
94 self.data = None
95 self.isConfig = False
96 self.figures = []
97 self.axes = []
98 self.cb_axes = []
99 self.localtime = kwargs.pop('localtime', True)
100 self.show = kwargs.get('show', True)
101 self.save = kwargs.get('save', False)
102 self.ftp = kwargs.get('ftp', False)
103 self.colormap = kwargs.get('colormap', self.colormap)
104 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
105 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
106 self.colormaps = kwargs.get('colormaps', None)
107 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
108 self.showprofile = kwargs.get('showprofile', False)
109 self.title = kwargs.get('wintitle', self.CODE.upper())
110 self.cb_label = kwargs.get('cb_label', None)
111 self.cb_labels = kwargs.get('cb_labels', None)
112 self.labels = kwargs.get('labels', None)
113 self.xaxis = kwargs.get('xaxis', 'frequency')
114 self.zmin = kwargs.get('zmin', None)
115 self.zmax = kwargs.get('zmax', None)
116 self.zlimits = kwargs.get('zlimits', None)
117 self.xmin = kwargs.get('xmin', None)
118 self.xmax = kwargs.get('xmax', None)
119 self.xrange = kwargs.get('xrange', 24)
120 self.xscale = kwargs.get('xscale', None)
121 self.ymin = kwargs.get('ymin', None)
122 self.ymax = kwargs.get('ymax', None)
123 self.yscale = kwargs.get('yscale', None)
124 self.xlabel = kwargs.get('xlabel', None)
125 self.decimation = kwargs.get('decimation', None)
126 self.showSNR = kwargs.get('showSNR', False)
127 self.oneFigure = kwargs.get('oneFigure', True)
128 self.width = kwargs.get('width', None)
129 self.height = kwargs.get('height', None)
130 self.colorbar = kwargs.get('colorbar', True)
131 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
132 self.channels = kwargs.get('channels', None)
133 self.titles = kwargs.get('titles', [])
134 self.polar = False
135 self.grid = kwargs.get('grid', False)
136
137 def __fmtTime(self, x, pos):
138 '''
139 '''
140
141 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
142
143 def __setup(self):
144 '''
145 Common setup for all figures, here figures and axes are created
146 '''
147
148 if self.CODE not in self.data:
149 raise ValueError(log.error('Missing data for {}'.format(self.CODE),
150 self.name))
151
152 self.setup()
153
154 self.time_label = 'LT' if self.localtime else 'UTC'
155 if self.data.localtime:
156 self.getDateTime = datetime.datetime.fromtimestamp
157 else:
158 self.getDateTime = datetime.datetime.utcfromtimestamp
159
160 if self.width is None:
161 self.width = 8
162
163 self.figures = []
164 self.axes = []
165 self.cb_axes = []
166 self.pf_axes = []
167 self.cmaps = []
168
169 size = '15%' if self.ncols == 1 else '30%'
170 pad = '4%' if self.ncols == 1 else '8%'
171
172 if self.oneFigure:
173 if self.height is None:
174 self.height = 1.4 * self.nrows + 1
175 fig = plt.figure(figsize=(self.width, self.height),
176 edgecolor='k',
177 facecolor='w')
178 self.figures.append(fig)
179 for n in range(self.nplots):
180 ax = fig.add_subplot(self.nrows, self.ncols,
181 n + 1, polar=self.polar)
182 ax.tick_params(labelsize=8)
183 ax.firsttime = True
184 ax.index = 0
185 ax.press = None
186 self.axes.append(ax)
187 if self.showprofile:
188 cax = self.__add_axes(ax, size=size, pad=pad)
189 cax.tick_params(labelsize=8)
190 self.pf_axes.append(cax)
191 else:
192 if self.height is None:
193 self.height = 3
194 for n in range(self.nplots):
195 fig = plt.figure(figsize=(self.width, self.height),
196 edgecolor='k',
197 facecolor='w')
198 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
199 ax.tick_params(labelsize=8)
200 ax.firsttime = True
201 ax.index = 0
202 ax.press = None
203 self.figures.append(fig)
204 self.axes.append(ax)
205 if self.showprofile:
206 cax = self.__add_axes(ax, size=size, pad=pad)
207 cax.tick_params(labelsize=8)
208 self.pf_axes.append(cax)
209
210 for n in range(self.nrows):
211 if self.colormaps is not None:
212 cmap = plt.get_cmap(self.colormaps[n])
213 else:
214 cmap = plt.get_cmap(self.colormap)
215 cmap.set_bad(self.bgcolor, 1.)
216 self.cmaps.append(cmap)
217
218 for fig in self.figures:
219 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
220 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
221 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
222 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
223 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
224 if self.show:
225 fig.show()
226
227 def OnKeyPress(self, event):
228 '''
229 Event for pressing keys (up, down) change colormap
230 '''
231 ax = event.inaxes
232 if ax in self.axes:
233 if event.key == 'down':
234 ax.index += 1
235 elif event.key == 'up':
236 ax.index -= 1
237 if ax.index < 0:
238 ax.index = len(CMAPS) - 1
239 elif ax.index == len(CMAPS):
240 ax.index = 0
241 cmap = CMAPS[ax.index]
242 ax.cbar.set_cmap(cmap)
243 ax.cbar.draw_all()
244 ax.plt.set_cmap(cmap)
245 ax.cbar.patch.figure.canvas.draw()
246 self.colormap = cmap.name
247
248 def OnBtnScroll(self, event):
249 '''
250 Event for scrolling, scale figure
251 '''
252 cb_ax = event.inaxes
253 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
254 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
255 pt = ax.cbar.ax.bbox.get_points()[:, 1]
256 nrm = ax.cbar.norm
257 vmin, vmax, p0, p1, pS = (
258 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
259 scale = 2 if event.step == 1 else 0.5
260 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
261 ax.cbar.norm.vmin = point - scale * (point - vmin)
262 ax.cbar.norm.vmax = point - scale * (point - vmax)
263 ax.plt.set_norm(ax.cbar.norm)
264 ax.cbar.draw_all()
265 ax.cbar.patch.figure.canvas.draw()
266
267 def onBtnPress(self, event):
268 '''
269 Event for mouse button press
270 '''
271 cb_ax = event.inaxes
272 if cb_ax is None:
273 return
274
275 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
276 cb_ax.press = event.x, event.y
277 else:
278 cb_ax.press = None
279
280 def onMotion(self, event):
281 '''
282 Event for move inside colorbar
283 '''
284 cb_ax = event.inaxes
285 if cb_ax is None:
286 return
287 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
288 return
289 if cb_ax.press is None:
290 return
291
292 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
293 xprev, yprev = cb_ax.press
294 dx = event.x - xprev
295 dy = event.y - yprev
296 cb_ax.press = event.x, event.y
297 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
298 perc = 0.03
299
300 if event.button == 1:
301 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
302 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
303 elif event.button == 3:
304 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
305 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
306
307 ax.cbar.draw_all()
308 ax.plt.set_norm(ax.cbar.norm)
309 ax.cbar.patch.figure.canvas.draw()
310
311 def onBtnRelease(self, event):
312 '''
313 Event for mouse button release
314 '''
315 cb_ax = event.inaxes
316 if cb_ax is not None:
317 cb_ax.press = None
318
319 def __add_axes(self, ax, size='30%', pad='8%'):
320 '''
321 Add new axes to the given figure
322 '''
323 divider = make_axes_locatable(ax)
324 nax = divider.new_horizontal(size=size, pad=pad)
325 ax.figure.add_axes(nax)
326 return nax
327
328 self.setup()
329
330 def setup(self):
331 '''
332 This method should be implemented in the child class, the following
333 attributes should be set:
334
335 self.nrows: number of rows
336 self.ncols: number of cols
337 self.nplots: number of plots (channels or pairs)
338 self.ylabel: label for Y axes
339 self.titles: list of axes title
340
341 '''
342 raise NotImplementedError
343
344 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
345 '''
346 Create a masked array for missing data
347 '''
348 if x_buffer.shape[0] < 2:
349 return x_buffer, y_buffer, z_buffer
350
351 deltas = x_buffer[1:] - x_buffer[0:-1]
352 x_median = numpy.median(deltas)
353
354 index = numpy.where(deltas > 5 * x_median)
355
356 if len(index[0]) != 0:
357 z_buffer[::, index[0], ::] = self.__missing
358 z_buffer = numpy.ma.masked_inside(z_buffer,
359 0.99 * self.__missing,
360 1.01 * self.__missing)
361
362 return x_buffer, y_buffer, z_buffer
363
364 def decimate(self):
365
366 # dx = int(len(self.x)/self.__MAXNUMX) + 1
367 dy = int(len(self.y) / self.decimation) + 1
368
369 # x = self.x[::dx]
370 x = self.x
371 y = self.y[::dy]
372 z = self.z[::, ::, ::dy]
373
374 return x, y, z
375
37
376 def format(self):
38 class SpectraPlot(Plot):
377 '''
378 Set min and max values, labels, ticks and titles
379 '''
380
381 if self.xmin is None:
382 xmin = self.min_time
383 else:
384 if self.xaxis is 'time':
385 dt = self.getDateTime(self.min_time)
386 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
387 datetime.datetime(1970, 1, 1)).total_seconds()
388 if self.data.localtime:
389 xmin += time.timezone
390 else:
391 xmin = self.xmin
392
393 if self.xmax is None:
394 xmax = xmin + self.xrange * 60 * 60
395 else:
396 if self.xaxis is 'time':
397 dt = self.getDateTime(self.max_time)
398 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
399 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
400 if self.data.localtime:
401 xmax += time.timezone
402 else:
403 xmax = self.xmax
404
405 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
406 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
407
408 Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000])
409 i = 1 if numpy.where(abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
410 ystep = Y[i] / 10.
411
412 if self.xaxis is not 'time':
413 X = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000])/2.
414 i = 1 if numpy.where(abs(xmax-xmin) <= X)[0][0] < 0 else numpy.where(abs(xmax-xmin) <= X)[0][0]
415 xstep = X[i] / 10.
416
417 for n, ax in enumerate(self.axes):
418 if ax.firsttime:
419 ax.set_facecolor(self.bgcolor)
420 ax.yaxis.set_major_locator(MultipleLocator(ystep))
421 if self.xscale:
422 ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{0:g}'.format(x*self.xscale)))
423 if self.xscale:
424 ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{0:g}'.format(x*self.yscale)))
425 if self.xaxis is 'time':
426 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
427 ax.xaxis.set_major_locator(LinearLocator(9))
428 else:
429 ax.xaxis.set_major_locator(MultipleLocator(xstep))
430 if self.xlabel is not None:
431 ax.set_xlabel(self.xlabel)
432 ax.set_ylabel(self.ylabel)
433 ax.firsttime = False
434 if self.showprofile:
435 self.pf_axes[n].set_ylim(ymin, ymax)
436 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
437 self.pf_axes[n].set_xlabel('dB')
438 self.pf_axes[n].grid(b=True, axis='x')
439 [tick.set_visible(False)
440 for tick in self.pf_axes[n].get_yticklabels()]
441 if self.colorbar:
442 ax.cbar = plt.colorbar(
443 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
444 ax.cbar.ax.tick_params(labelsize=8)
445 ax.cbar.ax.press = None
446 if self.cb_label:
447 ax.cbar.set_label(self.cb_label, size=8)
448 elif self.cb_labels:
449 ax.cbar.set_label(self.cb_labels[n], size=8)
450 else:
451 ax.cbar = None
452 if self.grid:
453 ax.grid(True)
454
455 if not self.polar:
456 ax.set_xlim(xmin, xmax)
457 ax.set_ylim(ymin, ymax)
458 ax.set_title('{} {} {}'.format(
459 self.titles[n],
460 self.getDateTime(self.max_time).strftime('%Y-%m-%dT%H:%M:%S'),
461 self.time_label),
462 size=8)
463 else:
464 ax.set_title('{}'.format(self.titles[n]), size=8)
465 ax.set_ylim(0, 90)
466 ax.set_yticks(numpy.arange(0, 90, 20))
467 ax.yaxis.labelpad = 40
468
469 def __plot(self):
470 '''
471 '''
472 log.log('Plotting', self.name)
473
474 try:
475 self.plot()
476 self.format()
477 except Exception as e:
478 log.warning('{} Plot could not be updated... check data'.format(self.CODE), self.name)
479 log.error(str(e), '')
480 return
481
482 for n, fig in enumerate(self.figures):
483 if self.nrows == 0 or self.nplots == 0:
484 log.warning('No data', self.name)
485 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
486 fig.canvas.manager.set_window_title(self.CODE)
487 continue
488
489 fig.tight_layout()
490 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
491 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
492 fig.canvas.draw()
493
494 if self.save and (self.data.ended or not self.data.buffering):
495
496 if self.save_labels:
497 labels = self.save_labels
498 else:
499 labels = list(range(self.nrows))
500
501 if self.oneFigure:
502 label = ''
503 else:
504 label = '-{}'.format(labels[n])
505 figname = os.path.join(
506 self.save,
507 self.CODE,
508 '{}{}_{}.png'.format(
509 self.CODE,
510 label,
511 self.getDateTime(self.saveTime).strftime(
512 '%Y%m%d_%H%M%S'),
513 )
514 )
515 log.log('Saving figure: {}'.format(figname), self.name)
516 if not os.path.isdir(os.path.dirname(figname)):
517 os.makedirs(os.path.dirname(figname))
518 fig.savefig(figname)
519
520 def plot(self):
521 '''
522 '''
523 raise NotImplementedError
524
525 def run(self):
526
527 log.log('Starting', self.name)
528
529 context = zmq.Context()
530 receiver = context.socket(zmq.SUB)
531 receiver.setsockopt(zmq.SUBSCRIBE, '')
532 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
533
534 if 'server' in self.kwargs['parent']:
535 receiver.connect(
536 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
537 else:
538 receiver.connect("ipc:///tmp/zmq.plots")
539
540 while True:
541 try:
542 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
543 if self.data.localtime and self.localtime:
544 self.times = self.data.times
545 elif self.data.localtime and not self.localtime:
546 self.times = self.data.times + time.timezone
547 elif not self.data.localtime and self.localtime:
548 self.times = self.data.times - time.timezone
549 else:
550 self.times = self.data.times
551
552 self.min_time = self.times[0]
553 self.max_time = self.times[-1]
554
555 if self.isConfig is False:
556 self.__setup()
557 self.isConfig = True
558
559 self.__plot()
560
561 except zmq.Again as e:
562 if self.data and self.data.ended:
563 break
564 log.log('Waiting for data...')
565 if self.data:
566 figpause(self.data.throttle)
567 else:
568 time.sleep(2)
569
570 def close(self):
571 if self.data:
572 self.__plot()
573
574
575 class PlotSpectraData(PlotData):
576 '''
39 '''
577 Plot for Spectra data
40 Plot for Spectra data
578 '''
41 '''
579
42
580 CODE = 'spc'
43 CODE = 'spc'
581 colormap = 'jro'
44 colormap = 'jro'
582
45
583 def setup(self):
46 def setup(self):
584 self.nplots = len(self.data.channels)
47 self.nplots = len(self.data.channels)
585 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
48 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
586 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
49 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
587 self.width = 3.4 * self.ncols
50 self.width = 3.4 * self.ncols
588 self.height = 3 * self.nrows
51 self.height = 3 * self.nrows
589 self.cb_label = 'dB'
52 self.cb_label = 'dB'
590 if self.showprofile:
53 if self.showprofile:
591 self.width += 0.8 * self.ncols
54 self.width += 0.8 * self.ncols
592
55
593 self.ylabel = 'Range [km]'
56 self.ylabel = 'Range [km]'
594
57
595 def plot(self):
58 def plot(self):
596 if self.xaxis == "frequency":
59 if self.xaxis == "frequency":
597 x = self.data.xrange[0]
60 x = self.data.xrange[0]
598 self.xlabel = "Frequency (kHz)"
61 self.xlabel = "Frequency (kHz)"
599 elif self.xaxis == "time":
62 elif self.xaxis == "time":
600 x = self.data.xrange[1]
63 x = self.data.xrange[1]
601 self.xlabel = "Time (ms)"
64 self.xlabel = "Time (ms)"
602 else:
65 else:
603 x = self.data.xrange[2]
66 x = self.data.xrange[2]
604 self.xlabel = "Velocity (m/s)"
67 self.xlabel = "Velocity (m/s)"
605
68
606 if self.CODE == 'spc_mean':
69 if self.CODE == 'spc_mean':
607 x = self.data.xrange[2]
70 x = self.data.xrange[2]
608 self.xlabel = "Velocity (m/s)"
71 self.xlabel = "Velocity (m/s)"
609
72
610 self.titles = []
73 self.titles = []
611
74
612 y = self.data.heights
75 y = self.data.heights
613 self.y = y
76 self.y = y
614 z = self.data['spc']
77 z = self.data['spc']
615
78
616 for n, ax in enumerate(self.axes):
79 for n, ax in enumerate(self.axes):
617 noise = self.data['noise'][n][-1]
80 noise = self.data['noise'][n][-1]
618 if self.CODE == 'spc_mean':
81 if self.CODE == 'spc_mean':
619 mean = self.data['mean'][n][-1]
82 mean = self.data['mean'][n][-1]
620 if ax.firsttime:
83 if ax.firsttime:
621 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
84 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
622 self.xmin = self.xmin if self.xmin else -self.xmax
85 self.xmin = self.xmin if self.xmin else -self.xmax
623 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
86 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
624 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
87 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
625 ax.plt = ax.pcolormesh(x, y, z[n].T,
88 ax.plt = ax.pcolormesh(x, y, z[n].T,
626 vmin=self.zmin,
89 vmin=self.zmin,
627 vmax=self.zmax,
90 vmax=self.zmax,
628 cmap=plt.get_cmap(self.colormap)
91 cmap=plt.get_cmap(self.colormap)
629 )
92 )
630
93
631 if self.showprofile:
94 if self.showprofile:
632 ax.plt_profile = self.pf_axes[n].plot(
95 ax.plt_profile = self.pf_axes[n].plot(
633 self.data['rti'][n][-1], y)[0]
96 self.data['rti'][n][-1], y)[0]
634 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
97 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
635 color="k", linestyle="dashed", lw=1)[0]
98 color="k", linestyle="dashed", lw=1)[0]
636 if self.CODE == 'spc_mean':
99 if self.CODE == 'spc_mean':
637 ax.plt_mean = ax.plot(mean, y, color='k')[0]
100 ax.plt_mean = ax.plot(mean, y, color='k')[0]
638 else:
101 else:
639 ax.plt.set_array(z[n].T.ravel())
102 ax.plt.set_array(z[n].T.ravel())
640 if self.showprofile:
103 if self.showprofile:
641 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
104 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
642 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
105 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
643 if self.CODE == 'spc_mean':
106 if self.CODE == 'spc_mean':
644 ax.plt_mean.set_data(mean, y)
107 ax.plt_mean.set_data(mean, y)
645
108
646 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
109 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
647 self.saveTime = self.max_time
648
110
649
111
650 class PlotCrossSpectraData(PlotData):
112 class CrossSpectraPlot(Plot):
651
113
652 CODE = 'cspc'
114 CODE = 'cspc'
653 zmin_coh = None
115 zmin_coh = None
654 zmax_coh = None
116 zmax_coh = None
655 zmin_phase = None
117 zmin_phase = None
656 zmax_phase = None
118 zmax_phase = None
657
119
658 def setup(self):
120 def setup(self):
659
121
660 self.ncols = 4
122 self.ncols = 4
661 self.nrows = len(self.data.pairs)
123 self.nrows = len(self.data.pairs)
662 self.nplots = self.nrows * 4
124 self.nplots = self.nrows * 4
663 self.width = 3.4 * self.ncols
125 self.width = 3.4 * self.ncols
664 self.height = 3 * self.nrows
126 self.height = 3 * self.nrows
665 self.ylabel = 'Range [km]'
127 self.ylabel = 'Range [km]'
666 self.showprofile = False
128 self.showprofile = False
667
129
668 def plot(self):
130 def plot(self):
669
131
670 if self.xaxis == "frequency":
132 if self.xaxis == "frequency":
671 x = self.data.xrange[0]
133 x = self.data.xrange[0]
672 self.xlabel = "Frequency (kHz)"
134 self.xlabel = "Frequency (kHz)"
673 elif self.xaxis == "time":
135 elif self.xaxis == "time":
674 x = self.data.xrange[1]
136 x = self.data.xrange[1]
675 self.xlabel = "Time (ms)"
137 self.xlabel = "Time (ms)"
676 else:
138 else:
677 x = self.data.xrange[2]
139 x = self.data.xrange[2]
678 self.xlabel = "Velocity (m/s)"
140 self.xlabel = "Velocity (m/s)"
679
141
680 self.titles = []
142 self.titles = []
681
143
682 y = self.data.heights
144 y = self.data.heights
683 self.y = y
145 self.y = y
684 spc = self.data['spc']
146 spc = self.data['spc']
685 cspc = self.data['cspc']
147 cspc = self.data['cspc']
686
148
687 for n in range(self.nrows):
149 for n in range(self.nrows):
688 noise = self.data['noise'][n][-1]
150 noise = self.data['noise'][n][-1]
689 pair = self.data.pairs[n]
151 pair = self.data.pairs[n]
690 ax = self.axes[4 * n]
152 ax = self.axes[4 * n]
691 ax3 = self.axes[4 * n + 3]
153 ax3 = self.axes[4 * n + 3]
692 if ax.firsttime:
154 if ax.firsttime:
693 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
155 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
694 self.xmin = self.xmin if self.xmin else -self.xmax
156 self.xmin = self.xmin if self.xmin else -self.xmax
695 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
157 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
696 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
158 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
697 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
159 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
698 vmin=self.zmin,
160 vmin=self.zmin,
699 vmax=self.zmax,
161 vmax=self.zmax,
700 cmap=plt.get_cmap(self.colormap)
162 cmap=plt.get_cmap(self.colormap)
701 )
163 )
702 else:
164 else:
703 ax.plt.set_array(spc[pair[0]].T.ravel())
165 ax.plt.set_array(spc[pair[0]].T.ravel())
704 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
166 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
705
167
706 ax = self.axes[4 * n + 1]
168 ax = self.axes[4 * n + 1]
707 if ax.firsttime:
169 if ax.firsttime:
708 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
170 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
709 vmin=self.zmin,
171 vmin=self.zmin,
710 vmax=self.zmax,
172 vmax=self.zmax,
711 cmap=plt.get_cmap(self.colormap)
173 cmap=plt.get_cmap(self.colormap)
712 )
174 )
713 else:
175 else:
714 ax.plt.set_array(spc[pair[1]].T.ravel())
176 ax.plt.set_array(spc[pair[1]].T.ravel())
715 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
177 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
716
178
717 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
179 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
718 coh = numpy.abs(out)
180 coh = numpy.abs(out)
719 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
181 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
720
182
721 ax = self.axes[4 * n + 2]
183 ax = self.axes[4 * n + 2]
722 if ax.firsttime:
184 if ax.firsttime:
723 ax.plt = ax.pcolormesh(x, y, coh.T,
185 ax.plt = ax.pcolormesh(x, y, coh.T,
724 vmin=0,
186 vmin=0,
725 vmax=1,
187 vmax=1,
726 cmap=plt.get_cmap(self.colormap_coh)
188 cmap=plt.get_cmap(self.colormap_coh)
727 )
189 )
728 else:
190 else:
729 ax.plt.set_array(coh.T.ravel())
191 ax.plt.set_array(coh.T.ravel())
730 self.titles.append(
192 self.titles.append(
731 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
193 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
732
194
733 ax = self.axes[4 * n + 3]
195 ax = self.axes[4 * n + 3]
734 if ax.firsttime:
196 if ax.firsttime:
735 ax.plt = ax.pcolormesh(x, y, phase.T,
197 ax.plt = ax.pcolormesh(x, y, phase.T,
736 vmin=-180,
198 vmin=-180,
737 vmax=180,
199 vmax=180,
738 cmap=plt.get_cmap(self.colormap_phase)
200 cmap=plt.get_cmap(self.colormap_phase)
739 )
201 )
740 else:
202 else:
741 ax.plt.set_array(phase.T.ravel())
203 ax.plt.set_array(phase.T.ravel())
742 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
204 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
743
205
744 self.saveTime = self.max_time
745
746
206
747 class PlotSpectraMeanData(PlotSpectraData):
207 class SpectraMeanPlot(SpectraPlot):
748 '''
208 '''
749 Plot for Spectra and Mean
209 Plot for Spectra and Mean
750 '''
210 '''
751 CODE = 'spc_mean'
211 CODE = 'spc_mean'
752 colormap = 'jro'
212 colormap = 'jro'
753
213
754
214
755 class PlotRTIData(PlotData):
215 class RTIPlot(Plot):
756 '''
216 '''
757 Plot for RTI data
217 Plot for RTI data
758 '''
218 '''
759
219
760 CODE = 'rti'
220 CODE = 'rti'
761 colormap = 'jro'
221 colormap = 'jro'
762
222
763 def setup(self):
223 def setup(self):
764 self.xaxis = 'time'
224 self.xaxis = 'time'
765 self.ncols = 1
225 self.ncols = 1
766 self.nrows = len(self.data.channels)
226 self.nrows = len(self.data.channels)
767 self.nplots = len(self.data.channels)
227 self.nplots = len(self.data.channels)
768 self.ylabel = 'Range [km]'
228 self.ylabel = 'Range [km]'
769 self.cb_label = 'dB'
229 self.cb_label = 'dB'
770 self.titles = ['{} Channel {}'.format(
230 self.titles = ['{} Channel {}'.format(
771 self.CODE.upper(), x) for x in range(self.nrows)]
231 self.CODE.upper(), x) for x in range(self.nrows)]
772
232
773 def plot(self):
233 def plot(self):
774 self.x = self.times
234 self.x = self.data.times
775 self.y = self.data.heights
235 self.y = self.data.heights
776 self.z = self.data[self.CODE]
236 self.z = self.data[self.CODE]
777 self.z = numpy.ma.masked_invalid(self.z)
237 self.z = numpy.ma.masked_invalid(self.z)
778
238
779 if self.decimation is None:
239 if self.decimation is None:
780 x, y, z = self.fill_gaps(self.x, self.y, self.z)
240 x, y, z = self.fill_gaps(self.x, self.y, self.z)
781 else:
241 else:
782 x, y, z = self.fill_gaps(*self.decimate())
242 x, y, z = self.fill_gaps(*self.decimate())
783
243
784 for n, ax in enumerate(self.axes):
244 for n, ax in enumerate(self.axes):
785 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
245 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
786 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
246 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
787 if ax.firsttime:
247 if ax.firsttime:
788 ax.plt = ax.pcolormesh(x, y, z[n].T,
248 ax.plt = ax.pcolormesh(x, y, z[n].T,
789 vmin=self.zmin,
249 vmin=self.zmin,
790 vmax=self.zmax,
250 vmax=self.zmax,
791 cmap=plt.get_cmap(self.colormap)
251 cmap=plt.get_cmap(self.colormap)
792 )
252 )
793 if self.showprofile:
253 if self.showprofile:
794 ax.plot_profile = self.pf_axes[n].plot(
254 ax.plot_profile = self.pf_axes[n].plot(
795 self.data['rti'][n][-1], self.y)[0]
255 self.data['rti'][n][-1], self.y)[0]
796 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
256 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
797 color="k", linestyle="dashed", lw=1)[0]
257 color="k", linestyle="dashed", lw=1)[0]
798 else:
258 else:
799 ax.collections.remove(ax.collections[0])
259 ax.collections.remove(ax.collections[0])
800 ax.plt = ax.pcolormesh(x, y, z[n].T,
260 ax.plt = ax.pcolormesh(x, y, z[n].T,
801 vmin=self.zmin,
261 vmin=self.zmin,
802 vmax=self.zmax,
262 vmax=self.zmax,
803 cmap=plt.get_cmap(self.colormap)
263 cmap=plt.get_cmap(self.colormap)
804 )
264 )
805 if self.showprofile:
265 if self.showprofile:
806 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
266 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
807 ax.plot_noise.set_data(numpy.repeat(
267 ax.plot_noise.set_data(numpy.repeat(
808 self.data['noise'][n][-1], len(self.y)), self.y)
268 self.data['noise'][n][-1], len(self.y)), self.y)
809
269
810 self.saveTime = self.min_time
811
812
270
813 class PlotCOHData(PlotRTIData):
271 class CoherencePlot(RTIPlot):
814 '''
272 '''
815 Plot for Coherence data
273 Plot for Coherence data
816 '''
274 '''
817
275
818 CODE = 'coh'
276 CODE = 'coh'
819
277
820 def setup(self):
278 def setup(self):
821 self.xaxis = 'time'
279 self.xaxis = 'time'
822 self.ncols = 1
280 self.ncols = 1
823 self.nrows = len(self.data.pairs)
281 self.nrows = len(self.data.pairs)
824 self.nplots = len(self.data.pairs)
282 self.nplots = len(self.data.pairs)
825 self.ylabel = 'Range [km]'
283 self.ylabel = 'Range [km]'
826 if self.CODE == 'coh':
284 if self.CODE == 'coh':
827 self.cb_label = ''
285 self.cb_label = ''
828 self.titles = [
286 self.titles = [
829 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
287 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
830 else:
288 else:
831 self.cb_label = 'Degrees'
289 self.cb_label = 'Degrees'
832 self.titles = [
290 self.titles = [
833 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
291 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
834
292
835
293
836 class PlotPHASEData(PlotCOHData):
294 class PhasePlot(CoherencePlot):
837 '''
295 '''
838 Plot for Phase map data
296 Plot for Phase map data
839 '''
297 '''
840
298
841 CODE = 'phase'
299 CODE = 'phase'
842 colormap = 'seismic'
300 colormap = 'seismic'
843
301
844
302
845 class PlotNoiseData(PlotData):
303 class NoisePlot(Plot):
846 '''
304 '''
847 Plot for noise
305 Plot for noise
848 '''
306 '''
849
307
850 CODE = 'noise'
308 CODE = 'noise'
851
309
852 def setup(self):
310 def setup(self):
853 self.xaxis = 'time'
311 self.xaxis = 'time'
854 self.ncols = 1
312 self.ncols = 1
855 self.nrows = 1
313 self.nrows = 1
856 self.nplots = 1
314 self.nplots = 1
857 self.ylabel = 'Intensity [dB]'
315 self.ylabel = 'Intensity [dB]'
858 self.titles = ['Noise']
316 self.titles = ['Noise']
859 self.colorbar = False
317 self.colorbar = False
860
318
861 def plot(self):
319 def plot(self):
862
320
863 x = self.times
321 x = self.data.times
864 xmin = self.min_time
322 xmin = self.data.min_time
865 xmax = xmin + self.xrange * 60 * 60
323 xmax = xmin + self.xrange * 60 * 60
866 Y = self.data[self.CODE]
324 Y = self.data[self.CODE]
867
325
868 if self.axes[0].firsttime:
326 if self.axes[0].firsttime:
869 for ch in self.data.channels:
327 for ch in self.data.channels:
870 y = Y[ch]
328 y = Y[ch]
871 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
329 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
872 plt.legend()
330 plt.legend()
873 else:
331 else:
874 for ch in self.data.channels:
332 for ch in self.data.channels:
875 y = Y[ch]
333 y = Y[ch]
876 self.axes[0].lines[ch].set_data(x, y)
334 self.axes[0].lines[ch].set_data(x, y)
877
335
878 self.ymin = numpy.nanmin(Y) - 5
336 self.ymin = numpy.nanmin(Y) - 5
879 self.ymax = numpy.nanmax(Y) + 5
337 self.ymax = numpy.nanmax(Y) + 5
880 self.saveTime = self.min_time
881
338
882
339
883 class PlotSNRData(PlotRTIData):
340 class SnrPlot(RTIPlot):
884 '''
341 '''
885 Plot for SNR Data
342 Plot for SNR Data
886 '''
343 '''
887
344
888 CODE = 'snr'
345 CODE = 'snr'
889 colormap = 'jet'
346 colormap = 'jet'
890
347
891
348
892 class PlotDOPData(PlotRTIData):
349 class DopplerPlot(RTIPlot):
893 '''
350 '''
894 Plot for DOPPLER Data
351 Plot for DOPPLER Data
895 '''
352 '''
896
353
897 CODE = 'dop'
354 CODE = 'dop'
898 colormap = 'jet'
355 colormap = 'jet'
899
356
900
357
901 class PlotSkyMapData(PlotData):
358 class SkyMapPlot(Plot):
902 '''
359 '''
903 Plot for meteors detection data
360 Plot for meteors detection data
904 '''
361 '''
905
362
906 CODE = 'param'
363 CODE = 'param'
907
364
908 def setup(self):
365 def setup(self):
909
366
910 self.ncols = 1
367 self.ncols = 1
911 self.nrows = 1
368 self.nrows = 1
912 self.width = 7.2
369 self.width = 7.2
913 self.height = 7.2
370 self.height = 7.2
914 self.nplots = 1
371 self.nplots = 1
915 self.xlabel = 'Zonal Zenith Angle (deg)'
372 self.xlabel = 'Zonal Zenith Angle (deg)'
916 self.ylabel = 'Meridional Zenith Angle (deg)'
373 self.ylabel = 'Meridional Zenith Angle (deg)'
917 self.polar = True
374 self.polar = True
918 self.ymin = -180
375 self.ymin = -180
919 self.ymax = 180
376 self.ymax = 180
920 self.colorbar = False
377 self.colorbar = False
921
378
922 def plot(self):
379 def plot(self):
923
380
924 arrayParameters = numpy.concatenate(self.data['param'])
381 arrayParameters = numpy.concatenate(self.data['param'])
925 error = arrayParameters[:, -1]
382 error = arrayParameters[:, -1]
926 indValid = numpy.where(error == 0)[0]
383 indValid = numpy.where(error == 0)[0]
927 finalMeteor = arrayParameters[indValid, :]
384 finalMeteor = arrayParameters[indValid, :]
928 finalAzimuth = finalMeteor[:, 3]
385 finalAzimuth = finalMeteor[:, 3]
929 finalZenith = finalMeteor[:, 4]
386 finalZenith = finalMeteor[:, 4]
930
387
931 x = finalAzimuth * numpy.pi / 180
388 x = finalAzimuth * numpy.pi / 180
932 y = finalZenith
389 y = finalZenith
933
390
934 ax = self.axes[0]
391 ax = self.axes[0]
935
392
936 if ax.firsttime:
393 if ax.firsttime:
937 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
394 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
938 else:
395 else:
939 ax.plot.set_data(x, y)
396 ax.plot.set_data(x, y)
940
397
941 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
398 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
942 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
399 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
943 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
400 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
944 dt2,
401 dt2,
945 len(x))
402 len(x))
946 self.titles[0] = title
403 self.titles[0] = title
947 self.saveTime = self.max_time
948
404
949
405
950 class PlotParamData(PlotRTIData):
406 class ParametersPlot(RTIPlot):
951 '''
407 '''
952 Plot for data_param object
408 Plot for data_param object
953 '''
409 '''
954
410
955 CODE = 'param'
411 CODE = 'param'
956 colormap = 'seismic'
412 colormap = 'seismic'
957
413
958 def setup(self):
414 def setup(self):
959 self.xaxis = 'time'
415 self.xaxis = 'time'
960 self.ncols = 1
416 self.ncols = 1
961 self.nrows = self.data.shape(self.CODE)[0]
417 self.nrows = self.data.shape(self.CODE)[0]
962 self.nplots = self.nrows
418 self.nplots = self.nrows
963 if self.showSNR:
419 if self.showSNR:
964 self.nrows += 1
420 self.nrows += 1
965 self.nplots += 1
421 self.nplots += 1
966
422
967 self.ylabel = 'Height [km]'
423 self.ylabel = 'Height [km]'
968 if not self.titles:
424 if not self.titles:
969 self.titles = self.data.parameters \
425 self.titles = self.data.parameters \
970 if self.data.parameters else ['Param {}'.format(x) for x in range(self.nrows)]
426 if self.data.parameters else ['Param {}'.format(x) for x in range(self.nrows)]
971 if self.showSNR:
427 if self.showSNR:
972 self.titles.append('SNR')
428 self.titles.append('SNR')
973
429
974 def plot(self):
430 def plot(self):
975 self.data.normalize_heights()
431 self.data.normalize_heights()
976 self.x = self.times
432 self.x = self.data.times
977 self.y = self.data.heights
433 self.y = self.data.heights
978 if self.showSNR:
434 if self.showSNR:
979 self.z = numpy.concatenate(
435 self.z = numpy.concatenate(
980 (self.data[self.CODE], self.data['snr'])
436 (self.data[self.CODE], self.data['snr'])
981 )
437 )
982 else:
438 else:
983 self.z = self.data[self.CODE]
439 self.z = self.data[self.CODE]
984
440
985 self.z = numpy.ma.masked_invalid(self.z)
441 self.z = numpy.ma.masked_invalid(self.z)
986
442
987 if self.decimation is None:
443 if self.decimation is None:
988 x, y, z = self.fill_gaps(self.x, self.y, self.z)
444 x, y, z = self.fill_gaps(self.x, self.y, self.z)
989 else:
445 else:
990 x, y, z = self.fill_gaps(*self.decimate())
446 x, y, z = self.fill_gaps(*self.decimate())
991
447
992 for n, ax in enumerate(self.axes):
448 for n, ax in enumerate(self.axes):
993
449
994 self.zmax = self.zmax if self.zmax is not None else numpy.max(
450 self.zmax = self.zmax if self.zmax is not None else numpy.max(
995 self.z[n])
451 self.z[n])
996 self.zmin = self.zmin if self.zmin is not None else numpy.min(
452 self.zmin = self.zmin if self.zmin is not None else numpy.min(
997 self.z[n])
453 self.z[n])
998
454
999 if ax.firsttime:
455 if ax.firsttime:
1000 if self.zlimits is not None:
456 if self.zlimits is not None:
1001 self.zmin, self.zmax = self.zlimits[n]
457 self.zmin, self.zmax = self.zlimits[n]
1002
458
1003 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
459 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
1004 vmin=self.zmin,
460 vmin=self.zmin,
1005 vmax=self.zmax,
461 vmax=self.zmax,
1006 cmap=self.cmaps[n]
462 cmap=self.cmaps[n]
1007 )
463 )
1008 else:
464 else:
1009 if self.zlimits is not None:
465 if self.zlimits is not None:
1010 self.zmin, self.zmax = self.zlimits[n]
466 self.zmin, self.zmax = self.zlimits[n]
1011 ax.collections.remove(ax.collections[0])
467 ax.collections.remove(ax.collections[0])
1012 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
468 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
1013 vmin=self.zmin,
469 vmin=self.zmin,
1014 vmax=self.zmax,
470 vmax=self.zmax,
1015 cmap=self.cmaps[n]
471 cmap=self.cmaps[n]
1016 )
472 )
1017
473
1018 self.saveTime = self.min_time
1019
1020
474
1021 class PlotOutputData(PlotParamData):
475 class OutputPlot(ParametersPlot):
1022 '''
476 '''
1023 Plot data_output object
477 Plot data_output object
1024 '''
478 '''
1025
479
1026 CODE = 'output'
480 CODE = 'output'
1027 colormap = 'seismic'
481 colormap = 'seismic'
1028
482
1029
483
1030 class PlotPolarMapData(PlotData):
484 class PolarMapPlot(Plot):
1031 '''
485 '''
1032 Plot for meteors detection data
486 Plot for weather radar
1033 '''
487 '''
1034
488
1035 CODE = 'param'
489 CODE = 'param'
1036 colormap = 'seismic'
490 colormap = 'seismic'
1037
491
1038 def setup(self):
492 def setup(self):
1039 self.ncols = 1
493 self.ncols = 1
1040 self.nrows = 1
494 self.nrows = 1
1041 self.width = 9
495 self.width = 9
1042 self.height = 8
496 self.height = 8
1043 self.mode = self.data.meta['mode']
497 self.mode = self.data.meta['mode']
1044 if self.channels is not None:
498 if self.channels is not None:
1045 self.nplots = len(self.channels)
499 self.nplots = len(self.channels)
1046 self.nrows = len(self.channels)
500 self.nrows = len(self.channels)
1047 else:
501 else:
1048 self.nplots = self.data.shape(self.CODE)[0]
502 self.nplots = self.data.shape(self.CODE)[0]
1049 self.nrows = self.nplots
503 self.nrows = self.nplots
1050 self.channels = list(range(self.nplots))
504 self.channels = list(range(self.nplots))
1051 if self.mode == 'E':
505 if self.mode == 'E':
1052 self.xlabel = 'Longitude'
506 self.xlabel = 'Longitude'
1053 self.ylabel = 'Latitude'
507 self.ylabel = 'Latitude'
1054 else:
508 else:
1055 self.xlabel = 'Range (km)'
509 self.xlabel = 'Range (km)'
1056 self.ylabel = 'Height (km)'
510 self.ylabel = 'Height (km)'
1057 self.bgcolor = 'white'
511 self.bgcolor = 'white'
1058 self.cb_labels = self.data.meta['units']
512 self.cb_labels = self.data.meta['units']
1059 self.lat = self.data.meta['latitude']
513 self.lat = self.data.meta['latitude']
1060 self.lon = self.data.meta['longitude']
514 self.lon = self.data.meta['longitude']
1061 self.xmin, self.xmax = float(km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
515 self.xmin, self.xmax = float(
1062 self.ymin, self.ymax = float(km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
516 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
517 self.ymin, self.ymax = float(
518 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
1063 # self.polar = True
519 # self.polar = True
1064
520
1065 def plot(self):
521 def plot(self):
1066
522
1067 for n, ax in enumerate(self.axes):
523 for n, ax in enumerate(self.axes):
1068 data = self.data['param'][self.channels[n]]
524 data = self.data['param'][self.channels[n]]
1069
525
1070 zeniths = numpy.linspace(0, self.data.meta['max_range'], data.shape[1])
526 zeniths = numpy.linspace(
1071 if self.mode == 'E':
527 0, self.data.meta['max_range'], data.shape[1])
528 if self.mode == 'E':
1072 azimuths = -numpy.radians(self.data.heights)+numpy.pi/2
529 azimuths = -numpy.radians(self.data.heights)+numpy.pi/2
1073 r, theta = numpy.meshgrid(zeniths, azimuths)
530 r, theta = numpy.meshgrid(zeniths, azimuths)
1074 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
531 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
532 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
1075 x = km2deg(x) + self.lon
533 x = km2deg(x) + self.lon
1076 y = km2deg(y) + self.lat
534 y = km2deg(y) + self.lat
1077 else:
535 else:
1078 azimuths = numpy.radians(self.data.heights)
536 azimuths = numpy.radians(self.data.heights)
1079 r, theta = numpy.meshgrid(zeniths, azimuths)
537 r, theta = numpy.meshgrid(zeniths, azimuths)
1080 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
538 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
1081 self.y = zeniths
539 self.y = zeniths
1082
540
1083 if ax.firsttime:
541 if ax.firsttime:
1084 if self.zlimits is not None:
542 if self.zlimits is not None:
1085 self.zmin, self.zmax = self.zlimits[n]
543 self.zmin, self.zmax = self.zlimits[n]
1086 ax.plt = ax.pcolormesh(#r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
544 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
1087 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
545 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
1088 vmin=self.zmin,
546 vmin=self.zmin,
1089 vmax=self.zmax,
547 vmax=self.zmax,
1090 cmap=self.cmaps[n])
548 cmap=self.cmaps[n])
1091 else:
549 else:
1092 if self.zlimits is not None:
550 if self.zlimits is not None:
1093 self.zmin, self.zmax = self.zlimits[n]
551 self.zmin, self.zmax = self.zlimits[n]
1094 ax.collections.remove(ax.collections[0])
552 ax.collections.remove(ax.collections[0])
1095 ax.plt = ax.pcolormesh(# r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
553 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
1096 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
554 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
1097 vmin=self.zmin,
555 vmin=self.zmin,
1098 vmax=self.zmax,
556 vmax=self.zmax,
1099 cmap=self.cmaps[n])
557 cmap=self.cmaps[n])
1100
558
1101 if self.mode == 'A':
559 if self.mode == 'A':
1102 continue
560 continue
1103
561
1104 # plot district names
562 # plot district names
1105 f = open('/data/workspace/schain_scripts/distrito.csv')
563 f = open('/data/workspace/schain_scripts/distrito.csv')
1106 for line in f:
564 for line in f:
1107 label, lon, lat = [s.strip() for s in line.split(',') if s]
565 label, lon, lat = [s.strip() for s in line.split(',') if s]
1108 lat = float(lat)
566 lat = float(lat)
1109 lon = float(lon)
567 lon = float(lon)
1110 # ax.plot(lon, lat, '.b', ms=2)
568 # ax.plot(lon, lat, '.b', ms=2)
1111 ax.text(lon, lat, label.decode('utf8'), ha='center', va='bottom', size='8', color='black')
569 ax.text(lon, lat, label.decode('utf8'), ha='center',
1112
570 va='bottom', size='8', color='black')
571
1113 # plot limites
572 # plot limites
1114 limites =[]
573 limites = []
1115 tmp = []
574 tmp = []
1116 for line in open('/data/workspace/schain_scripts/lima.csv'):
575 for line in open('/data/workspace/schain_scripts/lima.csv'):
1117 if '#' in line:
576 if '#' in line:
1118 if tmp:
577 if tmp:
1119 limites.append(tmp)
578 limites.append(tmp)
1120 tmp = []
579 tmp = []
1121 continue
580 continue
1122 values = line.strip().split(',')
581 values = line.strip().split(',')
1123 tmp.append((float(values[0]), float(values[1])))
582 tmp.append((float(values[0]), float(values[1])))
1124 for points in limites:
583 for points in limites:
1125 ax.add_patch(Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
584 ax.add_patch(
585 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
1126
586
1127 # plot Cuencas
587 # plot Cuencas
1128 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
588 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
1129 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
589 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
1130 values = [line.strip().split(',') for line in f]
590 values = [line.strip().split(',') for line in f]
1131 points = [(float(s[0]), float(s[1])) for s in values]
591 points = [(float(s[0]), float(s[1])) for s in values]
1132 ax.add_patch(Polygon(points, ec='b', fc='none'))
592 ax.add_patch(Polygon(points, ec='b', fc='none'))
1133
593
1134 # plot grid
594 # plot grid
1135 for r in (15, 30, 45, 60):
595 for r in (15, 30, 45, 60):
1136 ax.add_artist(plt.Circle((self.lon, self.lat), km2deg(r), color='0.6', fill=False, lw=0.2))
596 ax.add_artist(plt.Circle((self.lon, self.lat),
597 km2deg(r), color='0.6', fill=False, lw=0.2))
1137 ax.text(
598 ax.text(
1138 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
599 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
1139 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
600 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
1140 '{}km'.format(r),
601 '{}km'.format(r),
1141 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
602 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
1142
603
1143 if self.mode == 'E':
604 if self.mode == 'E':
1144 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
605 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
1145 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
606 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
1146 else:
607 else:
1147 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
608 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
1148 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
609 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
1149
1150 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
1151 self.titles = ['{} {}'.format(self.data.parameters[x], title) for x in self.channels]
1152 self.saveTime = self.max_time
1153
610
1154 No newline at end of file
611 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
612 self.titles = ['{} {}'.format(
613 self.data.parameters[x], title) for x in self.channels]
@@ -1,329 +1,329
1 '''
1 '''
2 Created on Jul 9, 2014
2 Created on Jul 9, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import os
6 import os
7 import datetime
7 import datetime
8 import numpy
8 import numpy
9
9
10 from .figure import Figure, isRealtime
10 from .figure import Figure, isRealtime
11 from .plotting_codes import *
11 from .plotting_codes import *
12
12
13 class SpectraHeisScope(Figure):
13 class SpectraHeisScope_(Figure):
14
14
15
15
16 isConfig = None
16 isConfig = None
17 __nsubplots = None
17 __nsubplots = None
18
18
19 WIDTHPROF = None
19 WIDTHPROF = None
20 HEIGHTPROF = None
20 HEIGHTPROF = None
21 PREFIX = 'spc'
21 PREFIX = 'spc'
22
22
23 def __init__(self, **kwargs):
23 def __init__(self, **kwargs):
24
24
25 Figure.__init__(self, **kwargs)
25 Figure.__init__(self, **kwargs)
26 self.isConfig = False
26 self.isConfig = False
27 self.__nsubplots = 1
27 self.__nsubplots = 1
28
28
29 self.WIDTH = 230
29 self.WIDTH = 230
30 self.HEIGHT = 250
30 self.HEIGHT = 250
31 self.WIDTHPROF = 120
31 self.WIDTHPROF = 120
32 self.HEIGHTPROF = 0
32 self.HEIGHTPROF = 0
33 self.counter_imagwr = 0
33 self.counter_imagwr = 0
34
34
35 self.PLOT_CODE = SPEC_CODE
35 self.PLOT_CODE = SPEC_CODE
36
36
37 def getSubplots(self):
37 def getSubplots(self):
38
38
39 ncol = int(numpy.sqrt(self.nplots)+0.9)
39 ncol = int(numpy.sqrt(self.nplots)+0.9)
40 nrow = int(self.nplots*1./ncol + 0.9)
40 nrow = int(self.nplots*1./ncol + 0.9)
41
41
42 return nrow, ncol
42 return nrow, ncol
43
43
44 def setup(self, id, nplots, wintitle, show):
44 def setup(self, id, nplots, wintitle, show):
45
45
46 showprofile = False
46 showprofile = False
47 self.__showprofile = showprofile
47 self.__showprofile = showprofile
48 self.nplots = nplots
48 self.nplots = nplots
49
49
50 ncolspan = 1
50 ncolspan = 1
51 colspan = 1
51 colspan = 1
52 if showprofile:
52 if showprofile:
53 ncolspan = 3
53 ncolspan = 3
54 colspan = 2
54 colspan = 2
55 self.__nsubplots = 2
55 self.__nsubplots = 2
56
56
57 self.createFigure(id = id,
57 self.createFigure(id = id,
58 wintitle = wintitle,
58 wintitle = wintitle,
59 widthplot = self.WIDTH + self.WIDTHPROF,
59 widthplot = self.WIDTH + self.WIDTHPROF,
60 heightplot = self.HEIGHT + self.HEIGHTPROF,
60 heightplot = self.HEIGHT + self.HEIGHTPROF,
61 show = show)
61 show = show)
62
62
63 nrow, ncol = self.getSubplots()
63 nrow, ncol = self.getSubplots()
64
64
65 counter = 0
65 counter = 0
66 for y in range(nrow):
66 for y in range(nrow):
67 for x in range(ncol):
67 for x in range(ncol):
68
68
69 if counter >= self.nplots:
69 if counter >= self.nplots:
70 break
70 break
71
71
72 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
72 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
73
73
74 if showprofile:
74 if showprofile:
75 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
75 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
76
76
77 counter += 1
77 counter += 1
78
78
79
79
80 def run(self, dataOut, id, wintitle="", channelList=None,
80 def run(self, dataOut, id, wintitle="", channelList=None,
81 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
81 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
82 figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
82 figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
83 server=None, folder=None, username=None, password=None,
83 server=None, folder=None, username=None, password=None,
84 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
84 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
85
85
86 """
86 """
87
87
88 Input:
88 Input:
89 dataOut :
89 dataOut :
90 id :
90 id :
91 wintitle :
91 wintitle :
92 channelList :
92 channelList :
93 xmin : None,
93 xmin : None,
94 xmax : None,
94 xmax : None,
95 ymin : None,
95 ymin : None,
96 ymax : None,
96 ymax : None,
97 """
97 """
98
98
99 if dataOut.realtime:
99 if dataOut.realtime:
100 if not(isRealtime(utcdatatime = dataOut.utctime)):
100 if not(isRealtime(utcdatatime = dataOut.utctime)):
101 print('Skipping this plot function')
101 print('Skipping this plot function')
102 return
102 return
103
103
104 if channelList == None:
104 if channelList == None:
105 channelIndexList = dataOut.channelIndexList
105 channelIndexList = dataOut.channelIndexList
106 else:
106 else:
107 channelIndexList = []
107 channelIndexList = []
108 for channel in channelList:
108 for channel in channelList:
109 if channel not in dataOut.channelList:
109 if channel not in dataOut.channelList:
110 raise ValueError("Channel %d is not in dataOut.channelList")
110 raise ValueError("Channel %d is not in dataOut.channelList")
111 channelIndexList.append(dataOut.channelList.index(channel))
111 channelIndexList.append(dataOut.channelList.index(channel))
112
112
113 # x = dataOut.heightList
113 # x = dataOut.heightList
114 c = 3E8
114 c = 3E8
115 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
115 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
116 #deberia cambiar para el caso de 1Mhz y 100KHz
116 #deberia cambiar para el caso de 1Mhz y 100KHz
117 x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000))
117 x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000))
118 #para 1Mhz descomentar la siguiente linea
118 #para 1Mhz descomentar la siguiente linea
119 #x= x/(10000.0)
119 #x= x/(10000.0)
120 # y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
120 # y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
121 # y = y.real
121 # y = y.real
122 factor = dataOut.normFactor
122 factor = dataOut.normFactor
123 data = dataOut.data_spc / factor
123 data = dataOut.data_spc / factor
124 datadB = 10.*numpy.log10(data)
124 datadB = 10.*numpy.log10(data)
125 y = datadB
125 y = datadB
126
126
127 #thisDatetime = dataOut.datatime
127 #thisDatetime = dataOut.datatime
128 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
128 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
129 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
129 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
130 xlabel = ""
130 xlabel = ""
131 #para 1Mhz descomentar la siguiente linea
131 #para 1Mhz descomentar la siguiente linea
132 #xlabel = "Frequency x 10000"
132 #xlabel = "Frequency x 10000"
133 ylabel = "Intensity (dB)"
133 ylabel = "Intensity (dB)"
134
134
135 if not self.isConfig:
135 if not self.isConfig:
136 nplots = len(channelIndexList)
136 nplots = len(channelIndexList)
137
137
138 self.setup(id=id,
138 self.setup(id=id,
139 nplots=nplots,
139 nplots=nplots,
140 wintitle=wintitle,
140 wintitle=wintitle,
141 show=show)
141 show=show)
142
142
143 if xmin == None: xmin = numpy.nanmin(x)
143 if xmin == None: xmin = numpy.nanmin(x)
144 if xmax == None: xmax = numpy.nanmax(x)
144 if xmax == None: xmax = numpy.nanmax(x)
145 if ymin == None: ymin = numpy.nanmin(y)
145 if ymin == None: ymin = numpy.nanmin(y)
146 if ymax == None: ymax = numpy.nanmax(y)
146 if ymax == None: ymax = numpy.nanmax(y)
147
147
148 self.FTP_WEI = ftp_wei
148 self.FTP_WEI = ftp_wei
149 self.EXP_CODE = exp_code
149 self.EXP_CODE = exp_code
150 self.SUB_EXP_CODE = sub_exp_code
150 self.SUB_EXP_CODE = sub_exp_code
151 self.PLOT_POS = plot_pos
151 self.PLOT_POS = plot_pos
152
152
153 self.isConfig = True
153 self.isConfig = True
154
154
155 self.setWinTitle(title)
155 self.setWinTitle(title)
156
156
157 for i in range(len(self.axesList)):
157 for i in range(len(self.axesList)):
158 ychannel = y[i,:]
158 ychannel = y[i,:]
159 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
159 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
160 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[channelIndexList[i]], numpy.max(ychannel), str_datetime)
160 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[channelIndexList[i]], numpy.max(ychannel), str_datetime)
161 axes = self.axesList[i]
161 axes = self.axesList[i]
162 axes.pline(x, ychannel,
162 axes.pline(x, ychannel,
163 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
163 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
164 xlabel=xlabel, ylabel=ylabel, title=title, grid='both')
164 xlabel=xlabel, ylabel=ylabel, title=title, grid='both')
165
165
166
166
167 self.draw()
167 self.draw()
168
168
169 self.save(figpath=figpath,
169 self.save(figpath=figpath,
170 figfile=figfile,
170 figfile=figfile,
171 save=save,
171 save=save,
172 ftp=ftp,
172 ftp=ftp,
173 wr_period=wr_period,
173 wr_period=wr_period,
174 thisDatetime=thisDatetime)
174 thisDatetime=thisDatetime)
175
175
176 class RTIfromSpectraHeis(Figure):
176 class RTIfromSpectraHeis_(Figure):
177
177
178 isConfig = None
178 isConfig = None
179 __nsubplots = None
179 __nsubplots = None
180
180
181 PREFIX = 'rtinoise'
181 PREFIX = 'rtinoise'
182
182
183 def __init__(self, **kwargs):
183 def __init__(self, **kwargs):
184 Figure.__init__(self, **kwargs)
184 Figure.__init__(self, **kwargs)
185 self.timerange = 24*60*60
185 self.timerange = 24*60*60
186 self.isConfig = False
186 self.isConfig = False
187 self.__nsubplots = 1
187 self.__nsubplots = 1
188
188
189 self.WIDTH = 820
189 self.WIDTH = 820
190 self.HEIGHT = 200
190 self.HEIGHT = 200
191 self.WIDTHPROF = 120
191 self.WIDTHPROF = 120
192 self.HEIGHTPROF = 0
192 self.HEIGHTPROF = 0
193 self.counter_imagwr = 0
193 self.counter_imagwr = 0
194 self.xdata = None
194 self.xdata = None
195 self.ydata = None
195 self.ydata = None
196 self.figfile = None
196 self.figfile = None
197
197
198 self.PLOT_CODE = RTI_CODE
198 self.PLOT_CODE = RTI_CODE
199
199
200 def getSubplots(self):
200 def getSubplots(self):
201
201
202 ncol = 1
202 ncol = 1
203 nrow = 1
203 nrow = 1
204
204
205 return nrow, ncol
205 return nrow, ncol
206
206
207 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
207 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
208
208
209 self.__showprofile = showprofile
209 self.__showprofile = showprofile
210 self.nplots = nplots
210 self.nplots = nplots
211
211
212 ncolspan = 7
212 ncolspan = 7
213 colspan = 6
213 colspan = 6
214 self.__nsubplots = 2
214 self.__nsubplots = 2
215
215
216 self.createFigure(id = id,
216 self.createFigure(id = id,
217 wintitle = wintitle,
217 wintitle = wintitle,
218 widthplot = self.WIDTH+self.WIDTHPROF,
218 widthplot = self.WIDTH+self.WIDTHPROF,
219 heightplot = self.HEIGHT+self.HEIGHTPROF,
219 heightplot = self.HEIGHT+self.HEIGHTPROF,
220 show = show)
220 show = show)
221
221
222 nrow, ncol = self.getSubplots()
222 nrow, ncol = self.getSubplots()
223
223
224 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
224 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
225
225
226
226
227 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
227 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
228 xmin=None, xmax=None, ymin=None, ymax=None,
228 xmin=None, xmax=None, ymin=None, ymax=None,
229 timerange=None,
229 timerange=None,
230 save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
230 save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
231 server=None, folder=None, username=None, password=None,
231 server=None, folder=None, username=None, password=None,
232 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
232 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
233
233
234 if channelList == None:
234 if channelList == None:
235 channelIndexList = dataOut.channelIndexList
235 channelIndexList = dataOut.channelIndexList
236 channelList = dataOut.channelList
236 channelList = dataOut.channelList
237 else:
237 else:
238 channelIndexList = []
238 channelIndexList = []
239 for channel in channelList:
239 for channel in channelList:
240 if channel not in dataOut.channelList:
240 if channel not in dataOut.channelList:
241 raise ValueError("Channel %d is not in dataOut.channelList")
241 raise ValueError("Channel %d is not in dataOut.channelList")
242 channelIndexList.append(dataOut.channelList.index(channel))
242 channelIndexList.append(dataOut.channelList.index(channel))
243
243
244 if timerange != None:
244 if timerange != None:
245 self.timerange = timerange
245 self.timerange = timerange
246
246
247 x = dataOut.getTimeRange()
247 x = dataOut.getTimeRange()
248 y = dataOut.getHeiRange()
248 y = dataOut.getHeiRange()
249
249
250 factor = dataOut.normFactor
250 factor = dataOut.normFactor
251 data = dataOut.data_spc / factor
251 data = dataOut.data_spc / factor
252 data = numpy.average(data,axis=1)
252 data = numpy.average(data,axis=1)
253 datadB = 10*numpy.log10(data)
253 datadB = 10*numpy.log10(data)
254
254
255 # factor = dataOut.normFactor
255 # factor = dataOut.normFactor
256 # noise = dataOut.getNoise()/factor
256 # noise = dataOut.getNoise()/factor
257 # noisedB = 10*numpy.log10(noise)
257 # noisedB = 10*numpy.log10(noise)
258
258
259 #thisDatetime = dataOut.datatime
259 #thisDatetime = dataOut.datatime
260 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
260 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
261 title = wintitle + " RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
261 title = wintitle + " RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
262 xlabel = "Local Time"
262 xlabel = "Local Time"
263 ylabel = "Intensity (dB)"
263 ylabel = "Intensity (dB)"
264
264
265 if not self.isConfig:
265 if not self.isConfig:
266
266
267 nplots = 1
267 nplots = 1
268
268
269 self.setup(id=id,
269 self.setup(id=id,
270 nplots=nplots,
270 nplots=nplots,
271 wintitle=wintitle,
271 wintitle=wintitle,
272 showprofile=showprofile,
272 showprofile=showprofile,
273 show=show)
273 show=show)
274
274
275 self.tmin, self.tmax = self.getTimeLim(x, xmin, xmax)
275 self.tmin, self.tmax = self.getTimeLim(x, xmin, xmax)
276
276
277 if ymin == None: ymin = numpy.nanmin(datadB)
277 if ymin == None: ymin = numpy.nanmin(datadB)
278 if ymax == None: ymax = numpy.nanmax(datadB)
278 if ymax == None: ymax = numpy.nanmax(datadB)
279
279
280 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
280 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
281 self.isConfig = True
281 self.isConfig = True
282 self.figfile = figfile
282 self.figfile = figfile
283 self.xdata = numpy.array([])
283 self.xdata = numpy.array([])
284 self.ydata = numpy.array([])
284 self.ydata = numpy.array([])
285
285
286 self.FTP_WEI = ftp_wei
286 self.FTP_WEI = ftp_wei
287 self.EXP_CODE = exp_code
287 self.EXP_CODE = exp_code
288 self.SUB_EXP_CODE = sub_exp_code
288 self.SUB_EXP_CODE = sub_exp_code
289 self.PLOT_POS = plot_pos
289 self.PLOT_POS = plot_pos
290
290
291 self.setWinTitle(title)
291 self.setWinTitle(title)
292
292
293
293
294 # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y"))
294 # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y"))
295 title = "RTI - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
295 title = "RTI - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
296
296
297 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
297 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
298 axes = self.axesList[0]
298 axes = self.axesList[0]
299
299
300 self.xdata = numpy.hstack((self.xdata, x[0:1]))
300 self.xdata = numpy.hstack((self.xdata, x[0:1]))
301
301
302 if len(self.ydata)==0:
302 if len(self.ydata)==0:
303 self.ydata = datadB[channelIndexList].reshape(-1,1)
303 self.ydata = datadB[channelIndexList].reshape(-1,1)
304 else:
304 else:
305 self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1)))
305 self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1)))
306
306
307
307
308 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
308 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
309 xmin=self.tmin, xmax=self.tmax, ymin=ymin, ymax=ymax,
309 xmin=self.tmin, xmax=self.tmax, ymin=ymin, ymax=ymax,
310 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both',
310 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both',
311 XAxisAsTime=True
311 XAxisAsTime=True
312 )
312 )
313
313
314 self.draw()
314 self.draw()
315
315
316 update_figfile = False
316 update_figfile = False
317
317
318 if dataOut.ltctime >= self.tmax:
318 if dataOut.ltctime >= self.tmax:
319 self.counter_imagwr = wr_period
319 self.counter_imagwr = wr_period
320 self.isConfig = False
320 self.isConfig = False
321 update_figfile = True
321 update_figfile = True
322
322
323 self.save(figpath=figpath,
323 self.save(figpath=figpath,
324 figfile=figfile,
324 figfile=figfile,
325 save=save,
325 save=save,
326 ftp=ftp,
326 ftp=ftp,
327 wr_period=wr_period,
327 wr_period=wr_period,
328 thisDatetime=thisDatetime,
328 thisDatetime=thisDatetime,
329 update_figfile=update_figfile) No newline at end of file
329 update_figfile=update_figfile)
@@ -1,2158 +1,2158
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4 import inspect
4 import inspect
5 from .figure import Figure, isRealtime, isTimeInHourRange
5 from .figure import Figure, isRealtime, isTimeInHourRange
6 from .plotting_codes import *
6 from .plotting_codes import *
7 from schainpy.model.proc.jroproc_base import MPDecorator
7 from schainpy.model.proc.jroproc_base import MPDecorator
8 from schainpy.utils import log
8 from schainpy.utils import log
9
9
10 class FitGauPlot(Figure):
10 class FitGauPlot_(Figure):
11
11
12 isConfig = None
12 isConfig = None
13 __nsubplots = None
13 __nsubplots = None
14
14
15 WIDTHPROF = None
15 WIDTHPROF = None
16 HEIGHTPROF = None
16 HEIGHTPROF = None
17 PREFIX = 'fitgau'
17 PREFIX = 'fitgau'
18
18
19 def __init__(self, **kwargs):
19 def __init__(self, **kwargs):
20 Figure.__init__(self, **kwargs)
20 Figure.__init__(self, **kwargs)
21 self.isConfig = False
21 self.isConfig = False
22 self.__nsubplots = 1
22 self.__nsubplots = 1
23
23
24 self.WIDTH = 250
24 self.WIDTH = 250
25 self.HEIGHT = 250
25 self.HEIGHT = 250
26 self.WIDTHPROF = 120
26 self.WIDTHPROF = 120
27 self.HEIGHTPROF = 0
27 self.HEIGHTPROF = 0
28 self.counter_imagwr = 0
28 self.counter_imagwr = 0
29
29
30 self.PLOT_CODE = SPEC_CODE
30 self.PLOT_CODE = SPEC_CODE
31
31
32 self.FTP_WEI = None
32 self.FTP_WEI = None
33 self.EXP_CODE = None
33 self.EXP_CODE = None
34 self.SUB_EXP_CODE = None
34 self.SUB_EXP_CODE = None
35 self.PLOT_POS = None
35 self.PLOT_POS = None
36
36
37 self.__xfilter_ena = False
37 self.__xfilter_ena = False
38 self.__yfilter_ena = False
38 self.__yfilter_ena = False
39
39
40 def getSubplots(self):
40 def getSubplots(self):
41
41
42 ncol = int(numpy.sqrt(self.nplots)+0.9)
42 ncol = int(numpy.sqrt(self.nplots)+0.9)
43 nrow = int(self.nplots*1./ncol + 0.9)
43 nrow = int(self.nplots*1./ncol + 0.9)
44
44
45 return nrow, ncol
45 return nrow, ncol
46
46
47 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
47 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
48
48
49 self.__showprofile = showprofile
49 self.__showprofile = showprofile
50 self.nplots = nplots
50 self.nplots = nplots
51
51
52 ncolspan = 1
52 ncolspan = 1
53 colspan = 1
53 colspan = 1
54 if showprofile:
54 if showprofile:
55 ncolspan = 3
55 ncolspan = 3
56 colspan = 2
56 colspan = 2
57 self.__nsubplots = 2
57 self.__nsubplots = 2
58
58
59 self.createFigure(id = id,
59 self.createFigure(id = id,
60 wintitle = wintitle,
60 wintitle = wintitle,
61 widthplot = self.WIDTH + self.WIDTHPROF,
61 widthplot = self.WIDTH + self.WIDTHPROF,
62 heightplot = self.HEIGHT + self.HEIGHTPROF,
62 heightplot = self.HEIGHT + self.HEIGHTPROF,
63 show=show)
63 show=show)
64
64
65 nrow, ncol = self.getSubplots()
65 nrow, ncol = self.getSubplots()
66
66
67 counter = 0
67 counter = 0
68 for y in range(nrow):
68 for y in range(nrow):
69 for x in range(ncol):
69 for x in range(ncol):
70
70
71 if counter >= self.nplots:
71 if counter >= self.nplots:
72 break
72 break
73
73
74 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
74 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
75
75
76 if showprofile:
76 if showprofile:
77 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
77 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
78
78
79 counter += 1
79 counter += 1
80
80
81 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
81 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
82 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
82 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
83 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
83 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
84 server=None, folder=None, username=None, password=None,
84 server=None, folder=None, username=None, password=None,
85 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
85 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
86 xaxis="frequency", colormap='jet', normFactor=None , GauSelector = 1):
86 xaxis="frequency", colormap='jet', normFactor=None , GauSelector = 1):
87
87
88 """
88 """
89
89
90 Input:
90 Input:
91 dataOut :
91 dataOut :
92 id :
92 id :
93 wintitle :
93 wintitle :
94 channelList :
94 channelList :
95 showProfile :
95 showProfile :
96 xmin : None,
96 xmin : None,
97 xmax : None,
97 xmax : None,
98 ymin : None,
98 ymin : None,
99 ymax : None,
99 ymax : None,
100 zmin : None,
100 zmin : None,
101 zmax : None
101 zmax : None
102 """
102 """
103 if realtime:
103 if realtime:
104 if not(isRealtime(utcdatatime = dataOut.utctime)):
104 if not(isRealtime(utcdatatime = dataOut.utctime)):
105 print('Skipping this plot function')
105 print('Skipping this plot function')
106 return
106 return
107
107
108 if channelList == None:
108 if channelList == None:
109 channelIndexList = dataOut.channelIndexList
109 channelIndexList = dataOut.channelIndexList
110 else:
110 else:
111 channelIndexList = []
111 channelIndexList = []
112 for channel in channelList:
112 for channel in channelList:
113 if channel not in dataOut.channelList:
113 if channel not in dataOut.channelList:
114 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
114 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
115 channelIndexList.append(dataOut.channelList.index(channel))
115 channelIndexList.append(dataOut.channelList.index(channel))
116
116
117 # if normFactor is None:
117 # if normFactor is None:
118 # factor = dataOut.normFactor
118 # factor = dataOut.normFactor
119 # else:
119 # else:
120 # factor = normFactor
120 # factor = normFactor
121 if xaxis == "frequency":
121 if xaxis == "frequency":
122 x = dataOut.spc_range[0]
122 x = dataOut.spc_range[0]
123 xlabel = "Frequency (kHz)"
123 xlabel = "Frequency (kHz)"
124
124
125 elif xaxis == "time":
125 elif xaxis == "time":
126 x = dataOut.spc_range[1]
126 x = dataOut.spc_range[1]
127 xlabel = "Time (ms)"
127 xlabel = "Time (ms)"
128
128
129 else:
129 else:
130 x = dataOut.spc_range[2]
130 x = dataOut.spc_range[2]
131 xlabel = "Velocity (m/s)"
131 xlabel = "Velocity (m/s)"
132
132
133 ylabel = "Range (Km)"
133 ylabel = "Range (Km)"
134
134
135 y = dataOut.getHeiRange()
135 y = dataOut.getHeiRange()
136
136
137 z = dataOut.GauSPC[:,GauSelector,:,:] #GauSelector] #dataOut.data_spc/factor
137 z = dataOut.GauSPC[:,GauSelector,:,:] #GauSelector] #dataOut.data_spc/factor
138 print('GausSPC', z[0,32,10:40])
138 print('GausSPC', z[0,32,10:40])
139 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
139 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
140 zdB = 10*numpy.log10(z)
140 zdB = 10*numpy.log10(z)
141
141
142 avg = numpy.average(z, axis=1)
142 avg = numpy.average(z, axis=1)
143 avgdB = 10*numpy.log10(avg)
143 avgdB = 10*numpy.log10(avg)
144
144
145 noise = dataOut.spc_noise
145 noise = dataOut.spc_noise
146 noisedB = 10*numpy.log10(noise)
146 noisedB = 10*numpy.log10(noise)
147
147
148 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
148 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
149 title = wintitle + " Spectra"
149 title = wintitle + " Spectra"
150 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
150 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
151 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
151 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
152
152
153 if not self.isConfig:
153 if not self.isConfig:
154
154
155 nplots = len(channelIndexList)
155 nplots = len(channelIndexList)
156
156
157 self.setup(id=id,
157 self.setup(id=id,
158 nplots=nplots,
158 nplots=nplots,
159 wintitle=wintitle,
159 wintitle=wintitle,
160 showprofile=showprofile,
160 showprofile=showprofile,
161 show=show)
161 show=show)
162
162
163 if xmin == None: xmin = numpy.nanmin(x)
163 if xmin == None: xmin = numpy.nanmin(x)
164 if xmax == None: xmax = numpy.nanmax(x)
164 if xmax == None: xmax = numpy.nanmax(x)
165 if ymin == None: ymin = numpy.nanmin(y)
165 if ymin == None: ymin = numpy.nanmin(y)
166 if ymax == None: ymax = numpy.nanmax(y)
166 if ymax == None: ymax = numpy.nanmax(y)
167 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
167 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
168 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
168 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
169
169
170 self.FTP_WEI = ftp_wei
170 self.FTP_WEI = ftp_wei
171 self.EXP_CODE = exp_code
171 self.EXP_CODE = exp_code
172 self.SUB_EXP_CODE = sub_exp_code
172 self.SUB_EXP_CODE = sub_exp_code
173 self.PLOT_POS = plot_pos
173 self.PLOT_POS = plot_pos
174
174
175 self.isConfig = True
175 self.isConfig = True
176
176
177 self.setWinTitle(title)
177 self.setWinTitle(title)
178
178
179 for i in range(self.nplots):
179 for i in range(self.nplots):
180 index = channelIndexList[i]
180 index = channelIndexList[i]
181 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
181 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
182 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
182 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
183 if len(dataOut.beam.codeList) != 0:
183 if len(dataOut.beam.codeList) != 0:
184 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
184 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
185
185
186 axes = self.axesList[i*self.__nsubplots]
186 axes = self.axesList[i*self.__nsubplots]
187 axes.pcolor(x, y, zdB[index,:,:],
187 axes.pcolor(x, y, zdB[index,:,:],
188 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
188 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
189 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
189 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
190 ticksize=9, cblabel='')
190 ticksize=9, cblabel='')
191
191
192 if self.__showprofile:
192 if self.__showprofile:
193 axes = self.axesList[i*self.__nsubplots +1]
193 axes = self.axesList[i*self.__nsubplots +1]
194 axes.pline(avgdB[index,:], y,
194 axes.pline(avgdB[index,:], y,
195 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
195 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
196 xlabel='dB', ylabel='', title='',
196 xlabel='dB', ylabel='', title='',
197 ytick_visible=False,
197 ytick_visible=False,
198 grid='x')
198 grid='x')
199
199
200 noiseline = numpy.repeat(noisedB[index], len(y))
200 noiseline = numpy.repeat(noisedB[index], len(y))
201 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
201 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
202
202
203 self.draw()
203 self.draw()
204
204
205 if figfile == None:
205 if figfile == None:
206 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
206 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
207 name = str_datetime
207 name = str_datetime
208 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
208 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
209 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
209 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
210 figfile = self.getFilename(name)
210 figfile = self.getFilename(name)
211
211
212 self.save(figpath=figpath,
212 self.save(figpath=figpath,
213 figfile=figfile,
213 figfile=figfile,
214 save=save,
214 save=save,
215 ftp=ftp,
215 ftp=ftp,
216 wr_period=wr_period,
216 wr_period=wr_period,
217 thisDatetime=thisDatetime)
217 thisDatetime=thisDatetime)
218
218
219
219
220
220
221 class MomentsPlot(Figure):
221 class MomentsPlot_(Figure):
222
222
223 isConfig = None
223 isConfig = None
224 __nsubplots = None
224 __nsubplots = None
225
225
226 WIDTHPROF = None
226 WIDTHPROF = None
227 HEIGHTPROF = None
227 HEIGHTPROF = None
228 PREFIX = 'prm'
228 PREFIX = 'prm'
229 def __init__(self):
229 def __init__(self):
230 Figure.__init__(self)
230 Figure.__init__(self)
231 self.isConfig = False
231 self.isConfig = False
232 self.__nsubplots = 1
232 self.__nsubplots = 1
233
233
234 self.WIDTH = 280
234 self.WIDTH = 280
235 self.HEIGHT = 250
235 self.HEIGHT = 250
236 self.WIDTHPROF = 120
236 self.WIDTHPROF = 120
237 self.HEIGHTPROF = 0
237 self.HEIGHTPROF = 0
238 self.counter_imagwr = 0
238 self.counter_imagwr = 0
239
239
240 self.PLOT_CODE = MOMENTS_CODE
240 self.PLOT_CODE = MOMENTS_CODE
241
241
242 self.FTP_WEI = None
242 self.FTP_WEI = None
243 self.EXP_CODE = None
243 self.EXP_CODE = None
244 self.SUB_EXP_CODE = None
244 self.SUB_EXP_CODE = None
245 self.PLOT_POS = None
245 self.PLOT_POS = None
246
246
247 def getSubplots(self):
247 def getSubplots(self):
248
248
249 ncol = int(numpy.sqrt(self.nplots)+0.9)
249 ncol = int(numpy.sqrt(self.nplots)+0.9)
250 nrow = int(self.nplots*1./ncol + 0.9)
250 nrow = int(self.nplots*1./ncol + 0.9)
251
251
252 return nrow, ncol
252 return nrow, ncol
253
253
254 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
254 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
255
255
256 self.__showprofile = showprofile
256 self.__showprofile = showprofile
257 self.nplots = nplots
257 self.nplots = nplots
258
258
259 ncolspan = 1
259 ncolspan = 1
260 colspan = 1
260 colspan = 1
261 if showprofile:
261 if showprofile:
262 ncolspan = 3
262 ncolspan = 3
263 colspan = 2
263 colspan = 2
264 self.__nsubplots = 2
264 self.__nsubplots = 2
265
265
266 self.createFigure(id = id,
266 self.createFigure(id = id,
267 wintitle = wintitle,
267 wintitle = wintitle,
268 widthplot = self.WIDTH + self.WIDTHPROF,
268 widthplot = self.WIDTH + self.WIDTHPROF,
269 heightplot = self.HEIGHT + self.HEIGHTPROF,
269 heightplot = self.HEIGHT + self.HEIGHTPROF,
270 show=show)
270 show=show)
271
271
272 nrow, ncol = self.getSubplots()
272 nrow, ncol = self.getSubplots()
273
273
274 counter = 0
274 counter = 0
275 for y in range(nrow):
275 for y in range(nrow):
276 for x in range(ncol):
276 for x in range(ncol):
277
277
278 if counter >= self.nplots:
278 if counter >= self.nplots:
279 break
279 break
280
280
281 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
281 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
282
282
283 if showprofile:
283 if showprofile:
284 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
284 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
285
285
286 counter += 1
286 counter += 1
287
287
288 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
288 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
289 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
289 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
290 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
290 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
291 server=None, folder=None, username=None, password=None,
291 server=None, folder=None, username=None, password=None,
292 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
292 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
293
293
294 """
294 """
295
295
296 Input:
296 Input:
297 dataOut :
297 dataOut :
298 id :
298 id :
299 wintitle :
299 wintitle :
300 channelList :
300 channelList :
301 showProfile :
301 showProfile :
302 xmin : None,
302 xmin : None,
303 xmax : None,
303 xmax : None,
304 ymin : None,
304 ymin : None,
305 ymax : None,
305 ymax : None,
306 zmin : None,
306 zmin : None,
307 zmax : None
307 zmax : None
308 """
308 """
309
309
310 if dataOut.flagNoData:
310 if dataOut.flagNoData:
311 return None
311 return None
312
312
313 if realtime:
313 if realtime:
314 if not(isRealtime(utcdatatime = dataOut.utctime)):
314 if not(isRealtime(utcdatatime = dataOut.utctime)):
315 print('Skipping this plot function')
315 print('Skipping this plot function')
316 return
316 return
317
317
318 if channelList == None:
318 if channelList == None:
319 channelIndexList = dataOut.channelIndexList
319 channelIndexList = dataOut.channelIndexList
320 else:
320 else:
321 channelIndexList = []
321 channelIndexList = []
322 for channel in channelList:
322 for channel in channelList:
323 if channel not in dataOut.channelList:
323 if channel not in dataOut.channelList:
324 raise ValueError("Channel %d is not in dataOut.channelList")
324 raise ValueError("Channel %d is not in dataOut.channelList")
325 channelIndexList.append(dataOut.channelList.index(channel))
325 channelIndexList.append(dataOut.channelList.index(channel))
326
326
327 factor = dataOut.normFactor
327 factor = dataOut.normFactor
328 x = dataOut.abscissaList
328 x = dataOut.abscissaList
329 y = dataOut.heightList
329 y = dataOut.heightList
330
330
331 z = dataOut.data_pre[channelIndexList,:,:]/factor
331 z = dataOut.data_pre[channelIndexList,:,:]/factor
332 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
332 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
333 avg = numpy.average(z, axis=1)
333 avg = numpy.average(z, axis=1)
334 noise = dataOut.noise/factor
334 noise = dataOut.noise/factor
335
335
336 zdB = 10*numpy.log10(z)
336 zdB = 10*numpy.log10(z)
337 avgdB = 10*numpy.log10(avg)
337 avgdB = 10*numpy.log10(avg)
338 noisedB = 10*numpy.log10(noise)
338 noisedB = 10*numpy.log10(noise)
339
339
340 #thisDatetime = dataOut.datatime
340 #thisDatetime = dataOut.datatime
341 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
341 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
342 title = wintitle + " Parameters"
342 title = wintitle + " Parameters"
343 xlabel = "Velocity (m/s)"
343 xlabel = "Velocity (m/s)"
344 ylabel = "Range (Km)"
344 ylabel = "Range (Km)"
345
345
346 update_figfile = False
346 update_figfile = False
347
347
348 if not self.isConfig:
348 if not self.isConfig:
349
349
350 nplots = len(channelIndexList)
350 nplots = len(channelIndexList)
351
351
352 self.setup(id=id,
352 self.setup(id=id,
353 nplots=nplots,
353 nplots=nplots,
354 wintitle=wintitle,
354 wintitle=wintitle,
355 showprofile=showprofile,
355 showprofile=showprofile,
356 show=show)
356 show=show)
357
357
358 if xmin == None: xmin = numpy.nanmin(x)
358 if xmin == None: xmin = numpy.nanmin(x)
359 if xmax == None: xmax = numpy.nanmax(x)
359 if xmax == None: xmax = numpy.nanmax(x)
360 if ymin == None: ymin = numpy.nanmin(y)
360 if ymin == None: ymin = numpy.nanmin(y)
361 if ymax == None: ymax = numpy.nanmax(y)
361 if ymax == None: ymax = numpy.nanmax(y)
362 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
362 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
363 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
363 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
364
364
365 self.FTP_WEI = ftp_wei
365 self.FTP_WEI = ftp_wei
366 self.EXP_CODE = exp_code
366 self.EXP_CODE = exp_code
367 self.SUB_EXP_CODE = sub_exp_code
367 self.SUB_EXP_CODE = sub_exp_code
368 self.PLOT_POS = plot_pos
368 self.PLOT_POS = plot_pos
369
369
370 self.isConfig = True
370 self.isConfig = True
371 update_figfile = True
371 update_figfile = True
372
372
373 self.setWinTitle(title)
373 self.setWinTitle(title)
374
374
375 for i in range(self.nplots):
375 for i in range(self.nplots):
376 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
376 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
377 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
377 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
378 axes = self.axesList[i*self.__nsubplots]
378 axes = self.axesList[i*self.__nsubplots]
379 axes.pcolor(x, y, zdB[i,:,:],
379 axes.pcolor(x, y, zdB[i,:,:],
380 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
380 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
381 xlabel=xlabel, ylabel=ylabel, title=title,
381 xlabel=xlabel, ylabel=ylabel, title=title,
382 ticksize=9, cblabel='')
382 ticksize=9, cblabel='')
383 #Mean Line
383 #Mean Line
384 mean = dataOut.data_param[i, 1, :]
384 mean = dataOut.data_param[i, 1, :]
385 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
385 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
386
386
387 if self.__showprofile:
387 if self.__showprofile:
388 axes = self.axesList[i*self.__nsubplots +1]
388 axes = self.axesList[i*self.__nsubplots +1]
389 axes.pline(avgdB[i], y,
389 axes.pline(avgdB[i], y,
390 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
390 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
391 xlabel='dB', ylabel='', title='',
391 xlabel='dB', ylabel='', title='',
392 ytick_visible=False,
392 ytick_visible=False,
393 grid='x')
393 grid='x')
394
394
395 noiseline = numpy.repeat(noisedB[i], len(y))
395 noiseline = numpy.repeat(noisedB[i], len(y))
396 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
396 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
397
397
398 self.draw()
398 self.draw()
399
399
400 self.save(figpath=figpath,
400 self.save(figpath=figpath,
401 figfile=figfile,
401 figfile=figfile,
402 save=save,
402 save=save,
403 ftp=ftp,
403 ftp=ftp,
404 wr_period=wr_period,
404 wr_period=wr_period,
405 thisDatetime=thisDatetime)
405 thisDatetime=thisDatetime)
406
406
407
407
408 class SkyMapPlot(Figure):
408 class SkyMapPlot_(Figure):
409
409
410 __isConfig = None
410 __isConfig = None
411 __nsubplots = None
411 __nsubplots = None
412
412
413 WIDTHPROF = None
413 WIDTHPROF = None
414 HEIGHTPROF = None
414 HEIGHTPROF = None
415 PREFIX = 'mmap'
415 PREFIX = 'mmap'
416
416
417 def __init__(self, **kwargs):
417 def __init__(self, **kwargs):
418 Figure.__init__(self, **kwargs)
418 Figure.__init__(self, **kwargs)
419 self.isConfig = False
419 self.isConfig = False
420 self.__nsubplots = 1
420 self.__nsubplots = 1
421
421
422 # self.WIDTH = 280
422 # self.WIDTH = 280
423 # self.HEIGHT = 250
423 # self.HEIGHT = 250
424 self.WIDTH = 600
424 self.WIDTH = 600
425 self.HEIGHT = 600
425 self.HEIGHT = 600
426 self.WIDTHPROF = 120
426 self.WIDTHPROF = 120
427 self.HEIGHTPROF = 0
427 self.HEIGHTPROF = 0
428 self.counter_imagwr = 0
428 self.counter_imagwr = 0
429
429
430 self.PLOT_CODE = MSKYMAP_CODE
430 self.PLOT_CODE = MSKYMAP_CODE
431
431
432 self.FTP_WEI = None
432 self.FTP_WEI = None
433 self.EXP_CODE = None
433 self.EXP_CODE = None
434 self.SUB_EXP_CODE = None
434 self.SUB_EXP_CODE = None
435 self.PLOT_POS = None
435 self.PLOT_POS = None
436
436
437 def getSubplots(self):
437 def getSubplots(self):
438
438
439 ncol = int(numpy.sqrt(self.nplots)+0.9)
439 ncol = int(numpy.sqrt(self.nplots)+0.9)
440 nrow = int(self.nplots*1./ncol + 0.9)
440 nrow = int(self.nplots*1./ncol + 0.9)
441
441
442 return nrow, ncol
442 return nrow, ncol
443
443
444 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
444 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
445
445
446 self.__showprofile = showprofile
446 self.__showprofile = showprofile
447 self.nplots = nplots
447 self.nplots = nplots
448
448
449 ncolspan = 1
449 ncolspan = 1
450 colspan = 1
450 colspan = 1
451
451
452 self.createFigure(id = id,
452 self.createFigure(id = id,
453 wintitle = wintitle,
453 wintitle = wintitle,
454 widthplot = self.WIDTH, #+ self.WIDTHPROF,
454 widthplot = self.WIDTH, #+ self.WIDTHPROF,
455 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
455 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
456 show=show)
456 show=show)
457
457
458 nrow, ncol = 1,1
458 nrow, ncol = 1,1
459 counter = 0
459 counter = 0
460 x = 0
460 x = 0
461 y = 0
461 y = 0
462 self.addAxes(1, 1, 0, 0, 1, 1, True)
462 self.addAxes(1, 1, 0, 0, 1, 1, True)
463
463
464 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
464 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
465 tmin=0, tmax=24, timerange=None,
465 tmin=0, tmax=24, timerange=None,
466 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
466 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
467 server=None, folder=None, username=None, password=None,
467 server=None, folder=None, username=None, password=None,
468 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
468 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
469
469
470 """
470 """
471
471
472 Input:
472 Input:
473 dataOut :
473 dataOut :
474 id :
474 id :
475 wintitle :
475 wintitle :
476 channelList :
476 channelList :
477 showProfile :
477 showProfile :
478 xmin : None,
478 xmin : None,
479 xmax : None,
479 xmax : None,
480 ymin : None,
480 ymin : None,
481 ymax : None,
481 ymax : None,
482 zmin : None,
482 zmin : None,
483 zmax : None
483 zmax : None
484 """
484 """
485
485
486 arrayParameters = dataOut.data_param
486 arrayParameters = dataOut.data_param
487 error = arrayParameters[:,-1]
487 error = arrayParameters[:,-1]
488 indValid = numpy.where(error == 0)[0]
488 indValid = numpy.where(error == 0)[0]
489 finalMeteor = arrayParameters[indValid,:]
489 finalMeteor = arrayParameters[indValid,:]
490 finalAzimuth = finalMeteor[:,3]
490 finalAzimuth = finalMeteor[:,3]
491 finalZenith = finalMeteor[:,4]
491 finalZenith = finalMeteor[:,4]
492
492
493 x = finalAzimuth*numpy.pi/180
493 x = finalAzimuth*numpy.pi/180
494 y = finalZenith
494 y = finalZenith
495 x1 = [dataOut.ltctime, dataOut.ltctime]
495 x1 = [dataOut.ltctime, dataOut.ltctime]
496
496
497 #thisDatetime = dataOut.datatime
497 #thisDatetime = dataOut.datatime
498 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
498 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
499 title = wintitle + " Parameters"
499 title = wintitle + " Parameters"
500 xlabel = "Zonal Zenith Angle (deg) "
500 xlabel = "Zonal Zenith Angle (deg) "
501 ylabel = "Meridional Zenith Angle (deg)"
501 ylabel = "Meridional Zenith Angle (deg)"
502 update_figfile = False
502 update_figfile = False
503
503
504 if not self.isConfig:
504 if not self.isConfig:
505
505
506 nplots = 1
506 nplots = 1
507
507
508 self.setup(id=id,
508 self.setup(id=id,
509 nplots=nplots,
509 nplots=nplots,
510 wintitle=wintitle,
510 wintitle=wintitle,
511 showprofile=showprofile,
511 showprofile=showprofile,
512 show=show)
512 show=show)
513
513
514 if self.xmin is None and self.xmax is None:
514 if self.xmin is None and self.xmax is None:
515 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
515 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
516
516
517 if timerange != None:
517 if timerange != None:
518 self.timerange = timerange
518 self.timerange = timerange
519 else:
519 else:
520 self.timerange = self.xmax - self.xmin
520 self.timerange = self.xmax - self.xmin
521
521
522 self.FTP_WEI = ftp_wei
522 self.FTP_WEI = ftp_wei
523 self.EXP_CODE = exp_code
523 self.EXP_CODE = exp_code
524 self.SUB_EXP_CODE = sub_exp_code
524 self.SUB_EXP_CODE = sub_exp_code
525 self.PLOT_POS = plot_pos
525 self.PLOT_POS = plot_pos
526 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
526 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
527 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
527 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
528 self.isConfig = True
528 self.isConfig = True
529 update_figfile = True
529 update_figfile = True
530
530
531 self.setWinTitle(title)
531 self.setWinTitle(title)
532
532
533 i = 0
533 i = 0
534 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
534 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
535
535
536 axes = self.axesList[i*self.__nsubplots]
536 axes = self.axesList[i*self.__nsubplots]
537 nevents = axes.x_buffer.shape[0] + x.shape[0]
537 nevents = axes.x_buffer.shape[0] + x.shape[0]
538 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
538 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
539 axes.polar(x, y,
539 axes.polar(x, y,
540 title=title, xlabel=xlabel, ylabel=ylabel,
540 title=title, xlabel=xlabel, ylabel=ylabel,
541 ticksize=9, cblabel='')
541 ticksize=9, cblabel='')
542
542
543 self.draw()
543 self.draw()
544
544
545 self.save(figpath=figpath,
545 self.save(figpath=figpath,
546 figfile=figfile,
546 figfile=figfile,
547 save=save,
547 save=save,
548 ftp=ftp,
548 ftp=ftp,
549 wr_period=wr_period,
549 wr_period=wr_period,
550 thisDatetime=thisDatetime,
550 thisDatetime=thisDatetime,
551 update_figfile=update_figfile)
551 update_figfile=update_figfile)
552
552
553 if dataOut.ltctime >= self.xmax:
553 if dataOut.ltctime >= self.xmax:
554 self.isConfigmagwr = wr_period
554 self.isConfigmagwr = wr_period
555 self.isConfig = False
555 self.isConfig = False
556 update_figfile = True
556 update_figfile = True
557 axes.__firsttime = True
557 axes.__firsttime = True
558 self.xmin += self.timerange
558 self.xmin += self.timerange
559 self.xmax += self.timerange
559 self.xmax += self.timerange
560
560
561
561
562
562
563
563
564 class WindProfilerPlot(Figure):
564 class WindProfilerPlot_(Figure):
565
565
566 __isConfig = None
566 __isConfig = None
567 __nsubplots = None
567 __nsubplots = None
568
568
569 WIDTHPROF = None
569 WIDTHPROF = None
570 HEIGHTPROF = None
570 HEIGHTPROF = None
571 PREFIX = 'wind'
571 PREFIX = 'wind'
572
572
573 def __init__(self, **kwargs):
573 def __init__(self, **kwargs):
574 Figure.__init__(self, **kwargs)
574 Figure.__init__(self, **kwargs)
575 self.timerange = None
575 self.timerange = None
576 self.isConfig = False
576 self.isConfig = False
577 self.__nsubplots = 1
577 self.__nsubplots = 1
578
578
579 self.WIDTH = 800
579 self.WIDTH = 800
580 self.HEIGHT = 300
580 self.HEIGHT = 300
581 self.WIDTHPROF = 120
581 self.WIDTHPROF = 120
582 self.HEIGHTPROF = 0
582 self.HEIGHTPROF = 0
583 self.counter_imagwr = 0
583 self.counter_imagwr = 0
584
584
585 self.PLOT_CODE = WIND_CODE
585 self.PLOT_CODE = WIND_CODE
586
586
587 self.FTP_WEI = None
587 self.FTP_WEI = None
588 self.EXP_CODE = None
588 self.EXP_CODE = None
589 self.SUB_EXP_CODE = None
589 self.SUB_EXP_CODE = None
590 self.PLOT_POS = None
590 self.PLOT_POS = None
591 self.tmin = None
591 self.tmin = None
592 self.tmax = None
592 self.tmax = None
593
593
594 self.xmin = None
594 self.xmin = None
595 self.xmax = None
595 self.xmax = None
596
596
597 self.figfile = None
597 self.figfile = None
598
598
599 def getSubplots(self):
599 def getSubplots(self):
600
600
601 ncol = 1
601 ncol = 1
602 nrow = self.nplots
602 nrow = self.nplots
603
603
604 return nrow, ncol
604 return nrow, ncol
605
605
606 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
606 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
607
607
608 self.__showprofile = showprofile
608 self.__showprofile = showprofile
609 self.nplots = nplots
609 self.nplots = nplots
610
610
611 ncolspan = 1
611 ncolspan = 1
612 colspan = 1
612 colspan = 1
613
613
614 self.createFigure(id = id,
614 self.createFigure(id = id,
615 wintitle = wintitle,
615 wintitle = wintitle,
616 widthplot = self.WIDTH + self.WIDTHPROF,
616 widthplot = self.WIDTH + self.WIDTHPROF,
617 heightplot = self.HEIGHT + self.HEIGHTPROF,
617 heightplot = self.HEIGHT + self.HEIGHTPROF,
618 show=show)
618 show=show)
619
619
620 nrow, ncol = self.getSubplots()
620 nrow, ncol = self.getSubplots()
621
621
622 counter = 0
622 counter = 0
623 for y in range(nrow):
623 for y in range(nrow):
624 if counter >= self.nplots:
624 if counter >= self.nplots:
625 break
625 break
626
626
627 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
627 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
628 counter += 1
628 counter += 1
629
629
630 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
630 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
631 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
631 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
632 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
632 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
633 timerange=None, SNRthresh = None,
633 timerange=None, SNRthresh = None,
634 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
634 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
635 server=None, folder=None, username=None, password=None,
635 server=None, folder=None, username=None, password=None,
636 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
636 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
637 """
637 """
638
638
639 Input:
639 Input:
640 dataOut :
640 dataOut :
641 id :
641 id :
642 wintitle :
642 wintitle :
643 channelList :
643 channelList :
644 showProfile :
644 showProfile :
645 xmin : None,
645 xmin : None,
646 xmax : None,
646 xmax : None,
647 ymin : None,
647 ymin : None,
648 ymax : None,
648 ymax : None,
649 zmin : None,
649 zmin : None,
650 zmax : None
650 zmax : None
651 """
651 """
652
652
653 # if timerange is not None:
653 # if timerange is not None:
654 # self.timerange = timerange
654 # self.timerange = timerange
655 #
655 #
656 # tmin = None
656 # tmin = None
657 # tmax = None
657 # tmax = None
658
658
659 x = dataOut.getTimeRange1(dataOut.paramInterval)
659 x = dataOut.getTimeRange1(dataOut.paramInterval)
660 y = dataOut.heightList
660 y = dataOut.heightList
661 z = dataOut.data_output.copy()
661 z = dataOut.data_output.copy()
662 nplots = z.shape[0] #Number of wind dimensions estimated
662 nplots = z.shape[0] #Number of wind dimensions estimated
663 nplotsw = nplots
663 nplotsw = nplots
664
664
665
665
666 #If there is a SNR function defined
666 #If there is a SNR function defined
667 if dataOut.data_SNR is not None:
667 if dataOut.data_SNR is not None:
668 nplots += 1
668 nplots += 1
669 SNR = dataOut.data_SNR
669 SNR = dataOut.data_SNR
670 SNRavg = numpy.average(SNR, axis=0)
670 SNRavg = numpy.average(SNR, axis=0)
671
671
672 SNRdB = 10*numpy.log10(SNR)
672 SNRdB = 10*numpy.log10(SNR)
673 SNRavgdB = 10*numpy.log10(SNRavg)
673 SNRavgdB = 10*numpy.log10(SNRavg)
674
674
675 if SNRthresh == None: SNRthresh = -5.0
675 if SNRthresh == None: SNRthresh = -5.0
676 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
676 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
677
677
678 for i in range(nplotsw):
678 for i in range(nplotsw):
679 z[i,ind] = numpy.nan
679 z[i,ind] = numpy.nan
680
680
681 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
681 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
682 #thisDatetime = datetime.datetime.now()
682 #thisDatetime = datetime.datetime.now()
683 title = wintitle + "Wind"
683 title = wintitle + "Wind"
684 xlabel = ""
684 xlabel = ""
685 ylabel = "Height (km)"
685 ylabel = "Height (km)"
686 update_figfile = False
686 update_figfile = False
687
687
688 if not self.isConfig:
688 if not self.isConfig:
689
689
690 self.setup(id=id,
690 self.setup(id=id,
691 nplots=nplots,
691 nplots=nplots,
692 wintitle=wintitle,
692 wintitle=wintitle,
693 showprofile=showprofile,
693 showprofile=showprofile,
694 show=show)
694 show=show)
695
695
696 if timerange is not None:
696 if timerange is not None:
697 self.timerange = timerange
697 self.timerange = timerange
698
698
699 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
699 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
700
700
701 if ymin == None: ymin = numpy.nanmin(y)
701 if ymin == None: ymin = numpy.nanmin(y)
702 if ymax == None: ymax = numpy.nanmax(y)
702 if ymax == None: ymax = numpy.nanmax(y)
703
703
704 if zmax == None: zmax = numpy.nanmax(abs(z[list(range(2)),:]))
704 if zmax == None: zmax = numpy.nanmax(abs(z[list(range(2)),:]))
705 #if numpy.isnan(zmax): zmax = 50
705 #if numpy.isnan(zmax): zmax = 50
706 if zmin == None: zmin = -zmax
706 if zmin == None: zmin = -zmax
707
707
708 if nplotsw == 3:
708 if nplotsw == 3:
709 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
709 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
710 if zmin_ver == None: zmin_ver = -zmax_ver
710 if zmin_ver == None: zmin_ver = -zmax_ver
711
711
712 if dataOut.data_SNR is not None:
712 if dataOut.data_SNR is not None:
713 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
713 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
714 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
714 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
715
715
716
716
717 self.FTP_WEI = ftp_wei
717 self.FTP_WEI = ftp_wei
718 self.EXP_CODE = exp_code
718 self.EXP_CODE = exp_code
719 self.SUB_EXP_CODE = sub_exp_code
719 self.SUB_EXP_CODE = sub_exp_code
720 self.PLOT_POS = plot_pos
720 self.PLOT_POS = plot_pos
721
721
722 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
722 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
723 self.isConfig = True
723 self.isConfig = True
724 self.figfile = figfile
724 self.figfile = figfile
725 update_figfile = True
725 update_figfile = True
726
726
727 self.setWinTitle(title)
727 self.setWinTitle(title)
728
728
729 if ((self.xmax - x[1]) < (x[1]-x[0])):
729 if ((self.xmax - x[1]) < (x[1]-x[0])):
730 x[1] = self.xmax
730 x[1] = self.xmax
731
731
732 strWind = ['Zonal', 'Meridional', 'Vertical']
732 strWind = ['Zonal', 'Meridional', 'Vertical']
733 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
733 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
734 zmaxVector = [zmax, zmax, zmax_ver]
734 zmaxVector = [zmax, zmax, zmax_ver]
735 zminVector = [zmin, zmin, zmin_ver]
735 zminVector = [zmin, zmin, zmin_ver]
736 windFactor = [1,1,100]
736 windFactor = [1,1,100]
737
737
738 for i in range(nplotsw):
738 for i in range(nplotsw):
739
739
740 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
740 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
741 axes = self.axesList[i*self.__nsubplots]
741 axes = self.axesList[i*self.__nsubplots]
742
742
743 z1 = z[i,:].reshape((1,-1))*windFactor[i]
743 z1 = z[i,:].reshape((1,-1))*windFactor[i]
744 #z1=numpy.ma.masked_where(z1==0.,z1)
744 #z1=numpy.ma.masked_where(z1==0.,z1)
745
745
746 axes.pcolorbuffer(x, y, z1,
746 axes.pcolorbuffer(x, y, z1,
747 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
747 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
748 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
748 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
749 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
749 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
750
750
751 if dataOut.data_SNR is not None:
751 if dataOut.data_SNR is not None:
752 i += 1
752 i += 1
753 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
753 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
754 axes = self.axesList[i*self.__nsubplots]
754 axes = self.axesList[i*self.__nsubplots]
755 SNRavgdB = SNRavgdB.reshape((1,-1))
755 SNRavgdB = SNRavgdB.reshape((1,-1))
756 axes.pcolorbuffer(x, y, SNRavgdB,
756 axes.pcolorbuffer(x, y, SNRavgdB,
757 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
757 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
758 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
758 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
759 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
759 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
760
760
761 self.draw()
761 self.draw()
762
762
763 self.save(figpath=figpath,
763 self.save(figpath=figpath,
764 figfile=figfile,
764 figfile=figfile,
765 save=save,
765 save=save,
766 ftp=ftp,
766 ftp=ftp,
767 wr_period=wr_period,
767 wr_period=wr_period,
768 thisDatetime=thisDatetime,
768 thisDatetime=thisDatetime,
769 update_figfile=update_figfile)
769 update_figfile=update_figfile)
770
770
771 if dataOut.ltctime + dataOut.paramInterval >= self.xmax:
771 if dataOut.ltctime + dataOut.paramInterval >= self.xmax:
772 self.counter_imagwr = wr_period
772 self.counter_imagwr = wr_period
773 self.isConfig = False
773 self.isConfig = False
774 update_figfile = True
774 update_figfile = True
775
775
776 @MPDecorator
776 @MPDecorator
777 class ParametersPlot(Figure):
777 class ParametersPlot_(Figure):
778
778
779 __isConfig = None
779 __isConfig = None
780 __nsubplots = None
780 __nsubplots = None
781
781
782 WIDTHPROF = None
782 WIDTHPROF = None
783 HEIGHTPROF = None
783 HEIGHTPROF = None
784 PREFIX = 'param'
784 PREFIX = 'param'
785
785
786 nplots = None
786 nplots = None
787 nchan = None
787 nchan = None
788
788
789 def __init__(self):#, **kwargs):
789 def __init__(self):#, **kwargs):
790 Figure.__init__(self)#, **kwargs)
790 Figure.__init__(self)#, **kwargs)
791 self.timerange = None
791 self.timerange = None
792 self.isConfig = False
792 self.isConfig = False
793 self.__nsubplots = 1
793 self.__nsubplots = 1
794
794
795 self.WIDTH = 800
795 self.WIDTH = 800
796 self.HEIGHT = 180
796 self.HEIGHT = 180
797 self.WIDTHPROF = 120
797 self.WIDTHPROF = 120
798 self.HEIGHTPROF = 0
798 self.HEIGHTPROF = 0
799 self.counter_imagwr = 0
799 self.counter_imagwr = 0
800
800
801 self.PLOT_CODE = RTI_CODE
801 self.PLOT_CODE = RTI_CODE
802
802
803 self.FTP_WEI = None
803 self.FTP_WEI = None
804 self.EXP_CODE = None
804 self.EXP_CODE = None
805 self.SUB_EXP_CODE = None
805 self.SUB_EXP_CODE = None
806 self.PLOT_POS = None
806 self.PLOT_POS = None
807 self.tmin = None
807 self.tmin = None
808 self.tmax = None
808 self.tmax = None
809
809
810 self.xmin = None
810 self.xmin = None
811 self.xmax = None
811 self.xmax = None
812
812
813 self.figfile = None
813 self.figfile = None
814
814
815 def getSubplots(self):
815 def getSubplots(self):
816
816
817 ncol = 1
817 ncol = 1
818 nrow = self.nplots
818 nrow = self.nplots
819
819
820 return nrow, ncol
820 return nrow, ncol
821
821
822 def setup(self, id, nplots, wintitle, show=True):
822 def setup(self, id, nplots, wintitle, show=True):
823
823
824 self.nplots = nplots
824 self.nplots = nplots
825
825
826 ncolspan = 1
826 ncolspan = 1
827 colspan = 1
827 colspan = 1
828
828
829 self.createFigure(id = id,
829 self.createFigure(id = id,
830 wintitle = wintitle,
830 wintitle = wintitle,
831 widthplot = self.WIDTH + self.WIDTHPROF,
831 widthplot = self.WIDTH + self.WIDTHPROF,
832 heightplot = self.HEIGHT + self.HEIGHTPROF,
832 heightplot = self.HEIGHT + self.HEIGHTPROF,
833 show=show)
833 show=show)
834
834
835 nrow, ncol = self.getSubplots()
835 nrow, ncol = self.getSubplots()
836
836
837 counter = 0
837 counter = 0
838 for y in range(nrow):
838 for y in range(nrow):
839 for x in range(ncol):
839 for x in range(ncol):
840
840
841 if counter >= self.nplots:
841 if counter >= self.nplots:
842 break
842 break
843
843
844 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
844 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
845
845
846 counter += 1
846 counter += 1
847
847
848 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet",
848 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet",
849 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
849 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
850 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
850 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
851 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
851 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
852 server=None, folder=None, username=None, password=None,
852 server=None, folder=None, username=None, password=None,
853 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None):
853 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None):
854 """
854 """
855
855
856 Input:
856 Input:
857 dataOut :
857 dataOut :
858 id :
858 id :
859 wintitle :
859 wintitle :
860 channelList :
860 channelList :
861 showProfile :
861 showProfile :
862 xmin : None,
862 xmin : None,
863 xmax : None,
863 xmax : None,
864 ymin : None,
864 ymin : None,
865 ymax : None,
865 ymax : None,
866 zmin : None,
866 zmin : None,
867 zmax : None
867 zmax : None
868 """
868 """
869 if dataOut.flagNoData:
869 if dataOut.flagNoData:
870 return dataOut
870 return dataOut
871
871
872
872
873 if HEIGHT is not None:
873 if HEIGHT is not None:
874 self.HEIGHT = HEIGHT
874 self.HEIGHT = HEIGHT
875
875
876
876
877 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
877 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
878 return
878 return
879
879
880 if channelList == None:
880 if channelList == None:
881 channelIndexList = list(range(dataOut.data_param.shape[0]))
881 channelIndexList = list(range(dataOut.data_param.shape[0]))
882 else:
882 else:
883 channelIndexList = []
883 channelIndexList = []
884 for channel in channelList:
884 for channel in channelList:
885 if channel not in dataOut.channelList:
885 if channel not in dataOut.channelList:
886 raise ValueError("Channel %d is not in dataOut.channelList")
886 raise ValueError("Channel %d is not in dataOut.channelList")
887 channelIndexList.append(dataOut.channelList.index(channel))
887 channelIndexList.append(dataOut.channelList.index(channel))
888
888
889 x = dataOut.getTimeRange1(dataOut.paramInterval)
889 x = dataOut.getTimeRange1(dataOut.paramInterval)
890 y = dataOut.getHeiRange()
890 y = dataOut.getHeiRange()
891
891
892 if dataOut.data_param.ndim == 3:
892 if dataOut.data_param.ndim == 3:
893 z = dataOut.data_param[channelIndexList,paramIndex,:]
893 z = dataOut.data_param[channelIndexList,paramIndex,:]
894 else:
894 else:
895 z = dataOut.data_param[channelIndexList,:]
895 z = dataOut.data_param[channelIndexList,:]
896
896
897 if showSNR:
897 if showSNR:
898 #SNR data
898 #SNR data
899 SNRarray = dataOut.data_SNR[channelIndexList,:]
899 SNRarray = dataOut.data_SNR[channelIndexList,:]
900 SNRdB = 10*numpy.log10(SNRarray)
900 SNRdB = 10*numpy.log10(SNRarray)
901 ind = numpy.where(SNRdB < SNRthresh)
901 ind = numpy.where(SNRdB < SNRthresh)
902 z[ind] = numpy.nan
902 z[ind] = numpy.nan
903
903
904 thisDatetime = dataOut.datatime
904 thisDatetime = dataOut.datatime
905 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
905 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
906 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
906 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
907 xlabel = ""
907 xlabel = ""
908 ylabel = "Range (Km)"
908 ylabel = "Range (Km)"
909
909
910 update_figfile = False
910 update_figfile = False
911
911
912 if not self.isConfig:
912 if not self.isConfig:
913
913
914 nchan = len(channelIndexList)
914 nchan = len(channelIndexList)
915 self.nchan = nchan
915 self.nchan = nchan
916 self.plotFact = 1
916 self.plotFact = 1
917 nplots = nchan
917 nplots = nchan
918
918
919 if showSNR:
919 if showSNR:
920 nplots = nchan*2
920 nplots = nchan*2
921 self.plotFact = 2
921 self.plotFact = 2
922 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
922 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
923 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
923 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
924
924
925 self.setup(id=id,
925 self.setup(id=id,
926 nplots=nplots,
926 nplots=nplots,
927 wintitle=wintitle,
927 wintitle=wintitle,
928 show=show)
928 show=show)
929
929
930 if timerange != None:
930 if timerange != None:
931 self.timerange = timerange
931 self.timerange = timerange
932
932
933 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
933 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
934
934
935 if ymin == None: ymin = numpy.nanmin(y)
935 if ymin == None: ymin = numpy.nanmin(y)
936 if ymax == None: ymax = numpy.nanmax(y)
936 if ymax == None: ymax = numpy.nanmax(y)
937 if zmin == None: zmin = numpy.nanmin(z)
937 if zmin == None: zmin = numpy.nanmin(z)
938 if zmax == None: zmax = numpy.nanmax(z)
938 if zmax == None: zmax = numpy.nanmax(z)
939
939
940 self.FTP_WEI = ftp_wei
940 self.FTP_WEI = ftp_wei
941 self.EXP_CODE = exp_code
941 self.EXP_CODE = exp_code
942 self.SUB_EXP_CODE = sub_exp_code
942 self.SUB_EXP_CODE = sub_exp_code
943 self.PLOT_POS = plot_pos
943 self.PLOT_POS = plot_pos
944
944
945 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
945 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
946 self.isConfig = True
946 self.isConfig = True
947 self.figfile = figfile
947 self.figfile = figfile
948 update_figfile = True
948 update_figfile = True
949
949
950 self.setWinTitle(title)
950 self.setWinTitle(title)
951
951
952 for i in range(self.nchan):
952 for i in range(self.nchan):
953 index = channelIndexList[i]
953 index = channelIndexList[i]
954 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
954 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
955 axes = self.axesList[i*self.plotFact]
955 axes = self.axesList[i*self.plotFact]
956 z1 = z[i,:].reshape((1,-1))
956 z1 = z[i,:].reshape((1,-1))
957 axes.pcolorbuffer(x, y, z1,
957 axes.pcolorbuffer(x, y, z1,
958 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
958 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
959 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
959 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
960 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
960 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
961
961
962 if showSNR:
962 if showSNR:
963 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
963 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
964 axes = self.axesList[i*self.plotFact + 1]
964 axes = self.axesList[i*self.plotFact + 1]
965 SNRdB1 = SNRdB[i,:].reshape((1,-1))
965 SNRdB1 = SNRdB[i,:].reshape((1,-1))
966 axes.pcolorbuffer(x, y, SNRdB1,
966 axes.pcolorbuffer(x, y, SNRdB1,
967 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
967 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
968 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
968 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
969 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
969 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
970
970
971
971
972 self.draw()
972 self.draw()
973
973
974 if dataOut.ltctime >= self.xmax:
974 if dataOut.ltctime >= self.xmax:
975 self.counter_imagwr = wr_period
975 self.counter_imagwr = wr_period
976 self.isConfig = False
976 self.isConfig = False
977 update_figfile = True
977 update_figfile = True
978
978
979 self.save(figpath=figpath,
979 self.save(figpath=figpath,
980 figfile=figfile,
980 figfile=figfile,
981 save=save,
981 save=save,
982 ftp=ftp,
982 ftp=ftp,
983 wr_period=wr_period,
983 wr_period=wr_period,
984 thisDatetime=thisDatetime,
984 thisDatetime=thisDatetime,
985 update_figfile=update_figfile)
985 update_figfile=update_figfile)
986
986
987 return dataOut
987 return dataOut
988 @MPDecorator
988 @MPDecorator
989 class Parameters1Plot(Figure):
989 class Parameters1Plot_(Figure):
990
990
991 __isConfig = None
991 __isConfig = None
992 __nsubplots = None
992 __nsubplots = None
993
993
994 WIDTHPROF = None
994 WIDTHPROF = None
995 HEIGHTPROF = None
995 HEIGHTPROF = None
996 PREFIX = 'prm'
996 PREFIX = 'prm'
997
997
998 def __init__(self):
998 def __init__(self):
999 Figure.__init__(self)
999 Figure.__init__(self)
1000 self.timerange = 2*60*60
1000 self.timerange = 2*60*60
1001 self.isConfig = False
1001 self.isConfig = False
1002 self.__nsubplots = 1
1002 self.__nsubplots = 1
1003
1003
1004 self.WIDTH = 800
1004 self.WIDTH = 800
1005 self.HEIGHT = 180
1005 self.HEIGHT = 180
1006 self.WIDTHPROF = 120
1006 self.WIDTHPROF = 120
1007 self.HEIGHTPROF = 0
1007 self.HEIGHTPROF = 0
1008 self.counter_imagwr = 0
1008 self.counter_imagwr = 0
1009
1009
1010 self.PLOT_CODE = PARMS_CODE
1010 self.PLOT_CODE = PARMS_CODE
1011
1011
1012 self.FTP_WEI = None
1012 self.FTP_WEI = None
1013 self.EXP_CODE = None
1013 self.EXP_CODE = None
1014 self.SUB_EXP_CODE = None
1014 self.SUB_EXP_CODE = None
1015 self.PLOT_POS = None
1015 self.PLOT_POS = None
1016 self.tmin = None
1016 self.tmin = None
1017 self.tmax = None
1017 self.tmax = None
1018
1018
1019 self.xmin = None
1019 self.xmin = None
1020 self.xmax = None
1020 self.xmax = None
1021
1021
1022 self.figfile = None
1022 self.figfile = None
1023
1023
1024 def getSubplots(self):
1024 def getSubplots(self):
1025
1025
1026 ncol = 1
1026 ncol = 1
1027 nrow = self.nplots
1027 nrow = self.nplots
1028
1028
1029 return nrow, ncol
1029 return nrow, ncol
1030
1030
1031 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1031 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1032
1032
1033 self.__showprofile = showprofile
1033 self.__showprofile = showprofile
1034 self.nplots = nplots
1034 self.nplots = nplots
1035
1035
1036 ncolspan = 1
1036 ncolspan = 1
1037 colspan = 1
1037 colspan = 1
1038
1038
1039 self.createFigure(id = id,
1039 self.createFigure(id = id,
1040 wintitle = wintitle,
1040 wintitle = wintitle,
1041 widthplot = self.WIDTH + self.WIDTHPROF,
1041 widthplot = self.WIDTH + self.WIDTHPROF,
1042 heightplot = self.HEIGHT + self.HEIGHTPROF,
1042 heightplot = self.HEIGHT + self.HEIGHTPROF,
1043 show=show)
1043 show=show)
1044
1044
1045 nrow, ncol = self.getSubplots()
1045 nrow, ncol = self.getSubplots()
1046
1046
1047 counter = 0
1047 counter = 0
1048 for y in range(nrow):
1048 for y in range(nrow):
1049 for x in range(ncol):
1049 for x in range(ncol):
1050
1050
1051 if counter >= self.nplots:
1051 if counter >= self.nplots:
1052 break
1052 break
1053
1053
1054 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1054 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1055
1055
1056 if showprofile:
1056 if showprofile:
1057 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1057 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1058
1058
1059 counter += 1
1059 counter += 1
1060
1060
1061 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
1061 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
1062 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
1062 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
1063 parameterIndex = None, onlyPositive = False,
1063 parameterIndex = None, onlyPositive = False,
1064 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
1064 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
1065 DOP = True,
1065 DOP = True,
1066 zlabel = "", parameterName = "", parameterObject = "data_param",
1066 zlabel = "", parameterName = "", parameterObject = "data_param",
1067 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1067 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1068 server=None, folder=None, username=None, password=None,
1068 server=None, folder=None, username=None, password=None,
1069 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1069 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1070 #print inspect.getargspec(self.run).args
1070 #print inspect.getargspec(self.run).args
1071 """
1071 """
1072
1072
1073 Input:
1073 Input:
1074 dataOut :
1074 dataOut :
1075 id :
1075 id :
1076 wintitle :
1076 wintitle :
1077 channelList :
1077 channelList :
1078 showProfile :
1078 showProfile :
1079 xmin : None,
1079 xmin : None,
1080 xmax : None,
1080 xmax : None,
1081 ymin : None,
1081 ymin : None,
1082 ymax : None,
1082 ymax : None,
1083 zmin : None,
1083 zmin : None,
1084 zmax : None
1084 zmax : None
1085 """
1085 """
1086 if dataOut.flagNoData:
1086 if dataOut.flagNoData:
1087 return dataOut
1087 return dataOut
1088
1088
1089 data_param = getattr(dataOut, parameterObject)
1089 data_param = getattr(dataOut, parameterObject)
1090
1090
1091 if channelList == None:
1091 if channelList == None:
1092 channelIndexList = numpy.arange(data_param.shape[0])
1092 channelIndexList = numpy.arange(data_param.shape[0])
1093 else:
1093 else:
1094 channelIndexList = numpy.array(channelList)
1094 channelIndexList = numpy.array(channelList)
1095
1095
1096 nchan = len(channelIndexList) #Number of channels being plotted
1096 nchan = len(channelIndexList) #Number of channels being plotted
1097
1097
1098 if nchan < 1:
1098 if nchan < 1:
1099 return
1099 return
1100
1100
1101 nGraphsByChannel = 0
1101 nGraphsByChannel = 0
1102
1102
1103 if SNR:
1103 if SNR:
1104 nGraphsByChannel += 1
1104 nGraphsByChannel += 1
1105 if DOP:
1105 if DOP:
1106 nGraphsByChannel += 1
1106 nGraphsByChannel += 1
1107
1107
1108 if nGraphsByChannel < 1:
1108 if nGraphsByChannel < 1:
1109 return
1109 return
1110
1110
1111 nplots = nGraphsByChannel*nchan
1111 nplots = nGraphsByChannel*nchan
1112
1112
1113 if timerange is not None:
1113 if timerange is not None:
1114 self.timerange = timerange
1114 self.timerange = timerange
1115
1115
1116 #tmin = None
1116 #tmin = None
1117 #tmax = None
1117 #tmax = None
1118 if parameterIndex == None:
1118 if parameterIndex == None:
1119 parameterIndex = 1
1119 parameterIndex = 1
1120
1120
1121 x = dataOut.getTimeRange1(dataOut.paramInterval)
1121 x = dataOut.getTimeRange1(dataOut.paramInterval)
1122 y = dataOut.heightList
1122 y = dataOut.heightList
1123
1123
1124 if dataOut.data_param.ndim == 3:
1124 if dataOut.data_param.ndim == 3:
1125 z = dataOut.data_param[channelIndexList,parameterIndex,:]
1125 z = dataOut.data_param[channelIndexList,parameterIndex,:]
1126 else:
1126 else:
1127 z = dataOut.data_param[channelIndexList,:]
1127 z = dataOut.data_param[channelIndexList,:]
1128
1128
1129 if dataOut.data_SNR is not None:
1129 if dataOut.data_SNR is not None:
1130 if dataOut.data_SNR.ndim == 2:
1130 if dataOut.data_SNR.ndim == 2:
1131 SNRavg = numpy.average(dataOut.data_SNR, axis=0)
1131 SNRavg = numpy.average(dataOut.data_SNR, axis=0)
1132 else:
1132 else:
1133 SNRavg = dataOut.data_SNR
1133 SNRavg = dataOut.data_SNR
1134 SNRdB = 10*numpy.log10(SNRavg)
1134 SNRdB = 10*numpy.log10(SNRavg)
1135
1135
1136 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1136 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1137 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1137 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1138 xlabel = ""
1138 xlabel = ""
1139 ylabel = "Range (Km)"
1139 ylabel = "Range (Km)"
1140
1140
1141 if onlyPositive:
1141 if onlyPositive:
1142 colormap = "jet"
1142 colormap = "jet"
1143 zmin = 0
1143 zmin = 0
1144 else: colormap = "RdBu_r"
1144 else: colormap = "RdBu_r"
1145
1145
1146 if not self.isConfig:
1146 if not self.isConfig:
1147
1147
1148 self.setup(id=id,
1148 self.setup(id=id,
1149 nplots=nplots,
1149 nplots=nplots,
1150 wintitle=wintitle,
1150 wintitle=wintitle,
1151 showprofile=showprofile,
1151 showprofile=showprofile,
1152 show=show)
1152 show=show)
1153
1153
1154 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1154 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1155
1155
1156 if ymin == None: ymin = numpy.nanmin(y)
1156 if ymin == None: ymin = numpy.nanmin(y)
1157 if ymax == None: ymax = numpy.nanmax(y)
1157 if ymax == None: ymax = numpy.nanmax(y)
1158 if zmin == None: zmin = numpy.nanmin(z)
1158 if zmin == None: zmin = numpy.nanmin(z)
1159 if zmax == None: zmax = numpy.nanmax(z)
1159 if zmax == None: zmax = numpy.nanmax(z)
1160
1160
1161 if SNR:
1161 if SNR:
1162 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1162 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1163 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1163 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1164
1164
1165 self.FTP_WEI = ftp_wei
1165 self.FTP_WEI = ftp_wei
1166 self.EXP_CODE = exp_code
1166 self.EXP_CODE = exp_code
1167 self.SUB_EXP_CODE = sub_exp_code
1167 self.SUB_EXP_CODE = sub_exp_code
1168 self.PLOT_POS = plot_pos
1168 self.PLOT_POS = plot_pos
1169
1169
1170 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1170 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1171 self.isConfig = True
1171 self.isConfig = True
1172 self.figfile = figfile
1172 self.figfile = figfile
1173
1173
1174 self.setWinTitle(title)
1174 self.setWinTitle(title)
1175
1175
1176 if ((self.xmax - x[1]) < (x[1]-x[0])):
1176 if ((self.xmax - x[1]) < (x[1]-x[0])):
1177 x[1] = self.xmax
1177 x[1] = self.xmax
1178
1178
1179 for i in range(nchan):
1179 for i in range(nchan):
1180
1180
1181 if (SNR and not onlySNR): j = 2*i
1181 if (SNR and not onlySNR): j = 2*i
1182 else: j = i
1182 else: j = i
1183
1183
1184 j = nGraphsByChannel*i
1184 j = nGraphsByChannel*i
1185
1185
1186 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1186 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1187 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1187 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1188
1188
1189 if not onlySNR:
1189 if not onlySNR:
1190 axes = self.axesList[j*self.__nsubplots]
1190 axes = self.axesList[j*self.__nsubplots]
1191 z1 = z[i,:].reshape((1,-1))
1191 z1 = z[i,:].reshape((1,-1))
1192 axes.pcolorbuffer(x, y, z1,
1192 axes.pcolorbuffer(x, y, z1,
1193 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1193 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1194 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1194 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1195 ticksize=9, cblabel=zlabel, cbsize="1%")
1195 ticksize=9, cblabel=zlabel, cbsize="1%")
1196
1196
1197 if DOP:
1197 if DOP:
1198 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1198 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1199
1199
1200 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1200 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1201 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1201 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1202 axes = self.axesList[j]
1202 axes = self.axesList[j]
1203 z1 = z[i,:].reshape((1,-1))
1203 z1 = z[i,:].reshape((1,-1))
1204 axes.pcolorbuffer(x, y, z1,
1204 axes.pcolorbuffer(x, y, z1,
1205 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1205 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1206 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1206 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1207 ticksize=9, cblabel=zlabel, cbsize="1%")
1207 ticksize=9, cblabel=zlabel, cbsize="1%")
1208
1208
1209 if SNR:
1209 if SNR:
1210 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1210 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1211 axes = self.axesList[(j)*self.__nsubplots]
1211 axes = self.axesList[(j)*self.__nsubplots]
1212 if not onlySNR:
1212 if not onlySNR:
1213 axes = self.axesList[(j + 1)*self.__nsubplots]
1213 axes = self.axesList[(j + 1)*self.__nsubplots]
1214
1214
1215 axes = self.axesList[(j + nGraphsByChannel-1)]
1215 axes = self.axesList[(j + nGraphsByChannel-1)]
1216 z1 = SNRdB.reshape((1,-1))
1216 z1 = SNRdB.reshape((1,-1))
1217 axes.pcolorbuffer(x, y, z1,
1217 axes.pcolorbuffer(x, y, z1,
1218 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1218 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1219 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1219 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1220 ticksize=9, cblabel=zlabel, cbsize="1%")
1220 ticksize=9, cblabel=zlabel, cbsize="1%")
1221
1221
1222
1222
1223
1223
1224 self.draw()
1224 self.draw()
1225
1225
1226 if x[1] >= self.axesList[0].xmax:
1226 if x[1] >= self.axesList[0].xmax:
1227 self.counter_imagwr = wr_period
1227 self.counter_imagwr = wr_period
1228 self.isConfig = False
1228 self.isConfig = False
1229 self.figfile = None
1229 self.figfile = None
1230
1230
1231 self.save(figpath=figpath,
1231 self.save(figpath=figpath,
1232 figfile=figfile,
1232 figfile=figfile,
1233 save=save,
1233 save=save,
1234 ftp=ftp,
1234 ftp=ftp,
1235 wr_period=wr_period,
1235 wr_period=wr_period,
1236 thisDatetime=thisDatetime,
1236 thisDatetime=thisDatetime,
1237 update_figfile=False)
1237 update_figfile=False)
1238 return dataOut
1238 return dataOut
1239
1239
1240 class SpectralFittingPlot(Figure):
1240 class SpectralFittingPlot_(Figure):
1241
1241
1242 __isConfig = None
1242 __isConfig = None
1243 __nsubplots = None
1243 __nsubplots = None
1244
1244
1245 WIDTHPROF = None
1245 WIDTHPROF = None
1246 HEIGHTPROF = None
1246 HEIGHTPROF = None
1247 PREFIX = 'prm'
1247 PREFIX = 'prm'
1248
1248
1249
1249
1250 N = None
1250 N = None
1251 ippSeconds = None
1251 ippSeconds = None
1252
1252
1253 def __init__(self, **kwargs):
1253 def __init__(self, **kwargs):
1254 Figure.__init__(self, **kwargs)
1254 Figure.__init__(self, **kwargs)
1255 self.isConfig = False
1255 self.isConfig = False
1256 self.__nsubplots = 1
1256 self.__nsubplots = 1
1257
1257
1258 self.PLOT_CODE = SPECFIT_CODE
1258 self.PLOT_CODE = SPECFIT_CODE
1259
1259
1260 self.WIDTH = 450
1260 self.WIDTH = 450
1261 self.HEIGHT = 250
1261 self.HEIGHT = 250
1262 self.WIDTHPROF = 0
1262 self.WIDTHPROF = 0
1263 self.HEIGHTPROF = 0
1263 self.HEIGHTPROF = 0
1264
1264
1265 def getSubplots(self):
1265 def getSubplots(self):
1266
1266
1267 ncol = int(numpy.sqrt(self.nplots)+0.9)
1267 ncol = int(numpy.sqrt(self.nplots)+0.9)
1268 nrow = int(self.nplots*1./ncol + 0.9)
1268 nrow = int(self.nplots*1./ncol + 0.9)
1269
1269
1270 return nrow, ncol
1270 return nrow, ncol
1271
1271
1272 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1272 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1273
1273
1274 showprofile = False
1274 showprofile = False
1275 self.__showprofile = showprofile
1275 self.__showprofile = showprofile
1276 self.nplots = nplots
1276 self.nplots = nplots
1277
1277
1278 ncolspan = 5
1278 ncolspan = 5
1279 colspan = 4
1279 colspan = 4
1280 if showprofile:
1280 if showprofile:
1281 ncolspan = 5
1281 ncolspan = 5
1282 colspan = 4
1282 colspan = 4
1283 self.__nsubplots = 2
1283 self.__nsubplots = 2
1284
1284
1285 self.createFigure(id = id,
1285 self.createFigure(id = id,
1286 wintitle = wintitle,
1286 wintitle = wintitle,
1287 widthplot = self.WIDTH + self.WIDTHPROF,
1287 widthplot = self.WIDTH + self.WIDTHPROF,
1288 heightplot = self.HEIGHT + self.HEIGHTPROF,
1288 heightplot = self.HEIGHT + self.HEIGHTPROF,
1289 show=show)
1289 show=show)
1290
1290
1291 nrow, ncol = self.getSubplots()
1291 nrow, ncol = self.getSubplots()
1292
1292
1293 counter = 0
1293 counter = 0
1294 for y in range(nrow):
1294 for y in range(nrow):
1295 for x in range(ncol):
1295 for x in range(ncol):
1296
1296
1297 if counter >= self.nplots:
1297 if counter >= self.nplots:
1298 break
1298 break
1299
1299
1300 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1300 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1301
1301
1302 if showprofile:
1302 if showprofile:
1303 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1303 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1304
1304
1305 counter += 1
1305 counter += 1
1306
1306
1307 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1307 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1308 xmin=None, xmax=None, ymin=None, ymax=None,
1308 xmin=None, xmax=None, ymin=None, ymax=None,
1309 save=False, figpath='./', figfile=None, show=True):
1309 save=False, figpath='./', figfile=None, show=True):
1310
1310
1311 """
1311 """
1312
1312
1313 Input:
1313 Input:
1314 dataOut :
1314 dataOut :
1315 id :
1315 id :
1316 wintitle :
1316 wintitle :
1317 channelList :
1317 channelList :
1318 showProfile :
1318 showProfile :
1319 xmin : None,
1319 xmin : None,
1320 xmax : None,
1320 xmax : None,
1321 zmin : None,
1321 zmin : None,
1322 zmax : None
1322 zmax : None
1323 """
1323 """
1324
1324
1325 if cutHeight==None:
1325 if cutHeight==None:
1326 h=270
1326 h=270
1327 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1327 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1328 cutHeight = dataOut.heightList[heightindex]
1328 cutHeight = dataOut.heightList[heightindex]
1329
1329
1330 factor = dataOut.normFactor
1330 factor = dataOut.normFactor
1331 x = dataOut.abscissaList[:-1]
1331 x = dataOut.abscissaList[:-1]
1332 #y = dataOut.getHeiRange()
1332 #y = dataOut.getHeiRange()
1333
1333
1334 z = dataOut.data_pre[:,:,heightindex]/factor
1334 z = dataOut.data_pre[:,:,heightindex]/factor
1335 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1335 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1336 avg = numpy.average(z, axis=1)
1336 avg = numpy.average(z, axis=1)
1337 listChannels = z.shape[0]
1337 listChannels = z.shape[0]
1338
1338
1339 #Reconstruct Function
1339 #Reconstruct Function
1340 if fit==True:
1340 if fit==True:
1341 groupArray = dataOut.groupList
1341 groupArray = dataOut.groupList
1342 listChannels = groupArray.reshape((groupArray.size))
1342 listChannels = groupArray.reshape((groupArray.size))
1343 listChannels.sort()
1343 listChannels.sort()
1344 spcFitLine = numpy.zeros(z.shape)
1344 spcFitLine = numpy.zeros(z.shape)
1345 constants = dataOut.constants
1345 constants = dataOut.constants
1346
1346
1347 nGroups = groupArray.shape[0]
1347 nGroups = groupArray.shape[0]
1348 nChannels = groupArray.shape[1]
1348 nChannels = groupArray.shape[1]
1349 nProfiles = z.shape[1]
1349 nProfiles = z.shape[1]
1350
1350
1351 for f in range(nGroups):
1351 for f in range(nGroups):
1352 groupChann = groupArray[f,:]
1352 groupChann = groupArray[f,:]
1353 p = dataOut.data_param[f,:,heightindex]
1353 p = dataOut.data_param[f,:,heightindex]
1354 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1354 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1355 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1355 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1356 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1356 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1357 spcFitLine[groupChann,:] = fitLineAux
1357 spcFitLine[groupChann,:] = fitLineAux
1358 # spcFitLine = spcFitLine/factor
1358 # spcFitLine = spcFitLine/factor
1359
1359
1360 z = z[listChannels,:]
1360 z = z[listChannels,:]
1361 spcFitLine = spcFitLine[listChannels,:]
1361 spcFitLine = spcFitLine[listChannels,:]
1362 spcFitLinedB = 10*numpy.log10(spcFitLine)
1362 spcFitLinedB = 10*numpy.log10(spcFitLine)
1363
1363
1364 zdB = 10*numpy.log10(z)
1364 zdB = 10*numpy.log10(z)
1365 #thisDatetime = dataOut.datatime
1365 #thisDatetime = dataOut.datatime
1366 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1366 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1367 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1367 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1368 xlabel = "Velocity (m/s)"
1368 xlabel = "Velocity (m/s)"
1369 ylabel = "Spectrum"
1369 ylabel = "Spectrum"
1370
1370
1371 if not self.isConfig:
1371 if not self.isConfig:
1372
1372
1373 nplots = listChannels.size
1373 nplots = listChannels.size
1374
1374
1375 self.setup(id=id,
1375 self.setup(id=id,
1376 nplots=nplots,
1376 nplots=nplots,
1377 wintitle=wintitle,
1377 wintitle=wintitle,
1378 showprofile=showprofile,
1378 showprofile=showprofile,
1379 show=show)
1379 show=show)
1380
1380
1381 if xmin == None: xmin = numpy.nanmin(x)
1381 if xmin == None: xmin = numpy.nanmin(x)
1382 if xmax == None: xmax = numpy.nanmax(x)
1382 if xmax == None: xmax = numpy.nanmax(x)
1383 if ymin == None: ymin = numpy.nanmin(zdB)
1383 if ymin == None: ymin = numpy.nanmin(zdB)
1384 if ymax == None: ymax = numpy.nanmax(zdB)+2
1384 if ymax == None: ymax = numpy.nanmax(zdB)+2
1385
1385
1386 self.isConfig = True
1386 self.isConfig = True
1387
1387
1388 self.setWinTitle(title)
1388 self.setWinTitle(title)
1389 for i in range(self.nplots):
1389 for i in range(self.nplots):
1390 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1390 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1391 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1391 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1392 axes = self.axesList[i*self.__nsubplots]
1392 axes = self.axesList[i*self.__nsubplots]
1393 if fit == False:
1393 if fit == False:
1394 axes.pline(x, zdB[i,:],
1394 axes.pline(x, zdB[i,:],
1395 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1395 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1396 xlabel=xlabel, ylabel=ylabel, title=title
1396 xlabel=xlabel, ylabel=ylabel, title=title
1397 )
1397 )
1398 if fit == True:
1398 if fit == True:
1399 fitline=spcFitLinedB[i,:]
1399 fitline=spcFitLinedB[i,:]
1400 y=numpy.vstack([zdB[i,:],fitline] )
1400 y=numpy.vstack([zdB[i,:],fitline] )
1401 legendlabels=['Data','Fitting']
1401 legendlabels=['Data','Fitting']
1402 axes.pmultilineyaxis(x, y,
1402 axes.pmultilineyaxis(x, y,
1403 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1403 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1404 xlabel=xlabel, ylabel=ylabel, title=title,
1404 xlabel=xlabel, ylabel=ylabel, title=title,
1405 legendlabels=legendlabels, marker=None,
1405 legendlabels=legendlabels, marker=None,
1406 linestyle='solid', grid='both')
1406 linestyle='solid', grid='both')
1407
1407
1408 self.draw()
1408 self.draw()
1409
1409
1410 self.save(figpath=figpath,
1410 self.save(figpath=figpath,
1411 figfile=figfile,
1411 figfile=figfile,
1412 save=save,
1412 save=save,
1413 ftp=ftp,
1413 ftp=ftp,
1414 wr_period=wr_period,
1414 wr_period=wr_period,
1415 thisDatetime=thisDatetime)
1415 thisDatetime=thisDatetime)
1416
1416
1417
1417
1418 class EWDriftsPlot(Figure):
1418 class EWDriftsPlot_(Figure):
1419
1419
1420 __isConfig = None
1420 __isConfig = None
1421 __nsubplots = None
1421 __nsubplots = None
1422
1422
1423 WIDTHPROF = None
1423 WIDTHPROF = None
1424 HEIGHTPROF = None
1424 HEIGHTPROF = None
1425 PREFIX = 'drift'
1425 PREFIX = 'drift'
1426
1426
1427 def __init__(self, **kwargs):
1427 def __init__(self, **kwargs):
1428 Figure.__init__(self, **kwargs)
1428 Figure.__init__(self, **kwargs)
1429 self.timerange = 2*60*60
1429 self.timerange = 2*60*60
1430 self.isConfig = False
1430 self.isConfig = False
1431 self.__nsubplots = 1
1431 self.__nsubplots = 1
1432
1432
1433 self.WIDTH = 800
1433 self.WIDTH = 800
1434 self.HEIGHT = 150
1434 self.HEIGHT = 150
1435 self.WIDTHPROF = 120
1435 self.WIDTHPROF = 120
1436 self.HEIGHTPROF = 0
1436 self.HEIGHTPROF = 0
1437 self.counter_imagwr = 0
1437 self.counter_imagwr = 0
1438
1438
1439 self.PLOT_CODE = EWDRIFT_CODE
1439 self.PLOT_CODE = EWDRIFT_CODE
1440
1440
1441 self.FTP_WEI = None
1441 self.FTP_WEI = None
1442 self.EXP_CODE = None
1442 self.EXP_CODE = None
1443 self.SUB_EXP_CODE = None
1443 self.SUB_EXP_CODE = None
1444 self.PLOT_POS = None
1444 self.PLOT_POS = None
1445 self.tmin = None
1445 self.tmin = None
1446 self.tmax = None
1446 self.tmax = None
1447
1447
1448 self.xmin = None
1448 self.xmin = None
1449 self.xmax = None
1449 self.xmax = None
1450
1450
1451 self.figfile = None
1451 self.figfile = None
1452
1452
1453 def getSubplots(self):
1453 def getSubplots(self):
1454
1454
1455 ncol = 1
1455 ncol = 1
1456 nrow = self.nplots
1456 nrow = self.nplots
1457
1457
1458 return nrow, ncol
1458 return nrow, ncol
1459
1459
1460 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1460 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1461
1461
1462 self.__showprofile = showprofile
1462 self.__showprofile = showprofile
1463 self.nplots = nplots
1463 self.nplots = nplots
1464
1464
1465 ncolspan = 1
1465 ncolspan = 1
1466 colspan = 1
1466 colspan = 1
1467
1467
1468 self.createFigure(id = id,
1468 self.createFigure(id = id,
1469 wintitle = wintitle,
1469 wintitle = wintitle,
1470 widthplot = self.WIDTH + self.WIDTHPROF,
1470 widthplot = self.WIDTH + self.WIDTHPROF,
1471 heightplot = self.HEIGHT + self.HEIGHTPROF,
1471 heightplot = self.HEIGHT + self.HEIGHTPROF,
1472 show=show)
1472 show=show)
1473
1473
1474 nrow, ncol = self.getSubplots()
1474 nrow, ncol = self.getSubplots()
1475
1475
1476 counter = 0
1476 counter = 0
1477 for y in range(nrow):
1477 for y in range(nrow):
1478 if counter >= self.nplots:
1478 if counter >= self.nplots:
1479 break
1479 break
1480
1480
1481 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1481 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1482 counter += 1
1482 counter += 1
1483
1483
1484 def run(self, dataOut, id, wintitle="", channelList=None,
1484 def run(self, dataOut, id, wintitle="", channelList=None,
1485 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1485 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1486 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1486 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1487 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1487 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1488 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1488 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1489 server=None, folder=None, username=None, password=None,
1489 server=None, folder=None, username=None, password=None,
1490 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1490 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1491 """
1491 """
1492
1492
1493 Input:
1493 Input:
1494 dataOut :
1494 dataOut :
1495 id :
1495 id :
1496 wintitle :
1496 wintitle :
1497 channelList :
1497 channelList :
1498 showProfile :
1498 showProfile :
1499 xmin : None,
1499 xmin : None,
1500 xmax : None,
1500 xmax : None,
1501 ymin : None,
1501 ymin : None,
1502 ymax : None,
1502 ymax : None,
1503 zmin : None,
1503 zmin : None,
1504 zmax : None
1504 zmax : None
1505 """
1505 """
1506
1506
1507 if timerange is not None:
1507 if timerange is not None:
1508 self.timerange = timerange
1508 self.timerange = timerange
1509
1509
1510 tmin = None
1510 tmin = None
1511 tmax = None
1511 tmax = None
1512
1512
1513 x = dataOut.getTimeRange1(dataOut.outputInterval)
1513 x = dataOut.getTimeRange1(dataOut.outputInterval)
1514 # y = dataOut.heightList
1514 # y = dataOut.heightList
1515 y = dataOut.heightList
1515 y = dataOut.heightList
1516
1516
1517 z = dataOut.data_output
1517 z = dataOut.data_output
1518 nplots = z.shape[0] #Number of wind dimensions estimated
1518 nplots = z.shape[0] #Number of wind dimensions estimated
1519 nplotsw = nplots
1519 nplotsw = nplots
1520
1520
1521 #If there is a SNR function defined
1521 #If there is a SNR function defined
1522 if dataOut.data_SNR is not None:
1522 if dataOut.data_SNR is not None:
1523 nplots += 1
1523 nplots += 1
1524 SNR = dataOut.data_SNR
1524 SNR = dataOut.data_SNR
1525
1525
1526 if SNR_1:
1526 if SNR_1:
1527 SNR += 1
1527 SNR += 1
1528
1528
1529 SNRavg = numpy.average(SNR, axis=0)
1529 SNRavg = numpy.average(SNR, axis=0)
1530
1530
1531 SNRdB = 10*numpy.log10(SNR)
1531 SNRdB = 10*numpy.log10(SNR)
1532 SNRavgdB = 10*numpy.log10(SNRavg)
1532 SNRavgdB = 10*numpy.log10(SNRavg)
1533
1533
1534 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1534 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1535
1535
1536 for i in range(nplotsw):
1536 for i in range(nplotsw):
1537 z[i,ind] = numpy.nan
1537 z[i,ind] = numpy.nan
1538
1538
1539
1539
1540 showprofile = False
1540 showprofile = False
1541 # thisDatetime = dataOut.datatime
1541 # thisDatetime = dataOut.datatime
1542 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1542 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1543 title = wintitle + " EW Drifts"
1543 title = wintitle + " EW Drifts"
1544 xlabel = ""
1544 xlabel = ""
1545 ylabel = "Height (Km)"
1545 ylabel = "Height (Km)"
1546
1546
1547 if not self.isConfig:
1547 if not self.isConfig:
1548
1548
1549 self.setup(id=id,
1549 self.setup(id=id,
1550 nplots=nplots,
1550 nplots=nplots,
1551 wintitle=wintitle,
1551 wintitle=wintitle,
1552 showprofile=showprofile,
1552 showprofile=showprofile,
1553 show=show)
1553 show=show)
1554
1554
1555 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1555 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1556
1556
1557 if ymin == None: ymin = numpy.nanmin(y)
1557 if ymin == None: ymin = numpy.nanmin(y)
1558 if ymax == None: ymax = numpy.nanmax(y)
1558 if ymax == None: ymax = numpy.nanmax(y)
1559
1559
1560 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1560 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1561 if zminZonal == None: zminZonal = -zmaxZonal
1561 if zminZonal == None: zminZonal = -zmaxZonal
1562 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1562 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1563 if zminVertical == None: zminVertical = -zmaxVertical
1563 if zminVertical == None: zminVertical = -zmaxVertical
1564
1564
1565 if dataOut.data_SNR is not None:
1565 if dataOut.data_SNR is not None:
1566 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1566 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1567 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1567 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1568
1568
1569 self.FTP_WEI = ftp_wei
1569 self.FTP_WEI = ftp_wei
1570 self.EXP_CODE = exp_code
1570 self.EXP_CODE = exp_code
1571 self.SUB_EXP_CODE = sub_exp_code
1571 self.SUB_EXP_CODE = sub_exp_code
1572 self.PLOT_POS = plot_pos
1572 self.PLOT_POS = plot_pos
1573
1573
1574 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1574 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1575 self.isConfig = True
1575 self.isConfig = True
1576
1576
1577
1577
1578 self.setWinTitle(title)
1578 self.setWinTitle(title)
1579
1579
1580 if ((self.xmax - x[1]) < (x[1]-x[0])):
1580 if ((self.xmax - x[1]) < (x[1]-x[0])):
1581 x[1] = self.xmax
1581 x[1] = self.xmax
1582
1582
1583 strWind = ['Zonal','Vertical']
1583 strWind = ['Zonal','Vertical']
1584 strCb = 'Velocity (m/s)'
1584 strCb = 'Velocity (m/s)'
1585 zmaxVector = [zmaxZonal, zmaxVertical]
1585 zmaxVector = [zmaxZonal, zmaxVertical]
1586 zminVector = [zminZonal, zminVertical]
1586 zminVector = [zminZonal, zminVertical]
1587
1587
1588 for i in range(nplotsw):
1588 for i in range(nplotsw):
1589
1589
1590 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1590 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1591 axes = self.axesList[i*self.__nsubplots]
1591 axes = self.axesList[i*self.__nsubplots]
1592
1592
1593 z1 = z[i,:].reshape((1,-1))
1593 z1 = z[i,:].reshape((1,-1))
1594
1594
1595 axes.pcolorbuffer(x, y, z1,
1595 axes.pcolorbuffer(x, y, z1,
1596 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1596 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1597 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1597 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1598 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1598 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1599
1599
1600 if dataOut.data_SNR is not None:
1600 if dataOut.data_SNR is not None:
1601 i += 1
1601 i += 1
1602 if SNR_1:
1602 if SNR_1:
1603 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1603 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1604 else:
1604 else:
1605 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1605 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1606 axes = self.axesList[i*self.__nsubplots]
1606 axes = self.axesList[i*self.__nsubplots]
1607 SNRavgdB = SNRavgdB.reshape((1,-1))
1607 SNRavgdB = SNRavgdB.reshape((1,-1))
1608
1608
1609 axes.pcolorbuffer(x, y, SNRavgdB,
1609 axes.pcolorbuffer(x, y, SNRavgdB,
1610 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1610 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1611 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1611 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1612 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1612 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1613
1613
1614 self.draw()
1614 self.draw()
1615
1615
1616 if x[1] >= self.axesList[0].xmax:
1616 if x[1] >= self.axesList[0].xmax:
1617 self.counter_imagwr = wr_period
1617 self.counter_imagwr = wr_period
1618 self.isConfig = False
1618 self.isConfig = False
1619 self.figfile = None
1619 self.figfile = None
1620
1620
1621
1621
1622
1622
1623
1623
1624 class PhasePlot(Figure):
1624 class PhasePlot_(Figure):
1625
1625
1626 __isConfig = None
1626 __isConfig = None
1627 __nsubplots = None
1627 __nsubplots = None
1628
1628
1629 PREFIX = 'mphase'
1629 PREFIX = 'mphase'
1630
1630
1631
1631
1632 def __init__(self, **kwargs):
1632 def __init__(self, **kwargs):
1633 Figure.__init__(self, **kwargs)
1633 Figure.__init__(self, **kwargs)
1634 self.timerange = 24*60*60
1634 self.timerange = 24*60*60
1635 self.isConfig = False
1635 self.isConfig = False
1636 self.__nsubplots = 1
1636 self.__nsubplots = 1
1637 self.counter_imagwr = 0
1637 self.counter_imagwr = 0
1638 self.WIDTH = 600
1638 self.WIDTH = 600
1639 self.HEIGHT = 300
1639 self.HEIGHT = 300
1640 self.WIDTHPROF = 120
1640 self.WIDTHPROF = 120
1641 self.HEIGHTPROF = 0
1641 self.HEIGHTPROF = 0
1642 self.xdata = None
1642 self.xdata = None
1643 self.ydata = None
1643 self.ydata = None
1644
1644
1645 self.PLOT_CODE = MPHASE_CODE
1645 self.PLOT_CODE = MPHASE_CODE
1646
1646
1647 self.FTP_WEI = None
1647 self.FTP_WEI = None
1648 self.EXP_CODE = None
1648 self.EXP_CODE = None
1649 self.SUB_EXP_CODE = None
1649 self.SUB_EXP_CODE = None
1650 self.PLOT_POS = None
1650 self.PLOT_POS = None
1651
1651
1652
1652
1653 self.filename_phase = None
1653 self.filename_phase = None
1654
1654
1655 self.figfile = None
1655 self.figfile = None
1656
1656
1657 def getSubplots(self):
1657 def getSubplots(self):
1658
1658
1659 ncol = 1
1659 ncol = 1
1660 nrow = 1
1660 nrow = 1
1661
1661
1662 return nrow, ncol
1662 return nrow, ncol
1663
1663
1664 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1664 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1665
1665
1666 self.__showprofile = showprofile
1666 self.__showprofile = showprofile
1667 self.nplots = nplots
1667 self.nplots = nplots
1668
1668
1669 ncolspan = 7
1669 ncolspan = 7
1670 colspan = 6
1670 colspan = 6
1671 self.__nsubplots = 2
1671 self.__nsubplots = 2
1672
1672
1673 self.createFigure(id = id,
1673 self.createFigure(id = id,
1674 wintitle = wintitle,
1674 wintitle = wintitle,
1675 widthplot = self.WIDTH+self.WIDTHPROF,
1675 widthplot = self.WIDTH+self.WIDTHPROF,
1676 heightplot = self.HEIGHT+self.HEIGHTPROF,
1676 heightplot = self.HEIGHT+self.HEIGHTPROF,
1677 show=show)
1677 show=show)
1678
1678
1679 nrow, ncol = self.getSubplots()
1679 nrow, ncol = self.getSubplots()
1680
1680
1681 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1681 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1682
1682
1683
1683
1684 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1684 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1685 xmin=None, xmax=None, ymin=None, ymax=None,
1685 xmin=None, xmax=None, ymin=None, ymax=None,
1686 timerange=None,
1686 timerange=None,
1687 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1687 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1688 server=None, folder=None, username=None, password=None,
1688 server=None, folder=None, username=None, password=None,
1689 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1689 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1690
1690
1691
1691
1692 tmin = None
1692 tmin = None
1693 tmax = None
1693 tmax = None
1694 x = dataOut.getTimeRange1(dataOut.outputInterval)
1694 x = dataOut.getTimeRange1(dataOut.outputInterval)
1695 y = dataOut.getHeiRange()
1695 y = dataOut.getHeiRange()
1696
1696
1697
1697
1698 #thisDatetime = dataOut.datatime
1698 #thisDatetime = dataOut.datatime
1699 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1699 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1700 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1700 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1701 xlabel = "Local Time"
1701 xlabel = "Local Time"
1702 ylabel = "Phase"
1702 ylabel = "Phase"
1703
1703
1704
1704
1705 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1705 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1706 phase_beacon = dataOut.data_output
1706 phase_beacon = dataOut.data_output
1707 update_figfile = False
1707 update_figfile = False
1708
1708
1709 if not self.isConfig:
1709 if not self.isConfig:
1710
1710
1711 self.nplots = phase_beacon.size
1711 self.nplots = phase_beacon.size
1712
1712
1713 self.setup(id=id,
1713 self.setup(id=id,
1714 nplots=self.nplots,
1714 nplots=self.nplots,
1715 wintitle=wintitle,
1715 wintitle=wintitle,
1716 showprofile=showprofile,
1716 showprofile=showprofile,
1717 show=show)
1717 show=show)
1718
1718
1719 if timerange is not None:
1719 if timerange is not None:
1720 self.timerange = timerange
1720 self.timerange = timerange
1721
1721
1722 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1722 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1723
1723
1724 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1724 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1725 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1725 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1726
1726
1727 self.FTP_WEI = ftp_wei
1727 self.FTP_WEI = ftp_wei
1728 self.EXP_CODE = exp_code
1728 self.EXP_CODE = exp_code
1729 self.SUB_EXP_CODE = sub_exp_code
1729 self.SUB_EXP_CODE = sub_exp_code
1730 self.PLOT_POS = plot_pos
1730 self.PLOT_POS = plot_pos
1731
1731
1732 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1732 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1733 self.isConfig = True
1733 self.isConfig = True
1734 self.figfile = figfile
1734 self.figfile = figfile
1735 self.xdata = numpy.array([])
1735 self.xdata = numpy.array([])
1736 self.ydata = numpy.array([])
1736 self.ydata = numpy.array([])
1737
1737
1738 #open file beacon phase
1738 #open file beacon phase
1739 path = '%s%03d' %(self.PREFIX, self.id)
1739 path = '%s%03d' %(self.PREFIX, self.id)
1740 beacon_file = os.path.join(path,'%s.txt'%self.name)
1740 beacon_file = os.path.join(path,'%s.txt'%self.name)
1741 self.filename_phase = os.path.join(figpath,beacon_file)
1741 self.filename_phase = os.path.join(figpath,beacon_file)
1742 update_figfile = True
1742 update_figfile = True
1743
1743
1744
1744
1745 #store data beacon phase
1745 #store data beacon phase
1746 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1746 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1747
1747
1748 self.setWinTitle(title)
1748 self.setWinTitle(title)
1749
1749
1750
1750
1751 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1751 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1752
1752
1753 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1753 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1754
1754
1755 axes = self.axesList[0]
1755 axes = self.axesList[0]
1756
1756
1757 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1757 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1758
1758
1759 if len(self.ydata)==0:
1759 if len(self.ydata)==0:
1760 self.ydata = phase_beacon.reshape(-1,1)
1760 self.ydata = phase_beacon.reshape(-1,1)
1761 else:
1761 else:
1762 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1762 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1763
1763
1764
1764
1765 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1765 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1766 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1766 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1767 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1767 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1768 XAxisAsTime=True, grid='both'
1768 XAxisAsTime=True, grid='both'
1769 )
1769 )
1770
1770
1771 self.draw()
1771 self.draw()
1772
1772
1773 self.save(figpath=figpath,
1773 self.save(figpath=figpath,
1774 figfile=figfile,
1774 figfile=figfile,
1775 save=save,
1775 save=save,
1776 ftp=ftp,
1776 ftp=ftp,
1777 wr_period=wr_period,
1777 wr_period=wr_period,
1778 thisDatetime=thisDatetime,
1778 thisDatetime=thisDatetime,
1779 update_figfile=update_figfile)
1779 update_figfile=update_figfile)
1780
1780
1781 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
1781 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
1782 self.counter_imagwr = wr_period
1782 self.counter_imagwr = wr_period
1783 self.isConfig = False
1783 self.isConfig = False
1784 update_figfile = True
1784 update_figfile = True
1785
1785
1786
1786
1787
1787
1788 class NSMeteorDetection1Plot(Figure):
1788 class NSMeteorDetection1Plot_(Figure):
1789
1789
1790 isConfig = None
1790 isConfig = None
1791 __nsubplots = None
1791 __nsubplots = None
1792
1792
1793 WIDTHPROF = None
1793 WIDTHPROF = None
1794 HEIGHTPROF = None
1794 HEIGHTPROF = None
1795 PREFIX = 'nsm'
1795 PREFIX = 'nsm'
1796
1796
1797 zminList = None
1797 zminList = None
1798 zmaxList = None
1798 zmaxList = None
1799 cmapList = None
1799 cmapList = None
1800 titleList = None
1800 titleList = None
1801 nPairs = None
1801 nPairs = None
1802 nChannels = None
1802 nChannels = None
1803 nParam = None
1803 nParam = None
1804
1804
1805 def __init__(self, **kwargs):
1805 def __init__(self, **kwargs):
1806 Figure.__init__(self, **kwargs)
1806 Figure.__init__(self, **kwargs)
1807 self.isConfig = False
1807 self.isConfig = False
1808 self.__nsubplots = 1
1808 self.__nsubplots = 1
1809
1809
1810 self.WIDTH = 750
1810 self.WIDTH = 750
1811 self.HEIGHT = 250
1811 self.HEIGHT = 250
1812 self.WIDTHPROF = 120
1812 self.WIDTHPROF = 120
1813 self.HEIGHTPROF = 0
1813 self.HEIGHTPROF = 0
1814 self.counter_imagwr = 0
1814 self.counter_imagwr = 0
1815
1815
1816 self.PLOT_CODE = SPEC_CODE
1816 self.PLOT_CODE = SPEC_CODE
1817
1817
1818 self.FTP_WEI = None
1818 self.FTP_WEI = None
1819 self.EXP_CODE = None
1819 self.EXP_CODE = None
1820 self.SUB_EXP_CODE = None
1820 self.SUB_EXP_CODE = None
1821 self.PLOT_POS = None
1821 self.PLOT_POS = None
1822
1822
1823 self.__xfilter_ena = False
1823 self.__xfilter_ena = False
1824 self.__yfilter_ena = False
1824 self.__yfilter_ena = False
1825
1825
1826 def getSubplots(self):
1826 def getSubplots(self):
1827
1827
1828 ncol = 3
1828 ncol = 3
1829 nrow = int(numpy.ceil(self.nplots/3.0))
1829 nrow = int(numpy.ceil(self.nplots/3.0))
1830
1830
1831 return nrow, ncol
1831 return nrow, ncol
1832
1832
1833 def setup(self, id, nplots, wintitle, show=True):
1833 def setup(self, id, nplots, wintitle, show=True):
1834
1834
1835 self.nplots = nplots
1835 self.nplots = nplots
1836
1836
1837 ncolspan = 1
1837 ncolspan = 1
1838 colspan = 1
1838 colspan = 1
1839
1839
1840 self.createFigure(id = id,
1840 self.createFigure(id = id,
1841 wintitle = wintitle,
1841 wintitle = wintitle,
1842 widthplot = self.WIDTH + self.WIDTHPROF,
1842 widthplot = self.WIDTH + self.WIDTHPROF,
1843 heightplot = self.HEIGHT + self.HEIGHTPROF,
1843 heightplot = self.HEIGHT + self.HEIGHTPROF,
1844 show=show)
1844 show=show)
1845
1845
1846 nrow, ncol = self.getSubplots()
1846 nrow, ncol = self.getSubplots()
1847
1847
1848 counter = 0
1848 counter = 0
1849 for y in range(nrow):
1849 for y in range(nrow):
1850 for x in range(ncol):
1850 for x in range(ncol):
1851
1851
1852 if counter >= self.nplots:
1852 if counter >= self.nplots:
1853 break
1853 break
1854
1854
1855 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1855 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1856
1856
1857 counter += 1
1857 counter += 1
1858
1858
1859 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1859 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1860 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1860 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1861 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1861 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1862 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1862 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1863 server=None, folder=None, username=None, password=None,
1863 server=None, folder=None, username=None, password=None,
1864 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1864 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1865 xaxis="frequency"):
1865 xaxis="frequency"):
1866
1866
1867 """
1867 """
1868
1868
1869 Input:
1869 Input:
1870 dataOut :
1870 dataOut :
1871 id :
1871 id :
1872 wintitle :
1872 wintitle :
1873 channelList :
1873 channelList :
1874 showProfile :
1874 showProfile :
1875 xmin : None,
1875 xmin : None,
1876 xmax : None,
1876 xmax : None,
1877 ymin : None,
1877 ymin : None,
1878 ymax : None,
1878 ymax : None,
1879 zmin : None,
1879 zmin : None,
1880 zmax : None
1880 zmax : None
1881 """
1881 """
1882 #SEPARAR EN DOS PLOTS
1882 #SEPARAR EN DOS PLOTS
1883 nParam = dataOut.data_param.shape[1] - 3
1883 nParam = dataOut.data_param.shape[1] - 3
1884
1884
1885 utctime = dataOut.data_param[0,0]
1885 utctime = dataOut.data_param[0,0]
1886 tmet = dataOut.data_param[:,1].astype(int)
1886 tmet = dataOut.data_param[:,1].astype(int)
1887 hmet = dataOut.data_param[:,2].astype(int)
1887 hmet = dataOut.data_param[:,2].astype(int)
1888
1888
1889 x = dataOut.abscissaList
1889 x = dataOut.abscissaList
1890 y = dataOut.heightList
1890 y = dataOut.heightList
1891
1891
1892 z = numpy.zeros((nParam, y.size, x.size - 1))
1892 z = numpy.zeros((nParam, y.size, x.size - 1))
1893 z[:,:] = numpy.nan
1893 z[:,:] = numpy.nan
1894 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
1894 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
1895 z[0,:,:] = 10*numpy.log10(z[0,:,:])
1895 z[0,:,:] = 10*numpy.log10(z[0,:,:])
1896
1896
1897 xlabel = "Time (s)"
1897 xlabel = "Time (s)"
1898 ylabel = "Range (km)"
1898 ylabel = "Range (km)"
1899
1899
1900 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1900 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1901
1901
1902 if not self.isConfig:
1902 if not self.isConfig:
1903
1903
1904 nplots = nParam
1904 nplots = nParam
1905
1905
1906 self.setup(id=id,
1906 self.setup(id=id,
1907 nplots=nplots,
1907 nplots=nplots,
1908 wintitle=wintitle,
1908 wintitle=wintitle,
1909 show=show)
1909 show=show)
1910
1910
1911 if xmin is None: xmin = numpy.nanmin(x)
1911 if xmin is None: xmin = numpy.nanmin(x)
1912 if xmax is None: xmax = numpy.nanmax(x)
1912 if xmax is None: xmax = numpy.nanmax(x)
1913 if ymin is None: ymin = numpy.nanmin(y)
1913 if ymin is None: ymin = numpy.nanmin(y)
1914 if ymax is None: ymax = numpy.nanmax(y)
1914 if ymax is None: ymax = numpy.nanmax(y)
1915 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1915 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1916 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1916 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1917 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1917 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1918 if vmin is None: vmin = -vmax
1918 if vmin is None: vmin = -vmax
1919 if wmin is None: wmin = 0
1919 if wmin is None: wmin = 0
1920 if wmax is None: wmax = 50
1920 if wmax is None: wmax = 50
1921
1921
1922 pairsList = dataOut.groupList
1922 pairsList = dataOut.groupList
1923 self.nPairs = len(dataOut.groupList)
1923 self.nPairs = len(dataOut.groupList)
1924
1924
1925 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
1925 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
1926 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
1926 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
1927 titleList = ["SNR","Radial Velocity","Coherence"]
1927 titleList = ["SNR","Radial Velocity","Coherence"]
1928 cmapList = ["jet","RdBu_r","jet"]
1928 cmapList = ["jet","RdBu_r","jet"]
1929
1929
1930 for i in range(self.nPairs):
1930 for i in range(self.nPairs):
1931 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
1931 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
1932 titleList = titleList + [strAux1]
1932 titleList = titleList + [strAux1]
1933 cmapList = cmapList + ["RdBu_r"]
1933 cmapList = cmapList + ["RdBu_r"]
1934
1934
1935 self.zminList = zminList
1935 self.zminList = zminList
1936 self.zmaxList = zmaxList
1936 self.zmaxList = zmaxList
1937 self.cmapList = cmapList
1937 self.cmapList = cmapList
1938 self.titleList = titleList
1938 self.titleList = titleList
1939
1939
1940 self.FTP_WEI = ftp_wei
1940 self.FTP_WEI = ftp_wei
1941 self.EXP_CODE = exp_code
1941 self.EXP_CODE = exp_code
1942 self.SUB_EXP_CODE = sub_exp_code
1942 self.SUB_EXP_CODE = sub_exp_code
1943 self.PLOT_POS = plot_pos
1943 self.PLOT_POS = plot_pos
1944
1944
1945 self.isConfig = True
1945 self.isConfig = True
1946
1946
1947 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1947 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1948
1948
1949 for i in range(nParam):
1949 for i in range(nParam):
1950 title = self.titleList[i] + ": " +str_datetime
1950 title = self.titleList[i] + ": " +str_datetime
1951 axes = self.axesList[i]
1951 axes = self.axesList[i]
1952 axes.pcolor(x, y, z[i,:].T,
1952 axes.pcolor(x, y, z[i,:].T,
1953 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1953 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1954 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1954 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1955 self.draw()
1955 self.draw()
1956
1956
1957 if figfile == None:
1957 if figfile == None:
1958 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1958 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1959 name = str_datetime
1959 name = str_datetime
1960 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1960 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1961 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1961 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1962 figfile = self.getFilename(name)
1962 figfile = self.getFilename(name)
1963
1963
1964 self.save(figpath=figpath,
1964 self.save(figpath=figpath,
1965 figfile=figfile,
1965 figfile=figfile,
1966 save=save,
1966 save=save,
1967 ftp=ftp,
1967 ftp=ftp,
1968 wr_period=wr_period,
1968 wr_period=wr_period,
1969 thisDatetime=thisDatetime)
1969 thisDatetime=thisDatetime)
1970
1970
1971
1971
1972 class NSMeteorDetection2Plot(Figure):
1972 class NSMeteorDetection2Plot_(Figure):
1973
1973
1974 isConfig = None
1974 isConfig = None
1975 __nsubplots = None
1975 __nsubplots = None
1976
1976
1977 WIDTHPROF = None
1977 WIDTHPROF = None
1978 HEIGHTPROF = None
1978 HEIGHTPROF = None
1979 PREFIX = 'nsm'
1979 PREFIX = 'nsm'
1980
1980
1981 zminList = None
1981 zminList = None
1982 zmaxList = None
1982 zmaxList = None
1983 cmapList = None
1983 cmapList = None
1984 titleList = None
1984 titleList = None
1985 nPairs = None
1985 nPairs = None
1986 nChannels = None
1986 nChannels = None
1987 nParam = None
1987 nParam = None
1988
1988
1989 def __init__(self, **kwargs):
1989 def __init__(self, **kwargs):
1990 Figure.__init__(self, **kwargs)
1990 Figure.__init__(self, **kwargs)
1991 self.isConfig = False
1991 self.isConfig = False
1992 self.__nsubplots = 1
1992 self.__nsubplots = 1
1993
1993
1994 self.WIDTH = 750
1994 self.WIDTH = 750
1995 self.HEIGHT = 250
1995 self.HEIGHT = 250
1996 self.WIDTHPROF = 120
1996 self.WIDTHPROF = 120
1997 self.HEIGHTPROF = 0
1997 self.HEIGHTPROF = 0
1998 self.counter_imagwr = 0
1998 self.counter_imagwr = 0
1999
1999
2000 self.PLOT_CODE = SPEC_CODE
2000 self.PLOT_CODE = SPEC_CODE
2001
2001
2002 self.FTP_WEI = None
2002 self.FTP_WEI = None
2003 self.EXP_CODE = None
2003 self.EXP_CODE = None
2004 self.SUB_EXP_CODE = None
2004 self.SUB_EXP_CODE = None
2005 self.PLOT_POS = None
2005 self.PLOT_POS = None
2006
2006
2007 self.__xfilter_ena = False
2007 self.__xfilter_ena = False
2008 self.__yfilter_ena = False
2008 self.__yfilter_ena = False
2009
2009
2010 def getSubplots(self):
2010 def getSubplots(self):
2011
2011
2012 ncol = 3
2012 ncol = 3
2013 nrow = int(numpy.ceil(self.nplots/3.0))
2013 nrow = int(numpy.ceil(self.nplots/3.0))
2014
2014
2015 return nrow, ncol
2015 return nrow, ncol
2016
2016
2017 def setup(self, id, nplots, wintitle, show=True):
2017 def setup(self, id, nplots, wintitle, show=True):
2018
2018
2019 self.nplots = nplots
2019 self.nplots = nplots
2020
2020
2021 ncolspan = 1
2021 ncolspan = 1
2022 colspan = 1
2022 colspan = 1
2023
2023
2024 self.createFigure(id = id,
2024 self.createFigure(id = id,
2025 wintitle = wintitle,
2025 wintitle = wintitle,
2026 widthplot = self.WIDTH + self.WIDTHPROF,
2026 widthplot = self.WIDTH + self.WIDTHPROF,
2027 heightplot = self.HEIGHT + self.HEIGHTPROF,
2027 heightplot = self.HEIGHT + self.HEIGHTPROF,
2028 show=show)
2028 show=show)
2029
2029
2030 nrow, ncol = self.getSubplots()
2030 nrow, ncol = self.getSubplots()
2031
2031
2032 counter = 0
2032 counter = 0
2033 for y in range(nrow):
2033 for y in range(nrow):
2034 for x in range(ncol):
2034 for x in range(ncol):
2035
2035
2036 if counter >= self.nplots:
2036 if counter >= self.nplots:
2037 break
2037 break
2038
2038
2039 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2039 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2040
2040
2041 counter += 1
2041 counter += 1
2042
2042
2043 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2043 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2044 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2044 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2045 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2045 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2046 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2046 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2047 server=None, folder=None, username=None, password=None,
2047 server=None, folder=None, username=None, password=None,
2048 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2048 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2049 xaxis="frequency"):
2049 xaxis="frequency"):
2050
2050
2051 """
2051 """
2052
2052
2053 Input:
2053 Input:
2054 dataOut :
2054 dataOut :
2055 id :
2055 id :
2056 wintitle :
2056 wintitle :
2057 channelList :
2057 channelList :
2058 showProfile :
2058 showProfile :
2059 xmin : None,
2059 xmin : None,
2060 xmax : None,
2060 xmax : None,
2061 ymin : None,
2061 ymin : None,
2062 ymax : None,
2062 ymax : None,
2063 zmin : None,
2063 zmin : None,
2064 zmax : None
2064 zmax : None
2065 """
2065 """
2066 #Rebuild matrix
2066 #Rebuild matrix
2067 utctime = dataOut.data_param[0,0]
2067 utctime = dataOut.data_param[0,0]
2068 cmet = dataOut.data_param[:,1].astype(int)
2068 cmet = dataOut.data_param[:,1].astype(int)
2069 tmet = dataOut.data_param[:,2].astype(int)
2069 tmet = dataOut.data_param[:,2].astype(int)
2070 hmet = dataOut.data_param[:,3].astype(int)
2070 hmet = dataOut.data_param[:,3].astype(int)
2071
2071
2072 nParam = 3
2072 nParam = 3
2073 nChan = len(dataOut.groupList)
2073 nChan = len(dataOut.groupList)
2074 x = dataOut.abscissaList
2074 x = dataOut.abscissaList
2075 y = dataOut.heightList
2075 y = dataOut.heightList
2076
2076
2077 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
2077 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
2078 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
2078 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
2079 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
2079 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
2080 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
2080 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
2081
2081
2082 xlabel = "Time (s)"
2082 xlabel = "Time (s)"
2083 ylabel = "Range (km)"
2083 ylabel = "Range (km)"
2084
2084
2085 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2085 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2086
2086
2087 if not self.isConfig:
2087 if not self.isConfig:
2088
2088
2089 nplots = nParam*nChan
2089 nplots = nParam*nChan
2090
2090
2091 self.setup(id=id,
2091 self.setup(id=id,
2092 nplots=nplots,
2092 nplots=nplots,
2093 wintitle=wintitle,
2093 wintitle=wintitle,
2094 show=show)
2094 show=show)
2095
2095
2096 if xmin is None: xmin = numpy.nanmin(x)
2096 if xmin is None: xmin = numpy.nanmin(x)
2097 if xmax is None: xmax = numpy.nanmax(x)
2097 if xmax is None: xmax = numpy.nanmax(x)
2098 if ymin is None: ymin = numpy.nanmin(y)
2098 if ymin is None: ymin = numpy.nanmin(y)
2099 if ymax is None: ymax = numpy.nanmax(y)
2099 if ymax is None: ymax = numpy.nanmax(y)
2100 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2100 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2101 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2101 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2102 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2102 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2103 if vmin is None: vmin = -vmax
2103 if vmin is None: vmin = -vmax
2104 if wmin is None: wmin = 0
2104 if wmin is None: wmin = 0
2105 if wmax is None: wmax = 50
2105 if wmax is None: wmax = 50
2106
2106
2107 self.nChannels = nChan
2107 self.nChannels = nChan
2108
2108
2109 zminList = []
2109 zminList = []
2110 zmaxList = []
2110 zmaxList = []
2111 titleList = []
2111 titleList = []
2112 cmapList = []
2112 cmapList = []
2113 for i in range(self.nChannels):
2113 for i in range(self.nChannels):
2114 strAux1 = "SNR Channel "+ str(i)
2114 strAux1 = "SNR Channel "+ str(i)
2115 strAux2 = "Radial Velocity Channel "+ str(i)
2115 strAux2 = "Radial Velocity Channel "+ str(i)
2116 strAux3 = "Spectral Width Channel "+ str(i)
2116 strAux3 = "Spectral Width Channel "+ str(i)
2117
2117
2118 titleList = titleList + [strAux1,strAux2,strAux3]
2118 titleList = titleList + [strAux1,strAux2,strAux3]
2119 cmapList = cmapList + ["jet","RdBu_r","jet"]
2119 cmapList = cmapList + ["jet","RdBu_r","jet"]
2120 zminList = zminList + [SNRmin,vmin,wmin]
2120 zminList = zminList + [SNRmin,vmin,wmin]
2121 zmaxList = zmaxList + [SNRmax,vmax,wmax]
2121 zmaxList = zmaxList + [SNRmax,vmax,wmax]
2122
2122
2123 self.zminList = zminList
2123 self.zminList = zminList
2124 self.zmaxList = zmaxList
2124 self.zmaxList = zmaxList
2125 self.cmapList = cmapList
2125 self.cmapList = cmapList
2126 self.titleList = titleList
2126 self.titleList = titleList
2127
2127
2128 self.FTP_WEI = ftp_wei
2128 self.FTP_WEI = ftp_wei
2129 self.EXP_CODE = exp_code
2129 self.EXP_CODE = exp_code
2130 self.SUB_EXP_CODE = sub_exp_code
2130 self.SUB_EXP_CODE = sub_exp_code
2131 self.PLOT_POS = plot_pos
2131 self.PLOT_POS = plot_pos
2132
2132
2133 self.isConfig = True
2133 self.isConfig = True
2134
2134
2135 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2135 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2136
2136
2137 for i in range(self.nplots):
2137 for i in range(self.nplots):
2138 title = self.titleList[i] + ": " +str_datetime
2138 title = self.titleList[i] + ": " +str_datetime
2139 axes = self.axesList[i]
2139 axes = self.axesList[i]
2140 axes.pcolor(x, y, z[i,:].T,
2140 axes.pcolor(x, y, z[i,:].T,
2141 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2141 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2142 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2142 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2143 self.draw()
2143 self.draw()
2144
2144
2145 if figfile == None:
2145 if figfile == None:
2146 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2146 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2147 name = str_datetime
2147 name = str_datetime
2148 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2148 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2149 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2149 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2150 figfile = self.getFilename(name)
2150 figfile = self.getFilename(name)
2151
2151
2152 self.save(figpath=figpath,
2152 self.save(figpath=figpath,
2153 figfile=figfile,
2153 figfile=figfile,
2154 save=save,
2154 save=save,
2155 ftp=ftp,
2155 ftp=ftp,
2156 wr_period=wr_period,
2156 wr_period=wr_period,
2157 thisDatetime=thisDatetime)
2157 thisDatetime=thisDatetime)
2158 No newline at end of file
2158
@@ -1,1587 +1,1587
1 '''
1 '''
2 Created on Jul 9, 2014
2 Created on Jul 9, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import os
6 import os
7 import datetime
7 import datetime
8 import numpy
8 import numpy
9
9
10 from .figure import Figure, isRealtime, isTimeInHourRange
10 from .figure import Figure, isRealtime, isTimeInHourRange
11 from .plotting_codes import *
11 from .plotting_codes import *
12 from schainpy.model.proc.jroproc_base import MPDecorator
12 from schainpy.model.proc.jroproc_base import MPDecorator
13
13
14 from schainpy.utils import log
14 from schainpy.utils import log
15
15
16 @MPDecorator
16 @MPDecorator
17 class SpectraPlot(Figure):
17 class SpectraPlot_(Figure):
18
18
19 isConfig = None
19 isConfig = None
20 __nsubplots = None
20 __nsubplots = None
21
21
22 WIDTHPROF = None
22 WIDTHPROF = None
23 HEIGHTPROF = None
23 HEIGHTPROF = None
24 PREFIX = 'spc'
24 PREFIX = 'spc'
25
25
26 def __init__(self):
26 def __init__(self):
27 Figure.__init__(self)
27 Figure.__init__(self)
28 self.isConfig = False
28 self.isConfig = False
29 self.__nsubplots = 1
29 self.__nsubplots = 1
30 self.WIDTH = 250
30 self.WIDTH = 250
31 self.HEIGHT = 250
31 self.HEIGHT = 250
32 self.WIDTHPROF = 120
32 self.WIDTHPROF = 120
33 self.HEIGHTPROF = 0
33 self.HEIGHTPROF = 0
34 self.counter_imagwr = 0
34 self.counter_imagwr = 0
35
35
36 self.PLOT_CODE = SPEC_CODE
36 self.PLOT_CODE = SPEC_CODE
37
37
38 self.FTP_WEI = None
38 self.FTP_WEI = None
39 self.EXP_CODE = None
39 self.EXP_CODE = None
40 self.SUB_EXP_CODE = None
40 self.SUB_EXP_CODE = None
41 self.PLOT_POS = None
41 self.PLOT_POS = None
42
42
43 self.__xfilter_ena = False
43 self.__xfilter_ena = False
44 self.__yfilter_ena = False
44 self.__yfilter_ena = False
45
45
46 def getSubplots(self):
46 def getSubplots(self):
47
47
48 ncol = int(numpy.sqrt(self.nplots)+0.9)
48 ncol = int(numpy.sqrt(self.nplots)+0.9)
49 nrow = int(self.nplots*1./ncol + 0.9)
49 nrow = int(self.nplots*1./ncol + 0.9)
50
50
51 return nrow, ncol
51 return nrow, ncol
52
52
53 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
53 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
54
54
55 self.__showprofile = showprofile
55 self.__showprofile = showprofile
56 self.nplots = nplots
56 self.nplots = nplots
57
57
58 ncolspan = 1
58 ncolspan = 1
59 colspan = 1
59 colspan = 1
60 if showprofile:
60 if showprofile:
61 ncolspan = 3
61 ncolspan = 3
62 colspan = 2
62 colspan = 2
63 self.__nsubplots = 2
63 self.__nsubplots = 2
64
64
65 self.createFigure(id = id,
65 self.createFigure(id = id,
66 wintitle = wintitle,
66 wintitle = wintitle,
67 widthplot = self.WIDTH + self.WIDTHPROF,
67 widthplot = self.WIDTH + self.WIDTHPROF,
68 heightplot = self.HEIGHT + self.HEIGHTPROF,
68 heightplot = self.HEIGHT + self.HEIGHTPROF,
69 show=show)
69 show=show)
70
70
71 nrow, ncol = self.getSubplots()
71 nrow, ncol = self.getSubplots()
72
72
73 counter = 0
73 counter = 0
74 for y in range(nrow):
74 for y in range(nrow):
75 for x in range(ncol):
75 for x in range(ncol):
76
76
77 if counter >= self.nplots:
77 if counter >= self.nplots:
78 break
78 break
79
79
80 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
80 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
81
81
82 if showprofile:
82 if showprofile:
83 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
83 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
84
84
85 counter += 1
85 counter += 1
86
86
87 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
87 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
88 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
88 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
89 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
89 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
90 server=None, folder=None, username=None, password=None,
90 server=None, folder=None, username=None, password=None,
91 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
91 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
92 xaxis="frequency", colormap='jet', normFactor=None):
92 xaxis="frequency", colormap='jet', normFactor=None):
93
93
94 """
94 """
95
95
96 Input:
96 Input:
97 dataOut :
97 dataOut :
98 id :
98 id :
99 wintitle :
99 wintitle :
100 channelList :
100 channelList :
101 showProfile :
101 showProfile :
102 xmin : None,
102 xmin : None,
103 xmax : None,
103 xmax : None,
104 ymin : None,
104 ymin : None,
105 ymax : None,
105 ymax : None,
106 zmin : None,
106 zmin : None,
107 zmax : None
107 zmax : None
108 """
108 """
109 if dataOut.flagNoData:
109 if dataOut.flagNoData:
110 return dataOut
110 return dataOut
111
111
112 if realtime:
112 if realtime:
113 if not(isRealtime(utcdatatime = dataOut.utctime)):
113 if not(isRealtime(utcdatatime = dataOut.utctime)):
114 print('Skipping this plot function')
114 print('Skipping this plot function')
115 return
115 return
116
116
117 if channelList == None:
117 if channelList == None:
118 channelIndexList = dataOut.channelIndexList
118 channelIndexList = dataOut.channelIndexList
119 else:
119 else:
120 channelIndexList = []
120 channelIndexList = []
121 for channel in channelList:
121 for channel in channelList:
122 if channel not in dataOut.channelList:
122 if channel not in dataOut.channelList:
123 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
123 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
124 channelIndexList.append(dataOut.channelList.index(channel))
124 channelIndexList.append(dataOut.channelList.index(channel))
125
125
126 if normFactor is None:
126 if normFactor is None:
127 factor = dataOut.normFactor
127 factor = dataOut.normFactor
128 else:
128 else:
129 factor = normFactor
129 factor = normFactor
130 if xaxis == "frequency":
130 if xaxis == "frequency":
131 x = dataOut.getFreqRange(1)/1000.
131 x = dataOut.getFreqRange(1)/1000.
132 xlabel = "Frequency (kHz)"
132 xlabel = "Frequency (kHz)"
133
133
134 elif xaxis == "time":
134 elif xaxis == "time":
135 x = dataOut.getAcfRange(1)
135 x = dataOut.getAcfRange(1)
136 xlabel = "Time (ms)"
136 xlabel = "Time (ms)"
137
137
138 else:
138 else:
139 x = dataOut.getVelRange(1)
139 x = dataOut.getVelRange(1)
140 xlabel = "Velocity (m/s)"
140 xlabel = "Velocity (m/s)"
141
141
142 ylabel = "Range (Km)"
142 ylabel = "Range (Km)"
143
143
144 y = dataOut.getHeiRange()
144 y = dataOut.getHeiRange()
145
145
146 z = dataOut.data_spc/factor
146 z = dataOut.data_spc/factor
147 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
147 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
148 zdB = 10*numpy.log10(z)
148 zdB = 10*numpy.log10(z)
149
149
150 avg = numpy.average(z, axis=1)
150 avg = numpy.average(z, axis=1)
151 avgdB = 10*numpy.log10(avg)
151 avgdB = 10*numpy.log10(avg)
152
152
153 noise = dataOut.getNoise()/factor
153 noise = dataOut.getNoise()/factor
154 noisedB = 10*numpy.log10(noise)
154 noisedB = 10*numpy.log10(noise)
155
155
156 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
156 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
157 title = wintitle + " Spectra"
157 title = wintitle + " Spectra"
158 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
158 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
159 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
159 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
160
160
161 if not self.isConfig:
161 if not self.isConfig:
162
162
163 nplots = len(channelIndexList)
163 nplots = len(channelIndexList)
164
164
165 self.setup(id=id,
165 self.setup(id=id,
166 nplots=nplots,
166 nplots=nplots,
167 wintitle=wintitle,
167 wintitle=wintitle,
168 showprofile=showprofile,
168 showprofile=showprofile,
169 show=show)
169 show=show)
170
170
171 if xmin == None: xmin = numpy.nanmin(x)
171 if xmin == None: xmin = numpy.nanmin(x)
172 if xmax == None: xmax = numpy.nanmax(x)
172 if xmax == None: xmax = numpy.nanmax(x)
173 if ymin == None: ymin = numpy.nanmin(y)
173 if ymin == None: ymin = numpy.nanmin(y)
174 if ymax == None: ymax = numpy.nanmax(y)
174 if ymax == None: ymax = numpy.nanmax(y)
175 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
175 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
176 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
176 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
177
177
178 self.FTP_WEI = ftp_wei
178 self.FTP_WEI = ftp_wei
179 self.EXP_CODE = exp_code
179 self.EXP_CODE = exp_code
180 self.SUB_EXP_CODE = sub_exp_code
180 self.SUB_EXP_CODE = sub_exp_code
181 self.PLOT_POS = plot_pos
181 self.PLOT_POS = plot_pos
182
182
183 self.isConfig = True
183 self.isConfig = True
184
184
185 self.setWinTitle(title)
185 self.setWinTitle(title)
186
186
187 for i in range(self.nplots):
187 for i in range(self.nplots):
188 index = channelIndexList[i]
188 index = channelIndexList[i]
189 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
189 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
190 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
190 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
191 if len(dataOut.beam.codeList) != 0:
191 if len(dataOut.beam.codeList) != 0:
192 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
192 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
193
193
194 axes = self.axesList[i*self.__nsubplots]
194 axes = self.axesList[i*self.__nsubplots]
195 axes.pcolor(x, y, zdB[index,:,:],
195 axes.pcolor(x, y, zdB[index,:,:],
196 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
196 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
197 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
197 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
198 ticksize=9, cblabel='')
198 ticksize=9, cblabel='')
199
199
200 if self.__showprofile:
200 if self.__showprofile:
201 axes = self.axesList[i*self.__nsubplots +1]
201 axes = self.axesList[i*self.__nsubplots +1]
202 axes.pline(avgdB[index,:], y,
202 axes.pline(avgdB[index,:], y,
203 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
203 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
204 xlabel='dB', ylabel='', title='',
204 xlabel='dB', ylabel='', title='',
205 ytick_visible=False,
205 ytick_visible=False,
206 grid='x')
206 grid='x')
207
207
208 noiseline = numpy.repeat(noisedB[index], len(y))
208 noiseline = numpy.repeat(noisedB[index], len(y))
209 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
209 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
210
210
211 self.draw()
211 self.draw()
212
212
213 if figfile == None:
213 if figfile == None:
214 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
214 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
215 name = str_datetime
215 name = str_datetime
216 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
216 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
217 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
217 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
218 figfile = self.getFilename(name)
218 figfile = self.getFilename(name)
219
219
220 self.save(figpath=figpath,
220 self.save(figpath=figpath,
221 figfile=figfile,
221 figfile=figfile,
222 save=save,
222 save=save,
223 ftp=ftp,
223 ftp=ftp,
224 wr_period=wr_period,
224 wr_period=wr_period,
225 thisDatetime=thisDatetime)
225 thisDatetime=thisDatetime)
226
226
227 return dataOut
227 return dataOut
228 @MPDecorator
228 @MPDecorator
229 class CrossSpectraPlot(Figure):
229 class CrossSpectraPlot_(Figure):
230
230
231 isConfig = None
231 isConfig = None
232 __nsubplots = None
232 __nsubplots = None
233
233
234 WIDTH = None
234 WIDTH = None
235 HEIGHT = None
235 HEIGHT = None
236 WIDTHPROF = None
236 WIDTHPROF = None
237 HEIGHTPROF = None
237 HEIGHTPROF = None
238 PREFIX = 'cspc'
238 PREFIX = 'cspc'
239
239
240 def __init__(self):
240 def __init__(self):
241 Figure.__init__(self)
241 Figure.__init__(self)
242 self.isConfig = False
242 self.isConfig = False
243 self.__nsubplots = 4
243 self.__nsubplots = 4
244 self.counter_imagwr = 0
244 self.counter_imagwr = 0
245 self.WIDTH = 250
245 self.WIDTH = 250
246 self.HEIGHT = 250
246 self.HEIGHT = 250
247 self.WIDTHPROF = 0
247 self.WIDTHPROF = 0
248 self.HEIGHTPROF = 0
248 self.HEIGHTPROF = 0
249
249
250 self.PLOT_CODE = CROSS_CODE
250 self.PLOT_CODE = CROSS_CODE
251 self.FTP_WEI = None
251 self.FTP_WEI = None
252 self.EXP_CODE = None
252 self.EXP_CODE = None
253 self.SUB_EXP_CODE = None
253 self.SUB_EXP_CODE = None
254 self.PLOT_POS = None
254 self.PLOT_POS = None
255
255
256 def getSubplots(self):
256 def getSubplots(self):
257
257
258 ncol = 4
258 ncol = 4
259 nrow = self.nplots
259 nrow = self.nplots
260
260
261 return nrow, ncol
261 return nrow, ncol
262
262
263 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
263 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
264
264
265 self.__showprofile = showprofile
265 self.__showprofile = showprofile
266 self.nplots = nplots
266 self.nplots = nplots
267
267
268 ncolspan = 1
268 ncolspan = 1
269 colspan = 1
269 colspan = 1
270
270
271 self.createFigure(id = id,
271 self.createFigure(id = id,
272 wintitle = wintitle,
272 wintitle = wintitle,
273 widthplot = self.WIDTH + self.WIDTHPROF,
273 widthplot = self.WIDTH + self.WIDTHPROF,
274 heightplot = self.HEIGHT + self.HEIGHTPROF,
274 heightplot = self.HEIGHT + self.HEIGHTPROF,
275 show=True)
275 show=True)
276
276
277 nrow, ncol = self.getSubplots()
277 nrow, ncol = self.getSubplots()
278
278
279 counter = 0
279 counter = 0
280 for y in range(nrow):
280 for y in range(nrow):
281 for x in range(ncol):
281 for x in range(ncol):
282 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
282 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
283
283
284 counter += 1
284 counter += 1
285
285
286 def run(self, dataOut, id, wintitle="", pairsList=None,
286 def run(self, dataOut, id, wintitle="", pairsList=None,
287 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
287 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
288 coh_min=None, coh_max=None, phase_min=None, phase_max=None,
288 coh_min=None, coh_max=None, phase_min=None, phase_max=None,
289 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
289 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
290 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
290 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
291 server=None, folder=None, username=None, password=None,
291 server=None, folder=None, username=None, password=None,
292 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None,
292 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None,
293 xaxis='frequency'):
293 xaxis='frequency'):
294
294
295 """
295 """
296
296
297 Input:
297 Input:
298 dataOut :
298 dataOut :
299 id :
299 id :
300 wintitle :
300 wintitle :
301 channelList :
301 channelList :
302 showProfile :
302 showProfile :
303 xmin : None,
303 xmin : None,
304 xmax : None,
304 xmax : None,
305 ymin : None,
305 ymin : None,
306 ymax : None,
306 ymax : None,
307 zmin : None,
307 zmin : None,
308 zmax : None
308 zmax : None
309 """
309 """
310
310
311 if dataOut.flagNoData:
311 if dataOut.flagNoData:
312 return dataOut
312 return dataOut
313
313
314 if pairsList == None:
314 if pairsList == None:
315 pairsIndexList = dataOut.pairsIndexList
315 pairsIndexList = dataOut.pairsIndexList
316 else:
316 else:
317 pairsIndexList = []
317 pairsIndexList = []
318 for pair in pairsList:
318 for pair in pairsList:
319 if pair not in dataOut.pairsList:
319 if pair not in dataOut.pairsList:
320 raise ValueError("Pair %s is not in dataOut.pairsList" %str(pair))
320 raise ValueError("Pair %s is not in dataOut.pairsList" %str(pair))
321 pairsIndexList.append(dataOut.pairsList.index(pair))
321 pairsIndexList.append(dataOut.pairsList.index(pair))
322
322
323 if not pairsIndexList:
323 if not pairsIndexList:
324 return
324 return
325
325
326 if len(pairsIndexList) > 4:
326 if len(pairsIndexList) > 4:
327 pairsIndexList = pairsIndexList[0:4]
327 pairsIndexList = pairsIndexList[0:4]
328
328
329 if normFactor is None:
329 if normFactor is None:
330 factor = dataOut.normFactor
330 factor = dataOut.normFactor
331 else:
331 else:
332 factor = normFactor
332 factor = normFactor
333 x = dataOut.getVelRange(1)
333 x = dataOut.getVelRange(1)
334 y = dataOut.getHeiRange()
334 y = dataOut.getHeiRange()
335 z = dataOut.data_spc[:,:,:]/factor
335 z = dataOut.data_spc[:,:,:]/factor
336 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
336 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
337
337
338 noise = dataOut.noise/factor
338 noise = dataOut.noise/factor
339
339
340 zdB = 10*numpy.log10(z)
340 zdB = 10*numpy.log10(z)
341 noisedB = 10*numpy.log10(noise)
341 noisedB = 10*numpy.log10(noise)
342
342
343 if coh_min == None:
343 if coh_min == None:
344 coh_min = 0.0
344 coh_min = 0.0
345 if coh_max == None:
345 if coh_max == None:
346 coh_max = 1.0
346 coh_max = 1.0
347
347
348 if phase_min == None:
348 if phase_min == None:
349 phase_min = -180
349 phase_min = -180
350 if phase_max == None:
350 if phase_max == None:
351 phase_max = 180
351 phase_max = 180
352
352
353 #thisDatetime = dataOut.datatime
353 #thisDatetime = dataOut.datatime
354 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
354 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
355 title = wintitle + " Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
355 title = wintitle + " Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
356 # xlabel = "Velocity (m/s)"
356 # xlabel = "Velocity (m/s)"
357 ylabel = "Range (Km)"
357 ylabel = "Range (Km)"
358
358
359 if xaxis == "frequency":
359 if xaxis == "frequency":
360 x = dataOut.getFreqRange(1)/1000.
360 x = dataOut.getFreqRange(1)/1000.
361 xlabel = "Frequency (kHz)"
361 xlabel = "Frequency (kHz)"
362
362
363 elif xaxis == "time":
363 elif xaxis == "time":
364 x = dataOut.getAcfRange(1)
364 x = dataOut.getAcfRange(1)
365 xlabel = "Time (ms)"
365 xlabel = "Time (ms)"
366
366
367 else:
367 else:
368 x = dataOut.getVelRange(1)
368 x = dataOut.getVelRange(1)
369 xlabel = "Velocity (m/s)"
369 xlabel = "Velocity (m/s)"
370
370
371 if not self.isConfig:
371 if not self.isConfig:
372
372
373 nplots = len(pairsIndexList)
373 nplots = len(pairsIndexList)
374
374
375 self.setup(id=id,
375 self.setup(id=id,
376 nplots=nplots,
376 nplots=nplots,
377 wintitle=wintitle,
377 wintitle=wintitle,
378 showprofile=False,
378 showprofile=False,
379 show=show)
379 show=show)
380
380
381 avg = numpy.abs(numpy.average(z, axis=1))
381 avg = numpy.abs(numpy.average(z, axis=1))
382 avgdB = 10*numpy.log10(avg)
382 avgdB = 10*numpy.log10(avg)
383
383
384 if xmin == None: xmin = numpy.nanmin(x)
384 if xmin == None: xmin = numpy.nanmin(x)
385 if xmax == None: xmax = numpy.nanmax(x)
385 if xmax == None: xmax = numpy.nanmax(x)
386 if ymin == None: ymin = numpy.nanmin(y)
386 if ymin == None: ymin = numpy.nanmin(y)
387 if ymax == None: ymax = numpy.nanmax(y)
387 if ymax == None: ymax = numpy.nanmax(y)
388 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
388 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
389 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
389 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
390
390
391 self.FTP_WEI = ftp_wei
391 self.FTP_WEI = ftp_wei
392 self.EXP_CODE = exp_code
392 self.EXP_CODE = exp_code
393 self.SUB_EXP_CODE = sub_exp_code
393 self.SUB_EXP_CODE = sub_exp_code
394 self.PLOT_POS = plot_pos
394 self.PLOT_POS = plot_pos
395
395
396 self.isConfig = True
396 self.isConfig = True
397
397
398 self.setWinTitle(title)
398 self.setWinTitle(title)
399
399
400 for i in range(self.nplots):
400 for i in range(self.nplots):
401 pair = dataOut.pairsList[pairsIndexList[i]]
401 pair = dataOut.pairsList[pairsIndexList[i]]
402
402
403 chan_index0 = dataOut.channelList.index(pair[0])
403 chan_index0 = dataOut.channelList.index(pair[0])
404 chan_index1 = dataOut.channelList.index(pair[1])
404 chan_index1 = dataOut.channelList.index(pair[1])
405
405
406 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
406 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
407 title = "Ch%d: %4.2fdB: %s" %(pair[0], noisedB[chan_index0], str_datetime)
407 title = "Ch%d: %4.2fdB: %s" %(pair[0], noisedB[chan_index0], str_datetime)
408 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index0,:,:]/factor)
408 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index0,:,:]/factor)
409 axes0 = self.axesList[i*self.__nsubplots]
409 axes0 = self.axesList[i*self.__nsubplots]
410 axes0.pcolor(x, y, zdB,
410 axes0.pcolor(x, y, zdB,
411 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
411 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
412 xlabel=xlabel, ylabel=ylabel, title=title,
412 xlabel=xlabel, ylabel=ylabel, title=title,
413 ticksize=9, colormap=power_cmap, cblabel='')
413 ticksize=9, colormap=power_cmap, cblabel='')
414
414
415 title = "Ch%d: %4.2fdB: %s" %(pair[1], noisedB[chan_index1], str_datetime)
415 title = "Ch%d: %4.2fdB: %s" %(pair[1], noisedB[chan_index1], str_datetime)
416 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index1,:,:]/factor)
416 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index1,:,:]/factor)
417 axes0 = self.axesList[i*self.__nsubplots+1]
417 axes0 = self.axesList[i*self.__nsubplots+1]
418 axes0.pcolor(x, y, zdB,
418 axes0.pcolor(x, y, zdB,
419 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
419 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
420 xlabel=xlabel, ylabel=ylabel, title=title,
420 xlabel=xlabel, ylabel=ylabel, title=title,
421 ticksize=9, colormap=power_cmap, cblabel='')
421 ticksize=9, colormap=power_cmap, cblabel='')
422
422
423 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[chan_index0,:,:]*dataOut.data_spc[chan_index1,:,:])
423 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[chan_index0,:,:]*dataOut.data_spc[chan_index1,:,:])
424 coherence = numpy.abs(coherenceComplex)
424 coherence = numpy.abs(coherenceComplex)
425 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
425 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
426 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
426 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
427
427
428 title = "Coherence Ch%d * Ch%d" %(pair[0], pair[1])
428 title = "Coherence Ch%d * Ch%d" %(pair[0], pair[1])
429 axes0 = self.axesList[i*self.__nsubplots+2]
429 axes0 = self.axesList[i*self.__nsubplots+2]
430 axes0.pcolor(x, y, coherence,
430 axes0.pcolor(x, y, coherence,
431 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=coh_min, zmax=coh_max,
431 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=coh_min, zmax=coh_max,
432 xlabel=xlabel, ylabel=ylabel, title=title,
432 xlabel=xlabel, ylabel=ylabel, title=title,
433 ticksize=9, colormap=coherence_cmap, cblabel='')
433 ticksize=9, colormap=coherence_cmap, cblabel='')
434
434
435 title = "Phase Ch%d * Ch%d" %(pair[0], pair[1])
435 title = "Phase Ch%d * Ch%d" %(pair[0], pair[1])
436 axes0 = self.axesList[i*self.__nsubplots+3]
436 axes0 = self.axesList[i*self.__nsubplots+3]
437 axes0.pcolor(x, y, phase,
437 axes0.pcolor(x, y, phase,
438 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
438 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
439 xlabel=xlabel, ylabel=ylabel, title=title,
439 xlabel=xlabel, ylabel=ylabel, title=title,
440 ticksize=9, colormap=phase_cmap, cblabel='')
440 ticksize=9, colormap=phase_cmap, cblabel='')
441
441
442
442
443
443
444 self.draw()
444 self.draw()
445
445
446 self.save(figpath=figpath,
446 self.save(figpath=figpath,
447 figfile=figfile,
447 figfile=figfile,
448 save=save,
448 save=save,
449 ftp=ftp,
449 ftp=ftp,
450 wr_period=wr_period,
450 wr_period=wr_period,
451 thisDatetime=thisDatetime)
451 thisDatetime=thisDatetime)
452
452
453 return dataOut
453 return dataOut
454
454
455 @MPDecorator
455 @MPDecorator
456 class RTIPlot(Figure):
456 class RTIPlot_(Figure):
457
457
458 __isConfig = None
458 __isConfig = None
459 __nsubplots = None
459 __nsubplots = None
460
460
461 WIDTHPROF = None
461 WIDTHPROF = None
462 HEIGHTPROF = None
462 HEIGHTPROF = None
463 PREFIX = 'rti'
463 PREFIX = 'rti'
464
464
465 def __init__(self):
465 def __init__(self):
466
466
467 Figure.__init__(self)
467 Figure.__init__(self)
468 self.timerange = None
468 self.timerange = None
469 self.isConfig = False
469 self.isConfig = False
470 self.__nsubplots = 1
470 self.__nsubplots = 1
471
471
472 self.WIDTH = 800
472 self.WIDTH = 800
473 self.HEIGHT = 180
473 self.HEIGHT = 180
474 self.WIDTHPROF = 120
474 self.WIDTHPROF = 120
475 self.HEIGHTPROF = 0
475 self.HEIGHTPROF = 0
476 self.counter_imagwr = 0
476 self.counter_imagwr = 0
477
477
478 self.PLOT_CODE = RTI_CODE
478 self.PLOT_CODE = RTI_CODE
479
479
480 self.FTP_WEI = None
480 self.FTP_WEI = None
481 self.EXP_CODE = None
481 self.EXP_CODE = None
482 self.SUB_EXP_CODE = None
482 self.SUB_EXP_CODE = None
483 self.PLOT_POS = None
483 self.PLOT_POS = None
484 self.tmin = None
484 self.tmin = None
485 self.tmax = None
485 self.tmax = None
486
486
487 self.xmin = None
487 self.xmin = None
488 self.xmax = None
488 self.xmax = None
489
489
490 self.figfile = None
490 self.figfile = None
491
491
492 def getSubplots(self):
492 def getSubplots(self):
493
493
494 ncol = 1
494 ncol = 1
495 nrow = self.nplots
495 nrow = self.nplots
496
496
497 return nrow, ncol
497 return nrow, ncol
498
498
499 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
499 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
500
500
501 self.__showprofile = showprofile
501 self.__showprofile = showprofile
502 self.nplots = nplots
502 self.nplots = nplots
503
503
504 ncolspan = 1
504 ncolspan = 1
505 colspan = 1
505 colspan = 1
506 if showprofile:
506 if showprofile:
507 ncolspan = 7
507 ncolspan = 7
508 colspan = 6
508 colspan = 6
509 self.__nsubplots = 2
509 self.__nsubplots = 2
510
510
511 self.createFigure(id = id,
511 self.createFigure(id = id,
512 wintitle = wintitle,
512 wintitle = wintitle,
513 widthplot = self.WIDTH + self.WIDTHPROF,
513 widthplot = self.WIDTH + self.WIDTHPROF,
514 heightplot = self.HEIGHT + self.HEIGHTPROF,
514 heightplot = self.HEIGHT + self.HEIGHTPROF,
515 show=show)
515 show=show)
516
516
517 nrow, ncol = self.getSubplots()
517 nrow, ncol = self.getSubplots()
518
518
519 counter = 0
519 counter = 0
520 for y in range(nrow):
520 for y in range(nrow):
521 for x in range(ncol):
521 for x in range(ncol):
522
522
523 if counter >= self.nplots:
523 if counter >= self.nplots:
524 break
524 break
525
525
526 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
526 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
527
527
528 if showprofile:
528 if showprofile:
529 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
529 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
530
530
531 counter += 1
531 counter += 1
532
532
533 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
533 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
534 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
534 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
535 timerange=None, colormap='jet',
535 timerange=None, colormap='jet',
536 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
536 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
537 server=None, folder=None, username=None, password=None,
537 server=None, folder=None, username=None, password=None,
538 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None, HEIGHT=None):
538 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None, HEIGHT=None):
539
539
540 """
540 """
541
541
542 Input:
542 Input:
543 dataOut :
543 dataOut :
544 id :
544 id :
545 wintitle :
545 wintitle :
546 channelList :
546 channelList :
547 showProfile :
547 showProfile :
548 xmin : None,
548 xmin : None,
549 xmax : None,
549 xmax : None,
550 ymin : None,
550 ymin : None,
551 ymax : None,
551 ymax : None,
552 zmin : None,
552 zmin : None,
553 zmax : None
553 zmax : None
554 """
554 """
555 if dataOut.flagNoData:
555 if dataOut.flagNoData:
556 return dataOut
556 return dataOut
557
557
558 #colormap = kwargs.get('colormap', 'jet')
558 #colormap = kwargs.get('colormap', 'jet')
559 if HEIGHT is not None:
559 if HEIGHT is not None:
560 self.HEIGHT = HEIGHT
560 self.HEIGHT = HEIGHT
561
561
562 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
562 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
563 return
563 return
564
564
565 if channelList == None:
565 if channelList == None:
566 channelIndexList = dataOut.channelIndexList
566 channelIndexList = dataOut.channelIndexList
567 else:
567 else:
568 channelIndexList = []
568 channelIndexList = []
569 for channel in channelList:
569 for channel in channelList:
570 if channel not in dataOut.channelList:
570 if channel not in dataOut.channelList:
571 raise ValueError("Channel %d is not in dataOut.channelList")
571 raise ValueError("Channel %d is not in dataOut.channelList")
572 channelIndexList.append(dataOut.channelList.index(channel))
572 channelIndexList.append(dataOut.channelList.index(channel))
573
573
574 if normFactor is None:
574 if normFactor is None:
575 factor = dataOut.normFactor
575 factor = dataOut.normFactor
576 else:
576 else:
577 factor = normFactor
577 factor = normFactor
578
578
579 #factor = dataOut.normFactor
579 #factor = dataOut.normFactor
580 x = dataOut.getTimeRange()
580 x = dataOut.getTimeRange()
581 y = dataOut.getHeiRange()
581 y = dataOut.getHeiRange()
582
582
583 z = dataOut.data_spc/factor
583 z = dataOut.data_spc/factor
584 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
584 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
585 avg = numpy.average(z, axis=1)
585 avg = numpy.average(z, axis=1)
586 avgdB = 10.*numpy.log10(avg)
586 avgdB = 10.*numpy.log10(avg)
587 # avgdB = dataOut.getPower()
587 # avgdB = dataOut.getPower()
588
588
589
589
590 thisDatetime = dataOut.datatime
590 thisDatetime = dataOut.datatime
591 #thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
591 #thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
592 title = wintitle + " RTI" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
592 title = wintitle + " RTI" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
593 xlabel = ""
593 xlabel = ""
594 ylabel = "Range (Km)"
594 ylabel = "Range (Km)"
595
595
596 update_figfile = False
596 update_figfile = False
597
597
598 if self.xmax is not None and dataOut.ltctime >= self.xmax: #yong
598 if self.xmax is not None and dataOut.ltctime >= self.xmax: #yong
599 self.counter_imagwr = wr_period
599 self.counter_imagwr = wr_period
600 self.isConfig = False
600 self.isConfig = False
601 update_figfile = True
601 update_figfile = True
602
602
603 if not self.isConfig:
603 if not self.isConfig:
604
604
605 nplots = len(channelIndexList)
605 nplots = len(channelIndexList)
606
606
607 self.setup(id=id,
607 self.setup(id=id,
608 nplots=nplots,
608 nplots=nplots,
609 wintitle=wintitle,
609 wintitle=wintitle,
610 showprofile=showprofile,
610 showprofile=showprofile,
611 show=show)
611 show=show)
612
612
613 if timerange != None:
613 if timerange != None:
614 self.timerange = timerange
614 self.timerange = timerange
615
615
616 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
616 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
617
617
618 noise = dataOut.noise/factor
618 noise = dataOut.noise/factor
619 noisedB = 10*numpy.log10(noise)
619 noisedB = 10*numpy.log10(noise)
620
620
621 if ymin == None: ymin = numpy.nanmin(y)
621 if ymin == None: ymin = numpy.nanmin(y)
622 if ymax == None: ymax = numpy.nanmax(y)
622 if ymax == None: ymax = numpy.nanmax(y)
623 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
623 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
624 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
624 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
625
625
626 self.FTP_WEI = ftp_wei
626 self.FTP_WEI = ftp_wei
627 self.EXP_CODE = exp_code
627 self.EXP_CODE = exp_code
628 self.SUB_EXP_CODE = sub_exp_code
628 self.SUB_EXP_CODE = sub_exp_code
629 self.PLOT_POS = plot_pos
629 self.PLOT_POS = plot_pos
630
630
631 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
631 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
632 self.isConfig = True
632 self.isConfig = True
633 self.figfile = figfile
633 self.figfile = figfile
634 update_figfile = True
634 update_figfile = True
635
635
636 self.setWinTitle(title)
636 self.setWinTitle(title)
637
637
638 for i in range(self.nplots):
638 for i in range(self.nplots):
639 index = channelIndexList[i]
639 index = channelIndexList[i]
640 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
640 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
641 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
641 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
642 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
642 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
643 axes = self.axesList[i*self.__nsubplots]
643 axes = self.axesList[i*self.__nsubplots]
644 zdB = avgdB[index].reshape((1,-1))
644 zdB = avgdB[index].reshape((1,-1))
645 axes.pcolorbuffer(x, y, zdB,
645 axes.pcolorbuffer(x, y, zdB,
646 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
646 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
647 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
647 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
648 ticksize=9, cblabel='', cbsize="1%", colormap=colormap)
648 ticksize=9, cblabel='', cbsize="1%", colormap=colormap)
649
649
650 if self.__showprofile:
650 if self.__showprofile:
651 axes = self.axesList[i*self.__nsubplots +1]
651 axes = self.axesList[i*self.__nsubplots +1]
652 axes.pline(avgdB[index], y,
652 axes.pline(avgdB[index], y,
653 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
653 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
654 xlabel='dB', ylabel='', title='',
654 xlabel='dB', ylabel='', title='',
655 ytick_visible=False,
655 ytick_visible=False,
656 grid='x')
656 grid='x')
657
657
658 self.draw()
658 self.draw()
659
659
660 self.save(figpath=figpath,
660 self.save(figpath=figpath,
661 figfile=figfile,
661 figfile=figfile,
662 save=save,
662 save=save,
663 ftp=ftp,
663 ftp=ftp,
664 wr_period=wr_period,
664 wr_period=wr_period,
665 thisDatetime=thisDatetime,
665 thisDatetime=thisDatetime,
666 update_figfile=update_figfile)
666 update_figfile=update_figfile)
667 return dataOut
667 return dataOut
668
668
669 @MPDecorator
669 @MPDecorator
670 class CoherenceMap(Figure):
670 class CoherenceMap_(Figure):
671 isConfig = None
671 isConfig = None
672 __nsubplots = None
672 __nsubplots = None
673
673
674 WIDTHPROF = None
674 WIDTHPROF = None
675 HEIGHTPROF = None
675 HEIGHTPROF = None
676 PREFIX = 'cmap'
676 PREFIX = 'cmap'
677
677
678 def __init__(self):
678 def __init__(self):
679 Figure.__init__(self)
679 Figure.__init__(self)
680 self.timerange = 2*60*60
680 self.timerange = 2*60*60
681 self.isConfig = False
681 self.isConfig = False
682 self.__nsubplots = 1
682 self.__nsubplots = 1
683
683
684 self.WIDTH = 800
684 self.WIDTH = 800
685 self.HEIGHT = 180
685 self.HEIGHT = 180
686 self.WIDTHPROF = 120
686 self.WIDTHPROF = 120
687 self.HEIGHTPROF = 0
687 self.HEIGHTPROF = 0
688 self.counter_imagwr = 0
688 self.counter_imagwr = 0
689
689
690 self.PLOT_CODE = COH_CODE
690 self.PLOT_CODE = COH_CODE
691
691
692 self.FTP_WEI = None
692 self.FTP_WEI = None
693 self.EXP_CODE = None
693 self.EXP_CODE = None
694 self.SUB_EXP_CODE = None
694 self.SUB_EXP_CODE = None
695 self.PLOT_POS = None
695 self.PLOT_POS = None
696 self.counter_imagwr = 0
696 self.counter_imagwr = 0
697
697
698 self.xmin = None
698 self.xmin = None
699 self.xmax = None
699 self.xmax = None
700
700
701 def getSubplots(self):
701 def getSubplots(self):
702 ncol = 1
702 ncol = 1
703 nrow = self.nplots*2
703 nrow = self.nplots*2
704
704
705 return nrow, ncol
705 return nrow, ncol
706
706
707 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
707 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
708 self.__showprofile = showprofile
708 self.__showprofile = showprofile
709 self.nplots = nplots
709 self.nplots = nplots
710
710
711 ncolspan = 1
711 ncolspan = 1
712 colspan = 1
712 colspan = 1
713 if showprofile:
713 if showprofile:
714 ncolspan = 7
714 ncolspan = 7
715 colspan = 6
715 colspan = 6
716 self.__nsubplots = 2
716 self.__nsubplots = 2
717
717
718 self.createFigure(id = id,
718 self.createFigure(id = id,
719 wintitle = wintitle,
719 wintitle = wintitle,
720 widthplot = self.WIDTH + self.WIDTHPROF,
720 widthplot = self.WIDTH + self.WIDTHPROF,
721 heightplot = self.HEIGHT + self.HEIGHTPROF,
721 heightplot = self.HEIGHT + self.HEIGHTPROF,
722 show=True)
722 show=True)
723
723
724 nrow, ncol = self.getSubplots()
724 nrow, ncol = self.getSubplots()
725
725
726 for y in range(nrow):
726 for y in range(nrow):
727 for x in range(ncol):
727 for x in range(ncol):
728
728
729 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
729 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
730
730
731 if showprofile:
731 if showprofile:
732 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
732 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
733
733
734 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
734 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
735 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
735 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
736 timerange=None, phase_min=None, phase_max=None,
736 timerange=None, phase_min=None, phase_max=None,
737 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
737 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
738 coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
738 coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
739 server=None, folder=None, username=None, password=None,
739 server=None, folder=None, username=None, password=None,
740 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
740 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
741
741
742
742
743 if dataOut.flagNoData:
743 if dataOut.flagNoData:
744 return dataOut
744 return dataOut
745
745
746 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
746 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
747 return
747 return
748
748
749 if pairsList == None:
749 if pairsList == None:
750 pairsIndexList = dataOut.pairsIndexList
750 pairsIndexList = dataOut.pairsIndexList
751 else:
751 else:
752 pairsIndexList = []
752 pairsIndexList = []
753 for pair in pairsList:
753 for pair in pairsList:
754 if pair not in dataOut.pairsList:
754 if pair not in dataOut.pairsList:
755 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
755 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
756 pairsIndexList.append(dataOut.pairsList.index(pair))
756 pairsIndexList.append(dataOut.pairsList.index(pair))
757
757
758 if pairsIndexList == []:
758 if pairsIndexList == []:
759 return
759 return
760
760
761 if len(pairsIndexList) > 4:
761 if len(pairsIndexList) > 4:
762 pairsIndexList = pairsIndexList[0:4]
762 pairsIndexList = pairsIndexList[0:4]
763
763
764 if phase_min == None:
764 if phase_min == None:
765 phase_min = -180
765 phase_min = -180
766 if phase_max == None:
766 if phase_max == None:
767 phase_max = 180
767 phase_max = 180
768
768
769 x = dataOut.getTimeRange()
769 x = dataOut.getTimeRange()
770 y = dataOut.getHeiRange()
770 y = dataOut.getHeiRange()
771
771
772 thisDatetime = dataOut.datatime
772 thisDatetime = dataOut.datatime
773
773
774 title = wintitle + " CoherenceMap" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
774 title = wintitle + " CoherenceMap" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
775 xlabel = ""
775 xlabel = ""
776 ylabel = "Range (Km)"
776 ylabel = "Range (Km)"
777 update_figfile = False
777 update_figfile = False
778
778
779 if not self.isConfig:
779 if not self.isConfig:
780 nplots = len(pairsIndexList)
780 nplots = len(pairsIndexList)
781 self.setup(id=id,
781 self.setup(id=id,
782 nplots=nplots,
782 nplots=nplots,
783 wintitle=wintitle,
783 wintitle=wintitle,
784 showprofile=showprofile,
784 showprofile=showprofile,
785 show=show)
785 show=show)
786
786
787 if timerange != None:
787 if timerange != None:
788 self.timerange = timerange
788 self.timerange = timerange
789
789
790 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
790 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
791
791
792 if ymin == None: ymin = numpy.nanmin(y)
792 if ymin == None: ymin = numpy.nanmin(y)
793 if ymax == None: ymax = numpy.nanmax(y)
793 if ymax == None: ymax = numpy.nanmax(y)
794 if zmin == None: zmin = 0.
794 if zmin == None: zmin = 0.
795 if zmax == None: zmax = 1.
795 if zmax == None: zmax = 1.
796
796
797 self.FTP_WEI = ftp_wei
797 self.FTP_WEI = ftp_wei
798 self.EXP_CODE = exp_code
798 self.EXP_CODE = exp_code
799 self.SUB_EXP_CODE = sub_exp_code
799 self.SUB_EXP_CODE = sub_exp_code
800 self.PLOT_POS = plot_pos
800 self.PLOT_POS = plot_pos
801
801
802 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
802 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
803
803
804 self.isConfig = True
804 self.isConfig = True
805 update_figfile = True
805 update_figfile = True
806
806
807 self.setWinTitle(title)
807 self.setWinTitle(title)
808
808
809 for i in range(self.nplots):
809 for i in range(self.nplots):
810
810
811 pair = dataOut.pairsList[pairsIndexList[i]]
811 pair = dataOut.pairsList[pairsIndexList[i]]
812
812
813 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i],:,:],axis=0)
813 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i],:,:],axis=0)
814 powa = numpy.average(dataOut.data_spc[pair[0],:,:],axis=0)
814 powa = numpy.average(dataOut.data_spc[pair[0],:,:],axis=0)
815 powb = numpy.average(dataOut.data_spc[pair[1],:,:],axis=0)
815 powb = numpy.average(dataOut.data_spc[pair[1],:,:],axis=0)
816
816
817
817
818 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
818 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
819 coherence = numpy.abs(avgcoherenceComplex)
819 coherence = numpy.abs(avgcoherenceComplex)
820
820
821 z = coherence.reshape((1,-1))
821 z = coherence.reshape((1,-1))
822
822
823 counter = 0
823 counter = 0
824
824
825 title = "Coherence Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
825 title = "Coherence Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
826 axes = self.axesList[i*self.__nsubplots*2]
826 axes = self.axesList[i*self.__nsubplots*2]
827 axes.pcolorbuffer(x, y, z,
827 axes.pcolorbuffer(x, y, z,
828 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
828 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
829 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
829 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
830 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
830 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
831
831
832 if self.__showprofile:
832 if self.__showprofile:
833 counter += 1
833 counter += 1
834 axes = self.axesList[i*self.__nsubplots*2 + counter]
834 axes = self.axesList[i*self.__nsubplots*2 + counter]
835 axes.pline(coherence, y,
835 axes.pline(coherence, y,
836 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
836 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
837 xlabel='', ylabel='', title='', ticksize=7,
837 xlabel='', ylabel='', title='', ticksize=7,
838 ytick_visible=False, nxticks=5,
838 ytick_visible=False, nxticks=5,
839 grid='x')
839 grid='x')
840
840
841 counter += 1
841 counter += 1
842
842
843 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
843 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
844
844
845 z = phase.reshape((1,-1))
845 z = phase.reshape((1,-1))
846
846
847 title = "Phase Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
847 title = "Phase Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
848 axes = self.axesList[i*self.__nsubplots*2 + counter]
848 axes = self.axesList[i*self.__nsubplots*2 + counter]
849 axes.pcolorbuffer(x, y, z,
849 axes.pcolorbuffer(x, y, z,
850 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
850 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
851 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
851 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
852 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
852 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
853
853
854 if self.__showprofile:
854 if self.__showprofile:
855 counter += 1
855 counter += 1
856 axes = self.axesList[i*self.__nsubplots*2 + counter]
856 axes = self.axesList[i*self.__nsubplots*2 + counter]
857 axes.pline(phase, y,
857 axes.pline(phase, y,
858 xmin=phase_min, xmax=phase_max, ymin=ymin, ymax=ymax,
858 xmin=phase_min, xmax=phase_max, ymin=ymin, ymax=ymax,
859 xlabel='', ylabel='', title='', ticksize=7,
859 xlabel='', ylabel='', title='', ticksize=7,
860 ytick_visible=False, nxticks=4,
860 ytick_visible=False, nxticks=4,
861 grid='x')
861 grid='x')
862
862
863 self.draw()
863 self.draw()
864
864
865 if dataOut.ltctime >= self.xmax:
865 if dataOut.ltctime >= self.xmax:
866 self.counter_imagwr = wr_period
866 self.counter_imagwr = wr_period
867 self.isConfig = False
867 self.isConfig = False
868 update_figfile = True
868 update_figfile = True
869
869
870 self.save(figpath=figpath,
870 self.save(figpath=figpath,
871 figfile=figfile,
871 figfile=figfile,
872 save=save,
872 save=save,
873 ftp=ftp,
873 ftp=ftp,
874 wr_period=wr_period,
874 wr_period=wr_period,
875 thisDatetime=thisDatetime,
875 thisDatetime=thisDatetime,
876 update_figfile=update_figfile)
876 update_figfile=update_figfile)
877
877
878 return dataOut
878 return dataOut
879
879
880 @MPDecorator
880 @MPDecorator
881 class PowerProfilePlot(Figure):
881 class PowerProfilePlot_(Figure):
882
882
883 isConfig = None
883 isConfig = None
884 __nsubplots = None
884 __nsubplots = None
885
885
886 WIDTHPROF = None
886 WIDTHPROF = None
887 HEIGHTPROF = None
887 HEIGHTPROF = None
888 PREFIX = 'spcprofile'
888 PREFIX = 'spcprofile'
889
889
890 def __init__(self):
890 def __init__(self):
891 Figure.__init__(self)
891 Figure.__init__(self)
892 self.isConfig = False
892 self.isConfig = False
893 self.__nsubplots = 1
893 self.__nsubplots = 1
894
894
895 self.PLOT_CODE = POWER_CODE
895 self.PLOT_CODE = POWER_CODE
896
896
897 self.WIDTH = 300
897 self.WIDTH = 300
898 self.HEIGHT = 500
898 self.HEIGHT = 500
899 self.counter_imagwr = 0
899 self.counter_imagwr = 0
900
900
901 def getSubplots(self):
901 def getSubplots(self):
902 ncol = 1
902 ncol = 1
903 nrow = 1
903 nrow = 1
904
904
905 return nrow, ncol
905 return nrow, ncol
906
906
907 def setup(self, id, nplots, wintitle, show):
907 def setup(self, id, nplots, wintitle, show):
908
908
909 self.nplots = nplots
909 self.nplots = nplots
910
910
911 ncolspan = 1
911 ncolspan = 1
912 colspan = 1
912 colspan = 1
913
913
914 self.createFigure(id = id,
914 self.createFigure(id = id,
915 wintitle = wintitle,
915 wintitle = wintitle,
916 widthplot = self.WIDTH,
916 widthplot = self.WIDTH,
917 heightplot = self.HEIGHT,
917 heightplot = self.HEIGHT,
918 show=show)
918 show=show)
919
919
920 nrow, ncol = self.getSubplots()
920 nrow, ncol = self.getSubplots()
921
921
922 counter = 0
922 counter = 0
923 for y in range(nrow):
923 for y in range(nrow):
924 for x in range(ncol):
924 for x in range(ncol):
925 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
925 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
926
926
927 def run(self, dataOut, id, wintitle="", channelList=None,
927 def run(self, dataOut, id, wintitle="", channelList=None,
928 xmin=None, xmax=None, ymin=None, ymax=None,
928 xmin=None, xmax=None, ymin=None, ymax=None,
929 save=False, figpath='./', figfile=None, show=True,
929 save=False, figpath='./', figfile=None, show=True,
930 ftp=False, wr_period=1, server=None,
930 ftp=False, wr_period=1, server=None,
931 folder=None, username=None, password=None):
931 folder=None, username=None, password=None):
932
932
933 if dataOut.flagNoData:
933 if dataOut.flagNoData:
934 return dataOut
934 return dataOut
935
935
936
936
937 if channelList == None:
937 if channelList == None:
938 channelIndexList = dataOut.channelIndexList
938 channelIndexList = dataOut.channelIndexList
939 channelList = dataOut.channelList
939 channelList = dataOut.channelList
940 else:
940 else:
941 channelIndexList = []
941 channelIndexList = []
942 for channel in channelList:
942 for channel in channelList:
943 if channel not in dataOut.channelList:
943 if channel not in dataOut.channelList:
944 raise ValueError("Channel %d is not in dataOut.channelList")
944 raise ValueError("Channel %d is not in dataOut.channelList")
945 channelIndexList.append(dataOut.channelList.index(channel))
945 channelIndexList.append(dataOut.channelList.index(channel))
946
946
947 factor = dataOut.normFactor
947 factor = dataOut.normFactor
948
948
949 y = dataOut.getHeiRange()
949 y = dataOut.getHeiRange()
950
950
951 #for voltage
951 #for voltage
952 if dataOut.type == 'Voltage':
952 if dataOut.type == 'Voltage':
953 x = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
953 x = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
954 x = x.real
954 x = x.real
955 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
955 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
956
956
957 #for spectra
957 #for spectra
958 if dataOut.type == 'Spectra':
958 if dataOut.type == 'Spectra':
959 x = dataOut.data_spc[channelIndexList,:,:]/factor
959 x = dataOut.data_spc[channelIndexList,:,:]/factor
960 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
960 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
961 x = numpy.average(x, axis=1)
961 x = numpy.average(x, axis=1)
962
962
963
963
964 xdB = 10*numpy.log10(x)
964 xdB = 10*numpy.log10(x)
965
965
966 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
966 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
967 title = wintitle + " Power Profile %s" %(thisDatetime.strftime("%d-%b-%Y"))
967 title = wintitle + " Power Profile %s" %(thisDatetime.strftime("%d-%b-%Y"))
968 xlabel = "dB"
968 xlabel = "dB"
969 ylabel = "Range (Km)"
969 ylabel = "Range (Km)"
970
970
971 if not self.isConfig:
971 if not self.isConfig:
972
972
973 nplots = 1
973 nplots = 1
974
974
975 self.setup(id=id,
975 self.setup(id=id,
976 nplots=nplots,
976 nplots=nplots,
977 wintitle=wintitle,
977 wintitle=wintitle,
978 show=show)
978 show=show)
979
979
980 if ymin == None: ymin = numpy.nanmin(y)
980 if ymin == None: ymin = numpy.nanmin(y)
981 if ymax == None: ymax = numpy.nanmax(y)
981 if ymax == None: ymax = numpy.nanmax(y)
982 if xmin == None: xmin = numpy.nanmin(xdB)*0.9
982 if xmin == None: xmin = numpy.nanmin(xdB)*0.9
983 if xmax == None: xmax = numpy.nanmax(xdB)*1.1
983 if xmax == None: xmax = numpy.nanmax(xdB)*1.1
984
984
985 self.isConfig = True
985 self.isConfig = True
986
986
987 self.setWinTitle(title)
987 self.setWinTitle(title)
988
988
989 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
989 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
990 axes = self.axesList[0]
990 axes = self.axesList[0]
991
991
992 legendlabels = ["channel %d"%x for x in channelList]
992 legendlabels = ["channel %d"%x for x in channelList]
993 axes.pmultiline(xdB, y,
993 axes.pmultiline(xdB, y,
994 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
994 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
995 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
995 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
996 ytick_visible=True, nxticks=5,
996 ytick_visible=True, nxticks=5,
997 grid='x')
997 grid='x')
998
998
999 self.draw()
999 self.draw()
1000
1000
1001 self.save(figpath=figpath,
1001 self.save(figpath=figpath,
1002 figfile=figfile,
1002 figfile=figfile,
1003 save=save,
1003 save=save,
1004 ftp=ftp,
1004 ftp=ftp,
1005 wr_period=wr_period,
1005 wr_period=wr_period,
1006 thisDatetime=thisDatetime)
1006 thisDatetime=thisDatetime)
1007
1007
1008 return dataOut
1008 return dataOut
1009
1009
1010 @MPDecorator
1010 @MPDecorator
1011 class SpectraCutPlot(Figure):
1011 class SpectraCutPlot_(Figure):
1012
1012
1013 isConfig = None
1013 isConfig = None
1014 __nsubplots = None
1014 __nsubplots = None
1015
1015
1016 WIDTHPROF = None
1016 WIDTHPROF = None
1017 HEIGHTPROF = None
1017 HEIGHTPROF = None
1018 PREFIX = 'spc_cut'
1018 PREFIX = 'spc_cut'
1019
1019
1020 def __init__(self):
1020 def __init__(self):
1021 Figure.__init__(self)
1021 Figure.__init__(self)
1022 self.isConfig = False
1022 self.isConfig = False
1023 self.__nsubplots = 1
1023 self.__nsubplots = 1
1024
1024
1025 self.PLOT_CODE = POWER_CODE
1025 self.PLOT_CODE = POWER_CODE
1026
1026
1027 self.WIDTH = 700
1027 self.WIDTH = 700
1028 self.HEIGHT = 500
1028 self.HEIGHT = 500
1029 self.counter_imagwr = 0
1029 self.counter_imagwr = 0
1030
1030
1031 def getSubplots(self):
1031 def getSubplots(self):
1032 ncol = 1
1032 ncol = 1
1033 nrow = 1
1033 nrow = 1
1034
1034
1035 return nrow, ncol
1035 return nrow, ncol
1036
1036
1037 def setup(self, id, nplots, wintitle, show):
1037 def setup(self, id, nplots, wintitle, show):
1038
1038
1039 self.nplots = nplots
1039 self.nplots = nplots
1040
1040
1041 ncolspan = 1
1041 ncolspan = 1
1042 colspan = 1
1042 colspan = 1
1043
1043
1044 self.createFigure(id = id,
1044 self.createFigure(id = id,
1045 wintitle = wintitle,
1045 wintitle = wintitle,
1046 widthplot = self.WIDTH,
1046 widthplot = self.WIDTH,
1047 heightplot = self.HEIGHT,
1047 heightplot = self.HEIGHT,
1048 show=show)
1048 show=show)
1049
1049
1050 nrow, ncol = self.getSubplots()
1050 nrow, ncol = self.getSubplots()
1051
1051
1052 counter = 0
1052 counter = 0
1053 for y in range(nrow):
1053 for y in range(nrow):
1054 for x in range(ncol):
1054 for x in range(ncol):
1055 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1055 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1056
1056
1057 def run(self, dataOut, id, wintitle="", channelList=None,
1057 def run(self, dataOut, id, wintitle="", channelList=None,
1058 xmin=None, xmax=None, ymin=None, ymax=None,
1058 xmin=None, xmax=None, ymin=None, ymax=None,
1059 save=False, figpath='./', figfile=None, show=True,
1059 save=False, figpath='./', figfile=None, show=True,
1060 ftp=False, wr_period=1, server=None,
1060 ftp=False, wr_period=1, server=None,
1061 folder=None, username=None, password=None,
1061 folder=None, username=None, password=None,
1062 xaxis="frequency"):
1062 xaxis="frequency"):
1063
1063
1064 if dataOut.flagNoData:
1064 if dataOut.flagNoData:
1065 return dataOut
1065 return dataOut
1066
1066
1067 if channelList == None:
1067 if channelList == None:
1068 channelIndexList = dataOut.channelIndexList
1068 channelIndexList = dataOut.channelIndexList
1069 channelList = dataOut.channelList
1069 channelList = dataOut.channelList
1070 else:
1070 else:
1071 channelIndexList = []
1071 channelIndexList = []
1072 for channel in channelList:
1072 for channel in channelList:
1073 if channel not in dataOut.channelList:
1073 if channel not in dataOut.channelList:
1074 raise ValueError("Channel %d is not in dataOut.channelList")
1074 raise ValueError("Channel %d is not in dataOut.channelList")
1075 channelIndexList.append(dataOut.channelList.index(channel))
1075 channelIndexList.append(dataOut.channelList.index(channel))
1076
1076
1077 factor = dataOut.normFactor
1077 factor = dataOut.normFactor
1078
1078
1079 y = dataOut.getHeiRange()
1079 y = dataOut.getHeiRange()
1080
1080
1081 z = dataOut.data_spc/factor
1081 z = dataOut.data_spc/factor
1082 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1082 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1083
1083
1084 hei_index = numpy.arange(25)*3 + 20
1084 hei_index = numpy.arange(25)*3 + 20
1085
1085
1086 if xaxis == "frequency":
1086 if xaxis == "frequency":
1087 x = dataOut.getFreqRange()/1000.
1087 x = dataOut.getFreqRange()/1000.
1088 zdB = 10*numpy.log10(z[0,:,hei_index])
1088 zdB = 10*numpy.log10(z[0,:,hei_index])
1089 xlabel = "Frequency (kHz)"
1089 xlabel = "Frequency (kHz)"
1090 ylabel = "Power (dB)"
1090 ylabel = "Power (dB)"
1091
1091
1092 elif xaxis == "time":
1092 elif xaxis == "time":
1093 x = dataOut.getAcfRange()
1093 x = dataOut.getAcfRange()
1094 zdB = z[0,:,hei_index]
1094 zdB = z[0,:,hei_index]
1095 xlabel = "Time (ms)"
1095 xlabel = "Time (ms)"
1096 ylabel = "ACF"
1096 ylabel = "ACF"
1097
1097
1098 else:
1098 else:
1099 x = dataOut.getVelRange()
1099 x = dataOut.getVelRange()
1100 zdB = 10*numpy.log10(z[0,:,hei_index])
1100 zdB = 10*numpy.log10(z[0,:,hei_index])
1101 xlabel = "Velocity (m/s)"
1101 xlabel = "Velocity (m/s)"
1102 ylabel = "Power (dB)"
1102 ylabel = "Power (dB)"
1103
1103
1104 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1104 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1105 title = wintitle + " Range Cuts %s" %(thisDatetime.strftime("%d-%b-%Y"))
1105 title = wintitle + " Range Cuts %s" %(thisDatetime.strftime("%d-%b-%Y"))
1106
1106
1107 if not self.isConfig:
1107 if not self.isConfig:
1108
1108
1109 nplots = 1
1109 nplots = 1
1110
1110
1111 self.setup(id=id,
1111 self.setup(id=id,
1112 nplots=nplots,
1112 nplots=nplots,
1113 wintitle=wintitle,
1113 wintitle=wintitle,
1114 show=show)
1114 show=show)
1115
1115
1116 if xmin == None: xmin = numpy.nanmin(x)*0.9
1116 if xmin == None: xmin = numpy.nanmin(x)*0.9
1117 if xmax == None: xmax = numpy.nanmax(x)*1.1
1117 if xmax == None: xmax = numpy.nanmax(x)*1.1
1118 if ymin == None: ymin = numpy.nanmin(zdB)
1118 if ymin == None: ymin = numpy.nanmin(zdB)
1119 if ymax == None: ymax = numpy.nanmax(zdB)
1119 if ymax == None: ymax = numpy.nanmax(zdB)
1120
1120
1121 self.isConfig = True
1121 self.isConfig = True
1122
1122
1123 self.setWinTitle(title)
1123 self.setWinTitle(title)
1124
1124
1125 title = "Spectra Cuts: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1125 title = "Spectra Cuts: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1126 axes = self.axesList[0]
1126 axes = self.axesList[0]
1127
1127
1128 legendlabels = ["Range = %dKm" %y[i] for i in hei_index]
1128 legendlabels = ["Range = %dKm" %y[i] for i in hei_index]
1129
1129
1130 axes.pmultilineyaxis( x, zdB,
1130 axes.pmultilineyaxis( x, zdB,
1131 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1131 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1132 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
1132 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
1133 ytick_visible=True, nxticks=5,
1133 ytick_visible=True, nxticks=5,
1134 grid='x')
1134 grid='x')
1135
1135
1136 self.draw()
1136 self.draw()
1137
1137
1138 self.save(figpath=figpath,
1138 self.save(figpath=figpath,
1139 figfile=figfile,
1139 figfile=figfile,
1140 save=save,
1140 save=save,
1141 ftp=ftp,
1141 ftp=ftp,
1142 wr_period=wr_period,
1142 wr_period=wr_period,
1143 thisDatetime=thisDatetime)
1143 thisDatetime=thisDatetime)
1144
1144
1145 return dataOut
1145 return dataOut
1146
1146
1147 @MPDecorator
1147 @MPDecorator
1148 class Noise(Figure):
1148 class Noise_(Figure):
1149
1149
1150 isConfig = None
1150 isConfig = None
1151 __nsubplots = None
1151 __nsubplots = None
1152
1152
1153 PREFIX = 'noise'
1153 PREFIX = 'noise'
1154
1154
1155
1155
1156 def __init__(self):
1156 def __init__(self):
1157 Figure.__init__(self)
1157 Figure.__init__(self)
1158 self.timerange = 24*60*60
1158 self.timerange = 24*60*60
1159 self.isConfig = False
1159 self.isConfig = False
1160 self.__nsubplots = 1
1160 self.__nsubplots = 1
1161 self.counter_imagwr = 0
1161 self.counter_imagwr = 0
1162 self.WIDTH = 800
1162 self.WIDTH = 800
1163 self.HEIGHT = 400
1163 self.HEIGHT = 400
1164 self.WIDTHPROF = 120
1164 self.WIDTHPROF = 120
1165 self.HEIGHTPROF = 0
1165 self.HEIGHTPROF = 0
1166 self.xdata = None
1166 self.xdata = None
1167 self.ydata = None
1167 self.ydata = None
1168
1168
1169 self.PLOT_CODE = NOISE_CODE
1169 self.PLOT_CODE = NOISE_CODE
1170
1170
1171 self.FTP_WEI = None
1171 self.FTP_WEI = None
1172 self.EXP_CODE = None
1172 self.EXP_CODE = None
1173 self.SUB_EXP_CODE = None
1173 self.SUB_EXP_CODE = None
1174 self.PLOT_POS = None
1174 self.PLOT_POS = None
1175 self.figfile = None
1175 self.figfile = None
1176
1176
1177 self.xmin = None
1177 self.xmin = None
1178 self.xmax = None
1178 self.xmax = None
1179
1179
1180 def getSubplots(self):
1180 def getSubplots(self):
1181
1181
1182 ncol = 1
1182 ncol = 1
1183 nrow = 1
1183 nrow = 1
1184
1184
1185 return nrow, ncol
1185 return nrow, ncol
1186
1186
1187 def openfile(self, filename):
1187 def openfile(self, filename):
1188 dirname = os.path.dirname(filename)
1188 dirname = os.path.dirname(filename)
1189
1189
1190 if not os.path.exists(dirname):
1190 if not os.path.exists(dirname):
1191 os.mkdir(dirname)
1191 os.mkdir(dirname)
1192
1192
1193 f = open(filename,'w+')
1193 f = open(filename,'w+')
1194 f.write('\n\n')
1194 f.write('\n\n')
1195 f.write('JICAMARCA RADIO OBSERVATORY - Noise \n')
1195 f.write('JICAMARCA RADIO OBSERVATORY - Noise \n')
1196 f.write('DD MM YYYY HH MM SS Channel0 Channel1 Channel2 Channel3\n\n' )
1196 f.write('DD MM YYYY HH MM SS Channel0 Channel1 Channel2 Channel3\n\n' )
1197 f.close()
1197 f.close()
1198
1198
1199 def save_data(self, filename_phase, data, data_datetime):
1199 def save_data(self, filename_phase, data, data_datetime):
1200
1200
1201 f=open(filename_phase,'a')
1201 f=open(filename_phase,'a')
1202
1202
1203 timetuple_data = data_datetime.timetuple()
1203 timetuple_data = data_datetime.timetuple()
1204 day = str(timetuple_data.tm_mday)
1204 day = str(timetuple_data.tm_mday)
1205 month = str(timetuple_data.tm_mon)
1205 month = str(timetuple_data.tm_mon)
1206 year = str(timetuple_data.tm_year)
1206 year = str(timetuple_data.tm_year)
1207 hour = str(timetuple_data.tm_hour)
1207 hour = str(timetuple_data.tm_hour)
1208 minute = str(timetuple_data.tm_min)
1208 minute = str(timetuple_data.tm_min)
1209 second = str(timetuple_data.tm_sec)
1209 second = str(timetuple_data.tm_sec)
1210
1210
1211 data_msg = ''
1211 data_msg = ''
1212 for i in range(len(data)):
1212 for i in range(len(data)):
1213 data_msg += str(data[i]) + ' '
1213 data_msg += str(data[i]) + ' '
1214
1214
1215 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' ' + data_msg + '\n')
1215 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' ' + data_msg + '\n')
1216 f.close()
1216 f.close()
1217
1217
1218
1218
1219 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1219 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1220
1220
1221 self.__showprofile = showprofile
1221 self.__showprofile = showprofile
1222 self.nplots = nplots
1222 self.nplots = nplots
1223
1223
1224 ncolspan = 7
1224 ncolspan = 7
1225 colspan = 6
1225 colspan = 6
1226 self.__nsubplots = 2
1226 self.__nsubplots = 2
1227
1227
1228 self.createFigure(id = id,
1228 self.createFigure(id = id,
1229 wintitle = wintitle,
1229 wintitle = wintitle,
1230 widthplot = self.WIDTH+self.WIDTHPROF,
1230 widthplot = self.WIDTH+self.WIDTHPROF,
1231 heightplot = self.HEIGHT+self.HEIGHTPROF,
1231 heightplot = self.HEIGHT+self.HEIGHTPROF,
1232 show=show)
1232 show=show)
1233
1233
1234 nrow, ncol = self.getSubplots()
1234 nrow, ncol = self.getSubplots()
1235
1235
1236 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1236 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1237
1237
1238
1238
1239 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1239 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1240 xmin=None, xmax=None, ymin=None, ymax=None,
1240 xmin=None, xmax=None, ymin=None, ymax=None,
1241 timerange=None,
1241 timerange=None,
1242 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1242 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1243 server=None, folder=None, username=None, password=None,
1243 server=None, folder=None, username=None, password=None,
1244 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1244 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1245
1245
1246 if dataOut.flagNoData:
1246 if dataOut.flagNoData:
1247 return dataOut
1247 return dataOut
1248
1248
1249 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1249 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1250 return
1250 return
1251
1251
1252 if channelList == None:
1252 if channelList == None:
1253 channelIndexList = dataOut.channelIndexList
1253 channelIndexList = dataOut.channelIndexList
1254 channelList = dataOut.channelList
1254 channelList = dataOut.channelList
1255 else:
1255 else:
1256 channelIndexList = []
1256 channelIndexList = []
1257 for channel in channelList:
1257 for channel in channelList:
1258 if channel not in dataOut.channelList:
1258 if channel not in dataOut.channelList:
1259 raise ValueError("Channel %d is not in dataOut.channelList")
1259 raise ValueError("Channel %d is not in dataOut.channelList")
1260 channelIndexList.append(dataOut.channelList.index(channel))
1260 channelIndexList.append(dataOut.channelList.index(channel))
1261
1261
1262 x = dataOut.getTimeRange()
1262 x = dataOut.getTimeRange()
1263 #y = dataOut.getHeiRange()
1263 #y = dataOut.getHeiRange()
1264 factor = dataOut.normFactor
1264 factor = dataOut.normFactor
1265 noise = dataOut.noise[channelIndexList]/factor
1265 noise = dataOut.noise[channelIndexList]/factor
1266 noisedB = 10*numpy.log10(noise)
1266 noisedB = 10*numpy.log10(noise)
1267
1267
1268 thisDatetime = dataOut.datatime
1268 thisDatetime = dataOut.datatime
1269
1269
1270 title = wintitle + " Noise" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1270 title = wintitle + " Noise" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1271 xlabel = ""
1271 xlabel = ""
1272 ylabel = "Intensity (dB)"
1272 ylabel = "Intensity (dB)"
1273 update_figfile = False
1273 update_figfile = False
1274
1274
1275 if not self.isConfig:
1275 if not self.isConfig:
1276
1276
1277 nplots = 1
1277 nplots = 1
1278
1278
1279 self.setup(id=id,
1279 self.setup(id=id,
1280 nplots=nplots,
1280 nplots=nplots,
1281 wintitle=wintitle,
1281 wintitle=wintitle,
1282 showprofile=showprofile,
1282 showprofile=showprofile,
1283 show=show)
1283 show=show)
1284
1284
1285 if timerange != None:
1285 if timerange != None:
1286 self.timerange = timerange
1286 self.timerange = timerange
1287
1287
1288 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1288 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1289
1289
1290 if ymin == None: ymin = numpy.floor(numpy.nanmin(noisedB)) - 10.0
1290 if ymin == None: ymin = numpy.floor(numpy.nanmin(noisedB)) - 10.0
1291 if ymax == None: ymax = numpy.nanmax(noisedB) + 10.0
1291 if ymax == None: ymax = numpy.nanmax(noisedB) + 10.0
1292
1292
1293 self.FTP_WEI = ftp_wei
1293 self.FTP_WEI = ftp_wei
1294 self.EXP_CODE = exp_code
1294 self.EXP_CODE = exp_code
1295 self.SUB_EXP_CODE = sub_exp_code
1295 self.SUB_EXP_CODE = sub_exp_code
1296 self.PLOT_POS = plot_pos
1296 self.PLOT_POS = plot_pos
1297
1297
1298
1298
1299 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1299 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1300 self.isConfig = True
1300 self.isConfig = True
1301 self.figfile = figfile
1301 self.figfile = figfile
1302 self.xdata = numpy.array([])
1302 self.xdata = numpy.array([])
1303 self.ydata = numpy.array([])
1303 self.ydata = numpy.array([])
1304
1304
1305 update_figfile = True
1305 update_figfile = True
1306
1306
1307 #open file beacon phase
1307 #open file beacon phase
1308 path = '%s%03d' %(self.PREFIX, self.id)
1308 path = '%s%03d' %(self.PREFIX, self.id)
1309 noise_file = os.path.join(path,'%s.txt'%self.name)
1309 noise_file = os.path.join(path,'%s.txt'%self.name)
1310 self.filename_noise = os.path.join(figpath,noise_file)
1310 self.filename_noise = os.path.join(figpath,noise_file)
1311
1311
1312 self.setWinTitle(title)
1312 self.setWinTitle(title)
1313
1313
1314 title = "Noise %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1314 title = "Noise %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1315
1315
1316 legendlabels = ["channel %d"%(idchannel) for idchannel in channelList]
1316 legendlabels = ["channel %d"%(idchannel) for idchannel in channelList]
1317 axes = self.axesList[0]
1317 axes = self.axesList[0]
1318
1318
1319 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1319 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1320
1320
1321 if len(self.ydata)==0:
1321 if len(self.ydata)==0:
1322 self.ydata = noisedB.reshape(-1,1)
1322 self.ydata = noisedB.reshape(-1,1)
1323 else:
1323 else:
1324 self.ydata = numpy.hstack((self.ydata, noisedB.reshape(-1,1)))
1324 self.ydata = numpy.hstack((self.ydata, noisedB.reshape(-1,1)))
1325
1325
1326
1326
1327 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1327 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1328 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1328 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1329 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1329 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1330 XAxisAsTime=True, grid='both'
1330 XAxisAsTime=True, grid='both'
1331 )
1331 )
1332
1332
1333 self.draw()
1333 self.draw()
1334
1334
1335 if dataOut.ltctime >= self.xmax:
1335 if dataOut.ltctime >= self.xmax:
1336 self.counter_imagwr = wr_period
1336 self.counter_imagwr = wr_period
1337 self.isConfig = False
1337 self.isConfig = False
1338 update_figfile = True
1338 update_figfile = True
1339
1339
1340 self.save(figpath=figpath,
1340 self.save(figpath=figpath,
1341 figfile=figfile,
1341 figfile=figfile,
1342 save=save,
1342 save=save,
1343 ftp=ftp,
1343 ftp=ftp,
1344 wr_period=wr_period,
1344 wr_period=wr_period,
1345 thisDatetime=thisDatetime,
1345 thisDatetime=thisDatetime,
1346 update_figfile=update_figfile)
1346 update_figfile=update_figfile)
1347
1347
1348 #store data beacon phase
1348 #store data beacon phase
1349 if save:
1349 if save:
1350 self.save_data(self.filename_noise, noisedB, thisDatetime)
1350 self.save_data(self.filename_noise, noisedB, thisDatetime)
1351
1351
1352 return dataOut
1352 return dataOut
1353
1353
1354 @MPDecorator
1354 @MPDecorator
1355 class BeaconPhase(Figure):
1355 class BeaconPhase_(Figure):
1356
1356
1357 __isConfig = None
1357 __isConfig = None
1358 __nsubplots = None
1358 __nsubplots = None
1359
1359
1360 PREFIX = 'beacon_phase'
1360 PREFIX = 'beacon_phase'
1361
1361
1362 def __init__(self):
1362 def __init__(self):
1363 Figure.__init__(self)
1363 Figure.__init__(self)
1364 self.timerange = 24*60*60
1364 self.timerange = 24*60*60
1365 self.isConfig = False
1365 self.isConfig = False
1366 self.__nsubplots = 1
1366 self.__nsubplots = 1
1367 self.counter_imagwr = 0
1367 self.counter_imagwr = 0
1368 self.WIDTH = 800
1368 self.WIDTH = 800
1369 self.HEIGHT = 400
1369 self.HEIGHT = 400
1370 self.WIDTHPROF = 120
1370 self.WIDTHPROF = 120
1371 self.HEIGHTPROF = 0
1371 self.HEIGHTPROF = 0
1372 self.xdata = None
1372 self.xdata = None
1373 self.ydata = None
1373 self.ydata = None
1374
1374
1375 self.PLOT_CODE = BEACON_CODE
1375 self.PLOT_CODE = BEACON_CODE
1376
1376
1377 self.FTP_WEI = None
1377 self.FTP_WEI = None
1378 self.EXP_CODE = None
1378 self.EXP_CODE = None
1379 self.SUB_EXP_CODE = None
1379 self.SUB_EXP_CODE = None
1380 self.PLOT_POS = None
1380 self.PLOT_POS = None
1381
1381
1382 self.filename_phase = None
1382 self.filename_phase = None
1383
1383
1384 self.figfile = None
1384 self.figfile = None
1385
1385
1386 self.xmin = None
1386 self.xmin = None
1387 self.xmax = None
1387 self.xmax = None
1388
1388
1389 def getSubplots(self):
1389 def getSubplots(self):
1390
1390
1391 ncol = 1
1391 ncol = 1
1392 nrow = 1
1392 nrow = 1
1393
1393
1394 return nrow, ncol
1394 return nrow, ncol
1395
1395
1396 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1396 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1397
1397
1398 self.__showprofile = showprofile
1398 self.__showprofile = showprofile
1399 self.nplots = nplots
1399 self.nplots = nplots
1400
1400
1401 ncolspan = 7
1401 ncolspan = 7
1402 colspan = 6
1402 colspan = 6
1403 self.__nsubplots = 2
1403 self.__nsubplots = 2
1404
1404
1405 self.createFigure(id = id,
1405 self.createFigure(id = id,
1406 wintitle = wintitle,
1406 wintitle = wintitle,
1407 widthplot = self.WIDTH+self.WIDTHPROF,
1407 widthplot = self.WIDTH+self.WIDTHPROF,
1408 heightplot = self.HEIGHT+self.HEIGHTPROF,
1408 heightplot = self.HEIGHT+self.HEIGHTPROF,
1409 show=show)
1409 show=show)
1410
1410
1411 nrow, ncol = self.getSubplots()
1411 nrow, ncol = self.getSubplots()
1412
1412
1413 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1413 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1414
1414
1415 def save_phase(self, filename_phase):
1415 def save_phase(self, filename_phase):
1416 f = open(filename_phase,'w+')
1416 f = open(filename_phase,'w+')
1417 f.write('\n\n')
1417 f.write('\n\n')
1418 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1418 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1419 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1419 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1420 f.close()
1420 f.close()
1421
1421
1422 def save_data(self, filename_phase, data, data_datetime):
1422 def save_data(self, filename_phase, data, data_datetime):
1423 f=open(filename_phase,'a')
1423 f=open(filename_phase,'a')
1424 timetuple_data = data_datetime.timetuple()
1424 timetuple_data = data_datetime.timetuple()
1425 day = str(timetuple_data.tm_mday)
1425 day = str(timetuple_data.tm_mday)
1426 month = str(timetuple_data.tm_mon)
1426 month = str(timetuple_data.tm_mon)
1427 year = str(timetuple_data.tm_year)
1427 year = str(timetuple_data.tm_year)
1428 hour = str(timetuple_data.tm_hour)
1428 hour = str(timetuple_data.tm_hour)
1429 minute = str(timetuple_data.tm_min)
1429 minute = str(timetuple_data.tm_min)
1430 second = str(timetuple_data.tm_sec)
1430 second = str(timetuple_data.tm_sec)
1431 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1431 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1432 f.close()
1432 f.close()
1433
1433
1434
1434
1435 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1435 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1436 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1436 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1437 timerange=None,
1437 timerange=None,
1438 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1438 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1439 server=None, folder=None, username=None, password=None,
1439 server=None, folder=None, username=None, password=None,
1440 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1440 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1441
1441
1442 if dataOut.flagNoData:
1442 if dataOut.flagNoData:
1443 return dataOut
1443 return dataOut
1444
1444
1445 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1445 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1446 return
1446 return
1447
1447
1448 if pairsList == None:
1448 if pairsList == None:
1449 pairsIndexList = dataOut.pairsIndexList[:10]
1449 pairsIndexList = dataOut.pairsIndexList[:10]
1450 else:
1450 else:
1451 pairsIndexList = []
1451 pairsIndexList = []
1452 for pair in pairsList:
1452 for pair in pairsList:
1453 if pair not in dataOut.pairsList:
1453 if pair not in dataOut.pairsList:
1454 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1454 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1455 pairsIndexList.append(dataOut.pairsList.index(pair))
1455 pairsIndexList.append(dataOut.pairsList.index(pair))
1456
1456
1457 if pairsIndexList == []:
1457 if pairsIndexList == []:
1458 return
1458 return
1459
1459
1460 # if len(pairsIndexList) > 4:
1460 # if len(pairsIndexList) > 4:
1461 # pairsIndexList = pairsIndexList[0:4]
1461 # pairsIndexList = pairsIndexList[0:4]
1462
1462
1463 hmin_index = None
1463 hmin_index = None
1464 hmax_index = None
1464 hmax_index = None
1465
1465
1466 if hmin != None and hmax != None:
1466 if hmin != None and hmax != None:
1467 indexes = numpy.arange(dataOut.nHeights)
1467 indexes = numpy.arange(dataOut.nHeights)
1468 hmin_list = indexes[dataOut.heightList >= hmin]
1468 hmin_list = indexes[dataOut.heightList >= hmin]
1469 hmax_list = indexes[dataOut.heightList <= hmax]
1469 hmax_list = indexes[dataOut.heightList <= hmax]
1470
1470
1471 if hmin_list.any():
1471 if hmin_list.any():
1472 hmin_index = hmin_list[0]
1472 hmin_index = hmin_list[0]
1473
1473
1474 if hmax_list.any():
1474 if hmax_list.any():
1475 hmax_index = hmax_list[-1]+1
1475 hmax_index = hmax_list[-1]+1
1476
1476
1477 x = dataOut.getTimeRange()
1477 x = dataOut.getTimeRange()
1478 #y = dataOut.getHeiRange()
1478 #y = dataOut.getHeiRange()
1479
1479
1480
1480
1481 thisDatetime = dataOut.datatime
1481 thisDatetime = dataOut.datatime
1482
1482
1483 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1483 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1484 xlabel = "Local Time"
1484 xlabel = "Local Time"
1485 ylabel = "Phase (degrees)"
1485 ylabel = "Phase (degrees)"
1486
1486
1487 update_figfile = False
1487 update_figfile = False
1488
1488
1489 nplots = len(pairsIndexList)
1489 nplots = len(pairsIndexList)
1490 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1490 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1491 phase_beacon = numpy.zeros(len(pairsIndexList))
1491 phase_beacon = numpy.zeros(len(pairsIndexList))
1492 for i in range(nplots):
1492 for i in range(nplots):
1493 pair = dataOut.pairsList[pairsIndexList[i]]
1493 pair = dataOut.pairsList[pairsIndexList[i]]
1494 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1494 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1495 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1495 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1496 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1496 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1497 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1497 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1498 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1498 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1499
1499
1500 #print "Phase %d%d" %(pair[0], pair[1])
1500 #print "Phase %d%d" %(pair[0], pair[1])
1501 #print phase[dataOut.beacon_heiIndexList]
1501 #print phase[dataOut.beacon_heiIndexList]
1502
1502
1503 if dataOut.beacon_heiIndexList:
1503 if dataOut.beacon_heiIndexList:
1504 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1504 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1505 else:
1505 else:
1506 phase_beacon[i] = numpy.average(phase)
1506 phase_beacon[i] = numpy.average(phase)
1507
1507
1508 if not self.isConfig:
1508 if not self.isConfig:
1509
1509
1510 nplots = len(pairsIndexList)
1510 nplots = len(pairsIndexList)
1511
1511
1512 self.setup(id=id,
1512 self.setup(id=id,
1513 nplots=nplots,
1513 nplots=nplots,
1514 wintitle=wintitle,
1514 wintitle=wintitle,
1515 showprofile=showprofile,
1515 showprofile=showprofile,
1516 show=show)
1516 show=show)
1517
1517
1518 if timerange != None:
1518 if timerange != None:
1519 self.timerange = timerange
1519 self.timerange = timerange
1520
1520
1521 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1521 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1522
1522
1523 if ymin == None: ymin = 0
1523 if ymin == None: ymin = 0
1524 if ymax == None: ymax = 360
1524 if ymax == None: ymax = 360
1525
1525
1526 self.FTP_WEI = ftp_wei
1526 self.FTP_WEI = ftp_wei
1527 self.EXP_CODE = exp_code
1527 self.EXP_CODE = exp_code
1528 self.SUB_EXP_CODE = sub_exp_code
1528 self.SUB_EXP_CODE = sub_exp_code
1529 self.PLOT_POS = plot_pos
1529 self.PLOT_POS = plot_pos
1530
1530
1531 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1531 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1532 self.isConfig = True
1532 self.isConfig = True
1533 self.figfile = figfile
1533 self.figfile = figfile
1534 self.xdata = numpy.array([])
1534 self.xdata = numpy.array([])
1535 self.ydata = numpy.array([])
1535 self.ydata = numpy.array([])
1536
1536
1537 update_figfile = True
1537 update_figfile = True
1538
1538
1539 #open file beacon phase
1539 #open file beacon phase
1540 path = '%s%03d' %(self.PREFIX, self.id)
1540 path = '%s%03d' %(self.PREFIX, self.id)
1541 beacon_file = os.path.join(path,'%s.txt'%self.name)
1541 beacon_file = os.path.join(path,'%s.txt'%self.name)
1542 self.filename_phase = os.path.join(figpath,beacon_file)
1542 self.filename_phase = os.path.join(figpath,beacon_file)
1543 #self.save_phase(self.filename_phase)
1543 #self.save_phase(self.filename_phase)
1544
1544
1545
1545
1546 #store data beacon phase
1546 #store data beacon phase
1547 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1547 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1548
1548
1549 self.setWinTitle(title)
1549 self.setWinTitle(title)
1550
1550
1551
1551
1552 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1552 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1553
1553
1554 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1554 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1555
1555
1556 axes = self.axesList[0]
1556 axes = self.axesList[0]
1557
1557
1558 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1558 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1559
1559
1560 if len(self.ydata)==0:
1560 if len(self.ydata)==0:
1561 self.ydata = phase_beacon.reshape(-1,1)
1561 self.ydata = phase_beacon.reshape(-1,1)
1562 else:
1562 else:
1563 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1563 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1564
1564
1565
1565
1566 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1566 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1567 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1567 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1568 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1568 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1569 XAxisAsTime=True, grid='both'
1569 XAxisAsTime=True, grid='both'
1570 )
1570 )
1571
1571
1572 self.draw()
1572 self.draw()
1573
1573
1574 if dataOut.ltctime >= self.xmax:
1574 if dataOut.ltctime >= self.xmax:
1575 self.counter_imagwr = wr_period
1575 self.counter_imagwr = wr_period
1576 self.isConfig = False
1576 self.isConfig = False
1577 update_figfile = True
1577 update_figfile = True
1578
1578
1579 self.save(figpath=figpath,
1579 self.save(figpath=figpath,
1580 figfile=figfile,
1580 figfile=figfile,
1581 save=save,
1581 save=save,
1582 ftp=ftp,
1582 ftp=ftp,
1583 wr_period=wr_period,
1583 wr_period=wr_period,
1584 thisDatetime=thisDatetime,
1584 thisDatetime=thisDatetime,
1585 update_figfile=update_figfile)
1585 update_figfile=update_figfile)
1586
1586
1587 return dataOut No newline at end of file
1587 return dataOut
@@ -1,232 +1,232
1 '''
1 '''
2 Created on Jul 9, 2014
2 Created on Jul 9, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import os
6 import os
7 import datetime
7 import datetime
8 import numpy
8 import numpy
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
10 from schainpy.utils import log
10 from schainpy.utils import log
11 from .figure import Figure
11 from .figure import Figure
12
12
13
13
14 @MPDecorator
14 @MPDecorator
15 class Scope(Figure):
15 class Scope_(Figure):
16
16
17 isConfig = None
17 isConfig = None
18
18
19 def __init__(self):#, **kwargs): #YONG
19 def __init__(self):#, **kwargs): #YONG
20 Figure.__init__(self)#, **kwargs)
20 Figure.__init__(self)#, **kwargs)
21 self.isConfig = False
21 self.isConfig = False
22 self.WIDTH = 300
22 self.WIDTH = 300
23 self.HEIGHT = 200
23 self.HEIGHT = 200
24 self.counter_imagwr = 0
24 self.counter_imagwr = 0
25
25
26 def getSubplots(self):
26 def getSubplots(self):
27
27
28 nrow = self.nplots
28 nrow = self.nplots
29 ncol = 3
29 ncol = 3
30 return nrow, ncol
30 return nrow, ncol
31
31
32 def setup(self, id, nplots, wintitle, show):
32 def setup(self, id, nplots, wintitle, show):
33
33
34 self.nplots = nplots
34 self.nplots = nplots
35
35
36 self.createFigure(id=id,
36 self.createFigure(id=id,
37 wintitle=wintitle,
37 wintitle=wintitle,
38 show=show)
38 show=show)
39
39
40 nrow,ncol = self.getSubplots()
40 nrow,ncol = self.getSubplots()
41 colspan = 3
41 colspan = 3
42 rowspan = 1
42 rowspan = 1
43
43
44 for i in range(nplots):
44 for i in range(nplots):
45 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
45 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
46
46
47 def plot_iq(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
47 def plot_iq(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
48 yreal = y[channelIndexList,:].real
48 yreal = y[channelIndexList,:].real
49 yimag = y[channelIndexList,:].imag
49 yimag = y[channelIndexList,:].imag
50
50
51 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
51 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
52 xlabel = "Range (Km)"
52 xlabel = "Range (Km)"
53 ylabel = "Intensity - IQ"
53 ylabel = "Intensity - IQ"
54
54
55 if not self.isConfig:
55 if not self.isConfig:
56 nplots = len(channelIndexList)
56 nplots = len(channelIndexList)
57
57
58 self.setup(id=id,
58 self.setup(id=id,
59 nplots=nplots,
59 nplots=nplots,
60 wintitle='',
60 wintitle='',
61 show=show)
61 show=show)
62
62
63 if xmin == None: xmin = numpy.nanmin(x)
63 if xmin == None: xmin = numpy.nanmin(x)
64 if xmax == None: xmax = numpy.nanmax(x)
64 if xmax == None: xmax = numpy.nanmax(x)
65 if ymin == None: ymin = min(numpy.nanmin(yreal),numpy.nanmin(yimag))
65 if ymin == None: ymin = min(numpy.nanmin(yreal),numpy.nanmin(yimag))
66 if ymax == None: ymax = max(numpy.nanmax(yreal),numpy.nanmax(yimag))
66 if ymax == None: ymax = max(numpy.nanmax(yreal),numpy.nanmax(yimag))
67
67
68 self.isConfig = True
68 self.isConfig = True
69
69
70 self.setWinTitle(title)
70 self.setWinTitle(title)
71
71
72 for i in range(len(self.axesList)):
72 for i in range(len(self.axesList)):
73 title = "Channel %d" %(i)
73 title = "Channel %d" %(i)
74 axes = self.axesList[i]
74 axes = self.axesList[i]
75
75
76 axes.pline(x, yreal[i,:],
76 axes.pline(x, yreal[i,:],
77 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
77 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
78 xlabel=xlabel, ylabel=ylabel, title=title)
78 xlabel=xlabel, ylabel=ylabel, title=title)
79
79
80 axes.addpline(x, yimag[i,:], idline=1, color="red", linestyle="solid", lw=2)
80 axes.addpline(x, yimag[i,:], idline=1, color="red", linestyle="solid", lw=2)
81
81
82 def plot_power(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
82 def plot_power(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
83 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
83 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
84 yreal = y.real
84 yreal = y.real
85
85
86 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
86 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
87 xlabel = "Range (Km)"
87 xlabel = "Range (Km)"
88 ylabel = "Intensity"
88 ylabel = "Intensity"
89
89
90 if not self.isConfig:
90 if not self.isConfig:
91 nplots = len(channelIndexList)
91 nplots = len(channelIndexList)
92
92
93 self.setup(id=id,
93 self.setup(id=id,
94 nplots=nplots,
94 nplots=nplots,
95 wintitle='',
95 wintitle='',
96 show=show)
96 show=show)
97
97
98 if xmin == None: xmin = numpy.nanmin(x)
98 if xmin == None: xmin = numpy.nanmin(x)
99 if xmax == None: xmax = numpy.nanmax(x)
99 if xmax == None: xmax = numpy.nanmax(x)
100 if ymin == None: ymin = numpy.nanmin(yreal)
100 if ymin == None: ymin = numpy.nanmin(yreal)
101 if ymax == None: ymax = numpy.nanmax(yreal)
101 if ymax == None: ymax = numpy.nanmax(yreal)
102
102
103 self.isConfig = True
103 self.isConfig = True
104
104
105 self.setWinTitle(title)
105 self.setWinTitle(title)
106
106
107 for i in range(len(self.axesList)):
107 for i in range(len(self.axesList)):
108 title = "Channel %d" %(i)
108 title = "Channel %d" %(i)
109 axes = self.axesList[i]
109 axes = self.axesList[i]
110 ychannel = yreal[i,:]
110 ychannel = yreal[i,:]
111 axes.pline(x, ychannel,
111 axes.pline(x, ychannel,
112 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
112 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
113 xlabel=xlabel, ylabel=ylabel, title=title)
113 xlabel=xlabel, ylabel=ylabel, title=title)
114
114
115
115
116 def run(self, dataOut, id, wintitle="", channelList=None,
116 def run(self, dataOut, id, wintitle="", channelList=None,
117 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
117 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
118 figpath='./', figfile=None, show=True, wr_period=1,
118 figpath='./', figfile=None, show=True, wr_period=1,
119 ftp=False, server=None, folder=None, username=None, password=None, type='power', **kwargs):
119 ftp=False, server=None, folder=None, username=None, password=None, type='power', **kwargs):
120
120
121 """
121 """
122
122
123 Input:
123 Input:
124 dataOut :
124 dataOut :
125 id :
125 id :
126 wintitle :
126 wintitle :
127 channelList :
127 channelList :
128 xmin : None,
128 xmin : None,
129 xmax : None,
129 xmax : None,
130 ymin : None,
130 ymin : None,
131 ymax : None,
131 ymax : None,
132 """
132 """
133 if dataOut.flagNoData:
133 if dataOut.flagNoData:
134 return dataOut
134 return dataOut
135
135
136 if channelList == None:
136 if channelList == None:
137 channelIndexList = dataOut.channelIndexList
137 channelIndexList = dataOut.channelIndexList
138 else:
138 else:
139 channelIndexList = []
139 channelIndexList = []
140 for channel in channelList:
140 for channel in channelList:
141 if channel not in dataOut.channelList:
141 if channel not in dataOut.channelList:
142 raise ValueError("Channel %d is not in dataOut.channelList")
142 raise ValueError("Channel %d is not in dataOut.channelList")
143 channelIndexList.append(dataOut.channelList.index(channel))
143 channelIndexList.append(dataOut.channelList.index(channel))
144
144
145 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
145 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
146
146
147 if dataOut.flagDataAsBlock:
147 if dataOut.flagDataAsBlock:
148
148
149 for i in range(dataOut.nProfiles):
149 for i in range(dataOut.nProfiles):
150
150
151 wintitle1 = wintitle + " [Profile = %d] " %i
151 wintitle1 = wintitle + " [Profile = %d] " %i
152
152
153 if type == "power":
153 if type == "power":
154 self.plot_power(dataOut.heightList,
154 self.plot_power(dataOut.heightList,
155 dataOut.data[:,i,:],
155 dataOut.data[:,i,:],
156 id,
156 id,
157 channelIndexList,
157 channelIndexList,
158 thisDatetime,
158 thisDatetime,
159 wintitle1,
159 wintitle1,
160 show,
160 show,
161 xmin,
161 xmin,
162 xmax,
162 xmax,
163 ymin,
163 ymin,
164 ymax)
164 ymax)
165
165
166 if type == "iq":
166 if type == "iq":
167 self.plot_iq(dataOut.heightList,
167 self.plot_iq(dataOut.heightList,
168 dataOut.data[:,i,:],
168 dataOut.data[:,i,:],
169 id,
169 id,
170 channelIndexList,
170 channelIndexList,
171 thisDatetime,
171 thisDatetime,
172 wintitle1,
172 wintitle1,
173 show,
173 show,
174 xmin,
174 xmin,
175 xmax,
175 xmax,
176 ymin,
176 ymin,
177 ymax)
177 ymax)
178
178
179 self.draw()
179 self.draw()
180
180
181 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
181 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
182 figfile = self.getFilename(name = str_datetime) + "_" + str(i)
182 figfile = self.getFilename(name = str_datetime) + "_" + str(i)
183
183
184 self.save(figpath=figpath,
184 self.save(figpath=figpath,
185 figfile=figfile,
185 figfile=figfile,
186 save=save,
186 save=save,
187 ftp=ftp,
187 ftp=ftp,
188 wr_period=wr_period,
188 wr_period=wr_period,
189 thisDatetime=thisDatetime)
189 thisDatetime=thisDatetime)
190
190
191 else:
191 else:
192 wintitle += " [Profile = %d] " %dataOut.profileIndex
192 wintitle += " [Profile = %d] " %dataOut.profileIndex
193
193
194 if type == "power":
194 if type == "power":
195 self.plot_power(dataOut.heightList,
195 self.plot_power(dataOut.heightList,
196 dataOut.data,
196 dataOut.data,
197 id,
197 id,
198 channelIndexList,
198 channelIndexList,
199 thisDatetime,
199 thisDatetime,
200 wintitle,
200 wintitle,
201 show,
201 show,
202 xmin,
202 xmin,
203 xmax,
203 xmax,
204 ymin,
204 ymin,
205 ymax)
205 ymax)
206
206
207 if type == "iq":
207 if type == "iq":
208 self.plot_iq(dataOut.heightList,
208 self.plot_iq(dataOut.heightList,
209 dataOut.data,
209 dataOut.data,
210 id,
210 id,
211 channelIndexList,
211 channelIndexList,
212 thisDatetime,
212 thisDatetime,
213 wintitle,
213 wintitle,
214 show,
214 show,
215 xmin,
215 xmin,
216 xmax,
216 xmax,
217 ymin,
217 ymin,
218 ymax)
218 ymax)
219
219
220 self.draw()
220 self.draw()
221
221
222 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + "_" + str(dataOut.profileIndex)
222 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + "_" + str(dataOut.profileIndex)
223 figfile = self.getFilename(name = str_datetime)
223 figfile = self.getFilename(name = str_datetime)
224
224
225 self.save(figpath=figpath,
225 self.save(figpath=figpath,
226 figfile=figfile,
226 figfile=figfile,
227 save=save,
227 save=save,
228 ftp=ftp,
228 ftp=ftp,
229 wr_period=wr_period,
229 wr_period=wr_period,
230 thisDatetime=thisDatetime)
230 thisDatetime=thisDatetime)
231
231
232 return dataOut No newline at end of file
232 return dataOut
@@ -1,367 +1,376
1 '''
1 '''
2 Updated for multiprocessing
2 Updated for multiprocessing
3 Author : Sergio Cortez
3 Author : Sergio Cortez
4 Jan 2018
4 Jan 2018
5 Abstract:
5 Abstract:
6 Base class for processing units and operations. A decorator provides multiprocessing features and interconnect the processes created.
6 Base class for processing units and operations. A decorator provides multiprocessing features and interconnect the processes created.
7 The argument (kwargs) sent from the controller is parsed and filtered via the decorator for each processing unit or operation instantiated.
7 The argument (kwargs) sent from the controller is parsed and filtered via the decorator for each processing unit or operation instantiated.
8 The decorator handle also the methods inside the processing unit to be called from the main script (not as operations) (OPERATION -> type ='self').
8 The decorator handle also the methods inside the processing unit to be called from the main script (not as operations) (OPERATION -> type ='self').
9
9
10 Based on:
10 Based on:
11 $Author: murco $
11 $Author: murco $
12 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
12 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
13 '''
13 '''
14 from platform import python_version
14
15 import inspect
15 import inspect
16 import zmq
16 import zmq
17 import time
17 import time
18 import pickle
18 import pickle
19 import os
19 import os
20 from multiprocessing import Process
20 from multiprocessing import Process
21 from zmq.utils.monitor import recv_monitor_message
22
21 from schainpy.utils import log
23 from schainpy.utils import log
22
24
23
25
24 class ProcessingUnit(object):
26 class ProcessingUnit(object):
25
27
26 """
28 """
27 Update - Jan 2018 - MULTIPROCESSING
29 Update - Jan 2018 - MULTIPROCESSING
28 All the "call" methods present in the previous base were removed.
30 All the "call" methods present in the previous base were removed.
29 The majority of operations are independant processes, thus
31 The majority of operations are independant processes, thus
30 the decorator is in charge of communicate the operation processes
32 the decorator is in charge of communicate the operation processes
31 with the proccessing unit via IPC.
33 with the proccessing unit via IPC.
32
34
33 The constructor does not receive any argument. The remaining methods
35 The constructor does not receive any argument. The remaining methods
34 are related with the operations to execute.
36 are related with the operations to execute.
35
37
36
38
37 """
39 """
38
39 METHODS = {}
40 dataIn = None
41 dataInList = []
42 id = None
43 inputId = None
44 dataOut = None
45 dictProcs = None
46 isConfig = False
47
40
48 def __init__(self):
41 def __init__(self):
49
42
50 self.dataIn = None
43 self.dataIn = None
51 self.dataOut = None
44 self.dataOut = None
52 self.isConfig = False
45 self.isConfig = False
53 self.operations = []
46 self.operations = []
47 self.plots = []
54
48
55 def getAllowedArgs(self):
49 def getAllowedArgs(self):
56 if hasattr(self, '__attrs__'):
50 if hasattr(self, '__attrs__'):
57 return self.__attrs__
51 return self.__attrs__
58 else:
52 else:
59 return inspect.getargspec(self.run).args
53 return inspect.getargspec(self.run).args
60
61 def addOperation(self, conf, operation):
62
54
55 def addOperation(self, conf, operation):
63 """
56 """
64 This method is used in the controller, and update the dictionary containing the operations to execute. The dict
57 This method is used in the controller, and update the dictionary containing the operations to execute. The dict
65 posses the id of the operation process (IPC purposes)
58 posses the id of the operation process (IPC purposes)
66
59
67 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
60 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
68 identificador asociado a este objeto.
61 identificador asociado a este objeto.
69
62
70 Input:
63 Input:
71
64
72 object : objeto de la clase "Operation"
65 object : objeto de la clase "Operation"
73
66
74 Return:
67 Return:
75
68
76 objId : identificador del objeto, necesario para comunicar con master(procUnit)
69 objId : identificador del objeto, necesario para comunicar con master(procUnit)
77 """
70 """
78
71
79 self.operations.append((operation, conf.type, conf.id, conf.getKwargs()))
72 self.operations.append(
73 (operation, conf.type, conf.id, conf.getKwargs()))
74
75 if 'plot' in self.name.lower():
76 self.plots.append(operation.CODE)
80
77
81 def getOperationObj(self, objId):
78 def getOperationObj(self, objId):
82
79
83 if objId not in list(self.operations.keys()):
80 if objId not in list(self.operations.keys()):
84 return None
81 return None
85
82
86 return self.operations[objId]
83 return self.operations[objId]
87
84
88 def operation(self, **kwargs):
85 def operation(self, **kwargs):
89
90 """
86 """
91 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
87 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
92 atributos del objeto dataOut
88 atributos del objeto dataOut
93
89
94 Input:
90 Input:
95
91
96 **kwargs : Diccionario de argumentos de la funcion a ejecutar
92 **kwargs : Diccionario de argumentos de la funcion a ejecutar
97 """
93 """
98
94
99 raise NotImplementedError
95 raise NotImplementedError
100
96
101 def setup(self):
97 def setup(self):
102
98
103 raise NotImplementedError
99 raise NotImplementedError
104
100
105 def run(self):
101 def run(self):
106
102
107 raise NotImplementedError
103 raise NotImplementedError
108
104
109 def close(self):
105 def close(self):
110 #Close every thread, queue or any other object here is it is neccesary.
106
111 return
107 return
112
108
109
113 class Operation(object):
110 class Operation(object):
114
111
115 """
112 """
116 Update - Jan 2018 - MULTIPROCESSING
113 Update - Jan 2018 - MULTIPROCESSING
117
114
118 Most of the methods remained the same. The decorator parse the arguments and executed the run() method for each process.
115 Most of the methods remained the same. The decorator parse the arguments and executed the run() method for each process.
119 The constructor doe snot receive any argument, neither the baseclass.
116 The constructor doe snot receive any argument, neither the baseclass.
120
117
121
118
122 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
119 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
123 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
120 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
124 acumulacion dentro de esta clase
121 acumulacion dentro de esta clase
125
122
126 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
123 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
127
124
128 """
125 """
129 id = None
130 __buffer = None
131 dest = None
132 isConfig = False
133 readyFlag = None
134
126
135 def __init__(self):
127 def __init__(self):
136
128
137 self.buffer = None
129 self.id = None
138 self.dest = None
139 self.isConfig = False
130 self.isConfig = False
140 self.readyFlag = False
141
131
142 if not hasattr(self, 'name'):
132 if not hasattr(self, 'name'):
143 self.name = self.__class__.__name__
133 self.name = self.__class__.__name__
144
134
145 def getAllowedArgs(self):
135 def getAllowedArgs(self):
146 if hasattr(self, '__attrs__'):
136 if hasattr(self, '__attrs__'):
147 return self.__attrs__
137 return self.__attrs__
148 else:
138 else:
149 return inspect.getargspec(self.run).args
139 return inspect.getargspec(self.run).args
150
140
151 def setup(self):
141 def setup(self):
152
142
153 self.isConfig = True
143 self.isConfig = True
154
144
155 raise NotImplementedError
145 raise NotImplementedError
156
146
157
158 def run(self, dataIn, **kwargs):
147 def run(self, dataIn, **kwargs):
159
160 """
148 """
161 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
149 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
162 atributos del objeto dataIn.
150 atributos del objeto dataIn.
163
151
164 Input:
152 Input:
165
153
166 dataIn : objeto del tipo JROData
154 dataIn : objeto del tipo JROData
167
155
168 Return:
156 Return:
169
157
170 None
158 None
171
159
172 Affected:
160 Affected:
173 __buffer : buffer de recepcion de datos.
161 __buffer : buffer de recepcion de datos.
174
162
175 """
163 """
176 if not self.isConfig:
164 if not self.isConfig:
177 self.setup(**kwargs)
165 self.setup(**kwargs)
178
166
179 raise NotImplementedError
167 raise NotImplementedError
180
168
181 def close(self):
169 def close(self):
182
170
183 pass
171 return
184
172
185
173
186 def MPDecorator(BaseClass):
174 def MPDecorator(BaseClass):
187
188 """
175 """
189 Multiprocessing class decorator
176 Multiprocessing class decorator
190
177
191 This function add multiprocessing features to a BaseClass. Also, it handle
178 This function add multiprocessing features to a BaseClass. Also, it handle
192 the communication beetween processes (readers, procUnits and operations).
179 the communication beetween processes (readers, procUnits and operations).
193 """
180 """
194
181
195 class MPClass(BaseClass, Process):
182 class MPClass(BaseClass, Process):
196
183
197 def __init__(self, *args, **kwargs):
184 def __init__(self, *args, **kwargs):
198 super(MPClass, self).__init__()
185 super(MPClass, self).__init__()
199 Process.__init__(self)
186 Process.__init__(self)
200 self.operationKwargs = {}
187 self.operationKwargs = {}
201 self.args = args
188 self.args = args
202 self.kwargs = kwargs
189 self.kwargs = kwargs
203 self.sender = None
190 self.sender = None
204 self.receiver = None
191 self.receiver = None
205 self.name = BaseClass.__name__
192 self.name = BaseClass.__name__
193 self.start_time = time.time()
206
194
207 if len(self.args) is 3:
195 if len(self.args) is 3:
208 self.typeProc = "ProcUnit"
196 self.typeProc = "ProcUnit"
209 self.id = args[0]
197 self.id = args[0]
210 self.inputId = args[1]
198 self.inputId = args[1]
211 self.project_id = args[2]
199 self.project_id = args[2]
212 else:
200 elif len(self.args) is 2:
213 self.id = args[0]
201 self.id = args[0]
214 self.inputId = args[0]
202 self.inputId = args[0]
215 self.project_id = args[1]
203 self.project_id = args[1]
216 self.typeProc = "Operation"
204 self.typeProc = "Operation"
217
205
218 def getAllowedArgs(self):
219
220 if hasattr(self, '__attrs__'):
221 return self.__attrs__
222 else:
223 return inspect.getargspec(BaseClass.run).args
224
225 def subscribe(self):
206 def subscribe(self):
226 '''
207 '''
227 This function create a socket to receive objects from the
208 This function create a socket to receive objects from the
228 topic `inputId`.
209 topic `inputId`.
229 '''
210 '''
230
211
231 c = zmq.Context()
212 c = zmq.Context()
232 self.receiver = c.socket(zmq.SUB)
213 self.receiver = c.socket(zmq.SUB)
233 self.receiver.connect('ipc:///tmp/schain/{}_pub'.format(self.project_id))
214 self.receiver.connect(
215 'ipc:///tmp/schain/{}_pub'.format(self.project_id))
234 self.receiver.setsockopt(zmq.SUBSCRIBE, self.inputId.encode())
216 self.receiver.setsockopt(zmq.SUBSCRIBE, self.inputId.encode())
235
217
236 def listen(self):
218 def listen(self):
237 '''
219 '''
238 This function waits for objects and deserialize using pickle
220 This function waits for objects and deserialize using pickle
239 '''
221 '''
240
222
241 data = pickle.loads(self.receiver.recv_multipart()[1])
223 data = pickle.loads(self.receiver.recv_multipart()[1])
224
242 return data
225 return data
243
226
244 def set_publisher(self):
227 def set_publisher(self):
245 '''
228 '''
246 This function create a socket for publishing purposes.
229 This function create a socket for publishing purposes.
247 '''
230 '''
248
231
249 time.sleep(1)
232 time.sleep(1)
250 c = zmq.Context()
233 c = zmq.Context()
251 self.sender = c.socket(zmq.PUB)
234 self.sender = c.socket(zmq.PUB)
252 self.sender.connect('ipc:///tmp/schain/{}_sub'.format(self.project_id))
235 self.sender.connect(
236 'ipc:///tmp/schain/{}_sub'.format(self.project_id))
253
237
254 def publish(self, data, id):
238 def publish(self, data, id):
255 '''
239 '''
256 This function publish an object, to a specific topic.
240 This function publish an object, to a specific topic.
257 '''
241 '''
258
259 self.sender.send_multipart([str(id).encode(), pickle.dumps(data)])
242 self.sender.send_multipart([str(id).encode(), pickle.dumps(data)])
260
243
261 def runReader(self):
244 def runReader(self):
262 '''
245 '''
263 Run fuction for read units
246 Run fuction for read units
264 '''
247 '''
265 while True:
248 while True:
266
267 BaseClass.run(self, **self.kwargs)
268
249
269 if self.dataOut.error[0] == -1:
250 BaseClass.run(self, **self.kwargs)
270 log.error(self.dataOut.error[1])
271 self.publish('end', self.id)
272 #self.sender.send_multipart([str(self.project_id).encode(), 'end'.encode()])
273 break
274
251
275 for op, optype, id, kwargs in self.operations:
252 for op, optype, opId, kwargs in self.operations:
276 if optype=='self':
253 if optype == 'self':
277 op(**kwargs)
254 op(**kwargs)
278 elif optype=='other':
255 elif optype == 'other':
279 self.dataOut = op.run(self.dataOut, **self.kwargs)
256 self.dataOut = op.run(self.dataOut, **self.kwargs)
280 elif optype=='external':
257 elif optype == 'external':
281 self.publish(self.dataOut, opId)
258 self.publish(self.dataOut, opId)
282
259
283 if self.dataOut.flagNoData:
260 if self.dataOut.flagNoData and self.dataOut.error is None:
284 continue
261 continue
285
262
286 self.publish(self.dataOut, self.id)
263 self.publish(self.dataOut, self.id)
287
264
265 if self.dataOut.error:
266 if self.dataOut.error[0] == -1:
267 log.error(self.dataOut.error[1], self.name)
268 if self.dataOut.error[0] == 1:
269 log.success(self.dataOut.error[1], self.name)
270 # self.sender.send_multipart([str(self.project_id).encode(), 'end'.encode()])
271 break
272
273 time.sleep(1)
274
288 def runProc(self):
275 def runProc(self):
289 '''
276 '''
290 Run function for proccessing units
277 Run function for proccessing units
291 '''
278 '''
292
279
293 while True:
280 while True:
294 self.dataIn = self.listen()
281 self.dataIn = self.listen()
295
282
296 if self.dataIn == 'end':
283 if self.dataIn.flagNoData and self.dataIn.error is None:
297 self.publish('end', self.id)
298 for op, optype, opId, kwargs in self.operations:
299 if optype == 'external':
300 self.publish('end', opId)
301 break
302
303 if self.dataIn.flagNoData:
304 continue
284 continue
305
285
306 BaseClass.run(self, **self.kwargs)
286 BaseClass.run(self, **self.kwargs)
307
287
308 for op, optype, opId, kwargs in self.operations:
288 for op, optype, opId, kwargs in self.operations:
309 if optype=='self':
289 if optype == 'self':
310 op(**kwargs)
290 op(**kwargs)
311 elif optype=='other':
291 elif optype == 'other':
312 self.dataOut = op.run(self.dataOut, **kwargs)
292 self.dataOut = op.run(self.dataOut, **kwargs)
313 elif optype=='external':
293 elif optype == 'external':
314 self.publish(self.dataOut, opId)
294 self.publish(self.dataOut, opId)
315
295
316 if self.dataOut.flagNoData:
317 continue
318
319 self.publish(self.dataOut, self.id)
296 self.publish(self.dataOut, self.id)
297 if self.dataIn.error:
298 break
299
300 time.sleep(1)
320
301
321 def runOp(self):
302 def runOp(self):
322 '''
303 '''
323 Run function for operations
304 Run function for external operations (this operations just receive data
305 ex: plots, writers, publishers)
324 '''
306 '''
325
307
326 while True:
308 while True:
327
309
328 dataOut = self.listen()
310 dataOut = self.listen()
329
311
330 if dataOut == 'end':
331 break
332
333 BaseClass.run(self, dataOut, **self.kwargs)
312 BaseClass.run(self, dataOut, **self.kwargs)
334
313
314 if dataOut.error:
315 break
316 time.sleep(1)
317
335 def run(self):
318 def run(self):
336
319
337 if self.typeProc is "ProcUnit":
320 if self.typeProc is "ProcUnit":
338
321
339 if self.inputId is not None:
322 if self.inputId is not None:
340 self.subscribe()
323 self.subscribe()
341 self.set_publisher()
324 self.set_publisher()
342
325
343 if 'Reader' not in BaseClass.__name__:
326 if 'Reader' not in BaseClass.__name__:
344 self.runProc()
327 self.runProc()
345 else:
328 else:
346 self.runReader()
329 self.runReader()
347
330
348 elif self.typeProc is "Operation":
331 elif self.typeProc is "Operation":
349
332
350 self.subscribe()
333 self.subscribe()
351 self.runOp()
334 self.runOp()
352
335
353 else:
336 else:
354 raise ValueError("Unknown type")
337 raise ValueError("Unknown type")
355
338
356 print("%s done" % BaseClass.__name__)
357 self.close()
339 self.close()
358
340
341 def event_monitor(self, monitor):
342
343 events = {}
344
345 for name in dir(zmq):
346 if name.startswith('EVENT_'):
347 value = getattr(zmq, name)
348 events[value] = name
349
350 while monitor.poll():
351 evt = recv_monitor_message(monitor)
352 if evt['event'] == 32:
353 self.connections += 1
354 if evt['event'] == 512:
355 pass
356
357 evt.update({'description': events[evt['event']]})
358
359 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
360 break
361 monitor.close()
362 print('event monitor thread done!')
363
359 def close(self):
364 def close(self):
360
365
366 BaseClass.close(self)
367
361 if self.sender:
368 if self.sender:
362 self.sender.close()
369 self.sender.close()
363
370
364 if self.receiver:
371 if self.receiver:
365 self.receiver.close()
372 self.receiver.close()
366
373
367 return MPClass No newline at end of file
374 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
375
376 return MPClass
This diff has been collapsed as it changes many lines, (612 lines changed) Show them Hide them
@@ -1,869 +1,309
1 '''
1 '''
2 @author: Juan C. Espinoza
2 @author: Juan C. Espinoza
3 '''
3 '''
4
4
5 import os
5 import os
6 import glob
6 import glob
7 import time
7 import time
8 import json
8 import json
9 import numpy
9 import numpy
10 import paho.mqtt.client as mqtt
11 import zmq
10 import zmq
12 import datetime
11 import datetime
13 import ftplib
12 import ftplib
14 from zmq.utils.monitor import recv_monitor_message
15 from functools import wraps
13 from functools import wraps
16 from threading import Thread
14 from threading import Thread
17 from multiprocessing import Process
15 from multiprocessing import Process
18
16
19 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
17 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
20 from schainpy.model.data.jrodata import JROData
18 from schainpy.model.data.jrodata import JROData
21 from schainpy.utils import log
19 from schainpy.utils import log
22
20
23 MAXNUMX = 500
21 MAXNUMX = 500
24 MAXNUMY = 500
22 MAXNUMY = 500
25
23
26 PLOT_CODES = {
24 PLOT_CODES = {
27 'rti': 0, # Range time intensity (RTI).
25 'rti': 0, # Range time intensity (RTI).
28 'spc': 1, # Spectra (and Cross-spectra) information.
26 'spc': 1, # Spectra (and Cross-spectra) information.
29 'cspc': 2, # Cross-Correlation information.
27 'cspc': 2, # Cross-Correlation information.
30 'coh': 3, # Coherence map.
28 'coh': 3, # Coherence map.
31 'base': 4, # Base lines graphic.
29 'base': 4, # Base lines graphic.
32 'row': 5, # Row Spectra.
30 'row': 5, # Row Spectra.
33 'total': 6, # Total Power.
31 'total': 6, # Total Power.
34 'drift': 7, # Drifts graphics.
32 'drift': 7, # Drifts graphics.
35 'height': 8, # Height profile.
33 'height': 8, # Height profile.
36 'phase': 9, # Signal Phase.
34 'phase': 9, # Signal Phase.
37 'power': 16,
35 'power': 16,
38 'noise': 17,
36 'noise': 17,
39 'beacon': 18,
37 'beacon': 18,
40 'wind': 22,
38 'wind': 22,
41 'skymap': 23,
39 'skymap': 23,
42 'Unknown': 24,
40 'Unknown': 24,
43 'V-E': 25, # PIP Velocity.
41 'V-E': 25, # PIP Velocity.
44 'Z-E': 26, # PIP Reflectivity.
42 'Z-E': 26, # PIP Reflectivity.
45 'V-A': 27, # RHI Velocity.
43 'V-A': 27, # RHI Velocity.
46 'Z-A': 28, # RHI Reflectivity.
44 'Z-A': 28, # RHI Reflectivity.
47 }
45 }
48
46
49 def get_plot_code(s):
47 def get_plot_code(s):
50 label = s.split('_')[0]
48 label = s.split('_')[0]
51 codes = [key for key in PLOT_CODES if key in label]
49 codes = [key for key in PLOT_CODES if key in label]
52 if codes:
50 if codes:
53 return PLOT_CODES[codes[0]]
51 return PLOT_CODES[codes[0]]
54 else:
52 else:
55 return 24
53 return 24
56
54
57 def roundFloats(obj):
58 if isinstance(obj, list):
59 return list(map(roundFloats, obj))
60 elif isinstance(obj, float):
61 return round(obj, 2)
62
63 def decimate(z, MAXNUMY):
55 def decimate(z, MAXNUMY):
64 dy = int(len(z[0])/MAXNUMY) + 1
56 dy = int(len(z[0])/MAXNUMY) + 1
65
57
66 return z[::, ::dy]
58 return z[::, ::dy]
67
59
68 class throttle(object):
69 '''
70 Decorator that prevents a function from being called more than once every
71 time period.
72 To create a function that cannot be called more than once a minute, but
73 will sleep until it can be called:
74 @throttle(minutes=1)
75 def foo():
76 pass
77
78 for i in range(10):
79 foo()
80 print "This function has run %s times." % i
81 '''
82
83 def __init__(self, seconds=0, minutes=0, hours=0):
84 self.throttle_period = datetime.timedelta(
85 seconds=seconds, minutes=minutes, hours=hours
86 )
87
88 self.time_of_last_call = datetime.datetime.min
89
90 def __call__(self, fn):
91 @wraps(fn)
92 def wrapper(*args, **kwargs):
93 coerce = kwargs.pop('coerce', None)
94 if coerce:
95 self.time_of_last_call = datetime.datetime.now()
96 return fn(*args, **kwargs)
97 else:
98 now = datetime.datetime.now()
99 time_since_last_call = now - self.time_of_last_call
100 time_left = self.throttle_period - time_since_last_call
101
102 if time_left > datetime.timedelta(seconds=0):
103 return
104
105 self.time_of_last_call = datetime.datetime.now()
106 return fn(*args, **kwargs)
107
108 return wrapper
109
110 class Data(object):
111 '''
112 Object to hold data to be plotted
113 '''
114
115 def __init__(self, plottypes, throttle_value, exp_code, buffering=True):
116 self.plottypes = plottypes
117 self.throttle = throttle_value
118 self.exp_code = exp_code
119 self.buffering = buffering
120 self.ended = False
121 self.localtime = False
122 self.meta = {}
123 self.__times = []
124 self.__heights = []
125
126 def __str__(self):
127 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
128 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
129
130 def __len__(self):
131 return len(self.__times)
132
133 def __getitem__(self, key):
134 if key not in self.data:
135 raise KeyError(log.error('Missing key: {}'.format(key)))
136
137 if 'spc' in key or not self.buffering:
138 ret = self.data[key]
139 else:
140 ret = numpy.array([self.data[key][x] for x in self.times])
141 if ret.ndim > 1:
142 ret = numpy.swapaxes(ret, 0, 1)
143 return ret
144
145 def __contains__(self, key):
146 return key in self.data
147
148 def setup(self):
149 '''
150 Configure object
151 '''
152
153 self.type = ''
154 self.ended = False
155 self.data = {}
156 self.__times = []
157 self.__heights = []
158 self.__all_heights = set()
159 for plot in self.plottypes:
160 if 'snr' in plot:
161 plot = 'snr'
162 self.data[plot] = {}
163
164 def shape(self, key):
165 '''
166 Get the shape of the one-element data for the given key
167 '''
168
169 if len(self.data[key]):
170 if 'spc' in key or not self.buffering:
171 return self.data[key].shape
172 return self.data[key][self.__times[0]].shape
173 return (0,)
174
175 def update(self, dataOut, tm):
176 '''
177 Update data object with new dataOut
178 '''
179
180 if tm in self.__times:
181 return
182
183 self.type = dataOut.type
184 self.parameters = getattr(dataOut, 'parameters', [])
185 if hasattr(dataOut, 'pairsList'):
186 self.pairs = dataOut.pairsList
187 if hasattr(dataOut, 'meta'):
188 self.meta = dataOut.meta
189 self.channels = dataOut.channelList
190 self.interval = dataOut.getTimeInterval()
191 self.localtime = dataOut.useLocalTime
192 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
193 self.xrange = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
194 self.__heights.append(dataOut.heightList)
195 self.__all_heights.update(dataOut.heightList)
196 self.__times.append(tm)
197
198 for plot in self.plottypes:
199 if plot == 'spc':
200 z = dataOut.data_spc/dataOut.normFactor
201 buffer = 10*numpy.log10(z)
202 if plot == 'cspc':
203 buffer = dataOut.data_cspc
204 if plot == 'noise':
205 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
206 if plot == 'rti':
207 buffer = dataOut.getPower()
208 if plot == 'snr_db':
209 buffer = dataOut.data_SNR
210 if plot == 'snr':
211 buffer = 10*numpy.log10(dataOut.data_SNR)
212 if plot == 'dop':
213 buffer = 10*numpy.log10(dataOut.data_DOP)
214 if plot == 'mean':
215 buffer = dataOut.data_MEAN
216 if plot == 'std':
217 buffer = dataOut.data_STD
218 if plot == 'coh':
219 buffer = dataOut.getCoherence()
220 if plot == 'phase':
221 buffer = dataOut.getCoherence(phase=True)
222 if plot == 'output':
223 buffer = dataOut.data_output
224 if plot == 'param':
225 buffer = dataOut.data_param
226
227 if 'spc' in plot:
228 self.data[plot] = buffer
229 else:
230 if self.buffering:
231 self.data[plot][tm] = buffer
232 else:
233 self.data[plot] = buffer
234
235 def normalize_heights(self):
236 '''
237 Ensure same-dimension of the data for different heighList
238 '''
239
240 H = numpy.array(list(self.__all_heights))
241 H.sort()
242 for key in self.data:
243 shape = self.shape(key)[:-1] + H.shape
244 for tm, obj in list(self.data[key].items()):
245 h = self.__heights[self.__times.index(tm)]
246 if H.size == h.size:
247 continue
248 index = numpy.where(numpy.in1d(H, h))[0]
249 dummy = numpy.zeros(shape) + numpy.nan
250 if len(shape) == 2:
251 dummy[:, index] = obj
252 else:
253 dummy[index] = obj
254 self.data[key][tm] = dummy
255
256 self.__heights = [H for tm in self.__times]
257
258 def jsonify(self, decimate=False):
259 '''
260 Convert data to json
261 '''
262
263 data = {}
264 tm = self.times[-1]
265 dy = int(self.heights.size/MAXNUMY) + 1
266 for key in self.data:
267 if key in ('spc', 'cspc') or not self.buffering:
268 dx = int(self.data[key].shape[1]/MAXNUMX) + 1
269 data[key] = roundFloats(self.data[key][::, ::dx, ::dy].tolist())
270 else:
271 data[key] = roundFloats(self.data[key][tm].tolist())
272
273 ret = {'data': data}
274 ret['exp_code'] = self.exp_code
275 ret['time'] = tm
276 ret['interval'] = self.interval
277 ret['localtime'] = self.localtime
278 ret['yrange'] = roundFloats(self.heights[::dy].tolist())
279 if 'spc' in self.data or 'cspc' in self.data:
280 ret['xrange'] = roundFloats(self.xrange[2][::dx].tolist())
281 else:
282 ret['xrange'] = []
283 if hasattr(self, 'pairs'):
284 ret['pairs'] = self.pairs
285 else:
286 ret['pairs'] = []
287
288 for key, value in list(self.meta.items()):
289 ret[key] = value
290
291 return json.dumps(ret)
292
293 @property
294 def times(self):
295 '''
296 Return the list of times of the current data
297 '''
298
299 ret = numpy.array(self.__times)
300 ret.sort()
301 return ret
302
303 @property
304 def heights(self):
305 '''
306 Return the list of heights of the current data
307 '''
308
309 return numpy.array(self.__heights[-1])
310
60
311 class PublishData(Operation):
61 class PublishData(Operation):
312 '''
62 '''
313 Operation to send data over zmq.
63 Operation to send data over zmq.
314 '''
64 '''
315
65
316 __attrs__ = ['host', 'port', 'delay', 'zeromq', 'mqtt', 'verbose']
66 __attrs__ = ['host', 'port', 'delay', 'verbose']
317
67
318 def __init__(self, **kwargs):
68 def __init__(self, **kwargs):
319 """Inicio."""
69 """Inicio."""
320 Operation.__init__(self, **kwargs)
70 Operation.__init__(self, **kwargs)
321 self.isConfig = False
71 self.isConfig = False
322 self.client = None
323 self.zeromq = None
324 self.mqtt = None
325
72
326 def on_disconnect(self, client, userdata, rc):
73 def setup(self, server='zmq.pipe', delay=0, verbose=True, **kwargs):
327 if rc != 0:
328 log.warning('Unexpected disconnection.')
329 self.connect()
330
331 def connect(self):
332 log.warning('trying to connect')
333 try:
334 self.client.connect(
335 host=self.host,
336 port=self.port,
337 keepalive=60*10,
338 bind_address='')
339 self.client.loop_start()
340 # self.client.publish(
341 # self.topic + 'SETUP',
342 # json.dumps(setup),
343 # retain=True
344 # )
345 except:
346 log.error('MQTT Conection error.')
347 self.client = False
348
349 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
350 self.counter = 0
74 self.counter = 0
351 self.topic = kwargs.get('topic', 'schain')
352 self.delay = kwargs.get('delay', 0)
75 self.delay = kwargs.get('delay', 0)
353 self.plottype = kwargs.get('plottype', 'spectra')
354 self.host = kwargs.get('host', "10.10.10.82")
355 self.port = kwargs.get('port', 3000)
356 self.clientId = clientId
357 self.cnt = 0
76 self.cnt = 0
358 self.zeromq = zeromq
359 self.mqtt = kwargs.get('plottype', 0)
360 self.client = None
361 self.verbose = verbose
77 self.verbose = verbose
362 setup = []
78 setup = []
363 if mqtt is 1:
79 context = zmq.Context()
364 self.client = mqtt.Client(
80 self.zmq_socket = context.socket(zmq.PUSH)
365 client_id=self.clientId + self.topic + 'SCHAIN',
81 server = kwargs.get('server', 'zmq.pipe')
366 clean_session=True)
82
367 self.client.on_disconnect = self.on_disconnect
83 if 'tcp://' in server:
368 self.connect()
84 address = server
369 for plot in self.plottype:
85 else:
370 setup.append({
86 address = 'ipc:///tmp/%s' % server
371 'plot': plot,
87
372 'topic': self.topic + plot,
88 self.zmq_socket.connect(address)
373 'title': getattr(self, plot + '_' + 'title', False),
89 time.sleep(1)
374 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
375 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
376 'xrange': getattr(self, plot + '_' + 'xrange', False),
377 'yrange': getattr(self, plot + '_' + 'yrange', False),
378 'zrange': getattr(self, plot + '_' + 'zrange', False),
379 })
380 if zeromq is 1:
381 context = zmq.Context()
382 self.zmq_socket = context.socket(zmq.PUSH)
383 server = kwargs.get('server', 'zmq.pipe')
384
385 if 'tcp://' in server:
386 address = server
387 else:
388 address = 'ipc:///tmp/%s' % server
389
390 self.zmq_socket.connect(address)
391 time.sleep(1)
392
90
393
91
394 def publish_data(self):
92 def publish_data(self):
395 self.dataOut.finished = False
93 self.dataOut.finished = False
396 if self.mqtt is 1:
94
397 yData = self.dataOut.heightList[:2].tolist()
95 if self.verbose:
398 if self.plottype == 'spectra':
96 log.log(
399 data = getattr(self.dataOut, 'data_spc')
97 'Sending {} - {}'.format(self.dataOut.type, self.dataOut.datatime),
400 z = data/self.dataOut.normFactor
98 self.name
401 zdB = 10*numpy.log10(z)
99 )
402 xlen, ylen = zdB[0].shape
100 self.zmq_socket.send_pyobj(self.dataOut)
403 dx = int(xlen/MAXNUMX) + 1
404 dy = int(ylen/MAXNUMY) + 1
405 Z = [0 for i in self.dataOut.channelList]
406 for i in self.dataOut.channelList:
407 Z[i] = zdB[i][::dx, ::dy].tolist()
408 payload = {
409 'timestamp': self.dataOut.utctime,
410 'data': roundFloats(Z),
411 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
412 'interval': self.dataOut.getTimeInterval(),
413 'type': self.plottype,
414 'yData': yData
415 }
416
417 elif self.plottype in ('rti', 'power'):
418 data = getattr(self.dataOut, 'data_spc')
419 z = data/self.dataOut.normFactor
420 avg = numpy.average(z, axis=1)
421 avgdB = 10*numpy.log10(avg)
422 xlen, ylen = z[0].shape
423 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
424 AVG = [0 for i in self.dataOut.channelList]
425 for i in self.dataOut.channelList:
426 AVG[i] = avgdB[i][::dy].tolist()
427 payload = {
428 'timestamp': self.dataOut.utctime,
429 'data': roundFloats(AVG),
430 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
431 'interval': self.dataOut.getTimeInterval(),
432 'type': self.plottype,
433 'yData': yData
434 }
435 elif self.plottype == 'noise':
436 noise = self.dataOut.getNoise()/self.dataOut.normFactor
437 noisedB = 10*numpy.log10(noise)
438 payload = {
439 'timestamp': self.dataOut.utctime,
440 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
441 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
442 'interval': self.dataOut.getTimeInterval(),
443 'type': self.plottype,
444 'yData': yData
445 }
446 elif self.plottype == 'snr':
447 data = getattr(self.dataOut, 'data_SNR')
448 avgdB = 10*numpy.log10(data)
449
450 ylen = data[0].size
451 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
452 AVG = [0 for i in self.dataOut.channelList]
453 for i in self.dataOut.channelList:
454 AVG[i] = avgdB[i][::dy].tolist()
455 payload = {
456 'timestamp': self.dataOut.utctime,
457 'data': roundFloats(AVG),
458 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
459 'type': self.plottype,
460 'yData': yData
461 }
462 else:
463 print("Tipo de grafico invalido")
464 payload = {
465 'data': 'None',
466 'timestamp': 'None',
467 'type': None
468 }
469
470 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
471
472 if self.zeromq is 1:
473 if self.verbose:
474 log.log(
475 'Sending {} - {}'.format(self.dataOut.type, self.dataOut.datatime),
476 self.name
477 )
478 self.zmq_socket.send_pyobj(self.dataOut)
479
101
480 def run(self, dataOut, **kwargs):
102 def run(self, dataOut, **kwargs):
481 self.dataOut = dataOut
103 self.dataOut = dataOut
482 if not self.isConfig:
104 if not self.isConfig:
483 self.setup(**kwargs)
105 self.setup(**kwargs)
484 self.isConfig = True
106 self.isConfig = True
485
107
486 self.publish_data()
108 self.publish_data()
487 time.sleep(self.delay)
109 time.sleep(self.delay)
488
110
489 def close(self):
111 def close(self):
490 if self.zeromq is 1:
112
491 self.dataOut.finished = True
113 self.dataOut.finished = True
492 self.zmq_socket.send_pyobj(self.dataOut)
114 self.zmq_socket.send_pyobj(self.dataOut)
493 time.sleep(0.1)
115 time.sleep(0.1)
494 self.zmq_socket.close()
116 self.zmq_socket.close()
495 if self.client:
117
496 self.client.loop_stop()
497 self.client.disconnect()
498
499
118
500 class ReceiverData(ProcessingUnit):
119 class ReceiverData(ProcessingUnit):
501
120
502 __attrs__ = ['server']
121 __attrs__ = ['server']
503
122
504 def __init__(self, **kwargs):
123 def __init__(self, **kwargs):
505
124
506 ProcessingUnit.__init__(self, **kwargs)
125 ProcessingUnit.__init__(self, **kwargs)
507
126
508 self.isConfig = False
127 self.isConfig = False
509 server = kwargs.get('server', 'zmq.pipe')
128 server = kwargs.get('server', 'zmq.pipe')
510 if 'tcp://' in server:
129 if 'tcp://' in server:
511 address = server
130 address = server
512 else:
131 else:
513 address = 'ipc:///tmp/%s' % server
132 address = 'ipc:///tmp/%s' % server
514
133
515 self.address = address
134 self.address = address
516 self.dataOut = JROData()
135 self.dataOut = JROData()
517
136
518 def setup(self):
137 def setup(self):
519
138
520 self.context = zmq.Context()
139 self.context = zmq.Context()
521 self.receiver = self.context.socket(zmq.PULL)
140 self.receiver = self.context.socket(zmq.PULL)
522 self.receiver.bind(self.address)
141 self.receiver.bind(self.address)
523 time.sleep(0.5)
142 time.sleep(0.5)
524 log.success('ReceiverData from {}'.format(self.address))
143 log.success('ReceiverData from {}'.format(self.address))
525
144
526
145
527 def run(self):
146 def run(self):
528
147
529 if not self.isConfig:
148 if not self.isConfig:
530 self.setup()
149 self.setup()
531 self.isConfig = True
150 self.isConfig = True
532
151
533 self.dataOut = self.receiver.recv_pyobj()
152 self.dataOut = self.receiver.recv_pyobj()
534 log.log('{} - {}'.format(self.dataOut.type,
153 log.log('{} - {}'.format(self.dataOut.type,
535 self.dataOut.datatime.ctime(),),
154 self.dataOut.datatime.ctime(),),
536 'Receiving')
155 'Receiving')
537
156
538
157
539 class PlotterReceiver(ProcessingUnit, Process):
540
541 throttle_value = 5
542 __attrs__ = ['server', 'plottypes', 'realtime', 'localtime', 'throttle',
543 'exp_code', 'web_server', 'buffering']
544
545 def __init__(self, **kwargs):
546
547 ProcessingUnit.__init__(self, **kwargs)
548 Process.__init__(self)
549 self.mp = False
550 self.isConfig = False
551 self.isWebConfig = False
552 self.connections = 0
553 server = kwargs.get('server', 'zmq.pipe')
554 web_server = kwargs.get('web_server', None)
555 if 'tcp://' in server:
556 address = server
557 else:
558 address = 'ipc:///tmp/%s' % server
559 self.address = address
560 self.web_address = web_server
561 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
562 self.realtime = kwargs.get('realtime', False)
563 self.localtime = kwargs.get('localtime', True)
564 self.buffering = kwargs.get('buffering', True)
565 self.throttle_value = kwargs.get('throttle', 5)
566 self.exp_code = kwargs.get('exp_code', None)
567 self.sendData = self.initThrottle(self.throttle_value)
568 self.dates = []
569 self.setup()
570
571 def setup(self):
572
573 self.data = Data(self.plottypes, self.throttle_value, self.exp_code, self.buffering)
574 self.isConfig = True
575
576 def event_monitor(self, monitor):
577
578 events = {}
579
580 for name in dir(zmq):
581 if name.startswith('EVENT_'):
582 value = getattr(zmq, name)
583 events[value] = name
584
585 while monitor.poll():
586 evt = recv_monitor_message(monitor)
587 if evt['event'] == 32:
588 self.connections += 1
589 if evt['event'] == 512:
590 pass
591
592 evt.update({'description': events[evt['event']]})
593
594 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
595 break
596 monitor.close()
597 print('event monitor thread done!')
598
599 def initThrottle(self, throttle_value):
600
601 @throttle(seconds=throttle_value)
602 def sendDataThrottled(fn_sender, data):
603 fn_sender(data)
604
605 return sendDataThrottled
606
607 def send(self, data):
608 log.log('Sending {}'.format(data), self.name)
609 self.sender.send_pyobj(data)
610
611 def run(self):
612
613 log.log(
614 'Starting from {}'.format(self.address),
615 self.name
616 )
617
618 self.context = zmq.Context()
619 self.receiver = self.context.socket(zmq.PULL)
620 self.receiver.bind(self.address)
621 monitor = self.receiver.get_monitor_socket()
622 self.sender = self.context.socket(zmq.PUB)
623 if self.web_address:
624 log.success(
625 'Sending to web: {}'.format(self.web_address),
626 self.name
627 )
628 self.sender_web = self.context.socket(zmq.REQ)
629 self.sender_web.connect(self.web_address)
630 self.poll = zmq.Poller()
631 self.poll.register(self.sender_web, zmq.POLLIN)
632 time.sleep(1)
633
634 if 'server' in self.kwargs:
635 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
636 else:
637 self.sender.bind("ipc:///tmp/zmq.plots")
638
639 time.sleep(2)
640
641 t = Thread(target=self.event_monitor, args=(monitor,))
642 t.start()
643
644 while True:
645 dataOut = self.receiver.recv_pyobj()
646 if not dataOut.flagNoData:
647 if dataOut.type == 'Parameters':
648 tm = dataOut.utctimeInit
649 else:
650 tm = dataOut.utctime
651 if dataOut.useLocalTime:
652 if not self.localtime:
653 tm += time.timezone
654 dt = datetime.datetime.fromtimestamp(tm).date()
655 else:
656 if self.localtime:
657 tm -= time.timezone
658 dt = datetime.datetime.utcfromtimestamp(tm).date()
659 coerce = False
660 if dt not in self.dates:
661 if self.data:
662 self.data.ended = True
663 self.send(self.data)
664 coerce = True
665 self.data.setup()
666 self.dates.append(dt)
667
668 self.data.update(dataOut, tm)
669
670 if dataOut.finished is True:
671 self.connections -= 1
672 if self.connections == 0 and dt in self.dates:
673 self.data.ended = True
674 self.send(self.data)
675 # self.data.setup()
676 time.sleep(1)
677 break
678 else:
679 if self.realtime:
680 self.send(self.data)
681 if self.web_address:
682 retries = 5
683 while True:
684 self.sender_web.send(self.data.jsonify())
685 socks = dict(self.poll.poll(5000))
686 if socks.get(self.sender_web) == zmq.POLLIN:
687 reply = self.sender_web.recv_string()
688 if reply == 'ok':
689 log.log("Response from server ok", self.name)
690 break
691 else:
692 log.warning("Malformed reply from server: {}".format(reply), self.name)
693
694 else:
695 log.warning("No response from server, retrying...", self.name)
696 self.sender_web.setsockopt(zmq.LINGER, 0)
697 self.sender_web.close()
698 self.poll.unregister(self.sender_web)
699 retries -= 1
700 if retries == 0:
701 log.error("Server seems to be offline, abandoning", self.name)
702 self.sender_web = self.context.socket(zmq.REQ)
703 self.sender_web.connect(self.web_address)
704 self.poll.register(self.sender_web, zmq.POLLIN)
705 time.sleep(1)
706 break
707 self.sender_web = self.context.socket(zmq.REQ)
708 self.sender_web.connect(self.web_address)
709 self.poll.register(self.sender_web, zmq.POLLIN)
710 time.sleep(1)
711 else:
712 self.sendData(self.send, self.data, coerce=coerce)
713 coerce = False
714
715 return
716
717
718 class SendToFTP(Operation, Process):
158 class SendToFTP(Operation, Process):
719
159
720 '''
160 '''
721 Operation to send data over FTP.
161 Operation to send data over FTP.
722 '''
162 '''
723
163
724 __attrs__ = ['server', 'username', 'password', 'patterns', 'timeout']
164 __attrs__ = ['server', 'username', 'password', 'patterns', 'timeout']
725
165
726 def __init__(self, **kwargs):
166 def __init__(self, **kwargs):
727 '''
167 '''
728 patterns = [(local1, remote1, ext, delay, exp_code, sub_exp_code), ...]
168 patterns = [(local1, remote1, ext, delay, exp_code, sub_exp_code), ...]
729 '''
169 '''
730 Operation.__init__(self, **kwargs)
170 Operation.__init__(self, **kwargs)
731 Process.__init__(self)
171 Process.__init__(self)
732 self.server = kwargs.get('server')
172 self.server = kwargs.get('server')
733 self.username = kwargs.get('username')
173 self.username = kwargs.get('username')
734 self.password = kwargs.get('password')
174 self.password = kwargs.get('password')
735 self.patterns = kwargs.get('patterns')
175 self.patterns = kwargs.get('patterns')
736 self.timeout = kwargs.get('timeout', 30)
176 self.timeout = kwargs.get('timeout', 30)
737 self.times = [time.time() for p in self.patterns]
177 self.times = [time.time() for p in self.patterns]
738 self.latest = ['' for p in self.patterns]
178 self.latest = ['' for p in self.patterns]
739 self.mp = False
179 self.mp = False
740 self.ftp = None
180 self.ftp = None
741
181
742 def setup(self):
182 def setup(self):
743
183
744 log.log('Connecting to ftp://{}'.format(self.server), self.name)
184 log.log('Connecting to ftp://{}'.format(self.server), self.name)
745 try:
185 try:
746 self.ftp = ftplib.FTP(self.server, timeout=self.timeout)
186 self.ftp = ftplib.FTP(self.server, timeout=self.timeout)
747 except ftplib.all_errors:
187 except ftplib.all_errors:
748 log.error('Server connection fail: {}'.format(self.server), self.name)
188 log.error('Server connection fail: {}'.format(self.server), self.name)
749 if self.ftp is not None:
189 if self.ftp is not None:
750 self.ftp.close()
190 self.ftp.close()
751 self.ftp = None
191 self.ftp = None
752 self.isConfig = False
192 self.isConfig = False
753 return
193 return
754
194
755 try:
195 try:
756 self.ftp.login(self.username, self.password)
196 self.ftp.login(self.username, self.password)
757 except ftplib.all_errors:
197 except ftplib.all_errors:
758 log.error('The given username y/o password are incorrect', self.name)
198 log.error('The given username y/o password are incorrect', self.name)
759 if self.ftp is not None:
199 if self.ftp is not None:
760 self.ftp.close()
200 self.ftp.close()
761 self.ftp = None
201 self.ftp = None
762 self.isConfig = False
202 self.isConfig = False
763 return
203 return
764
204
765 log.success('Connection success', self.name)
205 log.success('Connection success', self.name)
766 self.isConfig = True
206 self.isConfig = True
767 return
207 return
768
208
769 def check(self):
209 def check(self):
770
210
771 try:
211 try:
772 self.ftp.voidcmd("NOOP")
212 self.ftp.voidcmd("NOOP")
773 except:
213 except:
774 log.warning('Connection lost... trying to reconnect', self.name)
214 log.warning('Connection lost... trying to reconnect', self.name)
775 if self.ftp is not None:
215 if self.ftp is not None:
776 self.ftp.close()
216 self.ftp.close()
777 self.ftp = None
217 self.ftp = None
778 self.setup()
218 self.setup()
779
219
780 def find_files(self, path, ext):
220 def find_files(self, path, ext):
781
221
782 files = glob.glob1(path, '*{}'.format(ext))
222 files = glob.glob1(path, '*{}'.format(ext))
783 files.sort()
223 files.sort()
784 if files:
224 if files:
785 return files[-1]
225 return files[-1]
786 return None
226 return None
787
227
788 def getftpname(self, filename, exp_code, sub_exp_code):
228 def getftpname(self, filename, exp_code, sub_exp_code):
789
229
790 thisDatetime = datetime.datetime.strptime(filename.split('_')[1], '%Y%m%d')
230 thisDatetime = datetime.datetime.strptime(filename.split('_')[1], '%Y%m%d')
791 YEAR_STR = '%4.4d'%thisDatetime.timetuple().tm_year
231 YEAR_STR = '%4.4d'%thisDatetime.timetuple().tm_year
792 DOY_STR = '%3.3d'%thisDatetime.timetuple().tm_yday
232 DOY_STR = '%3.3d'%thisDatetime.timetuple().tm_yday
793 exp_code = '%3.3d'%exp_code
233 exp_code = '%3.3d'%exp_code
794 sub_exp_code = '%2.2d'%sub_exp_code
234 sub_exp_code = '%2.2d'%sub_exp_code
795 plot_code = '%2.2d'% get_plot_code(filename)
235 plot_code = '%2.2d'% get_plot_code(filename)
796 name = YEAR_STR + DOY_STR + '00' + exp_code + sub_exp_code + plot_code + '00.png'
236 name = YEAR_STR + DOY_STR + '00' + exp_code + sub_exp_code + plot_code + '00.png'
797 return name
237 return name
798
238
799 def upload(self, src, dst):
239 def upload(self, src, dst):
800
240
801 log.log('Uploading {} '.format(src), self.name, nl=False)
241 log.log('Uploading {} '.format(src), self.name, nl=False)
802
242
803 fp = open(src, 'rb')
243 fp = open(src, 'rb')
804 command = 'STOR {}'.format(dst)
244 command = 'STOR {}'.format(dst)
805
245
806 try:
246 try:
807 self.ftp.storbinary(command, fp, blocksize=1024)
247 self.ftp.storbinary(command, fp, blocksize=1024)
808 except Exception as e:
248 except Exception as e:
809 log.error('{}'.format(e), self.name)
249 log.error('{}'.format(e), self.name)
810 if self.ftp is not None:
250 if self.ftp is not None:
811 self.ftp.close()
251 self.ftp.close()
812 self.ftp = None
252 self.ftp = None
813 return 0
253 return 0
814
254
815 try:
255 try:
816 self.ftp.sendcmd('SITE CHMOD 755 {}'.format(dst))
256 self.ftp.sendcmd('SITE CHMOD 755 {}'.format(dst))
817 except Exception as e:
257 except Exception as e:
818 log.error('{}'.format(e), self.name)
258 log.error('{}'.format(e), self.name)
819 if self.ftp is not None:
259 if self.ftp is not None:
820 self.ftp.close()
260 self.ftp.close()
821 self.ftp = None
261 self.ftp = None
822 return 0
262 return 0
823
263
824 fp.close()
264 fp.close()
825 log.success('OK', tag='')
265 log.success('OK', tag='')
826 return 1
266 return 1
827
267
828 def send_files(self):
268 def send_files(self):
829
269
830 for x, pattern in enumerate(self.patterns):
270 for x, pattern in enumerate(self.patterns):
831 local, remote, ext, delay, exp_code, sub_exp_code = pattern
271 local, remote, ext, delay, exp_code, sub_exp_code = pattern
832 if time.time()-self.times[x] >= delay:
272 if time.time()-self.times[x] >= delay:
833 srcname = self.find_files(local, ext)
273 srcname = self.find_files(local, ext)
834 src = os.path.join(local, srcname)
274 src = os.path.join(local, srcname)
835 if os.path.getmtime(src) < time.time() - 30*60:
275 if os.path.getmtime(src) < time.time() - 30*60:
836 continue
276 continue
837
277
838 if srcname is None or srcname == self.latest[x]:
278 if srcname is None or srcname == self.latest[x]:
839 continue
279 continue
840
280
841 if 'png' in ext:
281 if 'png' in ext:
842 dstname = self.getftpname(srcname, exp_code, sub_exp_code)
282 dstname = self.getftpname(srcname, exp_code, sub_exp_code)
843 else:
283 else:
844 dstname = srcname
284 dstname = srcname
845
285
846 dst = os.path.join(remote, dstname)
286 dst = os.path.join(remote, dstname)
847
287
848 if self.upload(src, dst):
288 if self.upload(src, dst):
849 self.times[x] = time.time()
289 self.times[x] = time.time()
850 self.latest[x] = srcname
290 self.latest[x] = srcname
851 else:
291 else:
852 self.isConfig = False
292 self.isConfig = False
853 break
293 break
854
294
855 def run(self):
295 def run(self):
856
296
857 while True:
297 while True:
858 if not self.isConfig:
298 if not self.isConfig:
859 self.setup()
299 self.setup()
860 if self.ftp is not None:
300 if self.ftp is not None:
861 self.check()
301 self.check()
862 self.send_files()
302 self.send_files()
863 time.sleep(10)
303 time.sleep(10)
864
304
865 def close():
305 def close():
866
306
867 if self.ftp is not None:
307 if self.ftp is not None:
868 self.ftp.close()
308 self.ftp.close()
869 self.terminate() No newline at end of file
309 self.terminate()
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now