##// END OF EJS Templates
Add localtime anf fix pause figs
Juan C. Espinoza -
r1089:d97088881fbc
parent child
Show More
@@ -1,895 +1,922
1
1
2 import os
2 import os
3 import time
3 import time
4 import glob
4 import glob
5 import datetime
5 import datetime
6 from multiprocessing import Process
6 from multiprocessing import Process
7
7
8 import zmq
8 import zmq
9 import numpy
9 import numpy
10 import matplotlib
10 import matplotlib
11 import matplotlib.pyplot as plt
11 import matplotlib.pyplot as plt
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
14
14
15 from schainpy.model.proc.jroproc_base import Operation
15 from schainpy.model.proc.jroproc_base import Operation
16 from schainpy.utils import log
16 from schainpy.utils import log
17
17
18 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
18 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
19 blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15]
19 blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15]
20 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values)))
20 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values)))
21 matplotlib.pyplot.register_cmap(cmap=ncmap)
21 matplotlib.pyplot.register_cmap(cmap=ncmap)
22
22
23 func = lambda x, pos: '{}'.format(datetime.datetime.utcfromtimestamp(x).strftime('%H:%M'))
24
25 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'RdBu_r', 'seismic')]
23 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'RdBu_r', 'seismic')]
26
24
25 def figpause(interval):
26 backend = plt.rcParams['backend']
27 if backend in matplotlib.rcsetup.interactive_bk:
28 figManager = matplotlib._pylab_helpers.Gcf.get_active()
29 if figManager is not None:
30 canvas = figManager.canvas
31 if canvas.figure.stale:
32 canvas.draw()
33 canvas.start_event_loop(interval)
34 return
35
27 class PlotData(Operation, Process):
36 class PlotData(Operation, Process):
28 '''
37 '''
29 Base class for Schain plotting operations
38 Base class for Schain plotting operations
30 '''
39 '''
31
40
32 CODE = 'Figure'
41 CODE = 'Figure'
33 colormap = 'jro'
42 colormap = 'jro'
34 bgcolor = 'white'
43 bgcolor = 'white'
35 CONFLATE = False
44 CONFLATE = False
36 __MAXNUMX = 80
45 __MAXNUMX = 80
37 __missing = 1E30
46 __missing = 1E30
38
47
39 def __init__(self, **kwargs):
48 def __init__(self, **kwargs):
40
49
41 Operation.__init__(self, plot=True, **kwargs)
50 Operation.__init__(self, plot=True, **kwargs)
42 Process.__init__(self)
51 Process.__init__(self)
43 self.kwargs['code'] = self.CODE
52 self.kwargs['code'] = self.CODE
44 self.mp = False
53 self.mp = False
45 self.data = None
54 self.data = None
46 self.isConfig = False
55 self.isConfig = False
47 self.figures = []
56 self.figures = []
48 self.axes = []
57 self.axes = []
49 self.cb_axes = []
58 self.cb_axes = []
50 self.localtime = kwargs.pop('localtime', True)
59 self.localtime = kwargs.pop('localtime', True)
51 self.show = kwargs.get('show', True)
60 self.show = kwargs.get('show', True)
52 self.save = kwargs.get('save', False)
61 self.save = kwargs.get('save', False)
53 self.colormap = kwargs.get('colormap', self.colormap)
62 self.colormap = kwargs.get('colormap', self.colormap)
54 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
63 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
55 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
64 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
56 self.colormaps = kwargs.get('colormaps', None)
65 self.colormaps = kwargs.get('colormaps', None)
57 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
66 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
58 self.showprofile = kwargs.get('showprofile', False)
67 self.showprofile = kwargs.get('showprofile', False)
59 self.title = kwargs.get('wintitle', self.CODE.upper())
68 self.title = kwargs.get('wintitle', self.CODE.upper())
60 self.cb_label = kwargs.get('cb_label', None)
69 self.cb_label = kwargs.get('cb_label', None)
61 self.cb_labels = kwargs.get('cb_labels', None)
70 self.cb_labels = kwargs.get('cb_labels', None)
62 self.xaxis = kwargs.get('xaxis', 'frequency')
71 self.xaxis = kwargs.get('xaxis', 'frequency')
63 self.zmin = kwargs.get('zmin', None)
72 self.zmin = kwargs.get('zmin', None)
64 self.zmax = kwargs.get('zmax', None)
73 self.zmax = kwargs.get('zmax', None)
65 self.zlimits = kwargs.get('zlimits', None)
74 self.zlimits = kwargs.get('zlimits', None)
66 self.xmin = kwargs.get('xmin', None)
75 self.xmin = kwargs.get('xmin', None)
67 self.xmax = kwargs.get('xmax', None)
76 self.xmax = kwargs.get('xmax', None)
68 self.xrange = kwargs.get('xrange', 24)
77 self.xrange = kwargs.get('xrange', 24)
69 self.ymin = kwargs.get('ymin', None)
78 self.ymin = kwargs.get('ymin', None)
70 self.ymax = kwargs.get('ymax', None)
79 self.ymax = kwargs.get('ymax', None)
71 self.xlabel = kwargs.get('xlabel', None)
80 self.xlabel = kwargs.get('xlabel', None)
72 self.__MAXNUMY = kwargs.get('decimation', 100)
81 self.__MAXNUMY = kwargs.get('decimation', 100)
73 self.showSNR = kwargs.get('showSNR', False)
82 self.showSNR = kwargs.get('showSNR', False)
74 self.oneFigure = kwargs.get('oneFigure', True)
83 self.oneFigure = kwargs.get('oneFigure', True)
75 self.width = kwargs.get('width', None)
84 self.width = kwargs.get('width', None)
76 self.height = kwargs.get('height', None)
85 self.height = kwargs.get('height', None)
77 self.colorbar = kwargs.get('colorbar', True)
86 self.colorbar = kwargs.get('colorbar', True)
78 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
87 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
79 self.titles = ['' for __ in range(16)]
88 self.titles = ['' for __ in range(16)]
89
90 def __fmtTime(self, x, pos):
91 '''
92 '''
93
94 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
80
95
81 def __setup(self):
96 def __setup(self):
82 '''
97 '''
83 Common setup for all figures, here figures and axes are created
98 Common setup for all figures, here figures and axes are created
84 '''
99 '''
85
100
86 self.setup()
101 self.setup()
87
102
88 self.time_label = 'LT' if self.localtime else 'UTC'
103 self.time_label = 'LT' if self.localtime else 'UTC'
104 if self.data.localtime:
105 self.getDateTime = datetime.datetime.fromtimestamp
106 else:
107 self.getDateTime = datetime.datetime.utcfromtimestamp
89
108
90 if self.width is None:
109 if self.width is None:
91 self.width = 8
110 self.width = 8
92
111
93 self.figures = []
112 self.figures = []
94 self.axes = []
113 self.axes = []
95 self.cb_axes = []
114 self.cb_axes = []
96 self.pf_axes = []
115 self.pf_axes = []
97 self.cmaps = []
116 self.cmaps = []
98
117
99 size = '15%' if self.ncols==1 else '30%'
118 size = '15%' if self.ncols==1 else '30%'
100 pad = '4%' if self.ncols==1 else '8%'
119 pad = '4%' if self.ncols==1 else '8%'
101
120
102 if self.oneFigure:
121 if self.oneFigure:
103 if self.height is None:
122 if self.height is None:
104 self.height = 1.4*self.nrows + 1
123 self.height = 1.4*self.nrows + 1
105 fig = plt.figure(figsize=(self.width, self.height),
124 fig = plt.figure(figsize=(self.width, self.height),
106 edgecolor='k',
125 edgecolor='k',
107 facecolor='w')
126 facecolor='w')
108 self.figures.append(fig)
127 self.figures.append(fig)
109 for n in range(self.nplots):
128 for n in range(self.nplots):
110 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
129 ax = fig.add_subplot(self.nrows, self.ncols, n+1)
111 ax.tick_params(labelsize=8)
130 ax.tick_params(labelsize=8)
112 ax.firsttime = True
131 ax.firsttime = True
113 ax.index = 0
132 ax.index = 0
114 ax.press = None
133 ax.press = None
115 self.axes.append(ax)
134 self.axes.append(ax)
116 if self.showprofile:
135 if self.showprofile:
117 cax = self.__add_axes(ax, size=size, pad=pad)
136 cax = self.__add_axes(ax, size=size, pad=pad)
118 cax.tick_params(labelsize=8)
137 cax.tick_params(labelsize=8)
119 self.pf_axes.append(cax)
138 self.pf_axes.append(cax)
120 else:
139 else:
121 if self.height is None:
140 if self.height is None:
122 self.height = 3
141 self.height = 3
123 for n in range(self.nplots):
142 for n in range(self.nplots):
124 fig = plt.figure(figsize=(self.width, self.height),
143 fig = plt.figure(figsize=(self.width, self.height),
125 edgecolor='k',
144 edgecolor='k',
126 facecolor='w')
145 facecolor='w')
127 ax = fig.add_subplot(1, 1, 1)
146 ax = fig.add_subplot(1, 1, 1)
128 ax.tick_params(labelsize=8)
147 ax.tick_params(labelsize=8)
129 ax.firsttime = True
148 ax.firsttime = True
130 ax.index = 0
149 ax.index = 0
131 ax.press = None
150 ax.press = None
132 self.figures.append(fig)
151 self.figures.append(fig)
133 self.axes.append(ax)
152 self.axes.append(ax)
134 if self.showprofile:
153 if self.showprofile:
135 cax = self.__add_axes(ax, size=size, pad=pad)
154 cax = self.__add_axes(ax, size=size, pad=pad)
136 cax.tick_params(labelsize=8)
155 cax.tick_params(labelsize=8)
137 self.pf_axes.append(cax)
156 self.pf_axes.append(cax)
138
157
139 for n in range(self.nrows):
158 for n in range(self.nrows):
140 if self.colormaps is not None:
159 if self.colormaps is not None:
141 cmap = plt.get_cmap(self.colormaps[n])
160 cmap = plt.get_cmap(self.colormaps[n])
142 else:
161 else:
143 cmap = plt.get_cmap(self.colormap)
162 cmap = plt.get_cmap(self.colormap)
144 cmap.set_bad(self.bgcolor, 1.)
163 cmap.set_bad(self.bgcolor, 1.)
145 self.cmaps.append(cmap)
164 self.cmaps.append(cmap)
146
165
147 for fig in self.figures:
166 for fig in self.figures:
148 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
167 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
149 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
168 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
150 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
169 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
151 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
170 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
152 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
171 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
172 if self.show:
173 fig.show()
153
174
154 def OnKeyPress(self, event):
175 def OnKeyPress(self, event):
155 '''
176 '''
156 Event for pressing keys (up, down) change colormap
177 Event for pressing keys (up, down) change colormap
157 '''
178 '''
158 ax = event.inaxes
179 ax = event.inaxes
159 if ax in self.axes:
180 if ax in self.axes:
160 if event.key == 'down':
181 if event.key == 'down':
161 ax.index += 1
182 ax.index += 1
162 elif event.key == 'up':
183 elif event.key == 'up':
163 ax.index -= 1
184 ax.index -= 1
164 if ax.index < 0:
185 if ax.index < 0:
165 ax.index = len(CMAPS) - 1
186 ax.index = len(CMAPS) - 1
166 elif ax.index == len(CMAPS):
187 elif ax.index == len(CMAPS):
167 ax.index = 0
188 ax.index = 0
168 cmap = CMAPS[ax.index]
189 cmap = CMAPS[ax.index]
169 ax.cbar.set_cmap(cmap)
190 ax.cbar.set_cmap(cmap)
170 ax.cbar.draw_all()
191 ax.cbar.draw_all()
171 ax.plt.set_cmap(cmap)
192 ax.plt.set_cmap(cmap)
172 ax.cbar.patch.figure.canvas.draw()
193 ax.cbar.patch.figure.canvas.draw()
194 self.colormap = cmap.name
173
195
174 def OnBtnScroll(self, event):
196 def OnBtnScroll(self, event):
175 '''
197 '''
176 Event for scrolling, scale figure
198 Event for scrolling, scale figure
177 '''
199 '''
178 cb_ax = event.inaxes
200 cb_ax = event.inaxes
179 if cb_ax in [ax.cbar.ax for ax in self.axes]:
201 if cb_ax in [ax.cbar.ax for ax in self.axes]:
180 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
202 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
181 pt = ax.cbar.ax.bbox.get_points()[:,1]
203 pt = ax.cbar.ax.bbox.get_points()[:,1]
182 nrm = ax.cbar.norm
204 nrm = ax.cbar.norm
183 vmin, vmax, p0, p1, pS = (nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
205 vmin, vmax, p0, p1, pS = (nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
184 scale = 2 if event.step == 1 else 0.5
206 scale = 2 if event.step == 1 else 0.5
185 point = vmin + (vmax - vmin) / (p1 - p0)*(pS - p0)
207 point = vmin + (vmax - vmin) / (p1 - p0)*(pS - p0)
186 ax.cbar.norm.vmin = point - scale*(point - vmin)
208 ax.cbar.norm.vmin = point - scale*(point - vmin)
187 ax.cbar.norm.vmax = point - scale*(point - vmax)
209 ax.cbar.norm.vmax = point - scale*(point - vmax)
188 ax.plt.set_norm(ax.cbar.norm)
210 ax.plt.set_norm(ax.cbar.norm)
189 ax.cbar.draw_all()
211 ax.cbar.draw_all()
190 ax.cbar.patch.figure.canvas.draw()
212 ax.cbar.patch.figure.canvas.draw()
191
213
192 def onBtnPress(self, event):
214 def onBtnPress(self, event):
193 '''
215 '''
194 Event for mouse button press
216 Event for mouse button press
195 '''
217 '''
196 cb_ax = event.inaxes
218 cb_ax = event.inaxes
197 if cb_ax is None:
219 if cb_ax is None:
198 return
220 return
199
221
200 if cb_ax in [ax.cbar.ax for ax in self.axes]:
222 if cb_ax in [ax.cbar.ax for ax in self.axes]:
201 cb_ax.press = event.x, event.y
223 cb_ax.press = event.x, event.y
202 else:
224 else:
203 cb_ax.press = None
225 cb_ax.press = None
204
226
205 def onMotion(self, event):
227 def onMotion(self, event):
206 '''
228 '''
207 Event for move inside colorbar
229 Event for move inside colorbar
208 '''
230 '''
209 cb_ax = event.inaxes
231 cb_ax = event.inaxes
210 if cb_ax is None:
232 if cb_ax is None:
211 return
233 return
212 if cb_ax not in [ax.cbar.ax for ax in self.axes]:
234 if cb_ax not in [ax.cbar.ax for ax in self.axes]:
213 return
235 return
214 if cb_ax.press is None:
236 if cb_ax.press is None:
215 return
237 return
216
238
217 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
239 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
218 xprev, yprev = cb_ax.press
240 xprev, yprev = cb_ax.press
219 dx = event.x - xprev
241 dx = event.x - xprev
220 dy = event.y - yprev
242 dy = event.y - yprev
221 cb_ax.press = event.x, event.y
243 cb_ax.press = event.x, event.y
222 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
244 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
223 perc = 0.03
245 perc = 0.03
224
246
225 if event.button == 1:
247 if event.button == 1:
226 ax.cbar.norm.vmin -= (perc*scale)*numpy.sign(dy)
248 ax.cbar.norm.vmin -= (perc*scale)*numpy.sign(dy)
227 ax.cbar.norm.vmax -= (perc*scale)*numpy.sign(dy)
249 ax.cbar.norm.vmax -= (perc*scale)*numpy.sign(dy)
228 elif event.button == 3:
250 elif event.button == 3:
229 ax.cbar.norm.vmin -= (perc*scale)*numpy.sign(dy)
251 ax.cbar.norm.vmin -= (perc*scale)*numpy.sign(dy)
230 ax.cbar.norm.vmax += (perc*scale)*numpy.sign(dy)
252 ax.cbar.norm.vmax += (perc*scale)*numpy.sign(dy)
231
253
232 ax.cbar.draw_all()
254 ax.cbar.draw_all()
233 ax.plt.set_norm(ax.cbar.norm)
255 ax.plt.set_norm(ax.cbar.norm)
234 ax.cbar.patch.figure.canvas.draw()
256 ax.cbar.patch.figure.canvas.draw()
235
257
236 def onBtnRelease(self, event):
258 def onBtnRelease(self, event):
237 '''
259 '''
238 Event for mouse button release
260 Event for mouse button release
239 '''
261 '''
240 cb_ax = event.inaxes
262 cb_ax = event.inaxes
241 if cb_ax is not None:
263 if cb_ax is not None:
242 cb_ax.press = None
264 cb_ax.press = None
243
265
244 def __add_axes(self, ax, size='30%', pad='8%'):
266 def __add_axes(self, ax, size='30%', pad='8%'):
245 '''
267 '''
246 Add new axes to the given figure
268 Add new axes to the given figure
247 '''
269 '''
248 divider = make_axes_locatable(ax)
270 divider = make_axes_locatable(ax)
249 nax = divider.new_horizontal(size=size, pad=pad)
271 nax = divider.new_horizontal(size=size, pad=pad)
250 ax.figure.add_axes(nax)
272 ax.figure.add_axes(nax)
251 return nax
273 return nax
252
274
253 self.setup()
275 self.setup()
254
276
255 def setup(self):
277 def setup(self):
256 '''
278 '''
257 This method should be implemented in the child class, the following
279 This method should be implemented in the child class, the following
258 attributes should be set:
280 attributes should be set:
259
281
260 self.nrows: number of rows
282 self.nrows: number of rows
261 self.ncols: number of cols
283 self.ncols: number of cols
262 self.nplots: number of plots (channels or pairs)
284 self.nplots: number of plots (channels or pairs)
263 self.ylabel: label for Y axes
285 self.ylabel: label for Y axes
264 self.titles: list of axes title
286 self.titles: list of axes title
265
287
266 '''
288 '''
267 raise(NotImplementedError, 'Implement this method in child class')
289 raise(NotImplementedError, 'Implement this method in child class')
268
290
269 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
291 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
270 '''
292 '''
271 Create a masked array for missing data
293 Create a masked array for missing data
272 '''
294 '''
273 if x_buffer.shape[0] < 2:
295 if x_buffer.shape[0] < 2:
274 return x_buffer, y_buffer, z_buffer
296 return x_buffer, y_buffer, z_buffer
275
297
276 deltas = x_buffer[1:] - x_buffer[0:-1]
298 deltas = x_buffer[1:] - x_buffer[0:-1]
277 x_median = numpy.median(deltas)
299 x_median = numpy.median(deltas)
278
300
279 index = numpy.where(deltas > 5*x_median)
301 index = numpy.where(deltas > 5*x_median)
280
302
281 if len(index[0]) != 0:
303 if len(index[0]) != 0:
282 z_buffer[::, index[0], ::] = self.__missing
304 z_buffer[::, index[0], ::] = self.__missing
283 z_buffer = numpy.ma.masked_inside(z_buffer,
305 z_buffer = numpy.ma.masked_inside(z_buffer,
284 0.99*self.__missing,
306 0.99*self.__missing,
285 1.01*self.__missing)
307 1.01*self.__missing)
286
308
287 return x_buffer, y_buffer, z_buffer
309 return x_buffer, y_buffer, z_buffer
288
310
289 def decimate(self):
311 def decimate(self):
290
312
291 # dx = int(len(self.x)/self.__MAXNUMX) + 1
313 # dx = int(len(self.x)/self.__MAXNUMX) + 1
292 dy = int(len(self.y)/self.__MAXNUMY) + 1
314 dy = int(len(self.y)/self.__MAXNUMY) + 1
293
315
294 # x = self.x[::dx]
316 # x = self.x[::dx]
295 x = self.x
317 x = self.x
296 y = self.y[::dy]
318 y = self.y[::dy]
297 z = self.z[::, ::, ::dy]
319 z = self.z[::, ::, ::dy]
298
320
299 return x, y, z
321 return x, y, z
300
322
301 def format(self):
323 def format(self):
302 '''
324 '''
303 Set min and max values, labels, ticks and titles
325 Set min and max values, labels, ticks and titles
304 '''
326 '''
305
327
306 if self.xmin is None:
328 if self.xmin is None:
307 xmin = self.min_time
329 xmin = self.min_time
308 else:
330 else:
309 if self.xaxis is 'time':
331 if self.xaxis is 'time':
310 dt = datetime.datetime.utcfromtimestamp(self.min_time)
332 dt = self.getDateTime(self.min_time)
311 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) - datetime.datetime(1970, 1, 1)).total_seconds()
333 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) - datetime.datetime(1970, 1, 1)).total_seconds()
334 if self.data.localtime:
335 xmin += time.timezone
312 else:
336 else:
313 xmin = self.xmin
337 xmin = self.xmin
314
338
315 if self.xmax is None:
339 if self.xmax is None:
316 xmax = xmin+self.xrange*60*60
340 xmax = xmin+self.xrange*60*60
317 else:
341 else:
318 if self.xaxis is 'time':
342 if self.xaxis is 'time':
319 dt = datetime.datetime.utcfromtimestamp(self.min_time)
343 dt = self.getDateTime(self.max_time)
320 xmax = (dt.replace(hour=int(self.xmax), minute=0, second=0) - datetime.datetime(1970, 1, 1)).total_seconds()
344 xmax = (dt.replace(hour=int(self.xmax), minute=0, second=0) - datetime.datetime(1970, 1, 1)).total_seconds()
345 if self.data.localtime:
346 xmax += time.timezone
321 else:
347 else:
322 xmax = self.xmax
348 xmax = self.xmax
323
349
324 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
350 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
325 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
351 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
326
352
327 Y = numpy.array([10, 20, 50, 100, 200, 500, 1000, 2000])
353 Y = numpy.array([10, 20, 50, 100, 200, 500, 1000, 2000])
328 i = 1 if numpy.where(ymax < Y)[0][0] < 0 else numpy.where(ymax < Y)[0][0]
354 i = 1 if numpy.where(ymax < Y)[0][0] < 0 else numpy.where(ymax < Y)[0][0]
329 ystep = Y[i-1]/5
355 ystep = Y[i-1]/5
330
356
331 for n, ax in enumerate(self.axes):
357 for n, ax in enumerate(self.axes):
332 if ax.firsttime:
358 if ax.firsttime:
333 ax.set_facecolor(self.bgcolor)
359 ax.set_facecolor(self.bgcolor)
334 ax.yaxis.set_major_locator(MultipleLocator(ystep))
360 ax.yaxis.set_major_locator(MultipleLocator(ystep))
335 if self.xaxis is 'time':
361 if self.xaxis is 'time':
336 ax.xaxis.set_major_formatter(FuncFormatter(func))
362 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
337 ax.xaxis.set_major_locator(LinearLocator(9))
363 ax.xaxis.set_major_locator(LinearLocator(9))
338 if self.xlabel is not None:
364 if self.xlabel is not None:
339 ax.set_xlabel(self.xlabel)
365 ax.set_xlabel(self.xlabel)
340 ax.set_ylabel(self.ylabel)
366 ax.set_ylabel(self.ylabel)
341 ax.firsttime = False
367 ax.firsttime = False
342 if self.showprofile:
368 if self.showprofile:
343 self.pf_axes[n].set_ylim(ymin, ymax)
369 self.pf_axes[n].set_ylim(ymin, ymax)
344 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
370 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
345 self.pf_axes[n].set_xlabel('dB')
371 self.pf_axes[n].set_xlabel('dB')
346 self.pf_axes[n].grid(b=True, axis='x')
372 self.pf_axes[n].grid(b=True, axis='x')
347 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
373 [tick.set_visible(False) for tick in self.pf_axes[n].get_yticklabels()]
348 if self.colorbar:
374 if self.colorbar:
349 ax.cbar = plt.colorbar(ax.plt, ax=ax, pad=0.02, aspect=10)
375 ax.cbar = plt.colorbar(ax.plt, ax=ax, pad=0.02, aspect=10)
350 ax.cbar.ax.tick_params(labelsize=8)
376 ax.cbar.ax.tick_params(labelsize=8)
351 ax.cbar.ax.press = None
377 ax.cbar.ax.press = None
352 if self.cb_label:
378 if self.cb_label:
353 ax.cbar.set_label(self.cb_label, size=8)
379 ax.cbar.set_label(self.cb_label, size=8)
354 elif self.cb_labels:
380 elif self.cb_labels:
355 ax.cbar.set_label(self.cb_labels[n], size=8)
381 ax.cbar.set_label(self.cb_labels[n], size=8)
356
382
357 ax.set_title('{} - {} {}'.format(
383 ax.set_title('{} - {} {}'.format(
358 self.titles[n],
384 self.titles[n],
359 datetime.datetime.utcfromtimestamp(self.max_time).strftime('%H:%M:%S'),
385 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
360 self.time_label),
386 self.time_label),
361 size=8)
387 size=8)
362 ax.set_xlim(xmin, xmax)
388 ax.set_xlim(xmin, xmax)
363 ax.set_ylim(ymin, ymax)
389 ax.set_ylim(ymin, ymax)
364
390
365 def __plot(self):
391 def __plot(self):
366 '''
392 '''
367 '''
393 '''
368 log.success('Plotting', self.name)
394 log.success('Plotting', self.name)
369
395
370 self.plot()
396 self.plot()
371 self.format()
397 self.format()
372
398
373 for n, fig in enumerate(self.figures):
399 for n, fig in enumerate(self.figures):
374 if self.nrows == 0 or self.nplots == 0:
400 if self.nrows == 0 or self.nplots == 0:
375 log.warning('No data', self.name)
401 log.warning('No data', self.name)
376 continue
402 continue
377 if self.show:
378 fig.show()
379
403
380 fig.tight_layout()
404 fig.tight_layout()
381 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
405 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
382 datetime.datetime.utcfromtimestamp(self.max_time).strftime('%Y/%m/%d')))
406 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
383 # fig.canvas.draw()
407 # fig.canvas.draw()
384
408
385 if self.save and self.data.ended:
409 if self.save and self.data.ended:
386 channels = range(self.nrows)
410 channels = range(self.nrows)
387 if self.oneFigure:
411 if self.oneFigure:
388 label = ''
412 label = ''
389 else:
413 else:
390 label = '_{}'.format(channels[n])
414 label = '_{}'.format(channels[n])
391 figname = os.path.join(
415 figname = os.path.join(
392 self.save,
416 self.save,
393 '{}{}_{}.png'.format(
417 '{}{}_{}.png'.format(
394 self.CODE,
418 self.CODE,
395 label,
419 label,
396 datetime.datetime.utcfromtimestamp(self.saveTime).strftime('%y%m%d_%H%M%S')
420 self.getDateTime(self.saveTime).strftime('%y%m%d_%H%M%S')
397 )
421 )
398 )
422 )
399 print 'Saving figure: {}'.format(figname)
423 print 'Saving figure: {}'.format(figname)
400 fig.savefig(figname)
424 fig.savefig(figname)
401
425
402 def plot(self):
426 def plot(self):
403 '''
427 '''
404 '''
428 '''
405 raise(NotImplementedError, 'Implement this method in child class')
429 raise(NotImplementedError, 'Implement this method in child class')
406
430
407 def run(self):
431 def run(self):
408
432
409 log.success('Starting', self.name)
433 log.success('Starting', self.name)
410
434
411 context = zmq.Context()
435 context = zmq.Context()
412 receiver = context.socket(zmq.SUB)
436 receiver = context.socket(zmq.SUB)
413 receiver.setsockopt(zmq.SUBSCRIBE, '')
437 receiver.setsockopt(zmq.SUBSCRIBE, '')
414 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
438 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
415
439
416 if 'server' in self.kwargs['parent']:
440 if 'server' in self.kwargs['parent']:
417 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
441 receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
418 else:
442 else:
419 receiver.connect("ipc:///tmp/zmq.plots")
443 receiver.connect("ipc:///tmp/zmq.plots")
420
444
421 while True:
445 while True:
422 try:
446 try:
423 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
447 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
424
448 if self.data.localtime and self.localtime:
425 if self.localtime:
449 self.times = self.data.times
450 elif self.data.localtime and not self.localtime:
451 self.times = self.data.times + time.timezone
452 elif not self.data.localtime and self.localtime:
426 self.times = self.data.times - time.timezone
453 self.times = self.data.times - time.timezone
427 else:
454 else:
428 self.times = self.data.times
455 self.times = self.data.times
429
456
430 self.min_time = self.times[0]
457 self.min_time = self.times[0]
431 self.max_time = self.times[-1]
458 self.max_time = self.times[-1]
432
459
433 if self.isConfig is False:
460 if self.isConfig is False:
434 self.__setup()
461 self.__setup()
435 self.isConfig = True
462 self.isConfig = True
436
463
437 self.__plot()
464 self.__plot()
438
465
439 except zmq.Again as e:
466 except zmq.Again as e:
440 log.log('Waiting for data...')
467 log.log('Waiting for data...')
441 if self.data:
468 if self.data:
442 plt.pause(self.data.throttle)
469 figpause(self.data.throttle)
443 else:
470 else:
444 time.sleep(2)
471 time.sleep(2)
445
472
446 def close(self):
473 def close(self):
447 if self.data:
474 if self.data:
448 self.__plot()
475 self.__plot()
449
476
450 class PlotSpectraData(PlotData):
477 class PlotSpectraData(PlotData):
451 '''
478 '''
452 Plot for Spectra data
479 Plot for Spectra data
453 '''
480 '''
454
481
455 CODE = 'spc'
482 CODE = 'spc'
456 colormap = 'jro'
483 colormap = 'jro'
457
484
458 def setup(self):
485 def setup(self):
459 self.nplots = len(self.data.channels)
486 self.nplots = len(self.data.channels)
460 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
487 self.ncols = int(numpy.sqrt(self.nplots)+ 0.9)
461 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
488 self.nrows = int((1.0*self.nplots/self.ncols) + 0.9)
462 self.width = 3.4*self.ncols
489 self.width = 3.4*self.ncols
463 self.height = 3*self.nrows
490 self.height = 3*self.nrows
464 self.cb_label = 'dB'
491 self.cb_label = 'dB'
465 if self.showprofile:
492 if self.showprofile:
466 self.width += 0.8*self.ncols
493 self.width += 0.8*self.ncols
467
494
468 self.ylabel = 'Range [Km]'
495 self.ylabel = 'Range [Km]'
469
496
470 def plot(self):
497 def plot(self):
471 if self.xaxis == "frequency":
498 if self.xaxis == "frequency":
472 x = self.data.xrange[0]
499 x = self.data.xrange[0]
473 self.xlabel = "Frequency (kHz)"
500 self.xlabel = "Frequency (kHz)"
474 elif self.xaxis == "time":
501 elif self.xaxis == "time":
475 x = self.data.xrange[1]
502 x = self.data.xrange[1]
476 self.xlabel = "Time (ms)"
503 self.xlabel = "Time (ms)"
477 else:
504 else:
478 x = self.data.xrange[2]
505 x = self.data.xrange[2]
479 self.xlabel = "Velocity (m/s)"
506 self.xlabel = "Velocity (m/s)"
480
507
481 if self.CODE == 'spc_mean':
508 if self.CODE == 'spc_mean':
482 x = self.data.xrange[2]
509 x = self.data.xrange[2]
483 self.xlabel = "Velocity (m/s)"
510 self.xlabel = "Velocity (m/s)"
484
511
485 self.titles = []
512 self.titles = []
486
513
487 y = self.data.heights
514 y = self.data.heights
488 self.y = y
515 self.y = y
489 z = self.data['spc']
516 z = self.data['spc']
490
517
491 for n, ax in enumerate(self.axes):
518 for n, ax in enumerate(self.axes):
492 noise = self.data['noise'][n][-1]
519 noise = self.data['noise'][n][-1]
493 if self.CODE == 'spc_mean':
520 if self.CODE == 'spc_mean':
494 mean = self.data['mean'][n][-1]
521 mean = self.data['mean'][n][-1]
495 if ax.firsttime:
522 if ax.firsttime:
496 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
523 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
497 self.xmin = self.xmin if self.xmin else -self.xmax
524 self.xmin = self.xmin if self.xmin else -self.xmax
498 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
525 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
499 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
526 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
500 ax.plt = ax.pcolormesh(x, y, z[n].T,
527 ax.plt = ax.pcolormesh(x, y, z[n].T,
501 vmin=self.zmin,
528 vmin=self.zmin,
502 vmax=self.zmax,
529 vmax=self.zmax,
503 cmap=plt.get_cmap(self.colormap)
530 cmap=plt.get_cmap(self.colormap)
504 )
531 )
505
532
506 if self.showprofile:
533 if self.showprofile:
507 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
534 ax.plt_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], y)[0]
508 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
535 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
509 color="k", linestyle="dashed", lw=1)[0]
536 color="k", linestyle="dashed", lw=1)[0]
510 if self.CODE == 'spc_mean':
537 if self.CODE == 'spc_mean':
511 ax.plt_mean = ax.plot(mean, y, color='k')[0]
538 ax.plt_mean = ax.plot(mean, y, color='k')[0]
512 else:
539 else:
513 ax.plt.set_array(z[n].T.ravel())
540 ax.plt.set_array(z[n].T.ravel())
514 if self.showprofile:
541 if self.showprofile:
515 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
542 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
516 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
543 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
517 if self.CODE == 'spc_mean':
544 if self.CODE == 'spc_mean':
518 ax.plt_mean.set_data(mean, y)
545 ax.plt_mean.set_data(mean, y)
519
546
520 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
547 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
521 self.saveTime = self.max_time
548 self.saveTime = self.max_time
522
549
523
550
524 class PlotCrossSpectraData(PlotData):
551 class PlotCrossSpectraData(PlotData):
525
552
526 CODE = 'cspc'
553 CODE = 'cspc'
527 zmin_coh = None
554 zmin_coh = None
528 zmax_coh = None
555 zmax_coh = None
529 zmin_phase = None
556 zmin_phase = None
530 zmax_phase = None
557 zmax_phase = None
531
558
532 def setup(self):
559 def setup(self):
533
560
534 self.ncols = 4
561 self.ncols = 4
535 self.nrows = len(self.data.pairs)
562 self.nrows = len(self.data.pairs)
536 self.nplots = self.nrows*4
563 self.nplots = self.nrows*4
537 self.width = 3.4*self.ncols
564 self.width = 3.4*self.ncols
538 self.height = 3*self.nrows
565 self.height = 3*self.nrows
539 self.ylabel = 'Range [Km]'
566 self.ylabel = 'Range [Km]'
540 self.showprofile = False
567 self.showprofile = False
541
568
542 def plot(self):
569 def plot(self):
543
570
544 if self.xaxis == "frequency":
571 if self.xaxis == "frequency":
545 x = self.data.xrange[0]
572 x = self.data.xrange[0]
546 self.xlabel = "Frequency (kHz)"
573 self.xlabel = "Frequency (kHz)"
547 elif self.xaxis == "time":
574 elif self.xaxis == "time":
548 x = self.data.xrange[1]
575 x = self.data.xrange[1]
549 self.xlabel = "Time (ms)"
576 self.xlabel = "Time (ms)"
550 else:
577 else:
551 x = self.data.xrange[2]
578 x = self.data.xrange[2]
552 self.xlabel = "Velocity (m/s)"
579 self.xlabel = "Velocity (m/s)"
553
580
554 self.titles = []
581 self.titles = []
555
582
556 y = self.data.heights
583 y = self.data.heights
557 self.y = y
584 self.y = y
558 spc = self.data['spc']
585 spc = self.data['spc']
559 cspc = self.data['cspc']
586 cspc = self.data['cspc']
560
587
561 for n in range(self.nrows):
588 for n in range(self.nrows):
562 noise = self.data['noise'][n][-1]
589 noise = self.data['noise'][n][-1]
563 pair = self.data.pairs[n]
590 pair = self.data.pairs[n]
564 ax = self.axes[4*n]
591 ax = self.axes[4*n]
565 ax3 = self.axes[4*n+3]
592 ax3 = self.axes[4*n+3]
566 if ax.firsttime:
593 if ax.firsttime:
567 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
594 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
568 self.xmin = self.xmin if self.xmin else -self.xmax
595 self.xmin = self.xmin if self.xmin else -self.xmax
569 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
596 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
570 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
597 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
571 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
598 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
572 vmin=self.zmin,
599 vmin=self.zmin,
573 vmax=self.zmax,
600 vmax=self.zmax,
574 cmap=plt.get_cmap(self.colormap)
601 cmap=plt.get_cmap(self.colormap)
575 )
602 )
576 else:
603 else:
577 ax.plt.set_array(spc[pair[0]].T.ravel())
604 ax.plt.set_array(spc[pair[0]].T.ravel())
578 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
605 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
579
606
580 ax = self.axes[4*n+1]
607 ax = self.axes[4*n+1]
581 if ax.firsttime:
608 if ax.firsttime:
582 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
609 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
583 vmin=self.zmin,
610 vmin=self.zmin,
584 vmax=self.zmax,
611 vmax=self.zmax,
585 cmap=plt.get_cmap(self.colormap)
612 cmap=plt.get_cmap(self.colormap)
586 )
613 )
587 else:
614 else:
588 ax.plt.set_array(spc[pair[1]].T.ravel())
615 ax.plt.set_array(spc[pair[1]].T.ravel())
589 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
616 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
590
617
591 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
618 out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]])
592 coh = numpy.abs(out)
619 coh = numpy.abs(out)
593 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
620 phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi
594
621
595 ax = self.axes[4*n+2]
622 ax = self.axes[4*n+2]
596 if ax.firsttime:
623 if ax.firsttime:
597 ax.plt = ax.pcolormesh(x, y, coh.T,
624 ax.plt = ax.pcolormesh(x, y, coh.T,
598 vmin=0,
625 vmin=0,
599 vmax=1,
626 vmax=1,
600 cmap=plt.get_cmap(self.colormap_coh)
627 cmap=plt.get_cmap(self.colormap_coh)
601 )
628 )
602 else:
629 else:
603 ax.plt.set_array(coh.T.ravel())
630 ax.plt.set_array(coh.T.ravel())
604 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
631 self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
605
632
606 ax = self.axes[4*n+3]
633 ax = self.axes[4*n+3]
607 if ax.firsttime:
634 if ax.firsttime:
608 ax.plt = ax.pcolormesh(x, y, phase.T,
635 ax.plt = ax.pcolormesh(x, y, phase.T,
609 vmin=-180,
636 vmin=-180,
610 vmax=180,
637 vmax=180,
611 cmap=plt.get_cmap(self.colormap_phase)
638 cmap=plt.get_cmap(self.colormap_phase)
612 )
639 )
613 else:
640 else:
614 ax.plt.set_array(phase.T.ravel())
641 ax.plt.set_array(phase.T.ravel())
615 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
642 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
616
643
617 self.saveTime = self.max_time
644 self.saveTime = self.max_time
618
645
619
646
620 class PlotSpectraMeanData(PlotSpectraData):
647 class PlotSpectraMeanData(PlotSpectraData):
621 '''
648 '''
622 Plot for Spectra and Mean
649 Plot for Spectra and Mean
623 '''
650 '''
624 CODE = 'spc_mean'
651 CODE = 'spc_mean'
625 colormap = 'jro'
652 colormap = 'jro'
626
653
627
654
628 class PlotRTIData(PlotData):
655 class PlotRTIData(PlotData):
629 '''
656 '''
630 Plot for RTI data
657 Plot for RTI data
631 '''
658 '''
632
659
633 CODE = 'rti'
660 CODE = 'rti'
634 colormap = 'jro'
661 colormap = 'jro'
635
662
636 def setup(self):
663 def setup(self):
637 self.xaxis = 'time'
664 self.xaxis = 'time'
638 self.ncols = 1
665 self.ncols = 1
639 self.nrows = len(self.data.channels)
666 self.nrows = len(self.data.channels)
640 self.nplots = len(self.data.channels)
667 self.nplots = len(self.data.channels)
641 self.ylabel = 'Range [Km]'
668 self.ylabel = 'Range [Km]'
642 self.cb_label = 'dB'
669 self.cb_label = 'dB'
643 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
670 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
644
671
645 def plot(self):
672 def plot(self):
646 self.x = self.times
673 self.x = self.times
647 self.y = self.data.heights
674 self.y = self.data.heights
648 self.z = self.data[self.CODE]
675 self.z = self.data[self.CODE]
649 self.z = numpy.ma.masked_invalid(self.z)
676 self.z = numpy.ma.masked_invalid(self.z)
650
677
651 for n, ax in enumerate(self.axes):
678 for n, ax in enumerate(self.axes):
652 x, y, z = self.fill_gaps(*self.decimate())
679 x, y, z = self.fill_gaps(*self.decimate())
653 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
680 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
654 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
681 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
655 if ax.firsttime:
682 if ax.firsttime:
656 ax.plt = ax.pcolormesh(x, y, z[n].T,
683 ax.plt = ax.pcolormesh(x, y, z[n].T,
657 vmin=self.zmin,
684 vmin=self.zmin,
658 vmax=self.zmax,
685 vmax=self.zmax,
659 cmap=plt.get_cmap(self.colormap)
686 cmap=plt.get_cmap(self.colormap)
660 )
687 )
661 if self.showprofile:
688 if self.showprofile:
662 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
689 ax.plot_profile= self.pf_axes[n].plot(self.data['rti'][n][-1], self.y)[0]
663 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
690 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
664 color="k", linestyle="dashed", lw=1)[0]
691 color="k", linestyle="dashed", lw=1)[0]
665 else:
692 else:
666 ax.collections.remove(ax.collections[0])
693 ax.collections.remove(ax.collections[0])
667 ax.plt = ax.pcolormesh(x, y, z[n].T,
694 ax.plt = ax.pcolormesh(x, y, z[n].T,
668 vmin=self.zmin,
695 vmin=self.zmin,
669 vmax=self.zmax,
696 vmax=self.zmax,
670 cmap=plt.get_cmap(self.colormap)
697 cmap=plt.get_cmap(self.colormap)
671 )
698 )
672 if self.showprofile:
699 if self.showprofile:
673 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
700 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
674 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
701 ax.plot_noise.set_data(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y)
675
702
676 self.saveTime = self.min_time
703 self.saveTime = self.min_time
677
704
678
705
679 class PlotCOHData(PlotRTIData):
706 class PlotCOHData(PlotRTIData):
680 '''
707 '''
681 Plot for Coherence data
708 Plot for Coherence data
682 '''
709 '''
683
710
684 CODE = 'coh'
711 CODE = 'coh'
685
712
686 def setup(self):
713 def setup(self):
687 self.xaxis = 'time'
714 self.xaxis = 'time'
688 self.ncols = 1
715 self.ncols = 1
689 self.nrows = len(self.data.pairs)
716 self.nrows = len(self.data.pairs)
690 self.nplots = len(self.data.pairs)
717 self.nplots = len(self.data.pairs)
691 self.ylabel = 'Range [Km]'
718 self.ylabel = 'Range [Km]'
692 if self.CODE == 'coh':
719 if self.CODE == 'coh':
693 self.cb_label = ''
720 self.cb_label = ''
694 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
721 self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
695 else:
722 else:
696 self.cb_label = 'Degrees'
723 self.cb_label = 'Degrees'
697 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
724 self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
698
725
699
726
700 class PlotPHASEData(PlotCOHData):
727 class PlotPHASEData(PlotCOHData):
701 '''
728 '''
702 Plot for Phase map data
729 Plot for Phase map data
703 '''
730 '''
704
731
705 CODE = 'phase'
732 CODE = 'phase'
706 colormap = 'seismic'
733 colormap = 'seismic'
707
734
708
735
709 class PlotNoiseData(PlotData):
736 class PlotNoiseData(PlotData):
710 '''
737 '''
711 Plot for noise
738 Plot for noise
712 '''
739 '''
713
740
714 CODE = 'noise'
741 CODE = 'noise'
715
742
716 def setup(self):
743 def setup(self):
717 self.xaxis = 'time'
744 self.xaxis = 'time'
718 self.ncols = 1
745 self.ncols = 1
719 self.nrows = 1
746 self.nrows = 1
720 self.nplots = 1
747 self.nplots = 1
721 self.ylabel = 'Intensity [dB]'
748 self.ylabel = 'Intensity [dB]'
722 self.titles = ['Noise']
749 self.titles = ['Noise']
723 self.colorbar = False
750 self.colorbar = False
724
751
725 def plot(self):
752 def plot(self):
726
753
727 x = self.times
754 x = self.times
728 xmin = self.min_time
755 xmin = self.min_time
729 xmax = xmin+self.xrange*60*60
756 xmax = xmin+self.xrange*60*60
730 Y = self.data[self.CODE]
757 Y = self.data[self.CODE]
731
758
732 if self.axes[0].firsttime:
759 if self.axes[0].firsttime:
733 for ch in self.data.channels:
760 for ch in self.data.channels:
734 y = Y[ch]
761 y = Y[ch]
735 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
762 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
736 plt.legend()
763 plt.legend()
737 else:
764 else:
738 for ch in self.data.channels:
765 for ch in self.data.channels:
739 y = Y[ch]
766 y = Y[ch]
740 self.axes[0].lines[ch].set_data(x, y)
767 self.axes[0].lines[ch].set_data(x, y)
741
768
742 self.ymin = numpy.nanmin(Y) - 5
769 self.ymin = numpy.nanmin(Y) - 5
743 self.ymax = numpy.nanmax(Y) + 5
770 self.ymax = numpy.nanmax(Y) + 5
744 self.saveTime = self.min_time
771 self.saveTime = self.min_time
745
772
746
773
747 class PlotSNRData(PlotRTIData):
774 class PlotSNRData(PlotRTIData):
748 '''
775 '''
749 Plot for SNR Data
776 Plot for SNR Data
750 '''
777 '''
751
778
752 CODE = 'snr'
779 CODE = 'snr'
753 colormap = 'jet'
780 colormap = 'jet'
754
781
755
782
756 class PlotDOPData(PlotRTIData):
783 class PlotDOPData(PlotRTIData):
757 '''
784 '''
758 Plot for DOPPLER Data
785 Plot for DOPPLER Data
759 '''
786 '''
760
787
761 CODE = 'dop'
788 CODE = 'dop'
762 colormap = 'jet'
789 colormap = 'jet'
763
790
764
791
765 class PlotSkyMapData(PlotData):
792 class PlotSkyMapData(PlotData):
766 '''
793 '''
767 Plot for meteors detection data
794 Plot for meteors detection data
768 '''
795 '''
769
796
770 CODE = 'met'
797 CODE = 'met'
771
798
772 def setup(self):
799 def setup(self):
773
800
774 self.ncols = 1
801 self.ncols = 1
775 self.nrows = 1
802 self.nrows = 1
776 self.width = 7.2
803 self.width = 7.2
777 self.height = 7.2
804 self.height = 7.2
778
805
779 self.xlabel = 'Zonal Zenith Angle (deg)'
806 self.xlabel = 'Zonal Zenith Angle (deg)'
780 self.ylabel = 'Meridional Zenith Angle (deg)'
807 self.ylabel = 'Meridional Zenith Angle (deg)'
781
808
782 if self.figure is None:
809 if self.figure is None:
783 self.figure = plt.figure(figsize=(self.width, self.height),
810 self.figure = plt.figure(figsize=(self.width, self.height),
784 edgecolor='k',
811 edgecolor='k',
785 facecolor='w')
812 facecolor='w')
786 else:
813 else:
787 self.figure.clf()
814 self.figure.clf()
788
815
789 self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
816 self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
790 self.ax.firsttime = True
817 self.ax.firsttime = True
791
818
792
819
793 def plot(self):
820 def plot(self):
794
821
795 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.times])
822 arrayParameters = numpy.concatenate([self.data['param'][t] for t in self.times])
796 error = arrayParameters[:,-1]
823 error = arrayParameters[:,-1]
797 indValid = numpy.where(error == 0)[0]
824 indValid = numpy.where(error == 0)[0]
798 finalMeteor = arrayParameters[indValid,:]
825 finalMeteor = arrayParameters[indValid,:]
799 finalAzimuth = finalMeteor[:,3]
826 finalAzimuth = finalMeteor[:,3]
800 finalZenith = finalMeteor[:,4]
827 finalZenith = finalMeteor[:,4]
801
828
802 x = finalAzimuth*numpy.pi/180
829 x = finalAzimuth*numpy.pi/180
803 y = finalZenith
830 y = finalZenith
804
831
805 if self.ax.firsttime:
832 if self.ax.firsttime:
806 self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
833 self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
807 self.ax.set_ylim(0,90)
834 self.ax.set_ylim(0,90)
808 self.ax.set_yticks(numpy.arange(0,90,20))
835 self.ax.set_yticks(numpy.arange(0,90,20))
809 self.ax.set_xlabel(self.xlabel)
836 self.ax.set_xlabel(self.xlabel)
810 self.ax.set_ylabel(self.ylabel)
837 self.ax.set_ylabel(self.ylabel)
811 self.ax.yaxis.labelpad = 40
838 self.ax.yaxis.labelpad = 40
812 self.ax.firsttime = False
839 self.ax.firsttime = False
813 else:
840 else:
814 self.ax.plot.set_data(x, y)
841 self.ax.plot.set_data(x, y)
815
842
816
843
817 dt1 = datetime.datetime.utcfromtimestamp(self.min_time).strftime('%y/%m/%d %H:%M:%S')
844 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
818 dt2 = datetime.datetime.utcfromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')
845 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
819 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
846 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
820 dt2,
847 dt2,
821 len(x))
848 len(x))
822 self.ax.set_title(title, size=8)
849 self.ax.set_title(title, size=8)
823
850
824 self.saveTime = self.max_time
851 self.saveTime = self.max_time
825
852
826 class PlotParamData(PlotRTIData):
853 class PlotParamData(PlotRTIData):
827 '''
854 '''
828 Plot for data_param object
855 Plot for data_param object
829 '''
856 '''
830
857
831 CODE = 'param'
858 CODE = 'param'
832 colormap = 'seismic'
859 colormap = 'seismic'
833
860
834 def setup(self):
861 def setup(self):
835 self.xaxis = 'time'
862 self.xaxis = 'time'
836 self.ncols = 1
863 self.ncols = 1
837 self.nrows = self.data.shape(self.CODE)[0]
864 self.nrows = self.data.shape(self.CODE)[0]
838 self.nplots = self.nrows
865 self.nplots = self.nrows
839 if self.showSNR:
866 if self.showSNR:
840 self.nrows += 1
867 self.nrows += 1
841 self.nplots += 1
868 self.nplots += 1
842
869
843 self.ylabel = 'Height [Km]'
870 self.ylabel = 'Height [Km]'
844 self.titles = self.data.parameters \
871 self.titles = self.data.parameters \
845 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
872 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
846 if self.showSNR:
873 if self.showSNR:
847 self.titles.append('SNR')
874 self.titles.append('SNR')
848
875
849 def plot(self):
876 def plot(self):
850 self.data.normalize_heights()
877 self.data.normalize_heights()
851 self.x = self.times
878 self.x = self.times
852 self.y = self.data.heights
879 self.y = self.data.heights
853 if self.showSNR:
880 if self.showSNR:
854 self.z = numpy.concatenate(
881 self.z = numpy.concatenate(
855 (self.data[self.CODE], self.data['snr'])
882 (self.data[self.CODE], self.data['snr'])
856 )
883 )
857 else:
884 else:
858 self.z = self.data[self.CODE]
885 self.z = self.data[self.CODE]
859
886
860 self.z = numpy.ma.masked_invalid(self.z)
887 self.z = numpy.ma.masked_invalid(self.z)
861
888
862 for n, ax in enumerate(self.axes):
889 for n, ax in enumerate(self.axes):
863
890
864 x, y, z = self.fill_gaps(*self.decimate())
891 x, y, z = self.fill_gaps(*self.decimate())
865 self.zmax = self.zmax if self.zmax is not None else numpy.max(self.z[n])
892 self.zmax = self.zmax if self.zmax is not None else numpy.max(self.z[n])
866 self.zmin = self.zmin if self.zmin is not None else numpy.min(self.z[n])
893 self.zmin = self.zmin if self.zmin is not None else numpy.min(self.z[n])
867
894
868 if ax.firsttime:
895 if ax.firsttime:
869 if self.zlimits is not None:
896 if self.zlimits is not None:
870 self.zmin, self.zmax = self.zlimits[n]
897 self.zmin, self.zmax = self.zlimits[n]
871
898
872 ax.plt = ax.pcolormesh(x, y, z[n].T*self.factors[n],
899 ax.plt = ax.pcolormesh(x, y, z[n].T*self.factors[n],
873 vmin=self.zmin,
900 vmin=self.zmin,
874 vmax=self.zmax,
901 vmax=self.zmax,
875 cmap=self.cmaps[n]
902 cmap=self.cmaps[n]
876 )
903 )
877 else:
904 else:
878 if self.zlimits is not None:
905 if self.zlimits is not None:
879 self.zmin, self.zmax = self.zlimits[n]
906 self.zmin, self.zmax = self.zlimits[n]
880 ax.collections.remove(ax.collections[0])
907 ax.collections.remove(ax.collections[0])
881 ax.plt = ax.pcolormesh(x, y, z[n].T*self.factors[n],
908 ax.plt = ax.pcolormesh(x, y, z[n].T*self.factors[n],
882 vmin=self.zmin,
909 vmin=self.zmin,
883 vmax=self.zmax,
910 vmax=self.zmax,
884 cmap=self.cmaps[n]
911 cmap=self.cmaps[n]
885 )
912 )
886
913
887 self.saveTime = self.min_time
914 self.saveTime = self.min_time
888
915
889 class PlotOutputData(PlotParamData):
916 class PlotOutputData(PlotParamData):
890 '''
917 '''
891 Plot data_output object
918 Plot data_output object
892 '''
919 '''
893
920
894 CODE = 'output'
921 CODE = 'output'
895 colormap = 'seismic'
922 colormap = 'seismic'
@@ -1,607 +1,619
1 '''
1 '''
2 @author: Juan C. Espinoza
2 @author: Juan C. Espinoza
3 '''
3 '''
4
4
5 import time
5 import time
6 import json
6 import json
7 import numpy
7 import numpy
8 import paho.mqtt.client as mqtt
8 import paho.mqtt.client as mqtt
9 import zmq
9 import zmq
10 import datetime
10 import datetime
11 from zmq.utils.monitor import recv_monitor_message
11 from zmq.utils.monitor import recv_monitor_message
12 from functools import wraps
12 from functools import wraps
13 from threading import Thread
13 from threading import Thread
14 from multiprocessing import Process
14 from multiprocessing import Process
15
15
16 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
16 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
17 from schainpy.model.data.jrodata import JROData
17 from schainpy.model.data.jrodata import JROData
18 from schainpy.utils import log
18 from schainpy.utils import log
19
19
20 MAXNUMX = 100
20 MAXNUMX = 100
21 MAXNUMY = 100
21 MAXNUMY = 100
22
22
23 class PrettyFloat(float):
23 class PrettyFloat(float):
24 def __repr__(self):
24 def __repr__(self):
25 return '%.2f' % self
25 return '%.2f' % self
26
26
27 def roundFloats(obj):
27 def roundFloats(obj):
28 if isinstance(obj, list):
28 if isinstance(obj, list):
29 return map(roundFloats, obj)
29 return map(roundFloats, obj)
30 elif isinstance(obj, float):
30 elif isinstance(obj, float):
31 return round(obj, 2)
31 return round(obj, 2)
32
32
33 def decimate(z, MAXNUMY):
33 def decimate(z, MAXNUMY):
34 dy = int(len(z[0])/MAXNUMY) + 1
34 dy = int(len(z[0])/MAXNUMY) + 1
35
35
36 return z[::, ::dy]
36 return z[::, ::dy]
37
37
38 class throttle(object):
38 class throttle(object):
39 '''
39 '''
40 Decorator that prevents a function from being called more than once every
40 Decorator that prevents a function from being called more than once every
41 time period.
41 time period.
42 To create a function that cannot be called more than once a minute, but
42 To create a function that cannot be called more than once a minute, but
43 will sleep until it can be called:
43 will sleep until it can be called:
44 @throttle(minutes=1)
44 @throttle(minutes=1)
45 def foo():
45 def foo():
46 pass
46 pass
47
47
48 for i in range(10):
48 for i in range(10):
49 foo()
49 foo()
50 print "This function has run %s times." % i
50 print "This function has run %s times." % i
51 '''
51 '''
52
52
53 def __init__(self, seconds=0, minutes=0, hours=0):
53 def __init__(self, seconds=0, minutes=0, hours=0):
54 self.throttle_period = datetime.timedelta(
54 self.throttle_period = datetime.timedelta(
55 seconds=seconds, minutes=minutes, hours=hours
55 seconds=seconds, minutes=minutes, hours=hours
56 )
56 )
57
57
58 self.time_of_last_call = datetime.datetime.min
58 self.time_of_last_call = datetime.datetime.min
59
59
60 def __call__(self, fn):
60 def __call__(self, fn):
61 @wraps(fn)
61 @wraps(fn)
62 def wrapper(*args, **kwargs):
62 def wrapper(*args, **kwargs):
63 now = datetime.datetime.now()
63 now = datetime.datetime.now()
64 time_since_last_call = now - self.time_of_last_call
64 time_since_last_call = now - self.time_of_last_call
65 time_left = self.throttle_period - time_since_last_call
65 time_left = self.throttle_period - time_since_last_call
66
66
67 if time_left > datetime.timedelta(seconds=0):
67 if time_left > datetime.timedelta(seconds=0):
68 return
68 return
69
69
70 self.time_of_last_call = datetime.datetime.now()
70 self.time_of_last_call = datetime.datetime.now()
71 return fn(*args, **kwargs)
71 return fn(*args, **kwargs)
72
72
73 return wrapper
73 return wrapper
74
74
75 class Data(object):
75 class Data(object):
76 '''
76 '''
77 Object to hold data to be plotted
77 Object to hold data to be plotted
78 '''
78 '''
79
79
80 def __init__(self, plottypes, throttle_value):
80 def __init__(self, plottypes, throttle_value):
81 self.plottypes = plottypes
81 self.plottypes = plottypes
82 self.throttle = throttle_value
82 self.throttle = throttle_value
83 self.ended = False
83 self.ended = False
84 self.__times = []
84 self.localtime = False
85 self.__times = []
86 self.__heights = []
85
87
86 def __str__(self):
88 def __str__(self):
87 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
89 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
88 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
90 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
89
91
90 def __len__(self):
92 def __len__(self):
91 return len(self.__times)
93 return len(self.__times)
92
94
93 def __getitem__(self, key):
95 def __getitem__(self, key):
94 if key not in self.data:
96 if key not in self.data:
95 raise KeyError(log.error('Missing key: {}'.format(key)))
97 raise KeyError(log.error('Missing key: {}'.format(key)))
96
98
97 if 'spc' in key:
99 if 'spc' in key:
98 ret = self.data[key]
100 ret = self.data[key]
99 else:
101 else:
100 ret = numpy.array([self.data[key][x] for x in self.times])
102 ret = numpy.array([self.data[key][x] for x in self.times])
101 if ret.ndim > 1:
103 if ret.ndim > 1:
102 ret = numpy.swapaxes(ret, 0, 1)
104 ret = numpy.swapaxes(ret, 0, 1)
103 return ret
105 return ret
104
106
105 def setup(self):
107 def setup(self):
106 '''
108 '''
107 Configure object
109 Configure object
108 '''
110 '''
109
111
110 self.ended = False
112 self.ended = False
111 self.data = {}
113 self.data = {}
112 self.__times = []
114 self.__times = []
113 self.__heights = []
115 self.__heights = []
114 self.__all_heights = set()
116 self.__all_heights = set()
115 for plot in self.plottypes:
117 for plot in self.plottypes:
116 if 'snr' in plot:
118 if 'snr' in plot:
117 plot = 'snr'
119 plot = 'snr'
118 self.data[plot] = {}
120 self.data[plot] = {}
119
121
120 def shape(self, key):
122 def shape(self, key):
121 '''
123 '''
122 Get the shape of the one-element data for the given key
124 Get the shape of the one-element data for the given key
123 '''
125 '''
124
126
125 if len(self.data[key]):
127 if len(self.data[key]):
126 if 'spc' in key:
128 if 'spc' in key:
127 return self.data[key].shape
129 return self.data[key].shape
128 return self.data[key][self.__times[0]].shape
130 return self.data[key][self.__times[0]].shape
129 return (0,)
131 return (0,)
130
132
131 def update(self, dataOut):
133 def update(self, dataOut):
132 '''
134 '''
133 Update data object with new dataOut
135 Update data object with new dataOut
134 '''
136 '''
135
137
136 tm = dataOut.utctime
138 tm = dataOut.utctime
137 if tm in self.__times:
139 if tm in self.__times:
138 return
140 return
139
141
140 self.parameters = getattr(dataOut, 'parameters', [])
142 self.parameters = getattr(dataOut, 'parameters', [])
141 self.pairs = dataOut.pairsList
143 self.pairs = dataOut.pairsList
142 self.channels = dataOut.channelList
144 self.channels = dataOut.channelList
143 self.interval = dataOut.getTimeInterval()
145 self.interval = dataOut.getTimeInterval()
146 self.localtime = dataOut.useLocalTime
144 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
147 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
145 self.xrange = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
148 self.xrange = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
146 self.__heights.append(dataOut.heightList)
149 self.__heights.append(dataOut.heightList)
147 self.__all_heights.update(dataOut.heightList)
150 self.__all_heights.update(dataOut.heightList)
148 self.__times.append(tm)
151 self.__times.append(tm)
149
152
150 for plot in self.plottypes:
153 for plot in self.plottypes:
151 if plot == 'spc':
154 if plot == 'spc':
152 z = dataOut.data_spc/dataOut.normFactor
155 z = dataOut.data_spc/dataOut.normFactor
153 self.data[plot] = 10*numpy.log10(z)
156 self.data[plot] = 10*numpy.log10(z)
154 if plot == 'cspc':
157 if plot == 'cspc':
155 self.data[plot] = dataOut.data_cspc
158 self.data[plot] = dataOut.data_cspc
156 if plot == 'noise':
159 if plot == 'noise':
157 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
160 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
158 if plot == 'rti':
161 if plot == 'rti':
159 self.data[plot][tm] = dataOut.getPower()
162 self.data[plot][tm] = dataOut.getPower()
160 if plot == 'snr_db':
163 if plot == 'snr_db':
161 self.data['snr'][tm] = dataOut.data_SNR
164 self.data['snr'][tm] = dataOut.data_SNR
162 if plot == 'snr':
165 if plot == 'snr':
163 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
166 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
164 if plot == 'dop':
167 if plot == 'dop':
165 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
168 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
166 if plot == 'mean':
169 if plot == 'mean':
167 self.data[plot][tm] = dataOut.data_MEAN
170 self.data[plot][tm] = dataOut.data_MEAN
168 if plot == 'std':
171 if plot == 'std':
169 self.data[plot][tm] = dataOut.data_STD
172 self.data[plot][tm] = dataOut.data_STD
170 if plot == 'coh':
173 if plot == 'coh':
171 self.data[plot][tm] = dataOut.getCoherence()
174 self.data[plot][tm] = dataOut.getCoherence()
172 if plot == 'phase':
175 if plot == 'phase':
173 self.data[plot][tm] = dataOut.getCoherence(phase=True)
176 self.data[plot][tm] = dataOut.getCoherence(phase=True)
174 if plot == 'output':
177 if plot == 'output':
175 self.data[plot][tm] = dataOut.data_output
178 self.data[plot][tm] = dataOut.data_output
176 if plot == 'param':
179 if plot == 'param':
177 self.data[plot][tm] = dataOut.data_param
180 self.data[plot][tm] = dataOut.data_param
178
181
179 def normalize_heights(self):
182 def normalize_heights(self):
180 '''
183 '''
181 Ensure same-dimension of the data for different heighList
184 Ensure same-dimension of the data for different heighList
182 '''
185 '''
183
186
184 H = numpy.array(list(self.__all_heights))
187 H = numpy.array(list(self.__all_heights))
185 H.sort()
188 H.sort()
186 for key in self.data:
189 for key in self.data:
187 shape = self.shape(key)[:-1] + H.shape
190 shape = self.shape(key)[:-1] + H.shape
188 for tm, obj in self.data[key].items():
191 for tm, obj in self.data[key].items():
189 h = self.__heights[self.__times.index(tm)]
192 h = self.__heights[self.__times.index(tm)]
190 if H.size == h.size:
193 if H.size == h.size:
191 continue
194 continue
192 index = numpy.where(numpy.in1d(H, h))[0]
195 index = numpy.where(numpy.in1d(H, h))[0]
193 dummy = numpy.zeros(shape) + numpy.nan
196 dummy = numpy.zeros(shape) + numpy.nan
194 if len(shape) == 2:
197 if len(shape) == 2:
195 dummy[:, index] = obj
198 dummy[:, index] = obj
196 else:
199 else:
197 dummy[index] = obj
200 dummy[index] = obj
198 self.data[key][tm] = dummy
201 self.data[key][tm] = dummy
199
202
200 self.__heights = [H for tm in self.__times]
203 self.__heights = [H for tm in self.__times]
201
204
202 def jsonify(self, decimate=False):
205 def jsonify(self, decimate=False):
203 '''
206 '''
204 Convert data to json
207 Convert data to json
205 '''
208 '''
206
209
207 ret = {}
210 ret = {}
208 tm = self.times[-1]
211 tm = self.times[-1]
209
212
210 for key, value in self.data:
213 for key, value in self.data:
211 if key in ('spc', 'cspc'):
214 if key in ('spc', 'cspc'):
212 ret[key] = roundFloats(self.data[key].to_list())
215 ret[key] = roundFloats(self.data[key].to_list())
213 else:
216 else:
214 ret[key] = roundFloats(self.data[key][tm].to_list())
217 ret[key] = roundFloats(self.data[key][tm].to_list())
215
218
216 ret['timestamp'] = tm
219 ret['timestamp'] = tm
217 ret['interval'] = self.interval
220 ret['interval'] = self.interval
218
221
219 @property
222 @property
220 def times(self):
223 def times(self):
221 '''
224 '''
222 Return the list of times of the current data
225 Return the list of times of the current data
223 '''
226 '''
224
227
225 ret = numpy.array(self.__times)
228 ret = numpy.array(self.__times)
226 ret.sort()
229 ret.sort()
227 return ret
230 return ret
228
231
229 @property
232 @property
230 def heights(self):
233 def heights(self):
231 '''
234 '''
232 Return the list of heights of the current data
235 Return the list of heights of the current data
233 '''
236 '''
234
237
235 return numpy.array(self.__heights[-1])
238 return numpy.array(self.__heights[-1])
236
239
237 class PublishData(Operation):
240 class PublishData(Operation):
238 '''
241 '''
239 Operation to send data over zmq.
242 Operation to send data over zmq.
240 '''
243 '''
241
244
242 def __init__(self, **kwargs):
245 def __init__(self, **kwargs):
243 """Inicio."""
246 """Inicio."""
244 Operation.__init__(self, **kwargs)
247 Operation.__init__(self, **kwargs)
245 self.isConfig = False
248 self.isConfig = False
246 self.client = None
249 self.client = None
247 self.zeromq = None
250 self.zeromq = None
248 self.mqtt = None
251 self.mqtt = None
249
252
250 def on_disconnect(self, client, userdata, rc):
253 def on_disconnect(self, client, userdata, rc):
251 if rc != 0:
254 if rc != 0:
252 log.warning('Unexpected disconnection.')
255 log.warning('Unexpected disconnection.')
253 self.connect()
256 self.connect()
254
257
255 def connect(self):
258 def connect(self):
256 log.warning('trying to connect')
259 log.warning('trying to connect')
257 try:
260 try:
258 self.client.connect(
261 self.client.connect(
259 host=self.host,
262 host=self.host,
260 port=self.port,
263 port=self.port,
261 keepalive=60*10,
264 keepalive=60*10,
262 bind_address='')
265 bind_address='')
263 self.client.loop_start()
266 self.client.loop_start()
264 # self.client.publish(
267 # self.client.publish(
265 # self.topic + 'SETUP',
268 # self.topic + 'SETUP',
266 # json.dumps(setup),
269 # json.dumps(setup),
267 # retain=True
270 # retain=True
268 # )
271 # )
269 except:
272 except:
270 log.error('MQTT Conection error.')
273 log.error('MQTT Conection error.')
271 self.client = False
274 self.client = False
272
275
273 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
276 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
274 self.counter = 0
277 self.counter = 0
275 self.topic = kwargs.get('topic', 'schain')
278 self.topic = kwargs.get('topic', 'schain')
276 self.delay = kwargs.get('delay', 0)
279 self.delay = kwargs.get('delay', 0)
277 self.plottype = kwargs.get('plottype', 'spectra')
280 self.plottype = kwargs.get('plottype', 'spectra')
278 self.host = kwargs.get('host', "10.10.10.82")
281 self.host = kwargs.get('host', "10.10.10.82")
279 self.port = kwargs.get('port', 3000)
282 self.port = kwargs.get('port', 3000)
280 self.clientId = clientId
283 self.clientId = clientId
281 self.cnt = 0
284 self.cnt = 0
282 self.zeromq = zeromq
285 self.zeromq = zeromq
283 self.mqtt = kwargs.get('plottype', 0)
286 self.mqtt = kwargs.get('plottype', 0)
284 self.client = None
287 self.client = None
285 self.verbose = verbose
288 self.verbose = verbose
286 setup = []
289 setup = []
287 if mqtt is 1:
290 if mqtt is 1:
288 self.client = mqtt.Client(
291 self.client = mqtt.Client(
289 client_id=self.clientId + self.topic + 'SCHAIN',
292 client_id=self.clientId + self.topic + 'SCHAIN',
290 clean_session=True)
293 clean_session=True)
291 self.client.on_disconnect = self.on_disconnect
294 self.client.on_disconnect = self.on_disconnect
292 self.connect()
295 self.connect()
293 for plot in self.plottype:
296 for plot in self.plottype:
294 setup.append({
297 setup.append({
295 'plot': plot,
298 'plot': plot,
296 'topic': self.topic + plot,
299 'topic': self.topic + plot,
297 'title': getattr(self, plot + '_' + 'title', False),
300 'title': getattr(self, plot + '_' + 'title', False),
298 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
301 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
299 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
302 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
300 'xrange': getattr(self, plot + '_' + 'xrange', False),
303 'xrange': getattr(self, plot + '_' + 'xrange', False),
301 'yrange': getattr(self, plot + '_' + 'yrange', False),
304 'yrange': getattr(self, plot + '_' + 'yrange', False),
302 'zrange': getattr(self, plot + '_' + 'zrange', False),
305 'zrange': getattr(self, plot + '_' + 'zrange', False),
303 })
306 })
304 if zeromq is 1:
307 if zeromq is 1:
305 context = zmq.Context()
308 context = zmq.Context()
306 self.zmq_socket = context.socket(zmq.PUSH)
309 self.zmq_socket = context.socket(zmq.PUSH)
307 server = kwargs.get('server', 'zmq.pipe')
310 server = kwargs.get('server', 'zmq.pipe')
308
311
309 if 'tcp://' in server:
312 if 'tcp://' in server:
310 address = server
313 address = server
311 else:
314 else:
312 address = 'ipc:///tmp/%s' % server
315 address = 'ipc:///tmp/%s' % server
313
316
314 self.zmq_socket.connect(address)
317 self.zmq_socket.connect(address)
315 time.sleep(1)
318 time.sleep(1)
316
319
317
320
318 def publish_data(self):
321 def publish_data(self):
319 self.dataOut.finished = False
322 self.dataOut.finished = False
320 if self.mqtt is 1:
323 if self.mqtt is 1:
321 yData = self.dataOut.heightList[:2].tolist()
324 yData = self.dataOut.heightList[:2].tolist()
322 if self.plottype == 'spectra':
325 if self.plottype == 'spectra':
323 data = getattr(self.dataOut, 'data_spc')
326 data = getattr(self.dataOut, 'data_spc')
324 z = data/self.dataOut.normFactor
327 z = data/self.dataOut.normFactor
325 zdB = 10*numpy.log10(z)
328 zdB = 10*numpy.log10(z)
326 xlen, ylen = zdB[0].shape
329 xlen, ylen = zdB[0].shape
327 dx = int(xlen/MAXNUMX) + 1
330 dx = int(xlen/MAXNUMX) + 1
328 dy = int(ylen/MAXNUMY) + 1
331 dy = int(ylen/MAXNUMY) + 1
329 Z = [0 for i in self.dataOut.channelList]
332 Z = [0 for i in self.dataOut.channelList]
330 for i in self.dataOut.channelList:
333 for i in self.dataOut.channelList:
331 Z[i] = zdB[i][::dx, ::dy].tolist()
334 Z[i] = zdB[i][::dx, ::dy].tolist()
332 payload = {
335 payload = {
333 'timestamp': self.dataOut.utctime,
336 'timestamp': self.dataOut.utctime,
334 'data': roundFloats(Z),
337 'data': roundFloats(Z),
335 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
338 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
336 'interval': self.dataOut.getTimeInterval(),
339 'interval': self.dataOut.getTimeInterval(),
337 'type': self.plottype,
340 'type': self.plottype,
338 'yData': yData
341 'yData': yData
339 }
342 }
340
343
341 elif self.plottype in ('rti', 'power'):
344 elif self.plottype in ('rti', 'power'):
342 data = getattr(self.dataOut, 'data_spc')
345 data = getattr(self.dataOut, 'data_spc')
343 z = data/self.dataOut.normFactor
346 z = data/self.dataOut.normFactor
344 avg = numpy.average(z, axis=1)
347 avg = numpy.average(z, axis=1)
345 avgdB = 10*numpy.log10(avg)
348 avgdB = 10*numpy.log10(avg)
346 xlen, ylen = z[0].shape
349 xlen, ylen = z[0].shape
347 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
350 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
348 AVG = [0 for i in self.dataOut.channelList]
351 AVG = [0 for i in self.dataOut.channelList]
349 for i in self.dataOut.channelList:
352 for i in self.dataOut.channelList:
350 AVG[i] = avgdB[i][::dy].tolist()
353 AVG[i] = avgdB[i][::dy].tolist()
351 payload = {
354 payload = {
352 'timestamp': self.dataOut.utctime,
355 'timestamp': self.dataOut.utctime,
353 'data': roundFloats(AVG),
356 'data': roundFloats(AVG),
354 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
357 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
355 'interval': self.dataOut.getTimeInterval(),
358 'interval': self.dataOut.getTimeInterval(),
356 'type': self.plottype,
359 'type': self.plottype,
357 'yData': yData
360 'yData': yData
358 }
361 }
359 elif self.plottype == 'noise':
362 elif self.plottype == 'noise':
360 noise = self.dataOut.getNoise()/self.dataOut.normFactor
363 noise = self.dataOut.getNoise()/self.dataOut.normFactor
361 noisedB = 10*numpy.log10(noise)
364 noisedB = 10*numpy.log10(noise)
362 payload = {
365 payload = {
363 'timestamp': self.dataOut.utctime,
366 'timestamp': self.dataOut.utctime,
364 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
367 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
365 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
368 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
366 'interval': self.dataOut.getTimeInterval(),
369 'interval': self.dataOut.getTimeInterval(),
367 'type': self.plottype,
370 'type': self.plottype,
368 'yData': yData
371 'yData': yData
369 }
372 }
370 elif self.plottype == 'snr':
373 elif self.plottype == 'snr':
371 data = getattr(self.dataOut, 'data_SNR')
374 data = getattr(self.dataOut, 'data_SNR')
372 avgdB = 10*numpy.log10(data)
375 avgdB = 10*numpy.log10(data)
373
376
374 ylen = data[0].size
377 ylen = data[0].size
375 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
378 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
376 AVG = [0 for i in self.dataOut.channelList]
379 AVG = [0 for i in self.dataOut.channelList]
377 for i in self.dataOut.channelList:
380 for i in self.dataOut.channelList:
378 AVG[i] = avgdB[i][::dy].tolist()
381 AVG[i] = avgdB[i][::dy].tolist()
379 payload = {
382 payload = {
380 'timestamp': self.dataOut.utctime,
383 'timestamp': self.dataOut.utctime,
381 'data': roundFloats(AVG),
384 'data': roundFloats(AVG),
382 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
385 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
383 'type': self.plottype,
386 'type': self.plottype,
384 'yData': yData
387 'yData': yData
385 }
388 }
386 else:
389 else:
387 print "Tipo de grafico invalido"
390 print "Tipo de grafico invalido"
388 payload = {
391 payload = {
389 'data': 'None',
392 'data': 'None',
390 'timestamp': 'None',
393 'timestamp': 'None',
391 'type': None
394 'type': None
392 }
395 }
393
396
394 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
397 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
395
398
396 if self.zeromq is 1:
399 if self.zeromq is 1:
397 if self.verbose:
400 if self.verbose:
398 log.log(
401 log.log(
399 '{} - {}'.format(self.dataOut.type, self.dataOut.datatime),
402 'Sending {} - {}'.format(self.dataOut.type, self.dataOut.datatime),
400 'Sending'
403 self.name
401 )
404 )
402 self.zmq_socket.send_pyobj(self.dataOut)
405 self.zmq_socket.send_pyobj(self.dataOut)
403
406
404 def run(self, dataOut, **kwargs):
407 def run(self, dataOut, **kwargs):
405 self.dataOut = dataOut
408 self.dataOut = dataOut
406 if not self.isConfig:
409 if not self.isConfig:
407 self.setup(**kwargs)
410 self.setup(**kwargs)
408 self.isConfig = True
411 self.isConfig = True
409
412
410 self.publish_data()
413 self.publish_data()
411 time.sleep(self.delay)
414 time.sleep(self.delay)
412
415
413 def close(self):
416 def close(self):
414 if self.zeromq is 1:
417 if self.zeromq is 1:
415 self.dataOut.finished = True
418 self.dataOut.finished = True
416 self.zmq_socket.send_pyobj(self.dataOut)
419 self.zmq_socket.send_pyobj(self.dataOut)
417 time.sleep(0.1)
420 time.sleep(0.1)
418 self.zmq_socket.close()
421 self.zmq_socket.close()
419 if self.client:
422 if self.client:
420 self.client.loop_stop()
423 self.client.loop_stop()
421 self.client.disconnect()
424 self.client.disconnect()
422
425
423
426
424 class ReceiverData(ProcessingUnit):
427 class ReceiverData(ProcessingUnit):
425
428
426 def __init__(self, **kwargs):
429 def __init__(self, **kwargs):
427
430
428 ProcessingUnit.__init__(self, **kwargs)
431 ProcessingUnit.__init__(self, **kwargs)
429
432
430 self.isConfig = False
433 self.isConfig = False
431 server = kwargs.get('server', 'zmq.pipe')
434 server = kwargs.get('server', 'zmq.pipe')
432 if 'tcp://' in server:
435 if 'tcp://' in server:
433 address = server
436 address = server
434 else:
437 else:
435 address = 'ipc:///tmp/%s' % server
438 address = 'ipc:///tmp/%s' % server
436
439
437 self.address = address
440 self.address = address
438 self.dataOut = JROData()
441 self.dataOut = JROData()
439
442
440 def setup(self):
443 def setup(self):
441
444
442 self.context = zmq.Context()
445 self.context = zmq.Context()
443 self.receiver = self.context.socket(zmq.PULL)
446 self.receiver = self.context.socket(zmq.PULL)
444 self.receiver.bind(self.address)
447 self.receiver.bind(self.address)
445 time.sleep(0.5)
448 time.sleep(0.5)
446 log.success('ReceiverData from {}'.format(self.address))
449 log.success('ReceiverData from {}'.format(self.address))
447
450
448
451
449 def run(self):
452 def run(self):
450
453
451 if not self.isConfig:
454 if not self.isConfig:
452 self.setup()
455 self.setup()
453 self.isConfig = True
456 self.isConfig = True
454
457
455 self.dataOut = self.receiver.recv_pyobj()
458 self.dataOut = self.receiver.recv_pyobj()
456 log.log('{} - {}'.format(self.dataOut.type,
459 log.log('{} - {}'.format(self.dataOut.type,
457 self.dataOut.datatime.ctime(),),
460 self.dataOut.datatime.ctime(),),
458 'Receiving')
461 'Receiving')
459
462
460
463
461 class PlotterReceiver(ProcessingUnit, Process):
464 class PlotterReceiver(ProcessingUnit, Process):
462
465
463 throttle_value = 5
466 throttle_value = 5
464
467
465 def __init__(self, **kwargs):
468 def __init__(self, **kwargs):
466
469
467 ProcessingUnit.__init__(self, **kwargs)
470 ProcessingUnit.__init__(self, **kwargs)
468 Process.__init__(self)
471 Process.__init__(self)
469 self.mp = False
472 self.mp = False
470 self.isConfig = False
473 self.isConfig = False
471 self.isWebConfig = False
474 self.isWebConfig = False
472 self.connections = 0
475 self.connections = 0
473 server = kwargs.get('server', 'zmq.pipe')
476 server = kwargs.get('server', 'zmq.pipe')
474 plot_server = kwargs.get('plot_server', 'zmq.web')
477 plot_server = kwargs.get('plot_server', 'zmq.web')
475 if 'tcp://' in server:
478 if 'tcp://' in server:
476 address = server
479 address = server
477 else:
480 else:
478 address = 'ipc:///tmp/%s' % server
481 address = 'ipc:///tmp/%s' % server
479
482
480 if 'tcp://' in plot_server:
483 if 'tcp://' in plot_server:
481 plot_address = plot_server
484 plot_address = plot_server
482 else:
485 else:
483 plot_address = 'ipc:///tmp/%s' % plot_server
486 plot_address = 'ipc:///tmp/%s' % plot_server
484
487
485 self.address = address
488 self.address = address
486 self.plot_address = plot_address
489 self.plot_address = plot_address
487 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
490 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
488 self.realtime = kwargs.get('realtime', False)
491 self.realtime = kwargs.get('realtime', False)
492 self.localtime = kwargs.get('localtime', True)
489 self.throttle_value = kwargs.get('throttle', 5)
493 self.throttle_value = kwargs.get('throttle', 5)
490 self.sendData = self.initThrottle(self.throttle_value)
494 self.sendData = self.initThrottle(self.throttle_value)
491 self.dates = []
495 self.dates = []
492 self.setup()
496 self.setup()
493
497
494 def setup(self):
498 def setup(self):
495
499
496 self.data = Data(self.plottypes, self.throttle_value)
500 self.data = Data(self.plottypes, self.throttle_value)
497 self.isConfig = True
501 self.isConfig = True
498
502
499 def event_monitor(self, monitor):
503 def event_monitor(self, monitor):
500
504
501 events = {}
505 events = {}
502
506
503 for name in dir(zmq):
507 for name in dir(zmq):
504 if name.startswith('EVENT_'):
508 if name.startswith('EVENT_'):
505 value = getattr(zmq, name)
509 value = getattr(zmq, name)
506 events[value] = name
510 events[value] = name
507
511
508 while monitor.poll():
512 while monitor.poll():
509 evt = recv_monitor_message(monitor)
513 evt = recv_monitor_message(monitor)
510 if evt['event'] == 32:
514 if evt['event'] == 32:
511 self.connections += 1
515 self.connections += 1
512 if evt['event'] == 512:
516 if evt['event'] == 512:
513 pass
517 pass
514
518
515 evt.update({'description': events[evt['event']]})
519 evt.update({'description': events[evt['event']]})
516
520
517 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
521 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
518 break
522 break
519 monitor.close()
523 monitor.close()
520 print('event monitor thread done!')
524 print('event monitor thread done!')
521
525
522 def initThrottle(self, throttle_value):
526 def initThrottle(self, throttle_value):
523
527
524 @throttle(seconds=throttle_value)
528 @throttle(seconds=throttle_value)
525 def sendDataThrottled(fn_sender, data):
529 def sendDataThrottled(fn_sender, data):
526 fn_sender(data)
530 fn_sender(data)
527
531
528 return sendDataThrottled
532 return sendDataThrottled
529
533
530 def send(self, data):
534 def send(self, data):
531 log.success('Sending {}'.format(data), self.name)
535 log.success('Sending {}'.format(data), self.name)
532 self.sender.send_pyobj(data)
536 self.sender.send_pyobj(data)
533
537
534 def run(self):
538 def run(self):
535
539
536 log.success(
540 log.success(
537 'Starting from {}'.format(self.address),
541 'Starting from {}'.format(self.address),
538 self.name
542 self.name
539 )
543 )
540
544
541 self.context = zmq.Context()
545 self.context = zmq.Context()
542 self.receiver = self.context.socket(zmq.PULL)
546 self.receiver = self.context.socket(zmq.PULL)
543 self.receiver.bind(self.address)
547 self.receiver.bind(self.address)
544 monitor = self.receiver.get_monitor_socket()
548 monitor = self.receiver.get_monitor_socket()
545 self.sender = self.context.socket(zmq.PUB)
549 self.sender = self.context.socket(zmq.PUB)
546 if self.realtime:
550 if self.realtime:
547 self.sender_web = self.context.socket(zmq.PUB)
551 self.sender_web = self.context.socket(zmq.PUB)
548 self.sender_web.connect(self.plot_address)
552 self.sender_web.connect(self.plot_address)
549 time.sleep(1)
553 time.sleep(1)
550
554
551 if 'server' in self.kwargs:
555 if 'server' in self.kwargs:
552 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
556 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
553 else:
557 else:
554 self.sender.bind("ipc:///tmp/zmq.plots")
558 self.sender.bind("ipc:///tmp/zmq.plots")
555
559
556 time.sleep(2)
560 time.sleep(2)
557
561
558 t = Thread(target=self.event_monitor, args=(monitor,))
562 t = Thread(target=self.event_monitor, args=(monitor,))
559 t.start()
563 t.start()
560
564
561 while True:
565 while True:
562 dataOut = self.receiver.recv_pyobj()
566 dataOut = self.receiver.recv_pyobj()
563 dt = datetime.datetime.utcfromtimestamp(dataOut.utctime).date()
567 tm = dataOut.utctime
568 if dataOut.useLocalTime:
569 if not self.localtime:
570 tm += time.timezone
571 dt = datetime.datetime.fromtimestamp(tm).date()
572 else:
573 if self.localtime:
574 tm -= time.timezone
575 dt = datetime.datetime.utcfromtimestamp(tm).date()
564 sended = False
576 sended = False
565 if dt not in self.dates:
577 if dt not in self.dates:
566 if self.data:
578 if self.data:
567 self.data.ended = True
579 self.data.ended = True
568 self.send(self.data)
580 self.send(self.data)
569 sended = True
581 sended = True
570 self.data.setup()
582 self.data.setup()
571 self.dates.append(dt)
583 self.dates.append(dt)
572
584
573 self.data.update(dataOut)
585 self.data.update(dataOut)
574
586
575 if dataOut.finished is True:
587 if dataOut.finished is True:
576 self.connections -= 1
588 self.connections -= 1
577 if self.connections == 0 and dt in self.dates:
589 if self.connections == 0 and dt in self.dates:
578 self.data.ended = True
590 self.data.ended = True
579 self.send(self.data)
591 self.send(self.data)
580 self.data.setup()
592 self.data.setup()
581 else:
593 else:
582 if self.realtime:
594 if self.realtime:
583 self.send(self.data)
595 self.send(self.data)
584 # self.sender_web.send_string(self.data.jsonify())
596 # self.sender_web.send_string(self.data.jsonify())
585 else:
597 else:
586 if not sended:
598 if not sended:
587 self.sendData(self.send, self.data)
599 self.sendData(self.send, self.data)
588
600
589 return
601 return
590
602
591 def sendToWeb(self):
603 def sendToWeb(self):
592
604
593 if not self.isWebConfig:
605 if not self.isWebConfig:
594 context = zmq.Context()
606 context = zmq.Context()
595 sender_web_config = context.socket(zmq.PUB)
607 sender_web_config = context.socket(zmq.PUB)
596 if 'tcp://' in self.plot_address:
608 if 'tcp://' in self.plot_address:
597 dum, address, port = self.plot_address.split(':')
609 dum, address, port = self.plot_address.split(':')
598 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
610 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
599 else:
611 else:
600 conf_address = self.plot_address + '.config'
612 conf_address = self.plot_address + '.config'
601 sender_web_config.bind(conf_address)
613 sender_web_config.bind(conf_address)
602 time.sleep(1)
614 time.sleep(1)
603 for kwargs in self.operationKwargs.values():
615 for kwargs in self.operationKwargs.values():
604 if 'plot' in kwargs:
616 if 'plot' in kwargs:
605 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
617 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
606 sender_web_config.send_string(json.dumps(kwargs))
618 sender_web_config.send_string(json.dumps(kwargs))
607 self.isWebConfig = True No newline at end of file
619 self.isWebConfig = True
General Comments 0
You need to be logged in to leave comments. Login now