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