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