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