##// END OF EJS Templates
Clean code and fix for one channel in WR
Juan C. Espinoza -
r1483:c3f12c63a985
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,739 +1,739
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from collections import deque
15 from collections import deque
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib,re
18 import matplotlib,re
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("Agg")#TkAgg
23 matplotlib.use("Agg")#TkAgg
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('MacOSX')
25 matplotlib.use('MacOSX')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 rwg=matplotlib.colors.LinearSegmentedColormap.from_list('rwg',["r", "w", "g"], N=256)
47 rwg=matplotlib.colors.LinearSegmentedColormap.from_list('rwg',["r", "w", "g"], N=256)
48 matplotlib.pyplot.register_cmap(cmap=rwg)
48 matplotlib.pyplot.register_cmap(cmap=rwg)
49
49
50 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
50 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
51 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm','rwg')]
51 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm','rwg')]
52
52
53 EARTH_RADIUS = 6.3710e3
53 EARTH_RADIUS = 6.3710e3
54
54
55 def ll2xy(lat1, lon1, lat2, lon2):
55 def ll2xy(lat1, lon1, lat2, lon2):
56
56
57 p = 0.017453292519943295
57 p = 0.017453292519943295
58 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
58 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
59 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
59 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
60 r = 12742 * numpy.arcsin(numpy.sqrt(a))
60 r = 12742 * numpy.arcsin(numpy.sqrt(a))
61 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
61 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
62 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
62 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
63 theta = -theta + numpy.pi/2
63 theta = -theta + numpy.pi/2
64 return r*numpy.cos(theta), r*numpy.sin(theta)
64 return r*numpy.cos(theta), r*numpy.sin(theta)
65
65
66
66
67 def km2deg(km):
67 def km2deg(km):
68 '''
68 '''
69 Convert distance in km to degrees
69 Convert distance in km to degrees
70 '''
70 '''
71
71
72 return numpy.rad2deg(km/EARTH_RADIUS)
72 return numpy.rad2deg(km/EARTH_RADIUS)
73
73
74
74
75 def figpause(interval):
75 def figpause(interval):
76 backend = plt.rcParams['backend']
76 backend = plt.rcParams['backend']
77 if backend in matplotlib.rcsetup.interactive_bk:
77 if backend in matplotlib.rcsetup.interactive_bk:
78 figManager = matplotlib._pylab_helpers.Gcf.get_active()
78 figManager = matplotlib._pylab_helpers.Gcf.get_active()
79 if figManager is not None:
79 if figManager is not None:
80 canvas = figManager.canvas
80 canvas = figManager.canvas
81 if canvas.figure.stale:
81 if canvas.figure.stale:
82 canvas.draw()
82 canvas.draw()
83 try:
83 try:
84 canvas.start_event_loop(interval)
84 canvas.start_event_loop(interval)
85 except:
85 except:
86 pass
86 pass
87 return
87 return
88
88
89 def popup(message):
89 def popup(message):
90 '''
90 '''
91 '''
91 '''
92
92
93 fig = plt.figure(figsize=(12, 8), facecolor='r')
93 fig = plt.figure(figsize=(12, 8), facecolor='r')
94 text = '\n'.join([s.strip() for s in message.split(':')])
94 text = '\n'.join([s.strip() for s in message.split(':')])
95 fig.text(0.01, 0.5, text, ha='left', va='center',
95 fig.text(0.01, 0.5, text, ha='left', va='center',
96 size='20', weight='heavy', color='w')
96 size='20', weight='heavy', color='w')
97 fig.show()
97 fig.show()
98 figpause(1000)
98 figpause(1000)
99
99
100
100
101 class Throttle(object):
101 class Throttle(object):
102 '''
102 '''
103 Decorator that prevents a function from being called more than once every
103 Decorator that prevents a function from being called more than once every
104 time period.
104 time period.
105 To create a function that cannot be called more than once a minute, but
105 To create a function that cannot be called more than once a minute, but
106 will sleep until it can be called:
106 will sleep until it can be called:
107 @Throttle(minutes=1)
107 @Throttle(minutes=1)
108 def foo():
108 def foo():
109 pass
109 pass
110
110
111 for i in range(10):
111 for i in range(10):
112 foo()
112 foo()
113 print "This function has run %s times." % i
113 print "This function has run %s times." % i
114 '''
114 '''
115
115
116 def __init__(self, seconds=0, minutes=0, hours=0):
116 def __init__(self, seconds=0, minutes=0, hours=0):
117 self.throttle_period = datetime.timedelta(
117 self.throttle_period = datetime.timedelta(
118 seconds=seconds, minutes=minutes, hours=hours
118 seconds=seconds, minutes=minutes, hours=hours
119 )
119 )
120
120
121 self.time_of_last_call = datetime.datetime.min
121 self.time_of_last_call = datetime.datetime.min
122
122
123 def __call__(self, fn):
123 def __call__(self, fn):
124 @wraps(fn)
124 @wraps(fn)
125 def wrapper(*args, **kwargs):
125 def wrapper(*args, **kwargs):
126 coerce = kwargs.pop('coerce', None)
126 coerce = kwargs.pop('coerce', None)
127 if coerce:
127 if coerce:
128 self.time_of_last_call = datetime.datetime.now()
128 self.time_of_last_call = datetime.datetime.now()
129 return fn(*args, **kwargs)
129 return fn(*args, **kwargs)
130 else:
130 else:
131 now = datetime.datetime.now()
131 now = datetime.datetime.now()
132 time_since_last_call = now - self.time_of_last_call
132 time_since_last_call = now - self.time_of_last_call
133 time_left = self.throttle_period - time_since_last_call
133 time_left = self.throttle_period - time_since_last_call
134
134
135 if time_left > datetime.timedelta(seconds=0):
135 if time_left > datetime.timedelta(seconds=0):
136 return
136 return
137
137
138 self.time_of_last_call = datetime.datetime.now()
138 self.time_of_last_call = datetime.datetime.now()
139 return fn(*args, **kwargs)
139 return fn(*args, **kwargs)
140
140
141 return wrapper
141 return wrapper
142
142
143 def apply_throttle(value):
143 def apply_throttle(value):
144
144
145 @Throttle(seconds=value)
145 @Throttle(seconds=value)
146 def fnThrottled(fn):
146 def fnThrottled(fn):
147 fn()
147 fn()
148
148
149 return fnThrottled
149 return fnThrottled
150
150
151
151
152 @MPDecorator
152 @MPDecorator
153 class Plot(Operation):
153 class Plot(Operation):
154 """Base class for Schain plotting operations
154 """Base class for Schain plotting operations
155
155
156 This class should never be use directtly you must subclass a new operation,
156 This class should never be use directtly you must subclass a new operation,
157 children classes must be defined as follow:
157 children classes must be defined as follow:
158
158
159 ExamplePlot(Plot):
159 ExamplePlot(Plot):
160
160
161 CODE = 'code'
161 CODE = 'code'
162 colormap = 'jet'
162 colormap = 'jet'
163 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
163 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
164
164
165 def setup(self):
165 def setup(self):
166 pass
166 pass
167
167
168 def plot(self):
168 def plot(self):
169 pass
169 pass
170
170
171 """
171 """
172
172
173 CODE = 'Figure'
173 CODE = 'Figure'
174 colormap = 'jet'
174 colormap = 'jet'
175 bgcolor = 'white'
175 bgcolor = 'white'
176 buffering = True
176 buffering = True
177 __missing = 1E30
177 __missing = 1E30
178
178
179 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
179 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
180 'showprofile']
180 'showprofile']
181
181
182 def __init__(self):
182 def __init__(self):
183
183
184 Operation.__init__(self)
184 Operation.__init__(self)
185 self.isConfig = False
185 self.isConfig = False
186 self.isPlotConfig = False
186 self.isPlotConfig = False
187 self.save_time = 0
187 self.save_time = 0
188 self.sender_time = 0
188 self.sender_time = 0
189 self.data = None
189 self.data = None
190 self.firsttime = True
190 self.firsttime = True
191 self.sender_queue = deque(maxlen=10)
191 self.sender_queue = deque(maxlen=10)
192 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
192 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
193
193
194 def __fmtTime(self, x, pos):
194 def __fmtTime(self, x, pos):
195 '''
195 '''
196 '''
196 '''
197
197
198 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
198 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
199
199
200 def __setup(self, **kwargs):
200 def __setup(self, **kwargs):
201 '''
201 '''
202 Initialize variables
202 Initialize variables
203 '''
203 '''
204
204
205 self.figures = []
205 self.figures = []
206 self.axes = []
206 self.axes = []
207 self.cb_axes = []
207 self.cb_axes = []
208 self.localtime = kwargs.pop('localtime', True)
208 self.localtime = kwargs.pop('localtime', True)
209 self.show = kwargs.get('show', True)
209 self.show = kwargs.get('show', True)
210 self.save = kwargs.get('save', False)
210 self.save = kwargs.get('save', False)
211 self.save_period = kwargs.get('save_period', 0)
211 self.save_period = kwargs.get('save_period', 0)
212 self.colormap = kwargs.get('colormap', self.colormap)
212 self.colormap = kwargs.get('colormap', self.colormap)
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
215 self.colormaps = kwargs.get('colormaps', None)
215 self.colormaps = kwargs.get('colormaps', None)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
217 self.showprofile = kwargs.get('showprofile', False)
217 self.showprofile = kwargs.get('showprofile', False)
218 self.title = kwargs.get('wintitle', self.CODE.upper())
218 self.title = kwargs.get('wintitle', self.CODE.upper())
219 self.cb_label = kwargs.get('cb_label', None)
219 self.cb_label = kwargs.get('cb_label', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
221 self.labels = kwargs.get('labels', None)
221 self.labels = kwargs.get('labels', None)
222 self.xaxis = kwargs.get('xaxis', 'frequency')
222 self.xaxis = kwargs.get('xaxis', 'frequency')
223 self.zmin = kwargs.get('zmin', None)
223 self.zmin = kwargs.get('zmin', None)
224 self.zmax = kwargs.get('zmax', None)
224 self.zmax = kwargs.get('zmax', None)
225 self.zlimits = kwargs.get('zlimits', None)
225 self.zlimits = kwargs.get('zlimits', None)
226 self.xmin = kwargs.get('xmin', None)
226 self.xmin = kwargs.get('xmin', None)
227 self.xmax = kwargs.get('xmax', None)
227 self.xmax = kwargs.get('xmax', None)
228 self.xrange = kwargs.get('xrange', 12)
228 self.xrange = kwargs.get('xrange', 12)
229 self.xscale = kwargs.get('xscale', None)
229 self.xscale = kwargs.get('xscale', None)
230 self.ymin = kwargs.get('ymin', None)
230 self.ymin = kwargs.get('ymin', None)
231 self.ymax = kwargs.get('ymax', None)
231 self.ymax = kwargs.get('ymax', None)
232 self.yscale = kwargs.get('yscale', None)
232 self.yscale = kwargs.get('yscale', None)
233 self.xlabel = kwargs.get('xlabel', None)
233 self.xlabel = kwargs.get('xlabel', None)
234 self.attr_time = kwargs.get('attr_time', 'utctime')
234 self.attr_time = kwargs.get('attr_time', 'utctime')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
236 self.decimation = kwargs.get('decimation', None)
236 self.decimation = kwargs.get('decimation', None)
237 self.oneFigure = kwargs.get('oneFigure', True)
237 self.oneFigure = kwargs.get('oneFigure', True)
238 self.width = kwargs.get('width', None)
238 self.width = kwargs.get('width', None)
239 self.height = kwargs.get('height', None)
239 self.height = kwargs.get('height', None)
240 self.colorbar = kwargs.get('colorbar', True)
240 self.colorbar = kwargs.get('colorbar', True)
241 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
241 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
242 self.channels = kwargs.get('channels', None)
242 self.channels = kwargs.get('channels', None)
243 self.titles = kwargs.get('titles', [])
243 self.titles = kwargs.get('titles', [])
244 self.polar = False
244 self.polar = False
245 self.type = kwargs.get('type', 'iq')
245 self.type = kwargs.get('type', 'iq')
246 self.grid = kwargs.get('grid', False)
246 self.grid = kwargs.get('grid', False)
247 self.pause = kwargs.get('pause', False)
247 self.pause = kwargs.get('pause', False)
248 self.save_code = kwargs.get('save_code', self.CODE)
248 self.save_code = kwargs.get('save_code', self.CODE)
249 self.throttle = kwargs.get('throttle', 0)
249 self.throttle = kwargs.get('throttle', 0)
250 self.exp_code = kwargs.get('exp_code', None)
250 self.exp_code = kwargs.get('exp_code', None)
251 self.server = kwargs.get('server', False)
251 self.server = kwargs.get('server', False)
252 self.sender_period = kwargs.get('sender_period', 60)
252 self.sender_period = kwargs.get('sender_period', 60)
253 self.tag = kwargs.get('tag', '')
253 self.tag = kwargs.get('tag', '')
254 self.height_index = kwargs.get('height_index', None)
254 self.height_index = kwargs.get('height_index', None)
255 self.__throttle_plot = apply_throttle(self.throttle)
255 self.__throttle_plot = apply_throttle(self.throttle)
256 code = self.attr_data if self.attr_data else self.CODE
256 code = self.attr_data if self.attr_data else self.CODE
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
258 self.ang_min = kwargs.get('ang_min', None)
258 self.ang_min = kwargs.get('ang_min', None)
259 self.ang_max = kwargs.get('ang_max', None)
259 self.ang_max = kwargs.get('ang_max', None)
260 self.mode = kwargs.get('mode', None)
260 self.mode = kwargs.get('mode', None)
261
261
262
262
263
263
264 if self.server:
264 if self.server:
265 if not self.server.startswith('tcp://'):
265 if not self.server.startswith('tcp://'):
266 self.server = 'tcp://{}'.format(self.server)
266 self.server = 'tcp://{}'.format(self.server)
267 log.success(
267 log.success(
268 'Sending to server: {}'.format(self.server),
268 'Sending to server: {}'.format(self.server),
269 self.name
269 self.name
270 )
270 )
271
271
272 if isinstance(self.attr_data, str):
272 if isinstance(self.attr_data, str):
273 self.attr_data = [self.attr_data]
273 self.attr_data = [self.attr_data]
274
274
275 def __setup_plot(self):
275 def __setup_plot(self):
276 '''
276 '''
277 Common setup for all figures, here figures and axes are created
277 Common setup for all figures, here figures and axes are created
278 '''
278 '''
279
279
280 self.setup()
280 self.setup()
281
281
282 self.time_label = 'LT' if self.localtime else 'UTC'
282 self.time_label = 'LT' if self.localtime else 'UTC'
283
283
284 if self.width is None:
284 if self.width is None:
285 self.width = 8
285 self.width = 8
286
286
287 self.figures = []
287 self.figures = []
288 self.axes = []
288 self.axes = []
289 self.cb_axes = []
289 self.cb_axes = []
290 self.pf_axes = []
290 self.pf_axes = []
291 self.cmaps = []
291 self.cmaps = []
292
292
293 size = '15%' if self.ncols == 1 else '30%'
293 size = '15%' if self.ncols == 1 else '30%'
294 pad = '4%' if self.ncols == 1 else '8%'
294 pad = '4%' if self.ncols == 1 else '8%'
295
295
296 if self.oneFigure:
296 if self.oneFigure:
297 if self.height is None:
297 if self.height is None:
298 self.height = 1.4 * self.nrows + 1
298 self.height = 1.4 * self.nrows + 1
299 fig = plt.figure(figsize=(self.width, self.height),
299 fig = plt.figure(figsize=(self.width, self.height),
300 edgecolor='k',
300 edgecolor='k',
301 facecolor='w')
301 facecolor='w')
302 self.figures.append(fig)
302 self.figures.append(fig)
303 for n in range(self.nplots):
303 for n in range(self.nplots):
304 ax = fig.add_subplot(self.nrows, self.ncols,
304 ax = fig.add_subplot(self.nrows, self.ncols,
305 n + 1, polar=self.polar)
305 n + 1, polar=self.polar)
306 ax.tick_params(labelsize=8)
306 ax.tick_params(labelsize=8)
307 ax.firsttime = True
307 ax.firsttime = True
308 ax.index = 0
308 ax.index = 0
309 ax.press = None
309 ax.press = None
310 self.axes.append(ax)
310 self.axes.append(ax)
311 if self.showprofile:
311 if self.showprofile:
312 cax = self.__add_axes(ax, size=size, pad=pad)
312 cax = self.__add_axes(ax, size=size, pad=pad)
313 cax.tick_params(labelsize=8)
313 cax.tick_params(labelsize=8)
314 self.pf_axes.append(cax)
314 self.pf_axes.append(cax)
315 else:
315 else:
316 if self.height is None:
316 if self.height is None:
317 self.height = 3
317 self.height = 3
318 for n in range(self.nplots):
318 for n in range(self.nplots):
319 fig = plt.figure(figsize=(self.width, self.height),
319 fig = plt.figure(figsize=(self.width, self.height),
320 edgecolor='k',
320 edgecolor='k',
321 facecolor='w')
321 facecolor='w')
322 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
322 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
323 ax.tick_params(labelsize=8)
323 ax.tick_params(labelsize=8)
324 ax.firsttime = True
324 ax.firsttime = True
325 ax.index = 0
325 ax.index = 0
326 ax.press = None
326 ax.press = None
327 self.figures.append(fig)
327 self.figures.append(fig)
328 self.axes.append(ax)
328 self.axes.append(ax)
329 if self.showprofile:
329 if self.showprofile:
330 cax = self.__add_axes(ax, size=size, pad=pad)
330 cax = self.__add_axes(ax, size=size, pad=pad)
331 cax.tick_params(labelsize=8)
331 cax.tick_params(labelsize=8)
332 self.pf_axes.append(cax)
332 self.pf_axes.append(cax)
333
333
334 for n in range(self.nrows):
334 for n in range(self.nrows):
335 if self.colormaps is not None:
335 if self.colormaps is not None:
336 cmap = plt.get_cmap(self.colormaps[n])
336 cmap = plt.get_cmap(self.colormaps[n])
337 else:
337 else:
338 cmap = plt.get_cmap(self.colormap)
338 cmap = plt.get_cmap(self.colormap)
339 cmap.set_bad(self.bgcolor, 1.)
339 cmap.set_bad(self.bgcolor, 1.)
340 self.cmaps.append(cmap)
340 self.cmaps.append(cmap)
341
341
342 def __add_axes(self, ax, size='30%', pad='8%'):
342 def __add_axes(self, ax, size='30%', pad='8%'):
343 '''
343 '''
344 Add new axes to the given figure
344 Add new axes to the given figure
345 '''
345 '''
346 divider = make_axes_locatable(ax)
346 divider = make_axes_locatable(ax)
347 nax = divider.new_horizontal(size=size, pad=pad)
347 nax = divider.new_horizontal(size=size, pad=pad)
348 ax.figure.add_axes(nax)
348 ax.figure.add_axes(nax)
349 return nax
349 return nax
350
350
351 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
351 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
352 '''
352 '''
353 Create a masked array for missing data
353 Create a masked array for missing data
354 '''
354 '''
355 if x_buffer.shape[0] < 2:
355 if x_buffer.shape[0] < 2:
356 return x_buffer, y_buffer, z_buffer
356 return x_buffer, y_buffer, z_buffer
357
357
358 deltas = x_buffer[1:] - x_buffer[0:-1]
358 deltas = x_buffer[1:] - x_buffer[0:-1]
359 x_median = numpy.median(deltas)
359 x_median = numpy.median(deltas)
360
360
361 index = numpy.where(deltas > 5 * x_median)
361 index = numpy.where(deltas > 5 * x_median)
362
362
363 if len(index[0]) != 0:
363 if len(index[0]) != 0:
364 z_buffer[::, index[0], ::] = self.__missing
364 z_buffer[::, index[0], ::] = self.__missing
365 z_buffer = numpy.ma.masked_inside(z_buffer,
365 z_buffer = numpy.ma.masked_inside(z_buffer,
366 0.99 * self.__missing,
366 0.99 * self.__missing,
367 1.01 * self.__missing)
367 1.01 * self.__missing)
368
368
369 return x_buffer, y_buffer, z_buffer
369 return x_buffer, y_buffer, z_buffer
370
370
371 def decimate(self):
371 def decimate(self):
372
372
373 # dx = int(len(self.x)/self.__MAXNUMX) + 1
373 # dx = int(len(self.x)/self.__MAXNUMX) + 1
374 dy = int(len(self.y) / self.decimation) + 1
374 dy = int(len(self.y) / self.decimation) + 1
375
375
376 # x = self.x[::dx]
376 # x = self.x[::dx]
377 x = self.x
377 x = self.x
378 y = self.y[::dy]
378 y = self.y[::dy]
379 z = self.z[::, ::, ::dy]
379 z = self.z[::, ::, ::dy]
380
380
381 return x, y, z
381 return x, y, z
382
382
383 def format(self):
383 def format(self):
384 '''
384 '''
385 Set min and max values, labels, ticks and titles
385 Set min and max values, labels, ticks and titles
386 '''
386 '''
387
387
388 for n, ax in enumerate(self.axes):
388 for n, ax in enumerate(self.axes):
389 if ax.firsttime:
389 if ax.firsttime:
390 if self.xaxis != 'time':
390 if self.xaxis != 'time':
391 xmin = self.xmin
391 xmin = self.xmin
392 xmax = self.xmax
392 xmax = self.xmax
393 else:
393 else:
394 xmin = self.tmin
394 xmin = self.tmin
395 xmax = self.tmin + self.xrange*60*60
395 xmax = self.tmin + self.xrange*60*60
396 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
396 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
397 ax.xaxis.set_major_locator(LinearLocator(9))
397 ax.xaxis.set_major_locator(LinearLocator(9))
398 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
398 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
399 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
399 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
400 ax.set_facecolor(self.bgcolor)
400 ax.set_facecolor(self.bgcolor)
401 if self.xscale:
401 if self.xscale:
402 ax.xaxis.set_major_formatter(FuncFormatter(
402 ax.xaxis.set_major_formatter(FuncFormatter(
403 lambda x, pos: '{0:g}'.format(x*self.xscale)))
403 lambda x, pos: '{0:g}'.format(x*self.xscale)))
404 if self.yscale:
404 if self.yscale:
405 ax.yaxis.set_major_formatter(FuncFormatter(
405 ax.yaxis.set_major_formatter(FuncFormatter(
406 lambda x, pos: '{0:g}'.format(x*self.yscale)))
406 lambda x, pos: '{0:g}'.format(x*self.yscale)))
407 if self.xlabel is not None:
407 if self.xlabel is not None:
408 ax.set_xlabel(self.xlabel)
408 ax.set_xlabel(self.xlabel)
409 if self.ylabel is not None:
409 if self.ylabel is not None:
410 ax.set_ylabel(self.ylabel)
410 ax.set_ylabel(self.ylabel)
411 if self.showprofile:
411 if self.showprofile:
412 self.pf_axes[n].set_ylim(ymin, ymax)
412 self.pf_axes[n].set_ylim(ymin, ymax)
413 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
413 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
414 self.pf_axes[n].set_xlabel('dB')
414 self.pf_axes[n].set_xlabel('dB')
415 self.pf_axes[n].grid(b=True, axis='x')
415 self.pf_axes[n].grid(b=True, axis='x')
416 [tick.set_visible(False)
416 [tick.set_visible(False)
417 for tick in self.pf_axes[n].get_yticklabels()]
417 for tick in self.pf_axes[n].get_yticklabels()]
418 if self.colorbar:
418 if self.colorbar:
419 ax.cbar = plt.colorbar(
419 ax.cbar = plt.colorbar(
420 ax.plt, ax=ax, fraction=0.05, pad=0.06, aspect=10)
420 ax.plt, ax=ax, fraction=0.05, pad=0.06, aspect=10)
421 ax.cbar.ax.tick_params(labelsize=8)
421 ax.cbar.ax.tick_params(labelsize=8)
422 ax.cbar.ax.press = None
422 ax.cbar.ax.press = None
423 if self.cb_label:
423 if self.cb_label:
424 ax.cbar.set_label(self.cb_label, size=8)
424 ax.cbar.set_label(self.cb_label, size=8)
425 elif self.cb_labels:
425 elif self.cb_labels:
426 ax.cbar.set_label(self.cb_labels[n], size=8)
426 ax.cbar.set_label(self.cb_labels[n], size=8)
427 else:
427 else:
428 ax.cbar = None
428 ax.cbar = None
429 ax.set_xlim(xmin, xmax)
429 ax.set_xlim(xmin, xmax)
430 ax.set_ylim(ymin, ymax)
430 ax.set_ylim(ymin, ymax)
431 ax.firsttime = False
431 ax.firsttime = False
432 if self.grid:
432 if self.grid:
433 ax.grid(True)
433 ax.grid(True)
434 if not self.polar:
434 if not self.polar:
435 ax.set_title('{} {} {}'.format(
435 ax.set_title('{} {} {}'.format(
436 self.titles[n],
436 self.titles[n],
437 self.getDateTime(self.data.max_time).strftime(
437 self.getDateTime(self.data.max_time).strftime(
438 '%Y-%m-%d %H:%M:%S'),
438 '%Y-%m-%d %H:%M:%S'),
439 self.time_label),
439 self.time_label),
440 size=8)
440 size=8)
441 else:
441 else:
442 #ax.set_title('{}'.format(self.titles[n]), size=8)
442 #ax.set_title('{}'.format(self.titles[n]), size=8)
443 ax.set_title('{} {} {}'.format(
443 ax.set_title('{} {} {}'.format(
444 self.titles[n],
444 self.titles[n],
445 self.getDateTime(self.data.max_time).strftime(
445 self.getDateTime(self.data.max_time).strftime(
446 '%Y-%m-%d %H:%M:%S'),
446 '%Y-%m-%d %H:%M:%S'),
447 self.time_label),
447 self.time_label),
448 size=8)
448 size=8)
449 ax.set_ylim(0, self.ymax)
449 ax.set_ylim(0, self.ymax)
450 #ax.set_yticks(numpy.arange(0, self.ymax, 20))
450 #ax.set_yticks(numpy.arange(0, self.ymax, 20))
451 ax.yaxis.labelpad = 28
451 ax.yaxis.labelpad = 28
452
452
453 if self.firsttime:
453 if self.firsttime:
454 for n, fig in enumerate(self.figures):
454 for n, fig in enumerate(self.figures):
455 fig.subplots_adjust(**self.plots_adjust)
455 fig.subplots_adjust(**self.plots_adjust)
456 self.firsttime = False
456 self.firsttime = False
457
457
458 def clear_figures(self):
458 def clear_figures(self):
459 '''
459 '''
460 Reset axes for redraw plots
460 Reset axes for redraw plots
461 '''
461 '''
462
462
463 for ax in self.axes+self.pf_axes+self.cb_axes:
463 for ax in self.axes+self.pf_axes+self.cb_axes:
464 ax.clear()
464 ax.clear()
465 ax.firsttime = True
465 ax.firsttime = True
466 if hasattr(ax, 'cbar') and ax.cbar:
466 if hasattr(ax, 'cbar') and ax.cbar:
467 ax.cbar.remove()
467 ax.cbar.remove()
468
468
469 def __plot(self):
469 def __plot(self):
470 '''
470 '''
471 Main function to plot, format and save figures
471 Main function to plot, format and save figures
472 '''
472 '''
473
473
474 self.plot()
474 self.plot()
475 self.format()
475 self.format()
476
476
477 for n, fig in enumerate(self.figures):
477 for n, fig in enumerate(self.figures):
478 if self.nrows == 0 or self.nplots == 0:
478 if self.nrows == 0 or self.nplots == 0:
479 log.warning('No data', self.name)
479 log.warning('No data', self.name)
480 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
480 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
481 fig.canvas.manager.set_window_title(self.CODE)
481 fig.canvas.manager.set_window_title(self.CODE)
482 continue
482 continue
483
483
484 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
484 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
485 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
485 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
486 fig.canvas.draw()
486 fig.canvas.draw()
487 if self.show:
487 if self.show:
488 fig.show()
488 fig.show()
489 figpause(0.01)
489 figpause(0.01)
490
490
491 if self.save:
491 if self.save:
492 if self.CODE=="PPI" or self.CODE=="RHI":
492 if self.CODE=="PPI" or self.CODE=="RHI":
493 self.save_figure(n,stitle =self.titles)
493 self.save_figure(n,stitle =self.titles)
494 else:
494 else:
495 self.save_figure(n)
495 self.save_figure(n)
496
496
497 if self.server:
497 if self.server:
498 self.send_to_server()
498 self.send_to_server()
499
499
500 def __update(self, dataOut, timestamp):
500 def __update(self, dataOut, timestamp):
501 '''
501 '''
502 '''
502 '''
503
503
504 metadata = {
504 metadata = {
505 'yrange': dataOut.heightList,
505 'yrange': dataOut.heightList,
506 'interval': dataOut.timeInterval,
506 'interval': dataOut.timeInterval,
507 'channels': dataOut.channelList
507 'channels': dataOut.channelList
508 }
508 }
509
509
510 data, meta = self.update(dataOut)
510 data, meta = self.update(dataOut)
511 metadata.update(meta)
511 metadata.update(meta)
512 self.data.update(data, timestamp, metadata)
512 self.data.update(data, timestamp, metadata)
513
513
514 def save_figure(self, n,stitle=None):
514 def save_figure(self, n,stitle=None):
515 '''
515 '''
516 '''
516 '''
517 if stitle is not None:
517 if stitle is not None:
518 s_string = re.sub(r"[^A-Z0-9.]","",str(stitle))
518 s_string = re.sub(r"[^A-Z0-9.]","",str(stitle))
519 new_string=s_string[:3]+"_"+s_string[4:6]+"_"+s_string[6:]
519 new_string=s_string[:3]+"_"+s_string[4:6]+"_"+s_string[6:]
520
520
521 if self.oneFigure:
521 if self.oneFigure:
522 if (self.data.max_time - self.save_time) <= self.save_period:
522 if (self.data.max_time - self.save_time) <= self.save_period:
523 return
523 return
524
524
525 self.save_time = self.data.max_time
525 self.save_time = self.data.max_time
526
526
527 fig = self.figures[n]
527 fig = self.figures[n]
528
528
529 if self.throttle == 0:
529 if self.throttle == 0:
530 if self.oneFigure:
530 if self.oneFigure:
531 if stitle is not None:
531 if stitle is not None:
532 figname = os.path.join(
532 figname = os.path.join(
533 self.save,
533 self.save,
534 self.save_code,
534 self.save_code + '_' + new_string,
535 '{}_{}_{}.png'.format(
535 '{}_{}_{}.png'.format(
536 self.save_code,
536 self.save_code,
537 new_string,
537 self.getDateTime(self.data.max_time).strftime(
538 self.getDateTime(self.data.max_time).strftime(
538 '%Y%m%d_%H%M%S',
539 '%Y%m%d_%H%M%S',
539 ),
540 ),
540 new_string,
541 )
541 )
542 )
542 )
543 else:
543 else:
544 figname = os.path.join(
544 figname = os.path.join(
545 self.save,
545 self.save,
546 self.save_code,
546 self.save_code,
547 '{}_{}.png'.format(
547 '{}_{}.png'.format(
548 self.save_code,
548 self.save_code,
549 self.getDateTime(self.data.max_time).strftime(
549 self.getDateTime(self.data.max_time).strftime(
550 '%Y%m%d_%H%M%S'
550 '%Y%m%d_%H%M%S'
551 ),
551 ),
552 )
552 )
553 )
553 )
554 else:
554 else:
555 figname = os.path.join(
555 figname = os.path.join(
556 self.save,
556 self.save,
557 self.save_code,
557 self.save_code,
558 '{}_ch{}_{}.png'.format(
558 '{}_ch{}_{}.png'.format(
559 self.save_code,n,
559 self.save_code,n,
560 self.getDateTime(self.data.max_time).strftime(
560 self.getDateTime(self.data.max_time).strftime(
561 '%Y%m%d_%H%M%S'
561 '%Y%m%d_%H%M%S'
562 ),
562 ),
563 )
563 )
564 )
564 )
565 log.log('Saving figure: {}'.format(figname), self.name)
565 log.log('Saving figure: {}'.format(figname), self.name)
566 if not os.path.isdir(os.path.dirname(figname)):
566 if not os.path.isdir(os.path.dirname(figname)):
567 os.makedirs(os.path.dirname(figname))
567 os.makedirs(os.path.dirname(figname))
568 fig.savefig(figname)
568 fig.savefig(figname)
569
569
570 figname = os.path.join(
570 figname = os.path.join(
571 self.save,
571 self.save,
572 '{}_{}.png'.format(
572 '{}_{}.png'.format(
573 self.save_code,
573 self.save_code,
574 self.getDateTime(self.data.min_time).strftime(
574 self.getDateTime(self.data.min_time).strftime(
575 '%Y%m%d'
575 '%Y%m%d'
576 ),
576 ),
577 )
577 )
578 )
578 )
579
579
580 log.log('Saving figure: {}'.format(figname), self.name)
580 log.log('Saving figure: {}'.format(figname), self.name)
581 if not os.path.isdir(os.path.dirname(figname)):
581 if not os.path.isdir(os.path.dirname(figname)):
582 os.makedirs(os.path.dirname(figname))
582 os.makedirs(os.path.dirname(figname))
583 fig.savefig(figname)
583 fig.savefig(figname)
584
584
585 def send_to_server(self):
585 def send_to_server(self):
586 '''
586 '''
587 '''
587 '''
588
588
589 if self.exp_code == None:
589 if self.exp_code == None:
590 log.warning('Missing `exp_code` skipping sending to server...')
590 log.warning('Missing `exp_code` skipping sending to server...')
591
591
592 last_time = self.data.max_time
592 last_time = self.data.max_time
593 interval = last_time - self.sender_time
593 interval = last_time - self.sender_time
594 if interval < self.sender_period:
594 if interval < self.sender_period:
595 return
595 return
596
596
597 self.sender_time = last_time
597 self.sender_time = last_time
598
598
599 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
599 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
600 for attr in attrs:
600 for attr in attrs:
601 value = getattr(self, attr)
601 value = getattr(self, attr)
602 if value:
602 if value:
603 if isinstance(value, (numpy.float32, numpy.float64)):
603 if isinstance(value, (numpy.float32, numpy.float64)):
604 value = round(float(value), 2)
604 value = round(float(value), 2)
605 self.data.meta[attr] = value
605 self.data.meta[attr] = value
606 if self.colormap == 'jet':
606 if self.colormap == 'jet':
607 self.data.meta['colormap'] = 'Jet'
607 self.data.meta['colormap'] = 'Jet'
608 elif 'RdBu' in self.colormap:
608 elif 'RdBu' in self.colormap:
609 self.data.meta['colormap'] = 'RdBu'
609 self.data.meta['colormap'] = 'RdBu'
610 else:
610 else:
611 self.data.meta['colormap'] = 'Viridis'
611 self.data.meta['colormap'] = 'Viridis'
612 self.data.meta['interval'] = int(interval)
612 self.data.meta['interval'] = int(interval)
613
613
614 self.sender_queue.append(last_time)
614 self.sender_queue.append(last_time)
615
615
616 while True:
616 while True:
617 try:
617 try:
618 tm = self.sender_queue.popleft()
618 tm = self.sender_queue.popleft()
619 except IndexError:
619 except IndexError:
620 break
620 break
621 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
621 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
622 self.socket.send_string(msg)
622 self.socket.send_string(msg)
623 socks = dict(self.poll.poll(2000))
623 socks = dict(self.poll.poll(2000))
624 if socks.get(self.socket) == zmq.POLLIN:
624 if socks.get(self.socket) == zmq.POLLIN:
625 reply = self.socket.recv_string()
625 reply = self.socket.recv_string()
626 if reply == 'ok':
626 if reply == 'ok':
627 log.log("Response from server ok", self.name)
627 log.log("Response from server ok", self.name)
628 time.sleep(0.1)
628 time.sleep(0.1)
629 continue
629 continue
630 else:
630 else:
631 log.warning(
631 log.warning(
632 "Malformed reply from server: {}".format(reply), self.name)
632 "Malformed reply from server: {}".format(reply), self.name)
633 else:
633 else:
634 log.warning(
634 log.warning(
635 "No response from server, retrying...", self.name)
635 "No response from server, retrying...", self.name)
636 self.sender_queue.appendleft(tm)
636 self.sender_queue.appendleft(tm)
637 self.socket.setsockopt(zmq.LINGER, 0)
637 self.socket.setsockopt(zmq.LINGER, 0)
638 self.socket.close()
638 self.socket.close()
639 self.poll.unregister(self.socket)
639 self.poll.unregister(self.socket)
640 self.socket = self.context.socket(zmq.REQ)
640 self.socket = self.context.socket(zmq.REQ)
641 self.socket.connect(self.server)
641 self.socket.connect(self.server)
642 self.poll.register(self.socket, zmq.POLLIN)
642 self.poll.register(self.socket, zmq.POLLIN)
643 break
643 break
644
644
645 def setup(self):
645 def setup(self):
646 '''
646 '''
647 This method should be implemented in the child class, the following
647 This method should be implemented in the child class, the following
648 attributes should be set:
648 attributes should be set:
649
649
650 self.nrows: number of rows
650 self.nrows: number of rows
651 self.ncols: number of cols
651 self.ncols: number of cols
652 self.nplots: number of plots (channels or pairs)
652 self.nplots: number of plots (channels or pairs)
653 self.ylabel: label for Y axes
653 self.ylabel: label for Y axes
654 self.titles: list of axes title
654 self.titles: list of axes title
655
655
656 '''
656 '''
657 raise NotImplementedError
657 raise NotImplementedError
658
658
659 def plot(self):
659 def plot(self):
660 '''
660 '''
661 Must be defined in the child class, the actual plotting method
661 Must be defined in the child class, the actual plotting method
662 '''
662 '''
663 raise NotImplementedError
663 raise NotImplementedError
664
664
665 def update(self, dataOut):
665 def update(self, dataOut):
666 '''
666 '''
667 Must be defined in the child class, update self.data with new data
667 Must be defined in the child class, update self.data with new data
668 '''
668 '''
669
669
670 data = {
670 data = {
671 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
671 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
672 }
672 }
673 meta = {}
673 meta = {}
674
674
675 return data, meta
675 return data, meta
676
676
677 def run(self, dataOut, **kwargs):
677 def run(self, dataOut, **kwargs):
678 '''
678 '''
679 Main plotting routine
679 Main plotting routine
680 '''
680 '''
681
681
682 if self.isConfig is False:
682 if self.isConfig is False:
683 self.__setup(**kwargs)
683 self.__setup(**kwargs)
684
684
685 if self.localtime:
685 if self.localtime:
686 self.getDateTime = datetime.datetime.fromtimestamp
686 self.getDateTime = datetime.datetime.fromtimestamp
687 else:
687 else:
688 self.getDateTime = datetime.datetime.utcfromtimestamp
688 self.getDateTime = datetime.datetime.utcfromtimestamp
689
689
690 self.data.setup()
690 self.data.setup()
691 self.isConfig = True
691 self.isConfig = True
692 if self.server:
692 if self.server:
693 self.context = zmq.Context()
693 self.context = zmq.Context()
694 self.socket = self.context.socket(zmq.REQ)
694 self.socket = self.context.socket(zmq.REQ)
695 self.socket.connect(self.server)
695 self.socket.connect(self.server)
696 self.poll = zmq.Poller()
696 self.poll = zmq.Poller()
697 self.poll.register(self.socket, zmq.POLLIN)
697 self.poll.register(self.socket, zmq.POLLIN)
698
698
699 tm = getattr(dataOut, self.attr_time)
699 tm = getattr(dataOut, self.attr_time)
700
700
701 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
701 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
702 self.save_time = tm
702 self.save_time = tm
703 self.__plot()
703 self.__plot()
704 self.tmin += self.xrange*60*60
704 self.tmin += self.xrange*60*60
705 self.data.setup()
705 self.data.setup()
706 self.clear_figures()
706 self.clear_figures()
707
707
708 self.__update(dataOut, tm)
708 self.__update(dataOut, tm)
709
709
710 if self.isPlotConfig is False:
710 if self.isPlotConfig is False:
711 self.__setup_plot()
711 self.__setup_plot()
712 self.isPlotConfig = True
712 self.isPlotConfig = True
713 if self.xaxis == 'time':
713 if self.xaxis == 'time':
714 dt = self.getDateTime(tm)
714 dt = self.getDateTime(tm)
715 if self.xmin is None:
715 if self.xmin is None:
716 self.tmin = tm
716 self.tmin = tm
717 self.xmin = dt.hour
717 self.xmin = dt.hour
718 minutes = (self.xmin-int(self.xmin)) * 60
718 minutes = (self.xmin-int(self.xmin)) * 60
719 seconds = (minutes - int(minutes)) * 60
719 seconds = (minutes - int(minutes)) * 60
720 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
720 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
721 datetime.datetime(1970, 1, 1)).total_seconds()
721 datetime.datetime(1970, 1, 1)).total_seconds()
722 if self.localtime:
722 if self.localtime:
723 self.tmin += time.timezone
723 self.tmin += time.timezone
724
724
725 if self.xmin is not None and self.xmax is not None:
725 if self.xmin is not None and self.xmax is not None:
726 self.xrange = self.xmax - self.xmin
726 self.xrange = self.xmax - self.xmin
727
727
728 if self.throttle == 0:
728 if self.throttle == 0:
729 self.__plot()
729 self.__plot()
730 else:
730 else:
731 self.__throttle_plot(self.__plot)#, coerce=coerce)
731 self.__throttle_plot(self.__plot)#, coerce=coerce)
732
732
733 def close(self):
733 def close(self):
734
734
735 if self.data and not self.data.flagNoData:
735 if self.data and not self.data.flagNoData:
736 self.save_time = 0
736 self.save_time = 0
737 self.__plot()
737 self.__plot()
738 if self.data and not self.data.flagNoData and self.pause:
738 if self.data and not self.data.flagNoData and self.pause:
739 figpause(10)
739 figpause(10)
This diff has been collapsed as it changes many lines, (1437 lines changed) Show them Hide them
@@ -1,1936 +1,509
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
4 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
5
5
6 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_base import Plot, plt
7 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
7 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
8 from schainpy.utils import log
8 from schainpy.utils import log
9 # libreria wradlib
9 # libreria wradlib
10 #import wradlib as wrl
10 #import wradlib as wrl
11
11
12 EARTH_RADIUS = 6.3710e3
12 EARTH_RADIUS = 6.3710e3
13
13
14
14
15 def ll2xy(lat1, lon1, lat2, lon2):
15 def ll2xy(lat1, lon1, lat2, lon2):
16
16
17 p = 0.017453292519943295
17 p = 0.017453292519943295
18 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
18 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
19 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
19 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
20 r = 12742 * numpy.arcsin(numpy.sqrt(a))
20 r = 12742 * numpy.arcsin(numpy.sqrt(a))
21 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
21 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
22 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
22 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
23 theta = -theta + numpy.pi/2
23 theta = -theta + numpy.pi/2
24 return r*numpy.cos(theta), r*numpy.sin(theta)
24 return r*numpy.cos(theta), r*numpy.sin(theta)
25
25
26
26
27 def km2deg(km):
27 def km2deg(km):
28 '''
28 '''
29 Convert distance in km to degrees
29 Convert distance in km to degrees
30 '''
30 '''
31
31
32 return numpy.rad2deg(km/EARTH_RADIUS)
32 return numpy.rad2deg(km/EARTH_RADIUS)
33
33
34
34
35
35
36 class SpectralMomentsPlot(SpectraPlot):
36 class SpectralMomentsPlot(SpectraPlot):
37 '''
37 '''
38 Plot for Spectral Moments
38 Plot for Spectral Moments
39 '''
39 '''
40 CODE = 'spc_moments'
40 CODE = 'spc_moments'
41 # colormap = 'jet'
41 # colormap = 'jet'
42 # plot_type = 'pcolor'
42 # plot_type = 'pcolor'
43
43
44 class DobleGaussianPlot(SpectraPlot):
44 class DobleGaussianPlot(SpectraPlot):
45 '''
45 '''
46 Plot for Double Gaussian Plot
46 Plot for Double Gaussian Plot
47 '''
47 '''
48 CODE = 'gaussian_fit'
48 CODE = 'gaussian_fit'
49 # colormap = 'jet'
49 # colormap = 'jet'
50 # plot_type = 'pcolor'
50 # plot_type = 'pcolor'
51
51
52 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
52 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
53 '''
53 '''
54 Plot SpectraCut with Double Gaussian Fit
54 Plot SpectraCut with Double Gaussian Fit
55 '''
55 '''
56 CODE = 'cut_gaussian_fit'
56 CODE = 'cut_gaussian_fit'
57
57
58 class SnrPlot(RTIPlot):
58 class SnrPlot(RTIPlot):
59 '''
59 '''
60 Plot for SNR Data
60 Plot for SNR Data
61 '''
61 '''
62
62
63 CODE = 'snr'
63 CODE = 'snr'
64 colormap = 'jet'
64 colormap = 'jet'
65
65
66 def update(self, dataOut):
66 def update(self, dataOut):
67
67
68 data = {
68 data = {
69 'snr': 10*numpy.log10(dataOut.data_snr)
69 'snr': 10*numpy.log10(dataOut.data_snr)
70 }
70 }
71
71
72 return data, {}
72 return data, {}
73
73
74 class DopplerPlot(RTIPlot):
74 class DopplerPlot(RTIPlot):
75 '''
75 '''
76 Plot for DOPPLER Data (1st moment)
76 Plot for DOPPLER Data (1st moment)
77 '''
77 '''
78
78
79 CODE = 'dop'
79 CODE = 'dop'
80 colormap = 'jet'
80 colormap = 'jet'
81
81
82 def update(self, dataOut):
82 def update(self, dataOut):
83
83
84 data = {
84 data = {
85 'dop': 10*numpy.log10(dataOut.data_dop)
85 'dop': 10*numpy.log10(dataOut.data_dop)
86 }
86 }
87
87
88 return data, {}
88 return data, {}
89
89
90 class PowerPlot(RTIPlot):
90 class PowerPlot(RTIPlot):
91 '''
91 '''
92 Plot for Power Data (0 moment)
92 Plot for Power Data (0 moment)
93 '''
93 '''
94
94
95 CODE = 'pow'
95 CODE = 'pow'
96 colormap = 'jet'
96 colormap = 'jet'
97
97
98 def update(self, dataOut):
98 def update(self, dataOut):
99 data = {
99 data = {
100 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
100 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
101 }
101 }
102 return data, {}
102 return data, {}
103
103
104 class SpectralWidthPlot(RTIPlot):
104 class SpectralWidthPlot(RTIPlot):
105 '''
105 '''
106 Plot for Spectral Width Data (2nd moment)
106 Plot for Spectral Width Data (2nd moment)
107 '''
107 '''
108
108
109 CODE = 'width'
109 CODE = 'width'
110 colormap = 'jet'
110 colormap = 'jet'
111
111
112 def update(self, dataOut):
112 def update(self, dataOut):
113
113
114 data = {
114 data = {
115 'width': dataOut.data_width
115 'width': dataOut.data_width
116 }
116 }
117
117
118 return data, {}
118 return data, {}
119
119
120 class SkyMapPlot(Plot):
120 class SkyMapPlot(Plot):
121 '''
121 '''
122 Plot for meteors detection data
122 Plot for meteors detection data
123 '''
123 '''
124
124
125 CODE = 'param'
125 CODE = 'param'
126
126
127 def setup(self):
127 def setup(self):
128
128
129 self.ncols = 1
129 self.ncols = 1
130 self.nrows = 1
130 self.nrows = 1
131 self.width = 7.2
131 self.width = 7.2
132 self.height = 7.2
132 self.height = 7.2
133 self.nplots = 1
133 self.nplots = 1
134 self.xlabel = 'Zonal Zenith Angle (deg)'
134 self.xlabel = 'Zonal Zenith Angle (deg)'
135 self.ylabel = 'Meridional Zenith Angle (deg)'
135 self.ylabel = 'Meridional Zenith Angle (deg)'
136 self.polar = True
136 self.polar = True
137 self.ymin = -180
137 self.ymin = -180
138 self.ymax = 180
138 self.ymax = 180
139 self.colorbar = False
139 self.colorbar = False
140
140
141 def plot(self):
141 def plot(self):
142
142
143 arrayParameters = numpy.concatenate(self.data['param'])
143 arrayParameters = numpy.concatenate(self.data['param'])
144 error = arrayParameters[:, -1]
144 error = arrayParameters[:, -1]
145 indValid = numpy.where(error == 0)[0]
145 indValid = numpy.where(error == 0)[0]
146 finalMeteor = arrayParameters[indValid, :]
146 finalMeteor = arrayParameters[indValid, :]
147 finalAzimuth = finalMeteor[:, 3]
147 finalAzimuth = finalMeteor[:, 3]
148 finalZenith = finalMeteor[:, 4]
148 finalZenith = finalMeteor[:, 4]
149
149
150 x = finalAzimuth * numpy.pi / 180
150 x = finalAzimuth * numpy.pi / 180
151 y = finalZenith
151 y = finalZenith
152
152
153 ax = self.axes[0]
153 ax = self.axes[0]
154
154
155 if ax.firsttime:
155 if ax.firsttime:
156 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
156 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
157 else:
157 else:
158 ax.plot.set_data(x, y)
158 ax.plot.set_data(x, y)
159
159
160 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
160 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
161 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
161 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
162 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
162 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
163 dt2,
163 dt2,
164 len(x))
164 len(x))
165 self.titles[0] = title
165 self.titles[0] = title
166
166
167
167
168 class GenericRTIPlot(Plot):
168 class GenericRTIPlot(Plot):
169 '''
169 '''
170 Plot for data_xxxx object
170 Plot for data_xxxx object
171 '''
171 '''
172
172
173 CODE = 'param'
173 CODE = 'param'
174 colormap = 'viridis'
174 colormap = 'viridis'
175 plot_type = 'pcolorbuffer'
175 plot_type = 'pcolorbuffer'
176
176
177 def setup(self):
177 def setup(self):
178 self.xaxis = 'time'
178 self.xaxis = 'time'
179 self.ncols = 1
179 self.ncols = 1
180 self.nrows = self.data.shape('param')[0]
180 self.nrows = self.data.shape('param')[0]
181 self.nplots = self.nrows
181 self.nplots = self.nrows
182 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
182 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
183
183
184 if not self.xlabel:
184 if not self.xlabel:
185 self.xlabel = 'Time'
185 self.xlabel = 'Time'
186
186
187 self.ylabel = 'Range [km]'
187 self.ylabel = 'Range [km]'
188 if not self.titles:
188 if not self.titles:
189 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
189 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
190
190
191 def update(self, dataOut):
191 def update(self, dataOut):
192
192
193 data = {
193 data = {
194 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
194 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
195 }
195 }
196
196
197 meta = {}
197 meta = {}
198
198
199 return data, meta
199 return data, meta
200
200
201 def plot(self):
201 def plot(self):
202 # self.data.normalize_heights()
202 # self.data.normalize_heights()
203 self.x = self.data.times
203 self.x = self.data.times
204 self.y = self.data.yrange
204 self.y = self.data.yrange
205 self.z = self.data['param']
205 self.z = self.data['param']
206 self.z = 10*numpy.log10(self.z)
206 self.z = 10*numpy.log10(self.z)
207 self.z = numpy.ma.masked_invalid(self.z)
207 self.z = numpy.ma.masked_invalid(self.z)
208
208
209 if self.decimation is None:
209 if self.decimation is None:
210 x, y, z = self.fill_gaps(self.x, self.y, self.z)
210 x, y, z = self.fill_gaps(self.x, self.y, self.z)
211 else:
211 else:
212 x, y, z = self.fill_gaps(*self.decimate())
212 x, y, z = self.fill_gaps(*self.decimate())
213
213
214 for n, ax in enumerate(self.axes):
214 for n, ax in enumerate(self.axes):
215
215
216 self.zmax = self.zmax if self.zmax is not None else numpy.max(
216 self.zmax = self.zmax if self.zmax is not None else numpy.max(
217 self.z[n])
217 self.z[n])
218 self.zmin = self.zmin if self.zmin is not None else numpy.min(
218 self.zmin = self.zmin if self.zmin is not None else numpy.min(
219 self.z[n])
219 self.z[n])
220
220
221 if ax.firsttime:
221 if ax.firsttime:
222 if self.zlimits is not None:
222 if self.zlimits is not None:
223 self.zmin, self.zmax = self.zlimits[n]
223 self.zmin, self.zmax = self.zlimits[n]
224
224
225 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
225 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
226 vmin=self.zmin,
226 vmin=self.zmin,
227 vmax=self.zmax,
227 vmax=self.zmax,
228 cmap=self.cmaps[n]
228 cmap=self.cmaps[n]
229 )
229 )
230 else:
230 else:
231 if self.zlimits is not None:
231 if self.zlimits is not None:
232 self.zmin, self.zmax = self.zlimits[n]
232 self.zmin, self.zmax = self.zlimits[n]
233 ax.collections.remove(ax.collections[0])
233 ax.collections.remove(ax.collections[0])
234 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
234 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
235 vmin=self.zmin,
235 vmin=self.zmin,
236 vmax=self.zmax,
236 vmax=self.zmax,
237 cmap=self.cmaps[n]
237 cmap=self.cmaps[n]
238 )
238 )
239
239
240
240
241 class PolarMapPlot(Plot):
241 class PolarMapPlot(Plot):
242 '''
242 '''
243 Plot for weather radar
243 Plot for weather radar
244 '''
244 '''
245
245
246 CODE = 'param'
246 CODE = 'param'
247 colormap = 'seismic'
247 colormap = 'seismic'
248
248
249 def setup(self):
249 def setup(self):
250 self.ncols = 1
250 self.ncols = 1
251 self.nrows = 1
251 self.nrows = 1
252 self.width = 9
252 self.width = 9
253 self.height = 8
253 self.height = 8
254 self.mode = self.data.meta['mode']
254 self.mode = self.data.meta['mode']
255 if self.channels is not None:
255 if self.channels is not None:
256 self.nplots = len(self.channels)
256 self.nplots = len(self.channels)
257 self.nrows = len(self.channels)
257 self.nrows = len(self.channels)
258 else:
258 else:
259 self.nplots = self.data.shape(self.CODE)[0]
259 self.nplots = self.data.shape(self.CODE)[0]
260 self.nrows = self.nplots
260 self.nrows = self.nplots
261 self.channels = list(range(self.nplots))
261 self.channels = list(range(self.nplots))
262 if self.mode == 'E':
262 if self.mode == 'E':
263 self.xlabel = 'Longitude'
263 self.xlabel = 'Longitude'
264 self.ylabel = 'Latitude'
264 self.ylabel = 'Latitude'
265 else:
265 else:
266 self.xlabel = 'Range (km)'
266 self.xlabel = 'Range (km)'
267 self.ylabel = 'Height (km)'
267 self.ylabel = 'Height (km)'
268 self.bgcolor = 'white'
268 self.bgcolor = 'white'
269 self.cb_labels = self.data.meta['units']
269 self.cb_labels = self.data.meta['units']
270 self.lat = self.data.meta['latitude']
270 self.lat = self.data.meta['latitude']
271 self.lon = self.data.meta['longitude']
271 self.lon = self.data.meta['longitude']
272 self.xmin, self.xmax = float(
272 self.xmin, self.xmax = float(
273 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
273 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
274 self.ymin, self.ymax = float(
274 self.ymin, self.ymax = float(
275 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
275 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
276 # self.polar = True
276 # self.polar = True
277
277
278 def plot(self):
278 def plot(self):
279
279
280 for n, ax in enumerate(self.axes):
280 for n, ax in enumerate(self.axes):
281 data = self.data['param'][self.channels[n]]
281 data = self.data['param'][self.channels[n]]
282
282
283 zeniths = numpy.linspace(
283 zeniths = numpy.linspace(
284 0, self.data.meta['max_range'], data.shape[1])
284 0, self.data.meta['max_range'], data.shape[1])
285 if self.mode == 'E':
285 if self.mode == 'E':
286 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
286 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
287 r, theta = numpy.meshgrid(zeniths, azimuths)
287 r, theta = numpy.meshgrid(zeniths, azimuths)
288 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
288 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
289 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
289 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
290 x = km2deg(x) + self.lon
290 x = km2deg(x) + self.lon
291 y = km2deg(y) + self.lat
291 y = km2deg(y) + self.lat
292 else:
292 else:
293 azimuths = numpy.radians(self.data.yrange)
293 azimuths = numpy.radians(self.data.yrange)
294 r, theta = numpy.meshgrid(zeniths, azimuths)
294 r, theta = numpy.meshgrid(zeniths, azimuths)
295 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
295 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
296 self.y = zeniths
296 self.y = zeniths
297
297
298 if ax.firsttime:
298 if ax.firsttime:
299 if self.zlimits is not None:
299 if self.zlimits is not None:
300 self.zmin, self.zmax = self.zlimits[n]
300 self.zmin, self.zmax = self.zlimits[n]
301 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
301 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
302 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
302 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
303 vmin=self.zmin,
303 vmin=self.zmin,
304 vmax=self.zmax,
304 vmax=self.zmax,
305 cmap=self.cmaps[n])
305 cmap=self.cmaps[n])
306 else:
306 else:
307 if self.zlimits is not None:
307 if self.zlimits is not None:
308 self.zmin, self.zmax = self.zlimits[n]
308 self.zmin, self.zmax = self.zlimits[n]
309 ax.collections.remove(ax.collections[0])
309 ax.collections.remove(ax.collections[0])
310 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
310 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
311 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
311 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
312 vmin=self.zmin,
312 vmin=self.zmin,
313 vmax=self.zmax,
313 vmax=self.zmax,
314 cmap=self.cmaps[n])
314 cmap=self.cmaps[n])
315
315
316 if self.mode == 'A':
316 if self.mode == 'A':
317 continue
317 continue
318
318
319 # plot district names
319 # plot district names
320 f = open('/data/workspace/schain_scripts/distrito.csv')
320 f = open('/data/workspace/schain_scripts/distrito.csv')
321 for line in f:
321 for line in f:
322 label, lon, lat = [s.strip() for s in line.split(',') if s]
322 label, lon, lat = [s.strip() for s in line.split(',') if s]
323 lat = float(lat)
323 lat = float(lat)
324 lon = float(lon)
324 lon = float(lon)
325 # ax.plot(lon, lat, '.b', ms=2)
325 # ax.plot(lon, lat, '.b', ms=2)
326 ax.text(lon, lat, label.decode('utf8'), ha='center',
326 ax.text(lon, lat, label.decode('utf8'), ha='center',
327 va='bottom', size='8', color='black')
327 va='bottom', size='8', color='black')
328
328
329 # plot limites
329 # plot limites
330 limites = []
330 limites = []
331 tmp = []
331 tmp = []
332 for line in open('/data/workspace/schain_scripts/lima.csv'):
332 for line in open('/data/workspace/schain_scripts/lima.csv'):
333 if '#' in line:
333 if '#' in line:
334 if tmp:
334 if tmp:
335 limites.append(tmp)
335 limites.append(tmp)
336 tmp = []
336 tmp = []
337 continue
337 continue
338 values = line.strip().split(',')
338 values = line.strip().split(',')
339 tmp.append((float(values[0]), float(values[1])))
339 tmp.append((float(values[0]), float(values[1])))
340 for points in limites:
340 for points in limites:
341 ax.add_patch(
341 ax.add_patch(
342 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
342 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
343
343
344 # plot Cuencas
344 # plot Cuencas
345 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
345 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
346 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
346 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
347 values = [line.strip().split(',') for line in f]
347 values = [line.strip().split(',') for line in f]
348 points = [(float(s[0]), float(s[1])) for s in values]
348 points = [(float(s[0]), float(s[1])) for s in values]
349 ax.add_patch(Polygon(points, ec='b', fc='none'))
349 ax.add_patch(Polygon(points, ec='b', fc='none'))
350
350
351 # plot grid
351 # plot grid
352 for r in (15, 30, 45, 60):
352 for r in (15, 30, 45, 60):
353 ax.add_artist(plt.Circle((self.lon, self.lat),
353 ax.add_artist(plt.Circle((self.lon, self.lat),
354 km2deg(r), color='0.6', fill=False, lw=0.2))
354 km2deg(r), color='0.6', fill=False, lw=0.2))
355 ax.text(
355 ax.text(
356 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
356 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
357 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
357 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
358 '{}km'.format(r),
358 '{}km'.format(r),
359 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
359 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
360
360
361 if self.mode == 'E':
361 if self.mode == 'E':
362 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
362 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
363 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
363 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
364 else:
364 else:
365 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
365 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
366 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
366 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
367
367
368 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
368 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
369 self.titles = ['{} {}'.format(
369 self.titles = ['{} {}'.format(
370 self.data.parameters[x], title) for x in self.channels]
370 self.data.parameters[x], title) for x in self.channels]
371
371
372 class WeatherPlot(Plot):
373 CODE = 'weather'
374 plot_name = 'weather'
375 plot_type = 'ppistyle'
376 buffering = False
377
378 def setup(self):
379 self.ncols = 1
380 self.nrows = 1
381 self.width =8
382 self.height =8
383 self.nplots= 1
384 self.ylabel= 'Range [Km]'
385 self.titles= ['Weather']
386 self.colorbar=False
387 self.ini =0
388 self.len_azi =0
389 self.buffer_ini = None
390 self.buffer_azi = None
391 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
392 self.flag =0
393 self.indicador= 0
394 self.last_data_azi = None
395 self.val_mean = None
396
397 def update(self, dataOut):
398
399 data = {}
400 meta = {}
401 if hasattr(dataOut, 'dataPP_POWER'):
402 factor = 1
403 if hasattr(dataOut, 'nFFTPoints'):
404 factor = dataOut.normFactor
405 #print("DIME EL SHAPE PORFAVOR",dataOut.data_360.shape)
406 data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
407 data['azi'] = dataOut.data_azi
408 data['ele'] = dataOut.data_ele
409 return data, meta
410
411 def get2List(self,angulos):
412 list1=[]
413 list2=[]
414 for i in reversed(range(len(angulos))):
415 diff_ = angulos[i]-angulos[i-1]
416 if diff_ >1.5:
417 list1.append(i-1)
418 list2.append(diff_)
419 return list(reversed(list1)),list(reversed(list2))
420
421 def fixData360(self,list_,ang_):
422 if list_[0]==-1:
423 vec = numpy.where(ang_<ang_[0])
424 ang_[vec] = ang_[vec]+360
425 return ang_
426 return ang_
427
428 def fixData360HL(self,angulos):
429 vec = numpy.where(angulos>=360)
430 angulos[vec]=angulos[vec]-360
431 return angulos
432
433 def search_pos(self,pos,list_):
434 for i in range(len(list_)):
435 if pos == list_[i]:
436 return True,i
437 i=None
438 return False,i
439
440 def fixDataComp(self,ang_,list1_,list2_):
441 size = len(ang_)
442 size2 = 0
443 for i in range(len(list2_)):
444 size2=size2+round(list2_[i])-1
445 new_size= size+size2
446 ang_new = numpy.zeros(new_size)
447 ang_new2 = numpy.zeros(new_size)
448
449 tmp = 0
450 c = 0
451 for i in range(len(ang_)):
452 ang_new[tmp +c] = ang_[i]
453 ang_new2[tmp+c] = ang_[i]
454 condition , value = self.search_pos(i,list1_)
455 if condition:
456 pos = tmp + c + 1
457 for k in range(round(list2_[value])-1):
458 ang_new[pos+k] = ang_new[pos+k-1]+1
459 ang_new2[pos+k] = numpy.nan
460 tmp = pos +k
461 c = 0
462 c=c+1
463 return ang_new,ang_new2
464
465 def globalCheckPED(self,angulos):
466 l1,l2 = self.get2List(angulos)
467 if len(l1)>0:
468 angulos2 = self.fixData360(list_=l1,ang_=angulos)
469 l1,l2 = self.get2List(angulos2)
470
471 ang1_,ang2_ = self.fixDataComp(ang_=angulos2,list1_=l1,list2_=l2)
472 ang1_ = self.fixData360HL(ang1_)
473 ang2_ = self.fixData360HL(ang2_)
474 else:
475 ang1_= angulos
476 ang2_= angulos
477 return ang1_,ang2_
478
479 def analizeDATA(self,data_azi):
480 list1 = []
481 list2 = []
482 dat = data_azi
483 for i in reversed(range(1,len(dat))):
484 if dat[i]>dat[i-1]:
485 diff = int(dat[i])-int(dat[i-1])
486 else:
487 diff = 360+int(dat[i])-int(dat[i-1])
488 if diff > 1:
489 list1.append(i-1)
490 list2.append(diff-1)
491 return list1,list2
492
493 def fixDATANEW(self,data_azi,data_weather):
494 list1,list2 = self.analizeDATA(data_azi)
495 if len(list1)== 0:
496 return data_azi,data_weather
497 else:
498 resize = 0
499 for i in range(len(list2)):
500 resize= resize + list2[i]
501 new_data_azi = numpy.resize(data_azi,resize)
502 new_data_weather= numpy.resize(date_weather,resize)
503
504 for i in range(len(list2)):
505 j=0
506 position=list1[i]+1
507 for j in range(list2[i]):
508 new_data_azi[position+j]=new_data_azi[position+j-1]+1
509 return new_data_azi
510
511 def fixDATA(self,data_azi):
512 data=data_azi
513 for i in range(len(data)):
514 if numpy.isnan(data[i]):
515 data[i]=data[i-1]+1
516 return data
517
518 def replaceNAN(self,data_weather,data_azi,val):
519 data= data_azi
520 data_T= data_weather
521 if data.shape[0]> data_T.shape[0]:
522 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
523 c = 0
524 for i in range(len(data)):
525 if numpy.isnan(data[i]):
526 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
527 else:
528 data_N[i,:]=data_T[c,:]
529 c=c+1
530 return data_N
531 else:
532 for i in range(len(data)):
533 if numpy.isnan(data[i]):
534 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
535 return data_T
536
537 def const_ploteo(self,data_weather,data_azi,step,res):
538 if self.ini==0:
539 #-------
540 n = (360/res)-len(data_azi)
541 #--------------------- new -------------------------
542 data_azi_new ,data_azi_old= self.globalCheckPED(data_azi)
543 #------------------------
544 start = data_azi_new[-1] + res
545 end = data_azi_new[0] - res
546 #------ new
547 self.last_data_azi = end
548 if start>end:
549 end = end + 360
550 azi_vacia = numpy.linspace(start,end,int(n))
551 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
552 data_azi = numpy.hstack((data_azi_new,azi_vacia))
553 # RADAR
554 val_mean = numpy.mean(data_weather[:,-1])
555 self.val_mean = val_mean
556 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*val_mean
557 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
558 data_weather = numpy.vstack((data_weather,data_weather_cmp))
559 else:
560 # azimuth
561 flag=0
562 start_azi = self.res_azi[0]
563 #-----------new------------
564 data_azi ,data_azi_old= self.globalCheckPED(data_azi)
565 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
566 #--------------------------
567 start = data_azi[0]
568 end = data_azi[-1]
569 self.last_data_azi= end
570 if start< start_azi:
571 start = start +360
572 if end <start_azi:
573 end = end +360
574
575 pos_ini = int((start-start_azi)/res)
576 len_azi = len(data_azi)
577 if (360-pos_ini)<len_azi:
578 if pos_ini+1==360:
579 pos_ini=0
580 else:
581 flag=1
582 dif= 360-pos_ini
583 comp= len_azi-dif
584 #-----------------
585 if flag==0:
586 # AZIMUTH
587 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
588 # RADAR
589 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
590 else:
591 # AZIMUTH
592 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
593 self.res_azi[0:comp] = data_azi[dif:]
594 # RADAR
595 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
596 self.res_weather[0:comp,:] = data_weather[dif:,:]
597 flag=0
598 data_azi = self.res_azi
599 data_weather = self.res_weather
600
601 return data_weather,data_azi
602
603 def plot(self):
604 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
605 data = self.data[-1]
606 r = self.data.yrange
607 delta_height = r[1]-r[0]
608 r_mask = numpy.where(r>=0)[0]
609 r = numpy.arange(len(r_mask))*delta_height
610 self.y = 2*r
611 # RADAR
612 #data_weather = data['weather']
613 # PEDESTAL
614 #data_azi = data['azi']
615 res = 1
616 # STEP
617 step = (360/(res*data['weather'].shape[0]))
618
619 self.res_weather, self.res_azi = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_azi=data['azi'],step=step,res=res)
620 self.res_ele = numpy.mean(data['ele'])
621 ################# PLOTEO ###################
622 for i,ax in enumerate(self.axes):
623 self.zmin = self.zmin if self.zmin else 20
624 self.zmax = self.zmax if self.zmax else 80
625 if ax.firsttime:
626 plt.clf()
627 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=self.zmin, vmax=self.zmax)
628 else:
629 plt.clf()
630 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=self.zmin, vmax=self.zmax)
631 caax = cgax.parasites[0]
632 paax = cgax.parasites[1]
633 cbar = plt.gcf().colorbar(pm, pad=0.075)
634 caax.set_xlabel('x_range [km]')
635 caax.set_ylabel('y_range [km]')
636 plt.text(1.0, 1.05, 'Azimuth '+str(thisDatetime)+" Step "+str(self.ini)+ " EL: "+str(round(self.res_ele, 1)), transform=caax.transAxes, va='bottom',ha='right')
637
638 self.ini= self.ini+1
639
640
641 class WeatherRHIPlot(Plot):
642 CODE = 'weather'
643 plot_name = 'weather'
644 plot_type = 'rhistyle'
645 buffering = False
646 data_ele_tmp = None
647
648 def setup(self):
649 print("********************")
650 print("********************")
651 print("********************")
652 print("SETUP WEATHER PLOT")
653 self.ncols = 1
654 self.nrows = 1
655 self.nplots= 1
656 self.ylabel= 'Range [Km]'
657 self.titles= ['Weather']
658 if self.channels is not None:
659 self.nplots = len(self.channels)
660 self.nrows = len(self.channels)
661 else:
662 self.nplots = self.data.shape(self.CODE)[0]
663 self.nrows = self.nplots
664 self.channels = list(range(self.nplots))
665 print("channels",self.channels)
666 print("que saldra", self.data.shape(self.CODE)[0])
667 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
668 print("self.titles",self.titles)
669 self.colorbar=False
670 self.width =12
671 self.height =8
672 self.ini =0
673 self.len_azi =0
674 self.buffer_ini = None
675 self.buffer_ele = None
676 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
677 self.flag =0
678 self.indicador= 0
679 self.last_data_ele = None
680 self.val_mean = None
681
682 def update(self, dataOut):
683
684 data = {}
685 meta = {}
686 if hasattr(dataOut, 'dataPP_POWER'):
687 factor = 1
688 if hasattr(dataOut, 'nFFTPoints'):
689 factor = dataOut.normFactor
690 print("dataOut",dataOut.data_360.shape)
691 #
692 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
693 #
694 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
695 data['azi'] = dataOut.data_azi
696 data['ele'] = dataOut.data_ele
697 #print("UPDATE")
698 #print("data[weather]",data['weather'].shape)
699 #print("data[azi]",data['azi'])
700 return data, meta
701
702 def get2List(self,angulos):
703 list1=[]
704 list2=[]
705 for i in reversed(range(len(angulos))):
706 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
707 diff_ = angulos[i]-angulos[i-1]
708 if abs(diff_) >1.5:
709 list1.append(i-1)
710 list2.append(diff_)
711 return list(reversed(list1)),list(reversed(list2))
712
713 def fixData90(self,list_,ang_):
714 if list_[0]==-1:
715 vec = numpy.where(ang_<ang_[0])
716 ang_[vec] = ang_[vec]+90
717 return ang_
718 return ang_
719
720 def fixData90HL(self,angulos):
721 vec = numpy.where(angulos>=90)
722 angulos[vec]=angulos[vec]-90
723 return angulos
724
725
726 def search_pos(self,pos,list_):
727 for i in range(len(list_)):
728 if pos == list_[i]:
729 return True,i
730 i=None
731 return False,i
732
733 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
734 size = len(ang_)
735 size2 = 0
736 for i in range(len(list2_)):
737 size2=size2+round(abs(list2_[i]))-1
738 new_size= size+size2
739 ang_new = numpy.zeros(new_size)
740 ang_new2 = numpy.zeros(new_size)
741
742 tmp = 0
743 c = 0
744 for i in range(len(ang_)):
745 ang_new[tmp +c] = ang_[i]
746 ang_new2[tmp+c] = ang_[i]
747 condition , value = self.search_pos(i,list1_)
748 if condition:
749 pos = tmp + c + 1
750 for k in range(round(abs(list2_[value]))-1):
751 if tipo_case==0 or tipo_case==3:#subida
752 ang_new[pos+k] = ang_new[pos+k-1]+1
753 ang_new2[pos+k] = numpy.nan
754 elif tipo_case==1 or tipo_case==2:#bajada
755 ang_new[pos+k] = ang_new[pos+k-1]-1
756 ang_new2[pos+k] = numpy.nan
757
758 tmp = pos +k
759 c = 0
760 c=c+1
761 return ang_new,ang_new2
762
763 def globalCheckPED(self,angulos,tipo_case):
764 l1,l2 = self.get2List(angulos)
765 ##print("l1",l1)
766 ##print("l2",l2)
767 if len(l1)>0:
768 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
769 #l1,l2 = self.get2List(angulos2)
770 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
771 #ang1_ = self.fixData90HL(ang1_)
772 #ang2_ = self.fixData90HL(ang2_)
773 else:
774 ang1_= angulos
775 ang2_= angulos
776 return ang1_,ang2_
777
778
779 def replaceNAN(self,data_weather,data_ele,val):
780 data= data_ele
781 data_T= data_weather
782 if data.shape[0]> data_T.shape[0]:
783 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
784 c = 0
785 for i in range(len(data)):
786 if numpy.isnan(data[i]):
787 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
788 else:
789 data_N[i,:]=data_T[c,:]
790 c=c+1
791 return data_N
792 else:
793 for i in range(len(data)):
794 if numpy.isnan(data[i]):
795 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
796 return data_T
797
798 def check_case(self,data_ele,ang_max,ang_min):
799 start = data_ele[0]
800 end = data_ele[-1]
801 number = (end-start)
802 len_ang=len(data_ele)
803 print("start",start)
804 print("end",end)
805 print("number",number)
806
807 print("len_ang",len_ang)
808
809 #exit(1)
810
811 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
812 return 0
813 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
814 # return 1
815 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
816 return 1
817 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
818 return 2
819 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
820 return 3
821
822
823 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min):
824 ang_max= ang_max
825 ang_min= ang_min
826 data_weather=data_weather
827 val_ch=val_ch
828 ##print("*********************DATA WEATHER**************************************")
829 ##print(data_weather)
830 if self.ini==0:
831 '''
832 print("**********************************************")
833 print("**********************************************")
834 print("***************ini**************")
835 print("**********************************************")
836 print("**********************************************")
837 '''
838 #print("data_ele",data_ele)
839 #----------------------------------------------------------
840 tipo_case = self.check_case(data_ele,ang_max,ang_min)
841 print("check_case",tipo_case)
842 #exit(1)
843 #--------------------- new -------------------------
844 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
845
846 #-------------------------CAMBIOS RHI---------------------------------
847 start= ang_min
848 end = ang_max
849 n= (ang_max-ang_min)/res
850 #------ new
851 self.start_data_ele = data_ele_new[0]
852 self.end_data_ele = data_ele_new[-1]
853 if tipo_case==0 or tipo_case==3: # SUBIDA
854 n1= round(self.start_data_ele)- start
855 n2= end - round(self.end_data_ele)
856 print(self.start_data_ele)
857 print(self.end_data_ele)
858 if n1>0:
859 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
860 ele1_nan= numpy.ones(n1)*numpy.nan
861 data_ele = numpy.hstack((ele1,data_ele_new))
862 print("ele1_nan",ele1_nan.shape)
863 print("data_ele_old",data_ele_old.shape)
864 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
865 if n2>0:
866 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
867 ele2_nan= numpy.ones(n2)*numpy.nan
868 data_ele = numpy.hstack((data_ele,ele2))
869 print("ele2_nan",ele2_nan.shape)
870 print("data_ele_old",data_ele_old.shape)
871 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
872
873 if tipo_case==1 or tipo_case==2: # BAJADA
874 data_ele_new = data_ele_new[::-1] # reversa
875 data_ele_old = data_ele_old[::-1]# reversa
876 data_weather = data_weather[::-1,:]# reversa
877 vec= numpy.where(data_ele_new<ang_max)
878 data_ele_new = data_ele_new[vec]
879 data_ele_old = data_ele_old[vec]
880 data_weather = data_weather[vec[0]]
881 vec2= numpy.where(0<data_ele_new)
882 data_ele_new = data_ele_new[vec2]
883 data_ele_old = data_ele_old[vec2]
884 data_weather = data_weather[vec2[0]]
885 self.start_data_ele = data_ele_new[0]
886 self.end_data_ele = data_ele_new[-1]
887
888 n1= round(self.start_data_ele)- start
889 n2= end - round(self.end_data_ele)-1
890 print(self.start_data_ele)
891 print(self.end_data_ele)
892 if n1>0:
893 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
894 ele1_nan= numpy.ones(n1)*numpy.nan
895 data_ele = numpy.hstack((ele1,data_ele_new))
896 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
897 if n2>0:
898 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
899 ele2_nan= numpy.ones(n2)*numpy.nan
900 data_ele = numpy.hstack((data_ele,ele2))
901 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
902 # RADAR
903 # NOTA data_ele y data_weather es la variable que retorna
904 val_mean = numpy.mean(data_weather[:,-1])
905 self.val_mean = val_mean
906 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
907 self.data_ele_tmp[val_ch]= data_ele_old
908 else:
909 #print("**********************************************")
910 #print("****************VARIABLE**********************")
911 #-------------------------CAMBIOS RHI---------------------------------
912 #---------------------------------------------------------------------
913 ##print("INPUT data_ele",data_ele)
914 flag=0
915 start_ele = self.res_ele[0]
916 tipo_case = self.check_case(data_ele,ang_max,ang_min)
917 #print("TIPO DE DATA",tipo_case)
918 #-----------new------------
919 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
920 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
921
922 #-------------------------------NEW RHI ITERATIVO-------------------------
923
924 if tipo_case==0 : # SUBIDA
925 vec = numpy.where(data_ele<ang_max)
926 data_ele = data_ele[vec]
927 data_ele_old = data_ele_old[vec]
928 data_weather = data_weather[vec[0]]
929
930 vec2 = numpy.where(0<data_ele)
931 data_ele= data_ele[vec2]
932 data_ele_old= data_ele_old[vec2]
933 ##print(data_ele_new)
934 data_weather= data_weather[vec2[0]]
935
936 new_i_ele = int(round(data_ele[0]))
937 new_f_ele = int(round(data_ele[-1]))
938 #print(new_i_ele)
939 #print(new_f_ele)
940 #print(data_ele,len(data_ele))
941 #print(data_ele_old,len(data_ele_old))
942 if new_i_ele< 2:
943 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
944 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
945 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
946 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
947 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
948 data_ele = self.res_ele
949 data_weather = self.res_weather[val_ch]
950
951 elif tipo_case==1 : #BAJADA
952 data_ele = data_ele[::-1] # reversa
953 data_ele_old = data_ele_old[::-1]# reversa
954 data_weather = data_weather[::-1,:]# reversa
955 vec= numpy.where(data_ele<ang_max)
956 data_ele = data_ele[vec]
957 data_ele_old = data_ele_old[vec]
958 data_weather = data_weather[vec[0]]
959 vec2= numpy.where(0<data_ele)
960 data_ele = data_ele[vec2]
961 data_ele_old = data_ele_old[vec2]
962 data_weather = data_weather[vec2[0]]
963
964
965 new_i_ele = int(round(data_ele[0]))
966 new_f_ele = int(round(data_ele[-1]))
967 #print(data_ele)
968 #print(ang_max)
969 #print(data_ele_old)
970 if new_i_ele <= 1:
971 new_i_ele = 1
972 if round(data_ele[-1])>=ang_max-1:
973 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
974 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
975 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
976 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
977 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
978 data_ele = self.res_ele
979 data_weather = self.res_weather[val_ch]
980
981 elif tipo_case==2: #bajada
982 vec = numpy.where(data_ele<ang_max)
983 data_ele = data_ele[vec]
984 data_weather= data_weather[vec[0]]
985
986 len_vec = len(vec)
987 data_ele_new = data_ele[::-1] # reversa
988 data_weather = data_weather[::-1,:]
989 new_i_ele = int(data_ele_new[0])
990 new_f_ele = int(data_ele_new[-1])
991
992 n1= new_i_ele- ang_min
993 n2= ang_max - new_f_ele-1
994 if n1>0:
995 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
996 ele1_nan= numpy.ones(n1)*numpy.nan
997 data_ele = numpy.hstack((ele1,data_ele_new))
998 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
999 if n2>0:
1000 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1001 ele2_nan= numpy.ones(n2)*numpy.nan
1002 data_ele = numpy.hstack((data_ele,ele2))
1003 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1004
1005 self.data_ele_tmp[val_ch] = data_ele_old
1006 self.res_ele = data_ele
1007 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1008 data_ele = self.res_ele
1009 data_weather = self.res_weather[val_ch]
1010
1011 elif tipo_case==3:#subida
1012 vec = numpy.where(0<data_ele)
1013 data_ele= data_ele[vec]
1014 data_ele_new = data_ele
1015 data_ele_old= data_ele_old[vec]
1016 data_weather= data_weather[vec[0]]
1017 pos_ini = numpy.argmin(data_ele)
1018 if pos_ini>0:
1019 len_vec= len(data_ele)
1020 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1021 #print(vec3)
1022 data_ele= data_ele[vec3]
1023 data_ele_new = data_ele
1024 data_ele_old= data_ele_old[vec3]
1025 data_weather= data_weather[vec3]
1026
1027 new_i_ele = int(data_ele_new[0])
1028 new_f_ele = int(data_ele_new[-1])
1029 n1= new_i_ele- ang_min
1030 n2= ang_max - new_f_ele-1
1031 if n1>0:
1032 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1033 ele1_nan= numpy.ones(n1)*numpy.nan
1034 data_ele = numpy.hstack((ele1,data_ele_new))
1035 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1036 if n2>0:
1037 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1038 ele2_nan= numpy.ones(n2)*numpy.nan
1039 data_ele = numpy.hstack((data_ele,ele2))
1040 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1041
1042 self.data_ele_tmp[val_ch] = data_ele_old
1043 self.res_ele = data_ele
1044 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1045 data_ele = self.res_ele
1046 data_weather = self.res_weather[val_ch]
1047 #print("self.data_ele_tmp",self.data_ele_tmp)
1048 return data_weather,data_ele
1049
1050
1051 def plot(self):
1052 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1053 data = self.data[-1]
1054 r = self.data.yrange
1055 delta_height = r[1]-r[0]
1056 r_mask = numpy.where(r>=0)[0]
1057 ##print("delta_height",delta_height)
1058 #print("r_mask",r_mask,len(r_mask))
1059 r = numpy.arange(len(r_mask))*delta_height
1060 self.y = 2*r
1061 res = 1
1062 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1063 ang_max = self.ang_max
1064 ang_min = self.ang_min
1065 var_ang =ang_max - ang_min
1066 step = (int(var_ang)/(res*data['weather'].shape[0]))
1067 ###print("step",step)
1068 #--------------------------------------------------------
1069 ##print('weather',data['weather'].shape)
1070 ##print('ele',data['ele'].shape)
1071
1072 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1073 ###self.res_azi = numpy.mean(data['azi'])
1074 ###print("self.res_ele",self.res_ele)
1075 plt.clf()
1076 subplots = [121, 122]
1077 cg={'angular_spacing': 20.}
1078 if self.ini==0:
1079 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1080 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1081 print("SHAPE",self.data_ele_tmp.shape)
1082
1083 for i,ax in enumerate(self.axes):
1084 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1085 self.res_azi = numpy.mean(data['azi'])
1086 if i==0:
1087 print("*****************************************************************************to plot**************************",self.res_weather[i].shape)
1088 self.zmin = self.zmin if self.zmin else 20
1089 self.zmax = self.zmax if self.zmax else 80
1090 if ax.firsttime:
1091 #plt.clf()
1092 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj=cg,vmin=self.zmin, vmax=self.zmax)
1093 #fig=self.figures[0]
1094 else:
1095 #plt.clf()
1096 if i==0:
1097 print(self.res_weather[i])
1098 print(self.res_ele)
1099 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj=cg,vmin=self.zmin, vmax=self.zmax)
1100 caax = cgax.parasites[0]
1101 paax = cgax.parasites[1]
1102 cbar = plt.gcf().colorbar(pm, pad=0.075)
1103 caax.set_xlabel('x_range [km]')
1104 caax.set_ylabel('y_range [km]')
1105 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1106 print("***************************self.ini****************************",self.ini)
1107 self.ini= self.ini+1
1108
1109 class Weather_vRF_Plot(Plot):
1110 CODE = 'PPI'
1111 plot_name = 'PPI'
1112 #plot_type = 'ppistyle'
1113 buffering = False
1114
1115 def setup(self):
1116
1117 self.ncols = 1
1118 self.nrows = 1
1119 self.width =8
1120 self.height =8
1121 self.nplots= 1
1122 self.ylabel= 'Range [Km]'
1123 self.xlabel= 'Range [Km]'
1124 self.titles= ['PPI']
1125 self.polar = True
1126 if self.channels is not None:
1127 self.nplots = len(self.channels)
1128 self.nrows = len(self.channels)
1129 else:
1130 self.nplots = self.data.shape(self.CODE)[0]
1131 self.nrows = self.nplots
1132 self.channels = list(range(self.nplots))
1133
1134 if self.CODE == 'POWER':
1135 self.cb_label = r'Power (dB)'
1136 elif self.CODE == 'DOPPLER':
1137 self.cb_label = r'Velocity (m/s)'
1138 self.colorbar=True
1139 self.width = 9
1140 self.height =8
1141 self.ini =0
1142 self.len_azi =0
1143 self.buffer_ini = None
1144 self.buffer_ele = None
1145 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.15, 'right': 0.9, 'bottom': 0.08})
1146 self.flag =0
1147 self.indicador= 0
1148 self.last_data_ele = None
1149 self.val_mean = None
1150
1151 def update(self, dataOut):
1152
1153 data = {}
1154 meta = {}
1155 if hasattr(dataOut, 'dataPP_POWER'):
1156 factor = 1
1157 if hasattr(dataOut, 'nFFTPoints'):
1158 factor = dataOut.normFactor
1159
1160 if 'pow' in self.attr_data[0].lower():
1161 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1162 else:
1163 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1164
1165 data['azi'] = dataOut.data_azi
1166 data['ele'] = dataOut.data_ele
1167
1168 return data, meta
1169
1170 def plot(self):
1171 data = self.data[-1]
1172 r = self.data.yrange
1173 delta_height = r[1]-r[0]
1174 r_mask = numpy.where(r>=0)[0]
1175 self.r_mask = r_mask
1176 r = numpy.arange(len(r_mask))*delta_height
1177 self.y = 2*r
1178
1179 try:
1180 z = data['data'][self.channels[0]][:,r_mask]
1181
1182 except:
1183 z = data['data'][0][:,r_mask]
1184
1185 self.titles = []
1186
1187 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1188 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1189 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1190 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1191 self.ang_min = self.ang_min if self.ang_min else 0
1192 self.ang_max = self.ang_max if self.ang_max else 360
1193
1194 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1195
1196 for i,ax in enumerate(self.axes):
1197
1198 if ax.firsttime:
1199 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1200 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1201 ax.set_theta_direction(-1)
1202
1203 else:
1204 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1205 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1206 ax.set_theta_direction(-1)
1207
1208 ax.grid(True)
1209
1210 if len(self.channels) !=1:
1211 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.self.labels[x], str(round(numpy.mean(data['ele']),1)), x) for x in range(self.nrows)]
1212 else:
1213 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['ele']),1)), self.channels[0])]
1214
1215 class WeatherRHI_vRF2_Plot(Plot):
1216 CODE = 'weather'
1217 plot_name = 'weather'
1218 plot_type = 'rhistyle'
1219 buffering = False
1220 data_ele_tmp = None
1221
1222 def setup(self):
1223 print("********************")
1224 print("********************")
1225 print("********************")
1226 print("SETUP WEATHER PLOT")
1227 self.ncols = 1
1228 self.nrows = 1
1229 self.nplots= 1
1230 self.ylabel= 'Range [Km]'
1231 self.titles= ['Weather']
1232 if self.channels is not None:
1233 self.nplots = len(self.channels)
1234 self.nrows = len(self.channels)
1235 else:
1236 self.nplots = self.data.shape(self.CODE)[0]
1237 self.nrows = self.nplots
1238 self.channels = list(range(self.nplots))
1239 print("channels",self.channels)
1240 print("que saldra", self.data.shape(self.CODE)[0])
1241 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1242 print("self.titles",self.titles)
1243 self.colorbar=False
1244 self.width =8
1245 self.height =8
1246 self.ini =0
1247 self.len_azi =0
1248 self.buffer_ini = None
1249 self.buffer_ele = None
1250 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1251 self.flag =0
1252 self.indicador= 0
1253 self.last_data_ele = None
1254 self.val_mean = None
1255
1256 def update(self, dataOut):
1257
1258 data = {}
1259 meta = {}
1260 if hasattr(dataOut, 'dataPP_POWER'):
1261 factor = 1
1262 if hasattr(dataOut, 'nFFTPoints'):
1263 factor = dataOut.normFactor
1264 print("dataOut",dataOut.data_360.shape)
1265 #
1266 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1267 #
1268 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1269 data['azi'] = dataOut.data_azi
1270 data['ele'] = dataOut.data_ele
1271 data['case_flag'] = dataOut.case_flag
1272 #print("UPDATE")
1273 #print("data[weather]",data['weather'].shape)
1274 #print("data[azi]",data['azi'])
1275 return data, meta
1276
1277 def get2List(self,angulos):
1278 list1=[]
1279 list2=[]
1280 for i in reversed(range(len(angulos))):
1281 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1282 diff_ = angulos[i]-angulos[i-1]
1283 if abs(diff_) >1.5:
1284 list1.append(i-1)
1285 list2.append(diff_)
1286 return list(reversed(list1)),list(reversed(list2))
1287
1288 def fixData90(self,list_,ang_):
1289 if list_[0]==-1:
1290 vec = numpy.where(ang_<ang_[0])
1291 ang_[vec] = ang_[vec]+90
1292 return ang_
1293 return ang_
1294
1295 def fixData90HL(self,angulos):
1296 vec = numpy.where(angulos>=90)
1297 angulos[vec]=angulos[vec]-90
1298 return angulos
1299
1300
1301 def search_pos(self,pos,list_):
1302 for i in range(len(list_)):
1303 if pos == list_[i]:
1304 return True,i
1305 i=None
1306 return False,i
1307
1308 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1309 size = len(ang_)
1310 size2 = 0
1311 for i in range(len(list2_)):
1312 size2=size2+round(abs(list2_[i]))-1
1313 new_size= size+size2
1314 ang_new = numpy.zeros(new_size)
1315 ang_new2 = numpy.zeros(new_size)
1316
1317 tmp = 0
1318 c = 0
1319 for i in range(len(ang_)):
1320 ang_new[tmp +c] = ang_[i]
1321 ang_new2[tmp+c] = ang_[i]
1322 condition , value = self.search_pos(i,list1_)
1323 if condition:
1324 pos = tmp + c + 1
1325 for k in range(round(abs(list2_[value]))-1):
1326 if tipo_case==0 or tipo_case==3:#subida
1327 ang_new[pos+k] = ang_new[pos+k-1]+1
1328 ang_new2[pos+k] = numpy.nan
1329 elif tipo_case==1 or tipo_case==2:#bajada
1330 ang_new[pos+k] = ang_new[pos+k-1]-1
1331 ang_new2[pos+k] = numpy.nan
1332
1333 tmp = pos +k
1334 c = 0
1335 c=c+1
1336 return ang_new,ang_new2
1337
1338 def globalCheckPED(self,angulos,tipo_case):
1339 l1,l2 = self.get2List(angulos)
1340 ##print("l1",l1)
1341 ##print("l2",l2)
1342 if len(l1)>0:
1343 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1344 #l1,l2 = self.get2List(angulos2)
1345 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1346 #ang1_ = self.fixData90HL(ang1_)
1347 #ang2_ = self.fixData90HL(ang2_)
1348 else:
1349 ang1_= angulos
1350 ang2_= angulos
1351 return ang1_,ang2_
1352
1353
1354 def replaceNAN(self,data_weather,data_ele,val):
1355 data= data_ele
1356 data_T= data_weather
1357 if data.shape[0]> data_T.shape[0]:
1358 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1359 c = 0
1360 for i in range(len(data)):
1361 if numpy.isnan(data[i]):
1362 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1363 else:
1364 data_N[i,:]=data_T[c,:]
1365 c=c+1
1366 return data_N
1367 else:
1368 for i in range(len(data)):
1369 if numpy.isnan(data[i]):
1370 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1371 return data_T
1372
1373 def check_case(self,data_ele,ang_max,ang_min):
1374 start = data_ele[0]
1375 end = data_ele[-1]
1376 number = (end-start)
1377 len_ang=len(data_ele)
1378 print("start",start)
1379 print("end",end)
1380 print("number",number)
1381
1382 print("len_ang",len_ang)
1383
1384 #exit(1)
1385
1386 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
1387 return 0
1388 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
1389 # return 1
1390 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
1391 return 1
1392 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
1393 return 2
1394 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
1395 return 3
1396
1397
1398 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1399 ang_max= ang_max
1400 ang_min= ang_min
1401 data_weather=data_weather
1402 val_ch=val_ch
1403 ##print("*********************DATA WEATHER**************************************")
1404 ##print(data_weather)
1405 if self.ini==0:
1406 '''
1407 print("**********************************************")
1408 print("**********************************************")
1409 print("***************ini**************")
1410 print("**********************************************")
1411 print("**********************************************")
1412 '''
1413 #print("data_ele",data_ele)
1414 #----------------------------------------------------------
1415 tipo_case = case_flag[-1]
1416 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1417 print("check_case",tipo_case)
1418 #exit(1)
1419 #--------------------- new -------------------------
1420 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1421
1422 #-------------------------CAMBIOS RHI---------------------------------
1423 start= ang_min
1424 end = ang_max
1425 n= (ang_max-ang_min)/res
1426 #------ new
1427 self.start_data_ele = data_ele_new[0]
1428 self.end_data_ele = data_ele_new[-1]
1429 if tipo_case==0 or tipo_case==3: # SUBIDA
1430 n1= round(self.start_data_ele)- start
1431 n2= end - round(self.end_data_ele)
1432 print(self.start_data_ele)
1433 print(self.end_data_ele)
1434 if n1>0:
1435 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1436 ele1_nan= numpy.ones(n1)*numpy.nan
1437 data_ele = numpy.hstack((ele1,data_ele_new))
1438 print("ele1_nan",ele1_nan.shape)
1439 print("data_ele_old",data_ele_old.shape)
1440 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1441 if n2>0:
1442 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1443 ele2_nan= numpy.ones(n2)*numpy.nan
1444 data_ele = numpy.hstack((data_ele,ele2))
1445 print("ele2_nan",ele2_nan.shape)
1446 print("data_ele_old",data_ele_old.shape)
1447 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1448
1449 if tipo_case==1 or tipo_case==2: # BAJADA
1450 data_ele_new = data_ele_new[::-1] # reversa
1451 data_ele_old = data_ele_old[::-1]# reversa
1452 data_weather = data_weather[::-1,:]# reversa
1453 vec= numpy.where(data_ele_new<ang_max)
1454 data_ele_new = data_ele_new[vec]
1455 data_ele_old = data_ele_old[vec]
1456 data_weather = data_weather[vec[0]]
1457 vec2= numpy.where(0<data_ele_new)
1458 data_ele_new = data_ele_new[vec2]
1459 data_ele_old = data_ele_old[vec2]
1460 data_weather = data_weather[vec2[0]]
1461 self.start_data_ele = data_ele_new[0]
1462 self.end_data_ele = data_ele_new[-1]
1463
1464 n1= round(self.start_data_ele)- start
1465 n2= end - round(self.end_data_ele)-1
1466 print(self.start_data_ele)
1467 print(self.end_data_ele)
1468 if n1>0:
1469 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1470 ele1_nan= numpy.ones(n1)*numpy.nan
1471 data_ele = numpy.hstack((ele1,data_ele_new))
1472 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1473 if n2>0:
1474 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1475 ele2_nan= numpy.ones(n2)*numpy.nan
1476 data_ele = numpy.hstack((data_ele,ele2))
1477 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1478 # RADAR
1479 # NOTA data_ele y data_weather es la variable que retorna
1480 val_mean = numpy.mean(data_weather[:,-1])
1481 self.val_mean = val_mean
1482 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1483 print("eleold",data_ele_old)
1484 print(self.data_ele_tmp[val_ch])
1485 print(data_ele_old.shape[0])
1486 print(self.data_ele_tmp[val_ch].shape[0])
1487 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
1488 import sys
1489 print("EXIT",self.ini)
1490
1491 sys.exit(1)
1492 self.data_ele_tmp[val_ch]= data_ele_old
1493 else:
1494 #print("**********************************************")
1495 #print("****************VARIABLE**********************")
1496 #-------------------------CAMBIOS RHI---------------------------------
1497 #---------------------------------------------------------------------
1498 ##print("INPUT data_ele",data_ele)
1499 flag=0
1500 start_ele = self.res_ele[0]
1501 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1502 tipo_case = case_flag[-1]
1503 #print("TIPO DE DATA",tipo_case)
1504 #-----------new------------
1505 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
1506 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1507
1508 #-------------------------------NEW RHI ITERATIVO-------------------------
1509
1510 if tipo_case==0 : # SUBIDA
1511 vec = numpy.where(data_ele<ang_max)
1512 data_ele = data_ele[vec]
1513 data_ele_old = data_ele_old[vec]
1514 data_weather = data_weather[vec[0]]
1515
1516 vec2 = numpy.where(0<data_ele)
1517 data_ele= data_ele[vec2]
1518 data_ele_old= data_ele_old[vec2]
1519 ##print(data_ele_new)
1520 data_weather= data_weather[vec2[0]]
1521
1522 new_i_ele = int(round(data_ele[0]))
1523 new_f_ele = int(round(data_ele[-1]))
1524 #print(new_i_ele)
1525 #print(new_f_ele)
1526 #print(data_ele,len(data_ele))
1527 #print(data_ele_old,len(data_ele_old))
1528 if new_i_ele< 2:
1529 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1530 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1531 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
1532 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
1533 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
1534 data_ele = self.res_ele
1535 data_weather = self.res_weather[val_ch]
1536
1537 elif tipo_case==1 : #BAJADA
1538 data_ele = data_ele[::-1] # reversa
1539 data_ele_old = data_ele_old[::-1]# reversa
1540 data_weather = data_weather[::-1,:]# reversa
1541 vec= numpy.where(data_ele<ang_max)
1542 data_ele = data_ele[vec]
1543 data_ele_old = data_ele_old[vec]
1544 data_weather = data_weather[vec[0]]
1545 vec2= numpy.where(0<data_ele)
1546 data_ele = data_ele[vec2]
1547 data_ele_old = data_ele_old[vec2]
1548 data_weather = data_weather[vec2[0]]
1549
1550
1551 new_i_ele = int(round(data_ele[0]))
1552 new_f_ele = int(round(data_ele[-1]))
1553 #print(data_ele)
1554 #print(ang_max)
1555 #print(data_ele_old)
1556 if new_i_ele <= 1:
1557 new_i_ele = 1
1558 if round(data_ele[-1])>=ang_max-1:
1559 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1560 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1561 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
1562 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
1563 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
1564 data_ele = self.res_ele
1565 data_weather = self.res_weather[val_ch]
1566
1567 elif tipo_case==2: #bajada
1568 vec = numpy.where(data_ele<ang_max)
1569 data_ele = data_ele[vec]
1570 data_weather= data_weather[vec[0]]
1571
1572 len_vec = len(vec)
1573 data_ele_new = data_ele[::-1] # reversa
1574 data_weather = data_weather[::-1,:]
1575 new_i_ele = int(data_ele_new[0])
1576 new_f_ele = int(data_ele_new[-1])
1577
1578 n1= new_i_ele- ang_min
1579 n2= ang_max - new_f_ele-1
1580 if n1>0:
1581 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1582 ele1_nan= numpy.ones(n1)*numpy.nan
1583 data_ele = numpy.hstack((ele1,data_ele_new))
1584 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1585 if n2>0:
1586 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1587 ele2_nan= numpy.ones(n2)*numpy.nan
1588 data_ele = numpy.hstack((data_ele,ele2))
1589 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1590
1591 self.data_ele_tmp[val_ch] = data_ele_old
1592 self.res_ele = data_ele
1593 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1594 data_ele = self.res_ele
1595 data_weather = self.res_weather[val_ch]
1596
1597 elif tipo_case==3:#subida
1598 vec = numpy.where(0<data_ele)
1599 data_ele= data_ele[vec]
1600 data_ele_new = data_ele
1601 data_ele_old= data_ele_old[vec]
1602 data_weather= data_weather[vec[0]]
1603 pos_ini = numpy.argmin(data_ele)
1604 if pos_ini>0:
1605 len_vec= len(data_ele)
1606 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1607 #print(vec3)
1608 data_ele= data_ele[vec3]
1609 data_ele_new = data_ele
1610 data_ele_old= data_ele_old[vec3]
1611 data_weather= data_weather[vec3]
1612
1613 new_i_ele = int(data_ele_new[0])
1614 new_f_ele = int(data_ele_new[-1])
1615 n1= new_i_ele- ang_min
1616 n2= ang_max - new_f_ele-1
1617 if n1>0:
1618 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1619 ele1_nan= numpy.ones(n1)*numpy.nan
1620 data_ele = numpy.hstack((ele1,data_ele_new))
1621 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1622 if n2>0:
1623 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1624 ele2_nan= numpy.ones(n2)*numpy.nan
1625 data_ele = numpy.hstack((data_ele,ele2))
1626 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1627
1628 self.data_ele_tmp[val_ch] = data_ele_old
1629 self.res_ele = data_ele
1630 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1631 data_ele = self.res_ele
1632 data_weather = self.res_weather[val_ch]
1633 #print("self.data_ele_tmp",self.data_ele_tmp)
1634 return data_weather,data_ele
1635
1636
1637 def plot(self):
1638 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1639 data = self.data[-1]
1640 r = self.data.yrange
1641 delta_height = r[1]-r[0]
1642 r_mask = numpy.where(r>=0)[0]
1643 ##print("delta_height",delta_height)
1644 #print("r_mask",r_mask,len(r_mask))
1645 r = numpy.arange(len(r_mask))*delta_height
1646 self.y = 2*r
1647 res = 1
1648 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1649 ang_max = self.ang_max
1650 ang_min = self.ang_min
1651 var_ang =ang_max - ang_min
1652 step = (int(var_ang)/(res*data['weather'].shape[0]))
1653 ###print("step",step)
1654 #--------------------------------------------------------
1655 ##print('weather',data['weather'].shape)
1656 ##print('ele',data['ele'].shape)
1657
1658 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1659 ###self.res_azi = numpy.mean(data['azi'])
1660 ###print("self.res_ele",self.res_ele)
1661 plt.clf()
1662 subplots = [121, 122]
1663 try:
1664 if self.data[-2]['ele'].max()<data['ele'].max():
1665 self.ini=0
1666 except:
1667 pass
1668 if self.ini==0:
1669 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1670 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1671 print("SHAPE",self.data_ele_tmp.shape)
1672
1673 for i,ax in enumerate(self.axes):
1674 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min,case_flag=self.data['case_flag'])
1675 self.res_azi = numpy.mean(data['azi'])
1676
1677 if ax.firsttime:
1678 #plt.clf()
1679 print("Frist Plot")
1680 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1681 #fig=self.figures[0]
1682 else:
1683 #plt.clf()
1684 print("ELSE PLOT")
1685 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1686 caax = cgax.parasites[0]
1687 paax = cgax.parasites[1]
1688 cbar = plt.gcf().colorbar(pm, pad=0.075)
1689 caax.set_xlabel('x_range [km]')
1690 caax.set_ylabel('y_range [km]')
1691 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1692 print("***************************self.ini****************************",self.ini)
1693 self.ini= self.ini+1
1694
1695
1696
1697
1698
1699 class WeatherRHI_vRF4_Plot(Plot):
1700 CODE = 'RHI'
1701 plot_name = 'RHI'
1702 #plot_type = 'rhistyle'
1703 buffering = False
1704
1705 def setup(self):
1706
1707 self.ncols = 1
1708 self.nrows = 1
1709 self.nplots= 1
1710 self.ylabel= 'Range [Km]'
1711 self.xlabel= 'Range [Km]'
1712 self.titles= ['RHI']
1713 self.polar = True
1714 self.grid = True
1715 if self.channels is not None:
1716 self.nplots = len(self.channels)
1717 self.nrows = len(self.channels)
1718 else:
1719 self.nplots = self.data.shape(self.CODE)[0]
1720 self.nrows = self.nplots
1721 self.channels = list(range(self.nplots))
1722
1723 if self.CODE == 'Power':
1724 self.cb_label = r'Power (dB)'
1725 elif self.CODE == 'Doppler':
1726 self.cb_label = r'Velocity (m/s)'
1727 self.colorbar=True
1728 self.width =8
1729 self.height =8
1730 self.ini =0
1731 self.len_azi =0
1732 self.buffer_ini = None
1733 self.buffer_ele = None
1734 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1735 self.flag =0
1736 self.indicador= 0
1737 self.last_data_ele = None
1738 self.val_mean = None
1739
1740 def update(self, dataOut):
1741
1742 data = {}
1743 meta = {}
1744 if hasattr(dataOut, 'dataPP_POWER'):
1745 factor = 1
1746 if hasattr(dataOut, 'nFFTPoints'):
1747 factor = dataOut.normFactor
1748
1749 if 'pow' in self.attr_data[0].lower():
1750 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1751 else:
1752 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1753
1754 data['azi'] = dataOut.data_azi
1755 data['ele'] = dataOut.data_ele
1756
1757 return data, meta
1758
1759 def plot(self):
1760 data = self.data[-1]
1761 r = self.data.yrange
1762 delta_height = r[1]-r[0]
1763 r_mask = numpy.where(r>=0)[0]
1764 self.r_mask =r_mask
1765 r = numpy.arange(len(r_mask))*delta_height
1766 self.y = 2*r
1767
1768 try:
1769 z = data['data'][self.channels[0]][:,r_mask]
1770 except:
1771 z = data['data'][0][:,r_mask]
1772
1773 self.titles = []
1774
1775 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1776 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1777 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1778 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1779 self.ang_min = self.ang_min if self.ang_min else 0
1780 self.ang_max = self.ang_max if self.ang_max else 90
1781
1782 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1783
1784 for i,ax in enumerate(self.axes):
1785
1786 if ax.firsttime:
1787 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1788 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1789
1790 else:
1791 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1792 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1793 ax.grid(True)
1794 if len(self.channels) !=1:
1795 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(numpy.mean(data['azi']),1)), x) for x in range(self.nrows)]
1796 else:
1797 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['azi']),1)), self.channels[0])]
1798
1799 class WeatherParamsPlot(Plot):
372 class WeatherParamsPlot(Plot):
1800 #CODE = 'RHI'
373 #CODE = 'RHI'
1801 #plot_name = 'RHI'
374 #plot_name = 'RHI'
1802 #plot_type = 'rhistyle'
375 #plot_type = 'rhistyle'
1803 buffering = False
376 buffering = False
1804
377
1805 def setup(self):
378 def setup(self):
1806
379
1807 self.ncols = 1
380 self.ncols = 1
1808 self.nrows = 1
381 self.nrows = 1
1809 self.nplots= 1
382 self.nplots= 1
1810 self.ylabel= 'Range [km]'
383 self.ylabel= 'Range [km]'
1811 self.xlabel= 'Range [km]'
384 self.xlabel= 'Range [km]'
1812 self.polar = True
385 self.polar = True
1813 self.grid = True
386 self.grid = True
1814 if self.channels is not None:
387 if self.channels is not None:
1815 self.nplots = len(self.channels)
388 self.nplots = len(self.channels)
1816 self.nrows = len(self.channels)
389 self.nrows = len(self.channels)
1817 else:
390 else:
1818 self.nplots = self.data.shape(self.CODE)[0]
391 self.nplots = self.data.shape(self.CODE)[0]
1819 self.nrows = self.nplots
392 self.nrows = self.nplots
1820 self.channels = list(range(self.nplots))
393 self.channels = list(range(self.nplots))
1821
394
1822 self.colorbar=True
395 self.colorbar=True
1823 self.width =8
396 self.width =8
1824 self.height =8
397 self.height =8
1825 self.ini =0
398 self.ini =0
1826 self.len_azi =0
399 self.len_azi =0
1827 self.buffer_ini = None
400 self.buffer_ini = None
1828 self.buffer_ele = None
401 self.buffer_ele = None
1829 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
402 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1830 self.flag =0
403 self.flag =0
1831 self.indicador= 0
404 self.indicador= 0
1832 self.last_data_ele = None
405 self.last_data_ele = None
1833 self.val_mean = None
406 self.val_mean = None
1834
407
1835 def update(self, dataOut):
408 def update(self, dataOut):
1836
409
1837 data = {}
410 data = {}
1838 meta = {}
411 meta = {}
1839 if hasattr(dataOut, 'dataPP_POWER'):
412 if hasattr(dataOut, 'dataPP_POWER'):
1840 factor = 1
413 factor = 1
1841 if hasattr(dataOut, 'nFFTPoints'):
414 if hasattr(dataOut, 'nFFTPoints'):
1842 factor = dataOut.normFactor
415 factor = dataOut.normFactor
1843
416
1844 if 'pow' in self.attr_data[0].lower():
417 if 'pow' in self.attr_data[0].lower():
1845 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
418 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1846 else:
419 else:
1847 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
420 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1848
421
1849 if dataOut.mode_op == 'PPI':
422 if dataOut.mode_op == 'PPI':
1850 self.CODE = 'PPI'
423 self.CODE = 'PPI'
1851 self.title = self.CODE
424 self.title = self.CODE
1852 elif dataOut.mode_op == 'RHI':
425 elif dataOut.mode_op == 'RHI':
1853 self.CODE = 'RHI'
426 self.CODE = 'RHI'
1854 self.title = self.CODE
427 self.title = self.CODE
1855
428
1856 data['azi'] = dataOut.data_azi
429 data['azi'] = dataOut.data_azi
1857 data['ele'] = dataOut.data_ele
430 data['ele'] = dataOut.data_ele
1858 data['mode_op'] = dataOut.mode_op
431 data['mode_op'] = dataOut.mode_op
1859
432
1860 return data, meta
433 return data, meta
1861
434
1862 def plot(self):
435 def plot(self):
1863 data = self.data[-1]
436 data = self.data[-1]
1864 r = self.data.yrange
437 r = self.data.yrange
1865 delta_height = r[1]-r[0]
438 delta_height = r[1]-r[0]
1866 r_mask = numpy.where(r>=0)[0]
439 r_mask = numpy.where(r>=0)[0]
1867 self.r_mask =r_mask
440 self.r_mask =r_mask
1868 r = numpy.arange(len(r_mask))*delta_height
441 r = numpy.arange(len(r_mask))*delta_height
1869 self.y = 2*r
442 self.y = 2*r
1870
443
1871 try:
444 try:
1872 z = data['data'][self.channels[0]][:,r_mask]
445 z = data['data'][self.channels[0]][:,r_mask]
1873 except:
446 except:
1874 z = data['data'][0][:,r_mask]
447 z = data['data'][0][:,r_mask]
1875
448
1876 self.titles = []
449 self.titles = []
1877
450
1878 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
451 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1879 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
452 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1880 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
453 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1881 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
454 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1882 print("mode inside plot",self.data['mode_op'],data['mode_op'])
455
1883 if data['mode_op'] == 'RHI':
456 if data['mode_op'] == 'RHI':
1884 try:
457 try:
1885 if self.data['mode_op'][-2] == 'PPI':
458 if self.data['mode_op'][-2] == 'PPI':
1886 self.ang_min = None
459 self.ang_min = None
1887 self.ang_max = None
460 self.ang_max = None
1888 except:
461 except:
1889 pass
462 pass
1890 self.ang_min = self.ang_min if self.ang_min else 0
463 self.ang_min = self.ang_min if self.ang_min else 0
1891 self.ang_max = self.ang_max if self.ang_max else 90
464 self.ang_max = self.ang_max if self.ang_max else 90
1892 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
465 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1893 elif data['mode_op'] == 'PPI':
466 elif data['mode_op'] == 'PPI':
1894 try:
467 try:
1895 if self.data['mode_op'][-2] == 'RHI':
468 if self.data['mode_op'][-2] == 'RHI':
1896 self.ang_min = None
469 self.ang_min = None
1897 self.ang_max = None
470 self.ang_max = None
1898 except:
471 except:
1899 pass
472 pass
1900 self.ang_min = self.ang_min if self.ang_min else 0
473 self.ang_min = self.ang_min if self.ang_min else 0
1901 self.ang_max = self.ang_max if self.ang_max else 360
474 self.ang_max = self.ang_max if self.ang_max else 360
1902 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
475 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1903
476
1904 self.clear_figures()
477 self.clear_figures()
1905
478
1906 for i,ax in enumerate(self.axes):
479 for i,ax in enumerate(self.axes):
1907
480
1908 if ax.firsttime:
481 if ax.firsttime:
1909 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
482 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1910 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
483 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1911 if data['mode_op'] == 'PPI':
484 if data['mode_op'] == 'PPI':
1912 ax.set_theta_direction(-1)
485 ax.set_theta_direction(-1)
1913 ax.set_theta_offset(numpy.pi/2)
486 ax.set_theta_offset(numpy.pi/2)
1914
487
1915 else:
488 else:
1916 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
489 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1917 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
490 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1918 if data['mode_op'] == 'PPI':
491 if data['mode_op'] == 'PPI':
1919 ax.set_theta_direction(-1)
492 ax.set_theta_direction(-1)
1920 ax.set_theta_offset(numpy.pi/2)
493 ax.set_theta_offset(numpy.pi/2)
1921
494
1922 ax.grid(True)
495 ax.grid(True)
1923 if data['mode_op'] == 'RHI':
496 if data['mode_op'] == 'RHI':
1924 len_aux = int(data['azi'].shape[0]/4)
497 len_aux = int(data['azi'].shape[0]/4)
1925 mean = numpy.mean(data['azi'][len_aux:-len_aux])
498 mean = numpy.mean(data['azi'][len_aux:-len_aux])
1926 if len(self.channels) !=1:
499 if len(self.channels) !=1:
1927 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
500 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
1928 else:
501 else:
1929 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
502 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
1930 elif data['mode_op'] == 'PPI':
503 elif data['mode_op'] == 'PPI':
1931 len_aux = int(data['ele'].shape[0]/4)
504 len_aux = int(data['ele'].shape[0]/4)
1932 mean = numpy.mean(data['ele'][len_aux:-len_aux])
505 mean = numpy.mean(data['ele'][len_aux:-len_aux])
1933 if len(self.channels) !=1:
506 if len(self.channels) !=1:
1934 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
507 self.titles = ['PPI {} at EL: {} CH {}'.format(self.self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
1935 else:
508 else:
1936 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
509 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,1886 +1,1891
1 import sys
1 import sys
2 import numpy,math
2 import numpy,math
3 from scipy import interpolate
3 from scipy import interpolate
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
6 from schainpy.utils import log
6 from schainpy.utils import log
7 from time import time
7 from time import time
8
8
9
9
10
10
11 class VoltageProc(ProcessingUnit):
11 class VoltageProc(ProcessingUnit):
12
12
13 def __init__(self):
13 def __init__(self):
14
14
15 ProcessingUnit.__init__(self)
15 ProcessingUnit.__init__(self)
16
16
17 self.dataOut = Voltage()
17 self.dataOut = Voltage()
18 self.flip = 1
18 self.flip = 1
19 self.setupReq = False
19 self.setupReq = False
20
20
21 def run(self):
21 def run(self):
22
22
23 if self.dataIn.type == 'AMISR':
23 if self.dataIn.type == 'AMISR':
24 self.__updateObjFromAmisrInput()
24 self.__updateObjFromAmisrInput()
25
25
26 if self.dataIn.type == 'Voltage':
26 if self.dataIn.type == 'Voltage':
27 self.dataOut.copy(self.dataIn)
27 self.dataOut.copy(self.dataIn)
28
28
29 def __updateObjFromAmisrInput(self):
29 def __updateObjFromAmisrInput(self):
30
30
31 self.dataOut.timeZone = self.dataIn.timeZone
31 self.dataOut.timeZone = self.dataIn.timeZone
32 self.dataOut.dstFlag = self.dataIn.dstFlag
32 self.dataOut.dstFlag = self.dataIn.dstFlag
33 self.dataOut.errorCount = self.dataIn.errorCount
33 self.dataOut.errorCount = self.dataIn.errorCount
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
35
35
36 self.dataOut.flagNoData = self.dataIn.flagNoData
36 self.dataOut.flagNoData = self.dataIn.flagNoData
37 self.dataOut.data = self.dataIn.data
37 self.dataOut.data = self.dataIn.data
38 self.dataOut.utctime = self.dataIn.utctime
38 self.dataOut.utctime = self.dataIn.utctime
39 self.dataOut.channelList = self.dataIn.channelList
39 self.dataOut.channelList = self.dataIn.channelList
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
41 self.dataOut.heightList = self.dataIn.heightList
41 self.dataOut.heightList = self.dataIn.heightList
42 self.dataOut.nProfiles = self.dataIn.nProfiles
42 self.dataOut.nProfiles = self.dataIn.nProfiles
43
43
44 self.dataOut.nCohInt = self.dataIn.nCohInt
44 self.dataOut.nCohInt = self.dataIn.nCohInt
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
46 self.dataOut.frequency = self.dataIn.frequency
46 self.dataOut.frequency = self.dataIn.frequency
47
47
48 self.dataOut.azimuth = self.dataIn.azimuth
48 self.dataOut.azimuth = self.dataIn.azimuth
49 self.dataOut.zenith = self.dataIn.zenith
49 self.dataOut.zenith = self.dataIn.zenith
50
50
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
54
54
55
55
56 class selectChannels(Operation):
56 class selectChannels(Operation):
57
57
58 def run(self, dataOut, channelList):
58 def run(self, dataOut, channelList):
59
59
60 channelIndexList = []
60 channelIndexList = []
61 self.dataOut = dataOut
61 self.dataOut = dataOut
62 for channel in channelList:
62 for channel in channelList:
63 if channel not in self.dataOut.channelList:
63 if channel not in self.dataOut.channelList:
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
65
65
66 index = self.dataOut.channelList.index(channel)
66 index = self.dataOut.channelList.index(channel)
67 channelIndexList.append(index)
67 channelIndexList.append(index)
68 self.selectChannelsByIndex(channelIndexList)
68 self.selectChannelsByIndex(channelIndexList)
69 return self.dataOut
69 return self.dataOut
70
70
71 def selectChannelsByIndex(self, channelIndexList):
71 def selectChannelsByIndex(self, channelIndexList):
72 """
72 """
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
74
74
75 Input:
75 Input:
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
77
77
78 Affected:
78 Affected:
79 self.dataOut.data
79 self.dataOut.data
80 self.dataOut.channelIndexList
80 self.dataOut.channelIndexList
81 self.dataOut.nChannels
81 self.dataOut.nChannels
82 self.dataOut.m_ProcessingHeader.totalSpectra
82 self.dataOut.m_ProcessingHeader.totalSpectra
83 self.dataOut.systemHeaderObj.numChannels
83 self.dataOut.systemHeaderObj.numChannels
84 self.dataOut.m_ProcessingHeader.blockSize
84 self.dataOut.m_ProcessingHeader.blockSize
85
85
86 Return:
86 Return:
87 None
87 None
88 """
88 """
89
89
90 for channelIndex in channelIndexList:
90 for channelIndex in channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
93
93
94 if self.dataOut.type == 'Voltage':
94 if self.dataOut.type == 'Voltage':
95 if self.dataOut.flagDataAsBlock:
95 if self.dataOut.flagDataAsBlock:
96 """
96 """
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
98 """
98 """
99 data = self.dataOut.data[channelIndexList,:,:]
99 data = self.dataOut.data[channelIndexList,:,:]
100 else:
100 else:
101 data = self.dataOut.data[channelIndexList,:]
101 data = self.dataOut.data[channelIndexList,:]
102
102
103 self.dataOut.data = data
103 self.dataOut.data = data
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
105 self.dataOut.channelList = range(len(channelIndexList))
105 self.dataOut.channelList = range(len(channelIndexList))
106
106
107 elif self.dataOut.type == 'Spectra':
107 elif self.dataOut.type == 'Spectra':
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
110
110
111 self.dataOut.data_spc = data_spc
111 self.dataOut.data_spc = data_spc
112 self.dataOut.data_dc = data_dc
112 self.dataOut.data_dc = data_dc
113
113
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
115 self.dataOut.channelList = range(len(channelIndexList))
115 self.dataOut.channelList = range(len(channelIndexList))
116 self.__selectPairsByChannel(channelIndexList)
116 self.__selectPairsByChannel(channelIndexList)
117
117
118 return 1
118 return 1
119
119
120 def __selectPairsByChannel(self, channelList=None):
120 def __selectPairsByChannel(self, channelList=None):
121
121
122 if channelList == None:
122 if channelList == None:
123 return
123 return
124
124
125 pairsIndexListSelected = []
125 pairsIndexListSelected = []
126 for pairIndex in self.dataOut.pairsIndexList:
126 for pairIndex in self.dataOut.pairsIndexList:
127 # First pair
127 # First pair
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
129 continue
129 continue
130 # Second pair
130 # Second pair
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
132 continue
132 continue
133
133
134 pairsIndexListSelected.append(pairIndex)
134 pairsIndexListSelected.append(pairIndex)
135
135
136 if not pairsIndexListSelected:
136 if not pairsIndexListSelected:
137 self.dataOut.data_cspc = None
137 self.dataOut.data_cspc = None
138 self.dataOut.pairsList = []
138 self.dataOut.pairsList = []
139 return
139 return
140
140
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
143 for i in pairsIndexListSelected]
143 for i in pairsIndexListSelected]
144
144
145 return
145 return
146
146
147 class selectHeights(Operation):
147 class selectHeights(Operation):
148
148
149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
150 """
150 """
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 minHei <= height <= maxHei
152 minHei <= height <= maxHei
153
153
154 Input:
154 Input:
155 minHei : valor minimo de altura a considerar
155 minHei : valor minimo de altura a considerar
156 maxHei : valor maximo de altura a considerar
156 maxHei : valor maximo de altura a considerar
157
157
158 Affected:
158 Affected:
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
160
160
161 Return:
161 Return:
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
163 """
163 """
164
164
165 self.dataOut = dataOut
165 self.dataOut = dataOut
166
166
167 if minHei and maxHei:
167 if minHei and maxHei:
168
168
169 if (minHei < self.dataOut.heightList[0]):
169 if (minHei < self.dataOut.heightList[0]):
170 minHei = self.dataOut.heightList[0]
170 minHei = self.dataOut.heightList[0]
171
171
172 if (maxHei > self.dataOut.heightList[-1]):
172 if (maxHei > self.dataOut.heightList[-1]):
173 maxHei = self.dataOut.heightList[-1]
173 maxHei = self.dataOut.heightList[-1]
174
174
175 minIndex = 0
175 minIndex = 0
176 maxIndex = 0
176 maxIndex = 0
177 heights = self.dataOut.heightList
177 heights = self.dataOut.heightList
178
178
179 inda = numpy.where(heights >= minHei)
179 inda = numpy.where(heights >= minHei)
180 indb = numpy.where(heights <= maxHei)
180 indb = numpy.where(heights <= maxHei)
181
181
182 try:
182 try:
183 minIndex = inda[0][0]
183 minIndex = inda[0][0]
184 except:
184 except:
185 minIndex = 0
185 minIndex = 0
186
186
187 try:
187 try:
188 maxIndex = indb[0][-1]
188 maxIndex = indb[0][-1]
189 except:
189 except:
190 maxIndex = len(heights)
190 maxIndex = len(heights)
191
191
192 self.selectHeightsByIndex(minIndex, maxIndex)
192 self.selectHeightsByIndex(minIndex, maxIndex)
193
193
194 return self.dataOut
194 return self.dataOut
195
195
196 def selectHeightsByIndex(self, minIndex, maxIndex):
196 def selectHeightsByIndex(self, minIndex, maxIndex):
197 """
197 """
198 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
198 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
199 minIndex <= index <= maxIndex
199 minIndex <= index <= maxIndex
200
200
201 Input:
201 Input:
202 minIndex : valor de indice minimo de altura a considerar
202 minIndex : valor de indice minimo de altura a considerar
203 maxIndex : valor de indice maximo de altura a considerar
203 maxIndex : valor de indice maximo de altura a considerar
204
204
205 Affected:
205 Affected:
206 self.dataOut.data
206 self.dataOut.data
207 self.dataOut.heightList
207 self.dataOut.heightList
208
208
209 Return:
209 Return:
210 1 si el metodo se ejecuto con exito caso contrario devuelve 0
210 1 si el metodo se ejecuto con exito caso contrario devuelve 0
211 """
211 """
212
212
213 if self.dataOut.type == 'Voltage':
213 if self.dataOut.type == 'Voltage':
214 if (minIndex < 0) or (minIndex > maxIndex):
214 if (minIndex < 0) or (minIndex > maxIndex):
215 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
215 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
216
216
217 if (maxIndex >= self.dataOut.nHeights):
217 if (maxIndex >= self.dataOut.nHeights):
218 maxIndex = self.dataOut.nHeights
218 maxIndex = self.dataOut.nHeights
219 #print("shapeeee",self.dataOut.data.shape)
219 #print("shapeeee",self.dataOut.data.shape)
220 #voltage
220 #voltage
221 if self.dataOut.flagDataAsBlock:
221 if self.dataOut.flagDataAsBlock:
222 """
222 """
223 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
223 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
224 """
224 """
225 data = self.dataOut.data[:,:, minIndex:maxIndex]
225 data = self.dataOut.data[:,:, minIndex:maxIndex]
226 else:
226 else:
227 data = self.dataOut.data[:, minIndex:maxIndex]
227 data = self.dataOut.data[:, minIndex:maxIndex]
228
228
229 # firstHeight = self.dataOut.heightList[minIndex]
229 # firstHeight = self.dataOut.heightList[minIndex]
230
230
231 self.dataOut.data = data
231 self.dataOut.data = data
232 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
232 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
233
233
234 if self.dataOut.nHeights <= 1:
234 if self.dataOut.nHeights <= 1:
235 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
235 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
236 elif self.dataOut.type == 'Spectra':
236 elif self.dataOut.type == 'Spectra':
237 if (minIndex < 0) or (minIndex > maxIndex):
237 if (minIndex < 0) or (minIndex > maxIndex):
238 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
238 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
239 minIndex, maxIndex))
239 minIndex, maxIndex))
240
240
241 if (maxIndex >= self.dataOut.nHeights):
241 if (maxIndex >= self.dataOut.nHeights):
242 maxIndex = self.dataOut.nHeights - 1
242 maxIndex = self.dataOut.nHeights - 1
243
243
244 # Spectra
244 # Spectra
245 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
245 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
246
246
247 data_cspc = None
247 data_cspc = None
248 if self.dataOut.data_cspc is not None:
248 if self.dataOut.data_cspc is not None:
249 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
249 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
250
250
251 data_dc = None
251 data_dc = None
252 if self.dataOut.data_dc is not None:
252 if self.dataOut.data_dc is not None:
253 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
253 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
254
254
255 self.dataOut.data_spc = data_spc
255 self.dataOut.data_spc = data_spc
256 self.dataOut.data_cspc = data_cspc
256 self.dataOut.data_cspc = data_cspc
257 self.dataOut.data_dc = data_dc
257 self.dataOut.data_dc = data_dc
258
258
259 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
259 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
260
260
261 return 1
261 return 1
262
262
263
263
264 class filterByHeights(Operation):
264 class filterByHeights(Operation):
265
265
266 def run(self, dataOut, window):
266 def run(self, dataOut, window):
267
267
268 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
268 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
269
269
270 if window == None:
270 if window == None:
271 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
271 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
272
272
273 newdelta = deltaHeight * window
273 newdelta = deltaHeight * window
274 r = dataOut.nHeights % window
274 r = dataOut.nHeights % window
275 newheights = (dataOut.nHeights-r)/window
275 newheights = (dataOut.nHeights-r)/window
276
276
277 if newheights <= 1:
277 if newheights <= 1:
278 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
278 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
279
279
280 if dataOut.flagDataAsBlock:
280 if dataOut.flagDataAsBlock:
281 """
281 """
282 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
282 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
283 """
283 """
284 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
284 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
285 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
285 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
286 buffer = numpy.sum(buffer,3)
286 buffer = numpy.sum(buffer,3)
287
287
288 else:
288 else:
289 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
289 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
290 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
290 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
291 buffer = numpy.sum(buffer,2)
291 buffer = numpy.sum(buffer,2)
292
292
293 dataOut.data = buffer
293 dataOut.data = buffer
294 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
294 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
295 dataOut.windowOfFilter = window
295 dataOut.windowOfFilter = window
296
296
297 return dataOut
297 return dataOut
298
298
299
299
300 class setH0(Operation):
300 class setH0(Operation):
301
301
302 def run(self, dataOut, h0, deltaHeight = None):
302 def run(self, dataOut, h0, deltaHeight = None):
303
303
304 if not deltaHeight:
304 if not deltaHeight:
305 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
305 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
306
306
307 nHeights = dataOut.nHeights
307 nHeights = dataOut.nHeights
308
308
309 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
309 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
310
310
311 dataOut.heightList = newHeiRange
311 dataOut.heightList = newHeiRange
312 dataOut.h0 = h0
312 dataOut.h0 = h0
313
313
314 return dataOut
314 return dataOut
315
315
316
316
317 class deFlip(Operation):
317 class deFlip(Operation):
318
318
319 def run(self, dataOut, channelList = []):
319 def run(self, dataOut, channelList = []):
320
320
321 data = dataOut.data.copy()
321 data = dataOut.data.copy()
322
322
323 if dataOut.flagDataAsBlock:
323 if dataOut.flagDataAsBlock:
324 flip = self.flip
324 flip = self.flip
325 profileList = list(range(dataOut.nProfiles))
325 profileList = list(range(dataOut.nProfiles))
326
326
327 if not channelList:
327 if not channelList:
328 for thisProfile in profileList:
328 for thisProfile in profileList:
329 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
329 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
330 flip *= -1.0
330 flip *= -1.0
331 else:
331 else:
332 for thisChannel in channelList:
332 for thisChannel in channelList:
333 if thisChannel not in dataOut.channelList:
333 if thisChannel not in dataOut.channelList:
334 continue
334 continue
335
335
336 for thisProfile in profileList:
336 for thisProfile in profileList:
337 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
337 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
338 flip *= -1.0
338 flip *= -1.0
339
339
340 self.flip = flip
340 self.flip = flip
341
341
342 else:
342 else:
343 if not channelList:
343 if not channelList:
344 data[:,:] = data[:,:]*self.flip
344 data[:,:] = data[:,:]*self.flip
345 else:
345 else:
346 for thisChannel in channelList:
346 for thisChannel in channelList:
347 if thisChannel not in dataOut.channelList:
347 if thisChannel not in dataOut.channelList:
348 continue
348 continue
349
349
350 data[thisChannel,:] = data[thisChannel,:]*self.flip
350 data[thisChannel,:] = data[thisChannel,:]*self.flip
351
351
352 self.flip *= -1.
352 self.flip *= -1.
353
353
354 dataOut.data = data
354 dataOut.data = data
355
355
356 return dataOut
356 return dataOut
357
357
358
358
359 class setAttribute(Operation):
359 class setAttribute(Operation):
360 '''
360 '''
361 Set an arbitrary attribute(s) to dataOut
361 Set an arbitrary attribute(s) to dataOut
362 '''
362 '''
363
363
364 def __init__(self):
364 def __init__(self):
365
365
366 Operation.__init__(self)
366 Operation.__init__(self)
367 self._ready = False
367 self._ready = False
368
368
369 def run(self, dataOut, **kwargs):
369 def run(self, dataOut, **kwargs):
370
370
371 for key, value in kwargs.items():
371 for key, value in kwargs.items():
372 setattr(dataOut, key, value)
372 setattr(dataOut, key, value)
373
373
374 return dataOut
374 return dataOut
375
375
376
376
377 @MPDecorator
377 @MPDecorator
378 class printAttribute(Operation):
378 class printAttribute(Operation):
379 '''
379 '''
380 Print an arbitrary attribute of dataOut
380 Print an arbitrary attribute of dataOut
381 '''
381 '''
382
382
383 def __init__(self):
383 def __init__(self):
384
384
385 Operation.__init__(self)
385 Operation.__init__(self)
386
386
387 def run(self, dataOut, attributes):
387 def run(self, dataOut, attributes):
388
388
389 if isinstance(attributes, str):
389 if isinstance(attributes, str):
390 attributes = [attributes]
390 attributes = [attributes]
391 for attr in attributes:
391 for attr in attributes:
392 if hasattr(dataOut, attr):
392 if hasattr(dataOut, attr):
393 log.log(getattr(dataOut, attr), attr)
393 log.log(getattr(dataOut, attr), attr)
394
394
395
395
396 class interpolateHeights(Operation):
396 class interpolateHeights(Operation):
397
397
398 def run(self, dataOut, topLim, botLim):
398 def run(self, dataOut, topLim, botLim):
399 #69 al 72 para julia
399 #69 al 72 para julia
400 #82-84 para meteoros
400 #82-84 para meteoros
401 if len(numpy.shape(dataOut.data))==2:
401 if len(numpy.shape(dataOut.data))==2:
402 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
402 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
403 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
403 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
404 #dataOut.data[:,botLim:limSup+1] = sampInterp
404 #dataOut.data[:,botLim:limSup+1] = sampInterp
405 dataOut.data[:,botLim:topLim+1] = sampInterp
405 dataOut.data[:,botLim:topLim+1] = sampInterp
406 else:
406 else:
407 nHeights = dataOut.data.shape[2]
407 nHeights = dataOut.data.shape[2]
408 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
408 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
409 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
409 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
410 f = interpolate.interp1d(x, y, axis = 2)
410 f = interpolate.interp1d(x, y, axis = 2)
411 xnew = numpy.arange(botLim,topLim+1)
411 xnew = numpy.arange(botLim,topLim+1)
412 ynew = f(xnew)
412 ynew = f(xnew)
413 dataOut.data[:,:,botLim:topLim+1] = ynew
413 dataOut.data[:,:,botLim:topLim+1] = ynew
414
414
415 return dataOut
415 return dataOut
416
416
417
417
418 class CohInt(Operation):
418 class CohInt(Operation):
419
419
420 isConfig = False
420 isConfig = False
421 __profIndex = 0
421 __profIndex = 0
422 __byTime = False
422 __byTime = False
423 __initime = None
423 __initime = None
424 __lastdatatime = None
424 __lastdatatime = None
425 __integrationtime = None
425 __integrationtime = None
426 __buffer = None
426 __buffer = None
427 __bufferStride = []
427 __bufferStride = []
428 __dataReady = False
428 __dataReady = False
429 __profIndexStride = 0
429 __profIndexStride = 0
430 __dataToPutStride = False
430 __dataToPutStride = False
431 n = None
431 n = None
432
432
433 def __init__(self, **kwargs):
433 def __init__(self, **kwargs):
434
434
435 Operation.__init__(self, **kwargs)
435 Operation.__init__(self, **kwargs)
436
436
437 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
437 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
438 """
438 """
439 Set the parameters of the integration class.
439 Set the parameters of the integration class.
440
440
441 Inputs:
441 Inputs:
442
442
443 n : Number of coherent integrations
443 n : Number of coherent integrations
444 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
444 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
445 overlapping :
445 overlapping :
446 """
446 """
447
447
448 self.__initime = None
448 self.__initime = None
449 self.__lastdatatime = 0
449 self.__lastdatatime = 0
450 self.__buffer = None
450 self.__buffer = None
451 self.__dataReady = False
451 self.__dataReady = False
452 self.byblock = byblock
452 self.byblock = byblock
453 self.stride = stride
453 self.stride = stride
454
454
455 if n == None and timeInterval == None:
455 if n == None and timeInterval == None:
456 raise ValueError("n or timeInterval should be specified ...")
456 raise ValueError("n or timeInterval should be specified ...")
457
457
458 if n != None:
458 if n != None:
459 self.n = n
459 self.n = n
460 self.__byTime = False
460 self.__byTime = False
461 else:
461 else:
462 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
462 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
463 self.n = 9999
463 self.n = 9999
464 self.__byTime = True
464 self.__byTime = True
465
465
466 if overlapping:
466 if overlapping:
467 self.__withOverlapping = True
467 self.__withOverlapping = True
468 self.__buffer = None
468 self.__buffer = None
469 else:
469 else:
470 self.__withOverlapping = False
470 self.__withOverlapping = False
471 self.__buffer = 0
471 self.__buffer = 0
472
472
473 self.__profIndex = 0
473 self.__profIndex = 0
474
474
475 def putData(self, data):
475 def putData(self, data):
476
476
477 """
477 """
478 Add a profile to the __buffer and increase in one the __profileIndex
478 Add a profile to the __buffer and increase in one the __profileIndex
479
479
480 """
480 """
481
481
482 if not self.__withOverlapping:
482 if not self.__withOverlapping:
483 self.__buffer += data.copy()
483 self.__buffer += data.copy()
484 self.__profIndex += 1
484 self.__profIndex += 1
485 return
485 return
486
486
487 #Overlapping data
487 #Overlapping data
488 nChannels, nHeis = data.shape
488 nChannels, nHeis = data.shape
489 data = numpy.reshape(data, (1, nChannels, nHeis))
489 data = numpy.reshape(data, (1, nChannels, nHeis))
490
490
491 #If the buffer is empty then it takes the data value
491 #If the buffer is empty then it takes the data value
492 if self.__buffer is None:
492 if self.__buffer is None:
493 self.__buffer = data
493 self.__buffer = data
494 self.__profIndex += 1
494 self.__profIndex += 1
495 return
495 return
496
496
497 #If the buffer length is lower than n then stakcing the data value
497 #If the buffer length is lower than n then stakcing the data value
498 if self.__profIndex < self.n:
498 if self.__profIndex < self.n:
499 self.__buffer = numpy.vstack((self.__buffer, data))
499 self.__buffer = numpy.vstack((self.__buffer, data))
500 self.__profIndex += 1
500 self.__profIndex += 1
501 return
501 return
502
502
503 #If the buffer length is equal to n then replacing the last buffer value with the data value
503 #If the buffer length is equal to n then replacing the last buffer value with the data value
504 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
504 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
505 self.__buffer[self.n-1] = data
505 self.__buffer[self.n-1] = data
506 self.__profIndex = self.n
506 self.__profIndex = self.n
507 return
507 return
508
508
509
509
510 def pushData(self):
510 def pushData(self):
511 """
511 """
512 Return the sum of the last profiles and the profiles used in the sum.
512 Return the sum of the last profiles and the profiles used in the sum.
513
513
514 Affected:
514 Affected:
515
515
516 self.__profileIndex
516 self.__profileIndex
517
517
518 """
518 """
519
519
520 if not self.__withOverlapping:
520 if not self.__withOverlapping:
521 data = self.__buffer
521 data = self.__buffer
522 n = self.__profIndex
522 n = self.__profIndex
523
523
524 self.__buffer = 0
524 self.__buffer = 0
525 self.__profIndex = 0
525 self.__profIndex = 0
526
526
527 return data, n
527 return data, n
528
528
529 #Integration with Overlapping
529 #Integration with Overlapping
530 data = numpy.sum(self.__buffer, axis=0)
530 data = numpy.sum(self.__buffer, axis=0)
531 # print data
531 # print data
532 # raise
532 # raise
533 n = self.__profIndex
533 n = self.__profIndex
534
534
535 return data, n
535 return data, n
536
536
537 def byProfiles(self, data):
537 def byProfiles(self, data):
538
538
539 self.__dataReady = False
539 self.__dataReady = False
540 avgdata = None
540 avgdata = None
541 # n = None
541 # n = None
542 # print data
542 # print data
543 # raise
543 # raise
544 self.putData(data)
544 self.putData(data)
545
545
546 if self.__profIndex == self.n:
546 if self.__profIndex == self.n:
547 avgdata, n = self.pushData()
547 avgdata, n = self.pushData()
548 self.__dataReady = True
548 self.__dataReady = True
549
549
550 return avgdata
550 return avgdata
551
551
552 def byTime(self, data, datatime):
552 def byTime(self, data, datatime):
553
553
554 self.__dataReady = False
554 self.__dataReady = False
555 avgdata = None
555 avgdata = None
556 n = None
556 n = None
557
557
558 self.putData(data)
558 self.putData(data)
559
559
560 if (datatime - self.__initime) >= self.__integrationtime:
560 if (datatime - self.__initime) >= self.__integrationtime:
561 avgdata, n = self.pushData()
561 avgdata, n = self.pushData()
562 self.n = n
562 self.n = n
563 self.__dataReady = True
563 self.__dataReady = True
564
564
565 return avgdata
565 return avgdata
566
566
567 def integrateByStride(self, data, datatime):
567 def integrateByStride(self, data, datatime):
568 # print data
568 # print data
569 if self.__profIndex == 0:
569 if self.__profIndex == 0:
570 self.__buffer = [[data.copy(), datatime]]
570 self.__buffer = [[data.copy(), datatime]]
571 else:
571 else:
572 self.__buffer.append([data.copy(),datatime])
572 self.__buffer.append([data.copy(),datatime])
573 self.__profIndex += 1
573 self.__profIndex += 1
574 self.__dataReady = False
574 self.__dataReady = False
575
575
576 if self.__profIndex == self.n * self.stride :
576 if self.__profIndex == self.n * self.stride :
577 self.__dataToPutStride = True
577 self.__dataToPutStride = True
578 self.__profIndexStride = 0
578 self.__profIndexStride = 0
579 self.__profIndex = 0
579 self.__profIndex = 0
580 self.__bufferStride = []
580 self.__bufferStride = []
581 for i in range(self.stride):
581 for i in range(self.stride):
582 current = self.__buffer[i::self.stride]
582 current = self.__buffer[i::self.stride]
583 data = numpy.sum([t[0] for t in current], axis=0)
583 data = numpy.sum([t[0] for t in current], axis=0)
584 avgdatatime = numpy.average([t[1] for t in current])
584 avgdatatime = numpy.average([t[1] for t in current])
585 # print data
585 # print data
586 self.__bufferStride.append((data, avgdatatime))
586 self.__bufferStride.append((data, avgdatatime))
587
587
588 if self.__dataToPutStride:
588 if self.__dataToPutStride:
589 self.__dataReady = True
589 self.__dataReady = True
590 self.__profIndexStride += 1
590 self.__profIndexStride += 1
591 if self.__profIndexStride == self.stride:
591 if self.__profIndexStride == self.stride:
592 self.__dataToPutStride = False
592 self.__dataToPutStride = False
593 # print self.__bufferStride[self.__profIndexStride - 1]
593 # print self.__bufferStride[self.__profIndexStride - 1]
594 # raise
594 # raise
595 return self.__bufferStride[self.__profIndexStride - 1]
595 return self.__bufferStride[self.__profIndexStride - 1]
596
596
597
597
598 return None, None
598 return None, None
599
599
600 def integrate(self, data, datatime=None):
600 def integrate(self, data, datatime=None):
601
601
602 if self.__initime == None:
602 if self.__initime == None:
603 self.__initime = datatime
603 self.__initime = datatime
604
604
605 if self.__byTime:
605 if self.__byTime:
606 avgdata = self.byTime(data, datatime)
606 avgdata = self.byTime(data, datatime)
607 else:
607 else:
608 avgdata = self.byProfiles(data)
608 avgdata = self.byProfiles(data)
609
609
610
610
611 self.__lastdatatime = datatime
611 self.__lastdatatime = datatime
612
612
613 if avgdata is None:
613 if avgdata is None:
614 return None, None
614 return None, None
615
615
616 avgdatatime = self.__initime
616 avgdatatime = self.__initime
617
617
618 deltatime = datatime - self.__lastdatatime
618 deltatime = datatime - self.__lastdatatime
619
619
620 if not self.__withOverlapping:
620 if not self.__withOverlapping:
621 self.__initime = datatime
621 self.__initime = datatime
622 else:
622 else:
623 self.__initime += deltatime
623 self.__initime += deltatime
624
624
625 return avgdata, avgdatatime
625 return avgdata, avgdatatime
626
626
627 def integrateByBlock(self, dataOut):
627 def integrateByBlock(self, dataOut):
628
628
629 times = int(dataOut.data.shape[1]/self.n)
629 times = int(dataOut.data.shape[1]/self.n)
630 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
630 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
631
631
632 id_min = 0
632 id_min = 0
633 id_max = self.n
633 id_max = self.n
634
634
635 for i in range(times):
635 for i in range(times):
636 junk = dataOut.data[:,id_min:id_max,:]
636 junk = dataOut.data[:,id_min:id_max,:]
637 avgdata[:,i,:] = junk.sum(axis=1)
637 avgdata[:,i,:] = junk.sum(axis=1)
638 id_min += self.n
638 id_min += self.n
639 id_max += self.n
639 id_max += self.n
640
640
641 timeInterval = dataOut.ippSeconds*self.n
641 timeInterval = dataOut.ippSeconds*self.n
642 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
642 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
643 self.__dataReady = True
643 self.__dataReady = True
644 return avgdata, avgdatatime
644 return avgdata, avgdatatime
645
645
646 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
646 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
647
647
648 if not self.isConfig:
648 if not self.isConfig:
649 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
649 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
650 self.isConfig = True
650 self.isConfig = True
651
651
652 if dataOut.flagDataAsBlock:
652 if dataOut.flagDataAsBlock:
653 """
653 """
654 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
654 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
655 """
655 """
656 avgdata, avgdatatime = self.integrateByBlock(dataOut)
656 avgdata, avgdatatime = self.integrateByBlock(dataOut)
657 dataOut.nProfiles /= self.n
657 dataOut.nProfiles /= self.n
658 else:
658 else:
659 if stride is None:
659 if stride is None:
660 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
660 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
661 else:
661 else:
662 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
662 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
663
663
664
664
665 # dataOut.timeInterval *= n
665 # dataOut.timeInterval *= n
666 dataOut.flagNoData = True
666 dataOut.flagNoData = True
667
667
668 if self.__dataReady:
668 if self.__dataReady:
669 dataOut.data = avgdata
669 dataOut.data = avgdata
670 if not dataOut.flagCohInt:
670 if not dataOut.flagCohInt:
671 dataOut.nCohInt *= self.n
671 dataOut.nCohInt *= self.n
672 dataOut.flagCohInt = True
672 dataOut.flagCohInt = True
673 ####################################dataOut.utctime = avgdatatime
673 ####################################dataOut.utctime = avgdatatime
674 # print avgdata, avgdatatime
674 # print avgdata, avgdatatime
675 # raise
675 # raise
676 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
676 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
677 dataOut.flagNoData = False
677 dataOut.flagNoData = False
678 return dataOut
678 return dataOut
679
679
680 class Decoder(Operation):
680 class Decoder(Operation):
681
681
682 isConfig = False
682 isConfig = False
683 __profIndex = 0
683 __profIndex = 0
684
684
685 code = None
685 code = None
686
686
687 nCode = None
687 nCode = None
688 nBaud = None
688 nBaud = None
689
689
690 def __init__(self, **kwargs):
690 def __init__(self, **kwargs):
691
691
692 Operation.__init__(self, **kwargs)
692 Operation.__init__(self, **kwargs)
693
693
694 self.times = None
694 self.times = None
695 self.osamp = None
695 self.osamp = None
696 # self.__setValues = False
696 # self.__setValues = False
697 self.isConfig = False
697 self.isConfig = False
698 self.setupReq = False
698 self.setupReq = False
699 def setup(self, code, osamp, dataOut):
699 def setup(self, code, osamp, dataOut):
700
700
701 self.__profIndex = 0
701 self.__profIndex = 0
702
702
703 self.code = code
703 self.code = code
704
704
705 self.nCode = len(code)
705 self.nCode = len(code)
706 self.nBaud = len(code[0])
706 self.nBaud = len(code[0])
707
707
708 if (osamp != None) and (osamp >1):
708 if (osamp != None) and (osamp >1):
709 self.osamp = osamp
709 self.osamp = osamp
710 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
710 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
711 self.nBaud = self.nBaud*self.osamp
711 self.nBaud = self.nBaud*self.osamp
712
712
713 self.__nChannels = dataOut.nChannels
713 self.__nChannels = dataOut.nChannels
714 self.__nProfiles = dataOut.nProfiles
714 self.__nProfiles = dataOut.nProfiles
715 self.__nHeis = dataOut.nHeights
715 self.__nHeis = dataOut.nHeights
716
716
717 if self.__nHeis < self.nBaud:
717 if self.__nHeis < self.nBaud:
718 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
718 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
719
719
720 #Frequency
720 #Frequency
721 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
721 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
722
722
723 __codeBuffer[:,0:self.nBaud] = self.code
723 __codeBuffer[:,0:self.nBaud] = self.code
724
724
725 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
725 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
726
726
727 if dataOut.flagDataAsBlock:
727 if dataOut.flagDataAsBlock:
728
728
729 self.ndatadec = self.__nHeis #- self.nBaud + 1
729 self.ndatadec = self.__nHeis #- self.nBaud + 1
730
730
731 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
731 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
732
732
733 else:
733 else:
734
734
735 #Time
735 #Time
736 self.ndatadec = self.__nHeis #- self.nBaud + 1
736 self.ndatadec = self.__nHeis #- self.nBaud + 1
737
737
738 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
738 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
739
739
740 def __convolutionInFreq(self, data):
740 def __convolutionInFreq(self, data):
741
741
742 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
742 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
743
743
744 fft_data = numpy.fft.fft(data, axis=1)
744 fft_data = numpy.fft.fft(data, axis=1)
745
745
746 conv = fft_data*fft_code
746 conv = fft_data*fft_code
747
747
748 data = numpy.fft.ifft(conv,axis=1)
748 data = numpy.fft.ifft(conv,axis=1)
749
749
750 return data
750 return data
751
751
752 def __convolutionInFreqOpt(self, data):
752 def __convolutionInFreqOpt(self, data):
753
753
754 raise NotImplementedError
754 raise NotImplementedError
755
755
756 def __convolutionInTime(self, data):
756 def __convolutionInTime(self, data):
757
757
758 code = self.code[self.__profIndex]
758 code = self.code[self.__profIndex]
759 for i in range(self.__nChannels):
759 for i in range(self.__nChannels):
760 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
760 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
761
761
762 return self.datadecTime
762 return self.datadecTime
763
763
764 def __convolutionByBlockInTime(self, data):
764 def __convolutionByBlockInTime(self, data):
765
765
766 repetitions = int(self.__nProfiles / self.nCode)
766 repetitions = int(self.__nProfiles / self.nCode)
767 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
767 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
768 junk = junk.flatten()
768 junk = junk.flatten()
769 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
769 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
770 profilesList = range(self.__nProfiles)
770 profilesList = range(self.__nProfiles)
771
771
772 for i in range(self.__nChannels):
772 for i in range(self.__nChannels):
773 for j in profilesList:
773 for j in profilesList:
774 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
774 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
775 return self.datadecTime
775 return self.datadecTime
776
776
777 def __convolutionByBlockInFreq(self, data):
777 def __convolutionByBlockInFreq(self, data):
778
778
779 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
779 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
780
780
781
781
782 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
782 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
783
783
784 fft_data = numpy.fft.fft(data, axis=2)
784 fft_data = numpy.fft.fft(data, axis=2)
785
785
786 conv = fft_data*fft_code
786 conv = fft_data*fft_code
787
787
788 data = numpy.fft.ifft(conv,axis=2)
788 data = numpy.fft.ifft(conv,axis=2)
789
789
790 return data
790 return data
791
791
792
792
793 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
793 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
794
794
795 if dataOut.flagDecodeData:
795 if dataOut.flagDecodeData:
796 print("This data is already decoded, recoding again ...")
796 print("This data is already decoded, recoding again ...")
797
797
798 if not self.isConfig:
798 if not self.isConfig:
799
799
800 if code is None:
800 if code is None:
801 if dataOut.code is None:
801 if dataOut.code is None:
802 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
802 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
803
803
804 code = dataOut.code
804 code = dataOut.code
805 else:
805 else:
806 code = numpy.array(code).reshape(nCode,nBaud)
806 code = numpy.array(code).reshape(nCode,nBaud)
807 self.setup(code, osamp, dataOut)
807 self.setup(code, osamp, dataOut)
808
808
809 self.isConfig = True
809 self.isConfig = True
810
810
811 if mode == 3:
811 if mode == 3:
812 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
812 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
813
813
814 if times != None:
814 if times != None:
815 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
815 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
816
816
817 if self.code is None:
817 if self.code is None:
818 print("Fail decoding: Code is not defined.")
818 print("Fail decoding: Code is not defined.")
819 return
819 return
820
820
821 self.__nProfiles = dataOut.nProfiles
821 self.__nProfiles = dataOut.nProfiles
822 datadec = None
822 datadec = None
823
823
824 if mode == 3:
824 if mode == 3:
825 mode = 0
825 mode = 0
826
826
827 if dataOut.flagDataAsBlock:
827 if dataOut.flagDataAsBlock:
828 """
828 """
829 Decoding when data have been read as block,
829 Decoding when data have been read as block,
830 """
830 """
831
831
832 if mode == 0:
832 if mode == 0:
833 datadec = self.__convolutionByBlockInTime(dataOut.data)
833 datadec = self.__convolutionByBlockInTime(dataOut.data)
834 if mode == 1:
834 if mode == 1:
835 datadec = self.__convolutionByBlockInFreq(dataOut.data)
835 datadec = self.__convolutionByBlockInFreq(dataOut.data)
836 else:
836 else:
837 """
837 """
838 Decoding when data have been read profile by profile
838 Decoding when data have been read profile by profile
839 """
839 """
840 if mode == 0:
840 if mode == 0:
841 datadec = self.__convolutionInTime(dataOut.data)
841 datadec = self.__convolutionInTime(dataOut.data)
842
842
843 if mode == 1:
843 if mode == 1:
844 datadec = self.__convolutionInFreq(dataOut.data)
844 datadec = self.__convolutionInFreq(dataOut.data)
845
845
846 if mode == 2:
846 if mode == 2:
847 datadec = self.__convolutionInFreqOpt(dataOut.data)
847 datadec = self.__convolutionInFreqOpt(dataOut.data)
848
848
849 if datadec is None:
849 if datadec is None:
850 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
850 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
851
851
852 dataOut.code = self.code
852 dataOut.code = self.code
853 dataOut.nCode = self.nCode
853 dataOut.nCode = self.nCode
854 dataOut.nBaud = self.nBaud
854 dataOut.nBaud = self.nBaud
855
855
856 dataOut.data = datadec
856 dataOut.data = datadec
857
857
858 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
858 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
859
859
860 dataOut.flagDecodeData = True #asumo q la data esta decodificada
860 dataOut.flagDecodeData = True #asumo q la data esta decodificada
861
861
862 if self.__profIndex == self.nCode-1:
862 if self.__profIndex == self.nCode-1:
863 self.__profIndex = 0
863 self.__profIndex = 0
864 return dataOut
864 return dataOut
865
865
866 self.__profIndex += 1
866 self.__profIndex += 1
867
867
868 return dataOut
868 return dataOut
869 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
869 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
870
870
871
871
872 class ProfileConcat(Operation):
872 class ProfileConcat(Operation):
873
873
874 isConfig = False
874 isConfig = False
875 buffer = None
875 buffer = None
876
876
877 def __init__(self, **kwargs):
877 def __init__(self, **kwargs):
878
878
879 Operation.__init__(self, **kwargs)
879 Operation.__init__(self, **kwargs)
880 self.profileIndex = 0
880 self.profileIndex = 0
881
881
882 def reset(self):
882 def reset(self):
883 self.buffer = numpy.zeros_like(self.buffer)
883 self.buffer = numpy.zeros_like(self.buffer)
884 self.start_index = 0
884 self.start_index = 0
885 self.times = 1
885 self.times = 1
886
886
887 def setup(self, data, m, n=1):
887 def setup(self, data, m, n=1):
888 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
888 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
889 self.nHeights = data.shape[1]#.nHeights
889 self.nHeights = data.shape[1]#.nHeights
890 self.start_index = 0
890 self.start_index = 0
891 self.times = 1
891 self.times = 1
892
892
893 def concat(self, data):
893 def concat(self, data):
894
894
895 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
895 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
896 self.start_index = self.start_index + self.nHeights
896 self.start_index = self.start_index + self.nHeights
897
897
898 def run(self, dataOut, m):
898 def run(self, dataOut, m):
899 dataOut.flagNoData = True
899 dataOut.flagNoData = True
900
900
901 if not self.isConfig:
901 if not self.isConfig:
902 self.setup(dataOut.data, m, 1)
902 self.setup(dataOut.data, m, 1)
903 self.isConfig = True
903 self.isConfig = True
904
904
905 if dataOut.flagDataAsBlock:
905 if dataOut.flagDataAsBlock:
906 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
906 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
907
907
908 else:
908 else:
909 self.concat(dataOut.data)
909 self.concat(dataOut.data)
910 self.times += 1
910 self.times += 1
911 if self.times > m:
911 if self.times > m:
912 dataOut.data = self.buffer
912 dataOut.data = self.buffer
913 self.reset()
913 self.reset()
914 dataOut.flagNoData = False
914 dataOut.flagNoData = False
915 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
915 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
916 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
916 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
917 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
917 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
918 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
918 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
919 dataOut.ippSeconds *= m
919 dataOut.ippSeconds *= m
920 return dataOut
920 return dataOut
921
921
922 class ProfileSelector(Operation):
922 class ProfileSelector(Operation):
923
923
924 profileIndex = None
924 profileIndex = None
925 # Tamanho total de los perfiles
925 # Tamanho total de los perfiles
926 nProfiles = None
926 nProfiles = None
927
927
928 def __init__(self, **kwargs):
928 def __init__(self, **kwargs):
929
929
930 Operation.__init__(self, **kwargs)
930 Operation.__init__(self, **kwargs)
931 self.profileIndex = 0
931 self.profileIndex = 0
932
932
933 def incProfileIndex(self):
933 def incProfileIndex(self):
934
934
935 self.profileIndex += 1
935 self.profileIndex += 1
936
936
937 if self.profileIndex >= self.nProfiles:
937 if self.profileIndex >= self.nProfiles:
938 self.profileIndex = 0
938 self.profileIndex = 0
939
939
940 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
940 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
941
941
942 if profileIndex < minIndex:
942 if profileIndex < minIndex:
943 return False
943 return False
944
944
945 if profileIndex > maxIndex:
945 if profileIndex > maxIndex:
946 return False
946 return False
947
947
948 return True
948 return True
949
949
950 def isThisProfileInList(self, profileIndex, profileList):
950 def isThisProfileInList(self, profileIndex, profileList):
951
951
952 if profileIndex not in profileList:
952 if profileIndex not in profileList:
953 return False
953 return False
954
954
955 return True
955 return True
956
956
957 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
957 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
958 #print("before",dataOut.data.shape)
958 #print("before",dataOut.data.shape)
959 """
959 """
960 ProfileSelector:
960 ProfileSelector:
961
961
962 Inputs:
962 Inputs:
963 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
963 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
964
964
965 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
965 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
966
966
967 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
967 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
968
968
969 """
969 """
970
970
971 if rangeList is not None:
971 if rangeList is not None:
972 if type(rangeList[0]) not in (tuple, list):
972 if type(rangeList[0]) not in (tuple, list):
973 rangeList = [rangeList]
973 rangeList = [rangeList]
974
974
975 dataOut.flagNoData = True
975 dataOut.flagNoData = True
976
976
977 if dataOut.flagDataAsBlock:
977 if dataOut.flagDataAsBlock:
978 """
978 """
979 data dimension = [nChannels, nProfiles, nHeis]
979 data dimension = [nChannels, nProfiles, nHeis]
980 """
980 """
981 if profileList != None:
981 if profileList != None:
982 dataOut.data = dataOut.data[:,profileList,:]
982 dataOut.data = dataOut.data[:,profileList,:]
983
983
984 if profileRangeList != None:
984 if profileRangeList != None:
985 minIndex = profileRangeList[0]
985 minIndex = profileRangeList[0]
986 maxIndex = profileRangeList[1]
986 maxIndex = profileRangeList[1]
987 profileList = list(range(minIndex, maxIndex+1))
987 profileList = list(range(minIndex, maxIndex+1))
988
988
989 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
989 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
990
990
991 if rangeList != None:
991 if rangeList != None:
992
992
993 profileList = []
993 profileList = []
994
994
995 for thisRange in rangeList:
995 for thisRange in rangeList:
996 minIndex = thisRange[0]
996 minIndex = thisRange[0]
997 maxIndex = thisRange[1]
997 maxIndex = thisRange[1]
998
998
999 profileList.extend(list(range(minIndex, maxIndex+1)))
999 profileList.extend(list(range(minIndex, maxIndex+1)))
1000
1000
1001 dataOut.data = dataOut.data[:,profileList,:]
1001 dataOut.data = dataOut.data[:,profileList,:]
1002
1002
1003 dataOut.nProfiles = len(profileList)
1003 dataOut.nProfiles = len(profileList)
1004 dataOut.profileIndex = dataOut.nProfiles - 1
1004 dataOut.profileIndex = dataOut.nProfiles - 1
1005 dataOut.flagNoData = False
1005 dataOut.flagNoData = False
1006 #print(dataOut.data.shape)
1006 #print(dataOut.data.shape)
1007 return dataOut
1007 return dataOut
1008
1008
1009 """
1009 """
1010 data dimension = [nChannels, nHeis]
1010 data dimension = [nChannels, nHeis]
1011 """
1011 """
1012
1012
1013 if profileList != None:
1013 if profileList != None:
1014
1014
1015 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1015 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1016
1016
1017 self.nProfiles = len(profileList)
1017 self.nProfiles = len(profileList)
1018 dataOut.nProfiles = self.nProfiles
1018 dataOut.nProfiles = self.nProfiles
1019 dataOut.profileIndex = self.profileIndex
1019 dataOut.profileIndex = self.profileIndex
1020 dataOut.flagNoData = False
1020 dataOut.flagNoData = False
1021
1021
1022 self.incProfileIndex()
1022 self.incProfileIndex()
1023 return dataOut
1023 return dataOut
1024
1024
1025 if profileRangeList != None:
1025 if profileRangeList != None:
1026
1026
1027 minIndex = profileRangeList[0]
1027 minIndex = profileRangeList[0]
1028 maxIndex = profileRangeList[1]
1028 maxIndex = profileRangeList[1]
1029
1029
1030 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1030 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1031
1031
1032 self.nProfiles = maxIndex - minIndex + 1
1032 self.nProfiles = maxIndex - minIndex + 1
1033 dataOut.nProfiles = self.nProfiles
1033 dataOut.nProfiles = self.nProfiles
1034 dataOut.profileIndex = self.profileIndex
1034 dataOut.profileIndex = self.profileIndex
1035 dataOut.flagNoData = False
1035 dataOut.flagNoData = False
1036
1036
1037 self.incProfileIndex()
1037 self.incProfileIndex()
1038 return dataOut
1038 return dataOut
1039
1039
1040 if rangeList != None:
1040 if rangeList != None:
1041
1041
1042 nProfiles = 0
1042 nProfiles = 0
1043
1043
1044 for thisRange in rangeList:
1044 for thisRange in rangeList:
1045 minIndex = thisRange[0]
1045 minIndex = thisRange[0]
1046 maxIndex = thisRange[1]
1046 maxIndex = thisRange[1]
1047
1047
1048 nProfiles += maxIndex - minIndex + 1
1048 nProfiles += maxIndex - minIndex + 1
1049
1049
1050 for thisRange in rangeList:
1050 for thisRange in rangeList:
1051
1051
1052 minIndex = thisRange[0]
1052 minIndex = thisRange[0]
1053 maxIndex = thisRange[1]
1053 maxIndex = thisRange[1]
1054
1054
1055 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1055 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1056
1056
1057 self.nProfiles = nProfiles
1057 self.nProfiles = nProfiles
1058 dataOut.nProfiles = self.nProfiles
1058 dataOut.nProfiles = self.nProfiles
1059 dataOut.profileIndex = self.profileIndex
1059 dataOut.profileIndex = self.profileIndex
1060 dataOut.flagNoData = False
1060 dataOut.flagNoData = False
1061
1061
1062 self.incProfileIndex()
1062 self.incProfileIndex()
1063
1063
1064 break
1064 break
1065
1065
1066 return dataOut
1066 return dataOut
1067
1067
1068
1068
1069 if beam != None: #beam is only for AMISR data
1069 if beam != None: #beam is only for AMISR data
1070 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1070 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1071 dataOut.flagNoData = False
1071 dataOut.flagNoData = False
1072 dataOut.profileIndex = self.profileIndex
1072 dataOut.profileIndex = self.profileIndex
1073
1073
1074 self.incProfileIndex()
1074 self.incProfileIndex()
1075
1075
1076 return dataOut
1076 return dataOut
1077
1077
1078 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1078 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1079
1079
1080
1080
1081 class Reshaper(Operation):
1081 class Reshaper(Operation):
1082
1082
1083 def __init__(self, **kwargs):
1083 def __init__(self, **kwargs):
1084
1084
1085 Operation.__init__(self, **kwargs)
1085 Operation.__init__(self, **kwargs)
1086
1086
1087 self.__buffer = None
1087 self.__buffer = None
1088 self.__nitems = 0
1088 self.__nitems = 0
1089
1089
1090 def __appendProfile(self, dataOut, nTxs):
1090 def __appendProfile(self, dataOut, nTxs):
1091
1091
1092 if self.__buffer is None:
1092 if self.__buffer is None:
1093 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1093 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1094 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1094 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1095
1095
1096 ini = dataOut.nHeights * self.__nitems
1096 ini = dataOut.nHeights * self.__nitems
1097 end = ini + dataOut.nHeights
1097 end = ini + dataOut.nHeights
1098
1098
1099 self.__buffer[:, ini:end] = dataOut.data
1099 self.__buffer[:, ini:end] = dataOut.data
1100
1100
1101 self.__nitems += 1
1101 self.__nitems += 1
1102
1102
1103 return int(self.__nitems*nTxs)
1103 return int(self.__nitems*nTxs)
1104
1104
1105 def __getBuffer(self):
1105 def __getBuffer(self):
1106
1106
1107 if self.__nitems == int(1./self.__nTxs):
1107 if self.__nitems == int(1./self.__nTxs):
1108
1108
1109 self.__nitems = 0
1109 self.__nitems = 0
1110
1110
1111 return self.__buffer.copy()
1111 return self.__buffer.copy()
1112
1112
1113 return None
1113 return None
1114
1114
1115 def __checkInputs(self, dataOut, shape, nTxs):
1115 def __checkInputs(self, dataOut, shape, nTxs):
1116
1116
1117 if shape is None and nTxs is None:
1117 if shape is None and nTxs is None:
1118 raise ValueError("Reshaper: shape of factor should be defined")
1118 raise ValueError("Reshaper: shape of factor should be defined")
1119
1119
1120 if nTxs:
1120 if nTxs:
1121 if nTxs < 0:
1121 if nTxs < 0:
1122 raise ValueError("nTxs should be greater than 0")
1122 raise ValueError("nTxs should be greater than 0")
1123
1123
1124 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1124 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1125 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1125 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1126
1126
1127 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1127 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1128
1128
1129 return shape, nTxs
1129 return shape, nTxs
1130
1130
1131 if len(shape) != 2 and len(shape) != 3:
1131 if len(shape) != 2 and len(shape) != 3:
1132 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1132 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1133
1133
1134 if len(shape) == 2:
1134 if len(shape) == 2:
1135 shape_tuple = [dataOut.nChannels]
1135 shape_tuple = [dataOut.nChannels]
1136 shape_tuple.extend(shape)
1136 shape_tuple.extend(shape)
1137 else:
1137 else:
1138 shape_tuple = list(shape)
1138 shape_tuple = list(shape)
1139
1139
1140 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1140 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1141
1141
1142 return shape_tuple, nTxs
1142 return shape_tuple, nTxs
1143
1143
1144 def run(self, dataOut, shape=None, nTxs=None):
1144 def run(self, dataOut, shape=None, nTxs=None):
1145
1145
1146 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1146 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1147
1147
1148 dataOut.flagNoData = True
1148 dataOut.flagNoData = True
1149 profileIndex = None
1149 profileIndex = None
1150
1150
1151 if dataOut.flagDataAsBlock:
1151 if dataOut.flagDataAsBlock:
1152
1152
1153 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1153 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1154 dataOut.flagNoData = False
1154 dataOut.flagNoData = False
1155
1155
1156 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1156 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1157
1157
1158 else:
1158 else:
1159
1159
1160 if self.__nTxs < 1:
1160 if self.__nTxs < 1:
1161
1161
1162 self.__appendProfile(dataOut, self.__nTxs)
1162 self.__appendProfile(dataOut, self.__nTxs)
1163 new_data = self.__getBuffer()
1163 new_data = self.__getBuffer()
1164
1164
1165 if new_data is not None:
1165 if new_data is not None:
1166 dataOut.data = new_data
1166 dataOut.data = new_data
1167 dataOut.flagNoData = False
1167 dataOut.flagNoData = False
1168
1168
1169 profileIndex = dataOut.profileIndex*nTxs
1169 profileIndex = dataOut.profileIndex*nTxs
1170
1170
1171 else:
1171 else:
1172 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1172 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1173
1173
1174 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1174 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1175
1175
1176 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1176 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1177
1177
1178 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1178 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1179
1179
1180 dataOut.profileIndex = profileIndex
1180 dataOut.profileIndex = profileIndex
1181
1181
1182 dataOut.ippSeconds /= self.__nTxs
1182 dataOut.ippSeconds /= self.__nTxs
1183
1183
1184 return dataOut
1184 return dataOut
1185
1185
1186 class SplitProfiles(Operation):
1186 class SplitProfiles(Operation):
1187
1187
1188 def __init__(self, **kwargs):
1188 def __init__(self, **kwargs):
1189
1189
1190 Operation.__init__(self, **kwargs)
1190 Operation.__init__(self, **kwargs)
1191
1191
1192 def run(self, dataOut, n):
1192 def run(self, dataOut, n):
1193
1193
1194 dataOut.flagNoData = True
1194 dataOut.flagNoData = True
1195 profileIndex = None
1195 profileIndex = None
1196
1196
1197 if dataOut.flagDataAsBlock:
1197 if dataOut.flagDataAsBlock:
1198
1198
1199 #nchannels, nprofiles, nsamples
1199 #nchannels, nprofiles, nsamples
1200 shape = dataOut.data.shape
1200 shape = dataOut.data.shape
1201
1201
1202 if shape[2] % n != 0:
1202 if shape[2] % n != 0:
1203 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1203 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1204
1204
1205 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1205 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1206
1206
1207 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1207 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1208 dataOut.flagNoData = False
1208 dataOut.flagNoData = False
1209
1209
1210 profileIndex = int(dataOut.nProfiles/n) - 1
1210 profileIndex = int(dataOut.nProfiles/n) - 1
1211
1211
1212 else:
1212 else:
1213
1213
1214 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1214 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1215
1215
1216 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1216 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1217
1217
1218 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1218 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1219
1219
1220 dataOut.nProfiles = int(dataOut.nProfiles*n)
1220 dataOut.nProfiles = int(dataOut.nProfiles*n)
1221
1221
1222 dataOut.profileIndex = profileIndex
1222 dataOut.profileIndex = profileIndex
1223
1223
1224 dataOut.ippSeconds /= n
1224 dataOut.ippSeconds /= n
1225
1225
1226 return dataOut
1226 return dataOut
1227
1227
1228 class CombineProfiles(Operation):
1228 class CombineProfiles(Operation):
1229 def __init__(self, **kwargs):
1229 def __init__(self, **kwargs):
1230
1230
1231 Operation.__init__(self, **kwargs)
1231 Operation.__init__(self, **kwargs)
1232
1232
1233 self.__remData = None
1233 self.__remData = None
1234 self.__profileIndex = 0
1234 self.__profileIndex = 0
1235
1235
1236 def run(self, dataOut, n):
1236 def run(self, dataOut, n):
1237
1237
1238 dataOut.flagNoData = True
1238 dataOut.flagNoData = True
1239 profileIndex = None
1239 profileIndex = None
1240
1240
1241 if dataOut.flagDataAsBlock:
1241 if dataOut.flagDataAsBlock:
1242
1242
1243 #nchannels, nprofiles, nsamples
1243 #nchannels, nprofiles, nsamples
1244 shape = dataOut.data.shape
1244 shape = dataOut.data.shape
1245 new_shape = shape[0], shape[1]/n, shape[2]*n
1245 new_shape = shape[0], shape[1]/n, shape[2]*n
1246
1246
1247 if shape[1] % n != 0:
1247 if shape[1] % n != 0:
1248 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1248 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1249
1249
1250 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1250 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1251 dataOut.flagNoData = False
1251 dataOut.flagNoData = False
1252
1252
1253 profileIndex = int(dataOut.nProfiles*n) - 1
1253 profileIndex = int(dataOut.nProfiles*n) - 1
1254
1254
1255 else:
1255 else:
1256
1256
1257 #nchannels, nsamples
1257 #nchannels, nsamples
1258 if self.__remData is None:
1258 if self.__remData is None:
1259 newData = dataOut.data
1259 newData = dataOut.data
1260 else:
1260 else:
1261 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1261 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1262
1262
1263 self.__profileIndex += 1
1263 self.__profileIndex += 1
1264
1264
1265 if self.__profileIndex < n:
1265 if self.__profileIndex < n:
1266 self.__remData = newData
1266 self.__remData = newData
1267 #continue
1267 #continue
1268 return
1268 return
1269
1269
1270 self.__profileIndex = 0
1270 self.__profileIndex = 0
1271 self.__remData = None
1271 self.__remData = None
1272
1272
1273 dataOut.data = newData
1273 dataOut.data = newData
1274 dataOut.flagNoData = False
1274 dataOut.flagNoData = False
1275
1275
1276 profileIndex = dataOut.profileIndex/n
1276 profileIndex = dataOut.profileIndex/n
1277
1277
1278
1278
1279 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1279 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1280
1280
1281 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1281 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1282
1282
1283 dataOut.nProfiles = int(dataOut.nProfiles/n)
1283 dataOut.nProfiles = int(dataOut.nProfiles/n)
1284
1284
1285 dataOut.profileIndex = profileIndex
1285 dataOut.profileIndex = profileIndex
1286
1286
1287 dataOut.ippSeconds *= n
1287 dataOut.ippSeconds *= n
1288
1288
1289 return dataOut
1289 return dataOut
1290
1290
1291 class PulsePair(Operation):
1291 class PulsePair(Operation):
1292 '''
1292 '''
1293 Function PulsePair(Signal Power, Velocity)
1293 Function PulsePair(Signal Power, Velocity)
1294 The real component of Lag[0] provides Intensity Information
1294 The real component of Lag[0] provides Intensity Information
1295 The imag component of Lag[1] Phase provides Velocity Information
1295 The imag component of Lag[1] Phase provides Velocity Information
1296
1296
1297 Configuration Parameters:
1297 Configuration Parameters:
1298 nPRF = Number of Several PRF
1298 nPRF = Number of Several PRF
1299 theta = Degree Azimuth angel Boundaries
1299 theta = Degree Azimuth angel Boundaries
1300
1300
1301 Input:
1301 Input:
1302 self.dataOut
1302 self.dataOut
1303 lag[N]
1303 lag[N]
1304 Affected:
1304 Affected:
1305 self.dataOut.spc
1305 self.dataOut.spc
1306 '''
1306 '''
1307 isConfig = False
1307 isConfig = False
1308 __profIndex = 0
1308 __profIndex = 0
1309 __initime = None
1309 __initime = None
1310 __lastdatatime = None
1310 __lastdatatime = None
1311 __buffer = None
1311 __buffer = None
1312 noise = None
1312 noise = None
1313 __dataReady = False
1313 __dataReady = False
1314 n = None
1314 n = None
1315 __nch = 0
1315 __nch = 0
1316 __nHeis = 0
1316 __nHeis = 0
1317 removeDC = False
1317 removeDC = False
1318 ipp = None
1318 ipp = None
1319 lambda_ = 0
1319 lambda_ = 0
1320
1320
1321 def __init__(self,**kwargs):
1321 def __init__(self,**kwargs):
1322 Operation.__init__(self,**kwargs)
1322 Operation.__init__(self,**kwargs)
1323
1323
1324 def setup(self, dataOut, n = None, removeDC=False):
1324 def setup(self, dataOut, n = None, removeDC=False):
1325 '''
1325 '''
1326 n= Numero de PRF's de entrada
1326 n= Numero de PRF's de entrada
1327 '''
1327 '''
1328 self.__initime = None
1328 self.__initime = None
1329 ####print("[INICIO]-setup del METODO PULSE PAIR")
1329 ####print("[INICIO]-setup del METODO PULSE PAIR")
1330 self.__lastdatatime = 0
1330 self.__lastdatatime = 0
1331 self.__dataReady = False
1331 self.__dataReady = False
1332 self.__buffer = 0
1332 self.__buffer = 0
1333 self.__profIndex = 0
1333 self.__profIndex = 0
1334 self.noise = None
1334 self.noise = None
1335 self.__nch = dataOut.nChannels
1335 self.__nch = dataOut.nChannels
1336 self.__nHeis = dataOut.nHeights
1336 self.__nHeis = dataOut.nHeights
1337 self.removeDC = removeDC
1337 self.removeDC = removeDC
1338 self.lambda_ = 3.0e8/(9345.0e6)
1338 self.lambda_ = 3.0e8/(9345.0e6)
1339 self.ippSec = dataOut.ippSeconds
1339 self.ippSec = dataOut.ippSeconds
1340 self.nCohInt = dataOut.nCohInt
1340 self.nCohInt = dataOut.nCohInt
1341 ####print("IPPseconds",dataOut.ippSeconds)
1341 ####print("IPPseconds",dataOut.ippSeconds)
1342 ####print("ELVALOR DE n es:", n)
1342 ####print("ELVALOR DE n es:", n)
1343 if n == None:
1343 if n == None:
1344 raise ValueError("n should be specified.")
1344 raise ValueError("n should be specified.")
1345
1345
1346 if n != None:
1346 if n != None:
1347 if n<2:
1347 if n<2:
1348 raise ValueError("n should be greater than 2")
1348 raise ValueError("n should be greater than 2")
1349
1349
1350 self.n = n
1350 self.n = n
1351 self.__nProf = n
1351 self.__nProf = n
1352
1352
1353 self.__buffer = numpy.zeros((dataOut.nChannels,
1353 self.__buffer = numpy.zeros((dataOut.nChannels,
1354 n,
1354 n,
1355 dataOut.nHeights),
1355 dataOut.nHeights),
1356 dtype='complex')
1356 dtype='complex')
1357
1357
1358 def putData(self,data):
1358 def putData(self,data):
1359 '''
1359 '''
1360 Add a profile to he __buffer and increase in one the __profiel Index
1360 Add a profile to he __buffer and increase in one the __profiel Index
1361 '''
1361 '''
1362 self.__buffer[:,self.__profIndex,:]= data
1362 self.__buffer[:,self.__profIndex,:]= data
1363 self.__profIndex += 1
1363 self.__profIndex += 1
1364 return
1364 return
1365
1365
1366 def pushData(self,dataOut):
1366 def pushData(self,dataOut):
1367 '''
1367 '''
1368 Return the PULSEPAIR and the profiles used in the operation
1368 Return the PULSEPAIR and the profiles used in the operation
1369 Affected : self.__profileIndex
1369 Affected : self.__profileIndex
1370 '''
1370 '''
1371 #----------------- Remove DC-----------------------------------
1371 #----------------- Remove DC-----------------------------------
1372 if self.removeDC==True:
1372 if self.removeDC==True:
1373 mean = numpy.mean(self.__buffer,1)
1373 mean = numpy.mean(self.__buffer,1)
1374 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1374 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1375 dc= numpy.tile(tmp,[1,self.__nProf,1])
1375 dc= numpy.tile(tmp,[1,self.__nProf,1])
1376 self.__buffer = self.__buffer - dc
1376 self.__buffer = self.__buffer - dc
1377 #------------------Calculo de Potencia ------------------------
1377 #------------------Calculo de Potencia ------------------------
1378 pair0 = self.__buffer*numpy.conj(self.__buffer)
1378 pair0 = self.__buffer*numpy.conj(self.__buffer)
1379 pair0 = pair0.real
1379 pair0 = pair0.real
1380 lag_0 = numpy.sum(pair0,1)
1380 lag_0 = numpy.sum(pair0,1)
1381 #-----------------Calculo de Cscp------------------------------ New
1381 #-----------------Calculo de Cscp------------------------------ New
1382 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1382 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1383 #------------------Calculo de Ruido x canal--------------------
1383 #------------------Calculo de Ruido x canal--------------------
1384 self.noise = numpy.zeros(self.__nch)
1384 self.noise = numpy.zeros(self.__nch)
1385 for i in range(self.__nch):
1385 for i in range(self.__nch):
1386 daux = numpy.sort(pair0[i,:,:],axis= None)
1386 daux = numpy.sort(pair0[i,:,:],axis= None)
1387 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1387 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1388
1388
1389 self.noise = self.noise.reshape(self.__nch,1)
1389 self.noise = self.noise.reshape(self.__nch,1)
1390 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1390 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1391 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1391 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1392 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1392 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1393 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1393 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1394 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1394 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1395 #-------------------- Power --------------------------------------------------
1395 #-------------------- Power --------------------------------------------------
1396 data_power = lag_0/(self.n*self.nCohInt)
1396 data_power = lag_0/(self.n*self.nCohInt)
1397 #--------------------CCF------------------------------------------------------
1397 #--------------------CCF------------------------------------------------------
1398 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1398 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1399 #------------------ Senal --------------------------------------------------
1399 #------------------ Senal --------------------------------------------------
1400 data_intensity = pair0 - noise_buffer
1400 data_intensity = pair0 - noise_buffer
1401 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1401 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1402 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1402 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1403 for i in range(self.__nch):
1403 for i in range(self.__nch):
1404 for j in range(self.__nHeis):
1404 for j in range(self.__nHeis):
1405 if data_intensity[i][j] < 0:
1405 if data_intensity[i][j] < 0:
1406 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1406 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1407
1407
1408 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1408 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1409 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1409 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1410 lag_1 = numpy.sum(pair1,1)
1410 lag_1 = numpy.sum(pair1,1)
1411 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1411 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1412 data_velocity = (self.lambda_/2.0)*data_freq
1412 data_velocity = (self.lambda_/2.0)*data_freq
1413
1413
1414 #---------------- Potencia promedio estimada de la Senal-----------
1414 #---------------- Potencia promedio estimada de la Senal-----------
1415 lag_0 = lag_0/self.n
1415 lag_0 = lag_0/self.n
1416 S = lag_0-self.noise
1416 S = lag_0-self.noise
1417
1417
1418 #---------------- Frecuencia Doppler promedio ---------------------
1418 #---------------- Frecuencia Doppler promedio ---------------------
1419 lag_1 = lag_1/(self.n-1)
1419 lag_1 = lag_1/(self.n-1)
1420 R1 = numpy.abs(lag_1)
1420 R1 = numpy.abs(lag_1)
1421
1421
1422 #---------------- Calculo del SNR----------------------------------
1422 #---------------- Calculo del SNR----------------------------------
1423 data_snrPP = S/self.noise
1423 data_snrPP = S/self.noise
1424 for i in range(self.__nch):
1424 for i in range(self.__nch):
1425 for j in range(self.__nHeis):
1425 for j in range(self.__nHeis):
1426 if data_snrPP[i][j] < 1.e-20:
1426 if data_snrPP[i][j] < 1.e-20:
1427 data_snrPP[i][j] = 1.e-20
1427 data_snrPP[i][j] = 1.e-20
1428
1428
1429 #----------------- Calculo del ancho espectral ----------------------
1429 #----------------- Calculo del ancho espectral ----------------------
1430 L = S/R1
1430 L = S/R1
1431 L = numpy.where(L<0,1,L)
1431 L = numpy.where(L<0,1,L)
1432 L = numpy.log(L)
1432 L = numpy.log(L)
1433 tmp = numpy.sqrt(numpy.absolute(L))
1433 tmp = numpy.sqrt(numpy.absolute(L))
1434 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1434 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1435 n = self.__profIndex
1435 n = self.__profIndex
1436
1436
1437 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1437 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1438 self.__profIndex = 0
1438 self.__profIndex = 0
1439 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1439 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1440
1440
1441
1441
1442 def pulsePairbyProfiles(self,dataOut):
1442 def pulsePairbyProfiles(self,dataOut):
1443
1443
1444 self.__dataReady = False
1444 self.__dataReady = False
1445 data_power = None
1445 data_power = None
1446 data_intensity = None
1446 data_intensity = None
1447 data_velocity = None
1447 data_velocity = None
1448 data_specwidth = None
1448 data_specwidth = None
1449 data_snrPP = None
1449 data_snrPP = None
1450 data_ccf = None
1450 data_ccf = None
1451 self.putData(data=dataOut.data)
1451 self.putData(data=dataOut.data)
1452 if self.__profIndex == self.n:
1452 if self.__profIndex == self.n:
1453 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1453 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1454 self.__dataReady = True
1454 self.__dataReady = True
1455
1455
1456 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1456 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1457
1457
1458
1458
1459 def pulsePairOp(self, dataOut, datatime= None):
1459 def pulsePairOp(self, dataOut, datatime= None):
1460
1460
1461 if self.__initime == None:
1461 if self.__initime == None:
1462 self.__initime = datatime
1462 self.__initime = datatime
1463 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut)
1463 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut)
1464 self.__lastdatatime = datatime
1464 self.__lastdatatime = datatime
1465
1465
1466 if data_power is None:
1466 if data_power is None:
1467 return None, None, None,None,None,None,None
1467 return None, None, None,None,None,None,None
1468
1468
1469 avgdatatime = self.__initime
1469 avgdatatime = self.__initime
1470 deltatime = datatime - self.__lastdatatime
1470 deltatime = datatime - self.__lastdatatime
1471 self.__initime = datatime
1471 self.__initime = datatime
1472
1472
1473 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1473 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1474
1474
1475 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1475 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1476 #print("hey")
1476 #print("hey")
1477 #print(dataOut.data.shape)
1477 #print(dataOut.data.shape)
1478 #exit(1)
1478 #exit(1)
1479 #print(self.__profIndex)
1479 #print(self.__profIndex)
1480 if not self.isConfig:
1480 if not self.isConfig:
1481 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1481 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1482 self.isConfig = True
1482 self.isConfig = True
1483 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1483 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1484 dataOut.flagNoData = True
1484 dataOut.flagNoData = True
1485
1485
1486 if self.__dataReady:
1486 if self.__dataReady:
1487 ###print("READY ----------------------------------")
1487 ###print("READY ----------------------------------")
1488 dataOut.nCohInt *= self.n
1488 dataOut.nCohInt *= self.n
1489 dataOut.dataPP_POW = data_intensity # S
1489 dataOut.dataPP_POW = data_intensity # S
1490 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1490 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1491 dataOut.dataPP_DOP = data_velocity
1491 dataOut.dataPP_DOP = data_velocity
1492 dataOut.dataPP_SNR = data_snrPP
1492 dataOut.dataPP_SNR = data_snrPP
1493 dataOut.dataPP_WIDTH = data_specwidth
1493 dataOut.dataPP_WIDTH = data_specwidth
1494 dataOut.dataPP_CCF = data_ccf
1494 dataOut.dataPP_CCF = data_ccf
1495 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1495 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1496 dataOut.nProfiles = int(dataOut.nProfiles/n)
1496 dataOut.nProfiles = int(dataOut.nProfiles/n)
1497 dataOut.utctime = avgdatatime
1497 dataOut.utctime = avgdatatime
1498 dataOut.flagNoData = False
1498 dataOut.flagNoData = False
1499 return dataOut
1499 return dataOut
1500
1500
1501 class PulsePair_vRF(Operation):
1501 class PulsePair_vRF(Operation):
1502 '''
1502 '''
1503 Function PulsePair(Signal Power, Velocity)
1503 Function PulsePair(Signal Power, Velocity)
1504 The real component of Lag[0] provides Intensity Information
1504 The real component of Lag[0] provides Intensity Information
1505 The imag component of Lag[1] Phase provides Velocity Information
1505 The imag component of Lag[1] Phase provides Velocity Information
1506
1506
1507 Configuration Parameters:
1507 Configuration Parameters:
1508 nPRF = Number of Several PRF
1508 nPRF = Number of Several PRF
1509 theta = Degree Azimuth angel Boundaries
1509 theta = Degree Azimuth angel Boundaries
1510
1510
1511 Input:
1511 Input:
1512 self.dataOut
1512 self.dataOut
1513 lag[N]
1513 lag[N]
1514 Affected:
1514 Affected:
1515 self.dataOut.spc
1515 self.dataOut.spc
1516 '''
1516 '''
1517 isConfig = False
1517 isConfig = False
1518 __profIndex = 0
1518 __profIndex = 0
1519 __initime = None
1519 __initime = None
1520 __lastdatatime = None
1520 __lastdatatime = None
1521 __buffer = None
1521 __buffer = None
1522 noise = None
1522 noise = None
1523 __dataReady = False
1523 __dataReady = False
1524 n = None
1524 n = None
1525 __nch = 0
1525 __nch = 0
1526 __nHeis = 0
1526 __nHeis = 0
1527 removeDC = False
1527 removeDC = False
1528 ipp = None
1528 ipp = None
1529 lambda_ = 0
1529 lambda_ = 0
1530
1530
1531 def __init__(self,**kwargs):
1531 def __init__(self,**kwargs):
1532 Operation.__init__(self,**kwargs)
1532 Operation.__init__(self,**kwargs)
1533
1533
1534 def setup(self, dataOut, n = None, removeDC=False):
1534 def setup(self, dataOut, n = None, removeDC=False):
1535 '''
1535 '''
1536 n= Numero de PRF's de entrada
1536 n= Numero de PRF's de entrada
1537 '''
1537 '''
1538 self.__initime = None
1538 self.__initime = None
1539 ####print("[INICIO]-setup del METODO PULSE PAIR")
1539 ####print("[INICIO]-setup del METODO PULSE PAIR")
1540 self.__lastdatatime = 0
1540 self.__lastdatatime = 0
1541 self.__dataReady = False
1541 self.__dataReady = False
1542 self.__buffer = 0
1542 self.__buffer = 0
1543 self.__profIndex = 0
1543 self.__profIndex = 0
1544 self.noise = None
1544 self.noise = None
1545 self.__nch = dataOut.nChannels
1545 self.__nch = dataOut.nChannels
1546 self.__nHeis = dataOut.nHeights
1546 self.__nHeis = dataOut.nHeights
1547 self.removeDC = removeDC
1547 self.removeDC = removeDC
1548 self.lambda_ = 3.0e8/(9345.0e6)
1548 self.lambda_ = 3.0e8/(9345.0e6)
1549 self.ippSec = dataOut.ippSeconds
1549 self.ippSec = dataOut.ippSeconds
1550 self.nCohInt = dataOut.nCohInt
1550 self.nCohInt = dataOut.nCohInt
1551 ####print("IPPseconds",dataOut.ippSeconds)
1551 ####print("IPPseconds",dataOut.ippSeconds)
1552 ####print("ELVALOR DE n es:", n)
1552 ####print("ELVALOR DE n es:", n)
1553 if n == None:
1553 if n == None:
1554 raise ValueError("n should be specified.")
1554 raise ValueError("n should be specified.")
1555
1555
1556 if n != None:
1556 if n != None:
1557 if n<2:
1557 if n<2:
1558 raise ValueError("n should be greater than 2")
1558 raise ValueError("n should be greater than 2")
1559
1559
1560 self.n = n
1560 self.n = n
1561 self.__nProf = n
1561 self.__nProf = n
1562
1562
1563 self.__buffer = numpy.zeros((dataOut.nChannels,
1563 self.__buffer = numpy.zeros((dataOut.nChannels,
1564 n,
1564 n,
1565 dataOut.nHeights),
1565 dataOut.nHeights),
1566 dtype='complex')
1566 dtype='complex')
1567
1567
1568 def putData(self,data):
1568 def putData(self,data):
1569 '''
1569 '''
1570 Add a profile to he __buffer and increase in one the __profiel Index
1570 Add a profile to he __buffer and increase in one the __profiel Index
1571 '''
1571 '''
1572 self.__buffer[:,self.__profIndex,:]= data
1572 self.__buffer[:,self.__profIndex,:]= data
1573 self.__profIndex += 1
1573 self.__profIndex += 1
1574 return
1574 return
1575
1575
1576 def putDataByBlock(self,data,n):
1576 def putDataByBlock(self,data,n):
1577 '''
1577 '''
1578 Add a profile to he __buffer and increase in one the __profiel Index
1578 Add a profile to he __buffer and increase in one the __profiel Index
1579 '''
1579 '''
1580 self.__buffer[:]= data
1580 self.__buffer[:]= data
1581 self.__profIndex = n
1581 self.__profIndex = n
1582 return
1582 return
1583
1583
1584 def pushData(self,dataOut):
1584 def pushData(self,dataOut):
1585 '''
1585 '''
1586 Return the PULSEPAIR and the profiles used in the operation
1586 Return the PULSEPAIR and the profiles used in the operation
1587 Affected : self.__profileIndex
1587 Affected : self.__profileIndex
1588 NOTA:
1588 NOTA:
1589 1.) Calculo de Potencia
1589 1.) Calculo de Potencia
1590 PdBm = 10 *log10(10*(I**2 + Q**2)) Unidades dBm
1590 PdBm = 10 *log10(10*(I**2 + Q**2)) Unidades dBm
1591 self.__buffer = I + Qj
1591 self.__buffer = I + Qj
1592
1592
1593 2.) Data decodificada
1593 2.) Data decodificada
1594 Se toma como referencia el factor estimado en jrodata.py y se adiciona
1594 Se toma como referencia el factor estimado en jrodata.py y se adiciona
1595 en PulsePair solo pwcode.
1595 en PulsePair solo pwcode.
1596 if self.flagDecodeData:
1596 if self.flagDecodeData:
1597 pwcode = numpy.sum(self.code[0]**2)
1597 pwcode = numpy.sum(self.code[0]**2)
1598 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
1598 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
1599 3.) hildebrand_sekhon
1599 3.) hildebrand_sekhon
1600 Se pasa el arreglo de Potencia pair0 que contiene canales perfiles y altura dividiendole entre el
1600 Se pasa el arreglo de Potencia pair0 que contiene canales perfiles y altura dividiendole entre el
1601 factor pwcode.
1601 factor pwcode.
1602 4.) data_power
1602 4.) data_power
1603 Este parametro esta dividido por los factores: nro. perfiles, nro intCoh y pwcode
1603 Este parametro esta dividido por los factores: nro. perfiles, nro intCoh y pwcode
1604 5.) lag_0
1604 5.) lag_0
1605 Este parametro esta dividido por los factores: nro. perfiles, nro intCoh y pwcode
1605 Este parametro esta dividido por los factores: nro. perfiles, nro intCoh y pwcode
1606 Igual a data_power
1606 Igual a data_power
1607
1607
1608 '''
1608 '''
1609 #----------------- Remove DC-----------------------------------
1609 #----------------- Remove DC-----------------------------------
1610 if self.removeDC==True:
1610 if self.removeDC==True:
1611 mean = numpy.mean(self.__buffer,1)
1611 mean = numpy.mean(self.__buffer,1)
1612 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1612 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1613 dc= numpy.tile(tmp,[1,self.__nProf,1])
1613 dc= numpy.tile(tmp,[1,self.__nProf,1])
1614 self.__buffer = self.__buffer - dc
1614 self.__buffer = self.__buffer - dc
1615 #------------------Calculo de Potencia ------------------------
1615 #------------------Calculo de Potencia ------------------------
1616 pair0 = self.__buffer*numpy.conj(self.__buffer) * 10.0
1616 pair0 = self.__buffer*numpy.conj(self.__buffer) * 10.0
1617 pair0 = pair0.real
1617 pair0 = pair0.real
1618 lag_0 = numpy.sum(pair0,1)
1618 lag_0 = numpy.sum(pair0,1)
1619 #-----------------Calculo de Cscp------------------------------ New
1619 #-----------------Calculo de Cscp------------------------------ New
1620 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1620 if len(self.__buffer)>1:
1621 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1621 #------------------ Data Decodificada------------------------
1622 #------------------ Data Decodificada------------------------
1622 pwcode = 1
1623 pwcode = 1
1623 if dataOut.flagDecodeData == True:
1624 if dataOut.flagDecodeData == True:
1624 pwcode = numpy.sum(dataOut.code[0]**2)
1625 pwcode = numpy.sum(dataOut.code[0]**2)
1625 #------------------Calculo de Ruido x canal--------------------
1626 #------------------Calculo de Ruido x canal--------------------
1626 self.noise = numpy.zeros(self.__nch)
1627 self.noise = numpy.zeros(self.__nch)
1627 for i in range(self.__nch):
1628 for i in range(self.__nch):
1628 daux = numpy.sort(pair0[i,:,:],axis= None)
1629 daux = numpy.sort(pair0[i,:,:],axis= None)
1629 self.noise[i]=hildebrand_sekhon( daux/pwcode ,self.nCohInt)
1630 self.noise[i]=hildebrand_sekhon( daux/pwcode ,self.nCohInt)
1630
1631
1631 self.noise = self.noise.reshape(self.__nch,1)
1632 self.noise = self.noise.reshape(self.__nch,1)
1632 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1633 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1633 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1634 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1634 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1635 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1635 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1636 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1636 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1637 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1637 #-------------------- Power --------------------------------------------------
1638 #-------------------- Power --------------------------------------------------
1638 data_power = lag_0/(self.n*self.nCohInt*pwcode)
1639 data_power = lag_0/(self.n*self.nCohInt*pwcode)
1639 #--------------------CCF------------------------------------------------------
1640 #--------------------CCF------------------------------------------------------
1640 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1641
1642 if len(self.__buffer)>1:
1643 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1644 else:
1645 data_ccf = 0
1641 #------------------ Senal --------------------------------------------------
1646 #------------------ Senal --------------------------------------------------
1642 data_intensity = pair0 - noise_buffer
1647 data_intensity = pair0 - noise_buffer
1643 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1648 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1644 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1649 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1645 for i in range(self.__nch):
1650 for i in range(self.__nch):
1646 for j in range(self.__nHeis):
1651 for j in range(self.__nHeis):
1647 if data_intensity[i][j] < 0:
1652 if data_intensity[i][j] < 0:
1648 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1653 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1649
1654
1650 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1655 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1651 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1656 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1652 lag_1 = numpy.sum(pair1,1)
1657 lag_1 = numpy.sum(pair1,1)
1653 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1658 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1654 data_velocity = (self.lambda_/2.0)*data_freq
1659 data_velocity = (self.lambda_/2.0)*data_freq
1655
1660
1656 #---------------- Potencia promedio estimada de la Senal-----------
1661 #---------------- Potencia promedio estimada de la Senal-----------
1657 lag_0 = data_power
1662 lag_0 = data_power
1658 S = lag_0-self.noise
1663 S = lag_0-self.noise
1659
1664
1660 #---------------- Frecuencia Doppler promedio ---------------------
1665 #---------------- Frecuencia Doppler promedio ---------------------
1661 lag_1 = lag_1/(self.n-1)
1666 lag_1 = lag_1/(self.n-1)
1662 R1 = numpy.abs(lag_1)
1667 R1 = numpy.abs(lag_1)
1663
1668
1664 #---------------- Calculo del SNR----------------------------------
1669 #---------------- Calculo del SNR----------------------------------
1665 data_snrPP = S/self.noise
1670 data_snrPP = S/self.noise
1666 for i in range(self.__nch):
1671 for i in range(self.__nch):
1667 for j in range(self.__nHeis):
1672 for j in range(self.__nHeis):
1668 if data_snrPP[i][j] < 1.e-20:
1673 if data_snrPP[i][j] < 1.e-20:
1669 data_snrPP[i][j] = 1.e-20
1674 data_snrPP[i][j] = 1.e-20
1670
1675
1671 #----------------- Calculo del ancho espectral ----------------------
1676 #----------------- Calculo del ancho espectral ----------------------
1672 L = S/R1
1677 L = S/R1
1673 L = numpy.where(L<0,1,L)
1678 L = numpy.where(L<0,1,L)
1674 L = numpy.log(L)
1679 L = numpy.log(L)
1675 tmp = numpy.sqrt(numpy.absolute(L))
1680 tmp = numpy.sqrt(numpy.absolute(L))
1676 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1681 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1677 n = self.__profIndex
1682 n = self.__profIndex
1678
1683
1679 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1684 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1680 self.__profIndex = 0
1685 self.__profIndex = 0
1681 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1686 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1682
1687
1683
1688
1684 def pulsePairbyProfiles(self,dataOut,n):
1689 def pulsePairbyProfiles(self,dataOut,n):
1685
1690
1686 self.__dataReady = False
1691 self.__dataReady = False
1687 data_power = None
1692 data_power = None
1688 data_intensity = None
1693 data_intensity = None
1689 data_velocity = None
1694 data_velocity = None
1690 data_specwidth = None
1695 data_specwidth = None
1691 data_snrPP = None
1696 data_snrPP = None
1692 data_ccf = None
1697 data_ccf = None
1693
1698
1694 if dataOut.flagDataAsBlock:
1699 if dataOut.flagDataAsBlock:
1695 self.putDataByBlock(data=dataOut.data,n=n)
1700 self.putDataByBlock(data=dataOut.data,n=n)
1696 else:
1701 else:
1697 self.putData(data=dataOut.data)
1702 self.putData(data=dataOut.data)
1698 if self.__profIndex == self.n:
1703 if self.__profIndex == self.n:
1699 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1704 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1700 self.__dataReady = True
1705 self.__dataReady = True
1701
1706
1702 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1707 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1703
1708
1704
1709
1705 def pulsePairOp(self, dataOut, n, datatime= None):
1710 def pulsePairOp(self, dataOut, n, datatime= None):
1706
1711
1707 if self.__initime == None:
1712 if self.__initime == None:
1708 self.__initime = datatime
1713 self.__initime = datatime
1709 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut,n)
1714 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut,n)
1710 self.__lastdatatime = datatime
1715 self.__lastdatatime = datatime
1711
1716
1712 if data_power is None:
1717 if data_power is None:
1713 return None, None, None,None,None,None,None
1718 return None, None, None,None,None,None,None
1714
1719
1715 avgdatatime = self.__initime
1720 avgdatatime = self.__initime
1716 deltatime = datatime - self.__lastdatatime
1721 deltatime = datatime - self.__lastdatatime
1717 self.__initime = datatime
1722 self.__initime = datatime
1718
1723
1719 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1724 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1720
1725
1721 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1726 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1722
1727
1723 if dataOut.flagDataAsBlock:
1728 if dataOut.flagDataAsBlock:
1724 n = int(dataOut.nProfiles)
1729 n = int(dataOut.nProfiles)
1725 #print("n",n)
1730 #print("n",n)
1726
1731
1727 if not self.isConfig:
1732 if not self.isConfig:
1728 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1733 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1729 self.isConfig = True
1734 self.isConfig = True
1730
1735
1731
1736
1732 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, n, dataOut.utctime)
1737 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, n, dataOut.utctime)
1733
1738
1734
1739
1735 dataOut.flagNoData = True
1740 dataOut.flagNoData = True
1736
1741
1737 if self.__dataReady:
1742 if self.__dataReady:
1738 ###print("READY ----------------------------------")
1743 ###print("READY ----------------------------------")
1739 dataOut.nCohInt *= self.n
1744 dataOut.nCohInt *= self.n
1740 dataOut.dataPP_POW = data_intensity # S
1745 dataOut.dataPP_POW = data_intensity # S
1741 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1746 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1742 dataOut.dataPP_DOP = data_velocity
1747 dataOut.dataPP_DOP = data_velocity
1743 dataOut.dataPP_SNR = data_snrPP
1748 dataOut.dataPP_SNR = data_snrPP
1744 dataOut.dataPP_WIDTH = data_specwidth
1749 dataOut.dataPP_WIDTH = data_specwidth
1745 dataOut.dataPP_CCF = data_ccf
1750 dataOut.dataPP_CCF = data_ccf
1746 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1751 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1747 dataOut.nProfiles = int(dataOut.nProfiles/n)
1752 dataOut.nProfiles = int(dataOut.nProfiles/n)
1748 dataOut.utctime = avgdatatime
1753 dataOut.utctime = avgdatatime
1749 dataOut.flagNoData = False
1754 dataOut.flagNoData = False
1750 return dataOut
1755 return dataOut
1751
1756
1752 # import collections
1757 # import collections
1753 # from scipy.stats import mode
1758 # from scipy.stats import mode
1754 #
1759 #
1755 # class Synchronize(Operation):
1760 # class Synchronize(Operation):
1756 #
1761 #
1757 # isConfig = False
1762 # isConfig = False
1758 # __profIndex = 0
1763 # __profIndex = 0
1759 #
1764 #
1760 # def __init__(self, **kwargs):
1765 # def __init__(self, **kwargs):
1761 #
1766 #
1762 # Operation.__init__(self, **kwargs)
1767 # Operation.__init__(self, **kwargs)
1763 # # self.isConfig = False
1768 # # self.isConfig = False
1764 # self.__powBuffer = None
1769 # self.__powBuffer = None
1765 # self.__startIndex = 0
1770 # self.__startIndex = 0
1766 # self.__pulseFound = False
1771 # self.__pulseFound = False
1767 #
1772 #
1768 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1773 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1769 #
1774 #
1770 # #Read data
1775 # #Read data
1771 #
1776 #
1772 # powerdB = dataOut.getPower(channel = channel)
1777 # powerdB = dataOut.getPower(channel = channel)
1773 # noisedB = dataOut.getNoise(channel = channel)[0]
1778 # noisedB = dataOut.getNoise(channel = channel)[0]
1774 #
1779 #
1775 # self.__powBuffer.extend(powerdB.flatten())
1780 # self.__powBuffer.extend(powerdB.flatten())
1776 #
1781 #
1777 # dataArray = numpy.array(self.__powBuffer)
1782 # dataArray = numpy.array(self.__powBuffer)
1778 #
1783 #
1779 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1784 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1780 #
1785 #
1781 # maxValue = numpy.nanmax(filteredPower)
1786 # maxValue = numpy.nanmax(filteredPower)
1782 #
1787 #
1783 # if maxValue < noisedB + 10:
1788 # if maxValue < noisedB + 10:
1784 # #No se encuentra ningun pulso de transmision
1789 # #No se encuentra ningun pulso de transmision
1785 # return None
1790 # return None
1786 #
1791 #
1787 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1792 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1788 #
1793 #
1789 # if len(maxValuesIndex) < 2:
1794 # if len(maxValuesIndex) < 2:
1790 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1795 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1791 # return None
1796 # return None
1792 #
1797 #
1793 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1798 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1794 #
1799 #
1795 # #Seleccionar solo valores con un espaciamiento de nSamples
1800 # #Seleccionar solo valores con un espaciamiento de nSamples
1796 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1801 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1797 #
1802 #
1798 # if len(pulseIndex) < 2:
1803 # if len(pulseIndex) < 2:
1799 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1804 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1800 # return None
1805 # return None
1801 #
1806 #
1802 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1807 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1803 #
1808 #
1804 # #remover senales que se distancien menos de 10 unidades o muestras
1809 # #remover senales que se distancien menos de 10 unidades o muestras
1805 # #(No deberian existir IPP menor a 10 unidades)
1810 # #(No deberian existir IPP menor a 10 unidades)
1806 #
1811 #
1807 # realIndex = numpy.where(spacing > 10 )[0]
1812 # realIndex = numpy.where(spacing > 10 )[0]
1808 #
1813 #
1809 # if len(realIndex) < 2:
1814 # if len(realIndex) < 2:
1810 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1815 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1811 # return None
1816 # return None
1812 #
1817 #
1813 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1818 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1814 # realPulseIndex = pulseIndex[realIndex]
1819 # realPulseIndex = pulseIndex[realIndex]
1815 #
1820 #
1816 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1821 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1817 #
1822 #
1818 # print "IPP = %d samples" %period
1823 # print "IPP = %d samples" %period
1819 #
1824 #
1820 # self.__newNSamples = dataOut.nHeights #int(period)
1825 # self.__newNSamples = dataOut.nHeights #int(period)
1821 # self.__startIndex = int(realPulseIndex[0])
1826 # self.__startIndex = int(realPulseIndex[0])
1822 #
1827 #
1823 # return 1
1828 # return 1
1824 #
1829 #
1825 #
1830 #
1826 # def setup(self, nSamples, nChannels, buffer_size = 4):
1831 # def setup(self, nSamples, nChannels, buffer_size = 4):
1827 #
1832 #
1828 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1833 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1829 # maxlen = buffer_size*nSamples)
1834 # maxlen = buffer_size*nSamples)
1830 #
1835 #
1831 # bufferList = []
1836 # bufferList = []
1832 #
1837 #
1833 # for i in range(nChannels):
1838 # for i in range(nChannels):
1834 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1839 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1835 # maxlen = buffer_size*nSamples)
1840 # maxlen = buffer_size*nSamples)
1836 #
1841 #
1837 # bufferList.append(bufferByChannel)
1842 # bufferList.append(bufferByChannel)
1838 #
1843 #
1839 # self.__nSamples = nSamples
1844 # self.__nSamples = nSamples
1840 # self.__nChannels = nChannels
1845 # self.__nChannels = nChannels
1841 # self.__bufferList = bufferList
1846 # self.__bufferList = bufferList
1842 #
1847 #
1843 # def run(self, dataOut, channel = 0):
1848 # def run(self, dataOut, channel = 0):
1844 #
1849 #
1845 # if not self.isConfig:
1850 # if not self.isConfig:
1846 # nSamples = dataOut.nHeights
1851 # nSamples = dataOut.nHeights
1847 # nChannels = dataOut.nChannels
1852 # nChannels = dataOut.nChannels
1848 # self.setup(nSamples, nChannels)
1853 # self.setup(nSamples, nChannels)
1849 # self.isConfig = True
1854 # self.isConfig = True
1850 #
1855 #
1851 # #Append new data to internal buffer
1856 # #Append new data to internal buffer
1852 # for thisChannel in range(self.__nChannels):
1857 # for thisChannel in range(self.__nChannels):
1853 # bufferByChannel = self.__bufferList[thisChannel]
1858 # bufferByChannel = self.__bufferList[thisChannel]
1854 # bufferByChannel.extend(dataOut.data[thisChannel])
1859 # bufferByChannel.extend(dataOut.data[thisChannel])
1855 #
1860 #
1856 # if self.__pulseFound:
1861 # if self.__pulseFound:
1857 # self.__startIndex -= self.__nSamples
1862 # self.__startIndex -= self.__nSamples
1858 #
1863 #
1859 # #Finding Tx Pulse
1864 # #Finding Tx Pulse
1860 # if not self.__pulseFound:
1865 # if not self.__pulseFound:
1861 # indexFound = self.__findTxPulse(dataOut, channel)
1866 # indexFound = self.__findTxPulse(dataOut, channel)
1862 #
1867 #
1863 # if indexFound == None:
1868 # if indexFound == None:
1864 # dataOut.flagNoData = True
1869 # dataOut.flagNoData = True
1865 # return
1870 # return
1866 #
1871 #
1867 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1872 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1868 # self.__pulseFound = True
1873 # self.__pulseFound = True
1869 # self.__startIndex = indexFound
1874 # self.__startIndex = indexFound
1870 #
1875 #
1871 # #If pulse was found ...
1876 # #If pulse was found ...
1872 # for thisChannel in range(self.__nChannels):
1877 # for thisChannel in range(self.__nChannels):
1873 # bufferByChannel = self.__bufferList[thisChannel]
1878 # bufferByChannel = self.__bufferList[thisChannel]
1874 # #print self.__startIndex
1879 # #print self.__startIndex
1875 # x = numpy.array(bufferByChannel)
1880 # x = numpy.array(bufferByChannel)
1876 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1881 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1877 #
1882 #
1878 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1883 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1879 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1884 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1880 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1885 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1881 #
1886 #
1882 # dataOut.data = self.__arrayBuffer
1887 # dataOut.data = self.__arrayBuffer
1883 #
1888 #
1884 # self.__startIndex += self.__newNSamples
1889 # self.__startIndex += self.__newNSamples
1885 #
1890 #
1886 # return
1891 # return
General Comments 0
You need to be logged in to leave comments. Login now