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