##// END OF EJS Templates
Fix plotting bug
Juan C. Espinoza -
r1214:9d8b5d03f906
parent child
Show More
@@ -1,784 +1,802
1
1
2 import os
2 import os
3 import sys
3 import sys
4 import zmq
4 import zmq
5 import time
5 import time
6 import numpy
6 import numpy
7 import datetime
7 import datetime
8 from functools import wraps
8 from functools import wraps
9 from threading import Thread
9 from threading import Thread
10 import matplotlib
10 import matplotlib
11
11
12 if 'BACKEND' in os.environ:
12 if 'BACKEND' in os.environ:
13 matplotlib.use(os.environ['BACKEND'])
13 matplotlib.use(os.environ['BACKEND'])
14 elif 'linux' in sys.platform:
14 elif 'linux' in sys.platform:
15 matplotlib.use("TkAgg")
15 matplotlib.use("TkAgg")
16 elif 'darwin' in sys.platform:
16 elif 'darwin' in sys.platform:
17 matplotlib.use('WxAgg')
17 matplotlib.use('WxAgg')
18 else:
18 else:
19 from schainpy.utils import log
19 from schainpy.utils import log
20 log.warning('Using default Backend="Agg"', 'INFO')
20 log.warning('Using default Backend="Agg"', 'INFO')
21 matplotlib.use('Agg')
21 matplotlib.use('Agg')
22
22
23 import matplotlib.pyplot as plt
23 import matplotlib.pyplot as plt
24 from matplotlib.patches import Polygon
24 from matplotlib.patches import Polygon
25 from mpl_toolkits.axes_grid1 import make_axes_locatable
25 from mpl_toolkits.axes_grid1 import make_axes_locatable
26 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
26 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
27
27
28 from schainpy.model.data.jrodata import PlotterData
28 from schainpy.model.data.jrodata import PlotterData
29 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
29 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
30 from schainpy.utils import log
30 from schainpy.utils import log
31
31
32 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
32 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
33 blu_values = matplotlib.pyplot.get_cmap(
33 blu_values = matplotlib.pyplot.get_cmap(
34 'seismic_r', 20)(numpy.arange(20))[10:15]
34 'seismic_r', 20)(numpy.arange(20))[10:15]
35 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
35 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
36 'jro', numpy.vstack((blu_values, jet_values)))
36 'jro', numpy.vstack((blu_values, jet_values)))
37 matplotlib.pyplot.register_cmap(cmap=ncmap)
37 matplotlib.pyplot.register_cmap(cmap=ncmap)
38
38
39 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
39 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
40 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
40 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
41
41
42 EARTH_RADIUS = 6.3710e3
42 EARTH_RADIUS = 6.3710e3
43
43
44 def ll2xy(lat1, lon1, lat2, lon2):
44 def ll2xy(lat1, lon1, lat2, lon2):
45
45
46 p = 0.017453292519943295
46 p = 0.017453292519943295
47 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
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
48 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
49 r = 12742 * numpy.arcsin(numpy.sqrt(a))
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)
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))
51 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
52 theta = -theta + numpy.pi/2
52 theta = -theta + numpy.pi/2
53 return r*numpy.cos(theta), r*numpy.sin(theta)
53 return r*numpy.cos(theta), r*numpy.sin(theta)
54
54
55
55
56 def km2deg(km):
56 def km2deg(km):
57 '''
57 '''
58 Convert distance in km to degrees
58 Convert distance in km to degrees
59 '''
59 '''
60
60
61 return numpy.rad2deg(km/EARTH_RADIUS)
61 return numpy.rad2deg(km/EARTH_RADIUS)
62
62
63
63
64 def figpause(interval):
64 def figpause(interval):
65 backend = plt.rcParams['backend']
65 backend = plt.rcParams['backend']
66 if backend in matplotlib.rcsetup.interactive_bk:
66 if backend in matplotlib.rcsetup.interactive_bk:
67 figManager = matplotlib._pylab_helpers.Gcf.get_active()
67 figManager = matplotlib._pylab_helpers.Gcf.get_active()
68 if figManager is not None:
68 if figManager is not None:
69 canvas = figManager.canvas
69 canvas = figManager.canvas
70 if canvas.figure.stale:
70 if canvas.figure.stale:
71 canvas.draw()
71 canvas.draw()
72 try:
72 try:
73 canvas.start_event_loop(interval)
73 canvas.start_event_loop(interval)
74 except:
74 except:
75 pass
75 pass
76 return
76 return
77
77
78
78
79 def popup(message):
79 def popup(message):
80 '''
80 '''
81 '''
81 '''
82
82
83 fig = plt.figure(figsize=(12, 8), facecolor='r')
83 fig = plt.figure(figsize=(12, 8), facecolor='r')
84 text = '\n'.join([s.strip() for s in message.split(':')])
84 text = '\n'.join([s.strip() for s in message.split(':')])
85 fig.text(0.01, 0.5, text, ha='left', va='center',
85 fig.text(0.01, 0.5, text, ha='left', va='center',
86 size='20', weight='heavy', color='w')
86 size='20', weight='heavy', color='w')
87 fig.show()
87 fig.show()
88 figpause(1000)
88 figpause(1000)
89
89
90
90
91 class Throttle(object):
91 class Throttle(object):
92 '''
92 '''
93 Decorator that prevents a function from being called more than once every
93 Decorator that prevents a function from being called more than once every
94 time period.
94 time period.
95 To create a function that cannot be called more than once a minute, but
95 To create a function that cannot be called more than once a minute, but
96 will sleep until it can be called:
96 will sleep until it can be called:
97 @Throttle(minutes=1)
97 @Throttle(minutes=1)
98 def foo():
98 def foo():
99 pass
99 pass
100
100
101 for i in range(10):
101 for i in range(10):
102 foo()
102 foo()
103 print "This function has run %s times." % i
103 print "This function has run %s times." % i
104 '''
104 '''
105
105
106 def __init__(self, seconds=0, minutes=0, hours=0):
106 def __init__(self, seconds=0, minutes=0, hours=0):
107 self.throttle_period = datetime.timedelta(
107 self.throttle_period = datetime.timedelta(
108 seconds=seconds, minutes=minutes, hours=hours
108 seconds=seconds, minutes=minutes, hours=hours
109 )
109 )
110
110
111 self.time_of_last_call = datetime.datetime.min
111 self.time_of_last_call = datetime.datetime.min
112
112
113 def __call__(self, fn):
113 def __call__(self, fn):
114 @wraps(fn)
114 @wraps(fn)
115 def wrapper(*args, **kwargs):
115 def wrapper(*args, **kwargs):
116 coerce = kwargs.pop('coerce', None)
116 coerce = kwargs.pop('coerce', None)
117 if coerce:
117 if coerce:
118 self.time_of_last_call = datetime.datetime.now()
118 self.time_of_last_call = datetime.datetime.now()
119 return fn(*args, **kwargs)
119 return fn(*args, **kwargs)
120 else:
120 else:
121 now = datetime.datetime.now()
121 now = datetime.datetime.now()
122 time_since_last_call = now - self.time_of_last_call
122 time_since_last_call = now - self.time_of_last_call
123 time_left = self.throttle_period - time_since_last_call
123 time_left = self.throttle_period - time_since_last_call
124
124
125 if time_left > datetime.timedelta(seconds=0):
125 if time_left > datetime.timedelta(seconds=0):
126 return
126 return
127
127
128 self.time_of_last_call = datetime.datetime.now()
128 self.time_of_last_call = datetime.datetime.now()
129 return fn(*args, **kwargs)
129 return fn(*args, **kwargs)
130
130
131 return wrapper
131 return wrapper
132
132
133 def apply_throttle(value):
133 def apply_throttle(value):
134
134
135 @Throttle(seconds=value)
135 @Throttle(seconds=value)
136 def fnThrottled(fn):
136 def fnThrottled(fn):
137 fn()
137 fn()
138
138
139 return fnThrottled
139 return fnThrottled
140
140
141
141
142 @MPDecorator
142 @MPDecorator
143 class Plot(Operation):
143 class Plot(Operation):
144 '''
144 '''
145 Base class for Schain plotting operations
145 Base class for Schain plotting operations
146 '''
146 '''
147
147
148 CODE = 'Figure'
148 CODE = 'Figure'
149 colormap = 'jet'
149 colormap = 'jet'
150 bgcolor = 'white'
150 bgcolor = 'white'
151 __missing = 1E30
151 __missing = 1E30
152
152
153 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
153 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
154 'zlimits', 'xlabel', 'ylabel', 'xaxis', 'cb_label', 'title',
154 'zlimits', 'xlabel', 'ylabel', 'xaxis', 'cb_label', 'title',
155 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
155 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
156 'showprofile', 'decimation', 'pause']
156 'showprofile', 'decimation', 'pause']
157
157
158 def __init__(self):
158 def __init__(self):
159
159
160 Operation.__init__(self)
160 Operation.__init__(self)
161 self.isConfig = False
161 self.isConfig = False
162 self.isPlotConfig = False
162 self.isPlotConfig = False
163 self.save_counter = 1
163 self.save_counter = 1
164 self.sender_counter = 1
164 self.sender_counter = 1
165
165
166 def __fmtTime(self, x, pos):
166 def __fmtTime(self, x, pos):
167 '''
167 '''
168 '''
168 '''
169
169
170 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
170 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
171
171
172 def __setup(self, **kwargs):
172 def __setup(self, **kwargs):
173 '''
173 '''
174 Initialize variables
174 Initialize variables
175 '''
175 '''
176
176
177 self.figures = []
177 self.figures = []
178 self.axes = []
178 self.axes = []
179 self.cb_axes = []
179 self.cb_axes = []
180 self.localtime = kwargs.pop('localtime', True)
180 self.localtime = kwargs.pop('localtime', True)
181 self.show = kwargs.get('show', True)
181 self.show = kwargs.get('show', True)
182 self.save = kwargs.get('save', False)
182 self.save = kwargs.get('save', False)
183 self.save_period = kwargs.get('save_period', 2)
183 self.save_period = kwargs.get('save_period', 2)
184 self.ftp = kwargs.get('ftp', False)
184 self.ftp = kwargs.get('ftp', False)
185 self.colormap = kwargs.get('colormap', self.colormap)
185 self.colormap = kwargs.get('colormap', self.colormap)
186 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
186 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
187 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
187 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
188 self.colormaps = kwargs.get('colormaps', None)
188 self.colormaps = kwargs.get('colormaps', None)
189 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
189 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
190 self.showprofile = kwargs.get('showprofile', False)
190 self.showprofile = kwargs.get('showprofile', False)
191 self.title = kwargs.get('wintitle', self.CODE.upper())
191 self.title = kwargs.get('wintitle', self.CODE.upper())
192 self.cb_label = kwargs.get('cb_label', None)
192 self.cb_label = kwargs.get('cb_label', None)
193 self.cb_labels = kwargs.get('cb_labels', None)
193 self.cb_labels = kwargs.get('cb_labels', None)
194 self.labels = kwargs.get('labels', None)
194 self.labels = kwargs.get('labels', None)
195 self.xaxis = kwargs.get('xaxis', 'frequency')
195 self.xaxis = kwargs.get('xaxis', 'frequency')
196 self.zmin = kwargs.get('zmin', None)
196 self.zmin = kwargs.get('zmin', None)
197 self.zmax = kwargs.get('zmax', None)
197 self.zmax = kwargs.get('zmax', None)
198 self.zlimits = kwargs.get('zlimits', None)
198 self.zlimits = kwargs.get('zlimits', None)
199 self.xmin = kwargs.get('xmin', None)
199 self.xmin = kwargs.get('xmin', None)
200 self.xmax = kwargs.get('xmax', None)
200 self.xmax = kwargs.get('xmax', None)
201 self.xrange = kwargs.get('xrange', 24)
201 self.xrange = kwargs.get('xrange', 24)
202 self.xscale = kwargs.get('xscale', None)
202 self.xscale = kwargs.get('xscale', None)
203 self.ymin = kwargs.get('ymin', None)
203 self.ymin = kwargs.get('ymin', None)
204 self.ymax = kwargs.get('ymax', None)
204 self.ymax = kwargs.get('ymax', None)
205 self.yscale = kwargs.get('yscale', None)
205 self.yscale = kwargs.get('yscale', None)
206 self.xlabel = kwargs.get('xlabel', None)
206 self.xlabel = kwargs.get('xlabel', None)
207 self.decimation = kwargs.get('decimation', None)
207 self.decimation = kwargs.get('decimation', None)
208 self.showSNR = kwargs.get('showSNR', False)
208 self.showSNR = kwargs.get('showSNR', False)
209 self.oneFigure = kwargs.get('oneFigure', True)
209 self.oneFigure = kwargs.get('oneFigure', True)
210 self.width = kwargs.get('width', None)
210 self.width = kwargs.get('width', None)
211 self.height = kwargs.get('height', None)
211 self.height = kwargs.get('height', None)
212 self.colorbar = kwargs.get('colorbar', True)
212 self.colorbar = kwargs.get('colorbar', True)
213 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
213 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
214 self.channels = kwargs.get('channels', None)
214 self.channels = kwargs.get('channels', None)
215 self.titles = kwargs.get('titles', [])
215 self.titles = kwargs.get('titles', [])
216 self.polar = False
216 self.polar = False
217 self.type = kwargs.get('type', 'iq')
217 self.type = kwargs.get('type', 'iq')
218 self.grid = kwargs.get('grid', False)
218 self.grid = kwargs.get('grid', False)
219 self.pause = kwargs.get('pause', False)
219 self.pause = kwargs.get('pause', False)
220 self.save_labels = kwargs.get('save_labels', None)
220 self.save_labels = kwargs.get('save_labels', None)
221 self.realtime = kwargs.get('realtime', True)
221 self.realtime = kwargs.get('realtime', True)
222 self.buffering = kwargs.get('buffering', True)
222 self.buffering = kwargs.get('buffering', True)
223 self.throttle = kwargs.get('throttle', 2)
223 self.throttle = kwargs.get('throttle', 2)
224 self.exp_code = kwargs.get('exp_code', None)
224 self.exp_code = kwargs.get('exp_code', None)
225 self.plot_server = kwargs.get('plot_server', False)
225 self.plot_server = kwargs.get('plot_server', False)
226 self.sender_period = kwargs.get('sender_period', 2)
226 self.sender_period = kwargs.get('sender_period', 2)
227 self.__throttle_plot = apply_throttle(self.throttle)
227 self.__throttle_plot = apply_throttle(self.throttle)
228 self.data = PlotterData(
228 self.data = PlotterData(
229 self.CODE, self.throttle, self.exp_code, self.buffering)
229 self.CODE, self.throttle, self.exp_code, self.buffering)
230
230
231 if self.plot_server:
231 if self.plot_server:
232 if not self.plot_server.startswith('tcp://'):
232 if not self.plot_server.startswith('tcp://'):
233 self.plot_server = 'tcp://{}'.format(self.plot_server)
233 self.plot_server = 'tcp://{}'.format(self.plot_server)
234 log.success(
234 log.success(
235 'Sending to server: {}'.format(self.plot_server),
235 'Sending to server: {}'.format(self.plot_server),
236 self.name
236 self.name
237 )
237 )
238
238
239 def __setup_plot(self):
239 def __setup_plot(self):
240 '''
240 '''
241 Common setup for all figures, here figures and axes are created
241 Common setup for all figures, here figures and axes are created
242 '''
242 '''
243
243
244 self.setup()
244 self.setup()
245
245
246 self.time_label = 'LT' if self.localtime else 'UTC'
246 self.time_label = 'LT' if self.localtime else 'UTC'
247 if self.data.localtime:
247 if self.data.localtime:
248 self.getDateTime = datetime.datetime.fromtimestamp
248 self.getDateTime = datetime.datetime.fromtimestamp
249 else:
249 else:
250 self.getDateTime = datetime.datetime.utcfromtimestamp
250 self.getDateTime = datetime.datetime.utcfromtimestamp
251
251
252 if self.width is None:
252 if self.width is None:
253 self.width = 8
253 self.width = 8
254
254
255 self.figures = []
255 self.figures = []
256 self.axes = []
256 self.axes = []
257 self.cb_axes = []
257 self.cb_axes = []
258 self.pf_axes = []
258 self.pf_axes = []
259 self.cmaps = []
259 self.cmaps = []
260
260
261 size = '15%' if self.ncols == 1 else '30%'
261 size = '15%' if self.ncols == 1 else '30%'
262 pad = '4%' if self.ncols == 1 else '8%'
262 pad = '4%' if self.ncols == 1 else '8%'
263
263
264 if self.oneFigure:
264 if self.oneFigure:
265 if self.height is None:
265 if self.height is None:
266 self.height = 1.4 * self.nrows + 1
266 self.height = 1.4 * self.nrows + 1
267 fig = plt.figure(figsize=(self.width, self.height),
267 fig = plt.figure(figsize=(self.width, self.height),
268 edgecolor='k',
268 edgecolor='k',
269 facecolor='w')
269 facecolor='w')
270 self.figures.append(fig)
270 self.figures.append(fig)
271 for n in range(self.nplots):
271 for n in range(self.nplots):
272 ax = fig.add_subplot(self.nrows, self.ncols,
272 ax = fig.add_subplot(self.nrows, self.ncols,
273 n + 1, polar=self.polar)
273 n + 1, polar=self.polar)
274 ax.tick_params(labelsize=8)
274 ax.tick_params(labelsize=8)
275 ax.firsttime = True
275 ax.firsttime = True
276 ax.index = 0
276 ax.index = 0
277 ax.press = None
277 ax.press = None
278 self.axes.append(ax)
278 self.axes.append(ax)
279 if self.showprofile:
279 if self.showprofile:
280 cax = self.__add_axes(ax, size=size, pad=pad)
280 cax = self.__add_axes(ax, size=size, pad=pad)
281 cax.tick_params(labelsize=8)
281 cax.tick_params(labelsize=8)
282 self.pf_axes.append(cax)
282 self.pf_axes.append(cax)
283 else:
283 else:
284 if self.height is None:
284 if self.height is None:
285 self.height = 3
285 self.height = 3
286 for n in range(self.nplots):
286 for n in range(self.nplots):
287 fig = plt.figure(figsize=(self.width, self.height),
287 fig = plt.figure(figsize=(self.width, self.height),
288 edgecolor='k',
288 edgecolor='k',
289 facecolor='w')
289 facecolor='w')
290 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
290 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
291 ax.tick_params(labelsize=8)
291 ax.tick_params(labelsize=8)
292 ax.firsttime = True
292 ax.firsttime = True
293 ax.index = 0
293 ax.index = 0
294 ax.press = None
294 ax.press = None
295 self.figures.append(fig)
295 self.figures.append(fig)
296 self.axes.append(ax)
296 self.axes.append(ax)
297 if self.showprofile:
297 if self.showprofile:
298 cax = self.__add_axes(ax, size=size, pad=pad)
298 cax = self.__add_axes(ax, size=size, pad=pad)
299 cax.tick_params(labelsize=8)
299 cax.tick_params(labelsize=8)
300 self.pf_axes.append(cax)
300 self.pf_axes.append(cax)
301
301
302 for n in range(self.nrows):
302 for n in range(self.nrows):
303 if self.colormaps is not None:
303 if self.colormaps is not None:
304 cmap = plt.get_cmap(self.colormaps[n])
304 cmap = plt.get_cmap(self.colormaps[n])
305 else:
305 else:
306 cmap = plt.get_cmap(self.colormap)
306 cmap = plt.get_cmap(self.colormap)
307 cmap.set_bad(self.bgcolor, 1.)
307 cmap.set_bad(self.bgcolor, 1.)
308 self.cmaps.append(cmap)
308 self.cmaps.append(cmap)
309
309
310 for fig in self.figures:
310 for fig in self.figures:
311 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
311 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
312 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
312 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
313 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
313 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
314 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
314 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
315 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
315 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
316 if self.show:
316 if self.show:
317 fig.show()
317 fig.show()
318
318
319 def OnKeyPress(self, event):
319 def OnKeyPress(self, event):
320 '''
320 '''
321 Event for pressing keys (up, down) change colormap
321 Event for pressing keys (up, down) change colormap
322 '''
322 '''
323 ax = event.inaxes
323 ax = event.inaxes
324 if ax in self.axes:
324 if ax in self.axes:
325 if event.key == 'down':
325 if event.key == 'down':
326 ax.index += 1
326 ax.index += 1
327 elif event.key == 'up':
327 elif event.key == 'up':
328 ax.index -= 1
328 ax.index -= 1
329 if ax.index < 0:
329 if ax.index < 0:
330 ax.index = len(CMAPS) - 1
330 ax.index = len(CMAPS) - 1
331 elif ax.index == len(CMAPS):
331 elif ax.index == len(CMAPS):
332 ax.index = 0
332 ax.index = 0
333 cmap = CMAPS[ax.index]
333 cmap = CMAPS[ax.index]
334 ax.cbar.set_cmap(cmap)
334 ax.cbar.set_cmap(cmap)
335 ax.cbar.draw_all()
335 ax.cbar.draw_all()
336 ax.plt.set_cmap(cmap)
336 ax.plt.set_cmap(cmap)
337 ax.cbar.patch.figure.canvas.draw()
337 ax.cbar.patch.figure.canvas.draw()
338 self.colormap = cmap.name
338 self.colormap = cmap.name
339
339
340 def OnBtnScroll(self, event):
340 def OnBtnScroll(self, event):
341 '''
341 '''
342 Event for scrolling, scale figure
342 Event for scrolling, scale figure
343 '''
343 '''
344 cb_ax = event.inaxes
344 cb_ax = event.inaxes
345 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
345 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
346 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
346 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
347 pt = ax.cbar.ax.bbox.get_points()[:, 1]
347 pt = ax.cbar.ax.bbox.get_points()[:, 1]
348 nrm = ax.cbar.norm
348 nrm = ax.cbar.norm
349 vmin, vmax, p0, p1, pS = (
349 vmin, vmax, p0, p1, pS = (
350 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
350 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
351 scale = 2 if event.step == 1 else 0.5
351 scale = 2 if event.step == 1 else 0.5
352 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
352 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
353 ax.cbar.norm.vmin = point - scale * (point - vmin)
353 ax.cbar.norm.vmin = point - scale * (point - vmin)
354 ax.cbar.norm.vmax = point - scale * (point - vmax)
354 ax.cbar.norm.vmax = point - scale * (point - vmax)
355 ax.plt.set_norm(ax.cbar.norm)
355 ax.plt.set_norm(ax.cbar.norm)
356 ax.cbar.draw_all()
356 ax.cbar.draw_all()
357 ax.cbar.patch.figure.canvas.draw()
357 ax.cbar.patch.figure.canvas.draw()
358
358
359 def onBtnPress(self, event):
359 def onBtnPress(self, event):
360 '''
360 '''
361 Event for mouse button press
361 Event for mouse button press
362 '''
362 '''
363 cb_ax = event.inaxes
363 cb_ax = event.inaxes
364 if cb_ax is None:
364 if cb_ax is None:
365 return
365 return
366
366
367 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
367 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
368 cb_ax.press = event.x, event.y
368 cb_ax.press = event.x, event.y
369 else:
369 else:
370 cb_ax.press = None
370 cb_ax.press = None
371
371
372 def onMotion(self, event):
372 def onMotion(self, event):
373 '''
373 '''
374 Event for move inside colorbar
374 Event for move inside colorbar
375 '''
375 '''
376 cb_ax = event.inaxes
376 cb_ax = event.inaxes
377 if cb_ax is None:
377 if cb_ax is None:
378 return
378 return
379 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
379 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
380 return
380 return
381 if cb_ax.press is None:
381 if cb_ax.press is None:
382 return
382 return
383
383
384 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
384 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
385 xprev, yprev = cb_ax.press
385 xprev, yprev = cb_ax.press
386 dx = event.x - xprev
386 dx = event.x - xprev
387 dy = event.y - yprev
387 dy = event.y - yprev
388 cb_ax.press = event.x, event.y
388 cb_ax.press = event.x, event.y
389 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
389 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
390 perc = 0.03
390 perc = 0.03
391
391
392 if event.button == 1:
392 if event.button == 1:
393 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
393 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
394 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
394 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
395 elif event.button == 3:
395 elif event.button == 3:
396 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
396 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
397 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
397 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
398
398
399 ax.cbar.draw_all()
399 ax.cbar.draw_all()
400 ax.plt.set_norm(ax.cbar.norm)
400 ax.plt.set_norm(ax.cbar.norm)
401 ax.cbar.patch.figure.canvas.draw()
401 ax.cbar.patch.figure.canvas.draw()
402
402
403 def onBtnRelease(self, event):
403 def onBtnRelease(self, event):
404 '''
404 '''
405 Event for mouse button release
405 Event for mouse button release
406 '''
406 '''
407 cb_ax = event.inaxes
407 cb_ax = event.inaxes
408 if cb_ax is not None:
408 if cb_ax is not None:
409 cb_ax.press = None
409 cb_ax.press = None
410
410
411 def __add_axes(self, ax, size='30%', pad='8%'):
411 def __add_axes(self, ax, size='30%', pad='8%'):
412 '''
412 '''
413 Add new axes to the given figure
413 Add new axes to the given figure
414 '''
414 '''
415 divider = make_axes_locatable(ax)
415 divider = make_axes_locatable(ax)
416 nax = divider.new_horizontal(size=size, pad=pad)
416 nax = divider.new_horizontal(size=size, pad=pad)
417 ax.figure.add_axes(nax)
417 ax.figure.add_axes(nax)
418 return nax
418 return nax
419
419
420 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
420 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
421 '''
421 '''
422 Create a masked array for missing data
422 Create a masked array for missing data
423 '''
423 '''
424 if x_buffer.shape[0] < 2:
424 if x_buffer.shape[0] < 2:
425 return x_buffer, y_buffer, z_buffer
425 return x_buffer, y_buffer, z_buffer
426
426
427 deltas = x_buffer[1:] - x_buffer[0:-1]
427 deltas = x_buffer[1:] - x_buffer[0:-1]
428 x_median = numpy.median(deltas)
428 x_median = numpy.median(deltas)
429
429
430 index = numpy.where(deltas > 5 * x_median)
430 index = numpy.where(deltas > 5 * x_median)
431
431
432 if len(index[0]) != 0:
432 if len(index[0]) != 0:
433 z_buffer[::, index[0], ::] = self.__missing
433 z_buffer[::, index[0], ::] = self.__missing
434 z_buffer = numpy.ma.masked_inside(z_buffer,
434 z_buffer = numpy.ma.masked_inside(z_buffer,
435 0.99 * self.__missing,
435 0.99 * self.__missing,
436 1.01 * self.__missing)
436 1.01 * self.__missing)
437
437
438 return x_buffer, y_buffer, z_buffer
438 return x_buffer, y_buffer, z_buffer
439
439
440 def decimate(self):
440 def decimate(self):
441
441
442 # dx = int(len(self.x)/self.__MAXNUMX) + 1
442 # dx = int(len(self.x)/self.__MAXNUMX) + 1
443 dy = int(len(self.y) / self.decimation) + 1
443 dy = int(len(self.y) / self.decimation) + 1
444
444
445 # x = self.x[::dx]
445 # x = self.x[::dx]
446 x = self.x
446 x = self.x
447 y = self.y[::dy]
447 y = self.y[::dy]
448 z = self.z[::, ::, ::dy]
448 z = self.z[::, ::, ::dy]
449
449
450 return x, y, z
450 return x, y, z
451
451
452 def format(self):
452 def format(self):
453 '''
453 '''
454 Set min and max values, labels, ticks and titles
454 Set min and max values, labels, ticks and titles
455 '''
455 '''
456
456
457 if self.xmin is None:
457 if self.xmin is None:
458 xmin = self.data.min_time
458 xmin = self.data.min_time
459 else:
459 else:
460 if self.xaxis is 'time':
460 if self.xaxis is 'time':
461 dt = self.getDateTime(self.data.min_time)
461 dt = self.getDateTime(self.data.min_time)
462 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
462 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
463 datetime.datetime(1970, 1, 1)).total_seconds()
463 datetime.datetime(1970, 1, 1)).total_seconds()
464 if self.data.localtime:
464 if self.data.localtime:
465 xmin += time.timezone
465 xmin += time.timezone
466 self.tmin = xmin
467 else:
466 else:
468 xmin = self.xmin
467 xmin = self.xmin
469
468
470 if self.xmax is None:
469 if self.xmax is None:
471 xmax = xmin + self.xrange * 60 * 60
470 xmax = xmin + self.xrange * 60 * 60
472 else:
471 else:
473 if self.xaxis is 'time':
472 if self.xaxis is 'time':
474 dt = self.getDateTime(self.data.max_time)
473 dt = self.getDateTime(self.data.max_time)
475 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
474 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
476 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
475 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
477 if self.data.localtime:
476 if self.data.localtime:
478 xmax += time.timezone
477 xmax += time.timezone
479 else:
478 else:
480 xmax = self.xmax
479 xmax = self.xmax
481
480
482 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
481 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
483 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
482 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
484 #Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000])
483 #Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000])
485
484
486 #i = 1 if numpy.where(
485 #i = 1 if numpy.where(
487 # abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
486 # abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
488 #ystep = Y[i] / 10.
487 #ystep = Y[i] / 10.
489 dig = int(numpy.log10(ymax))
488 dig = int(numpy.log10(ymax))
490 if dig == 0:
489 if dig == 0:
491 digD = len(str(ymax)) - 2
490 digD = len(str(ymax)) - 2
492 ydec = ymax*(10**digD)
491 ydec = ymax*(10**digD)
493
492
494 dig = int(numpy.log10(ydec))
493 dig = int(numpy.log10(ydec))
495 ystep = ((ydec + (10**(dig)))//10**(dig))*(10**(dig))
494 ystep = ((ydec + (10**(dig)))//10**(dig))*(10**(dig))
496 ystep = ystep/5
495 ystep = ystep/5
497 ystep = ystep/(10**digD)
496 ystep = ystep/(10**digD)
498
497
499 else:
498 else:
500 ystep = ((ymax + (10**(dig)))//10**(dig))*(10**(dig))
499 ystep = ((ymax + (10**(dig)))//10**(dig))*(10**(dig))
501 ystep = ystep/5
500 ystep = ystep/5
502
501
503 if self.xaxis is not 'time':
502 if self.xaxis is not 'time':
504
503
505 dig = int(numpy.log10(xmax))
504 dig = int(numpy.log10(xmax))
506
505
507 if dig <= 0:
506 if dig <= 0:
508 digD = len(str(xmax)) - 2
507 digD = len(str(xmax)) - 2
509 xdec = xmax*(10**digD)
508 xdec = xmax*(10**digD)
510
509
511 dig = int(numpy.log10(xdec))
510 dig = int(numpy.log10(xdec))
512 xstep = ((xdec + (10**(dig)))//10**(dig))*(10**(dig))
511 xstep = ((xdec + (10**(dig)))//10**(dig))*(10**(dig))
513 xstep = xstep*0.5
512 xstep = xstep*0.5
514 xstep = xstep/(10**digD)
513 xstep = xstep/(10**digD)
515
514
516 else:
515 else:
517 xstep = ((xmax + (10**(dig)))//10**(dig))*(10**(dig))
516 xstep = ((xmax + (10**(dig)))//10**(dig))*(10**(dig))
518 xstep = xstep/5
517 xstep = xstep/5
519
518
520 for n, ax in enumerate(self.axes):
519 for n, ax in enumerate(self.axes):
521 if ax.firsttime:
520 if ax.firsttime:
522 ax.set_facecolor(self.bgcolor)
521 ax.set_facecolor(self.bgcolor)
523 ax.yaxis.set_major_locator(MultipleLocator(ystep))
522 ax.yaxis.set_major_locator(MultipleLocator(ystep))
524 if self.xscale:
523 if self.xscale:
525 ax.xaxis.set_major_formatter(FuncFormatter(
524 ax.xaxis.set_major_formatter(FuncFormatter(
526 lambda x, pos: '{0:g}'.format(x*self.xscale)))
525 lambda x, pos: '{0:g}'.format(x*self.xscale)))
527 if self.xscale:
526 if self.xscale:
528 ax.yaxis.set_major_formatter(FuncFormatter(
527 ax.yaxis.set_major_formatter(FuncFormatter(
529 lambda x, pos: '{0:g}'.format(x*self.yscale)))
528 lambda x, pos: '{0:g}'.format(x*self.yscale)))
530 if self.xaxis is 'time':
529 if self.xaxis is 'time':
531 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
530 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
532 ax.xaxis.set_major_locator(LinearLocator(9))
531 ax.xaxis.set_major_locator(LinearLocator(9))
533 else:
532 else:
534 ax.xaxis.set_major_locator(MultipleLocator(xstep))
533 ax.xaxis.set_major_locator(MultipleLocator(xstep))
535 if self.xlabel is not None:
534 if self.xlabel is not None:
536 ax.set_xlabel(self.xlabel)
535 ax.set_xlabel(self.xlabel)
537 ax.set_ylabel(self.ylabel)
536 ax.set_ylabel(self.ylabel)
538 ax.firsttime = False
537 ax.firsttime = False
539 if self.showprofile:
538 if self.showprofile:
540 self.pf_axes[n].set_ylim(ymin, ymax)
539 self.pf_axes[n].set_ylim(ymin, ymax)
541 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
540 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
542 self.pf_axes[n].set_xlabel('dB')
541 self.pf_axes[n].set_xlabel('dB')
543 self.pf_axes[n].grid(b=True, axis='x')
542 self.pf_axes[n].grid(b=True, axis='x')
544 [tick.set_visible(False)
543 [tick.set_visible(False)
545 for tick in self.pf_axes[n].get_yticklabels()]
544 for tick in self.pf_axes[n].get_yticklabels()]
546 if self.colorbar:
545 if self.colorbar:
547 ax.cbar = plt.colorbar(
546 ax.cbar = plt.colorbar(
548 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
547 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
549 ax.cbar.ax.tick_params(labelsize=8)
548 ax.cbar.ax.tick_params(labelsize=8)
550 ax.cbar.ax.press = None
549 ax.cbar.ax.press = None
551 if self.cb_label:
550 if self.cb_label:
552 ax.cbar.set_label(self.cb_label, size=8)
551 ax.cbar.set_label(self.cb_label, size=8)
553 elif self.cb_labels:
552 elif self.cb_labels:
554 ax.cbar.set_label(self.cb_labels[n], size=8)
553 ax.cbar.set_label(self.cb_labels[n], size=8)
555 else:
554 else:
556 ax.cbar = None
555 ax.cbar = None
557 if self.grid:
556 if self.grid:
558 ax.grid(True)
557 ax.grid(True)
559
558
560 if not self.polar:
559 if not self.polar:
561 ax.set_xlim(xmin, xmax)
560 ax.set_xlim(xmin, xmax)
562 ax.set_ylim(ymin, ymax)
561 ax.set_ylim(ymin, ymax)
563 ax.set_title('{} {} {}'.format(
562 ax.set_title('{} {} {}'.format(
564 self.titles[n],
563 self.titles[n],
565 self.getDateTime(self.data.max_time).strftime(
564 self.getDateTime(self.data.max_time).strftime(
566 '%H:%M:%S'),
565 '%Y-%m-%d %H:%M:%S'),
567 self.time_label),
566 self.time_label),
568 size=8)
567 size=8)
569 else:
568 else:
570 ax.set_title('{}'.format(self.titles[n]), size=8)
569 ax.set_title('{}'.format(self.titles[n]), size=8)
571 ax.set_ylim(0, 90)
570 ax.set_ylim(0, 90)
572 ax.set_yticks(numpy.arange(0, 90, 20))
571 ax.set_yticks(numpy.arange(0, 90, 20))
573 ax.yaxis.labelpad = 40
572 ax.yaxis.labelpad = 40
574
573
575 def clear_figures(self):
574 def clear_figures(self):
576 '''
575 '''
577 Reset axes for redraw plots
576 Reset axes for redraw plots
578 '''
577 '''
579
578
580 for ax in self.axes:
579 for ax in self.axes:
581 ax.clear()
580 ax.clear()
582 ax.firsttime = True
581 ax.firsttime = True
583 if ax.cbar:
582 if ax.cbar:
584 ax.cbar.remove()
583 ax.cbar.remove()
585
584
586 def __plot(self):
585 def __plot(self):
587 '''
586 '''
588 Main function to plot, format and save figures
587 Main function to plot, format and save figures
589 '''
588 '''
590
589
591 try:
590 try:
592 self.plot()
591 self.plot()
593 self.format()
592 self.format()
594 except Exception as e:
593 except Exception as e:
595 log.warning('{} Plot could not be updated... check data'.format(
594 log.warning('{} Plot could not be updated... check data'.format(
596 self.CODE), self.name)
595 self.CODE), self.name)
597 log.error(str(e), '')
596 log.error(str(e), '')
598 return
597 return
599
598
600 for n, fig in enumerate(self.figures):
599 for n, fig in enumerate(self.figures):
601 if self.nrows == 0 or self.nplots == 0:
600 if self.nrows == 0 or self.nplots == 0:
602 log.warning('No data', self.name)
601 log.warning('No data', self.name)
603 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
602 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
604 fig.canvas.manager.set_window_title(self.CODE)
603 fig.canvas.manager.set_window_title(self.CODE)
605 continue
604 continue
606
605
607 fig.tight_layout()
606 fig.tight_layout()
608 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
607 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
609 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
608 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
610 fig.canvas.draw()
609 fig.canvas.draw()
611
610
612 if self.save:
611 if self.save:
613 self.save_figure(n)
612 self.save_figure(n)
614
613
615 if self.plot_server:
614 if self.plot_server:
616 self.send_to_server()
615 self.send_to_server()
617 # t = Thread(target=self.send_to_server)
616 # t = Thread(target=self.send_to_server)
618 # t.start()
617 # t.start()
619
618
620 def save_figure(self, n):
619 def save_figure(self, n):
621 '''
620 '''
622 '''
621 '''
623
622
624 if self.save_counter < self.save_period:
623 if self.save_counter < self.save_period:
625 self.save_counter += 1
624 self.save_counter += 1
626 return
625 return
627
626
628 self.save_counter = 1
627 self.save_counter = 1
629
628
630 fig = self.figures[n]
629 fig = self.figures[n]
631
630
632 if self.save_labels:
631 if self.save_labels:
633 labels = self.save_labels
632 labels = self.save_labels
634 else:
633 else:
635 labels = list(range(self.nrows))
634 labels = list(range(self.nrows))
636
635
637 if self.oneFigure:
636 if self.oneFigure:
638 label = ''
637 label = ''
639 else:
638 else:
640 label = '-{}'.format(labels[n])
639 label = '-{}'.format(labels[n])
641 figname = os.path.join(
640 figname = os.path.join(
642 self.save,
641 self.save,
643 self.CODE,
642 self.CODE,
644 '{}{}_{}.png'.format(
643 '{}{}_{}.png'.format(
645 self.CODE,
644 self.CODE,
646 label,
645 label,
647 self.getDateTime(self.data.max_time).strftime(
646 self.getDateTime(self.data.max_time).strftime(
648 '%Y%m%d_%H%M%S'
647 '%Y%m%d_%H%M%S'
649 ),
648 ),
650 )
649 )
651 )
650 )
652 log.log('Saving figure: {}'.format(figname), self.name)
651 log.log('Saving figure: {}'.format(figname), self.name)
653 if not os.path.isdir(os.path.dirname(figname)):
652 if not os.path.isdir(os.path.dirname(figname)):
654 os.makedirs(os.path.dirname(figname))
653 os.makedirs(os.path.dirname(figname))
655 fig.savefig(figname)
654 fig.savefig(figname)
656
655
657 if self.realtime:
656 if self.realtime:
658 figname = os.path.join(
657 figname = os.path.join(
659 self.save,
658 self.save,
660 '{}{}_{}.png'.format(
659 '{}{}_{}.png'.format(
661 self.CODE,
660 self.CODE,
662 label,
661 label,
663 self.getDateTime(self.data.min_time).strftime(
662 self.getDateTime(self.data.min_time).strftime(
664 '%Y%m%d'
663 '%Y%m%d'
665 ),
664 ),
666 )
665 )
667 )
666 )
668 fig.savefig(figname)
667 fig.savefig(figname)
669
668
670 def send_to_server(self):
669 def send_to_server(self):
671 '''
670 '''
672 '''
671 '''
673
672
674 if self.sender_counter < self.sender_period:
673 if self.sender_counter < self.sender_period:
675 self.sender_counter += 1
674 self.sender_counter += 1
676
675
677 self.sender_counter = 1
676 self.sender_counter = 1
678
677
679 retries = 2
678 retries = 2
680 while True:
679 while True:
681 self.socket.send_string(self.data.jsonify())
680 self.socket.send_string(self.data.jsonify())
682 socks = dict(self.poll.poll(5000))
681 socks = dict(self.poll.poll(5000))
683 if socks.get(self.socket) == zmq.POLLIN:
682 if socks.get(self.socket) == zmq.POLLIN:
684 reply = self.socket.recv_string()
683 reply = self.socket.recv_string()
685 if reply == 'ok':
684 if reply == 'ok':
686 log.log("Response from server ok", self.name)
685 log.log("Response from server ok", self.name)
687 break
686 break
688 else:
687 else:
689 log.warning(
688 log.warning(
690 "Malformed reply from server: {}".format(reply), self.name)
689 "Malformed reply from server: {}".format(reply), self.name)
691
690
692 else:
691 else:
693 log.warning(
692 log.warning(
694 "No response from server, retrying...", self.name)
693 "No response from server, retrying...", self.name)
695 self.socket.setsockopt(zmq.LINGER, 0)
694 self.socket.setsockopt(zmq.LINGER, 0)
696 self.socket.close()
695 self.socket.close()
697 self.poll.unregister(self.socket)
696 self.poll.unregister(self.socket)
698 retries -= 1
697 retries -= 1
699 if retries == 0:
698 if retries == 0:
700 log.error(
699 log.error(
701 "Server seems to be offline, abandoning", self.name)
700 "Server seems to be offline, abandoning", self.name)
702 self.socket = self.context.socket(zmq.REQ)
701 self.socket = self.context.socket(zmq.REQ)
703 self.socket.connect(self.plot_server)
702 self.socket.connect(self.plot_server)
704 self.poll.register(self.socket, zmq.POLLIN)
703 self.poll.register(self.socket, zmq.POLLIN)
705 time.sleep(1)
704 time.sleep(1)
706 break
705 break
707 self.socket = self.context.socket(zmq.REQ)
706 self.socket = self.context.socket(zmq.REQ)
708 self.socket.connect(self.plot_server)
707 self.socket.connect(self.plot_server)
709 self.poll.register(self.socket, zmq.POLLIN)
708 self.poll.register(self.socket, zmq.POLLIN)
710 time.sleep(0.5)
709 time.sleep(0.5)
711
710
712 def setup(self):
711 def setup(self):
713 '''
712 '''
714 This method should be implemented in the child class, the following
713 This method should be implemented in the child class, the following
715 attributes should be set:
714 attributes should be set:
716
715
717 self.nrows: number of rows
716 self.nrows: number of rows
718 self.ncols: number of cols
717 self.ncols: number of cols
719 self.nplots: number of plots (channels or pairs)
718 self.nplots: number of plots (channels or pairs)
720 self.ylabel: label for Y axes
719 self.ylabel: label for Y axes
721 self.titles: list of axes title
720 self.titles: list of axes title
722
721
723 '''
722 '''
724 raise NotImplementedError
723 raise NotImplementedError
725
724
726 def plot(self):
725 def plot(self):
727 '''
726 '''
728 Must be defined in the child class
727 Must be defined in the child class
729 '''
728 '''
730 raise NotImplementedError
729 raise NotImplementedError
731
730
732 def run(self, dataOut, **kwargs):
731 def run(self, dataOut, **kwargs):
733
732
734 if dataOut.error:
733 if dataOut.error:
735 coerce = True
734 coerce = True
736 else:
735 else:
737 coerce = False
736 coerce = False
738
737
739 if self.isConfig is False:
738 if self.isConfig is False:
740 self.__setup(**kwargs)
739 self.__setup(**kwargs)
740 if dataOut.type == 'Parameters':
741 self.tmin = dataOut.utctimeInit
742 else:
743 self.tmin = dataOut.utctime
744
745 if dataOut.useLocalTime:
746 if not self.localtime:
747 self.tmin += time.timezone
748 else:
749 if self.localtime:
750 self.tmin -= time.timezone
741 self.data.setup()
751 self.data.setup()
742 self.isConfig = True
752 self.isConfig = True
743 if self.plot_server:
753 if self.plot_server:
744 self.context = zmq.Context()
754 self.context = zmq.Context()
745 self.socket = self.context.socket(zmq.REQ)
755 self.socket = self.context.socket(zmq.REQ)
746 self.socket.connect(self.plot_server)
756 self.socket.connect(self.plot_server)
747 self.poll = zmq.Poller()
757 self.poll = zmq.Poller()
748 self.poll.register(self.socket, zmq.POLLIN)
758 self.poll.register(self.socket, zmq.POLLIN)
749
759
750 if dataOut.type == 'Parameters':
760 if dataOut.type == 'Parameters':
751 tm = dataOut.utctimeInit
761 tm = dataOut.utctimeInit
752 else:
762 else:
753 tm = dataOut.utctime
763 tm = dataOut.utctime
754
764
755 if dataOut.useLocalTime:
765 if dataOut.useLocalTime:
756 if not self.localtime:
766 if not self.localtime:
757 tm += time.timezone
767 tm += time.timezone
758 else:
768 else:
759 if self.localtime:
769 if self.localtime:
760 tm -= time.timezone
770 tm -= time.timezone
761
771
762 if self.xaxis is 'time' and self.data and (tm - self.tmin) >= self.xrange*60*60:
772 if self.xaxis is 'time' and self.data and (tm - self.tmin) >= self.xrange*60*60:
773 self.save_counter = self.save_period
763 self.__plot()
774 self.__plot()
775 self.xmin += self.xrange
776 if self.xmin >= 24:
777 self.xmin -= 24
778 self.tmin += self.xrange*60*60
764 self.data.setup()
779 self.data.setup()
765 self.clear_figures()
780 self.clear_figures()
766
781
767 self.data.update(dataOut, tm)
782 self.data.update(dataOut, tm)
768
783
769 if self.isPlotConfig is False:
784 if self.isPlotConfig is False:
770 self.__setup_plot()
785 self.__setup_plot()
771 self.isPlotConfig = True
786 self.isPlotConfig = True
772
787
773 if self.realtime:
788 if self.realtime:
774 self.__plot()
789 self.__plot()
775 else:
790 else:
776 self.__throttle_plot(self.__plot, coerce=coerce)
791 self.__throttle_plot(self.__plot, coerce=coerce)
777
792
778 figpause(0.001)
793 figpause(0.01)
779
794
780 def close(self):
795 def close(self):
781
796
797 if self.data:
798 self.save_counter = self.save_period
799 self.__plot()
782 if self.data and self.pause:
800 if self.data and self.pause:
783 figpause(10)
801 figpause(10)
784
802
General Comments 0
You need to be logged in to leave comments. Login now