##// END OF EJS Templates
Bugs in PlotData
Juan C. Espinoza -
r1099:78313f9994b6
parent child
Show More
@@ -1,955 +1,952
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', 'RdBu_r', 'seismic')]
25 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'RdBu_r', 'seismic')]
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 __MAXNUMX = 80
49 __MAXNUMX = 80
50 __missing = 1E30
50 __missing = 1E30
51
51
52 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
52 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
53 'zlimits', 'xlabel', 'ylabel', 'cb_label', 'title', 'titles', 'colorbar',
53 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title',
54 'bgcolor', 'width', 'height', 'localtime', 'oneFigure', 'showprofile']
54 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
55 'showprofile', 'decimation']
55
56
56 def __init__(self, **kwargs):
57 def __init__(self, **kwargs):
57
58
58 Operation.__init__(self, plot=True, **kwargs)
59 Operation.__init__(self, plot=True, **kwargs)
59 Process.__init__(self)
60 Process.__init__(self)
60 self.contador = 0
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.__MAXNUMY = kwargs.get('decimation', 300)
90 self.__MAXNUMY = kwargs.get('decimation', 200)
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 = ['' for __ in range(16)]
97 self.titles = ['' for __ in range(16)]
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.__MAXNUMY) + 1
330 dy = int(len(self.y) / self.__MAXNUMY) + 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)).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([10, 20, 50, 100, 200, 500, 1000, 2000])
371 Y = numpy.array([10, 20, 50, 100, 200, 500, 1000, 2000])
372 i = 1 if numpy.where(ymax < Y)[
372 i = 1 if numpy.where(ymax-ymin < Y)[0][0] < 0 else numpy.where(ymax-ymin < Y)[0][0]
373 0][0] < 0 else numpy.where(ymax < Y)[0][0]
373 ystep = Y[i] / 5
374 ystep = Y[i - 1] / 5
375
374
376 for n, ax in enumerate(self.axes):
375 for n, ax in enumerate(self.axes):
377 if ax.firsttime:
376 if ax.firsttime:
378 ax.set_facecolor(self.bgcolor)
377 ax.set_facecolor(self.bgcolor)
379 ax.yaxis.set_major_locator(MultipleLocator(ystep))
378 ax.yaxis.set_major_locator(MultipleLocator(ystep))
380 if self.xaxis is 'time':
379 if self.xaxis is 'time':
381 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
380 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
382 ax.xaxis.set_major_locator(LinearLocator(9))
381 ax.xaxis.set_major_locator(LinearLocator(9))
383 if self.xlabel is not None:
382 if self.xlabel is not None:
384 ax.set_xlabel(self.xlabel)
383 ax.set_xlabel(self.xlabel)
385 ax.set_ylabel(self.ylabel)
384 ax.set_ylabel(self.ylabel)
386 ax.firsttime = False
385 ax.firsttime = False
387 if self.showprofile:
386 if self.showprofile:
388 self.pf_axes[n].set_ylim(ymin, ymax)
387 self.pf_axes[n].set_ylim(ymin, ymax)
389 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
388 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
390 self.pf_axes[n].set_xlabel('dB')
389 self.pf_axes[n].set_xlabel('dB')
391 self.pf_axes[n].grid(b=True, axis='x')
390 self.pf_axes[n].grid(b=True, axis='x')
392 [tick.set_visible(False)
391 [tick.set_visible(False)
393 for tick in self.pf_axes[n].get_yticklabels()]
392 for tick in self.pf_axes[n].get_yticklabels()]
394 if self.colorbar:
393 if self.colorbar:
395 ax.cbar = plt.colorbar(
394 ax.cbar = plt.colorbar(
396 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)
397 ax.cbar.ax.tick_params(labelsize=8)
396 ax.cbar.ax.tick_params(labelsize=8)
398 ax.cbar.ax.press = None
397 ax.cbar.ax.press = None
399 if self.cb_label:
398 if self.cb_label:
400 ax.cbar.set_label(self.cb_label, size=8)
399 ax.cbar.set_label(self.cb_label, size=8)
401 elif self.cb_labels:
400 elif self.cb_labels:
402 ax.cbar.set_label(self.cb_labels[n], size=8)
401 ax.cbar.set_label(self.cb_labels[n], size=8)
403 else:
402 else:
404 ax.cbar = None
403 ax.cbar = None
405
404
406 if not self.polar:
405 if not self.polar:
407 ax.set_xlim(xmin, xmax)
406 ax.set_xlim(xmin, xmax)
408 ax.set_ylim(ymin, ymax)
407 ax.set_ylim(ymin, ymax)
409 ax.set_title('{} - {} {}'.format(
408 ax.set_title('{} - {} {}'.format(
410 self.titles[n],
409 self.titles[n],
411 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
410 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
412 self.time_label),
411 self.time_label),
413 size=8)
412 size=8)
414 else:
413 else:
415 ax.set_title('{}'.format(self.titles[n]), size=8)
414 ax.set_title('{}'.format(self.titles[n]), size=8)
416 ax.set_ylim(0, 90)
415 ax.set_ylim(0, 90)
417 ax.set_yticks(numpy.arange(0, 90, 20))
416 ax.set_yticks(numpy.arange(0, 90, 20))
418 ax.yaxis.labelpad = 40
417 ax.yaxis.labelpad = 40
419
418
420 def __plot(self):
419 def __plot(self):
421 '''
420 '''
422 '''
421 '''
423 log.success('Plotting', self.name)
422 log.success('Plotting', self.name)
424
423
425 self.plot()
424 self.plot()
426 self.format()
425 self.format()
427
426
428 for n, fig in enumerate(self.figures):
427 for n, fig in enumerate(self.figures):
429 if self.nrows == 0 or self.nplots == 0:
428 if self.nrows == 0 or self.nplots == 0:
430 log.warning('No data', self.name)
429 log.warning('No data', self.name)
431 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
430 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
431 fig.canvas.manager.set_window_title(self.CODE)
432 continue
432 continue
433
433
434 fig.tight_layout()
434 fig.tight_layout()
435 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
435 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
436 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
436 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
437 # fig.canvas.draw()
437 # fig.canvas.draw()
438
438
439 if self.save: # and self.data.ended:
439 if self.save and self.data.ended:
440 self.contador += 1
441 channels = range(self.nrows)
440 channels = range(self.nrows)
442 if self.oneFigure:
441 if self.oneFigure:
443 label = ''
442 label = ''
444 else:
443 else:
445 label = '_{}'.format(channels[n])
444 label = '_{}'.format(channels[n])
446 figname = os.path.join(
445 figname = os.path.join(
447 self.save,
446 self.save,
448 '{}{}_{}{}.png'.format(
447 '{}{}_{}.png'.format(
449 self.CODE,
448 self.CODE,
450 label,
449 label,
451 self.getDateTime(self.saveTime).strftime(
450 self.getDateTime(self.saveTime).strftime('%y%m%d_%H%M%S')
452 '%y%m%d_%H%M%S'),
453 str(self.contador),
454 )
451 )
455 )
452 )
456 log.log('Saving figure: {}'.format(figname), self.name)
453 log.log('Saving figure: {}'.format(figname), self.name)
457 fig.savefig(figname)
454 fig.savefig(figname)
458
455
459 def plot(self):
456 def plot(self):
460 '''
457 '''
461 '''
458 '''
462 raise(NotImplementedError, 'Implement this method in child class')
459 raise(NotImplementedError, 'Implement this method in child class')
463
460
464 def run(self):
461 def run(self):
465
462
466 log.success('Starting', self.name)
463 log.success('Starting', self.name)
467
464
468 context = zmq.Context()
465 context = zmq.Context()
469 receiver = context.socket(zmq.SUB)
466 receiver = context.socket(zmq.SUB)
470 receiver.setsockopt(zmq.SUBSCRIBE, '')
467 receiver.setsockopt(zmq.SUBSCRIBE, '')
471 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
468 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
472
469
473 if 'server' in self.kwargs['parent']:
470 if 'server' in self.kwargs['parent']:
474 receiver.connect(
471 receiver.connect(
475 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
472 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
476 else:
473 else:
477 receiver.connect("ipc:///tmp/zmq.plots")
474 receiver.connect("ipc:///tmp/zmq.plots")
478
475
479 while True:
476 while True:
480 try:
477 try:
481 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
478 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
482 if self.data.localtime and self.localtime:
479 if self.data.localtime and self.localtime:
483 self.times = self.data.times
480 self.times = self.data.times
484 elif self.data.localtime and not self.localtime:
481 elif self.data.localtime and not self.localtime:
485 self.times = self.data.times + time.timezone
482 self.times = self.data.times + time.timezone
486 elif not self.data.localtime and self.localtime:
483 elif not self.data.localtime and self.localtime:
487 self.times = self.data.times - time.timezone
484 self.times = self.data.times - time.timezone
488 else:
485 else:
489 self.times = self.data.times
486 self.times = self.data.times
490
487
491 self.min_time = self.times[0]
488 self.min_time = self.times[0]
492 self.max_time = self.times[-1]
489 self.max_time = self.times[-1]
493
490
494 if self.isConfig is False:
491 if self.isConfig is False:
495 self.__setup()
492 self.__setup()
496 self.isConfig = True
493 self.isConfig = True
497
494
498 self.__plot()
495 self.__plot()
499
496
500 except zmq.Again as e:
497 except zmq.Again as e:
501 log.log('Waiting for data...')
498 log.log('Waiting for data...')
502 if self.data:
499 if self.data:
503 figpause(self.data.throttle)
500 figpause(self.data.throttle)
504 else:
501 else:
505 time.sleep(2)
502 time.sleep(2)
506
503
507 def close(self):
504 def close(self):
508 if self.data:
505 if self.data:
509 self.__plot()
506 self.__plot()
510
507
511
508
512 class PlotSpectraData(PlotData):
509 class PlotSpectraData(PlotData):
513 '''
510 '''
514 Plot for Spectra data
511 Plot for Spectra data
515 '''
512 '''
516
513
517 CODE = 'spc'
514 CODE = 'spc'
518 colormap = 'jro'
515 colormap = 'jro'
519
516
520 def setup(self):
517 def setup(self):
521 self.nplots = len(self.data.channels)
518 self.nplots = len(self.data.channels)
522 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
519 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
523 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
520 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
524 self.width = 3.4 * self.ncols
521 self.width = 3.4 * self.ncols
525 self.height = 3 * self.nrows
522 self.height = 3 * self.nrows
526 self.cb_label = 'dB'
523 self.cb_label = 'dB'
527 if self.showprofile:
524 if self.showprofile:
528 self.width += 0.8 * self.ncols
525 self.width += 0.8 * self.ncols
529
526
530 self.ylabel = 'Range [Km]'
527 self.ylabel = 'Range [Km]'
531
528
532 def plot(self):
529 def plot(self):
533 if self.xaxis == "frequency":
530 if self.xaxis == "frequency":
534 x = self.data.xrange[0]
531 x = self.data.xrange[0]
535 self.xlabel = "Frequency (kHz)"
532 self.xlabel = "Frequency (kHz)"
536 elif self.xaxis == "time":
533 elif self.xaxis == "time":
537 x = self.data.xrange[1]
534 x = self.data.xrange[1]
538 self.xlabel = "Time (ms)"
535 self.xlabel = "Time (ms)"
539 else:
536 else:
540 x = self.data.xrange[2]
537 x = self.data.xrange[2]
541 self.xlabel = "Velocity (m/s)"
538 self.xlabel = "Velocity (m/s)"
542
539
543 if self.CODE == 'spc_mean':
540 if self.CODE == 'spc_mean':
544 x = self.data.xrange[2]
541 x = self.data.xrange[2]
545 self.xlabel = "Velocity (m/s)"
542 self.xlabel = "Velocity (m/s)"
546
543
547 self.titles = []
544 self.titles = []
548
545
549 y = self.data.heights
546 y = self.data.heights
550 self.y = y
547 self.y = y
551 z = self.data['spc']
548 z = self.data['spc']
552
549
553 for n, ax in enumerate(self.axes):
550 for n, ax in enumerate(self.axes):
554 noise = self.data['noise'][n][-1]
551 noise = self.data['noise'][n][-1]
555 if self.CODE == 'spc_mean':
552 if self.CODE == 'spc_mean':
556 mean = self.data['mean'][n][-1]
553 mean = self.data['mean'][n][-1]
557 if ax.firsttime:
554 if ax.firsttime:
558 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
555 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
559 self.xmin = self.xmin if self.xmin else -self.xmax
556 self.xmin = self.xmin if self.xmin else -self.xmax
560 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
557 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
561 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
558 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
562 ax.plt = ax.pcolormesh(x, y, z[n].T,
559 ax.plt = ax.pcolormesh(x, y, z[n].T,
563 vmin=self.zmin,
560 vmin=self.zmin,
564 vmax=self.zmax,
561 vmax=self.zmax,
565 cmap=plt.get_cmap(self.colormap)
562 cmap=plt.get_cmap(self.colormap)
566 )
563 )
567
564
568 if self.showprofile:
565 if self.showprofile:
569 ax.plt_profile = self.pf_axes[n].plot(
566 ax.plt_profile = self.pf_axes[n].plot(
570 self.data['rti'][n][-1], y)[0]
567 self.data['rti'][n][-1], y)[0]
571 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
568 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
572 color="k", linestyle="dashed", lw=1)[0]
569 color="k", linestyle="dashed", lw=1)[0]
573 if self.CODE == 'spc_mean':
570 if self.CODE == 'spc_mean':
574 ax.plt_mean = ax.plot(mean, y, color='k')[0]
571 ax.plt_mean = ax.plot(mean, y, color='k')[0]
575 else:
572 else:
576 ax.plt.set_array(z[n].T.ravel())
573 ax.plt.set_array(z[n].T.ravel())
577 if self.showprofile:
574 if self.showprofile:
578 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
575 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
579 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
576 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
580 if self.CODE == 'spc_mean':
577 if self.CODE == 'spc_mean':
581 ax.plt_mean.set_data(mean, y)
578 ax.plt_mean.set_data(mean, y)
582
579
583 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
580 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
584 self.saveTime = self.max_time
581 self.saveTime = self.max_time
585
582
586
583
587 class PlotCrossSpectraData(PlotData):
584 class PlotCrossSpectraData(PlotData):
588
585
589 CODE = 'cspc'
586 CODE = 'cspc'
590 zmin_coh = None
587 zmin_coh = None
591 zmax_coh = None
588 zmax_coh = None
592 zmin_phase = None
589 zmin_phase = None
593 zmax_phase = None
590 zmax_phase = None
594
591
595 def setup(self):
592 def setup(self):
596
593
597 self.ncols = 4
594 self.ncols = 4
598 self.nrows = len(self.data.pairs)
595 self.nrows = len(self.data.pairs)
599 self.nplots = self.nrows * 4
596 self.nplots = self.nrows * 4
600 self.width = 3.4 * self.ncols
597 self.width = 3.4 * self.ncols
601 self.height = 3 * self.nrows
598 self.height = 3 * self.nrows
602 self.ylabel = 'Range [Km]'
599 self.ylabel = 'Range [Km]'
603 self.showprofile = False
600 self.showprofile = False
604
601
605 def plot(self):
602 def plot(self):
606
603
607 if self.xaxis == "frequency":
604 if self.xaxis == "frequency":
608 x = self.data.xrange[0]
605 x = self.data.xrange[0]
609 self.xlabel = "Frequency (kHz)"
606 self.xlabel = "Frequency (kHz)"
610 elif self.xaxis == "time":
607 elif self.xaxis == "time":
611 x = self.data.xrange[1]
608 x = self.data.xrange[1]
612 self.xlabel = "Time (ms)"
609 self.xlabel = "Time (ms)"
613 else:
610 else:
614 x = self.data.xrange[2]
611 x = self.data.xrange[2]
615 self.xlabel = "Velocity (m/s)"
612 self.xlabel = "Velocity (m/s)"
616
613
617 self.titles = []
614 self.titles = []
618
615
619 y = self.data.heights
616 y = self.data.heights
620 self.y = y
617 self.y = y
621 spc = self.data['spc']
618 spc = self.data['spc']
622 cspc = self.data['cspc']
619 cspc = self.data['cspc']
623
620
624 for n in range(self.nrows):
621 for n in range(self.nrows):
625 noise = self.data['noise'][n][-1]
622 noise = self.data['noise'][n][-1]
626 pair = self.data.pairs[n]
623 pair = self.data.pairs[n]
627 ax = self.axes[4 * n]
624 ax = self.axes[4 * n]
628 ax3 = self.axes[4 * n + 3]
625 ax3 = self.axes[4 * n + 3]
629 if ax.firsttime:
626 if ax.firsttime:
630 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
631 self.xmin = self.xmin if self.xmin else -self.xmax
628 self.xmin = self.xmin if self.xmin else -self.xmax
632 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
629 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
633 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
634 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
631 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
635 vmin=self.zmin,
632 vmin=self.zmin,
636 vmax=self.zmax,
633 vmax=self.zmax,
637 cmap=plt.get_cmap(self.colormap)
634 cmap=plt.get_cmap(self.colormap)
638 )
635 )
639 else:
636 else:
640 ax.plt.set_array(spc[pair[0]].T.ravel())
637 ax.plt.set_array(spc[pair[0]].T.ravel())
641 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
638 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
642
639
643 ax = self.axes[4 * n + 1]
640 ax = self.axes[4 * n + 1]
644 if ax.firsttime:
641 if ax.firsttime:
645 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
642 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
646 vmin=self.zmin,
643 vmin=self.zmin,
647 vmax=self.zmax,
644 vmax=self.zmax,
648 cmap=plt.get_cmap(self.colormap)
645 cmap=plt.get_cmap(self.colormap)
649 )
646 )
650 else:
647 else:
651 ax.plt.set_array(spc[pair[1]].T.ravel())
648 ax.plt.set_array(spc[pair[1]].T.ravel())
652 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
649 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
653
650
654 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
651 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
655 coh = numpy.abs(out)
652 coh = numpy.abs(out)
656 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
653 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
657
654
658 ax = self.axes[4 * n + 2]
655 ax = self.axes[4 * n + 2]
659 if ax.firsttime:
656 if ax.firsttime:
660 ax.plt = ax.pcolormesh(x, y, coh.T,
657 ax.plt = ax.pcolormesh(x, y, coh.T,
661 vmin=0,
658 vmin=0,
662 vmax=1,
659 vmax=1,
663 cmap=plt.get_cmap(self.colormap_coh)
660 cmap=plt.get_cmap(self.colormap_coh)
664 )
661 )
665 else:
662 else:
666 ax.plt.set_array(coh.T.ravel())
663 ax.plt.set_array(coh.T.ravel())
667 self.titles.append(
664 self.titles.append(
668 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
665 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
669
666
670 ax = self.axes[4 * n + 3]
667 ax = self.axes[4 * n + 3]
671 if ax.firsttime:
668 if ax.firsttime:
672 ax.plt = ax.pcolormesh(x, y, phase.T,
669 ax.plt = ax.pcolormesh(x, y, phase.T,
673 vmin=-180,
670 vmin=-180,
674 vmax=180,
671 vmax=180,
675 cmap=plt.get_cmap(self.colormap_phase)
672 cmap=plt.get_cmap(self.colormap_phase)
676 )
673 )
677 else:
674 else:
678 ax.plt.set_array(phase.T.ravel())
675 ax.plt.set_array(phase.T.ravel())
679 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
676 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
680
677
681 self.saveTime = self.max_time
678 self.saveTime = self.max_time
682
679
683
680
684 class PlotSpectraMeanData(PlotSpectraData):
681 class PlotSpectraMeanData(PlotSpectraData):
685 '''
682 '''
686 Plot for Spectra and Mean
683 Plot for Spectra and Mean
687 '''
684 '''
688 CODE = 'spc_mean'
685 CODE = 'spc_mean'
689 colormap = 'jro'
686 colormap = 'jro'
690
687
691
688
692 class PlotRTIData(PlotData):
689 class PlotRTIData(PlotData):
693 '''
690 '''
694 Plot for RTI data
691 Plot for RTI data
695 '''
692 '''
696
693
697 CODE = 'rti'
694 CODE = 'rti'
698 colormap = 'jro'
695 colormap = 'jro'
699
696
700 def setup(self):
697 def setup(self):
701 self.xaxis = 'time'
698 self.xaxis = 'time'
702 self.ncols = 1
699 self.ncols = 1
703 self.nrows = len(self.data.channels)
700 self.nrows = len(self.data.channels)
704 self.nplots = len(self.data.channels)
701 self.nplots = len(self.data.channels)
705 self.ylabel = 'Range [Km]'
702 self.ylabel = 'Range [Km]'
706 self.cb_label = 'dB'
703 self.cb_label = 'dB'
707 self.titles = ['{} Channel {}'.format(
704 self.titles = ['{} Channel {}'.format(
708 self.CODE.upper(), x) for x in range(self.nrows)]
705 self.CODE.upper(), x) for x in range(self.nrows)]
709
706
710 def plot(self):
707 def plot(self):
711 self.x = self.times
708 self.x = self.times
712 self.y = self.data.heights
709 self.y = self.data.heights
713 self.z = self.data[self.CODE]
710 self.z = self.data[self.CODE]
714 self.z = numpy.ma.masked_invalid(self.z)
711 self.z = numpy.ma.masked_invalid(self.z)
715
712
716 for n, ax in enumerate(self.axes):
713 for n, ax in enumerate(self.axes):
717 x, y, z = self.fill_gaps(*self.decimate())
714 x, y, z = self.fill_gaps(*self.decimate())
718 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
715 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
719 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
716 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
720 if ax.firsttime:
717 if ax.firsttime:
721 ax.plt = ax.pcolormesh(x, y, z[n].T,
718 ax.plt = ax.pcolormesh(x, y, z[n].T,
722 vmin=self.zmin,
719 vmin=self.zmin,
723 vmax=self.zmax,
720 vmax=self.zmax,
724 cmap=plt.get_cmap(self.colormap)
721 cmap=plt.get_cmap(self.colormap)
725 )
722 )
726 if self.showprofile:
723 if self.showprofile:
727 ax.plot_profile = self.pf_axes[n].plot(
724 ax.plot_profile = self.pf_axes[n].plot(
728 self.data['rti'][n][-1], self.y)[0]
725 self.data['rti'][n][-1], self.y)[0]
729 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
726 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
730 color="k", linestyle="dashed", lw=1)[0]
727 color="k", linestyle="dashed", lw=1)[0]
731 else:
728 else:
732 ax.collections.remove(ax.collections[0])
729 ax.collections.remove(ax.collections[0])
733 ax.plt = ax.pcolormesh(x, y, z[n].T,
730 ax.plt = ax.pcolormesh(x, y, z[n].T,
734 vmin=self.zmin,
731 vmin=self.zmin,
735 vmax=self.zmax,
732 vmax=self.zmax,
736 cmap=plt.get_cmap(self.colormap)
733 cmap=plt.get_cmap(self.colormap)
737 )
734 )
738 if self.showprofile:
735 if self.showprofile:
739 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
736 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
740 ax.plot_noise.set_data(numpy.repeat(
737 ax.plot_noise.set_data(numpy.repeat(
741 self.data['noise'][n][-1], len(self.y)), self.y)
738 self.data['noise'][n][-1], len(self.y)), self.y)
742
739
743 self.saveTime = self.min_time
740 self.saveTime = self.min_time
744
741
745
742
746 class PlotCOHData(PlotRTIData):
743 class PlotCOHData(PlotRTIData):
747 '''
744 '''
748 Plot for Coherence data
745 Plot for Coherence data
749 '''
746 '''
750
747
751 CODE = 'coh'
748 CODE = 'coh'
752
749
753 def setup(self):
750 def setup(self):
754 self.xaxis = 'time'
751 self.xaxis = 'time'
755 self.ncols = 1
752 self.ncols = 1
756 self.nrows = len(self.data.pairs)
753 self.nrows = len(self.data.pairs)
757 self.nplots = len(self.data.pairs)
754 self.nplots = len(self.data.pairs)
758 self.ylabel = 'Range [Km]'
755 self.ylabel = 'Range [Km]'
759 if self.CODE == 'coh':
756 if self.CODE == 'coh':
760 self.cb_label = ''
757 self.cb_label = ''
761 self.titles = [
758 self.titles = [
762 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
759 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
763 else:
760 else:
764 self.cb_label = 'Degrees'
761 self.cb_label = 'Degrees'
765 self.titles = [
762 self.titles = [
766 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
763 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
767
764
768
765
769 class PlotPHASEData(PlotCOHData):
766 class PlotPHASEData(PlotCOHData):
770 '''
767 '''
771 Plot for Phase map data
768 Plot for Phase map data
772 '''
769 '''
773
770
774 CODE = 'phase'
771 CODE = 'phase'
775 colormap = 'seismic'
772 colormap = 'seismic'
776
773
777
774
778 class PlotNoiseData(PlotData):
775 class PlotNoiseData(PlotData):
779 '''
776 '''
780 Plot for noise
777 Plot for noise
781 '''
778 '''
782
779
783 CODE = 'noise'
780 CODE = 'noise'
784
781
785 def setup(self):
782 def setup(self):
786 self.xaxis = 'time'
783 self.xaxis = 'time'
787 self.ncols = 1
784 self.ncols = 1
788 self.nrows = 1
785 self.nrows = 1
789 self.nplots = 1
786 self.nplots = 1
790 self.ylabel = 'Intensity [dB]'
787 self.ylabel = 'Intensity [dB]'
791 self.titles = ['Noise']
788 self.titles = ['Noise']
792 self.colorbar = False
789 self.colorbar = False
793
790
794 def plot(self):
791 def plot(self):
795
792
796 x = self.times
793 x = self.times
797 xmin = self.min_time
794 xmin = self.min_time
798 xmax = xmin + self.xrange * 60 * 60
795 xmax = xmin + self.xrange * 60 * 60
799 Y = self.data[self.CODE]
796 Y = self.data[self.CODE]
800
797
801 if self.axes[0].firsttime:
798 if self.axes[0].firsttime:
802 for ch in self.data.channels:
799 for ch in self.data.channels:
803 y = Y[ch]
800 y = Y[ch]
804 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
801 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
805 plt.legend()
802 plt.legend()
806 else:
803 else:
807 for ch in self.data.channels:
804 for ch in self.data.channels:
808 y = Y[ch]
805 y = Y[ch]
809 self.axes[0].lines[ch].set_data(x, y)
806 self.axes[0].lines[ch].set_data(x, y)
810
807
811 self.ymin = numpy.nanmin(Y) - 5
808 self.ymin = numpy.nanmin(Y) - 5
812 self.ymax = numpy.nanmax(Y) + 5
809 self.ymax = numpy.nanmax(Y) + 5
813 self.saveTime = self.min_time
810 self.saveTime = self.min_time
814
811
815
812
816 class PlotSNRData(PlotRTIData):
813 class PlotSNRData(PlotRTIData):
817 '''
814 '''
818 Plot for SNR Data
815 Plot for SNR Data
819 '''
816 '''
820
817
821 CODE = 'snr'
818 CODE = 'snr'
822 colormap = 'jet'
819 colormap = 'jet'
823
820
824
821
825 class PlotDOPData(PlotRTIData):
822 class PlotDOPData(PlotRTIData):
826 '''
823 '''
827 Plot for DOPPLER Data
824 Plot for DOPPLER Data
828 '''
825 '''
829
826
830 CODE = 'dop'
827 CODE = 'dop'
831 colormap = 'jet'
828 colormap = 'jet'
832
829
833
830
834 class PlotSkyMapData(PlotData):
831 class PlotSkyMapData(PlotData):
835 '''
832 '''
836 Plot for meteors detection data
833 Plot for meteors detection data
837 '''
834 '''
838
835
839 CODE = 'param'
836 CODE = 'param'
840
837
841 def setup(self):
838 def setup(self):
842
839
843 self.ncols = 1
840 self.ncols = 1
844 self.nrows = 1
841 self.nrows = 1
845 self.width = 7.2
842 self.width = 7.2
846 self.height = 7.2
843 self.height = 7.2
847 self.nplots = 1
844 self.nplots = 1
848 self.xlabel = 'Zonal Zenith Angle (deg)'
845 self.xlabel = 'Zonal Zenith Angle (deg)'
849 self.ylabel = 'Meridional Zenith Angle (deg)'
846 self.ylabel = 'Meridional Zenith Angle (deg)'
850 self.polar = True
847 self.polar = True
851 self.ymin = -180
848 self.ymin = -180
852 self.ymax = 180
849 self.ymax = 180
853 self.colorbar = False
850 self.colorbar = False
854
851
855 def plot(self):
852 def plot(self):
856
853
857 arrayParameters = numpy.concatenate(self.data['param'])
854 arrayParameters = numpy.concatenate(self.data['param'])
858 error = arrayParameters[:, -1]
855 error = arrayParameters[:, -1]
859 indValid = numpy.where(error == 0)[0]
856 indValid = numpy.where(error == 0)[0]
860 finalMeteor = arrayParameters[indValid, :]
857 finalMeteor = arrayParameters[indValid, :]
861 finalAzimuth = finalMeteor[:, 3]
858 finalAzimuth = finalMeteor[:, 3]
862 finalZenith = finalMeteor[:, 4]
859 finalZenith = finalMeteor[:, 4]
863
860
864 x = finalAzimuth * numpy.pi / 180
861 x = finalAzimuth * numpy.pi / 180
865 y = finalZenith
862 y = finalZenith
866
863
867 ax = self.axes[0]
864 ax = self.axes[0]
868
865
869 if ax.firsttime:
866 if ax.firsttime:
870 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
867 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
871 else:
868 else:
872 ax.plot.set_data(x, y)
869 ax.plot.set_data(x, y)
873
870
874 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
871 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
875 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
872 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
876 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
873 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
877 dt2,
874 dt2,
878 len(x))
875 len(x))
879 self.titles[0] = title
876 self.titles[0] = title
880 self.saveTime = self.max_time
877 self.saveTime = self.max_time
881
878
882
879
883 class PlotParamData(PlotRTIData):
880 class PlotParamData(PlotRTIData):
884 '''
881 '''
885 Plot for data_param object
882 Plot for data_param object
886 '''
883 '''
887
884
888 CODE = 'param'
885 CODE = 'param'
889 colormap = 'seismic'
886 colormap = 'seismic'
890
887
891 def setup(self):
888 def setup(self):
892 self.xaxis = 'time'
889 self.xaxis = 'time'
893 self.ncols = 1
890 self.ncols = 1
894 self.nrows = self.data.shape(self.CODE)[0]
891 self.nrows = self.data.shape(self.CODE)[0]
895 self.nplots = self.nrows
892 self.nplots = self.nrows
896 if self.showSNR:
893 if self.showSNR:
897 self.nrows += 1
894 self.nrows += 1
898 self.nplots += 1
895 self.nplots += 1
899
896
900 self.ylabel = 'Height [Km]'
897 self.ylabel = 'Height [Km]'
901 self.titles = self.data.parameters \
898 self.titles = self.data.parameters \
902 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
899 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
903 if self.showSNR:
900 if self.showSNR:
904 self.titles.append('SNR')
901 self.titles.append('SNR')
905
902
906 def plot(self):
903 def plot(self):
907 self.data.normalize_heights()
904 self.data.normalize_heights()
908 self.x = self.times
905 self.x = self.times
909 self.y = self.data.heights
906 self.y = self.data.heights
910 if self.showSNR:
907 if self.showSNR:
911 self.z = numpy.concatenate(
908 self.z = numpy.concatenate(
912 (self.data[self.CODE], self.data['snr'])
909 (self.data[self.CODE], self.data['snr'])
913 )
910 )
914 else:
911 else:
915 self.z = self.data[self.CODE]
912 self.z = self.data[self.CODE]
916
913
917 self.z = numpy.ma.masked_invalid(self.z)
914 self.z = numpy.ma.masked_invalid(self.z)
918
915
919 for n, ax in enumerate(self.axes):
916 for n, ax in enumerate(self.axes):
920
917
921 x, y, z = self.fill_gaps(*self.decimate())
918 x, y, z = self.fill_gaps(*self.decimate())
922 self.zmax = self.zmax if self.zmax is not None else numpy.max(
919 self.zmax = self.zmax if self.zmax is not None else numpy.max(
923 self.z[n])
920 self.z[n])
924 self.zmin = self.zmin if self.zmin is not None else numpy.min(
921 self.zmin = self.zmin if self.zmin is not None else numpy.min(
925 self.z[n])
922 self.z[n])
926
923
927 if ax.firsttime:
924 if ax.firsttime:
928 if self.zlimits is not None:
925 if self.zlimits is not None:
929 self.zmin, self.zmax = self.zlimits[n]
926 self.zmin, self.zmax = self.zlimits[n]
930
927
931 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
928 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
932 vmin=self.zmin,
929 vmin=self.zmin,
933 vmax=self.zmax,
930 vmax=self.zmax,
934 cmap=self.cmaps[n]
931 cmap=self.cmaps[n]
935 )
932 )
936 else:
933 else:
937 if self.zlimits is not None:
934 if self.zlimits is not None:
938 self.zmin, self.zmax = self.zlimits[n]
935 self.zmin, self.zmax = self.zlimits[n]
939 ax.collections.remove(ax.collections[0])
936 ax.collections.remove(ax.collections[0])
940 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
937 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
941 vmin=self.zmin,
938 vmin=self.zmin,
942 vmax=self.zmax,
939 vmax=self.zmax,
943 cmap=self.cmaps[n]
940 cmap=self.cmaps[n]
944 )
941 )
945
942
946 self.saveTime = self.min_time
943 self.saveTime = self.min_time
947
944
948
945
949 class PlotOutputData(PlotParamData):
946 class PlotOutputData(PlotParamData):
950 '''
947 '''
951 Plot data_output object
948 Plot data_output object
952 '''
949 '''
953
950
954 CODE = 'output'
951 CODE = 'output'
955 colormap = 'seismic'
952 colormap = 'seismic'
General Comments 0
You need to be logged in to leave comments. Login now