##// END OF EJS Templates
Fix xrange for RTI plots
Juan C. Espinoza -
r1213:76af808a8dc6
parent child
Show More
@@ -1,783 +1,784
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', 12)
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
466 else:
467 else:
467 xmin = self.xmin
468 xmin = self.xmin
468
469
469 if self.xmax is None:
470 if self.xmax is None:
470 xmax = xmin + self.xrange * 60 * 60
471 xmax = xmin + self.xrange * 60 * 60
471 else:
472 else:
472 if self.xaxis is 'time':
473 if self.xaxis is 'time':
473 dt = self.getDateTime(self.data.max_time)
474 dt = self.getDateTime(self.data.max_time)
474 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
475 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
475 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
476 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
476 if self.data.localtime:
477 if self.data.localtime:
477 xmax += time.timezone
478 xmax += time.timezone
478 else:
479 else:
479 xmax = self.xmax
480 xmax = self.xmax
480
481
481 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
482 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
482 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
483 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
483 #Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000])
484 #Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000])
484
485
485 #i = 1 if numpy.where(
486 #i = 1 if numpy.where(
486 # abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
487 # abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
487 #ystep = Y[i] / 10.
488 #ystep = Y[i] / 10.
488 dig = int(numpy.log10(ymax))
489 dig = int(numpy.log10(ymax))
489 if dig == 0:
490 if dig == 0:
490 digD = len(str(ymax)) - 2
491 digD = len(str(ymax)) - 2
491 ydec = ymax*(10**digD)
492 ydec = ymax*(10**digD)
492
493
493 dig = int(numpy.log10(ydec))
494 dig = int(numpy.log10(ydec))
494 ystep = ((ydec + (10**(dig)))//10**(dig))*(10**(dig))
495 ystep = ((ydec + (10**(dig)))//10**(dig))*(10**(dig))
495 ystep = ystep/5
496 ystep = ystep/5
496 ystep = ystep/(10**digD)
497 ystep = ystep/(10**digD)
497
498
498 else:
499 else:
499 ystep = ((ymax + (10**(dig)))//10**(dig))*(10**(dig))
500 ystep = ((ymax + (10**(dig)))//10**(dig))*(10**(dig))
500 ystep = ystep/5
501 ystep = ystep/5
501
502
502 if self.xaxis is not 'time':
503 if self.xaxis is not 'time':
503
504
504 dig = int(numpy.log10(xmax))
505 dig = int(numpy.log10(xmax))
505
506
506 if dig <= 0:
507 if dig <= 0:
507 digD = len(str(xmax)) - 2
508 digD = len(str(xmax)) - 2
508 xdec = xmax*(10**digD)
509 xdec = xmax*(10**digD)
509
510
510 dig = int(numpy.log10(xdec))
511 dig = int(numpy.log10(xdec))
511 xstep = ((xdec + (10**(dig)))//10**(dig))*(10**(dig))
512 xstep = ((xdec + (10**(dig)))//10**(dig))*(10**(dig))
512 xstep = xstep*0.5
513 xstep = xstep*0.5
513 xstep = xstep/(10**digD)
514 xstep = xstep/(10**digD)
514
515
515 else:
516 else:
516 xstep = ((xmax + (10**(dig)))//10**(dig))*(10**(dig))
517 xstep = ((xmax + (10**(dig)))//10**(dig))*(10**(dig))
517 xstep = xstep/5
518 xstep = xstep/5
518
519
519 for n, ax in enumerate(self.axes):
520 for n, ax in enumerate(self.axes):
520 if ax.firsttime:
521 if ax.firsttime:
521 ax.set_facecolor(self.bgcolor)
522 ax.set_facecolor(self.bgcolor)
522 ax.yaxis.set_major_locator(MultipleLocator(ystep))
523 ax.yaxis.set_major_locator(MultipleLocator(ystep))
523 if self.xscale:
524 if self.xscale:
524 ax.xaxis.set_major_formatter(FuncFormatter(
525 ax.xaxis.set_major_formatter(FuncFormatter(
525 lambda x, pos: '{0:g}'.format(x*self.xscale)))
526 lambda x, pos: '{0:g}'.format(x*self.xscale)))
526 if self.xscale:
527 if self.xscale:
527 ax.yaxis.set_major_formatter(FuncFormatter(
528 ax.yaxis.set_major_formatter(FuncFormatter(
528 lambda x, pos: '{0:g}'.format(x*self.yscale)))
529 lambda x, pos: '{0:g}'.format(x*self.yscale)))
529 if self.xaxis is 'time':
530 if self.xaxis is 'time':
530 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
531 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
531 ax.xaxis.set_major_locator(LinearLocator(9))
532 ax.xaxis.set_major_locator(LinearLocator(9))
532 else:
533 else:
533 ax.xaxis.set_major_locator(MultipleLocator(xstep))
534 ax.xaxis.set_major_locator(MultipleLocator(xstep))
534 if self.xlabel is not None:
535 if self.xlabel is not None:
535 ax.set_xlabel(self.xlabel)
536 ax.set_xlabel(self.xlabel)
536 ax.set_ylabel(self.ylabel)
537 ax.set_ylabel(self.ylabel)
537 ax.firsttime = False
538 ax.firsttime = False
538 if self.showprofile:
539 if self.showprofile:
539 self.pf_axes[n].set_ylim(ymin, ymax)
540 self.pf_axes[n].set_ylim(ymin, ymax)
540 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
541 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
541 self.pf_axes[n].set_xlabel('dB')
542 self.pf_axes[n].set_xlabel('dB')
542 self.pf_axes[n].grid(b=True, axis='x')
543 self.pf_axes[n].grid(b=True, axis='x')
543 [tick.set_visible(False)
544 [tick.set_visible(False)
544 for tick in self.pf_axes[n].get_yticklabels()]
545 for tick in self.pf_axes[n].get_yticklabels()]
545 if self.colorbar:
546 if self.colorbar:
546 ax.cbar = plt.colorbar(
547 ax.cbar = plt.colorbar(
547 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
548 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
548 ax.cbar.ax.tick_params(labelsize=8)
549 ax.cbar.ax.tick_params(labelsize=8)
549 ax.cbar.ax.press = None
550 ax.cbar.ax.press = None
550 if self.cb_label:
551 if self.cb_label:
551 ax.cbar.set_label(self.cb_label, size=8)
552 ax.cbar.set_label(self.cb_label, size=8)
552 elif self.cb_labels:
553 elif self.cb_labels:
553 ax.cbar.set_label(self.cb_labels[n], size=8)
554 ax.cbar.set_label(self.cb_labels[n], size=8)
554 else:
555 else:
555 ax.cbar = None
556 ax.cbar = None
556 if self.grid:
557 if self.grid:
557 ax.grid(True)
558 ax.grid(True)
558
559
559 if not self.polar:
560 if not self.polar:
560 ax.set_xlim(xmin, xmax)
561 ax.set_xlim(xmin, xmax)
561 ax.set_ylim(ymin, ymax)
562 ax.set_ylim(ymin, ymax)
562 ax.set_title('{} {} {}'.format(
563 ax.set_title('{} {} {}'.format(
563 self.titles[n],
564 self.titles[n],
564 self.getDateTime(self.data.max_time).strftime(
565 self.getDateTime(self.data.max_time).strftime(
565 '%H:%M:%S'),
566 '%H:%M:%S'),
566 self.time_label),
567 self.time_label),
567 size=8)
568 size=8)
568 else:
569 else:
569 ax.set_title('{}'.format(self.titles[n]), size=8)
570 ax.set_title('{}'.format(self.titles[n]), size=8)
570 ax.set_ylim(0, 90)
571 ax.set_ylim(0, 90)
571 ax.set_yticks(numpy.arange(0, 90, 20))
572 ax.set_yticks(numpy.arange(0, 90, 20))
572 ax.yaxis.labelpad = 40
573 ax.yaxis.labelpad = 40
573
574
574 def clear_figures(self):
575 def clear_figures(self):
575 '''
576 '''
576 Reset axes for redraw plots
577 Reset axes for redraw plots
577 '''
578 '''
578
579
579 for ax in self.axes:
580 for ax in self.axes:
580 ax.clear()
581 ax.clear()
581 ax.firsttime = True
582 ax.firsttime = True
582 if ax.cbar:
583 if ax.cbar:
583 ax.cbar.remove()
584 ax.cbar.remove()
584
585
585 def __plot(self):
586 def __plot(self):
586 '''
587 '''
587 Main function to plot, format and save figures
588 Main function to plot, format and save figures
588 '''
589 '''
589
590
590 try:
591 try:
591 self.plot()
592 self.plot()
592 self.format()
593 self.format()
593 except Exception as e:
594 except Exception as e:
594 log.warning('{} Plot could not be updated... check data'.format(
595 log.warning('{} Plot could not be updated... check data'.format(
595 self.CODE), self.name)
596 self.CODE), self.name)
596 log.error(str(e), '')
597 log.error(str(e), '')
597 return
598 return
598
599
599 for n, fig in enumerate(self.figures):
600 for n, fig in enumerate(self.figures):
600 if self.nrows == 0 or self.nplots == 0:
601 if self.nrows == 0 or self.nplots == 0:
601 log.warning('No data', self.name)
602 log.warning('No data', self.name)
602 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
603 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
603 fig.canvas.manager.set_window_title(self.CODE)
604 fig.canvas.manager.set_window_title(self.CODE)
604 continue
605 continue
605
606
606 fig.tight_layout()
607 fig.tight_layout()
607 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
608 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
608 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
609 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
609 fig.canvas.draw()
610 fig.canvas.draw()
610
611
611 if self.save:
612 if self.save:
612 self.save_figure(n)
613 self.save_figure(n)
613
614
614 if self.plot_server:
615 if self.plot_server:
615 self.send_to_server()
616 self.send_to_server()
616 # t = Thread(target=self.send_to_server)
617 # t = Thread(target=self.send_to_server)
617 # t.start()
618 # t.start()
618
619
619 def save_figure(self, n):
620 def save_figure(self, n):
620 '''
621 '''
621 '''
622 '''
622
623
623 if self.save_counter < self.save_period:
624 if self.save_counter < self.save_period:
624 self.save_counter += 1
625 self.save_counter += 1
625 return
626 return
626
627
627 self.save_counter = 1
628 self.save_counter = 1
628
629
629 fig = self.figures[n]
630 fig = self.figures[n]
630
631
631 if self.save_labels:
632 if self.save_labels:
632 labels = self.save_labels
633 labels = self.save_labels
633 else:
634 else:
634 labels = list(range(self.nrows))
635 labels = list(range(self.nrows))
635
636
636 if self.oneFigure:
637 if self.oneFigure:
637 label = ''
638 label = ''
638 else:
639 else:
639 label = '-{}'.format(labels[n])
640 label = '-{}'.format(labels[n])
640 figname = os.path.join(
641 figname = os.path.join(
641 self.save,
642 self.save,
642 self.CODE,
643 self.CODE,
643 '{}{}_{}.png'.format(
644 '{}{}_{}.png'.format(
644 self.CODE,
645 self.CODE,
645 label,
646 label,
646 self.getDateTime(self.data.max_time).strftime(
647 self.getDateTime(self.data.max_time).strftime(
647 '%Y%m%d_%H%M%S'
648 '%Y%m%d_%H%M%S'
648 ),
649 ),
649 )
650 )
650 )
651 )
651 log.log('Saving figure: {}'.format(figname), self.name)
652 log.log('Saving figure: {}'.format(figname), self.name)
652 if not os.path.isdir(os.path.dirname(figname)):
653 if not os.path.isdir(os.path.dirname(figname)):
653 os.makedirs(os.path.dirname(figname))
654 os.makedirs(os.path.dirname(figname))
654 fig.savefig(figname)
655 fig.savefig(figname)
655
656
656 if self.realtime:
657 if self.realtime:
657 figname = os.path.join(
658 figname = os.path.join(
658 self.save,
659 self.save,
659 '{}{}_{}.png'.format(
660 '{}{}_{}.png'.format(
660 self.CODE,
661 self.CODE,
661 label,
662 label,
662 self.getDateTime(self.data.min_time).strftime(
663 self.getDateTime(self.data.min_time).strftime(
663 '%Y%m%d'
664 '%Y%m%d'
664 ),
665 ),
665 )
666 )
666 )
667 )
667 fig.savefig(figname)
668 fig.savefig(figname)
668
669
669 def send_to_server(self):
670 def send_to_server(self):
670 '''
671 '''
671 '''
672 '''
672
673
673 if self.sender_counter < self.sender_period:
674 if self.sender_counter < self.sender_period:
674 self.sender_counter += 1
675 self.sender_counter += 1
675
676
676 self.sender_counter = 1
677 self.sender_counter = 1
677
678
678 retries = 2
679 retries = 2
679 while True:
680 while True:
680 self.socket.send_string(self.data.jsonify())
681 self.socket.send_string(self.data.jsonify())
681 socks = dict(self.poll.poll(5000))
682 socks = dict(self.poll.poll(5000))
682 if socks.get(self.socket) == zmq.POLLIN:
683 if socks.get(self.socket) == zmq.POLLIN:
683 reply = self.socket.recv_string()
684 reply = self.socket.recv_string()
684 if reply == 'ok':
685 if reply == 'ok':
685 log.log("Response from server ok", self.name)
686 log.log("Response from server ok", self.name)
686 break
687 break
687 else:
688 else:
688 log.warning(
689 log.warning(
689 "Malformed reply from server: {}".format(reply), self.name)
690 "Malformed reply from server: {}".format(reply), self.name)
690
691
691 else:
692 else:
692 log.warning(
693 log.warning(
693 "No response from server, retrying...", self.name)
694 "No response from server, retrying...", self.name)
694 self.socket.setsockopt(zmq.LINGER, 0)
695 self.socket.setsockopt(zmq.LINGER, 0)
695 self.socket.close()
696 self.socket.close()
696 self.poll.unregister(self.socket)
697 self.poll.unregister(self.socket)
697 retries -= 1
698 retries -= 1
698 if retries == 0:
699 if retries == 0:
699 log.error(
700 log.error(
700 "Server seems to be offline, abandoning", self.name)
701 "Server seems to be offline, abandoning", self.name)
701 self.socket = self.context.socket(zmq.REQ)
702 self.socket = self.context.socket(zmq.REQ)
702 self.socket.connect(self.plot_server)
703 self.socket.connect(self.plot_server)
703 self.poll.register(self.socket, zmq.POLLIN)
704 self.poll.register(self.socket, zmq.POLLIN)
704 time.sleep(1)
705 time.sleep(1)
705 break
706 break
706 self.socket = self.context.socket(zmq.REQ)
707 self.socket = self.context.socket(zmq.REQ)
707 self.socket.connect(self.plot_server)
708 self.socket.connect(self.plot_server)
708 self.poll.register(self.socket, zmq.POLLIN)
709 self.poll.register(self.socket, zmq.POLLIN)
709 time.sleep(0.5)
710 time.sleep(0.5)
710
711
711 def setup(self):
712 def setup(self):
712 '''
713 '''
713 This method should be implemented in the child class, the following
714 This method should be implemented in the child class, the following
714 attributes should be set:
715 attributes should be set:
715
716
716 self.nrows: number of rows
717 self.nrows: number of rows
717 self.ncols: number of cols
718 self.ncols: number of cols
718 self.nplots: number of plots (channels or pairs)
719 self.nplots: number of plots (channels or pairs)
719 self.ylabel: label for Y axes
720 self.ylabel: label for Y axes
720 self.titles: list of axes title
721 self.titles: list of axes title
721
722
722 '''
723 '''
723 raise NotImplementedError
724 raise NotImplementedError
724
725
725 def plot(self):
726 def plot(self):
726 '''
727 '''
727 Must be defined in the child class
728 Must be defined in the child class
728 '''
729 '''
729 raise NotImplementedError
730 raise NotImplementedError
730
731
731 def run(self, dataOut, **kwargs):
732 def run(self, dataOut, **kwargs):
732
733
733 if dataOut.error:
734 if dataOut.error:
734 coerce = True
735 coerce = True
735 else:
736 else:
736 coerce = False
737 coerce = False
737
738
738 if self.isConfig is False:
739 if self.isConfig is False:
739 self.__setup(**kwargs)
740 self.__setup(**kwargs)
740 self.data.setup()
741 self.data.setup()
741 self.isConfig = True
742 self.isConfig = True
742 if self.plot_server:
743 if self.plot_server:
743 self.context = zmq.Context()
744 self.context = zmq.Context()
744 self.socket = self.context.socket(zmq.REQ)
745 self.socket = self.context.socket(zmq.REQ)
745 self.socket.connect(self.plot_server)
746 self.socket.connect(self.plot_server)
746 self.poll = zmq.Poller()
747 self.poll = zmq.Poller()
747 self.poll.register(self.socket, zmq.POLLIN)
748 self.poll.register(self.socket, zmq.POLLIN)
748
749
749 if dataOut.type == 'Parameters':
750 if dataOut.type == 'Parameters':
750 tm = dataOut.utctimeInit
751 tm = dataOut.utctimeInit
751 else:
752 else:
752 tm = dataOut.utctime
753 tm = dataOut.utctime
753
754
754 if dataOut.useLocalTime:
755 if dataOut.useLocalTime:
755 if not self.localtime:
756 if not self.localtime:
756 tm += time.timezone
757 tm += time.timezone
757 else:
758 else:
758 if self.localtime:
759 if self.localtime:
759 tm -= time.timezone
760 tm -= time.timezone
760
761
761 if self.data and (tm - self.data.min_time) >= self.xrange*60*60:
762 if self.xaxis is 'time' and self.data and (tm - self.tmin) >= self.xrange*60*60:
762 self.__plot()
763 self.__plot()
763 self.data.setup()
764 self.data.setup()
764 self.clear_figures()
765 self.clear_figures()
765
766
766 self.data.update(dataOut, tm)
767 self.data.update(dataOut, tm)
767
768
768 if self.isPlotConfig is False:
769 if self.isPlotConfig is False:
769 self.__setup_plot()
770 self.__setup_plot()
770 self.isPlotConfig = True
771 self.isPlotConfig = True
771
772
772 if self.realtime:
773 if self.realtime:
773 self.__plot()
774 self.__plot()
774 else:
775 else:
775 self.__throttle_plot(self.__plot, coerce=coerce)
776 self.__throttle_plot(self.__plot, coerce=coerce)
776
777
777 figpause(0.001)
778 figpause(0.001)
778
779
779 def close(self):
780 def close(self):
780
781
781 if self.data and self.pause:
782 if self.data and self.pause:
782 figpause(10)
783 figpause(10)
783
784
General Comments 0
You need to be logged in to leave comments. Login now