##// END OF EJS Templates
PPI Plot fixed to clockwise
rflores -
r1453:4e2472cf7118
parent child
Show More
@@ -1,1788 +1,1790
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):
372 class WeatherPlot(Plot):
373 CODE = 'weather'
373 CODE = 'weather'
374 plot_name = 'weather'
374 plot_name = 'weather'
375 plot_type = 'ppistyle'
375 plot_type = 'ppistyle'
376 buffering = False
376 buffering = False
377
377
378 def setup(self):
378 def setup(self):
379 self.ncols = 1
379 self.ncols = 1
380 self.nrows = 1
380 self.nrows = 1
381 self.width =8
381 self.width =8
382 self.height =8
382 self.height =8
383 self.nplots= 1
383 self.nplots= 1
384 self.ylabel= 'Range [Km]'
384 self.ylabel= 'Range [Km]'
385 self.titles= ['Weather']
385 self.titles= ['Weather']
386 self.colorbar=False
386 self.colorbar=False
387 self.ini =0
387 self.ini =0
388 self.len_azi =0
388 self.len_azi =0
389 self.buffer_ini = None
389 self.buffer_ini = None
390 self.buffer_azi = 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})
391 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
392 self.flag =0
392 self.flag =0
393 self.indicador= 0
393 self.indicador= 0
394 self.last_data_azi = None
394 self.last_data_azi = None
395 self.val_mean = None
395 self.val_mean = None
396
396
397 def update(self, dataOut):
397 def update(self, dataOut):
398
398
399 data = {}
399 data = {}
400 meta = {}
400 meta = {}
401 if hasattr(dataOut, 'dataPP_POWER'):
401 if hasattr(dataOut, 'dataPP_POWER'):
402 factor = 1
402 factor = 1
403 if hasattr(dataOut, 'nFFTPoints'):
403 if hasattr(dataOut, 'nFFTPoints'):
404 factor = dataOut.normFactor
404 factor = dataOut.normFactor
405 #print("DIME EL SHAPE PORFAVOR",dataOut.data_360.shape)
405 #print("DIME EL SHAPE PORFAVOR",dataOut.data_360.shape)
406 data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
406 data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
407 data['azi'] = dataOut.data_azi
407 data['azi'] = dataOut.data_azi
408 data['ele'] = dataOut.data_ele
408 data['ele'] = dataOut.data_ele
409 return data, meta
409 return data, meta
410
410
411 def get2List(self,angulos):
411 def get2List(self,angulos):
412 list1=[]
412 list1=[]
413 list2=[]
413 list2=[]
414 for i in reversed(range(len(angulos))):
414 for i in reversed(range(len(angulos))):
415 diff_ = angulos[i]-angulos[i-1]
415 diff_ = angulos[i]-angulos[i-1]
416 if diff_ >1.5:
416 if diff_ >1.5:
417 list1.append(i-1)
417 list1.append(i-1)
418 list2.append(diff_)
418 list2.append(diff_)
419 return list(reversed(list1)),list(reversed(list2))
419 return list(reversed(list1)),list(reversed(list2))
420
420
421 def fixData360(self,list_,ang_):
421 def fixData360(self,list_,ang_):
422 if list_[0]==-1:
422 if list_[0]==-1:
423 vec = numpy.where(ang_<ang_[0])
423 vec = numpy.where(ang_<ang_[0])
424 ang_[vec] = ang_[vec]+360
424 ang_[vec] = ang_[vec]+360
425 return ang_
425 return ang_
426 return ang_
426 return ang_
427
427
428 def fixData360HL(self,angulos):
428 def fixData360HL(self,angulos):
429 vec = numpy.where(angulos>=360)
429 vec = numpy.where(angulos>=360)
430 angulos[vec]=angulos[vec]-360
430 angulos[vec]=angulos[vec]-360
431 return angulos
431 return angulos
432
432
433 def search_pos(self,pos,list_):
433 def search_pos(self,pos,list_):
434 for i in range(len(list_)):
434 for i in range(len(list_)):
435 if pos == list_[i]:
435 if pos == list_[i]:
436 return True,i
436 return True,i
437 i=None
437 i=None
438 return False,i
438 return False,i
439
439
440 def fixDataComp(self,ang_,list1_,list2_):
440 def fixDataComp(self,ang_,list1_,list2_):
441 size = len(ang_)
441 size = len(ang_)
442 size2 = 0
442 size2 = 0
443 for i in range(len(list2_)):
443 for i in range(len(list2_)):
444 size2=size2+round(list2_[i])-1
444 size2=size2+round(list2_[i])-1
445 new_size= size+size2
445 new_size= size+size2
446 ang_new = numpy.zeros(new_size)
446 ang_new = numpy.zeros(new_size)
447 ang_new2 = numpy.zeros(new_size)
447 ang_new2 = numpy.zeros(new_size)
448
448
449 tmp = 0
449 tmp = 0
450 c = 0
450 c = 0
451 for i in range(len(ang_)):
451 for i in range(len(ang_)):
452 ang_new[tmp +c] = ang_[i]
452 ang_new[tmp +c] = ang_[i]
453 ang_new2[tmp+c] = ang_[i]
453 ang_new2[tmp+c] = ang_[i]
454 condition , value = self.search_pos(i,list1_)
454 condition , value = self.search_pos(i,list1_)
455 if condition:
455 if condition:
456 pos = tmp + c + 1
456 pos = tmp + c + 1
457 for k in range(round(list2_[value])-1):
457 for k in range(round(list2_[value])-1):
458 ang_new[pos+k] = ang_new[pos+k-1]+1
458 ang_new[pos+k] = ang_new[pos+k-1]+1
459 ang_new2[pos+k] = numpy.nan
459 ang_new2[pos+k] = numpy.nan
460 tmp = pos +k
460 tmp = pos +k
461 c = 0
461 c = 0
462 c=c+1
462 c=c+1
463 return ang_new,ang_new2
463 return ang_new,ang_new2
464
464
465 def globalCheckPED(self,angulos):
465 def globalCheckPED(self,angulos):
466 l1,l2 = self.get2List(angulos)
466 l1,l2 = self.get2List(angulos)
467 if len(l1)>0:
467 if len(l1)>0:
468 angulos2 = self.fixData360(list_=l1,ang_=angulos)
468 angulos2 = self.fixData360(list_=l1,ang_=angulos)
469 l1,l2 = self.get2List(angulos2)
469 l1,l2 = self.get2List(angulos2)
470
470
471 ang1_,ang2_ = self.fixDataComp(ang_=angulos2,list1_=l1,list2_=l2)
471 ang1_,ang2_ = self.fixDataComp(ang_=angulos2,list1_=l1,list2_=l2)
472 ang1_ = self.fixData360HL(ang1_)
472 ang1_ = self.fixData360HL(ang1_)
473 ang2_ = self.fixData360HL(ang2_)
473 ang2_ = self.fixData360HL(ang2_)
474 else:
474 else:
475 ang1_= angulos
475 ang1_= angulos
476 ang2_= angulos
476 ang2_= angulos
477 return ang1_,ang2_
477 return ang1_,ang2_
478
478
479 def analizeDATA(self,data_azi):
479 def analizeDATA(self,data_azi):
480 list1 = []
480 list1 = []
481 list2 = []
481 list2 = []
482 dat = data_azi
482 dat = data_azi
483 for i in reversed(range(1,len(dat))):
483 for i in reversed(range(1,len(dat))):
484 if dat[i]>dat[i-1]:
484 if dat[i]>dat[i-1]:
485 diff = int(dat[i])-int(dat[i-1])
485 diff = int(dat[i])-int(dat[i-1])
486 else:
486 else:
487 diff = 360+int(dat[i])-int(dat[i-1])
487 diff = 360+int(dat[i])-int(dat[i-1])
488 if diff > 1:
488 if diff > 1:
489 list1.append(i-1)
489 list1.append(i-1)
490 list2.append(diff-1)
490 list2.append(diff-1)
491 return list1,list2
491 return list1,list2
492
492
493 def fixDATANEW(self,data_azi,data_weather):
493 def fixDATANEW(self,data_azi,data_weather):
494 list1,list2 = self.analizeDATA(data_azi)
494 list1,list2 = self.analizeDATA(data_azi)
495 if len(list1)== 0:
495 if len(list1)== 0:
496 return data_azi,data_weather
496 return data_azi,data_weather
497 else:
497 else:
498 resize = 0
498 resize = 0
499 for i in range(len(list2)):
499 for i in range(len(list2)):
500 resize= resize + list2[i]
500 resize= resize + list2[i]
501 new_data_azi = numpy.resize(data_azi,resize)
501 new_data_azi = numpy.resize(data_azi,resize)
502 new_data_weather= numpy.resize(date_weather,resize)
502 new_data_weather= numpy.resize(date_weather,resize)
503
503
504 for i in range(len(list2)):
504 for i in range(len(list2)):
505 j=0
505 j=0
506 position=list1[i]+1
506 position=list1[i]+1
507 for j in range(list2[i]):
507 for j in range(list2[i]):
508 new_data_azi[position+j]=new_data_azi[position+j-1]+1
508 new_data_azi[position+j]=new_data_azi[position+j-1]+1
509 return new_data_azi
509 return new_data_azi
510
510
511 def fixDATA(self,data_azi):
511 def fixDATA(self,data_azi):
512 data=data_azi
512 data=data_azi
513 for i in range(len(data)):
513 for i in range(len(data)):
514 if numpy.isnan(data[i]):
514 if numpy.isnan(data[i]):
515 data[i]=data[i-1]+1
515 data[i]=data[i-1]+1
516 return data
516 return data
517
517
518 def replaceNAN(self,data_weather,data_azi,val):
518 def replaceNAN(self,data_weather,data_azi,val):
519 data= data_azi
519 data= data_azi
520 data_T= data_weather
520 data_T= data_weather
521 if data.shape[0]> data_T.shape[0]:
521 if data.shape[0]> data_T.shape[0]:
522 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
522 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
523 c = 0
523 c = 0
524 for i in range(len(data)):
524 for i in range(len(data)):
525 if numpy.isnan(data[i]):
525 if numpy.isnan(data[i]):
526 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
526 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
527 else:
527 else:
528 data_N[i,:]=data_T[c,:]
528 data_N[i,:]=data_T[c,:]
529 c=c+1
529 c=c+1
530 return data_N
530 return data_N
531 else:
531 else:
532 for i in range(len(data)):
532 for i in range(len(data)):
533 if numpy.isnan(data[i]):
533 if numpy.isnan(data[i]):
534 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
534 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
535 return data_T
535 return data_T
536
536
537 def const_ploteo(self,data_weather,data_azi,step,res):
537 def const_ploteo(self,data_weather,data_azi,step,res):
538 if self.ini==0:
538 if self.ini==0:
539 #-------
539 #-------
540 n = (360/res)-len(data_azi)
540 n = (360/res)-len(data_azi)
541 #--------------------- new -------------------------
541 #--------------------- new -------------------------
542 data_azi_new ,data_azi_old= self.globalCheckPED(data_azi)
542 data_azi_new ,data_azi_old= self.globalCheckPED(data_azi)
543 #------------------------
543 #------------------------
544 start = data_azi_new[-1] + res
544 start = data_azi_new[-1] + res
545 end = data_azi_new[0] - res
545 end = data_azi_new[0] - res
546 #------ new
546 #------ new
547 self.last_data_azi = end
547 self.last_data_azi = end
548 if start>end:
548 if start>end:
549 end = end + 360
549 end = end + 360
550 azi_vacia = numpy.linspace(start,end,int(n))
550 azi_vacia = numpy.linspace(start,end,int(n))
551 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
551 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
552 data_azi = numpy.hstack((data_azi_new,azi_vacia))
552 data_azi = numpy.hstack((data_azi_new,azi_vacia))
553 # RADAR
553 # RADAR
554 val_mean = numpy.mean(data_weather[:,-1])
554 val_mean = numpy.mean(data_weather[:,-1])
555 self.val_mean = val_mean
555 self.val_mean = val_mean
556 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*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)
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))
558 data_weather = numpy.vstack((data_weather,data_weather_cmp))
559 else:
559 else:
560 # azimuth
560 # azimuth
561 flag=0
561 flag=0
562 start_azi = self.res_azi[0]
562 start_azi = self.res_azi[0]
563 #-----------new------------
563 #-----------new------------
564 data_azi ,data_azi_old= self.globalCheckPED(data_azi)
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)
565 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
566 #--------------------------
566 #--------------------------
567 start = data_azi[0]
567 start = data_azi[0]
568 end = data_azi[-1]
568 end = data_azi[-1]
569 self.last_data_azi= end
569 self.last_data_azi= end
570 if start< start_azi:
570 if start< start_azi:
571 start = start +360
571 start = start +360
572 if end <start_azi:
572 if end <start_azi:
573 end = end +360
573 end = end +360
574
574
575 pos_ini = int((start-start_azi)/res)
575 pos_ini = int((start-start_azi)/res)
576 len_azi = len(data_azi)
576 len_azi = len(data_azi)
577 if (360-pos_ini)<len_azi:
577 if (360-pos_ini)<len_azi:
578 if pos_ini+1==360:
578 if pos_ini+1==360:
579 pos_ini=0
579 pos_ini=0
580 else:
580 else:
581 flag=1
581 flag=1
582 dif= 360-pos_ini
582 dif= 360-pos_ini
583 comp= len_azi-dif
583 comp= len_azi-dif
584 #-----------------
584 #-----------------
585 if flag==0:
585 if flag==0:
586 # AZIMUTH
586 # AZIMUTH
587 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
587 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
588 # RADAR
588 # RADAR
589 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
589 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
590 else:
590 else:
591 # AZIMUTH
591 # AZIMUTH
592 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
592 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
593 self.res_azi[0:comp] = data_azi[dif:]
593 self.res_azi[0:comp] = data_azi[dif:]
594 # RADAR
594 # RADAR
595 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
595 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
596 self.res_weather[0:comp,:] = data_weather[dif:,:]
596 self.res_weather[0:comp,:] = data_weather[dif:,:]
597 flag=0
597 flag=0
598 data_azi = self.res_azi
598 data_azi = self.res_azi
599 data_weather = self.res_weather
599 data_weather = self.res_weather
600
600
601 return data_weather,data_azi
601 return data_weather,data_azi
602
602
603 def plot(self):
603 def plot(self):
604 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
604 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
605 data = self.data[-1]
605 data = self.data[-1]
606 r = self.data.yrange
606 r = self.data.yrange
607 delta_height = r[1]-r[0]
607 delta_height = r[1]-r[0]
608 r_mask = numpy.where(r>=0)[0]
608 r_mask = numpy.where(r>=0)[0]
609 r = numpy.arange(len(r_mask))*delta_height
609 r = numpy.arange(len(r_mask))*delta_height
610 self.y = 2*r
610 self.y = 2*r
611 # RADAR
611 # RADAR
612 #data_weather = data['weather']
612 #data_weather = data['weather']
613 # PEDESTAL
613 # PEDESTAL
614 #data_azi = data['azi']
614 #data_azi = data['azi']
615 res = 1
615 res = 1
616 # STEP
616 # STEP
617 step = (360/(res*data['weather'].shape[0]))
617 step = (360/(res*data['weather'].shape[0]))
618
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)
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'])
620 self.res_ele = numpy.mean(data['ele'])
621 ################# PLOTEO ###################
621 ################# PLOTEO ###################
622 for i,ax in enumerate(self.axes):
622 for i,ax in enumerate(self.axes):
623 self.zmin = self.zmin if self.zmin else 20
623 self.zmin = self.zmin if self.zmin else 20
624 self.zmax = self.zmax if self.zmax else 80
624 self.zmax = self.zmax if self.zmax else 80
625 if ax.firsttime:
625 if ax.firsttime:
626 plt.clf()
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)
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:
628 else:
629 plt.clf()
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)
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]
631 caax = cgax.parasites[0]
632 paax = cgax.parasites[1]
632 paax = cgax.parasites[1]
633 cbar = plt.gcf().colorbar(pm, pad=0.075)
633 cbar = plt.gcf().colorbar(pm, pad=0.075)
634 caax.set_xlabel('x_range [km]')
634 caax.set_xlabel('x_range [km]')
635 caax.set_ylabel('y_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')
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
637
638 self.ini= self.ini+1
638 self.ini= self.ini+1
639
639
640
640
641 class WeatherRHIPlot(Plot):
641 class WeatherRHIPlot(Plot):
642 CODE = 'weather'
642 CODE = 'weather'
643 plot_name = 'weather'
643 plot_name = 'weather'
644 plot_type = 'rhistyle'
644 plot_type = 'rhistyle'
645 buffering = False
645 buffering = False
646 data_ele_tmp = None
646 data_ele_tmp = None
647
647
648 def setup(self):
648 def setup(self):
649 print("********************")
649 print("********************")
650 print("********************")
650 print("********************")
651 print("********************")
651 print("********************")
652 print("SETUP WEATHER PLOT")
652 print("SETUP WEATHER PLOT")
653 self.ncols = 1
653 self.ncols = 1
654 self.nrows = 1
654 self.nrows = 1
655 self.nplots= 1
655 self.nplots= 1
656 self.ylabel= 'Range [Km]'
656 self.ylabel= 'Range [Km]'
657 self.titles= ['Weather']
657 self.titles= ['Weather']
658 if self.channels is not None:
658 if self.channels is not None:
659 self.nplots = len(self.channels)
659 self.nplots = len(self.channels)
660 self.nrows = len(self.channels)
660 self.nrows = len(self.channels)
661 else:
661 else:
662 self.nplots = self.data.shape(self.CODE)[0]
662 self.nplots = self.data.shape(self.CODE)[0]
663 self.nrows = self.nplots
663 self.nrows = self.nplots
664 self.channels = list(range(self.nplots))
664 self.channels = list(range(self.nplots))
665 print("channels",self.channels)
665 print("channels",self.channels)
666 print("que saldra", self.data.shape(self.CODE)[0])
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)]
667 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
668 print("self.titles",self.titles)
668 print("self.titles",self.titles)
669 self.colorbar=False
669 self.colorbar=False
670 self.width =12
670 self.width =12
671 self.height =8
671 self.height =8
672 self.ini =0
672 self.ini =0
673 self.len_azi =0
673 self.len_azi =0
674 self.buffer_ini = None
674 self.buffer_ini = None
675 self.buffer_ele = 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})
676 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
677 self.flag =0
677 self.flag =0
678 self.indicador= 0
678 self.indicador= 0
679 self.last_data_ele = None
679 self.last_data_ele = None
680 self.val_mean = None
680 self.val_mean = None
681
681
682 def update(self, dataOut):
682 def update(self, dataOut):
683
683
684 data = {}
684 data = {}
685 meta = {}
685 meta = {}
686 if hasattr(dataOut, 'dataPP_POWER'):
686 if hasattr(dataOut, 'dataPP_POWER'):
687 factor = 1
687 factor = 1
688 if hasattr(dataOut, 'nFFTPoints'):
688 if hasattr(dataOut, 'nFFTPoints'):
689 factor = dataOut.normFactor
689 factor = dataOut.normFactor
690 print("dataOut",dataOut.data_360.shape)
690 print("dataOut",dataOut.data_360.shape)
691 #
691 #
692 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
692 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
693 #
693 #
694 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
694 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
695 data['azi'] = dataOut.data_azi
695 data['azi'] = dataOut.data_azi
696 data['ele'] = dataOut.data_ele
696 data['ele'] = dataOut.data_ele
697 #print("UPDATE")
697 #print("UPDATE")
698 #print("data[weather]",data['weather'].shape)
698 #print("data[weather]",data['weather'].shape)
699 #print("data[azi]",data['azi'])
699 #print("data[azi]",data['azi'])
700 return data, meta
700 return data, meta
701
701
702 def get2List(self,angulos):
702 def get2List(self,angulos):
703 list1=[]
703 list1=[]
704 list2=[]
704 list2=[]
705 for i in reversed(range(len(angulos))):
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
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]
707 diff_ = angulos[i]-angulos[i-1]
708 if abs(diff_) >1.5:
708 if abs(diff_) >1.5:
709 list1.append(i-1)
709 list1.append(i-1)
710 list2.append(diff_)
710 list2.append(diff_)
711 return list(reversed(list1)),list(reversed(list2))
711 return list(reversed(list1)),list(reversed(list2))
712
712
713 def fixData90(self,list_,ang_):
713 def fixData90(self,list_,ang_):
714 if list_[0]==-1:
714 if list_[0]==-1:
715 vec = numpy.where(ang_<ang_[0])
715 vec = numpy.where(ang_<ang_[0])
716 ang_[vec] = ang_[vec]+90
716 ang_[vec] = ang_[vec]+90
717 return ang_
717 return ang_
718 return ang_
718 return ang_
719
719
720 def fixData90HL(self,angulos):
720 def fixData90HL(self,angulos):
721 vec = numpy.where(angulos>=90)
721 vec = numpy.where(angulos>=90)
722 angulos[vec]=angulos[vec]-90
722 angulos[vec]=angulos[vec]-90
723 return angulos
723 return angulos
724
724
725
725
726 def search_pos(self,pos,list_):
726 def search_pos(self,pos,list_):
727 for i in range(len(list_)):
727 for i in range(len(list_)):
728 if pos == list_[i]:
728 if pos == list_[i]:
729 return True,i
729 return True,i
730 i=None
730 i=None
731 return False,i
731 return False,i
732
732
733 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
733 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
734 size = len(ang_)
734 size = len(ang_)
735 size2 = 0
735 size2 = 0
736 for i in range(len(list2_)):
736 for i in range(len(list2_)):
737 size2=size2+round(abs(list2_[i]))-1
737 size2=size2+round(abs(list2_[i]))-1
738 new_size= size+size2
738 new_size= size+size2
739 ang_new = numpy.zeros(new_size)
739 ang_new = numpy.zeros(new_size)
740 ang_new2 = numpy.zeros(new_size)
740 ang_new2 = numpy.zeros(new_size)
741
741
742 tmp = 0
742 tmp = 0
743 c = 0
743 c = 0
744 for i in range(len(ang_)):
744 for i in range(len(ang_)):
745 ang_new[tmp +c] = ang_[i]
745 ang_new[tmp +c] = ang_[i]
746 ang_new2[tmp+c] = ang_[i]
746 ang_new2[tmp+c] = ang_[i]
747 condition , value = self.search_pos(i,list1_)
747 condition , value = self.search_pos(i,list1_)
748 if condition:
748 if condition:
749 pos = tmp + c + 1
749 pos = tmp + c + 1
750 for k in range(round(abs(list2_[value]))-1):
750 for k in range(round(abs(list2_[value]))-1):
751 if tipo_case==0 or tipo_case==3:#subida
751 if tipo_case==0 or tipo_case==3:#subida
752 ang_new[pos+k] = ang_new[pos+k-1]+1
752 ang_new[pos+k] = ang_new[pos+k-1]+1
753 ang_new2[pos+k] = numpy.nan
753 ang_new2[pos+k] = numpy.nan
754 elif tipo_case==1 or tipo_case==2:#bajada
754 elif tipo_case==1 or tipo_case==2:#bajada
755 ang_new[pos+k] = ang_new[pos+k-1]-1
755 ang_new[pos+k] = ang_new[pos+k-1]-1
756 ang_new2[pos+k] = numpy.nan
756 ang_new2[pos+k] = numpy.nan
757
757
758 tmp = pos +k
758 tmp = pos +k
759 c = 0
759 c = 0
760 c=c+1
760 c=c+1
761 return ang_new,ang_new2
761 return ang_new,ang_new2
762
762
763 def globalCheckPED(self,angulos,tipo_case):
763 def globalCheckPED(self,angulos,tipo_case):
764 l1,l2 = self.get2List(angulos)
764 l1,l2 = self.get2List(angulos)
765 ##print("l1",l1)
765 ##print("l1",l1)
766 ##print("l2",l2)
766 ##print("l2",l2)
767 if len(l1)>0:
767 if len(l1)>0:
768 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
768 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
769 #l1,l2 = self.get2List(angulos2)
769 #l1,l2 = self.get2List(angulos2)
770 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
770 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
771 #ang1_ = self.fixData90HL(ang1_)
771 #ang1_ = self.fixData90HL(ang1_)
772 #ang2_ = self.fixData90HL(ang2_)
772 #ang2_ = self.fixData90HL(ang2_)
773 else:
773 else:
774 ang1_= angulos
774 ang1_= angulos
775 ang2_= angulos
775 ang2_= angulos
776 return ang1_,ang2_
776 return ang1_,ang2_
777
777
778
778
779 def replaceNAN(self,data_weather,data_ele,val):
779 def replaceNAN(self,data_weather,data_ele,val):
780 data= data_ele
780 data= data_ele
781 data_T= data_weather
781 data_T= data_weather
782 if data.shape[0]> data_T.shape[0]:
782 if data.shape[0]> data_T.shape[0]:
783 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
783 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
784 c = 0
784 c = 0
785 for i in range(len(data)):
785 for i in range(len(data)):
786 if numpy.isnan(data[i]):
786 if numpy.isnan(data[i]):
787 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
787 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
788 else:
788 else:
789 data_N[i,:]=data_T[c,:]
789 data_N[i,:]=data_T[c,:]
790 c=c+1
790 c=c+1
791 return data_N
791 return data_N
792 else:
792 else:
793 for i in range(len(data)):
793 for i in range(len(data)):
794 if numpy.isnan(data[i]):
794 if numpy.isnan(data[i]):
795 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
795 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
796 return data_T
796 return data_T
797
797
798 def check_case(self,data_ele,ang_max,ang_min):
798 def check_case(self,data_ele,ang_max,ang_min):
799 start = data_ele[0]
799 start = data_ele[0]
800 end = data_ele[-1]
800 end = data_ele[-1]
801 number = (end-start)
801 number = (end-start)
802 len_ang=len(data_ele)
802 len_ang=len(data_ele)
803 print("start",start)
803 print("start",start)
804 print("end",end)
804 print("end",end)
805 print("number",number)
805 print("number",number)
806
806
807 print("len_ang",len_ang)
807 print("len_ang",len_ang)
808
808
809 #exit(1)
809 #exit(1)
810
810
811 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
811 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
812 return 0
812 return 0
813 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
813 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
814 # return 1
814 # return 1
815 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
815 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
816 return 1
816 return 1
817 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
817 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
818 return 2
818 return 2
819 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
819 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
820 return 3
820 return 3
821
821
822
822
823 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min):
823 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min):
824 ang_max= ang_max
824 ang_max= ang_max
825 ang_min= ang_min
825 ang_min= ang_min
826 data_weather=data_weather
826 data_weather=data_weather
827 val_ch=val_ch
827 val_ch=val_ch
828 ##print("*********************DATA WEATHER**************************************")
828 ##print("*********************DATA WEATHER**************************************")
829 ##print(data_weather)
829 ##print(data_weather)
830 if self.ini==0:
830 if self.ini==0:
831 '''
831 '''
832 print("**********************************************")
832 print("**********************************************")
833 print("**********************************************")
833 print("**********************************************")
834 print("***************ini**************")
834 print("***************ini**************")
835 print("**********************************************")
835 print("**********************************************")
836 print("**********************************************")
836 print("**********************************************")
837 '''
837 '''
838 #print("data_ele",data_ele)
838 #print("data_ele",data_ele)
839 #----------------------------------------------------------
839 #----------------------------------------------------------
840 tipo_case = self.check_case(data_ele,ang_max,ang_min)
840 tipo_case = self.check_case(data_ele,ang_max,ang_min)
841 print("check_case",tipo_case)
841 print("check_case",tipo_case)
842 #exit(1)
842 #exit(1)
843 #--------------------- new -------------------------
843 #--------------------- new -------------------------
844 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
844 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
845
845
846 #-------------------------CAMBIOS RHI---------------------------------
846 #-------------------------CAMBIOS RHI---------------------------------
847 start= ang_min
847 start= ang_min
848 end = ang_max
848 end = ang_max
849 n= (ang_max-ang_min)/res
849 n= (ang_max-ang_min)/res
850 #------ new
850 #------ new
851 self.start_data_ele = data_ele_new[0]
851 self.start_data_ele = data_ele_new[0]
852 self.end_data_ele = data_ele_new[-1]
852 self.end_data_ele = data_ele_new[-1]
853 if tipo_case==0 or tipo_case==3: # SUBIDA
853 if tipo_case==0 or tipo_case==3: # SUBIDA
854 n1= round(self.start_data_ele)- start
854 n1= round(self.start_data_ele)- start
855 n2= end - round(self.end_data_ele)
855 n2= end - round(self.end_data_ele)
856 print(self.start_data_ele)
856 print(self.start_data_ele)
857 print(self.end_data_ele)
857 print(self.end_data_ele)
858 if n1>0:
858 if n1>0:
859 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
859 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
860 ele1_nan= numpy.ones(n1)*numpy.nan
860 ele1_nan= numpy.ones(n1)*numpy.nan
861 data_ele = numpy.hstack((ele1,data_ele_new))
861 data_ele = numpy.hstack((ele1,data_ele_new))
862 print("ele1_nan",ele1_nan.shape)
862 print("ele1_nan",ele1_nan.shape)
863 print("data_ele_old",data_ele_old.shape)
863 print("data_ele_old",data_ele_old.shape)
864 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
864 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
865 if n2>0:
865 if n2>0:
866 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
866 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
867 ele2_nan= numpy.ones(n2)*numpy.nan
867 ele2_nan= numpy.ones(n2)*numpy.nan
868 data_ele = numpy.hstack((data_ele,ele2))
868 data_ele = numpy.hstack((data_ele,ele2))
869 print("ele2_nan",ele2_nan.shape)
869 print("ele2_nan",ele2_nan.shape)
870 print("data_ele_old",data_ele_old.shape)
870 print("data_ele_old",data_ele_old.shape)
871 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
871 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
872
872
873 if tipo_case==1 or tipo_case==2: # BAJADA
873 if tipo_case==1 or tipo_case==2: # BAJADA
874 data_ele_new = data_ele_new[::-1] # reversa
874 data_ele_new = data_ele_new[::-1] # reversa
875 data_ele_old = data_ele_old[::-1]# reversa
875 data_ele_old = data_ele_old[::-1]# reversa
876 data_weather = data_weather[::-1,:]# reversa
876 data_weather = data_weather[::-1,:]# reversa
877 vec= numpy.where(data_ele_new<ang_max)
877 vec= numpy.where(data_ele_new<ang_max)
878 data_ele_new = data_ele_new[vec]
878 data_ele_new = data_ele_new[vec]
879 data_ele_old = data_ele_old[vec]
879 data_ele_old = data_ele_old[vec]
880 data_weather = data_weather[vec[0]]
880 data_weather = data_weather[vec[0]]
881 vec2= numpy.where(0<data_ele_new)
881 vec2= numpy.where(0<data_ele_new)
882 data_ele_new = data_ele_new[vec2]
882 data_ele_new = data_ele_new[vec2]
883 data_ele_old = data_ele_old[vec2]
883 data_ele_old = data_ele_old[vec2]
884 data_weather = data_weather[vec2[0]]
884 data_weather = data_weather[vec2[0]]
885 self.start_data_ele = data_ele_new[0]
885 self.start_data_ele = data_ele_new[0]
886 self.end_data_ele = data_ele_new[-1]
886 self.end_data_ele = data_ele_new[-1]
887
887
888 n1= round(self.start_data_ele)- start
888 n1= round(self.start_data_ele)- start
889 n2= end - round(self.end_data_ele)-1
889 n2= end - round(self.end_data_ele)-1
890 print(self.start_data_ele)
890 print(self.start_data_ele)
891 print(self.end_data_ele)
891 print(self.end_data_ele)
892 if n1>0:
892 if n1>0:
893 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
893 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
894 ele1_nan= numpy.ones(n1)*numpy.nan
894 ele1_nan= numpy.ones(n1)*numpy.nan
895 data_ele = numpy.hstack((ele1,data_ele_new))
895 data_ele = numpy.hstack((ele1,data_ele_new))
896 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
896 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
897 if n2>0:
897 if n2>0:
898 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
898 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
899 ele2_nan= numpy.ones(n2)*numpy.nan
899 ele2_nan= numpy.ones(n2)*numpy.nan
900 data_ele = numpy.hstack((data_ele,ele2))
900 data_ele = numpy.hstack((data_ele,ele2))
901 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
901 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
902 # RADAR
902 # RADAR
903 # NOTA data_ele y data_weather es la variable que retorna
903 # NOTA data_ele y data_weather es la variable que retorna
904 val_mean = numpy.mean(data_weather[:,-1])
904 val_mean = numpy.mean(data_weather[:,-1])
905 self.val_mean = val_mean
905 self.val_mean = val_mean
906 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.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
907 self.data_ele_tmp[val_ch]= data_ele_old
908 else:
908 else:
909 #print("**********************************************")
909 #print("**********************************************")
910 #print("****************VARIABLE**********************")
910 #print("****************VARIABLE**********************")
911 #-------------------------CAMBIOS RHI---------------------------------
911 #-------------------------CAMBIOS RHI---------------------------------
912 #---------------------------------------------------------------------
912 #---------------------------------------------------------------------
913 ##print("INPUT data_ele",data_ele)
913 ##print("INPUT data_ele",data_ele)
914 flag=0
914 flag=0
915 start_ele = self.res_ele[0]
915 start_ele = self.res_ele[0]
916 tipo_case = self.check_case(data_ele,ang_max,ang_min)
916 tipo_case = self.check_case(data_ele,ang_max,ang_min)
917 #print("TIPO DE DATA",tipo_case)
917 #print("TIPO DE DATA",tipo_case)
918 #-----------new------------
918 #-----------new------------
919 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
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)
920 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
921
921
922 #-------------------------------NEW RHI ITERATIVO-------------------------
922 #-------------------------------NEW RHI ITERATIVO-------------------------
923
923
924 if tipo_case==0 : # SUBIDA
924 if tipo_case==0 : # SUBIDA
925 vec = numpy.where(data_ele<ang_max)
925 vec = numpy.where(data_ele<ang_max)
926 data_ele = data_ele[vec]
926 data_ele = data_ele[vec]
927 data_ele_old = data_ele_old[vec]
927 data_ele_old = data_ele_old[vec]
928 data_weather = data_weather[vec[0]]
928 data_weather = data_weather[vec[0]]
929
929
930 vec2 = numpy.where(0<data_ele)
930 vec2 = numpy.where(0<data_ele)
931 data_ele= data_ele[vec2]
931 data_ele= data_ele[vec2]
932 data_ele_old= data_ele_old[vec2]
932 data_ele_old= data_ele_old[vec2]
933 ##print(data_ele_new)
933 ##print(data_ele_new)
934 data_weather= data_weather[vec2[0]]
934 data_weather= data_weather[vec2[0]]
935
935
936 new_i_ele = int(round(data_ele[0]))
936 new_i_ele = int(round(data_ele[0]))
937 new_f_ele = int(round(data_ele[-1]))
937 new_f_ele = int(round(data_ele[-1]))
938 #print(new_i_ele)
938 #print(new_i_ele)
939 #print(new_f_ele)
939 #print(new_f_ele)
940 #print(data_ele,len(data_ele))
940 #print(data_ele,len(data_ele))
941 #print(data_ele_old,len(data_ele_old))
941 #print(data_ele_old,len(data_ele_old))
942 if new_i_ele< 2:
942 if new_i_ele< 2:
943 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
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)
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
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
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
947 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
948 data_ele = self.res_ele
948 data_ele = self.res_ele
949 data_weather = self.res_weather[val_ch]
949 data_weather = self.res_weather[val_ch]
950
950
951 elif tipo_case==1 : #BAJADA
951 elif tipo_case==1 : #BAJADA
952 data_ele = data_ele[::-1] # reversa
952 data_ele = data_ele[::-1] # reversa
953 data_ele_old = data_ele_old[::-1]# reversa
953 data_ele_old = data_ele_old[::-1]# reversa
954 data_weather = data_weather[::-1,:]# reversa
954 data_weather = data_weather[::-1,:]# reversa
955 vec= numpy.where(data_ele<ang_max)
955 vec= numpy.where(data_ele<ang_max)
956 data_ele = data_ele[vec]
956 data_ele = data_ele[vec]
957 data_ele_old = data_ele_old[vec]
957 data_ele_old = data_ele_old[vec]
958 data_weather = data_weather[vec[0]]
958 data_weather = data_weather[vec[0]]
959 vec2= numpy.where(0<data_ele)
959 vec2= numpy.where(0<data_ele)
960 data_ele = data_ele[vec2]
960 data_ele = data_ele[vec2]
961 data_ele_old = data_ele_old[vec2]
961 data_ele_old = data_ele_old[vec2]
962 data_weather = data_weather[vec2[0]]
962 data_weather = data_weather[vec2[0]]
963
963
964
964
965 new_i_ele = int(round(data_ele[0]))
965 new_i_ele = int(round(data_ele[0]))
966 new_f_ele = int(round(data_ele[-1]))
966 new_f_ele = int(round(data_ele[-1]))
967 #print(data_ele)
967 #print(data_ele)
968 #print(ang_max)
968 #print(ang_max)
969 #print(data_ele_old)
969 #print(data_ele_old)
970 if new_i_ele <= 1:
970 if new_i_ele <= 1:
971 new_i_ele = 1
971 new_i_ele = 1
972 if round(data_ele[-1])>=ang_max-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
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)
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
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
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
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
978 data_ele = self.res_ele
979 data_weather = self.res_weather[val_ch]
979 data_weather = self.res_weather[val_ch]
980
980
981 elif tipo_case==2: #bajada
981 elif tipo_case==2: #bajada
982 vec = numpy.where(data_ele<ang_max)
982 vec = numpy.where(data_ele<ang_max)
983 data_ele = data_ele[vec]
983 data_ele = data_ele[vec]
984 data_weather= data_weather[vec[0]]
984 data_weather= data_weather[vec[0]]
985
985
986 len_vec = len(vec)
986 len_vec = len(vec)
987 data_ele_new = data_ele[::-1] # reversa
987 data_ele_new = data_ele[::-1] # reversa
988 data_weather = data_weather[::-1,:]
988 data_weather = data_weather[::-1,:]
989 new_i_ele = int(data_ele_new[0])
989 new_i_ele = int(data_ele_new[0])
990 new_f_ele = int(data_ele_new[-1])
990 new_f_ele = int(data_ele_new[-1])
991
991
992 n1= new_i_ele- ang_min
992 n1= new_i_ele- ang_min
993 n2= ang_max - new_f_ele-1
993 n2= ang_max - new_f_ele-1
994 if n1>0:
994 if n1>0:
995 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
995 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
996 ele1_nan= numpy.ones(n1)*numpy.nan
996 ele1_nan= numpy.ones(n1)*numpy.nan
997 data_ele = numpy.hstack((ele1,data_ele_new))
997 data_ele = numpy.hstack((ele1,data_ele_new))
998 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
998 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
999 if n2>0:
999 if n2>0:
1000 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1000 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1001 ele2_nan= numpy.ones(n2)*numpy.nan
1001 ele2_nan= numpy.ones(n2)*numpy.nan
1002 data_ele = numpy.hstack((data_ele,ele2))
1002 data_ele = numpy.hstack((data_ele,ele2))
1003 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1003 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1004
1004
1005 self.data_ele_tmp[val_ch] = data_ele_old
1005 self.data_ele_tmp[val_ch] = data_ele_old
1006 self.res_ele = data_ele
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)
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
1008 data_ele = self.res_ele
1009 data_weather = self.res_weather[val_ch]
1009 data_weather = self.res_weather[val_ch]
1010
1010
1011 elif tipo_case==3:#subida
1011 elif tipo_case==3:#subida
1012 vec = numpy.where(0<data_ele)
1012 vec = numpy.where(0<data_ele)
1013 data_ele= data_ele[vec]
1013 data_ele= data_ele[vec]
1014 data_ele_new = data_ele
1014 data_ele_new = data_ele
1015 data_ele_old= data_ele_old[vec]
1015 data_ele_old= data_ele_old[vec]
1016 data_weather= data_weather[vec[0]]
1016 data_weather= data_weather[vec[0]]
1017 pos_ini = numpy.argmin(data_ele)
1017 pos_ini = numpy.argmin(data_ele)
1018 if pos_ini>0:
1018 if pos_ini>0:
1019 len_vec= len(data_ele)
1019 len_vec= len(data_ele)
1020 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1020 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1021 #print(vec3)
1021 #print(vec3)
1022 data_ele= data_ele[vec3]
1022 data_ele= data_ele[vec3]
1023 data_ele_new = data_ele
1023 data_ele_new = data_ele
1024 data_ele_old= data_ele_old[vec3]
1024 data_ele_old= data_ele_old[vec3]
1025 data_weather= data_weather[vec3]
1025 data_weather= data_weather[vec3]
1026
1026
1027 new_i_ele = int(data_ele_new[0])
1027 new_i_ele = int(data_ele_new[0])
1028 new_f_ele = int(data_ele_new[-1])
1028 new_f_ele = int(data_ele_new[-1])
1029 n1= new_i_ele- ang_min
1029 n1= new_i_ele- ang_min
1030 n2= ang_max - new_f_ele-1
1030 n2= ang_max - new_f_ele-1
1031 if n1>0:
1031 if n1>0:
1032 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1032 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1033 ele1_nan= numpy.ones(n1)*numpy.nan
1033 ele1_nan= numpy.ones(n1)*numpy.nan
1034 data_ele = numpy.hstack((ele1,data_ele_new))
1034 data_ele = numpy.hstack((ele1,data_ele_new))
1035 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1035 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1036 if n2>0:
1036 if n2>0:
1037 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1037 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1038 ele2_nan= numpy.ones(n2)*numpy.nan
1038 ele2_nan= numpy.ones(n2)*numpy.nan
1039 data_ele = numpy.hstack((data_ele,ele2))
1039 data_ele = numpy.hstack((data_ele,ele2))
1040 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1040 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1041
1041
1042 self.data_ele_tmp[val_ch] = data_ele_old
1042 self.data_ele_tmp[val_ch] = data_ele_old
1043 self.res_ele = data_ele
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)
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
1045 data_ele = self.res_ele
1046 data_weather = self.res_weather[val_ch]
1046 data_weather = self.res_weather[val_ch]
1047 #print("self.data_ele_tmp",self.data_ele_tmp)
1047 #print("self.data_ele_tmp",self.data_ele_tmp)
1048 return data_weather,data_ele
1048 return data_weather,data_ele
1049
1049
1050
1050
1051 def plot(self):
1051 def plot(self):
1052 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1052 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1053 data = self.data[-1]
1053 data = self.data[-1]
1054 r = self.data.yrange
1054 r = self.data.yrange
1055 delta_height = r[1]-r[0]
1055 delta_height = r[1]-r[0]
1056 r_mask = numpy.where(r>=0)[0]
1056 r_mask = numpy.where(r>=0)[0]
1057 ##print("delta_height",delta_height)
1057 ##print("delta_height",delta_height)
1058 #print("r_mask",r_mask,len(r_mask))
1058 #print("r_mask",r_mask,len(r_mask))
1059 r = numpy.arange(len(r_mask))*delta_height
1059 r = numpy.arange(len(r_mask))*delta_height
1060 self.y = 2*r
1060 self.y = 2*r
1061 res = 1
1061 res = 1
1062 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1062 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1063 ang_max = self.ang_max
1063 ang_max = self.ang_max
1064 ang_min = self.ang_min
1064 ang_min = self.ang_min
1065 var_ang =ang_max - ang_min
1065 var_ang =ang_max - ang_min
1066 step = (int(var_ang)/(res*data['weather'].shape[0]))
1066 step = (int(var_ang)/(res*data['weather'].shape[0]))
1067 ###print("step",step)
1067 ###print("step",step)
1068 #--------------------------------------------------------
1068 #--------------------------------------------------------
1069 ##print('weather',data['weather'].shape)
1069 ##print('weather',data['weather'].shape)
1070 ##print('ele',data['ele'].shape)
1070 ##print('ele',data['ele'].shape)
1071
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)
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'])
1073 ###self.res_azi = numpy.mean(data['azi'])
1074 ###print("self.res_ele",self.res_ele)
1074 ###print("self.res_ele",self.res_ele)
1075 plt.clf()
1075 plt.clf()
1076 subplots = [121, 122]
1076 subplots = [121, 122]
1077 cg={'angular_spacing': 20.}
1077 cg={'angular_spacing': 20.}
1078 if self.ini==0:
1078 if self.ini==0:
1079 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
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
1080 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1081 print("SHAPE",self.data_ele_tmp.shape)
1081 print("SHAPE",self.data_ele_tmp.shape)
1082
1082
1083 for i,ax in enumerate(self.axes):
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)
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'])
1085 self.res_azi = numpy.mean(data['azi'])
1086 if i==0:
1086 if i==0:
1087 print("*****************************************************************************to plot**************************",self.res_weather[i].shape)
1087 print("*****************************************************************************to plot**************************",self.res_weather[i].shape)
1088 self.zmin = self.zmin if self.zmin else 20
1088 self.zmin = self.zmin if self.zmin else 20
1089 self.zmax = self.zmax if self.zmax else 80
1089 self.zmax = self.zmax if self.zmax else 80
1090 if ax.firsttime:
1090 if ax.firsttime:
1091 #plt.clf()
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)
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]
1093 #fig=self.figures[0]
1094 else:
1094 else:
1095 #plt.clf()
1095 #plt.clf()
1096 if i==0:
1096 if i==0:
1097 print(self.res_weather[i])
1097 print(self.res_weather[i])
1098 print(self.res_ele)
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)
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]
1100 caax = cgax.parasites[0]
1101 paax = cgax.parasites[1]
1101 paax = cgax.parasites[1]
1102 cbar = plt.gcf().colorbar(pm, pad=0.075)
1102 cbar = plt.gcf().colorbar(pm, pad=0.075)
1103 caax.set_xlabel('x_range [km]')
1103 caax.set_xlabel('x_range [km]')
1104 caax.set_ylabel('y_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')
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)
1106 print("***************************self.ini****************************",self.ini)
1107 self.ini= self.ini+1
1107 self.ini= self.ini+1
1108
1108
1109 class Weather_vRF_Plot(Plot):
1109 class Weather_vRF_Plot(Plot):
1110 CODE = 'PPI'
1110 CODE = 'PPI'
1111 plot_name = 'PPI'
1111 plot_name = 'PPI'
1112 #plot_type = 'ppistyle'
1112 #plot_type = 'ppistyle'
1113 buffering = False
1113 buffering = False
1114
1114
1115 def setup(self):
1115 def setup(self):
1116
1116
1117 self.ncols = 1
1117 self.ncols = 1
1118 self.nrows = 1
1118 self.nrows = 1
1119 self.width =8
1119 self.width =8
1120 self.height =8
1120 self.height =8
1121 self.nplots= 1
1121 self.nplots= 1
1122 self.ylabel= 'Range [Km]'
1122 self.ylabel= 'Range [Km]'
1123 self.xlabel= 'Range [Km]'
1123 self.xlabel= 'Range [Km]'
1124 self.titles= ['PPI']
1124 self.titles= ['PPI']
1125 self.polar = True
1125 self.polar = True
1126 if self.channels is not None:
1126 if self.channels is not None:
1127 self.nplots = len(self.channels)
1127 self.nplots = len(self.channels)
1128 self.nrows = len(self.channels)
1128 self.nrows = len(self.channels)
1129 else:
1129 else:
1130 self.nplots = self.data.shape(self.CODE)[0]
1130 self.nplots = self.data.shape(self.CODE)[0]
1131 self.nrows = self.nplots
1131 self.nrows = self.nplots
1132 self.channels = list(range(self.nplots))
1132 self.channels = list(range(self.nplots))
1133
1133
1134 if self.CODE == 'POWER':
1134 if self.CODE == 'POWER':
1135 self.cb_label = r'Power (dB)'
1135 self.cb_label = r'Power (dB)'
1136 elif self.CODE == 'DOPPLER':
1136 elif self.CODE == 'DOPPLER':
1137 self.cb_label = r'Velocity (m/s)'
1137 self.cb_label = r'Velocity (m/s)'
1138 self.colorbar=True
1138 self.colorbar=True
1139 self.width = 9
1139 self.width = 9
1140 self.height =8
1140 self.height =8
1141 self.ini =0
1141 self.ini =0
1142 self.len_azi =0
1142 self.len_azi =0
1143 self.buffer_ini = None
1143 self.buffer_ini = None
1144 self.buffer_ele = 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})
1145 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.15, 'right': 0.9, 'bottom': 0.08})
1146 self.flag =0
1146 self.flag =0
1147 self.indicador= 0
1147 self.indicador= 0
1148 self.last_data_ele = None
1148 self.last_data_ele = None
1149 self.val_mean = None
1149 self.val_mean = None
1150
1150
1151 def update(self, dataOut):
1151 def update(self, dataOut):
1152
1152
1153 data = {}
1153 data = {}
1154 meta = {}
1154 meta = {}
1155 if hasattr(dataOut, 'dataPP_POWER'):
1155 if hasattr(dataOut, 'dataPP_POWER'):
1156 factor = 1
1156 factor = 1
1157 if hasattr(dataOut, 'nFFTPoints'):
1157 if hasattr(dataOut, 'nFFTPoints'):
1158 factor = dataOut.normFactor
1158 factor = dataOut.normFactor
1159
1159
1160 if 'pow' in self.attr_data[0].lower():
1160 if 'pow' in self.attr_data[0].lower():
1161 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1161 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1162 else:
1162 else:
1163 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1163 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1164
1164
1165 data['azi'] = dataOut.data_azi
1165 data['azi'] = dataOut.data_azi
1166 data['ele'] = dataOut.data_ele
1166 data['ele'] = dataOut.data_ele
1167
1167
1168 return data, meta
1168 return data, meta
1169
1169
1170 def plot(self):
1170 def plot(self):
1171 data = self.data[-1]
1171 data = self.data[-1]
1172 r = self.data.yrange
1172 r = self.data.yrange
1173 delta_height = r[1]-r[0]
1173 delta_height = r[1]-r[0]
1174 r_mask = numpy.where(r>=0)[0]
1174 r_mask = numpy.where(r>=0)[0]
1175 self.r_mask = r_mask
1175 self.r_mask = r_mask
1176 r = numpy.arange(len(r_mask))*delta_height
1176 r = numpy.arange(len(r_mask))*delta_height
1177 self.y = 2*r
1177 self.y = 2*r
1178
1178
1179 z = data['data'][self.channels[0]][:,r_mask]
1179 z = data['data'][self.channels[0]][:,r_mask]
1180
1180
1181 self.titles = []
1181 self.titles = []
1182
1182
1183 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1183 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1184 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1184 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1185 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1185 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1186 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1186 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1187 self.ang_min = self.ang_min if self.ang_min else 0
1187 self.ang_min = self.ang_min if self.ang_min else 0
1188 self.ang_max = self.ang_max if self.ang_max else 360
1188 self.ang_max = self.ang_max if self.ang_max else 360
1189
1189
1190 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1190 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1191
1191
1192 for i,ax in enumerate(self.axes):
1192 for i,ax in enumerate(self.axes):
1193
1193
1194 if ax.firsttime:
1194 if ax.firsttime:
1195 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1195 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1196 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1196 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1197 ax.set_theta_direction(-1)
1197
1198
1198 else:
1199 else:
1199 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1200 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.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1202 ax.set_theta_direction(-1)
1201
1203
1202 ax.grid(True)
1204 ax.grid(True)
1203
1205
1204 if len(self.channels) !=1:
1206 if len(self.channels) !=1:
1205 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)]
1207 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)]
1206 else:
1208 else:
1207 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['ele']),1)), self.channels[0])]
1209 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['ele']),1)), self.channels[0])]
1208
1210
1209 class WeatherRHI_vRF2_Plot(Plot):
1211 class WeatherRHI_vRF2_Plot(Plot):
1210 CODE = 'weather'
1212 CODE = 'weather'
1211 plot_name = 'weather'
1213 plot_name = 'weather'
1212 plot_type = 'rhistyle'
1214 plot_type = 'rhistyle'
1213 buffering = False
1215 buffering = False
1214 data_ele_tmp = None
1216 data_ele_tmp = None
1215
1217
1216 def setup(self):
1218 def setup(self):
1217 print("********************")
1219 print("********************")
1218 print("********************")
1220 print("********************")
1219 print("********************")
1221 print("********************")
1220 print("SETUP WEATHER PLOT")
1222 print("SETUP WEATHER PLOT")
1221 self.ncols = 1
1223 self.ncols = 1
1222 self.nrows = 1
1224 self.nrows = 1
1223 self.nplots= 1
1225 self.nplots= 1
1224 self.ylabel= 'Range [Km]'
1226 self.ylabel= 'Range [Km]'
1225 self.titles= ['Weather']
1227 self.titles= ['Weather']
1226 if self.channels is not None:
1228 if self.channels is not None:
1227 self.nplots = len(self.channels)
1229 self.nplots = len(self.channels)
1228 self.nrows = len(self.channels)
1230 self.nrows = len(self.channels)
1229 else:
1231 else:
1230 self.nplots = self.data.shape(self.CODE)[0]
1232 self.nplots = self.data.shape(self.CODE)[0]
1231 self.nrows = self.nplots
1233 self.nrows = self.nplots
1232 self.channels = list(range(self.nplots))
1234 self.channels = list(range(self.nplots))
1233 print("channels",self.channels)
1235 print("channels",self.channels)
1234 print("que saldra", self.data.shape(self.CODE)[0])
1236 print("que saldra", self.data.shape(self.CODE)[0])
1235 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1237 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1236 print("self.titles",self.titles)
1238 print("self.titles",self.titles)
1237 self.colorbar=False
1239 self.colorbar=False
1238 self.width =8
1240 self.width =8
1239 self.height =8
1241 self.height =8
1240 self.ini =0
1242 self.ini =0
1241 self.len_azi =0
1243 self.len_azi =0
1242 self.buffer_ini = None
1244 self.buffer_ini = None
1243 self.buffer_ele = None
1245 self.buffer_ele = None
1244 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1246 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1245 self.flag =0
1247 self.flag =0
1246 self.indicador= 0
1248 self.indicador= 0
1247 self.last_data_ele = None
1249 self.last_data_ele = None
1248 self.val_mean = None
1250 self.val_mean = None
1249
1251
1250 def update(self, dataOut):
1252 def update(self, dataOut):
1251
1253
1252 data = {}
1254 data = {}
1253 meta = {}
1255 meta = {}
1254 if hasattr(dataOut, 'dataPP_POWER'):
1256 if hasattr(dataOut, 'dataPP_POWER'):
1255 factor = 1
1257 factor = 1
1256 if hasattr(dataOut, 'nFFTPoints'):
1258 if hasattr(dataOut, 'nFFTPoints'):
1257 factor = dataOut.normFactor
1259 factor = dataOut.normFactor
1258 print("dataOut",dataOut.data_360.shape)
1260 print("dataOut",dataOut.data_360.shape)
1259 #
1261 #
1260 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1262 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1261 #
1263 #
1262 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1264 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1263 data['azi'] = dataOut.data_azi
1265 data['azi'] = dataOut.data_azi
1264 data['ele'] = dataOut.data_ele
1266 data['ele'] = dataOut.data_ele
1265 data['case_flag'] = dataOut.case_flag
1267 data['case_flag'] = dataOut.case_flag
1266 #print("UPDATE")
1268 #print("UPDATE")
1267 #print("data[weather]",data['weather'].shape)
1269 #print("data[weather]",data['weather'].shape)
1268 #print("data[azi]",data['azi'])
1270 #print("data[azi]",data['azi'])
1269 return data, meta
1271 return data, meta
1270
1272
1271 def get2List(self,angulos):
1273 def get2List(self,angulos):
1272 list1=[]
1274 list1=[]
1273 list2=[]
1275 list2=[]
1274 for i in reversed(range(len(angulos))):
1276 for i in reversed(range(len(angulos))):
1275 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1277 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1276 diff_ = angulos[i]-angulos[i-1]
1278 diff_ = angulos[i]-angulos[i-1]
1277 if abs(diff_) >1.5:
1279 if abs(diff_) >1.5:
1278 list1.append(i-1)
1280 list1.append(i-1)
1279 list2.append(diff_)
1281 list2.append(diff_)
1280 return list(reversed(list1)),list(reversed(list2))
1282 return list(reversed(list1)),list(reversed(list2))
1281
1283
1282 def fixData90(self,list_,ang_):
1284 def fixData90(self,list_,ang_):
1283 if list_[0]==-1:
1285 if list_[0]==-1:
1284 vec = numpy.where(ang_<ang_[0])
1286 vec = numpy.where(ang_<ang_[0])
1285 ang_[vec] = ang_[vec]+90
1287 ang_[vec] = ang_[vec]+90
1286 return ang_
1288 return ang_
1287 return ang_
1289 return ang_
1288
1290
1289 def fixData90HL(self,angulos):
1291 def fixData90HL(self,angulos):
1290 vec = numpy.where(angulos>=90)
1292 vec = numpy.where(angulos>=90)
1291 angulos[vec]=angulos[vec]-90
1293 angulos[vec]=angulos[vec]-90
1292 return angulos
1294 return angulos
1293
1295
1294
1296
1295 def search_pos(self,pos,list_):
1297 def search_pos(self,pos,list_):
1296 for i in range(len(list_)):
1298 for i in range(len(list_)):
1297 if pos == list_[i]:
1299 if pos == list_[i]:
1298 return True,i
1300 return True,i
1299 i=None
1301 i=None
1300 return False,i
1302 return False,i
1301
1303
1302 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1304 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1303 size = len(ang_)
1305 size = len(ang_)
1304 size2 = 0
1306 size2 = 0
1305 for i in range(len(list2_)):
1307 for i in range(len(list2_)):
1306 size2=size2+round(abs(list2_[i]))-1
1308 size2=size2+round(abs(list2_[i]))-1
1307 new_size= size+size2
1309 new_size= size+size2
1308 ang_new = numpy.zeros(new_size)
1310 ang_new = numpy.zeros(new_size)
1309 ang_new2 = numpy.zeros(new_size)
1311 ang_new2 = numpy.zeros(new_size)
1310
1312
1311 tmp = 0
1313 tmp = 0
1312 c = 0
1314 c = 0
1313 for i in range(len(ang_)):
1315 for i in range(len(ang_)):
1314 ang_new[tmp +c] = ang_[i]
1316 ang_new[tmp +c] = ang_[i]
1315 ang_new2[tmp+c] = ang_[i]
1317 ang_new2[tmp+c] = ang_[i]
1316 condition , value = self.search_pos(i,list1_)
1318 condition , value = self.search_pos(i,list1_)
1317 if condition:
1319 if condition:
1318 pos = tmp + c + 1
1320 pos = tmp + c + 1
1319 for k in range(round(abs(list2_[value]))-1):
1321 for k in range(round(abs(list2_[value]))-1):
1320 if tipo_case==0 or tipo_case==3:#subida
1322 if tipo_case==0 or tipo_case==3:#subida
1321 ang_new[pos+k] = ang_new[pos+k-1]+1
1323 ang_new[pos+k] = ang_new[pos+k-1]+1
1322 ang_new2[pos+k] = numpy.nan
1324 ang_new2[pos+k] = numpy.nan
1323 elif tipo_case==1 or tipo_case==2:#bajada
1325 elif tipo_case==1 or tipo_case==2:#bajada
1324 ang_new[pos+k] = ang_new[pos+k-1]-1
1326 ang_new[pos+k] = ang_new[pos+k-1]-1
1325 ang_new2[pos+k] = numpy.nan
1327 ang_new2[pos+k] = numpy.nan
1326
1328
1327 tmp = pos +k
1329 tmp = pos +k
1328 c = 0
1330 c = 0
1329 c=c+1
1331 c=c+1
1330 return ang_new,ang_new2
1332 return ang_new,ang_new2
1331
1333
1332 def globalCheckPED(self,angulos,tipo_case):
1334 def globalCheckPED(self,angulos,tipo_case):
1333 l1,l2 = self.get2List(angulos)
1335 l1,l2 = self.get2List(angulos)
1334 ##print("l1",l1)
1336 ##print("l1",l1)
1335 ##print("l2",l2)
1337 ##print("l2",l2)
1336 if len(l1)>0:
1338 if len(l1)>0:
1337 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1339 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1338 #l1,l2 = self.get2List(angulos2)
1340 #l1,l2 = self.get2List(angulos2)
1339 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1341 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1340 #ang1_ = self.fixData90HL(ang1_)
1342 #ang1_ = self.fixData90HL(ang1_)
1341 #ang2_ = self.fixData90HL(ang2_)
1343 #ang2_ = self.fixData90HL(ang2_)
1342 else:
1344 else:
1343 ang1_= angulos
1345 ang1_= angulos
1344 ang2_= angulos
1346 ang2_= angulos
1345 return ang1_,ang2_
1347 return ang1_,ang2_
1346
1348
1347
1349
1348 def replaceNAN(self,data_weather,data_ele,val):
1350 def replaceNAN(self,data_weather,data_ele,val):
1349 data= data_ele
1351 data= data_ele
1350 data_T= data_weather
1352 data_T= data_weather
1351 if data.shape[0]> data_T.shape[0]:
1353 if data.shape[0]> data_T.shape[0]:
1352 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1354 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1353 c = 0
1355 c = 0
1354 for i in range(len(data)):
1356 for i in range(len(data)):
1355 if numpy.isnan(data[i]):
1357 if numpy.isnan(data[i]):
1356 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1358 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1357 else:
1359 else:
1358 data_N[i,:]=data_T[c,:]
1360 data_N[i,:]=data_T[c,:]
1359 c=c+1
1361 c=c+1
1360 return data_N
1362 return data_N
1361 else:
1363 else:
1362 for i in range(len(data)):
1364 for i in range(len(data)):
1363 if numpy.isnan(data[i]):
1365 if numpy.isnan(data[i]):
1364 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1366 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1365 return data_T
1367 return data_T
1366
1368
1367 def check_case(self,data_ele,ang_max,ang_min):
1369 def check_case(self,data_ele,ang_max,ang_min):
1368 start = data_ele[0]
1370 start = data_ele[0]
1369 end = data_ele[-1]
1371 end = data_ele[-1]
1370 number = (end-start)
1372 number = (end-start)
1371 len_ang=len(data_ele)
1373 len_ang=len(data_ele)
1372 print("start",start)
1374 print("start",start)
1373 print("end",end)
1375 print("end",end)
1374 print("number",number)
1376 print("number",number)
1375
1377
1376 print("len_ang",len_ang)
1378 print("len_ang",len_ang)
1377
1379
1378 #exit(1)
1380 #exit(1)
1379
1381
1380 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
1382 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
1381 return 0
1383 return 0
1382 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
1384 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
1383 # return 1
1385 # return 1
1384 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
1386 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
1385 return 1
1387 return 1
1386 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
1388 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
1387 return 2
1389 return 2
1388 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
1390 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
1389 return 3
1391 return 3
1390
1392
1391
1393
1392 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1394 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1393 ang_max= ang_max
1395 ang_max= ang_max
1394 ang_min= ang_min
1396 ang_min= ang_min
1395 data_weather=data_weather
1397 data_weather=data_weather
1396 val_ch=val_ch
1398 val_ch=val_ch
1397 ##print("*********************DATA WEATHER**************************************")
1399 ##print("*********************DATA WEATHER**************************************")
1398 ##print(data_weather)
1400 ##print(data_weather)
1399 if self.ini==0:
1401 if self.ini==0:
1400 '''
1402 '''
1401 print("**********************************************")
1403 print("**********************************************")
1402 print("**********************************************")
1404 print("**********************************************")
1403 print("***************ini**************")
1405 print("***************ini**************")
1404 print("**********************************************")
1406 print("**********************************************")
1405 print("**********************************************")
1407 print("**********************************************")
1406 '''
1408 '''
1407 #print("data_ele",data_ele)
1409 #print("data_ele",data_ele)
1408 #----------------------------------------------------------
1410 #----------------------------------------------------------
1409 tipo_case = case_flag[-1]
1411 tipo_case = case_flag[-1]
1410 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1412 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1411 print("check_case",tipo_case)
1413 print("check_case",tipo_case)
1412 #exit(1)
1414 #exit(1)
1413 #--------------------- new -------------------------
1415 #--------------------- new -------------------------
1414 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1416 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1415
1417
1416 #-------------------------CAMBIOS RHI---------------------------------
1418 #-------------------------CAMBIOS RHI---------------------------------
1417 start= ang_min
1419 start= ang_min
1418 end = ang_max
1420 end = ang_max
1419 n= (ang_max-ang_min)/res
1421 n= (ang_max-ang_min)/res
1420 #------ new
1422 #------ new
1421 self.start_data_ele = data_ele_new[0]
1423 self.start_data_ele = data_ele_new[0]
1422 self.end_data_ele = data_ele_new[-1]
1424 self.end_data_ele = data_ele_new[-1]
1423 if tipo_case==0 or tipo_case==3: # SUBIDA
1425 if tipo_case==0 or tipo_case==3: # SUBIDA
1424 n1= round(self.start_data_ele)- start
1426 n1= round(self.start_data_ele)- start
1425 n2= end - round(self.end_data_ele)
1427 n2= end - round(self.end_data_ele)
1426 print(self.start_data_ele)
1428 print(self.start_data_ele)
1427 print(self.end_data_ele)
1429 print(self.end_data_ele)
1428 if n1>0:
1430 if n1>0:
1429 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1431 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1430 ele1_nan= numpy.ones(n1)*numpy.nan
1432 ele1_nan= numpy.ones(n1)*numpy.nan
1431 data_ele = numpy.hstack((ele1,data_ele_new))
1433 data_ele = numpy.hstack((ele1,data_ele_new))
1432 print("ele1_nan",ele1_nan.shape)
1434 print("ele1_nan",ele1_nan.shape)
1433 print("data_ele_old",data_ele_old.shape)
1435 print("data_ele_old",data_ele_old.shape)
1434 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1436 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1435 if n2>0:
1437 if n2>0:
1436 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1438 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1437 ele2_nan= numpy.ones(n2)*numpy.nan
1439 ele2_nan= numpy.ones(n2)*numpy.nan
1438 data_ele = numpy.hstack((data_ele,ele2))
1440 data_ele = numpy.hstack((data_ele,ele2))
1439 print("ele2_nan",ele2_nan.shape)
1441 print("ele2_nan",ele2_nan.shape)
1440 print("data_ele_old",data_ele_old.shape)
1442 print("data_ele_old",data_ele_old.shape)
1441 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1443 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1442
1444
1443 if tipo_case==1 or tipo_case==2: # BAJADA
1445 if tipo_case==1 or tipo_case==2: # BAJADA
1444 data_ele_new = data_ele_new[::-1] # reversa
1446 data_ele_new = data_ele_new[::-1] # reversa
1445 data_ele_old = data_ele_old[::-1]# reversa
1447 data_ele_old = data_ele_old[::-1]# reversa
1446 data_weather = data_weather[::-1,:]# reversa
1448 data_weather = data_weather[::-1,:]# reversa
1447 vec= numpy.where(data_ele_new<ang_max)
1449 vec= numpy.where(data_ele_new<ang_max)
1448 data_ele_new = data_ele_new[vec]
1450 data_ele_new = data_ele_new[vec]
1449 data_ele_old = data_ele_old[vec]
1451 data_ele_old = data_ele_old[vec]
1450 data_weather = data_weather[vec[0]]
1452 data_weather = data_weather[vec[0]]
1451 vec2= numpy.where(0<data_ele_new)
1453 vec2= numpy.where(0<data_ele_new)
1452 data_ele_new = data_ele_new[vec2]
1454 data_ele_new = data_ele_new[vec2]
1453 data_ele_old = data_ele_old[vec2]
1455 data_ele_old = data_ele_old[vec2]
1454 data_weather = data_weather[vec2[0]]
1456 data_weather = data_weather[vec2[0]]
1455 self.start_data_ele = data_ele_new[0]
1457 self.start_data_ele = data_ele_new[0]
1456 self.end_data_ele = data_ele_new[-1]
1458 self.end_data_ele = data_ele_new[-1]
1457
1459
1458 n1= round(self.start_data_ele)- start
1460 n1= round(self.start_data_ele)- start
1459 n2= end - round(self.end_data_ele)-1
1461 n2= end - round(self.end_data_ele)-1
1460 print(self.start_data_ele)
1462 print(self.start_data_ele)
1461 print(self.end_data_ele)
1463 print(self.end_data_ele)
1462 if n1>0:
1464 if n1>0:
1463 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1465 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1464 ele1_nan= numpy.ones(n1)*numpy.nan
1466 ele1_nan= numpy.ones(n1)*numpy.nan
1465 data_ele = numpy.hstack((ele1,data_ele_new))
1467 data_ele = numpy.hstack((ele1,data_ele_new))
1466 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1468 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1467 if n2>0:
1469 if n2>0:
1468 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1470 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1469 ele2_nan= numpy.ones(n2)*numpy.nan
1471 ele2_nan= numpy.ones(n2)*numpy.nan
1470 data_ele = numpy.hstack((data_ele,ele2))
1472 data_ele = numpy.hstack((data_ele,ele2))
1471 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1473 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1472 # RADAR
1474 # RADAR
1473 # NOTA data_ele y data_weather es la variable que retorna
1475 # NOTA data_ele y data_weather es la variable que retorna
1474 val_mean = numpy.mean(data_weather[:,-1])
1476 val_mean = numpy.mean(data_weather[:,-1])
1475 self.val_mean = val_mean
1477 self.val_mean = val_mean
1476 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1478 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1477 print("eleold",data_ele_old)
1479 print("eleold",data_ele_old)
1478 print(self.data_ele_tmp[val_ch])
1480 print(self.data_ele_tmp[val_ch])
1479 print(data_ele_old.shape[0])
1481 print(data_ele_old.shape[0])
1480 print(self.data_ele_tmp[val_ch].shape[0])
1482 print(self.data_ele_tmp[val_ch].shape[0])
1481 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
1483 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
1482 import sys
1484 import sys
1483 print("EXIT",self.ini)
1485 print("EXIT",self.ini)
1484
1486
1485 sys.exit(1)
1487 sys.exit(1)
1486 self.data_ele_tmp[val_ch]= data_ele_old
1488 self.data_ele_tmp[val_ch]= data_ele_old
1487 else:
1489 else:
1488 #print("**********************************************")
1490 #print("**********************************************")
1489 #print("****************VARIABLE**********************")
1491 #print("****************VARIABLE**********************")
1490 #-------------------------CAMBIOS RHI---------------------------------
1492 #-------------------------CAMBIOS RHI---------------------------------
1491 #---------------------------------------------------------------------
1493 #---------------------------------------------------------------------
1492 ##print("INPUT data_ele",data_ele)
1494 ##print("INPUT data_ele",data_ele)
1493 flag=0
1495 flag=0
1494 start_ele = self.res_ele[0]
1496 start_ele = self.res_ele[0]
1495 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1497 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1496 tipo_case = case_flag[-1]
1498 tipo_case = case_flag[-1]
1497 #print("TIPO DE DATA",tipo_case)
1499 #print("TIPO DE DATA",tipo_case)
1498 #-----------new------------
1500 #-----------new------------
1499 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
1501 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
1500 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1502 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1501
1503
1502 #-------------------------------NEW RHI ITERATIVO-------------------------
1504 #-------------------------------NEW RHI ITERATIVO-------------------------
1503
1505
1504 if tipo_case==0 : # SUBIDA
1506 if tipo_case==0 : # SUBIDA
1505 vec = numpy.where(data_ele<ang_max)
1507 vec = numpy.where(data_ele<ang_max)
1506 data_ele = data_ele[vec]
1508 data_ele = data_ele[vec]
1507 data_ele_old = data_ele_old[vec]
1509 data_ele_old = data_ele_old[vec]
1508 data_weather = data_weather[vec[0]]
1510 data_weather = data_weather[vec[0]]
1509
1511
1510 vec2 = numpy.where(0<data_ele)
1512 vec2 = numpy.where(0<data_ele)
1511 data_ele= data_ele[vec2]
1513 data_ele= data_ele[vec2]
1512 data_ele_old= data_ele_old[vec2]
1514 data_ele_old= data_ele_old[vec2]
1513 ##print(data_ele_new)
1515 ##print(data_ele_new)
1514 data_weather= data_weather[vec2[0]]
1516 data_weather= data_weather[vec2[0]]
1515
1517
1516 new_i_ele = int(round(data_ele[0]))
1518 new_i_ele = int(round(data_ele[0]))
1517 new_f_ele = int(round(data_ele[-1]))
1519 new_f_ele = int(round(data_ele[-1]))
1518 #print(new_i_ele)
1520 #print(new_i_ele)
1519 #print(new_f_ele)
1521 #print(new_f_ele)
1520 #print(data_ele,len(data_ele))
1522 #print(data_ele,len(data_ele))
1521 #print(data_ele_old,len(data_ele_old))
1523 #print(data_ele_old,len(data_ele_old))
1522 if new_i_ele< 2:
1524 if new_i_ele< 2:
1523 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1525 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1524 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)
1526 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)
1525 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
1527 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
1526 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
1528 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
1527 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
1529 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
1528 data_ele = self.res_ele
1530 data_ele = self.res_ele
1529 data_weather = self.res_weather[val_ch]
1531 data_weather = self.res_weather[val_ch]
1530
1532
1531 elif tipo_case==1 : #BAJADA
1533 elif tipo_case==1 : #BAJADA
1532 data_ele = data_ele[::-1] # reversa
1534 data_ele = data_ele[::-1] # reversa
1533 data_ele_old = data_ele_old[::-1]# reversa
1535 data_ele_old = data_ele_old[::-1]# reversa
1534 data_weather = data_weather[::-1,:]# reversa
1536 data_weather = data_weather[::-1,:]# reversa
1535 vec= numpy.where(data_ele<ang_max)
1537 vec= numpy.where(data_ele<ang_max)
1536 data_ele = data_ele[vec]
1538 data_ele = data_ele[vec]
1537 data_ele_old = data_ele_old[vec]
1539 data_ele_old = data_ele_old[vec]
1538 data_weather = data_weather[vec[0]]
1540 data_weather = data_weather[vec[0]]
1539 vec2= numpy.where(0<data_ele)
1541 vec2= numpy.where(0<data_ele)
1540 data_ele = data_ele[vec2]
1542 data_ele = data_ele[vec2]
1541 data_ele_old = data_ele_old[vec2]
1543 data_ele_old = data_ele_old[vec2]
1542 data_weather = data_weather[vec2[0]]
1544 data_weather = data_weather[vec2[0]]
1543
1545
1544
1546
1545 new_i_ele = int(round(data_ele[0]))
1547 new_i_ele = int(round(data_ele[0]))
1546 new_f_ele = int(round(data_ele[-1]))
1548 new_f_ele = int(round(data_ele[-1]))
1547 #print(data_ele)
1549 #print(data_ele)
1548 #print(ang_max)
1550 #print(ang_max)
1549 #print(data_ele_old)
1551 #print(data_ele_old)
1550 if new_i_ele <= 1:
1552 if new_i_ele <= 1:
1551 new_i_ele = 1
1553 new_i_ele = 1
1552 if round(data_ele[-1])>=ang_max-1:
1554 if round(data_ele[-1])>=ang_max-1:
1553 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1555 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1554 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)
1556 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)
1555 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
1557 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
1556 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
1558 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
1557 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
1559 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
1558 data_ele = self.res_ele
1560 data_ele = self.res_ele
1559 data_weather = self.res_weather[val_ch]
1561 data_weather = self.res_weather[val_ch]
1560
1562
1561 elif tipo_case==2: #bajada
1563 elif tipo_case==2: #bajada
1562 vec = numpy.where(data_ele<ang_max)
1564 vec = numpy.where(data_ele<ang_max)
1563 data_ele = data_ele[vec]
1565 data_ele = data_ele[vec]
1564 data_weather= data_weather[vec[0]]
1566 data_weather= data_weather[vec[0]]
1565
1567
1566 len_vec = len(vec)
1568 len_vec = len(vec)
1567 data_ele_new = data_ele[::-1] # reversa
1569 data_ele_new = data_ele[::-1] # reversa
1568 data_weather = data_weather[::-1,:]
1570 data_weather = data_weather[::-1,:]
1569 new_i_ele = int(data_ele_new[0])
1571 new_i_ele = int(data_ele_new[0])
1570 new_f_ele = int(data_ele_new[-1])
1572 new_f_ele = int(data_ele_new[-1])
1571
1573
1572 n1= new_i_ele- ang_min
1574 n1= new_i_ele- ang_min
1573 n2= ang_max - new_f_ele-1
1575 n2= ang_max - new_f_ele-1
1574 if n1>0:
1576 if n1>0:
1575 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1577 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1576 ele1_nan= numpy.ones(n1)*numpy.nan
1578 ele1_nan= numpy.ones(n1)*numpy.nan
1577 data_ele = numpy.hstack((ele1,data_ele_new))
1579 data_ele = numpy.hstack((ele1,data_ele_new))
1578 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1580 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1579 if n2>0:
1581 if n2>0:
1580 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1582 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1581 ele2_nan= numpy.ones(n2)*numpy.nan
1583 ele2_nan= numpy.ones(n2)*numpy.nan
1582 data_ele = numpy.hstack((data_ele,ele2))
1584 data_ele = numpy.hstack((data_ele,ele2))
1583 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1585 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1584
1586
1585 self.data_ele_tmp[val_ch] = data_ele_old
1587 self.data_ele_tmp[val_ch] = data_ele_old
1586 self.res_ele = data_ele
1588 self.res_ele = data_ele
1587 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1589 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1588 data_ele = self.res_ele
1590 data_ele = self.res_ele
1589 data_weather = self.res_weather[val_ch]
1591 data_weather = self.res_weather[val_ch]
1590
1592
1591 elif tipo_case==3:#subida
1593 elif tipo_case==3:#subida
1592 vec = numpy.where(0<data_ele)
1594 vec = numpy.where(0<data_ele)
1593 data_ele= data_ele[vec]
1595 data_ele= data_ele[vec]
1594 data_ele_new = data_ele
1596 data_ele_new = data_ele
1595 data_ele_old= data_ele_old[vec]
1597 data_ele_old= data_ele_old[vec]
1596 data_weather= data_weather[vec[0]]
1598 data_weather= data_weather[vec[0]]
1597 pos_ini = numpy.argmin(data_ele)
1599 pos_ini = numpy.argmin(data_ele)
1598 if pos_ini>0:
1600 if pos_ini>0:
1599 len_vec= len(data_ele)
1601 len_vec= len(data_ele)
1600 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1602 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1601 #print(vec3)
1603 #print(vec3)
1602 data_ele= data_ele[vec3]
1604 data_ele= data_ele[vec3]
1603 data_ele_new = data_ele
1605 data_ele_new = data_ele
1604 data_ele_old= data_ele_old[vec3]
1606 data_ele_old= data_ele_old[vec3]
1605 data_weather= data_weather[vec3]
1607 data_weather= data_weather[vec3]
1606
1608
1607 new_i_ele = int(data_ele_new[0])
1609 new_i_ele = int(data_ele_new[0])
1608 new_f_ele = int(data_ele_new[-1])
1610 new_f_ele = int(data_ele_new[-1])
1609 n1= new_i_ele- ang_min
1611 n1= new_i_ele- ang_min
1610 n2= ang_max - new_f_ele-1
1612 n2= ang_max - new_f_ele-1
1611 if n1>0:
1613 if n1>0:
1612 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1614 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1613 ele1_nan= numpy.ones(n1)*numpy.nan
1615 ele1_nan= numpy.ones(n1)*numpy.nan
1614 data_ele = numpy.hstack((ele1,data_ele_new))
1616 data_ele = numpy.hstack((ele1,data_ele_new))
1615 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1617 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1616 if n2>0:
1618 if n2>0:
1617 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1619 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1618 ele2_nan= numpy.ones(n2)*numpy.nan
1620 ele2_nan= numpy.ones(n2)*numpy.nan
1619 data_ele = numpy.hstack((data_ele,ele2))
1621 data_ele = numpy.hstack((data_ele,ele2))
1620 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1622 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1621
1623
1622 self.data_ele_tmp[val_ch] = data_ele_old
1624 self.data_ele_tmp[val_ch] = data_ele_old
1623 self.res_ele = data_ele
1625 self.res_ele = data_ele
1624 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1626 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1625 data_ele = self.res_ele
1627 data_ele = self.res_ele
1626 data_weather = self.res_weather[val_ch]
1628 data_weather = self.res_weather[val_ch]
1627 #print("self.data_ele_tmp",self.data_ele_tmp)
1629 #print("self.data_ele_tmp",self.data_ele_tmp)
1628 return data_weather,data_ele
1630 return data_weather,data_ele
1629
1631
1630
1632
1631 def plot(self):
1633 def plot(self):
1632 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1634 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1633 data = self.data[-1]
1635 data = self.data[-1]
1634 r = self.data.yrange
1636 r = self.data.yrange
1635 delta_height = r[1]-r[0]
1637 delta_height = r[1]-r[0]
1636 r_mask = numpy.where(r>=0)[0]
1638 r_mask = numpy.where(r>=0)[0]
1637 ##print("delta_height",delta_height)
1639 ##print("delta_height",delta_height)
1638 #print("r_mask",r_mask,len(r_mask))
1640 #print("r_mask",r_mask,len(r_mask))
1639 r = numpy.arange(len(r_mask))*delta_height
1641 r = numpy.arange(len(r_mask))*delta_height
1640 self.y = 2*r
1642 self.y = 2*r
1641 res = 1
1643 res = 1
1642 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1644 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1643 ang_max = self.ang_max
1645 ang_max = self.ang_max
1644 ang_min = self.ang_min
1646 ang_min = self.ang_min
1645 var_ang =ang_max - ang_min
1647 var_ang =ang_max - ang_min
1646 step = (int(var_ang)/(res*data['weather'].shape[0]))
1648 step = (int(var_ang)/(res*data['weather'].shape[0]))
1647 ###print("step",step)
1649 ###print("step",step)
1648 #--------------------------------------------------------
1650 #--------------------------------------------------------
1649 ##print('weather',data['weather'].shape)
1651 ##print('weather',data['weather'].shape)
1650 ##print('ele',data['ele'].shape)
1652 ##print('ele',data['ele'].shape)
1651
1653
1652 ###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)
1654 ###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)
1653 ###self.res_azi = numpy.mean(data['azi'])
1655 ###self.res_azi = numpy.mean(data['azi'])
1654 ###print("self.res_ele",self.res_ele)
1656 ###print("self.res_ele",self.res_ele)
1655 plt.clf()
1657 plt.clf()
1656 subplots = [121, 122]
1658 subplots = [121, 122]
1657 try:
1659 try:
1658 if self.data[-2]['ele'].max()<data['ele'].max():
1660 if self.data[-2]['ele'].max()<data['ele'].max():
1659 self.ini=0
1661 self.ini=0
1660 except:
1662 except:
1661 pass
1663 pass
1662 if self.ini==0:
1664 if self.ini==0:
1663 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1665 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1664 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1666 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1665 print("SHAPE",self.data_ele_tmp.shape)
1667 print("SHAPE",self.data_ele_tmp.shape)
1666
1668
1667 for i,ax in enumerate(self.axes):
1669 for i,ax in enumerate(self.axes):
1668 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'])
1670 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'])
1669 self.res_azi = numpy.mean(data['azi'])
1671 self.res_azi = numpy.mean(data['azi'])
1670
1672
1671 if ax.firsttime:
1673 if ax.firsttime:
1672 #plt.clf()
1674 #plt.clf()
1673 print("Frist Plot")
1675 print("Frist Plot")
1674 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)
1676 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)
1675 #fig=self.figures[0]
1677 #fig=self.figures[0]
1676 else:
1678 else:
1677 #plt.clf()
1679 #plt.clf()
1678 print("ELSE PLOT")
1680 print("ELSE PLOT")
1679 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 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)
1680 caax = cgax.parasites[0]
1682 caax = cgax.parasites[0]
1681 paax = cgax.parasites[1]
1683 paax = cgax.parasites[1]
1682 cbar = plt.gcf().colorbar(pm, pad=0.075)
1684 cbar = plt.gcf().colorbar(pm, pad=0.075)
1683 caax.set_xlabel('x_range [km]')
1685 caax.set_xlabel('x_range [km]')
1684 caax.set_ylabel('y_range [km]')
1686 caax.set_ylabel('y_range [km]')
1685 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')
1687 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')
1686 print("***************************self.ini****************************",self.ini)
1688 print("***************************self.ini****************************",self.ini)
1687 self.ini= self.ini+1
1689 self.ini= self.ini+1
1688
1690
1689
1691
1690
1692
1691
1693
1692
1694
1693 class WeatherRHI_vRF4_Plot(Plot):
1695 class WeatherRHI_vRF4_Plot(Plot):
1694 CODE = 'RHI'
1696 CODE = 'RHI'
1695 plot_name = 'RHI'
1697 plot_name = 'RHI'
1696 #plot_type = 'rhistyle'
1698 #plot_type = 'rhistyle'
1697 buffering = False
1699 buffering = False
1698
1700
1699 def setup(self):
1701 def setup(self):
1700
1702
1701 self.ncols = 1
1703 self.ncols = 1
1702 self.nrows = 1
1704 self.nrows = 1
1703 self.nplots= 1
1705 self.nplots= 1
1704 self.ylabel= 'Range [Km]'
1706 self.ylabel= 'Range [Km]'
1705 self.xlabel= 'Range [Km]'
1707 self.xlabel= 'Range [Km]'
1706 self.titles= ['RHI']
1708 self.titles= ['RHI']
1707 self.polar = True
1709 self.polar = True
1708 self.grid = True
1710 self.grid = True
1709 if self.channels is not None:
1711 if self.channels is not None:
1710 self.nplots = len(self.channels)
1712 self.nplots = len(self.channels)
1711 self.nrows = len(self.channels)
1713 self.nrows = len(self.channels)
1712 else:
1714 else:
1713 self.nplots = self.data.shape(self.CODE)[0]
1715 self.nplots = self.data.shape(self.CODE)[0]
1714 self.nrows = self.nplots
1716 self.nrows = self.nplots
1715 self.channels = list(range(self.nplots))
1717 self.channels = list(range(self.nplots))
1716
1718
1717 if self.CODE == 'Power':
1719 if self.CODE == 'Power':
1718 self.cb_label = r'Power (dB)'
1720 self.cb_label = r'Power (dB)'
1719 elif self.CODE == 'Doppler':
1721 elif self.CODE == 'Doppler':
1720 self.cb_label = r'Velocity (m/s)'
1722 self.cb_label = r'Velocity (m/s)'
1721 self.colorbar=True
1723 self.colorbar=True
1722 self.width =8
1724 self.width =8
1723 self.height =8
1725 self.height =8
1724 self.ini =0
1726 self.ini =0
1725 self.len_azi =0
1727 self.len_azi =0
1726 self.buffer_ini = None
1728 self.buffer_ini = None
1727 self.buffer_ele = None
1729 self.buffer_ele = None
1728 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1730 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1729 self.flag =0
1731 self.flag =0
1730 self.indicador= 0
1732 self.indicador= 0
1731 self.last_data_ele = None
1733 self.last_data_ele = None
1732 self.val_mean = None
1734 self.val_mean = None
1733
1735
1734 def update(self, dataOut):
1736 def update(self, dataOut):
1735
1737
1736 data = {}
1738 data = {}
1737 meta = {}
1739 meta = {}
1738 if hasattr(dataOut, 'dataPP_POWER'):
1740 if hasattr(dataOut, 'dataPP_POWER'):
1739 factor = 1
1741 factor = 1
1740 if hasattr(dataOut, 'nFFTPoints'):
1742 if hasattr(dataOut, 'nFFTPoints'):
1741 factor = dataOut.normFactor
1743 factor = dataOut.normFactor
1742
1744
1743 if 'pow' in self.attr_data[0].lower():
1745 if 'pow' in self.attr_data[0].lower():
1744 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1746 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1745 else:
1747 else:
1746 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1748 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1747
1749
1748 data['azi'] = dataOut.data_azi
1750 data['azi'] = dataOut.data_azi
1749 data['ele'] = dataOut.data_ele
1751 data['ele'] = dataOut.data_ele
1750
1752
1751 return data, meta
1753 return data, meta
1752
1754
1753 def plot(self):
1755 def plot(self):
1754 data = self.data[-1]
1756 data = self.data[-1]
1755 r = self.data.yrange
1757 r = self.data.yrange
1756 delta_height = r[1]-r[0]
1758 delta_height = r[1]-r[0]
1757 r_mask = numpy.where(r>=0)[0]
1759 r_mask = numpy.where(r>=0)[0]
1758 self.r_mask =r_mask
1760 self.r_mask =r_mask
1759 r = numpy.arange(len(r_mask))*delta_height
1761 r = numpy.arange(len(r_mask))*delta_height
1760 self.y = 2*r
1762 self.y = 2*r
1761
1763
1762 z = data['data'][self.channels[0]][:,r_mask]
1764 z = data['data'][self.channels[0]][:,r_mask]
1763
1765
1764 self.titles = []
1766 self.titles = []
1765
1767
1766 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1768 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1767 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1769 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1768 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1770 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1769 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1771 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1770 self.ang_min = self.ang_min if self.ang_min else 0
1772 self.ang_min = self.ang_min if self.ang_min else 0
1771 self.ang_max = self.ang_max if self.ang_max else 90
1773 self.ang_max = self.ang_max if self.ang_max else 90
1772
1774
1773 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1775 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1774
1776
1775 for i,ax in enumerate(self.axes):
1777 for i,ax in enumerate(self.axes):
1776
1778
1777 if ax.firsttime:
1779 if ax.firsttime:
1778 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1780 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1779 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1781 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1780
1782
1781 else:
1783 else:
1782 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1784 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1783 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1785 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1784 ax.grid(True)
1786 ax.grid(True)
1785 if len(self.channels) !=1:
1787 if len(self.channels) !=1:
1786 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(numpy.mean(data['azi']),1)), x) for x in range(self.nrows)]
1788 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(numpy.mean(data['azi']),1)), x) for x in range(self.nrows)]
1787 else:
1789 else:
1788 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['azi']),1)), self.channels[0])]
1790 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['azi']),1)), self.channels[0])]
@@ -1,5088 +1,5089
1
1
2 import os
2 import os
3 import time
3 import time
4 import math
4 import math
5
5
6 import re
6 import re
7 import datetime
7 import datetime
8 import copy
8 import copy
9 import sys
9 import sys
10 import importlib
10 import importlib
11 import itertools
11 import itertools
12
12
13 from multiprocessing import Pool, TimeoutError
13 from multiprocessing import Pool, TimeoutError
14 from multiprocessing.pool import ThreadPool
14 from multiprocessing.pool import ThreadPool
15 import numpy
15 import numpy
16 import glob
16 import glob
17 import scipy
17 import scipy
18 import h5py
18 import h5py
19 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
19 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
20 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
20 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
21 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
21 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
22 from scipy import asarray as ar,exp
22 from scipy import asarray as ar,exp
23 from scipy.optimize import curve_fit
23 from scipy.optimize import curve_fit
24 from schainpy.utils import log
24 from schainpy.utils import log
25 import schainpy.admin
25 import schainpy.admin
26 import warnings
26 import warnings
27 from scipy import optimize, interpolate, signal, stats, ndimage
27 from scipy import optimize, interpolate, signal, stats, ndimage
28 from scipy.optimize.optimize import OptimizeWarning
28 from scipy.optimize.optimize import OptimizeWarning
29 warnings.filterwarnings('ignore')
29 warnings.filterwarnings('ignore')
30
30
31
31
32 SPEED_OF_LIGHT = 299792458
32 SPEED_OF_LIGHT = 299792458
33
33
34 '''solving pickling issue'''
34 '''solving pickling issue'''
35
35
36 def _pickle_method(method):
36 def _pickle_method(method):
37 func_name = method.__func__.__name__
37 func_name = method.__func__.__name__
38 obj = method.__self__
38 obj = method.__self__
39 cls = method.__self__.__class__
39 cls = method.__self__.__class__
40 return _unpickle_method, (func_name, obj, cls)
40 return _unpickle_method, (func_name, obj, cls)
41
41
42 def _unpickle_method(func_name, obj, cls):
42 def _unpickle_method(func_name, obj, cls):
43 for cls in cls.mro():
43 for cls in cls.mro():
44 try:
44 try:
45 func = cls.__dict__[func_name]
45 func = cls.__dict__[func_name]
46 except KeyError:
46 except KeyError:
47 pass
47 pass
48 else:
48 else:
49 break
49 break
50 return func.__get__(obj, cls)
50 return func.__get__(obj, cls)
51
51
52 def isNumber(str):
52 def isNumber(str):
53 try:
53 try:
54 float(str)
54 float(str)
55 return True
55 return True
56 except:
56 except:
57 return False
57 return False
58
58
59 class ParametersProc(ProcessingUnit):
59 class ParametersProc(ProcessingUnit):
60
60
61 METHODS = {}
61 METHODS = {}
62 nSeconds = None
62 nSeconds = None
63
63
64 def __init__(self):
64 def __init__(self):
65 ProcessingUnit.__init__(self)
65 ProcessingUnit.__init__(self)
66
66
67 # self.objectDict = {}
67 # self.objectDict = {}
68 self.buffer = None
68 self.buffer = None
69 self.firstdatatime = None
69 self.firstdatatime = None
70 self.profIndex = 0
70 self.profIndex = 0
71 self.dataOut = Parameters()
71 self.dataOut = Parameters()
72 self.setupReq = False #Agregar a todas las unidades de proc
72 self.setupReq = False #Agregar a todas las unidades de proc
73
73
74 def __updateObjFromInput(self):
74 def __updateObjFromInput(self):
75
75
76 self.dataOut.inputUnit = self.dataIn.type
76 self.dataOut.inputUnit = self.dataIn.type
77
77
78 self.dataOut.timeZone = self.dataIn.timeZone
78 self.dataOut.timeZone = self.dataIn.timeZone
79 self.dataOut.dstFlag = self.dataIn.dstFlag
79 self.dataOut.dstFlag = self.dataIn.dstFlag
80 self.dataOut.errorCount = self.dataIn.errorCount
80 self.dataOut.errorCount = self.dataIn.errorCount
81 self.dataOut.useLocalTime = self.dataIn.useLocalTime
81 self.dataOut.useLocalTime = self.dataIn.useLocalTime
82
82
83 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
83 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
84 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
84 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
85 self.dataOut.channelList = self.dataIn.channelList
85 self.dataOut.channelList = self.dataIn.channelList
86 self.dataOut.heightList = self.dataIn.heightList
86 self.dataOut.heightList = self.dataIn.heightList
87 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
87 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
88 # self.dataOut.nHeights = self.dataIn.nHeights
88 # self.dataOut.nHeights = self.dataIn.nHeights
89 # self.dataOut.nChannels = self.dataIn.nChannels
89 # self.dataOut.nChannels = self.dataIn.nChannels
90 # self.dataOut.nBaud = self.dataIn.nBaud
90 # self.dataOut.nBaud = self.dataIn.nBaud
91 # self.dataOut.nCode = self.dataIn.nCode
91 # self.dataOut.nCode = self.dataIn.nCode
92 # self.dataOut.code = self.dataIn.code
92 # self.dataOut.code = self.dataIn.code
93 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
93 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
94 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
94 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
95 # self.dataOut.utctime = self.firstdatatime
95 # self.dataOut.utctime = self.firstdatatime
96 self.dataOut.utctime = self.dataIn.utctime
96 self.dataOut.utctime = self.dataIn.utctime
97 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
97 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
98 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
98 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
99 self.dataOut.nCohInt = self.dataIn.nCohInt
99 self.dataOut.nCohInt = self.dataIn.nCohInt
100 # self.dataOut.nIncohInt = 1
100 # self.dataOut.nIncohInt = 1
101 # self.dataOut.ippSeconds = self.dataIn.ippSeconds
101 # self.dataOut.ippSeconds = self.dataIn.ippSeconds
102 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
102 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
103 self.dataOut.timeInterval1 = self.dataIn.timeInterval
103 self.dataOut.timeInterval1 = self.dataIn.timeInterval
104 self.dataOut.heightList = self.dataIn.heightList
104 self.dataOut.heightList = self.dataIn.heightList
105 self.dataOut.frequency = self.dataIn.frequency
105 self.dataOut.frequency = self.dataIn.frequency
106 # self.dataOut.noise = self.dataIn.noise
106 # self.dataOut.noise = self.dataIn.noise
107 self.dataOut.runNextUnit = self.dataIn.runNextUnit
107 self.dataOut.runNextUnit = self.dataIn.runNextUnit
108
108
109 def run(self, runNextUnit = 0):
109 def run(self, runNextUnit = 0):
110
110
111 self.dataIn.runNextUnit = runNextUnit
111 self.dataIn.runNextUnit = runNextUnit
112 #print("HOLA MUNDO SOY YO")
112 #print("HOLA MUNDO SOY YO")
113 #---------------------- Voltage Data ---------------------------
113 #---------------------- Voltage Data ---------------------------
114
114
115 if self.dataIn.type == "Voltage":
115 if self.dataIn.type == "Voltage":
116
116
117 self.__updateObjFromInput()
117 self.__updateObjFromInput()
118 self.dataOut.data_pre = self.dataIn.data.copy()
118 self.dataOut.data_pre = self.dataIn.data.copy()
119 self.dataOut.flagNoData = False
119 self.dataOut.flagNoData = False
120 self.dataOut.utctimeInit = self.dataIn.utctime
120 self.dataOut.utctimeInit = self.dataIn.utctime
121 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
121 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
122
122
123 if hasattr(self.dataIn, 'flagDataAsBlock'):
123 if hasattr(self.dataIn, 'flagDataAsBlock'):
124 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
124 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
125
125
126 if hasattr(self.dataIn, 'profileIndex'):
126 if hasattr(self.dataIn, 'profileIndex'):
127 self.dataOut.profileIndex = self.dataIn.profileIndex
127 self.dataOut.profileIndex = self.dataIn.profileIndex
128
128
129 if hasattr(self.dataIn, 'dataPP_POW'):
129 if hasattr(self.dataIn, 'dataPP_POW'):
130 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
130 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
131
131
132 if hasattr(self.dataIn, 'dataPP_POWER'):
132 if hasattr(self.dataIn, 'dataPP_POWER'):
133 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
133 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
134
134
135 if hasattr(self.dataIn, 'dataPP_DOP'):
135 if hasattr(self.dataIn, 'dataPP_DOP'):
136 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
136 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
137
137
138 if hasattr(self.dataIn, 'dataPP_SNR'):
138 if hasattr(self.dataIn, 'dataPP_SNR'):
139 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
139 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
140
140
141 if hasattr(self.dataIn, 'dataPP_WIDTH'):
141 if hasattr(self.dataIn, 'dataPP_WIDTH'):
142 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
142 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
143 return
143 return
144
144
145 #---------------------- Spectra Data ---------------------------
145 #---------------------- Spectra Data ---------------------------
146
146
147 if self.dataIn.type == "Spectra":
147 if self.dataIn.type == "Spectra":
148 #print("que paso en spectra")
148 #print("que paso en spectra")
149 self.dataOut.data_pre = [self.dataIn.data_spc, self.dataIn.data_cspc]
149 self.dataOut.data_pre = [self.dataIn.data_spc, self.dataIn.data_cspc]
150 self.dataOut.data_spc = self.dataIn.data_spc
150 self.dataOut.data_spc = self.dataIn.data_spc
151 self.dataOut.data_cspc = self.dataIn.data_cspc
151 self.dataOut.data_cspc = self.dataIn.data_cspc
152 self.dataOut.nProfiles = self.dataIn.nProfiles
152 self.dataOut.nProfiles = self.dataIn.nProfiles
153 self.dataOut.nIncohInt = self.dataIn.nIncohInt
153 self.dataOut.nIncohInt = self.dataIn.nIncohInt
154 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
154 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
155 self.dataOut.ippFactor = self.dataIn.ippFactor
155 self.dataOut.ippFactor = self.dataIn.ippFactor
156 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
156 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
157 self.dataOut.spc_noise = self.dataIn.getNoise()
157 self.dataOut.spc_noise = self.dataIn.getNoise()
158 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
158 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
159 # self.dataOut.normFactor = self.dataIn.normFactor
159 # self.dataOut.normFactor = self.dataIn.normFactor
160 self.dataOut.pairsList = self.dataIn.pairsList
160 self.dataOut.pairsList = self.dataIn.pairsList
161 self.dataOut.groupList = self.dataIn.pairsList
161 self.dataOut.groupList = self.dataIn.pairsList
162 self.dataOut.flagNoData = False
162 self.dataOut.flagNoData = False
163
163
164 if hasattr(self.dataIn, 'flagDataAsBlock'):
164 if hasattr(self.dataIn, 'flagDataAsBlock'):
165 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
165 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
166
166
167 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
167 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
168 self.dataOut.ChanDist = self.dataIn.ChanDist
168 self.dataOut.ChanDist = self.dataIn.ChanDist
169 else: self.dataOut.ChanDist = None
169 else: self.dataOut.ChanDist = None
170
170
171 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
171 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
172 # self.dataOut.VelRange = self.dataIn.VelRange
172 # self.dataOut.VelRange = self.dataIn.VelRange
173 #else: self.dataOut.VelRange = None
173 #else: self.dataOut.VelRange = None
174
174
175 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
175 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
176 self.dataOut.RadarConst = self.dataIn.RadarConst
176 self.dataOut.RadarConst = self.dataIn.RadarConst
177
177
178 if hasattr(self.dataIn, 'NPW'): #NPW
178 if hasattr(self.dataIn, 'NPW'): #NPW
179 self.dataOut.NPW = self.dataIn.NPW
179 self.dataOut.NPW = self.dataIn.NPW
180
180
181 if hasattr(self.dataIn, 'COFA'): #COFA
181 if hasattr(self.dataIn, 'COFA'): #COFA
182 self.dataOut.COFA = self.dataIn.COFA
182 self.dataOut.COFA = self.dataIn.COFA
183
183
184
184
185
185
186 #---------------------- Correlation Data ---------------------------
186 #---------------------- Correlation Data ---------------------------
187
187
188 if self.dataIn.type == "Correlation":
188 if self.dataIn.type == "Correlation":
189 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
189 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
190
190
191 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
191 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
192 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
192 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
193 self.dataOut.groupList = (acf_pairs, ccf_pairs)
193 self.dataOut.groupList = (acf_pairs, ccf_pairs)
194
194
195 self.dataOut.abscissaList = self.dataIn.lagRange
195 self.dataOut.abscissaList = self.dataIn.lagRange
196 self.dataOut.noise = self.dataIn.noise
196 self.dataOut.noise = self.dataIn.noise
197 self.dataOut.data_snr = self.dataIn.SNR
197 self.dataOut.data_snr = self.dataIn.SNR
198 self.dataOut.flagNoData = False
198 self.dataOut.flagNoData = False
199 self.dataOut.nAvg = self.dataIn.nAvg
199 self.dataOut.nAvg = self.dataIn.nAvg
200
200
201 #---------------------- Parameters Data ---------------------------
201 #---------------------- Parameters Data ---------------------------
202
202
203 if self.dataIn.type == "Parameters":
203 if self.dataIn.type == "Parameters":
204 self.dataOut.copy(self.dataIn)
204 self.dataOut.copy(self.dataIn)
205 self.dataOut.flagNoData = False
205 self.dataOut.flagNoData = False
206 #print("yo si entre")
206 #print("yo si entre")
207
207
208 return True
208 return True
209
209
210 self.__updateObjFromInput()
210 self.__updateObjFromInput()
211 #print("yo si entre2")
211 #print("yo si entre2")
212
212
213 self.dataOut.utctimeInit = self.dataIn.utctime
213 self.dataOut.utctimeInit = self.dataIn.utctime
214 self.dataOut.paramInterval = self.dataIn.timeInterval
214 self.dataOut.paramInterval = self.dataIn.timeInterval
215 #print("soy spectra ",self.dataOut.utctimeInit)
215 #print("soy spectra ",self.dataOut.utctimeInit)
216 return
216 return
217
217
218
218
219 def target(tups):
219 def target(tups):
220
220
221 obj, args = tups
221 obj, args = tups
222
222
223 return obj.FitGau(args)
223 return obj.FitGau(args)
224
224
225 class RemoveWideGC(Operation):
225 class RemoveWideGC(Operation):
226 ''' This class remove the wide clutter and replace it with a simple interpolation points
226 ''' This class remove the wide clutter and replace it with a simple interpolation points
227 This mainly applies to CLAIRE radar
227 This mainly applies to CLAIRE radar
228
228
229 ClutterWidth : Width to look for the clutter peak
229 ClutterWidth : Width to look for the clutter peak
230
230
231 Input:
231 Input:
232
232
233 self.dataOut.data_pre : SPC and CSPC
233 self.dataOut.data_pre : SPC and CSPC
234 self.dataOut.spc_range : To select wind and rainfall velocities
234 self.dataOut.spc_range : To select wind and rainfall velocities
235
235
236 Affected:
236 Affected:
237
237
238 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
238 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
239
239
240 Written by D. ScipiΓ³n 25.02.2021
240 Written by D. ScipiΓ³n 25.02.2021
241 '''
241 '''
242 def __init__(self):
242 def __init__(self):
243 Operation.__init__(self)
243 Operation.__init__(self)
244 self.i = 0
244 self.i = 0
245 self.ich = 0
245 self.ich = 0
246 self.ir = 0
246 self.ir = 0
247
247
248 def run(self, dataOut, ClutterWidth=2.5):
248 def run(self, dataOut, ClutterWidth=2.5):
249 # print ('Entering RemoveWideGC ... ')
249 # print ('Entering RemoveWideGC ... ')
250
250
251 self.spc = dataOut.data_pre[0].copy()
251 self.spc = dataOut.data_pre[0].copy()
252 self.spc_out = dataOut.data_pre[0].copy()
252 self.spc_out = dataOut.data_pre[0].copy()
253 self.Num_Chn = self.spc.shape[0]
253 self.Num_Chn = self.spc.shape[0]
254 self.Num_Hei = self.spc.shape[2]
254 self.Num_Hei = self.spc.shape[2]
255 VelRange = dataOut.spc_range[2][:-1]
255 VelRange = dataOut.spc_range[2][:-1]
256 dv = VelRange[1]-VelRange[0]
256 dv = VelRange[1]-VelRange[0]
257
257
258 # Find the velocities that corresponds to zero
258 # Find the velocities that corresponds to zero
259 gc_values = numpy.squeeze(numpy.where(numpy.abs(VelRange) <= ClutterWidth))
259 gc_values = numpy.squeeze(numpy.where(numpy.abs(VelRange) <= ClutterWidth))
260
260
261 # Removing novalid data from the spectra
261 # Removing novalid data from the spectra
262 for ich in range(self.Num_Chn) :
262 for ich in range(self.Num_Chn) :
263 for ir in range(self.Num_Hei) :
263 for ir in range(self.Num_Hei) :
264 # Estimate the noise at each range
264 # Estimate the noise at each range
265 HSn = hildebrand_sekhon(self.spc[ich,:,ir],dataOut.nIncohInt)
265 HSn = hildebrand_sekhon(self.spc[ich,:,ir],dataOut.nIncohInt)
266
266
267 # Removing the noise floor at each range
267 # Removing the noise floor at each range
268 novalid = numpy.where(self.spc[ich,:,ir] < HSn)
268 novalid = numpy.where(self.spc[ich,:,ir] < HSn)
269 self.spc[ich,novalid,ir] = HSn
269 self.spc[ich,novalid,ir] = HSn
270
270
271 junk = numpy.append(numpy.insert(numpy.squeeze(self.spc[ich,gc_values,ir]),0,HSn),HSn)
271 junk = numpy.append(numpy.insert(numpy.squeeze(self.spc[ich,gc_values,ir]),0,HSn),HSn)
272 j1index = numpy.squeeze(numpy.where(numpy.diff(junk)>0))
272 j1index = numpy.squeeze(numpy.where(numpy.diff(junk)>0))
273 j2index = numpy.squeeze(numpy.where(numpy.diff(junk)<0))
273 j2index = numpy.squeeze(numpy.where(numpy.diff(junk)<0))
274 if ((numpy.size(j1index)<=1) | (numpy.size(j2index)<=1)) :
274 if ((numpy.size(j1index)<=1) | (numpy.size(j2index)<=1)) :
275 continue
275 continue
276 junk3 = numpy.squeeze(numpy.diff(j1index))
276 junk3 = numpy.squeeze(numpy.diff(j1index))
277 junk4 = numpy.squeeze(numpy.diff(j2index))
277 junk4 = numpy.squeeze(numpy.diff(j2index))
278
278
279 valleyindex = j2index[numpy.where(junk4>1)]
279 valleyindex = j2index[numpy.where(junk4>1)]
280 peakindex = j1index[numpy.where(junk3>1)]
280 peakindex = j1index[numpy.where(junk3>1)]
281
281
282 isvalid = numpy.squeeze(numpy.where(numpy.abs(VelRange[gc_values[peakindex]]) <= 2.5*dv))
282 isvalid = numpy.squeeze(numpy.where(numpy.abs(VelRange[gc_values[peakindex]]) <= 2.5*dv))
283 if numpy.size(isvalid) == 0 :
283 if numpy.size(isvalid) == 0 :
284 continue
284 continue
285 if numpy.size(isvalid) >1 :
285 if numpy.size(isvalid) >1 :
286 vindex = numpy.argmax(self.spc[ich,gc_values[peakindex[isvalid]],ir])
286 vindex = numpy.argmax(self.spc[ich,gc_values[peakindex[isvalid]],ir])
287 isvalid = isvalid[vindex]
287 isvalid = isvalid[vindex]
288
288
289 # clutter peak
289 # clutter peak
290 gcpeak = peakindex[isvalid]
290 gcpeak = peakindex[isvalid]
291 vl = numpy.where(valleyindex < gcpeak)
291 vl = numpy.where(valleyindex < gcpeak)
292 if numpy.size(vl) == 0:
292 if numpy.size(vl) == 0:
293 continue
293 continue
294 gcvl = valleyindex[vl[0][-1]]
294 gcvl = valleyindex[vl[0][-1]]
295 vr = numpy.where(valleyindex > gcpeak)
295 vr = numpy.where(valleyindex > gcpeak)
296 if numpy.size(vr) == 0:
296 if numpy.size(vr) == 0:
297 continue
297 continue
298 gcvr = valleyindex[vr[0][0]]
298 gcvr = valleyindex[vr[0][0]]
299
299
300 # Removing the clutter
300 # Removing the clutter
301 interpindex = numpy.array([gc_values[gcvl], gc_values[gcvr]])
301 interpindex = numpy.array([gc_values[gcvl], gc_values[gcvr]])
302 gcindex = gc_values[gcvl+1:gcvr-1]
302 gcindex = gc_values[gcvl+1:gcvr-1]
303 self.spc_out[ich,gcindex,ir] = numpy.interp(VelRange[gcindex],VelRange[interpindex],self.spc[ich,interpindex,ir])
303 self.spc_out[ich,gcindex,ir] = numpy.interp(VelRange[gcindex],VelRange[interpindex],self.spc[ich,interpindex,ir])
304
304
305 dataOut.data_pre[0] = self.spc_out
305 dataOut.data_pre[0] = self.spc_out
306 #print ('Leaving RemoveWideGC ... ')
306 #print ('Leaving RemoveWideGC ... ')
307 return dataOut
307 return dataOut
308
308
309 class SpectralFilters(Operation):
309 class SpectralFilters(Operation):
310 ''' This class allows to replace the novalid values with noise for each channel
310 ''' This class allows to replace the novalid values with noise for each channel
311 This applies to CLAIRE RADAR
311 This applies to CLAIRE RADAR
312
312
313 PositiveLimit : RightLimit of novalid data
313 PositiveLimit : RightLimit of novalid data
314 NegativeLimit : LeftLimit of novalid data
314 NegativeLimit : LeftLimit of novalid data
315
315
316 Input:
316 Input:
317
317
318 self.dataOut.data_pre : SPC and CSPC
318 self.dataOut.data_pre : SPC and CSPC
319 self.dataOut.spc_range : To select wind and rainfall velocities
319 self.dataOut.spc_range : To select wind and rainfall velocities
320
320
321 Affected:
321 Affected:
322
322
323 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
323 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
324
324
325 Written by D. ScipiΓ³n 29.01.2021
325 Written by D. ScipiΓ³n 29.01.2021
326 '''
326 '''
327 def __init__(self):
327 def __init__(self):
328 Operation.__init__(self)
328 Operation.__init__(self)
329 self.i = 0
329 self.i = 0
330
330
331 def run(self, dataOut, ):
331 def run(self, dataOut, ):
332
332
333 self.spc = dataOut.data_pre[0].copy()
333 self.spc = dataOut.data_pre[0].copy()
334 self.Num_Chn = self.spc.shape[0]
334 self.Num_Chn = self.spc.shape[0]
335 VelRange = dataOut.spc_range[2]
335 VelRange = dataOut.spc_range[2]
336
336
337 # novalid corresponds to data within the Negative and PositiveLimit
337 # novalid corresponds to data within the Negative and PositiveLimit
338
338
339
339
340 # Removing novalid data from the spectra
340 # Removing novalid data from the spectra
341 for i in range(self.Num_Chn):
341 for i in range(self.Num_Chn):
342 self.spc[i,novalid,:] = dataOut.noise[i]
342 self.spc[i,novalid,:] = dataOut.noise[i]
343 dataOut.data_pre[0] = self.spc
343 dataOut.data_pre[0] = self.spc
344 return dataOut
344 return dataOut
345
345
346 class GaussianFit(Operation):
346 class GaussianFit(Operation):
347
347
348 '''
348 '''
349 Function that fit of one and two generalized gaussians (gg) based
349 Function that fit of one and two generalized gaussians (gg) based
350 on the PSD shape across an "power band" identified from a cumsum of
350 on the PSD shape across an "power band" identified from a cumsum of
351 the measured spectrum - noise.
351 the measured spectrum - noise.
352
352
353 Input:
353 Input:
354 self.dataOut.data_pre : SelfSpectra
354 self.dataOut.data_pre : SelfSpectra
355
355
356 Output:
356 Output:
357 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
357 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
358
358
359 '''
359 '''
360 def __init__(self):
360 def __init__(self):
361 Operation.__init__(self)
361 Operation.__init__(self)
362 self.i=0
362 self.i=0
363
363
364
364
365 # def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
365 # def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
366 def run(self, dataOut, SNRdBlimit=-9, method='generalized'):
366 def run(self, dataOut, SNRdBlimit=-9, method='generalized'):
367 """This routine will find a couple of generalized Gaussians to a power spectrum
367 """This routine will find a couple of generalized Gaussians to a power spectrum
368 methods: generalized, squared
368 methods: generalized, squared
369 input: spc
369 input: spc
370 output:
370 output:
371 noise, amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1
371 noise, amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1
372 """
372 """
373 print ('Entering ',method,' double Gaussian fit')
373 print ('Entering ',method,' double Gaussian fit')
374 self.spc = dataOut.data_pre[0].copy()
374 self.spc = dataOut.data_pre[0].copy()
375 self.Num_Hei = self.spc.shape[2]
375 self.Num_Hei = self.spc.shape[2]
376 self.Num_Bin = self.spc.shape[1]
376 self.Num_Bin = self.spc.shape[1]
377 self.Num_Chn = self.spc.shape[0]
377 self.Num_Chn = self.spc.shape[0]
378
378
379 start_time = time.time()
379 start_time = time.time()
380
380
381 pool = Pool(processes=self.Num_Chn)
381 pool = Pool(processes=self.Num_Chn)
382 args = [(dataOut.spc_range[2], ich, dataOut.spc_noise[ich], dataOut.nIncohInt, SNRdBlimit) for ich in range(self.Num_Chn)]
382 args = [(dataOut.spc_range[2], ich, dataOut.spc_noise[ich], dataOut.nIncohInt, SNRdBlimit) for ich in range(self.Num_Chn)]
383 objs = [self for __ in range(self.Num_Chn)]
383 objs = [self for __ in range(self.Num_Chn)]
384 attrs = list(zip(objs, args))
384 attrs = list(zip(objs, args))
385 DGauFitParam = pool.map(target, attrs)
385 DGauFitParam = pool.map(target, attrs)
386 # Parameters:
386 # Parameters:
387 # 0. Noise, 1. Amplitude, 2. Shift, 3. Width 4. Power
387 # 0. Noise, 1. Amplitude, 2. Shift, 3. Width 4. Power
388 dataOut.DGauFitParams = numpy.asarray(DGauFitParam)
388 dataOut.DGauFitParams = numpy.asarray(DGauFitParam)
389
389
390 # Double Gaussian Curves
390 # Double Gaussian Curves
391 gau0 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
391 gau0 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
392 gau0[:] = numpy.NaN
392 gau0[:] = numpy.NaN
393 gau1 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
393 gau1 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
394 gau1[:] = numpy.NaN
394 gau1[:] = numpy.NaN
395 x_mtr = numpy.transpose(numpy.tile(dataOut.getVelRange(1)[:-1], (self.Num_Hei,1)))
395 x_mtr = numpy.transpose(numpy.tile(dataOut.getVelRange(1)[:-1], (self.Num_Hei,1)))
396 for iCh in range(self.Num_Chn):
396 for iCh in range(self.Num_Chn):
397 N0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,0]] * self.Num_Bin))
397 N0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,0]] * self.Num_Bin))
398 N1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,1]] * self.Num_Bin))
398 N1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,1]] * self.Num_Bin))
399 A0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,0]] * self.Num_Bin))
399 A0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,0]] * self.Num_Bin))
400 A1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,1]] * self.Num_Bin))
400 A1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,1]] * self.Num_Bin))
401 v0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,0]] * self.Num_Bin))
401 v0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,0]] * self.Num_Bin))
402 v1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,1]] * self.Num_Bin))
402 v1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,1]] * self.Num_Bin))
403 s0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,0]] * self.Num_Bin))
403 s0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,0]] * self.Num_Bin))
404 s1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,1]] * self.Num_Bin))
404 s1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,1]] * self.Num_Bin))
405 if method == 'genealized':
405 if method == 'genealized':
406 p0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,0]] * self.Num_Bin))
406 p0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,0]] * self.Num_Bin))
407 p1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,1]] * self.Num_Bin))
407 p1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,1]] * self.Num_Bin))
408 elif method == 'squared':
408 elif method == 'squared':
409 p0 = 2.
409 p0 = 2.
410 p1 = 2.
410 p1 = 2.
411 gau0[iCh] = A0*numpy.exp(-0.5*numpy.abs((x_mtr-v0)/s0)**p0)+N0
411 gau0[iCh] = A0*numpy.exp(-0.5*numpy.abs((x_mtr-v0)/s0)**p0)+N0
412 gau1[iCh] = A1*numpy.exp(-0.5*numpy.abs((x_mtr-v1)/s1)**p1)+N1
412 gau1[iCh] = A1*numpy.exp(-0.5*numpy.abs((x_mtr-v1)/s1)**p1)+N1
413 dataOut.GaussFit0 = gau0
413 dataOut.GaussFit0 = gau0
414 dataOut.GaussFit1 = gau1
414 dataOut.GaussFit1 = gau1
415
415
416 print('Leaving ',method ,' double Gaussian fit')
416 print('Leaving ',method ,' double Gaussian fit')
417 return dataOut
417 return dataOut
418
418
419 def FitGau(self, X):
419 def FitGau(self, X):
420 # print('Entering FitGau')
420 # print('Entering FitGau')
421 # Assigning the variables
421 # Assigning the variables
422 Vrange, ch, wnoise, num_intg, SNRlimit = X
422 Vrange, ch, wnoise, num_intg, SNRlimit = X
423 # Noise Limits
423 # Noise Limits
424 noisebl = wnoise * 0.9
424 noisebl = wnoise * 0.9
425 noisebh = wnoise * 1.1
425 noisebh = wnoise * 1.1
426 # Radar Velocity
426 # Radar Velocity
427 Va = max(Vrange)
427 Va = max(Vrange)
428 deltav = Vrange[1] - Vrange[0]
428 deltav = Vrange[1] - Vrange[0]
429 x = numpy.arange(self.Num_Bin)
429 x = numpy.arange(self.Num_Bin)
430
430
431 # print ('stop 0')
431 # print ('stop 0')
432
432
433 # 5 parameters, 2 Gaussians
433 # 5 parameters, 2 Gaussians
434 DGauFitParam = numpy.zeros([5, self.Num_Hei,2])
434 DGauFitParam = numpy.zeros([5, self.Num_Hei,2])
435 DGauFitParam[:] = numpy.NaN
435 DGauFitParam[:] = numpy.NaN
436
436
437 # SPCparam = []
437 # SPCparam = []
438 # SPC_ch1 = numpy.zeros([self.Num_Bin,self.Num_Hei])
438 # SPC_ch1 = numpy.zeros([self.Num_Bin,self.Num_Hei])
439 # SPC_ch2 = numpy.zeros([self.Num_Bin,self.Num_Hei])
439 # SPC_ch2 = numpy.zeros([self.Num_Bin,self.Num_Hei])
440 # SPC_ch1[:] = 0 #numpy.NaN
440 # SPC_ch1[:] = 0 #numpy.NaN
441 # SPC_ch2[:] = 0 #numpy.NaN
441 # SPC_ch2[:] = 0 #numpy.NaN
442 # print ('stop 1')
442 # print ('stop 1')
443 for ht in range(self.Num_Hei):
443 for ht in range(self.Num_Hei):
444 # print (ht)
444 # print (ht)
445 # print ('stop 2')
445 # print ('stop 2')
446 # Spectra at each range
446 # Spectra at each range
447 spc = numpy.asarray(self.spc)[ch,:,ht]
447 spc = numpy.asarray(self.spc)[ch,:,ht]
448 snr = ( spc.mean() - wnoise ) / wnoise
448 snr = ( spc.mean() - wnoise ) / wnoise
449 snrdB = 10.*numpy.log10(snr)
449 snrdB = 10.*numpy.log10(snr)
450
450
451 #print ('stop 3')
451 #print ('stop 3')
452 if snrdB < SNRlimit :
452 if snrdB < SNRlimit :
453 # snr = numpy.NaN
453 # snr = numpy.NaN
454 # SPC_ch1[:,ht] = 0#numpy.NaN
454 # SPC_ch1[:,ht] = 0#numpy.NaN
455 # SPC_ch1[:,ht] = 0#numpy.NaN
455 # SPC_ch1[:,ht] = 0#numpy.NaN
456 # SPCparam = (SPC_ch1,SPC_ch2)
456 # SPCparam = (SPC_ch1,SPC_ch2)
457 # print ('SNR less than SNRth')
457 # print ('SNR less than SNRth')
458 continue
458 continue
459 # wnoise = hildebrand_sekhon(spc,num_intg)
459 # wnoise = hildebrand_sekhon(spc,num_intg)
460 # print ('stop 2.01')
460 # print ('stop 2.01')
461 #############################################
461 #############################################
462 # normalizing spc and noise
462 # normalizing spc and noise
463 # This part differs from gg1
463 # This part differs from gg1
464 # spc_norm_max = max(spc) #commented by D. ScipiΓ³n 19.03.2021
464 # spc_norm_max = max(spc) #commented by D. ScipiΓ³n 19.03.2021
465 #spc = spc / spc_norm_max
465 #spc = spc / spc_norm_max
466 # pnoise = pnoise #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
466 # pnoise = pnoise #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
467 #############################################
467 #############################################
468
468
469 # print ('stop 2.1')
469 # print ('stop 2.1')
470 fatspectra=1.0
470 fatspectra=1.0
471 # noise per channel.... we might want to use the noise at each range
471 # noise per channel.... we might want to use the noise at each range
472
472
473 # wnoise = noise_ #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
473 # wnoise = noise_ #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
474 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
474 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
475 #if wnoise>1.1*pnoise: # to be tested later
475 #if wnoise>1.1*pnoise: # to be tested later
476 # wnoise=pnoise
476 # wnoise=pnoise
477 # noisebl = wnoise*0.9
477 # noisebl = wnoise*0.9
478 # noisebh = wnoise*1.1
478 # noisebh = wnoise*1.1
479 spc = spc - wnoise # signal
479 spc = spc - wnoise # signal
480
480
481 # print ('stop 2.2')
481 # print ('stop 2.2')
482 minx = numpy.argmin(spc)
482 minx = numpy.argmin(spc)
483 #spcs=spc.copy()
483 #spcs=spc.copy()
484 spcs = numpy.roll(spc,-minx)
484 spcs = numpy.roll(spc,-minx)
485 cum = numpy.cumsum(spcs)
485 cum = numpy.cumsum(spcs)
486 # tot_noise = wnoise * self.Num_Bin #64;
486 # tot_noise = wnoise * self.Num_Bin #64;
487
487
488 # print ('stop 2.3')
488 # print ('stop 2.3')
489 # snr = sum(spcs) / tot_noise
489 # snr = sum(spcs) / tot_noise
490 # snrdB = 10.*numpy.log10(snr)
490 # snrdB = 10.*numpy.log10(snr)
491 #print ('stop 3')
491 #print ('stop 3')
492 # if snrdB < SNRlimit :
492 # if snrdB < SNRlimit :
493 # snr = numpy.NaN
493 # snr = numpy.NaN
494 # SPC_ch1[:,ht] = 0#numpy.NaN
494 # SPC_ch1[:,ht] = 0#numpy.NaN
495 # SPC_ch1[:,ht] = 0#numpy.NaN
495 # SPC_ch1[:,ht] = 0#numpy.NaN
496 # SPCparam = (SPC_ch1,SPC_ch2)
496 # SPCparam = (SPC_ch1,SPC_ch2)
497 # print ('SNR less than SNRth')
497 # print ('SNR less than SNRth')
498 # continue
498 # continue
499
499
500
500
501 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
501 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
502 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
502 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
503 # print ('stop 4')
503 # print ('stop 4')
504 cummax = max(cum)
504 cummax = max(cum)
505 epsi = 0.08 * fatspectra # cumsum to narrow down the energy region
505 epsi = 0.08 * fatspectra # cumsum to narrow down the energy region
506 cumlo = cummax * epsi
506 cumlo = cummax * epsi
507 cumhi = cummax * (1-epsi)
507 cumhi = cummax * (1-epsi)
508 powerindex = numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
508 powerindex = numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
509
509
510 # print ('stop 5')
510 # print ('stop 5')
511 if len(powerindex) < 1:# case for powerindex 0
511 if len(powerindex) < 1:# case for powerindex 0
512 # print ('powerindex < 1')
512 # print ('powerindex < 1')
513 continue
513 continue
514 powerlo = powerindex[0]
514 powerlo = powerindex[0]
515 powerhi = powerindex[-1]
515 powerhi = powerindex[-1]
516 powerwidth = powerhi-powerlo
516 powerwidth = powerhi-powerlo
517 if powerwidth <= 1:
517 if powerwidth <= 1:
518 # print('powerwidth <= 1')
518 # print('powerwidth <= 1')
519 continue
519 continue
520
520
521 # print ('stop 6')
521 # print ('stop 6')
522 firstpeak = powerlo + powerwidth/10.# first gaussian energy location
522 firstpeak = powerlo + powerwidth/10.# first gaussian energy location
523 secondpeak = powerhi - powerwidth/10. #second gaussian energy location
523 secondpeak = powerhi - powerwidth/10. #second gaussian energy location
524 midpeak = (firstpeak + secondpeak)/2.
524 midpeak = (firstpeak + secondpeak)/2.
525 firstamp = spcs[int(firstpeak)]
525 firstamp = spcs[int(firstpeak)]
526 secondamp = spcs[int(secondpeak)]
526 secondamp = spcs[int(secondpeak)]
527 midamp = spcs[int(midpeak)]
527 midamp = spcs[int(midpeak)]
528
528
529 y_data = spc + wnoise
529 y_data = spc + wnoise
530
530
531 ''' single Gaussian '''
531 ''' single Gaussian '''
532 shift0 = numpy.mod(midpeak+minx, self.Num_Bin )
532 shift0 = numpy.mod(midpeak+minx, self.Num_Bin )
533 width0 = powerwidth/4.#Initialization entire power of spectrum divided by 4
533 width0 = powerwidth/4.#Initialization entire power of spectrum divided by 4
534 power0 = 2.
534 power0 = 2.
535 amplitude0 = midamp
535 amplitude0 = midamp
536 state0 = [shift0,width0,amplitude0,power0,wnoise]
536 state0 = [shift0,width0,amplitude0,power0,wnoise]
537 bnds = ((0,self.Num_Bin-1),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
537 bnds = ((0,self.Num_Bin-1),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
538 lsq1 = fmin_l_bfgs_b(self.misfit1, state0, args=(y_data,x,num_intg), bounds=bnds, approx_grad=True)
538 lsq1 = fmin_l_bfgs_b(self.misfit1, state0, args=(y_data,x,num_intg), bounds=bnds, approx_grad=True)
539 # print ('stop 7.1')
539 # print ('stop 7.1')
540 # print (bnds)
540 # print (bnds)
541
541
542 chiSq1=lsq1[1]
542 chiSq1=lsq1[1]
543
543
544 # print ('stop 8')
544 # print ('stop 8')
545 if fatspectra<1.0 and powerwidth<4:
545 if fatspectra<1.0 and powerwidth<4:
546 choice=0
546 choice=0
547 Amplitude0=lsq1[0][2]
547 Amplitude0=lsq1[0][2]
548 shift0=lsq1[0][0]
548 shift0=lsq1[0][0]
549 width0=lsq1[0][1]
549 width0=lsq1[0][1]
550 p0=lsq1[0][3]
550 p0=lsq1[0][3]
551 Amplitude1=0.
551 Amplitude1=0.
552 shift1=0.
552 shift1=0.
553 width1=0.
553 width1=0.
554 p1=0.
554 p1=0.
555 noise=lsq1[0][4]
555 noise=lsq1[0][4]
556 #return (numpy.array([shift0,width0,Amplitude0,p0]),
556 #return (numpy.array([shift0,width0,Amplitude0,p0]),
557 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
557 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
558
558
559 # print ('stop 9')
559 # print ('stop 9')
560 ''' two Gaussians '''
560 ''' two Gaussians '''
561 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
561 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
562 shift0 = numpy.mod(firstpeak+minx, self.Num_Bin )
562 shift0 = numpy.mod(firstpeak+minx, self.Num_Bin )
563 shift1 = numpy.mod(secondpeak+minx, self.Num_Bin )
563 shift1 = numpy.mod(secondpeak+minx, self.Num_Bin )
564 width0 = powerwidth/6.
564 width0 = powerwidth/6.
565 width1 = width0
565 width1 = width0
566 power0 = 2.
566 power0 = 2.
567 power1 = power0
567 power1 = power0
568 amplitude0 = firstamp
568 amplitude0 = firstamp
569 amplitude1 = secondamp
569 amplitude1 = secondamp
570 state0 = [shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
570 state0 = [shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
571 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
571 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
572 bnds=((0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
572 bnds=((0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
573 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
573 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
574
574
575 # print ('stop 10')
575 # print ('stop 10')
576 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
576 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
577
577
578 # print ('stop 11')
578 # print ('stop 11')
579 chiSq2 = lsq2[1]
579 chiSq2 = lsq2[1]
580
580
581 # print ('stop 12')
581 # print ('stop 12')
582
582
583 oneG = (chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
583 oneG = (chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
584
584
585 # print ('stop 13')
585 # print ('stop 13')
586 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
586 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
587 if oneG:
587 if oneG:
588 choice = 0
588 choice = 0
589 else:
589 else:
590 w1 = lsq2[0][1]; w2 = lsq2[0][5]
590 w1 = lsq2[0][1]; w2 = lsq2[0][5]
591 a1 = lsq2[0][2]; a2 = lsq2[0][6]
591 a1 = lsq2[0][2]; a2 = lsq2[0][6]
592 p1 = lsq2[0][3]; p2 = lsq2[0][7]
592 p1 = lsq2[0][3]; p2 = lsq2[0][7]
593 s1 = (2**(1+1./p1))*scipy.special.gamma(1./p1)/p1
593 s1 = (2**(1+1./p1))*scipy.special.gamma(1./p1)/p1
594 s2 = (2**(1+1./p2))*scipy.special.gamma(1./p2)/p2
594 s2 = (2**(1+1./p2))*scipy.special.gamma(1./p2)/p2
595 gp1 = a1*w1*s1; gp2 = a2*w2*s2 # power content of each ggaussian with proper p scaling
595 gp1 = a1*w1*s1; gp2 = a2*w2*s2 # power content of each ggaussian with proper p scaling
596
596
597 if gp1>gp2:
597 if gp1>gp2:
598 if a1>0.7*a2:
598 if a1>0.7*a2:
599 choice = 1
599 choice = 1
600 else:
600 else:
601 choice = 2
601 choice = 2
602 elif gp2>gp1:
602 elif gp2>gp1:
603 if a2>0.7*a1:
603 if a2>0.7*a1:
604 choice = 2
604 choice = 2
605 else:
605 else:
606 choice = 1
606 choice = 1
607 else:
607 else:
608 choice = numpy.argmax([a1,a2])+1
608 choice = numpy.argmax([a1,a2])+1
609 #else:
609 #else:
610 #choice=argmin([std2a,std2b])+1
610 #choice=argmin([std2a,std2b])+1
611
611
612 else: # with low SNR go to the most energetic peak
612 else: # with low SNR go to the most energetic peak
613 choice = numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
613 choice = numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
614
614
615 # print ('stop 14')
615 # print ('stop 14')
616 shift0 = lsq2[0][0]
616 shift0 = lsq2[0][0]
617 vel0 = Vrange[0] + shift0 * deltav
617 vel0 = Vrange[0] + shift0 * deltav
618 shift1 = lsq2[0][4]
618 shift1 = lsq2[0][4]
619 # vel1=Vrange[0] + shift1 * deltav
619 # vel1=Vrange[0] + shift1 * deltav
620
620
621 # max_vel = 1.0
621 # max_vel = 1.0
622 # Va = max(Vrange)
622 # Va = max(Vrange)
623 # deltav = Vrange[1]-Vrange[0]
623 # deltav = Vrange[1]-Vrange[0]
624 # print ('stop 15')
624 # print ('stop 15')
625 #first peak will be 0, second peak will be 1
625 #first peak will be 0, second peak will be 1
626 # if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range # Commented by D.ScipiΓ³n 19.03.2021
626 # if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range # Commented by D.ScipiΓ³n 19.03.2021
627 if vel0 > -Va and vel0 < Va : #first peak is in the correct range
627 if vel0 > -Va and vel0 < Va : #first peak is in the correct range
628 shift0 = lsq2[0][0]
628 shift0 = lsq2[0][0]
629 width0 = lsq2[0][1]
629 width0 = lsq2[0][1]
630 Amplitude0 = lsq2[0][2]
630 Amplitude0 = lsq2[0][2]
631 p0 = lsq2[0][3]
631 p0 = lsq2[0][3]
632
632
633 shift1 = lsq2[0][4]
633 shift1 = lsq2[0][4]
634 width1 = lsq2[0][5]
634 width1 = lsq2[0][5]
635 Amplitude1 = lsq2[0][6]
635 Amplitude1 = lsq2[0][6]
636 p1 = lsq2[0][7]
636 p1 = lsq2[0][7]
637 noise = lsq2[0][8]
637 noise = lsq2[0][8]
638 else:
638 else:
639 shift1 = lsq2[0][0]
639 shift1 = lsq2[0][0]
640 width1 = lsq2[0][1]
640 width1 = lsq2[0][1]
641 Amplitude1 = lsq2[0][2]
641 Amplitude1 = lsq2[0][2]
642 p1 = lsq2[0][3]
642 p1 = lsq2[0][3]
643
643
644 shift0 = lsq2[0][4]
644 shift0 = lsq2[0][4]
645 width0 = lsq2[0][5]
645 width0 = lsq2[0][5]
646 Amplitude0 = lsq2[0][6]
646 Amplitude0 = lsq2[0][6]
647 p0 = lsq2[0][7]
647 p0 = lsq2[0][7]
648 noise = lsq2[0][8]
648 noise = lsq2[0][8]
649
649
650 if Amplitude0<0.05: # in case the peak is noise
650 if Amplitude0<0.05: # in case the peak is noise
651 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
651 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
652 if Amplitude1<0.05:
652 if Amplitude1<0.05:
653 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
653 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
654
654
655 # print ('stop 16 ')
655 # print ('stop 16 ')
656 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0)/width0)**p0)
656 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0)/width0)**p0)
657 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1)/width1)**p1)
657 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1)/width1)**p1)
658 # SPCparam = (SPC_ch1,SPC_ch2)
658 # SPCparam = (SPC_ch1,SPC_ch2)
659
659
660 DGauFitParam[0,ht,0] = noise
660 DGauFitParam[0,ht,0] = noise
661 DGauFitParam[0,ht,1] = noise
661 DGauFitParam[0,ht,1] = noise
662 DGauFitParam[1,ht,0] = Amplitude0
662 DGauFitParam[1,ht,0] = Amplitude0
663 DGauFitParam[1,ht,1] = Amplitude1
663 DGauFitParam[1,ht,1] = Amplitude1
664 DGauFitParam[2,ht,0] = Vrange[0] + shift0 * deltav
664 DGauFitParam[2,ht,0] = Vrange[0] + shift0 * deltav
665 DGauFitParam[2,ht,1] = Vrange[0] + shift1 * deltav
665 DGauFitParam[2,ht,1] = Vrange[0] + shift1 * deltav
666 DGauFitParam[3,ht,0] = width0 * deltav
666 DGauFitParam[3,ht,0] = width0 * deltav
667 DGauFitParam[3,ht,1] = width1 * deltav
667 DGauFitParam[3,ht,1] = width1 * deltav
668 DGauFitParam[4,ht,0] = p0
668 DGauFitParam[4,ht,0] = p0
669 DGauFitParam[4,ht,1] = p1
669 DGauFitParam[4,ht,1] = p1
670
670
671 # print (DGauFitParam.shape)
671 # print (DGauFitParam.shape)
672 # print ('Leaving FitGau')
672 # print ('Leaving FitGau')
673 return DGauFitParam
673 return DGauFitParam
674 # return SPCparam
674 # return SPCparam
675 # return GauSPC
675 # return GauSPC
676
676
677 def y_model1(self,x,state):
677 def y_model1(self,x,state):
678 shift0, width0, amplitude0, power0, noise = state
678 shift0, width0, amplitude0, power0, noise = state
679 model0 = amplitude0*numpy.exp(-0.5*abs((x - shift0)/width0)**power0)
679 model0 = amplitude0*numpy.exp(-0.5*abs((x - shift0)/width0)**power0)
680 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
680 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
681 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
681 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
682 return model0 + model0u + model0d + noise
682 return model0 + model0u + model0d + noise
683
683
684 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
684 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
685 shift0, width0, amplitude0, power0, shift1, width1, amplitude1, power1, noise = state
685 shift0, width0, amplitude0, power0, shift1, width1, amplitude1, power1, noise = state
686 model0 = amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
686 model0 = amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
687 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
687 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
688 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
688 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
689
689
690 model1 = amplitude1*numpy.exp(-0.5*abs((x - shift1)/width1)**power1)
690 model1 = amplitude1*numpy.exp(-0.5*abs((x - shift1)/width1)**power1)
691 model1u = amplitude1*numpy.exp(-0.5*abs((x - shift1 - self.Num_Bin)/width1)**power1)
691 model1u = amplitude1*numpy.exp(-0.5*abs((x - shift1 - self.Num_Bin)/width1)**power1)
692 model1d = amplitude1*numpy.exp(-0.5*abs((x - shift1 + self.Num_Bin)/width1)**power1)
692 model1d = amplitude1*numpy.exp(-0.5*abs((x - shift1 + self.Num_Bin)/width1)**power1)
693 return model0 + model0u + model0d + model1 + model1u + model1d + noise
693 return model0 + model0u + model0d + model1 + model1u + model1d + noise
694
694
695 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
695 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
696
696
697 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
697 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
698
698
699 def misfit2(self,state,y_data,x,num_intg):
699 def misfit2(self,state,y_data,x,num_intg):
700 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
700 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
701
701
702
702
703
703
704 class PrecipitationProc(Operation):
704 class PrecipitationProc(Operation):
705
705
706 '''
706 '''
707 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
707 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
708
708
709 Input:
709 Input:
710 self.dataOut.data_pre : SelfSpectra
710 self.dataOut.data_pre : SelfSpectra
711
711
712 Output:
712 Output:
713
713
714 self.dataOut.data_output : Reflectivity factor, rainfall Rate
714 self.dataOut.data_output : Reflectivity factor, rainfall Rate
715
715
716
716
717 Parameters affected:
717 Parameters affected:
718 '''
718 '''
719
719
720 def __init__(self):
720 def __init__(self):
721 Operation.__init__(self)
721 Operation.__init__(self)
722 self.i=0
722 self.i=0
723
723
724 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
724 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
725 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km2 = 0.93, Altitude=3350,SNRdBlimit=-30):
725 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km2 = 0.93, Altitude=3350,SNRdBlimit=-30):
726
726
727 # print ('Entering PrecepitationProc ... ')
727 # print ('Entering PrecepitationProc ... ')
728
728
729 if radar == "MIRA35C" :
729 if radar == "MIRA35C" :
730
730
731 self.spc = dataOut.data_pre[0].copy()
731 self.spc = dataOut.data_pre[0].copy()
732 self.Num_Hei = self.spc.shape[2]
732 self.Num_Hei = self.spc.shape[2]
733 self.Num_Bin = self.spc.shape[1]
733 self.Num_Bin = self.spc.shape[1]
734 self.Num_Chn = self.spc.shape[0]
734 self.Num_Chn = self.spc.shape[0]
735 Ze = self.dBZeMODE2(dataOut)
735 Ze = self.dBZeMODE2(dataOut)
736
736
737 else:
737 else:
738
738
739 self.spc = dataOut.data_pre[0].copy()
739 self.spc = dataOut.data_pre[0].copy()
740
740
741 #NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX
741 #NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX
742 self.spc[:,:,0:7]= numpy.NaN
742 self.spc[:,:,0:7]= numpy.NaN
743
743
744 self.Num_Hei = self.spc.shape[2]
744 self.Num_Hei = self.spc.shape[2]
745 self.Num_Bin = self.spc.shape[1]
745 self.Num_Bin = self.spc.shape[1]
746 self.Num_Chn = self.spc.shape[0]
746 self.Num_Chn = self.spc.shape[0]
747
747
748 VelRange = dataOut.spc_range[2]
748 VelRange = dataOut.spc_range[2]
749
749
750 ''' Se obtiene la constante del RADAR '''
750 ''' Se obtiene la constante del RADAR '''
751
751
752 self.Pt = Pt
752 self.Pt = Pt
753 self.Gt = Gt
753 self.Gt = Gt
754 self.Gr = Gr
754 self.Gr = Gr
755 self.Lambda = Lambda
755 self.Lambda = Lambda
756 self.aL = aL
756 self.aL = aL
757 self.tauW = tauW
757 self.tauW = tauW
758 self.ThetaT = ThetaT
758 self.ThetaT = ThetaT
759 self.ThetaR = ThetaR
759 self.ThetaR = ThetaR
760 self.GSys = 10**(36.63/10) # Ganancia de los LNA 36.63 dB
760 self.GSys = 10**(36.63/10) # Ganancia de los LNA 36.63 dB
761 self.lt = 10**(1.67/10) # Perdida en cables Tx 1.67 dB
761 self.lt = 10**(1.67/10) # Perdida en cables Tx 1.67 dB
762 self.lr = 10**(5.73/10) # Perdida en cables Rx 5.73 dB
762 self.lr = 10**(5.73/10) # Perdida en cables Rx 5.73 dB
763
763
764 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
764 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
765 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
765 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
766 RadarConstant = 10e-26 * Numerator / Denominator #
766 RadarConstant = 10e-26 * Numerator / Denominator #
767 ExpConstant = 10**(40/10) #Constante Experimental
767 ExpConstant = 10**(40/10) #Constante Experimental
768
768
769 SignalPower = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
769 SignalPower = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
770 for i in range(self.Num_Chn):
770 for i in range(self.Num_Chn):
771 SignalPower[i,:,:] = self.spc[i,:,:] - dataOut.noise[i]
771 SignalPower[i,:,:] = self.spc[i,:,:] - dataOut.noise[i]
772 SignalPower[numpy.where(SignalPower < 0)] = 1e-20
772 SignalPower[numpy.where(SignalPower < 0)] = 1e-20
773
773
774 SPCmean = numpy.mean(SignalPower, 0)
774 SPCmean = numpy.mean(SignalPower, 0)
775 Pr = SPCmean[:,:]/dataOut.normFactor
775 Pr = SPCmean[:,:]/dataOut.normFactor
776
776
777 # Declaring auxiliary variables
777 # Declaring auxiliary variables
778 Range = dataOut.heightList*1000. #Range in m
778 Range = dataOut.heightList*1000. #Range in m
779 # replicate the heightlist to obtain a matrix [Num_Bin,Num_Hei]
779 # replicate the heightlist to obtain a matrix [Num_Bin,Num_Hei]
780 rMtrx = numpy.transpose(numpy.transpose([dataOut.heightList*1000.] * self.Num_Bin))
780 rMtrx = numpy.transpose(numpy.transpose([dataOut.heightList*1000.] * self.Num_Bin))
781 zMtrx = rMtrx+Altitude
781 zMtrx = rMtrx+Altitude
782 # replicate the VelRange to obtain a matrix [Num_Bin,Num_Hei]
782 # replicate the VelRange to obtain a matrix [Num_Bin,Num_Hei]
783 VelMtrx = numpy.transpose(numpy.tile(VelRange[:-1], (self.Num_Hei,1)))
783 VelMtrx = numpy.transpose(numpy.tile(VelRange[:-1], (self.Num_Hei,1)))
784
784
785 # height dependence to air density Foote and Du Toit (1969)
785 # height dependence to air density Foote and Du Toit (1969)
786 delv_z = 1 + 3.68e-5 * zMtrx + 1.71e-9 * zMtrx**2
786 delv_z = 1 + 3.68e-5 * zMtrx + 1.71e-9 * zMtrx**2
787 VMtrx = VelMtrx / delv_z #Normalized velocity
787 VMtrx = VelMtrx / delv_z #Normalized velocity
788 VMtrx[numpy.where(VMtrx> 9.6)] = numpy.NaN
788 VMtrx[numpy.where(VMtrx> 9.6)] = numpy.NaN
789 # Diameter is related to the fall speed of falling drops
789 # Diameter is related to the fall speed of falling drops
790 D_Vz = -1.667 * numpy.log( 0.9369 - 0.097087 * VMtrx ) # D in [mm]
790 D_Vz = -1.667 * numpy.log( 0.9369 - 0.097087 * VMtrx ) # D in [mm]
791 # Only valid for D>= 0.16 mm
791 # Only valid for D>= 0.16 mm
792 D_Vz[numpy.where(D_Vz < 0.16)] = numpy.NaN
792 D_Vz[numpy.where(D_Vz < 0.16)] = numpy.NaN
793
793
794 #Calculate Radar Reflectivity ETAn
794 #Calculate Radar Reflectivity ETAn
795 ETAn = (RadarConstant *ExpConstant) * Pr * rMtrx**2 #Reflectivity (ETA)
795 ETAn = (RadarConstant *ExpConstant) * Pr * rMtrx**2 #Reflectivity (ETA)
796 ETAd = ETAn * 6.18 * exp( -0.6 * D_Vz ) * delv_z
796 ETAd = ETAn * 6.18 * exp( -0.6 * D_Vz ) * delv_z
797 # Radar Cross Section
797 # Radar Cross Section
798 sigmaD = Km2 * (D_Vz * 1e-3 )**6 * numpy.pi**5 / Lambda**4
798 sigmaD = Km2 * (D_Vz * 1e-3 )**6 * numpy.pi**5 / Lambda**4
799 # Drop Size Distribution
799 # Drop Size Distribution
800 DSD = ETAn / sigmaD
800 DSD = ETAn / sigmaD
801 # Equivalente Reflectivy
801 # Equivalente Reflectivy
802 Ze_eqn = numpy.nansum( DSD * D_Vz**6 ,axis=0)
802 Ze_eqn = numpy.nansum( DSD * D_Vz**6 ,axis=0)
803 Ze_org = numpy.nansum(ETAn * Lambda**4, axis=0) / (1e-18*numpy.pi**5 * Km2) # [mm^6 /m^3]
803 Ze_org = numpy.nansum(ETAn * Lambda**4, axis=0) / (1e-18*numpy.pi**5 * Km2) # [mm^6 /m^3]
804 # RainFall Rate
804 # RainFall Rate
805 RR = 0.0006*numpy.pi * numpy.nansum( D_Vz**3 * DSD * VelMtrx ,0) #mm/hr
805 RR = 0.0006*numpy.pi * numpy.nansum( D_Vz**3 * DSD * VelMtrx ,0) #mm/hr
806
806
807 # Censoring the data
807 # Censoring the data
808 # Removing data with SNRth < 0dB se debe considerar el SNR por canal
808 # Removing data with SNRth < 0dB se debe considerar el SNR por canal
809 SNRth = 10**(SNRdBlimit/10) #-30dB
809 SNRth = 10**(SNRdBlimit/10) #-30dB
810 novalid = numpy.where((dataOut.data_snr[0,:] <SNRth) | (dataOut.data_snr[1,:] <SNRth) | (dataOut.data_snr[2,:] <SNRth)) # AND condition. Maybe OR condition better
810 novalid = numpy.where((dataOut.data_snr[0,:] <SNRth) | (dataOut.data_snr[1,:] <SNRth) | (dataOut.data_snr[2,:] <SNRth)) # AND condition. Maybe OR condition better
811 W = numpy.nanmean(dataOut.data_dop,0)
811 W = numpy.nanmean(dataOut.data_dop,0)
812 W[novalid] = numpy.NaN
812 W[novalid] = numpy.NaN
813 Ze_org[novalid] = numpy.NaN
813 Ze_org[novalid] = numpy.NaN
814 RR[novalid] = numpy.NaN
814 RR[novalid] = numpy.NaN
815
815
816 dataOut.data_output = RR[8]
816 dataOut.data_output = RR[8]
817 dataOut.data_param = numpy.ones([3,self.Num_Hei])
817 dataOut.data_param = numpy.ones([3,self.Num_Hei])
818 dataOut.channelList = [0,1,2]
818 dataOut.channelList = [0,1,2]
819
819
820 dataOut.data_param[0]=10*numpy.log10(Ze_org)
820 dataOut.data_param[0]=10*numpy.log10(Ze_org)
821 dataOut.data_param[1]=-W
821 dataOut.data_param[1]=-W
822 dataOut.data_param[2]=RR
822 dataOut.data_param[2]=RR
823
823
824 # print ('Leaving PrecepitationProc ... ')
824 # print ('Leaving PrecepitationProc ... ')
825 return dataOut
825 return dataOut
826
826
827 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
827 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
828
828
829 NPW = dataOut.NPW
829 NPW = dataOut.NPW
830 COFA = dataOut.COFA
830 COFA = dataOut.COFA
831
831
832 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
832 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
833 RadarConst = dataOut.RadarConst
833 RadarConst = dataOut.RadarConst
834 #frequency = 34.85*10**9
834 #frequency = 34.85*10**9
835
835
836 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
836 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
837 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
837 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
838
838
839 ETA = numpy.sum(SNR,1)
839 ETA = numpy.sum(SNR,1)
840
840
841 ETA = numpy.where(ETA != 0. , ETA, numpy.NaN)
841 ETA = numpy.where(ETA != 0. , ETA, numpy.NaN)
842
842
843 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
843 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
844
844
845 for r in range(self.Num_Hei):
845 for r in range(self.Num_Hei):
846
846
847 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
847 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
848 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
848 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
849
849
850 return Ze
850 return Ze
851
851
852 # def GetRadarConstant(self):
852 # def GetRadarConstant(self):
853 #
853 #
854 # """
854 # """
855 # Constants:
855 # Constants:
856 #
856 #
857 # Pt: Transmission Power dB 5kW 5000
857 # Pt: Transmission Power dB 5kW 5000
858 # Gt: Transmission Gain dB 24.7 dB 295.1209
858 # Gt: Transmission Gain dB 24.7 dB 295.1209
859 # Gr: Reception Gain dB 18.5 dB 70.7945
859 # Gr: Reception Gain dB 18.5 dB 70.7945
860 # Lambda: Wavelenght m 0.6741 m 0.6741
860 # Lambda: Wavelenght m 0.6741 m 0.6741
861 # aL: Attenuation loses dB 4dB 2.5118
861 # aL: Attenuation loses dB 4dB 2.5118
862 # tauW: Width of transmission pulse s 4us 4e-6
862 # tauW: Width of transmission pulse s 4us 4e-6
863 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
863 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
864 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
864 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
865 #
865 #
866 # """
866 # """
867 #
867 #
868 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
868 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
869 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
869 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
870 # RadarConstant = Numerator / Denominator
870 # RadarConstant = Numerator / Denominator
871 #
871 #
872 # return RadarConstant
872 # return RadarConstant
873
873
874
874
875
875
876 class FullSpectralAnalysis(Operation):
876 class FullSpectralAnalysis(Operation):
877
877
878 """
878 """
879 Function that implements Full Spectral Analysis technique.
879 Function that implements Full Spectral Analysis technique.
880
880
881 Input:
881 Input:
882 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
882 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
883 self.dataOut.groupList : Pairlist of channels
883 self.dataOut.groupList : Pairlist of channels
884 self.dataOut.ChanDist : Physical distance between receivers
884 self.dataOut.ChanDist : Physical distance between receivers
885
885
886
886
887 Output:
887 Output:
888
888
889 self.dataOut.data_output : Zonal wind, Meridional wind, and Vertical wind
889 self.dataOut.data_output : Zonal wind, Meridional wind, and Vertical wind
890
890
891
891
892 Parameters affected: Winds, height range, SNR
892 Parameters affected: Winds, height range, SNR
893
893
894 """
894 """
895 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRdBlimit=-30,
895 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRdBlimit=-30,
896 minheight=None, maxheight=None, NegativeLimit=None, PositiveLimit=None):
896 minheight=None, maxheight=None, NegativeLimit=None, PositiveLimit=None):
897
897
898 spc = dataOut.data_pre[0].copy()
898 spc = dataOut.data_pre[0].copy()
899 cspc = dataOut.data_pre[1]
899 cspc = dataOut.data_pre[1]
900 nHeights = spc.shape[2]
900 nHeights = spc.shape[2]
901
901
902 # first_height = 0.75 #km (ref: data header 20170822)
902 # first_height = 0.75 #km (ref: data header 20170822)
903 # resolution_height = 0.075 #km
903 # resolution_height = 0.075 #km
904 '''
904 '''
905 finding height range. check this when radar parameters are changed!
905 finding height range. check this when radar parameters are changed!
906 '''
906 '''
907 if maxheight is not None:
907 if maxheight is not None:
908 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
908 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
909 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
909 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
910 else:
910 else:
911 range_max = nHeights
911 range_max = nHeights
912 if minheight is not None:
912 if minheight is not None:
913 # range_min = int((minheight - first_height) / resolution_height) # theoretical
913 # range_min = int((minheight - first_height) / resolution_height) # theoretical
914 range_min = int(13.26 * minheight - 5) # empirical, works better
914 range_min = int(13.26 * minheight - 5) # empirical, works better
915 if range_min < 0:
915 if range_min < 0:
916 range_min = 0
916 range_min = 0
917 else:
917 else:
918 range_min = 0
918 range_min = 0
919
919
920 pairsList = dataOut.groupList
920 pairsList = dataOut.groupList
921 if dataOut.ChanDist is not None :
921 if dataOut.ChanDist is not None :
922 ChanDist = dataOut.ChanDist
922 ChanDist = dataOut.ChanDist
923 else:
923 else:
924 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
924 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
925
925
926 # 4 variables: zonal, meridional, vertical, and average SNR
926 # 4 variables: zonal, meridional, vertical, and average SNR
927 data_param = numpy.zeros([4,nHeights]) * numpy.NaN
927 data_param = numpy.zeros([4,nHeights]) * numpy.NaN
928 velocityX = numpy.zeros([nHeights]) * numpy.NaN
928 velocityX = numpy.zeros([nHeights]) * numpy.NaN
929 velocityY = numpy.zeros([nHeights]) * numpy.NaN
929 velocityY = numpy.zeros([nHeights]) * numpy.NaN
930 velocityZ = numpy.zeros([nHeights]) * numpy.NaN
930 velocityZ = numpy.zeros([nHeights]) * numpy.NaN
931
931
932 dbSNR = 10*numpy.log10(numpy.average(dataOut.data_snr,0))
932 dbSNR = 10*numpy.log10(numpy.average(dataOut.data_snr,0))
933
933
934 '''***********************************************WIND ESTIMATION**************************************'''
934 '''***********************************************WIND ESTIMATION**************************************'''
935 for Height in range(nHeights):
935 for Height in range(nHeights):
936
936
937 if Height >= range_min and Height < range_max:
937 if Height >= range_min and Height < range_max:
938 # error_code will be useful in future analysis
938 # error_code will be useful in future analysis
939 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList,
939 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList,
940 ChanDist, Height, dataOut.noise, dataOut.spc_range, dbSNR[Height], SNRdBlimit, NegativeLimit, PositiveLimit,dataOut.frequency)
940 ChanDist, Height, dataOut.noise, dataOut.spc_range, dbSNR[Height], SNRdBlimit, NegativeLimit, PositiveLimit,dataOut.frequency)
941
941
942 if abs(Vzon) < 100. and abs(Vmer) < 100.:
942 if abs(Vzon) < 100. and abs(Vmer) < 100.:
943 velocityX[Height] = Vzon
943 velocityX[Height] = Vzon
944 velocityY[Height] = -Vmer
944 velocityY[Height] = -Vmer
945 velocityZ[Height] = Vver
945 velocityZ[Height] = Vver
946
946
947 # Censoring data with SNR threshold
947 # Censoring data with SNR threshold
948 dbSNR [dbSNR < SNRdBlimit] = numpy.NaN
948 dbSNR [dbSNR < SNRdBlimit] = numpy.NaN
949
949
950 data_param[0] = velocityX
950 data_param[0] = velocityX
951 data_param[1] = velocityY
951 data_param[1] = velocityY
952 data_param[2] = velocityZ
952 data_param[2] = velocityZ
953 data_param[3] = dbSNR
953 data_param[3] = dbSNR
954 dataOut.data_param = data_param
954 dataOut.data_param = data_param
955 return dataOut
955 return dataOut
956
956
957 def moving_average(self,x, N=2):
957 def moving_average(self,x, N=2):
958 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
958 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
959 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
959 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
960
960
961 def gaus(self,xSamples,Amp,Mu,Sigma):
961 def gaus(self,xSamples,Amp,Mu,Sigma):
962 return Amp * numpy.exp(-0.5*((xSamples - Mu)/Sigma)**2)
962 return Amp * numpy.exp(-0.5*((xSamples - Mu)/Sigma)**2)
963
963
964 def Moments(self, ySamples, xSamples):
964 def Moments(self, ySamples, xSamples):
965 Power = numpy.nanmean(ySamples) # Power, 0th Moment
965 Power = numpy.nanmean(ySamples) # Power, 0th Moment
966 yNorm = ySamples / numpy.nansum(ySamples)
966 yNorm = ySamples / numpy.nansum(ySamples)
967 RadVel = numpy.nansum(xSamples * yNorm) # Radial Velocity, 1st Moment
967 RadVel = numpy.nansum(xSamples * yNorm) # Radial Velocity, 1st Moment
968 Sigma2 = numpy.nansum(yNorm * (xSamples - RadVel)**2) # Spectral Width, 2nd Moment
968 Sigma2 = numpy.nansum(yNorm * (xSamples - RadVel)**2) # Spectral Width, 2nd Moment
969 StdDev = numpy.sqrt(numpy.abs(Sigma2)) # Desv. Estandar, Ancho espectral
969 StdDev = numpy.sqrt(numpy.abs(Sigma2)) # Desv. Estandar, Ancho espectral
970 return numpy.array([Power,RadVel,StdDev])
970 return numpy.array([Power,RadVel,StdDev])
971
971
972 def StopWindEstimation(self, error_code):
972 def StopWindEstimation(self, error_code):
973 Vzon = numpy.NaN
973 Vzon = numpy.NaN
974 Vmer = numpy.NaN
974 Vmer = numpy.NaN
975 Vver = numpy.NaN
975 Vver = numpy.NaN
976 return Vzon, Vmer, Vver, error_code
976 return Vzon, Vmer, Vver, error_code
977
977
978 def AntiAliasing(self, interval, maxstep):
978 def AntiAliasing(self, interval, maxstep):
979 """
979 """
980 function to prevent errors from aliased values when computing phaseslope
980 function to prevent errors from aliased values when computing phaseslope
981 """
981 """
982 antialiased = numpy.zeros(len(interval))
982 antialiased = numpy.zeros(len(interval))
983 copyinterval = interval.copy()
983 copyinterval = interval.copy()
984
984
985 antialiased[0] = copyinterval[0]
985 antialiased[0] = copyinterval[0]
986
986
987 for i in range(1,len(antialiased)):
987 for i in range(1,len(antialiased)):
988 step = interval[i] - interval[i-1]
988 step = interval[i] - interval[i-1]
989 if step > maxstep:
989 if step > maxstep:
990 copyinterval -= 2*numpy.pi
990 copyinterval -= 2*numpy.pi
991 antialiased[i] = copyinterval[i]
991 antialiased[i] = copyinterval[i]
992 elif step < maxstep*(-1):
992 elif step < maxstep*(-1):
993 copyinterval += 2*numpy.pi
993 copyinterval += 2*numpy.pi
994 antialiased[i] = copyinterval[i]
994 antialiased[i] = copyinterval[i]
995 else:
995 else:
996 antialiased[i] = copyinterval[i].copy()
996 antialiased[i] = copyinterval[i].copy()
997
997
998 return antialiased
998 return antialiased
999
999
1000 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit, NegativeLimit, PositiveLimit, radfreq):
1000 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit, NegativeLimit, PositiveLimit, radfreq):
1001 """
1001 """
1002 Function that Calculates Zonal, Meridional and Vertical wind velocities.
1002 Function that Calculates Zonal, Meridional and Vertical wind velocities.
1003 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
1003 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
1004
1004
1005 Input:
1005 Input:
1006 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1006 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1007 pairsList : Pairlist of channels
1007 pairsList : Pairlist of channels
1008 ChanDist : array of xi_ij and eta_ij
1008 ChanDist : array of xi_ij and eta_ij
1009 Height : height at which data is processed
1009 Height : height at which data is processed
1010 noise : noise in [channels] format for specific height
1010 noise : noise in [channels] format for specific height
1011 Abbsisarange : range of the frequencies or velocities
1011 Abbsisarange : range of the frequencies or velocities
1012 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1012 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1013
1013
1014 Output:
1014 Output:
1015 Vzon, Vmer, Vver : wind velocities
1015 Vzon, Vmer, Vver : wind velocities
1016 error_code : int that states where code is terminated
1016 error_code : int that states where code is terminated
1017
1017
1018 0 : no error detected
1018 0 : no error detected
1019 1 : Gaussian of mean spc exceeds widthlimit
1019 1 : Gaussian of mean spc exceeds widthlimit
1020 2 : no Gaussian of mean spc found
1020 2 : no Gaussian of mean spc found
1021 3 : SNR to low or velocity to high -> prec. e.g.
1021 3 : SNR to low or velocity to high -> prec. e.g.
1022 4 : at least one Gaussian of cspc exceeds widthlimit
1022 4 : at least one Gaussian of cspc exceeds widthlimit
1023 5 : zero out of three cspc Gaussian fits converged
1023 5 : zero out of three cspc Gaussian fits converged
1024 6 : phase slope fit could not be found
1024 6 : phase slope fit could not be found
1025 7 : arrays used to fit phase have different length
1025 7 : arrays used to fit phase have different length
1026 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1026 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1027
1027
1028 """
1028 """
1029
1029
1030 error_code = 0
1030 error_code = 0
1031
1031
1032 nChan = spc.shape[0]
1032 nChan = spc.shape[0]
1033 nProf = spc.shape[1]
1033 nProf = spc.shape[1]
1034 nPair = cspc.shape[0]
1034 nPair = cspc.shape[0]
1035
1035
1036 SPC_Samples = numpy.zeros([nChan, nProf]) # for normalized spc values for one height
1036 SPC_Samples = numpy.zeros([nChan, nProf]) # for normalized spc values for one height
1037 CSPC_Samples = numpy.zeros([nPair, nProf], dtype=numpy.complex_) # for normalized cspc values
1037 CSPC_Samples = numpy.zeros([nPair, nProf], dtype=numpy.complex_) # for normalized cspc values
1038 phase = numpy.zeros([nPair, nProf]) # phase between channels
1038 phase = numpy.zeros([nPair, nProf]) # phase between channels
1039 PhaseSlope = numpy.zeros(nPair) # slope of the phases, channelwise
1039 PhaseSlope = numpy.zeros(nPair) # slope of the phases, channelwise
1040 PhaseInter = numpy.zeros(nPair) # intercept to the slope of the phases, channelwise
1040 PhaseInter = numpy.zeros(nPair) # intercept to the slope of the phases, channelwise
1041 xFrec = AbbsisaRange[0][:-1] # frequency range
1041 xFrec = AbbsisaRange[0][:-1] # frequency range
1042 xVel = AbbsisaRange[2][:-1] # velocity range
1042 xVel = AbbsisaRange[2][:-1] # velocity range
1043 xSamples = xFrec # the frequency range is taken
1043 xSamples = xFrec # the frequency range is taken
1044 delta_x = xSamples[1] - xSamples[0] # delta_f or delta_x
1044 delta_x = xSamples[1] - xSamples[0] # delta_f or delta_x
1045
1045
1046 # only consider velocities with in NegativeLimit and PositiveLimit
1046 # only consider velocities with in NegativeLimit and PositiveLimit
1047 if (NegativeLimit is None):
1047 if (NegativeLimit is None):
1048 NegativeLimit = numpy.min(xVel)
1048 NegativeLimit = numpy.min(xVel)
1049 if (PositiveLimit is None):
1049 if (PositiveLimit is None):
1050 PositiveLimit = numpy.max(xVel)
1050 PositiveLimit = numpy.max(xVel)
1051 xvalid = numpy.where((xVel > NegativeLimit) & (xVel < PositiveLimit))
1051 xvalid = numpy.where((xVel > NegativeLimit) & (xVel < PositiveLimit))
1052 xSamples_zoom = xSamples[xvalid]
1052 xSamples_zoom = xSamples[xvalid]
1053
1053
1054 '''Getting Eij and Nij'''
1054 '''Getting Eij and Nij'''
1055 Xi01, Xi02, Xi12 = ChanDist[:,0]
1055 Xi01, Xi02, Xi12 = ChanDist[:,0]
1056 Eta01, Eta02, Eta12 = ChanDist[:,1]
1056 Eta01, Eta02, Eta12 = ChanDist[:,1]
1057
1057
1058 # spwd limit - updated by D. ScipiΓ³n 30.03.2021
1058 # spwd limit - updated by D. ScipiΓ³n 30.03.2021
1059 widthlimit = 10
1059 widthlimit = 10
1060 '''************************* SPC is normalized ********************************'''
1060 '''************************* SPC is normalized ********************************'''
1061 spc_norm = spc.copy()
1061 spc_norm = spc.copy()
1062 # For each channel
1062 # For each channel
1063 for i in range(nChan):
1063 for i in range(nChan):
1064 spc_sub = spc_norm[i,:] - noise[i] # only the signal power
1064 spc_sub = spc_norm[i,:] - noise[i] # only the signal power
1065 SPC_Samples[i] = spc_sub / (numpy.nansum(spc_sub) * delta_x)
1065 SPC_Samples[i] = spc_sub / (numpy.nansum(spc_sub) * delta_x)
1066
1066
1067 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1067 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1068
1068
1069 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1069 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1070 you only fit the curve and don't need the absolute value of height for calculation,
1070 you only fit the curve and don't need the absolute value of height for calculation,
1071 only for estimation of width. for normalization of cross spectra, you need initial,
1071 only for estimation of width. for normalization of cross spectra, you need initial,
1072 unnormalized self-spectra With noise.
1072 unnormalized self-spectra With noise.
1073
1073
1074 Technically, you don't even need to normalize the self-spectra, as you only need the
1074 Technically, you don't even need to normalize the self-spectra, as you only need the
1075 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1075 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1076 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1076 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1077 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1077 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1078 """
1078 """
1079 # initial conditions
1079 # initial conditions
1080 popt = [1e-10,0,1e-10]
1080 popt = [1e-10,0,1e-10]
1081 # Spectra average
1081 # Spectra average
1082 SPCMean = numpy.average(SPC_Samples,0)
1082 SPCMean = numpy.average(SPC_Samples,0)
1083 # Moments in frequency
1083 # Moments in frequency
1084 SPCMoments = self.Moments(SPCMean[xvalid], xSamples_zoom)
1084 SPCMoments = self.Moments(SPCMean[xvalid], xSamples_zoom)
1085
1085
1086 # Gauss Fit SPC in frequency domain
1086 # Gauss Fit SPC in frequency domain
1087 if dbSNR > SNRlimit: # only if SNR > SNRth
1087 if dbSNR > SNRlimit: # only if SNR > SNRth
1088 try:
1088 try:
1089 popt,pcov = curve_fit(self.gaus,xSamples_zoom,SPCMean[xvalid],p0=SPCMoments)
1089 popt,pcov = curve_fit(self.gaus,xSamples_zoom,SPCMean[xvalid],p0=SPCMoments)
1090 if popt[2] <= 0 or popt[2] > widthlimit: # CONDITION
1090 if popt[2] <= 0 or popt[2] > widthlimit: # CONDITION
1091 return self.StopWindEstimation(error_code = 1)
1091 return self.StopWindEstimation(error_code = 1)
1092 FitGauss = self.gaus(xSamples_zoom,*popt)
1092 FitGauss = self.gaus(xSamples_zoom,*popt)
1093 except :#RuntimeError:
1093 except :#RuntimeError:
1094 return self.StopWindEstimation(error_code = 2)
1094 return self.StopWindEstimation(error_code = 2)
1095 else:
1095 else:
1096 return self.StopWindEstimation(error_code = 3)
1096 return self.StopWindEstimation(error_code = 3)
1097
1097
1098 '''***************************** CSPC Normalization *************************
1098 '''***************************** CSPC Normalization *************************
1099 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1099 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1100 influence the norm which is not desired. First, a range is identified where the
1100 influence the norm which is not desired. First, a range is identified where the
1101 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1101 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1102 around it gets cut off and values replaced by mean determined by the boundary
1102 around it gets cut off and values replaced by mean determined by the boundary
1103 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1103 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1104
1104
1105 The sums are then added and multiplied by range/datapoints, because you need
1105 The sums are then added and multiplied by range/datapoints, because you need
1106 an integral and not a sum for normalization.
1106 an integral and not a sum for normalization.
1107
1107
1108 A norm is found according to Briggs 92.
1108 A norm is found according to Briggs 92.
1109 '''
1109 '''
1110 # for each pair
1110 # for each pair
1111 for i in range(nPair):
1111 for i in range(nPair):
1112 cspc_norm = cspc[i,:].copy()
1112 cspc_norm = cspc[i,:].copy()
1113 chan_index0 = pairsList[i][0]
1113 chan_index0 = pairsList[i][0]
1114 chan_index1 = pairsList[i][1]
1114 chan_index1 = pairsList[i][1]
1115 CSPC_Samples[i] = cspc_norm / (numpy.sqrt(numpy.nansum(spc_norm[chan_index0])*numpy.nansum(spc_norm[chan_index1])) * delta_x)
1115 CSPC_Samples[i] = cspc_norm / (numpy.sqrt(numpy.nansum(spc_norm[chan_index0])*numpy.nansum(spc_norm[chan_index1])) * delta_x)
1116 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1116 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1117
1117
1118 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0,xvalid]), xSamples_zoom),
1118 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0,xvalid]), xSamples_zoom),
1119 self.Moments(numpy.abs(CSPC_Samples[1,xvalid]), xSamples_zoom),
1119 self.Moments(numpy.abs(CSPC_Samples[1,xvalid]), xSamples_zoom),
1120 self.Moments(numpy.abs(CSPC_Samples[2,xvalid]), xSamples_zoom)])
1120 self.Moments(numpy.abs(CSPC_Samples[2,xvalid]), xSamples_zoom)])
1121
1121
1122 popt01, popt02, popt12 = [1e-10,0,1e-10], [1e-10,0,1e-10] ,[1e-10,0,1e-10]
1122 popt01, popt02, popt12 = [1e-10,0,1e-10], [1e-10,0,1e-10] ,[1e-10,0,1e-10]
1123 FitGauss01, FitGauss02, FitGauss12 = numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples))
1123 FitGauss01, FitGauss02, FitGauss12 = numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples))
1124
1124
1125 '''*******************************FIT GAUSS CSPC************************************'''
1125 '''*******************************FIT GAUSS CSPC************************************'''
1126 try:
1126 try:
1127 popt01,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[0][xvalid]),p0=CSPCmoments[0])
1127 popt01,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[0][xvalid]),p0=CSPCmoments[0])
1128 if popt01[2] > widthlimit: # CONDITION
1128 if popt01[2] > widthlimit: # CONDITION
1129 return self.StopWindEstimation(error_code = 4)
1129 return self.StopWindEstimation(error_code = 4)
1130 popt02,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[1][xvalid]),p0=CSPCmoments[1])
1130 popt02,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[1][xvalid]),p0=CSPCmoments[1])
1131 if popt02[2] > widthlimit: # CONDITION
1131 if popt02[2] > widthlimit: # CONDITION
1132 return self.StopWindEstimation(error_code = 4)
1132 return self.StopWindEstimation(error_code = 4)
1133 popt12,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[2][xvalid]),p0=CSPCmoments[2])
1133 popt12,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[2][xvalid]),p0=CSPCmoments[2])
1134 if popt12[2] > widthlimit: # CONDITION
1134 if popt12[2] > widthlimit: # CONDITION
1135 return self.StopWindEstimation(error_code = 4)
1135 return self.StopWindEstimation(error_code = 4)
1136
1136
1137 FitGauss01 = self.gaus(xSamples_zoom, *popt01)
1137 FitGauss01 = self.gaus(xSamples_zoom, *popt01)
1138 FitGauss02 = self.gaus(xSamples_zoom, *popt02)
1138 FitGauss02 = self.gaus(xSamples_zoom, *popt02)
1139 FitGauss12 = self.gaus(xSamples_zoom, *popt12)
1139 FitGauss12 = self.gaus(xSamples_zoom, *popt12)
1140 except:
1140 except:
1141 return self.StopWindEstimation(error_code = 5)
1141 return self.StopWindEstimation(error_code = 5)
1142
1142
1143
1143
1144 '''************* Getting Fij ***************'''
1144 '''************* Getting Fij ***************'''
1145 # x-axis point of the gaussian where the center is located from GaussFit of spectra
1145 # x-axis point of the gaussian where the center is located from GaussFit of spectra
1146 GaussCenter = popt[1]
1146 GaussCenter = popt[1]
1147 ClosestCenter = xSamples_zoom[numpy.abs(xSamples_zoom-GaussCenter).argmin()]
1147 ClosestCenter = xSamples_zoom[numpy.abs(xSamples_zoom-GaussCenter).argmin()]
1148 PointGauCenter = numpy.where(xSamples_zoom==ClosestCenter)[0][0]
1148 PointGauCenter = numpy.where(xSamples_zoom==ClosestCenter)[0][0]
1149
1149
1150 # Point where e^-1 is located in the gaussian
1150 # Point where e^-1 is located in the gaussian
1151 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1151 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1152 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # The closest point to"Peminus1" in "FitGauss"
1152 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # The closest point to"Peminus1" in "FitGauss"
1153 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1153 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1154 Fij = numpy.abs(xSamples_zoom[PointFij] - xSamples_zoom[PointGauCenter])
1154 Fij = numpy.abs(xSamples_zoom[PointFij] - xSamples_zoom[PointGauCenter])
1155
1155
1156 '''********** Taking frequency ranges from mean SPCs **********'''
1156 '''********** Taking frequency ranges from mean SPCs **********'''
1157 GauWidth = popt[2] * 3/2 # Bandwidth of Gau01
1157 GauWidth = popt[2] * 3/2 # Bandwidth of Gau01
1158 Range = numpy.empty(2)
1158 Range = numpy.empty(2)
1159 Range[0] = GaussCenter - GauWidth
1159 Range[0] = GaussCenter - GauWidth
1160 Range[1] = GaussCenter + GauWidth
1160 Range[1] = GaussCenter + GauWidth
1161 # Point in x-axis where the bandwidth is located (min:max)
1161 # Point in x-axis where the bandwidth is located (min:max)
1162 ClosRangeMin = xSamples_zoom[numpy.abs(xSamples_zoom-Range[0]).argmin()]
1162 ClosRangeMin = xSamples_zoom[numpy.abs(xSamples_zoom-Range[0]).argmin()]
1163 ClosRangeMax = xSamples_zoom[numpy.abs(xSamples_zoom-Range[1]).argmin()]
1163 ClosRangeMax = xSamples_zoom[numpy.abs(xSamples_zoom-Range[1]).argmin()]
1164 PointRangeMin = numpy.where(xSamples_zoom==ClosRangeMin)[0][0]
1164 PointRangeMin = numpy.where(xSamples_zoom==ClosRangeMin)[0][0]
1165 PointRangeMax = numpy.where(xSamples_zoom==ClosRangeMax)[0][0]
1165 PointRangeMax = numpy.where(xSamples_zoom==ClosRangeMax)[0][0]
1166 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1166 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1167 FrecRange = xSamples_zoom[ Range[0] : Range[1] ]
1167 FrecRange = xSamples_zoom[ Range[0] : Range[1] ]
1168
1168
1169 '''************************** Getting Phase Slope ***************************'''
1169 '''************************** Getting Phase Slope ***************************'''
1170 for i in range(nPair):
1170 for i in range(nPair):
1171 if len(FrecRange) > 5:
1171 if len(FrecRange) > 5:
1172 PhaseRange = phase[i, xvalid[0][Range[0]:Range[1]]].copy()
1172 PhaseRange = phase[i, xvalid[0][Range[0]:Range[1]]].copy()
1173 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1173 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1174 if len(FrecRange) == len(PhaseRange):
1174 if len(FrecRange) == len(PhaseRange):
1175 try:
1175 try:
1176 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1176 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1177 PhaseSlope[i] = slope
1177 PhaseSlope[i] = slope
1178 PhaseInter[i] = intercept
1178 PhaseInter[i] = intercept
1179 except:
1179 except:
1180 return self.StopWindEstimation(error_code = 6)
1180 return self.StopWindEstimation(error_code = 6)
1181 else:
1181 else:
1182 return self.StopWindEstimation(error_code = 7)
1182 return self.StopWindEstimation(error_code = 7)
1183 else:
1183 else:
1184 return self.StopWindEstimation(error_code = 8)
1184 return self.StopWindEstimation(error_code = 8)
1185
1185
1186 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1186 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1187
1187
1188 '''Getting constant C'''
1188 '''Getting constant C'''
1189 cC=(Fij*numpy.pi)**2
1189 cC=(Fij*numpy.pi)**2
1190
1190
1191 '''****** Getting constants F and G ******'''
1191 '''****** Getting constants F and G ******'''
1192 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1192 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1193 # MijEijNij = numpy.array([[Xi01,Eta01], [Xi02,Eta02], [Xi12,Eta12]])
1193 # MijEijNij = numpy.array([[Xi01,Eta01], [Xi02,Eta02], [Xi12,Eta12]])
1194 # MijResult0 = (-PhaseSlope[0] * cC) / (2*numpy.pi)
1194 # MijResult0 = (-PhaseSlope[0] * cC) / (2*numpy.pi)
1195 MijResult1 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1195 MijResult1 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1196 MijResult2 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1196 MijResult2 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1197 # MijResults = numpy.array([MijResult0, MijResult1, MijResult2])
1197 # MijResults = numpy.array([MijResult0, MijResult1, MijResult2])
1198 MijResults = numpy.array([MijResult1, MijResult2])
1198 MijResults = numpy.array([MijResult1, MijResult2])
1199 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1199 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1200
1200
1201 '''****** Getting constants A, B and H ******'''
1201 '''****** Getting constants A, B and H ******'''
1202 W01 = numpy.nanmax( FitGauss01 )
1202 W01 = numpy.nanmax( FitGauss01 )
1203 W02 = numpy.nanmax( FitGauss02 )
1203 W02 = numpy.nanmax( FitGauss02 )
1204 W12 = numpy.nanmax( FitGauss12 )
1204 W12 = numpy.nanmax( FitGauss12 )
1205
1205
1206 WijResult01 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1206 WijResult01 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1207 WijResult02 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1207 WijResult02 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1208 WijResult12 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1208 WijResult12 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1209 WijResults = numpy.array([WijResult01, WijResult02, WijResult12])
1209 WijResults = numpy.array([WijResult01, WijResult02, WijResult12])
1210
1210
1211 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1211 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1212 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1212 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1213
1213
1214 VxVy = numpy.array([[cA,cH],[cH,cB]])
1214 VxVy = numpy.array([[cA,cH],[cH,cB]])
1215 VxVyResults = numpy.array([-cF,-cG])
1215 VxVyResults = numpy.array([-cF,-cG])
1216 (Vmer,Vzon) = numpy.linalg.solve(VxVy, VxVyResults)
1216 (Vmer,Vzon) = numpy.linalg.solve(VxVy, VxVyResults)
1217 Vver = -SPCMoments[1]*SPEED_OF_LIGHT/(2*radfreq)
1217 Vver = -SPCMoments[1]*SPEED_OF_LIGHT/(2*radfreq)
1218 error_code = 0
1218 error_code = 0
1219
1219
1220 return Vzon, Vmer, Vver, error_code
1220 return Vzon, Vmer, Vver, error_code
1221
1221
1222 class SpectralMoments(Operation):
1222 class SpectralMoments(Operation):
1223
1223
1224 '''
1224 '''
1225 Function SpectralMoments()
1225 Function SpectralMoments()
1226
1226
1227 Calculates moments (power, mean, standard deviation) and SNR of the signal
1227 Calculates moments (power, mean, standard deviation) and SNR of the signal
1228
1228
1229 Type of dataIn: Spectra
1229 Type of dataIn: Spectra
1230
1230
1231 Configuration Parameters:
1231 Configuration Parameters:
1232
1232
1233 dirCosx : Cosine director in X axis
1233 dirCosx : Cosine director in X axis
1234 dirCosy : Cosine director in Y axis
1234 dirCosy : Cosine director in Y axis
1235
1235
1236 elevation :
1236 elevation :
1237 azimuth :
1237 azimuth :
1238
1238
1239 Input:
1239 Input:
1240 channelList : simple channel list to select e.g. [2,3,7]
1240 channelList : simple channel list to select e.g. [2,3,7]
1241 self.dataOut.data_pre : Spectral data
1241 self.dataOut.data_pre : Spectral data
1242 self.dataOut.abscissaList : List of frequencies
1242 self.dataOut.abscissaList : List of frequencies
1243 self.dataOut.noise : Noise level per channel
1243 self.dataOut.noise : Noise level per channel
1244
1244
1245 Affected:
1245 Affected:
1246 self.dataOut.moments : Parameters per channel
1246 self.dataOut.moments : Parameters per channel
1247 self.dataOut.data_snr : SNR per channel
1247 self.dataOut.data_snr : SNR per channel
1248
1248
1249 '''
1249 '''
1250
1250
1251 def run(self, dataOut):
1251 def run(self, dataOut):
1252
1252
1253 data = dataOut.data_pre[0]
1253 data = dataOut.data_pre[0]
1254 absc = dataOut.abscissaList[:-1]
1254 absc = dataOut.abscissaList[:-1]
1255 noise = dataOut.noise
1255 noise = dataOut.noise
1256 nChannel = data.shape[0]
1256 nChannel = data.shape[0]
1257 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1257 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1258
1258
1259 for ind in range(nChannel):
1259 for ind in range(nChannel):
1260 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1260 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1261
1261
1262 dataOut.moments = data_param[:,1:,:]
1262 dataOut.moments = data_param[:,1:,:]
1263 dataOut.data_snr = data_param[:,0]
1263 dataOut.data_snr = data_param[:,0]
1264 dataOut.data_pow = data_param[:,1]
1264 dataOut.data_pow = data_param[:,1]
1265 dataOut.data_dop = data_param[:,2]
1265 dataOut.data_dop = data_param[:,2]
1266 dataOut.data_width = data_param[:,3]
1266 dataOut.data_width = data_param[:,3]
1267 return dataOut
1267 return dataOut
1268
1268
1269 def __calculateMoments(self, oldspec, oldfreq, n0,
1269 def __calculateMoments(self, oldspec, oldfreq, n0,
1270 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1270 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1271
1271
1272 if (nicoh is None): nicoh = 1
1272 if (nicoh is None): nicoh = 1
1273 if (graph is None): graph = 0
1273 if (graph is None): graph = 0
1274 if (smooth is None): smooth = 0
1274 if (smooth is None): smooth = 0
1275 elif (self.smooth < 3): smooth = 0
1275 elif (self.smooth < 3): smooth = 0
1276
1276
1277 if (type1 is None): type1 = 0
1277 if (type1 is None): type1 = 0
1278 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1278 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1279 if (snrth is None): snrth = -3
1279 if (snrth is None): snrth = -3
1280 if (dc is None): dc = 0
1280 if (dc is None): dc = 0
1281 if (aliasing is None): aliasing = 0
1281 if (aliasing is None): aliasing = 0
1282 if (oldfd is None): oldfd = 0
1282 if (oldfd is None): oldfd = 0
1283 if (wwauto is None): wwauto = 0
1283 if (wwauto is None): wwauto = 0
1284
1284
1285 if (n0 < 1.e-20): n0 = 1.e-20
1285 if (n0 < 1.e-20): n0 = 1.e-20
1286
1286
1287 freq = oldfreq
1287 freq = oldfreq
1288 vec_power = numpy.zeros(oldspec.shape[1])
1288 vec_power = numpy.zeros(oldspec.shape[1])
1289 vec_fd = numpy.zeros(oldspec.shape[1])
1289 vec_fd = numpy.zeros(oldspec.shape[1])
1290 vec_w = numpy.zeros(oldspec.shape[1])
1290 vec_w = numpy.zeros(oldspec.shape[1])
1291 vec_snr = numpy.zeros(oldspec.shape[1])
1291 vec_snr = numpy.zeros(oldspec.shape[1])
1292
1292
1293 # oldspec = numpy.ma.masked_invalid(oldspec)
1293 # oldspec = numpy.ma.masked_invalid(oldspec)
1294 for ind in range(oldspec.shape[1]):
1294 for ind in range(oldspec.shape[1]):
1295
1295
1296 spec = oldspec[:,ind]
1296 spec = oldspec[:,ind]
1297 aux = spec*fwindow
1297 aux = spec*fwindow
1298 max_spec = aux.max()
1298 max_spec = aux.max()
1299 m = aux.tolist().index(max_spec)
1299 m = aux.tolist().index(max_spec)
1300
1300
1301 # Smooth
1301 # Smooth
1302 if (smooth == 0):
1302 if (smooth == 0):
1303 spec2 = spec
1303 spec2 = spec
1304 else:
1304 else:
1305 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1305 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1306
1306
1307 # Moments Estimation
1307 # Moments Estimation
1308 bb = spec2[numpy.arange(m,spec2.size)]
1308 bb = spec2[numpy.arange(m,spec2.size)]
1309 bb = (bb<n0).nonzero()
1309 bb = (bb<n0).nonzero()
1310 bb = bb[0]
1310 bb = bb[0]
1311
1311
1312 ss = spec2[numpy.arange(0,m + 1)]
1312 ss = spec2[numpy.arange(0,m + 1)]
1313 ss = (ss<n0).nonzero()
1313 ss = (ss<n0).nonzero()
1314 ss = ss[0]
1314 ss = ss[0]
1315
1315
1316 if (bb.size == 0):
1316 if (bb.size == 0):
1317 bb0 = spec.size - 1 - m
1317 bb0 = spec.size - 1 - m
1318 else:
1318 else:
1319 bb0 = bb[0] - 1
1319 bb0 = bb[0] - 1
1320 if (bb0 < 0):
1320 if (bb0 < 0):
1321 bb0 = 0
1321 bb0 = 0
1322
1322
1323 if (ss.size == 0):
1323 if (ss.size == 0):
1324 ss1 = 1
1324 ss1 = 1
1325 else:
1325 else:
1326 ss1 = max(ss) + 1
1326 ss1 = max(ss) + 1
1327
1327
1328 if (ss1 > m):
1328 if (ss1 > m):
1329 ss1 = m
1329 ss1 = m
1330
1330
1331 #valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1331 #valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1332 valid = numpy.arange(1,oldspec.shape[0])# valid perfil completo igual pulsepair
1332 valid = numpy.arange(1,oldspec.shape[0])# valid perfil completo igual pulsepair
1333 signal_power = ((spec2[valid] - n0) * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1333 signal_power = ((spec2[valid] - n0) * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1334 total_power = (spec2[valid] * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1334 total_power = (spec2[valid] * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1335 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1335 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1336 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1336 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1337 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1337 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1338 snr = (spec2.mean()-n0)/n0
1338 snr = (spec2.mean()-n0)/n0
1339 if (snr < 1.e-20) :
1339 if (snr < 1.e-20) :
1340 snr = 1.e-20
1340 snr = 1.e-20
1341
1341
1342 # vec_power[ind] = power #D. ScipiΓ³n replaced with the line below
1342 # vec_power[ind] = power #D. ScipiΓ³n replaced with the line below
1343 vec_power[ind] = total_power
1343 vec_power[ind] = total_power
1344 vec_fd[ind] = fd
1344 vec_fd[ind] = fd
1345 vec_w[ind] = w
1345 vec_w[ind] = w
1346 vec_snr[ind] = snr
1346 vec_snr[ind] = snr
1347
1347
1348 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1348 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1349
1349
1350 #------------------ Get SA Parameters --------------------------
1350 #------------------ Get SA Parameters --------------------------
1351
1351
1352 def GetSAParameters(self):
1352 def GetSAParameters(self):
1353 #SA en frecuencia
1353 #SA en frecuencia
1354 pairslist = self.dataOut.groupList
1354 pairslist = self.dataOut.groupList
1355 num_pairs = len(pairslist)
1355 num_pairs = len(pairslist)
1356
1356
1357 vel = self.dataOut.abscissaList
1357 vel = self.dataOut.abscissaList
1358 spectra = self.dataOut.data_pre
1358 spectra = self.dataOut.data_pre
1359 cspectra = self.dataIn.data_cspc
1359 cspectra = self.dataIn.data_cspc
1360 delta_v = vel[1] - vel[0]
1360 delta_v = vel[1] - vel[0]
1361
1361
1362 #Calculating the power spectrum
1362 #Calculating the power spectrum
1363 spc_pow = numpy.sum(spectra, 3)*delta_v
1363 spc_pow = numpy.sum(spectra, 3)*delta_v
1364 #Normalizing Spectra
1364 #Normalizing Spectra
1365 norm_spectra = spectra/spc_pow
1365 norm_spectra = spectra/spc_pow
1366 #Calculating the norm_spectra at peak
1366 #Calculating the norm_spectra at peak
1367 max_spectra = numpy.max(norm_spectra, 3)
1367 max_spectra = numpy.max(norm_spectra, 3)
1368
1368
1369 #Normalizing Cross Spectra
1369 #Normalizing Cross Spectra
1370 norm_cspectra = numpy.zeros(cspectra.shape)
1370 norm_cspectra = numpy.zeros(cspectra.shape)
1371
1371
1372 for i in range(num_chan):
1372 for i in range(num_chan):
1373 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1373 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1374
1374
1375 max_cspectra = numpy.max(norm_cspectra,2)
1375 max_cspectra = numpy.max(norm_cspectra,2)
1376 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1376 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1377
1377
1378 for i in range(num_pairs):
1378 for i in range(num_pairs):
1379 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1379 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1380 #------------------- Get Lags ----------------------------------
1380 #------------------- Get Lags ----------------------------------
1381
1381
1382 class SALags(Operation):
1382 class SALags(Operation):
1383 '''
1383 '''
1384 Function GetMoments()
1384 Function GetMoments()
1385
1385
1386 Input:
1386 Input:
1387 self.dataOut.data_pre
1387 self.dataOut.data_pre
1388 self.dataOut.abscissaList
1388 self.dataOut.abscissaList
1389 self.dataOut.noise
1389 self.dataOut.noise
1390 self.dataOut.normFactor
1390 self.dataOut.normFactor
1391 self.dataOut.data_snr
1391 self.dataOut.data_snr
1392 self.dataOut.groupList
1392 self.dataOut.groupList
1393 self.dataOut.nChannels
1393 self.dataOut.nChannels
1394
1394
1395 Affected:
1395 Affected:
1396 self.dataOut.data_param
1396 self.dataOut.data_param
1397
1397
1398 '''
1398 '''
1399 def run(self, dataOut):
1399 def run(self, dataOut):
1400 data_acf = dataOut.data_pre[0]
1400 data_acf = dataOut.data_pre[0]
1401 data_ccf = dataOut.data_pre[1]
1401 data_ccf = dataOut.data_pre[1]
1402 normFactor_acf = dataOut.normFactor[0]
1402 normFactor_acf = dataOut.normFactor[0]
1403 normFactor_ccf = dataOut.normFactor[1]
1403 normFactor_ccf = dataOut.normFactor[1]
1404 pairs_acf = dataOut.groupList[0]
1404 pairs_acf = dataOut.groupList[0]
1405 pairs_ccf = dataOut.groupList[1]
1405 pairs_ccf = dataOut.groupList[1]
1406
1406
1407 nHeights = dataOut.nHeights
1407 nHeights = dataOut.nHeights
1408 absc = dataOut.abscissaList
1408 absc = dataOut.abscissaList
1409 noise = dataOut.noise
1409 noise = dataOut.noise
1410 SNR = dataOut.data_snr
1410 SNR = dataOut.data_snr
1411 nChannels = dataOut.nChannels
1411 nChannels = dataOut.nChannels
1412 # pairsList = dataOut.groupList
1412 # pairsList = dataOut.groupList
1413 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1413 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1414
1414
1415 for l in range(len(pairs_acf)):
1415 for l in range(len(pairs_acf)):
1416 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1416 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1417
1417
1418 for l in range(len(pairs_ccf)):
1418 for l in range(len(pairs_ccf)):
1419 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1419 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1420
1420
1421 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1421 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1422 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1422 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1423 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1423 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1424 return
1424 return
1425
1425
1426 # def __getPairsAutoCorr(self, pairsList, nChannels):
1426 # def __getPairsAutoCorr(self, pairsList, nChannels):
1427 #
1427 #
1428 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1428 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1429 #
1429 #
1430 # for l in range(len(pairsList)):
1430 # for l in range(len(pairsList)):
1431 # firstChannel = pairsList[l][0]
1431 # firstChannel = pairsList[l][0]
1432 # secondChannel = pairsList[l][1]
1432 # secondChannel = pairsList[l][1]
1433 #
1433 #
1434 # #Obteniendo pares de Autocorrelacion
1434 # #Obteniendo pares de Autocorrelacion
1435 # if firstChannel == secondChannel:
1435 # if firstChannel == secondChannel:
1436 # pairsAutoCorr[firstChannel] = int(l)
1436 # pairsAutoCorr[firstChannel] = int(l)
1437 #
1437 #
1438 # pairsAutoCorr = pairsAutoCorr.astype(int)
1438 # pairsAutoCorr = pairsAutoCorr.astype(int)
1439 #
1439 #
1440 # pairsCrossCorr = range(len(pairsList))
1440 # pairsCrossCorr = range(len(pairsList))
1441 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1441 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1442 #
1442 #
1443 # return pairsAutoCorr, pairsCrossCorr
1443 # return pairsAutoCorr, pairsCrossCorr
1444
1444
1445 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1445 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1446
1446
1447 lag0 = data_acf.shape[1]/2
1447 lag0 = data_acf.shape[1]/2
1448 #Funcion de Autocorrelacion
1448 #Funcion de Autocorrelacion
1449 mean_acf = stats.nanmean(data_acf, axis = 0)
1449 mean_acf = stats.nanmean(data_acf, axis = 0)
1450
1450
1451 #Obtencion Indice de TauCross
1451 #Obtencion Indice de TauCross
1452 ind_ccf = data_ccf.argmax(axis = 1)
1452 ind_ccf = data_ccf.argmax(axis = 1)
1453 #Obtencion Indice de TauAuto
1453 #Obtencion Indice de TauAuto
1454 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1454 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1455 ccf_lag0 = data_ccf[:,lag0,:]
1455 ccf_lag0 = data_ccf[:,lag0,:]
1456
1456
1457 for i in range(ccf_lag0.shape[0]):
1457 for i in range(ccf_lag0.shape[0]):
1458 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1458 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1459
1459
1460 #Obtencion de TauCross y TauAuto
1460 #Obtencion de TauCross y TauAuto
1461 tau_ccf = lagRange[ind_ccf]
1461 tau_ccf = lagRange[ind_ccf]
1462 tau_acf = lagRange[ind_acf]
1462 tau_acf = lagRange[ind_acf]
1463
1463
1464 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1464 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1465
1465
1466 tau_ccf[Nan1,Nan2] = numpy.nan
1466 tau_ccf[Nan1,Nan2] = numpy.nan
1467 tau_acf[Nan1,Nan2] = numpy.nan
1467 tau_acf[Nan1,Nan2] = numpy.nan
1468 tau = numpy.vstack((tau_ccf,tau_acf))
1468 tau = numpy.vstack((tau_ccf,tau_acf))
1469
1469
1470 return tau
1470 return tau
1471
1471
1472 def __calculateLag1Phase(self, data, lagTRange):
1472 def __calculateLag1Phase(self, data, lagTRange):
1473 data1 = stats.nanmean(data, axis = 0)
1473 data1 = stats.nanmean(data, axis = 0)
1474 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1474 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1475
1475
1476 phase = numpy.angle(data1[lag1,:])
1476 phase = numpy.angle(data1[lag1,:])
1477
1477
1478 return phase
1478 return phase
1479
1479
1480 class SpectralFitting(Operation):
1480 class SpectralFitting(Operation):
1481 '''
1481 '''
1482 Function GetMoments()
1482 Function GetMoments()
1483
1483
1484 Input:
1484 Input:
1485 Output:
1485 Output:
1486 Variables modified:
1486 Variables modified:
1487 '''
1487 '''
1488
1488
1489 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1489 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1490
1490
1491
1491
1492 if path != None:
1492 if path != None:
1493 sys.path.append(path)
1493 sys.path.append(path)
1494 self.dataOut.library = importlib.import_module(file)
1494 self.dataOut.library = importlib.import_module(file)
1495
1495
1496 #To be inserted as a parameter
1496 #To be inserted as a parameter
1497 groupArray = numpy.array(groupList)
1497 groupArray = numpy.array(groupList)
1498 # groupArray = numpy.array([[0,1],[2,3]])
1498 # groupArray = numpy.array([[0,1],[2,3]])
1499 self.dataOut.groupList = groupArray
1499 self.dataOut.groupList = groupArray
1500
1500
1501 nGroups = groupArray.shape[0]
1501 nGroups = groupArray.shape[0]
1502 nChannels = self.dataIn.nChannels
1502 nChannels = self.dataIn.nChannels
1503 nHeights=self.dataIn.heightList.size
1503 nHeights=self.dataIn.heightList.size
1504
1504
1505 #Parameters Array
1505 #Parameters Array
1506 self.dataOut.data_param = None
1506 self.dataOut.data_param = None
1507
1507
1508 #Set constants
1508 #Set constants
1509 constants = self.dataOut.library.setConstants(self.dataIn)
1509 constants = self.dataOut.library.setConstants(self.dataIn)
1510 self.dataOut.constants = constants
1510 self.dataOut.constants = constants
1511 M = self.dataIn.normFactor
1511 M = self.dataIn.normFactor
1512 N = self.dataIn.nFFTPoints
1512 N = self.dataIn.nFFTPoints
1513 ippSeconds = self.dataIn.ippSeconds
1513 ippSeconds = self.dataIn.ippSeconds
1514 K = self.dataIn.nIncohInt
1514 K = self.dataIn.nIncohInt
1515 pairsArray = numpy.array(self.dataIn.pairsList)
1515 pairsArray = numpy.array(self.dataIn.pairsList)
1516
1516
1517 #List of possible combinations
1517 #List of possible combinations
1518 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1518 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1519 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1519 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1520
1520
1521 if getSNR:
1521 if getSNR:
1522 listChannels = groupArray.reshape((groupArray.size))
1522 listChannels = groupArray.reshape((groupArray.size))
1523 listChannels.sort()
1523 listChannels.sort()
1524 noise = self.dataIn.getNoise()
1524 noise = self.dataIn.getNoise()
1525 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1525 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1526
1526
1527 for i in range(nGroups):
1527 for i in range(nGroups):
1528 coord = groupArray[i,:]
1528 coord = groupArray[i,:]
1529
1529
1530 #Input data array
1530 #Input data array
1531 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1531 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1532 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1532 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1533
1533
1534 #Cross Spectra data array for Covariance Matrixes
1534 #Cross Spectra data array for Covariance Matrixes
1535 ind = 0
1535 ind = 0
1536 for pairs in listComb:
1536 for pairs in listComb:
1537 pairsSel = numpy.array([coord[x],coord[y]])
1537 pairsSel = numpy.array([coord[x],coord[y]])
1538 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1538 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1539 ind += 1
1539 ind += 1
1540 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1540 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1541 dataCross = dataCross**2/K
1541 dataCross = dataCross**2/K
1542
1542
1543 for h in range(nHeights):
1543 for h in range(nHeights):
1544
1544
1545 #Input
1545 #Input
1546 d = data[:,h]
1546 d = data[:,h]
1547
1547
1548 #Covariance Matrix
1548 #Covariance Matrix
1549 D = numpy.diag(d**2/K)
1549 D = numpy.diag(d**2/K)
1550 ind = 0
1550 ind = 0
1551 for pairs in listComb:
1551 for pairs in listComb:
1552 #Coordinates in Covariance Matrix
1552 #Coordinates in Covariance Matrix
1553 x = pairs[0]
1553 x = pairs[0]
1554 y = pairs[1]
1554 y = pairs[1]
1555 #Channel Index
1555 #Channel Index
1556 S12 = dataCross[ind,:,h]
1556 S12 = dataCross[ind,:,h]
1557 D12 = numpy.diag(S12)
1557 D12 = numpy.diag(S12)
1558 #Completing Covariance Matrix with Cross Spectras
1558 #Completing Covariance Matrix with Cross Spectras
1559 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1559 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1560 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1560 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1561 ind += 1
1561 ind += 1
1562 Dinv=numpy.linalg.inv(D)
1562 Dinv=numpy.linalg.inv(D)
1563 L=numpy.linalg.cholesky(Dinv)
1563 L=numpy.linalg.cholesky(Dinv)
1564 LT=L.T
1564 LT=L.T
1565
1565
1566 dp = numpy.dot(LT,d)
1566 dp = numpy.dot(LT,d)
1567
1567
1568 #Initial values
1568 #Initial values
1569 data_spc = self.dataIn.data_spc[coord,:,h]
1569 data_spc = self.dataIn.data_spc[coord,:,h]
1570
1570
1571 if (h>0)and(error1[3]<5):
1571 if (h>0)and(error1[3]<5):
1572 p0 = self.dataOut.data_param[i,:,h-1]
1572 p0 = self.dataOut.data_param[i,:,h-1]
1573 else:
1573 else:
1574 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1574 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1575
1575
1576 try:
1576 try:
1577 #Least Squares
1577 #Least Squares
1578 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1578 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1579 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1579 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1580 #Chi square error
1580 #Chi square error
1581 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1581 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1582 #Error with Jacobian
1582 #Error with Jacobian
1583 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1583 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1584 except:
1584 except:
1585 minp = p0*numpy.nan
1585 minp = p0*numpy.nan
1586 error0 = numpy.nan
1586 error0 = numpy.nan
1587 error1 = p0*numpy.nan
1587 error1 = p0*numpy.nan
1588
1588
1589 #Save
1589 #Save
1590 if self.dataOut.data_param is None:
1590 if self.dataOut.data_param is None:
1591 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1591 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1592 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1592 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1593
1593
1594 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1594 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1595 self.dataOut.data_param[i,:,h] = minp
1595 self.dataOut.data_param[i,:,h] = minp
1596 return
1596 return
1597
1597
1598 def __residFunction(self, p, dp, LT, constants):
1598 def __residFunction(self, p, dp, LT, constants):
1599
1599
1600 fm = self.dataOut.library.modelFunction(p, constants)
1600 fm = self.dataOut.library.modelFunction(p, constants)
1601 fmp=numpy.dot(LT,fm)
1601 fmp=numpy.dot(LT,fm)
1602
1602
1603 return dp-fmp
1603 return dp-fmp
1604
1604
1605 def __getSNR(self, z, noise):
1605 def __getSNR(self, z, noise):
1606
1606
1607 avg = numpy.average(z, axis=1)
1607 avg = numpy.average(z, axis=1)
1608 SNR = (avg.T-noise)/noise
1608 SNR = (avg.T-noise)/noise
1609 SNR = SNR.T
1609 SNR = SNR.T
1610 return SNR
1610 return SNR
1611
1611
1612 def __chisq(p,chindex,hindex):
1612 def __chisq(p,chindex,hindex):
1613 #similar to Resid but calculates CHI**2
1613 #similar to Resid but calculates CHI**2
1614 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1614 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1615 dp=numpy.dot(LT,d)
1615 dp=numpy.dot(LT,d)
1616 fmp=numpy.dot(LT,fm)
1616 fmp=numpy.dot(LT,fm)
1617 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1617 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1618 return chisq
1618 return chisq
1619
1619
1620 class WindProfiler(Operation):
1620 class WindProfiler(Operation):
1621
1621
1622 __isConfig = False
1622 __isConfig = False
1623
1623
1624 __initime = None
1624 __initime = None
1625 __lastdatatime = None
1625 __lastdatatime = None
1626 __integrationtime = None
1626 __integrationtime = None
1627
1627
1628 __buffer = None
1628 __buffer = None
1629
1629
1630 __dataReady = False
1630 __dataReady = False
1631
1631
1632 __firstdata = None
1632 __firstdata = None
1633
1633
1634 n = None
1634 n = None
1635
1635
1636 def __init__(self):
1636 def __init__(self):
1637 Operation.__init__(self)
1637 Operation.__init__(self)
1638
1638
1639 def __calculateCosDir(self, elev, azim):
1639 def __calculateCosDir(self, elev, azim):
1640 zen = (90 - elev)*numpy.pi/180
1640 zen = (90 - elev)*numpy.pi/180
1641 azim = azim*numpy.pi/180
1641 azim = azim*numpy.pi/180
1642 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1642 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1643 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1643 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1644
1644
1645 signX = numpy.sign(numpy.cos(azim))
1645 signX = numpy.sign(numpy.cos(azim))
1646 signY = numpy.sign(numpy.sin(azim))
1646 signY = numpy.sign(numpy.sin(azim))
1647
1647
1648 cosDirX = numpy.copysign(cosDirX, signX)
1648 cosDirX = numpy.copysign(cosDirX, signX)
1649 cosDirY = numpy.copysign(cosDirY, signY)
1649 cosDirY = numpy.copysign(cosDirY, signY)
1650 return cosDirX, cosDirY
1650 return cosDirX, cosDirY
1651
1651
1652 def __calculateAngles(self, theta_x, theta_y, azimuth):
1652 def __calculateAngles(self, theta_x, theta_y, azimuth):
1653
1653
1654 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1654 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1655 zenith_arr = numpy.arccos(dir_cosw)
1655 zenith_arr = numpy.arccos(dir_cosw)
1656 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1656 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1657
1657
1658 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1658 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1659 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1659 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1660
1660
1661 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1661 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1662
1662
1663 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1663 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1664
1664
1665 #
1665 #
1666 if horOnly:
1666 if horOnly:
1667 A = numpy.c_[dir_cosu,dir_cosv]
1667 A = numpy.c_[dir_cosu,dir_cosv]
1668 else:
1668 else:
1669 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1669 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1670 A = numpy.asmatrix(A)
1670 A = numpy.asmatrix(A)
1671 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1671 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1672
1672
1673 return A1
1673 return A1
1674
1674
1675 def __correctValues(self, heiRang, phi, velRadial, SNR):
1675 def __correctValues(self, heiRang, phi, velRadial, SNR):
1676 listPhi = phi.tolist()
1676 listPhi = phi.tolist()
1677 maxid = listPhi.index(max(listPhi))
1677 maxid = listPhi.index(max(listPhi))
1678 minid = listPhi.index(min(listPhi))
1678 minid = listPhi.index(min(listPhi))
1679
1679
1680 rango = list(range(len(phi)))
1680 rango = list(range(len(phi)))
1681 # rango = numpy.delete(rango,maxid)
1681 # rango = numpy.delete(rango,maxid)
1682
1682
1683 heiRang1 = heiRang*math.cos(phi[maxid])
1683 heiRang1 = heiRang*math.cos(phi[maxid])
1684 heiRangAux = heiRang*math.cos(phi[minid])
1684 heiRangAux = heiRang*math.cos(phi[minid])
1685 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1685 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1686 heiRang1 = numpy.delete(heiRang1,indOut)
1686 heiRang1 = numpy.delete(heiRang1,indOut)
1687
1687
1688 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1688 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1689 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1689 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1690
1690
1691 for i in rango:
1691 for i in rango:
1692 x = heiRang*math.cos(phi[i])
1692 x = heiRang*math.cos(phi[i])
1693 y1 = velRadial[i,:]
1693 y1 = velRadial[i,:]
1694 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1694 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1695
1695
1696 x1 = heiRang1
1696 x1 = heiRang1
1697 y11 = f1(x1)
1697 y11 = f1(x1)
1698
1698
1699 y2 = SNR[i,:]
1699 y2 = SNR[i,:]
1700 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1700 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1701 y21 = f2(x1)
1701 y21 = f2(x1)
1702
1702
1703 velRadial1[i,:] = y11
1703 velRadial1[i,:] = y11
1704 SNR1[i,:] = y21
1704 SNR1[i,:] = y21
1705
1705
1706 return heiRang1, velRadial1, SNR1
1706 return heiRang1, velRadial1, SNR1
1707
1707
1708 def __calculateVelUVW(self, A, velRadial):
1708 def __calculateVelUVW(self, A, velRadial):
1709
1709
1710 #Operacion Matricial
1710 #Operacion Matricial
1711 # velUVW = numpy.zeros((velRadial.shape[1],3))
1711 # velUVW = numpy.zeros((velRadial.shape[1],3))
1712 # for ind in range(velRadial.shape[1]):
1712 # for ind in range(velRadial.shape[1]):
1713 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1713 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1714 # velUVW = velUVW.transpose()
1714 # velUVW = velUVW.transpose()
1715 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1715 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1716 velUVW[:,:] = numpy.dot(A,velRadial)
1716 velUVW[:,:] = numpy.dot(A,velRadial)
1717
1717
1718
1718
1719 return velUVW
1719 return velUVW
1720
1720
1721 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1721 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1722
1722
1723 def techniqueDBS(self, kwargs):
1723 def techniqueDBS(self, kwargs):
1724 """
1724 """
1725 Function that implements Doppler Beam Swinging (DBS) technique.
1725 Function that implements Doppler Beam Swinging (DBS) technique.
1726
1726
1727 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1727 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1728 Direction correction (if necessary), Ranges and SNR
1728 Direction correction (if necessary), Ranges and SNR
1729
1729
1730 Output: Winds estimation (Zonal, Meridional and Vertical)
1730 Output: Winds estimation (Zonal, Meridional and Vertical)
1731
1731
1732 Parameters affected: Winds, height range, SNR
1732 Parameters affected: Winds, height range, SNR
1733 """
1733 """
1734 velRadial0 = kwargs['velRadial']
1734 velRadial0 = kwargs['velRadial']
1735 heiRang = kwargs['heightList']
1735 heiRang = kwargs['heightList']
1736 SNR0 = kwargs['SNR']
1736 SNR0 = kwargs['SNR']
1737
1737
1738 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1738 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1739 theta_x = numpy.array(kwargs['dirCosx'])
1739 theta_x = numpy.array(kwargs['dirCosx'])
1740 theta_y = numpy.array(kwargs['dirCosy'])
1740 theta_y = numpy.array(kwargs['dirCosy'])
1741 else:
1741 else:
1742 elev = numpy.array(kwargs['elevation'])
1742 elev = numpy.array(kwargs['elevation'])
1743 azim = numpy.array(kwargs['azimuth'])
1743 azim = numpy.array(kwargs['azimuth'])
1744 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1744 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1745 azimuth = kwargs['correctAzimuth']
1745 azimuth = kwargs['correctAzimuth']
1746 if 'horizontalOnly' in kwargs:
1746 if 'horizontalOnly' in kwargs:
1747 horizontalOnly = kwargs['horizontalOnly']
1747 horizontalOnly = kwargs['horizontalOnly']
1748 else: horizontalOnly = False
1748 else: horizontalOnly = False
1749 if 'correctFactor' in kwargs:
1749 if 'correctFactor' in kwargs:
1750 correctFactor = kwargs['correctFactor']
1750 correctFactor = kwargs['correctFactor']
1751 else: correctFactor = 1
1751 else: correctFactor = 1
1752 if 'channelList' in kwargs:
1752 if 'channelList' in kwargs:
1753 channelList = kwargs['channelList']
1753 channelList = kwargs['channelList']
1754 if len(channelList) == 2:
1754 if len(channelList) == 2:
1755 horizontalOnly = True
1755 horizontalOnly = True
1756 arrayChannel = numpy.array(channelList)
1756 arrayChannel = numpy.array(channelList)
1757 param = param[arrayChannel,:,:]
1757 param = param[arrayChannel,:,:]
1758 theta_x = theta_x[arrayChannel]
1758 theta_x = theta_x[arrayChannel]
1759 theta_y = theta_y[arrayChannel]
1759 theta_y = theta_y[arrayChannel]
1760
1760
1761 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1761 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1762 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1762 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1763 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1763 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1764
1764
1765 #Calculo de Componentes de la velocidad con DBS
1765 #Calculo de Componentes de la velocidad con DBS
1766 winds = self.__calculateVelUVW(A,velRadial1)
1766 winds = self.__calculateVelUVW(A,velRadial1)
1767
1767
1768 return winds, heiRang1, SNR1
1768 return winds, heiRang1, SNR1
1769
1769
1770 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1770 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1771
1771
1772 nPairs = len(pairs_ccf)
1772 nPairs = len(pairs_ccf)
1773 posx = numpy.asarray(posx)
1773 posx = numpy.asarray(posx)
1774 posy = numpy.asarray(posy)
1774 posy = numpy.asarray(posy)
1775
1775
1776 #Rotacion Inversa para alinear con el azimuth
1776 #Rotacion Inversa para alinear con el azimuth
1777 if azimuth!= None:
1777 if azimuth!= None:
1778 azimuth = azimuth*math.pi/180
1778 azimuth = azimuth*math.pi/180
1779 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1779 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1780 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1780 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1781 else:
1781 else:
1782 posx1 = posx
1782 posx1 = posx
1783 posy1 = posy
1783 posy1 = posy
1784
1784
1785 #Calculo de Distancias
1785 #Calculo de Distancias
1786 distx = numpy.zeros(nPairs)
1786 distx = numpy.zeros(nPairs)
1787 disty = numpy.zeros(nPairs)
1787 disty = numpy.zeros(nPairs)
1788 dist = numpy.zeros(nPairs)
1788 dist = numpy.zeros(nPairs)
1789 ang = numpy.zeros(nPairs)
1789 ang = numpy.zeros(nPairs)
1790
1790
1791 for i in range(nPairs):
1791 for i in range(nPairs):
1792 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1792 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1793 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1793 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1794 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1794 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1795 ang[i] = numpy.arctan2(disty[i],distx[i])
1795 ang[i] = numpy.arctan2(disty[i],distx[i])
1796
1796
1797 return distx, disty, dist, ang
1797 return distx, disty, dist, ang
1798 #Calculo de Matrices
1798 #Calculo de Matrices
1799 # nPairs = len(pairs)
1799 # nPairs = len(pairs)
1800 # ang1 = numpy.zeros((nPairs, 2, 1))
1800 # ang1 = numpy.zeros((nPairs, 2, 1))
1801 # dist1 = numpy.zeros((nPairs, 2, 1))
1801 # dist1 = numpy.zeros((nPairs, 2, 1))
1802 #
1802 #
1803 # for j in range(nPairs):
1803 # for j in range(nPairs):
1804 # dist1[j,0,0] = dist[pairs[j][0]]
1804 # dist1[j,0,0] = dist[pairs[j][0]]
1805 # dist1[j,1,0] = dist[pairs[j][1]]
1805 # dist1[j,1,0] = dist[pairs[j][1]]
1806 # ang1[j,0,0] = ang[pairs[j][0]]
1806 # ang1[j,0,0] = ang[pairs[j][0]]
1807 # ang1[j,1,0] = ang[pairs[j][1]]
1807 # ang1[j,1,0] = ang[pairs[j][1]]
1808 #
1808 #
1809 # return distx,disty, dist1,ang1
1809 # return distx,disty, dist1,ang1
1810
1810
1811
1811
1812 def __calculateVelVer(self, phase, lagTRange, _lambda):
1812 def __calculateVelVer(self, phase, lagTRange, _lambda):
1813
1813
1814 Ts = lagTRange[1] - lagTRange[0]
1814 Ts = lagTRange[1] - lagTRange[0]
1815 velW = -_lambda*phase/(4*math.pi*Ts)
1815 velW = -_lambda*phase/(4*math.pi*Ts)
1816
1816
1817 return velW
1817 return velW
1818
1818
1819 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1819 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1820 nPairs = tau1.shape[0]
1820 nPairs = tau1.shape[0]
1821 nHeights = tau1.shape[1]
1821 nHeights = tau1.shape[1]
1822 vel = numpy.zeros((nPairs,3,nHeights))
1822 vel = numpy.zeros((nPairs,3,nHeights))
1823 dist1 = numpy.reshape(dist, (dist.size,1))
1823 dist1 = numpy.reshape(dist, (dist.size,1))
1824
1824
1825 angCos = numpy.cos(ang)
1825 angCos = numpy.cos(ang)
1826 angSin = numpy.sin(ang)
1826 angSin = numpy.sin(ang)
1827
1827
1828 vel0 = dist1*tau1/(2*tau2**2)
1828 vel0 = dist1*tau1/(2*tau2**2)
1829 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1829 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1830 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1830 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1831
1831
1832 ind = numpy.where(numpy.isinf(vel))
1832 ind = numpy.where(numpy.isinf(vel))
1833 vel[ind] = numpy.nan
1833 vel[ind] = numpy.nan
1834
1834
1835 return vel
1835 return vel
1836
1836
1837 # def __getPairsAutoCorr(self, pairsList, nChannels):
1837 # def __getPairsAutoCorr(self, pairsList, nChannels):
1838 #
1838 #
1839 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1839 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1840 #
1840 #
1841 # for l in range(len(pairsList)):
1841 # for l in range(len(pairsList)):
1842 # firstChannel = pairsList[l][0]
1842 # firstChannel = pairsList[l][0]
1843 # secondChannel = pairsList[l][1]
1843 # secondChannel = pairsList[l][1]
1844 #
1844 #
1845 # #Obteniendo pares de Autocorrelacion
1845 # #Obteniendo pares de Autocorrelacion
1846 # if firstChannel == secondChannel:
1846 # if firstChannel == secondChannel:
1847 # pairsAutoCorr[firstChannel] = int(l)
1847 # pairsAutoCorr[firstChannel] = int(l)
1848 #
1848 #
1849 # pairsAutoCorr = pairsAutoCorr.astype(int)
1849 # pairsAutoCorr = pairsAutoCorr.astype(int)
1850 #
1850 #
1851 # pairsCrossCorr = range(len(pairsList))
1851 # pairsCrossCorr = range(len(pairsList))
1852 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1852 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1853 #
1853 #
1854 # return pairsAutoCorr, pairsCrossCorr
1854 # return pairsAutoCorr, pairsCrossCorr
1855
1855
1856 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1856 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1857 def techniqueSA(self, kwargs):
1857 def techniqueSA(self, kwargs):
1858
1858
1859 """
1859 """
1860 Function that implements Spaced Antenna (SA) technique.
1860 Function that implements Spaced Antenna (SA) technique.
1861
1861
1862 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1862 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1863 Direction correction (if necessary), Ranges and SNR
1863 Direction correction (if necessary), Ranges and SNR
1864
1864
1865 Output: Winds estimation (Zonal, Meridional and Vertical)
1865 Output: Winds estimation (Zonal, Meridional and Vertical)
1866
1866
1867 Parameters affected: Winds
1867 Parameters affected: Winds
1868 """
1868 """
1869 position_x = kwargs['positionX']
1869 position_x = kwargs['positionX']
1870 position_y = kwargs['positionY']
1870 position_y = kwargs['positionY']
1871 azimuth = kwargs['azimuth']
1871 azimuth = kwargs['azimuth']
1872
1872
1873 if 'correctFactor' in kwargs:
1873 if 'correctFactor' in kwargs:
1874 correctFactor = kwargs['correctFactor']
1874 correctFactor = kwargs['correctFactor']
1875 else:
1875 else:
1876 correctFactor = 1
1876 correctFactor = 1
1877
1877
1878 groupList = kwargs['groupList']
1878 groupList = kwargs['groupList']
1879 pairs_ccf = groupList[1]
1879 pairs_ccf = groupList[1]
1880 tau = kwargs['tau']
1880 tau = kwargs['tau']
1881 _lambda = kwargs['_lambda']
1881 _lambda = kwargs['_lambda']
1882
1882
1883 #Cross Correlation pairs obtained
1883 #Cross Correlation pairs obtained
1884 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1884 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1885 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1885 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1886 # pairsSelArray = numpy.array(pairsSelected)
1886 # pairsSelArray = numpy.array(pairsSelected)
1887 # pairs = []
1887 # pairs = []
1888 #
1888 #
1889 # #Wind estimation pairs obtained
1889 # #Wind estimation pairs obtained
1890 # for i in range(pairsSelArray.shape[0]/2):
1890 # for i in range(pairsSelArray.shape[0]/2):
1891 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1891 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1892 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1892 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1893 # pairs.append((ind1,ind2))
1893 # pairs.append((ind1,ind2))
1894
1894
1895 indtau = tau.shape[0]/2
1895 indtau = tau.shape[0]/2
1896 tau1 = tau[:indtau,:]
1896 tau1 = tau[:indtau,:]
1897 tau2 = tau[indtau:-1,:]
1897 tau2 = tau[indtau:-1,:]
1898 # tau1 = tau1[pairs,:]
1898 # tau1 = tau1[pairs,:]
1899 # tau2 = tau2[pairs,:]
1899 # tau2 = tau2[pairs,:]
1900 phase1 = tau[-1,:]
1900 phase1 = tau[-1,:]
1901
1901
1902 #---------------------------------------------------------------------
1902 #---------------------------------------------------------------------
1903 #Metodo Directo
1903 #Metodo Directo
1904 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1904 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1905 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1905 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1906 winds = stats.nanmean(winds, axis=0)
1906 winds = stats.nanmean(winds, axis=0)
1907 #---------------------------------------------------------------------
1907 #---------------------------------------------------------------------
1908 #Metodo General
1908 #Metodo General
1909 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1909 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1910 # #Calculo Coeficientes de Funcion de Correlacion
1910 # #Calculo Coeficientes de Funcion de Correlacion
1911 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1911 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1912 # #Calculo de Velocidades
1912 # #Calculo de Velocidades
1913 # winds = self.calculateVelUV(F,G,A,B,H)
1913 # winds = self.calculateVelUV(F,G,A,B,H)
1914
1914
1915 #---------------------------------------------------------------------
1915 #---------------------------------------------------------------------
1916 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1916 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1917 winds = correctFactor*winds
1917 winds = correctFactor*winds
1918 return winds
1918 return winds
1919
1919
1920 def __checkTime(self, currentTime, paramInterval, outputInterval):
1920 def __checkTime(self, currentTime, paramInterval, outputInterval):
1921
1921
1922 dataTime = currentTime + paramInterval
1922 dataTime = currentTime + paramInterval
1923 deltaTime = dataTime - self.__initime
1923 deltaTime = dataTime - self.__initime
1924
1924
1925 if deltaTime >= outputInterval or deltaTime < 0:
1925 if deltaTime >= outputInterval or deltaTime < 0:
1926 self.__dataReady = True
1926 self.__dataReady = True
1927 return
1927 return
1928
1928
1929 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1929 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1930 '''
1930 '''
1931 Function that implements winds estimation technique with detected meteors.
1931 Function that implements winds estimation technique with detected meteors.
1932
1932
1933 Input: Detected meteors, Minimum meteor quantity to wind estimation
1933 Input: Detected meteors, Minimum meteor quantity to wind estimation
1934
1934
1935 Output: Winds estimation (Zonal and Meridional)
1935 Output: Winds estimation (Zonal and Meridional)
1936
1936
1937 Parameters affected: Winds
1937 Parameters affected: Winds
1938 '''
1938 '''
1939 #Settings
1939 #Settings
1940 nInt = (heightMax - heightMin)/2
1940 nInt = (heightMax - heightMin)/2
1941 nInt = int(nInt)
1941 nInt = int(nInt)
1942 winds = numpy.zeros((2,nInt))*numpy.nan
1942 winds = numpy.zeros((2,nInt))*numpy.nan
1943
1943
1944 #Filter errors
1944 #Filter errors
1945 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1945 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1946 finalMeteor = arrayMeteor[error,:]
1946 finalMeteor = arrayMeteor[error,:]
1947
1947
1948 #Meteor Histogram
1948 #Meteor Histogram
1949 finalHeights = finalMeteor[:,2]
1949 finalHeights = finalMeteor[:,2]
1950 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1950 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1951 nMeteorsPerI = hist[0]
1951 nMeteorsPerI = hist[0]
1952 heightPerI = hist[1]
1952 heightPerI = hist[1]
1953
1953
1954 #Sort of meteors
1954 #Sort of meteors
1955 indSort = finalHeights.argsort()
1955 indSort = finalHeights.argsort()
1956 finalMeteor2 = finalMeteor[indSort,:]
1956 finalMeteor2 = finalMeteor[indSort,:]
1957
1957
1958 # Calculating winds
1958 # Calculating winds
1959 ind1 = 0
1959 ind1 = 0
1960 ind2 = 0
1960 ind2 = 0
1961
1961
1962 for i in range(nInt):
1962 for i in range(nInt):
1963 nMet = nMeteorsPerI[i]
1963 nMet = nMeteorsPerI[i]
1964 ind1 = ind2
1964 ind1 = ind2
1965 ind2 = ind1 + nMet
1965 ind2 = ind1 + nMet
1966
1966
1967 meteorAux = finalMeteor2[ind1:ind2,:]
1967 meteorAux = finalMeteor2[ind1:ind2,:]
1968
1968
1969 if meteorAux.shape[0] >= meteorThresh:
1969 if meteorAux.shape[0] >= meteorThresh:
1970 vel = meteorAux[:, 6]
1970 vel = meteorAux[:, 6]
1971 zen = meteorAux[:, 4]*numpy.pi/180
1971 zen = meteorAux[:, 4]*numpy.pi/180
1972 azim = meteorAux[:, 3]*numpy.pi/180
1972 azim = meteorAux[:, 3]*numpy.pi/180
1973
1973
1974 n = numpy.cos(zen)
1974 n = numpy.cos(zen)
1975 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1975 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1976 # l = m*numpy.tan(azim)
1976 # l = m*numpy.tan(azim)
1977 l = numpy.sin(zen)*numpy.sin(azim)
1977 l = numpy.sin(zen)*numpy.sin(azim)
1978 m = numpy.sin(zen)*numpy.cos(azim)
1978 m = numpy.sin(zen)*numpy.cos(azim)
1979
1979
1980 A = numpy.vstack((l, m)).transpose()
1980 A = numpy.vstack((l, m)).transpose()
1981 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1981 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1982 windsAux = numpy.dot(A1, vel)
1982 windsAux = numpy.dot(A1, vel)
1983
1983
1984 winds[0,i] = windsAux[0]
1984 winds[0,i] = windsAux[0]
1985 winds[1,i] = windsAux[1]
1985 winds[1,i] = windsAux[1]
1986
1986
1987 return winds, heightPerI[:-1]
1987 return winds, heightPerI[:-1]
1988
1988
1989 def techniqueNSM_SA(self, **kwargs):
1989 def techniqueNSM_SA(self, **kwargs):
1990 metArray = kwargs['metArray']
1990 metArray = kwargs['metArray']
1991 heightList = kwargs['heightList']
1991 heightList = kwargs['heightList']
1992 timeList = kwargs['timeList']
1992 timeList = kwargs['timeList']
1993
1993
1994 rx_location = kwargs['rx_location']
1994 rx_location = kwargs['rx_location']
1995 groupList = kwargs['groupList']
1995 groupList = kwargs['groupList']
1996 azimuth = kwargs['azimuth']
1996 azimuth = kwargs['azimuth']
1997 dfactor = kwargs['dfactor']
1997 dfactor = kwargs['dfactor']
1998 k = kwargs['k']
1998 k = kwargs['k']
1999
1999
2000 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2000 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2001 d = dist*dfactor
2001 d = dist*dfactor
2002 #Phase calculation
2002 #Phase calculation
2003 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2003 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2004
2004
2005 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2005 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2006
2006
2007 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2007 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2008 azimuth1 = azimuth1*numpy.pi/180
2008 azimuth1 = azimuth1*numpy.pi/180
2009
2009
2010 for i in range(heightList.size):
2010 for i in range(heightList.size):
2011 h = heightList[i]
2011 h = heightList[i]
2012 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2012 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2013 metHeight = metArray1[indH,:]
2013 metHeight = metArray1[indH,:]
2014 if metHeight.shape[0] >= 2:
2014 if metHeight.shape[0] >= 2:
2015 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2015 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2016 iazim = metHeight[:,1].astype(int)
2016 iazim = metHeight[:,1].astype(int)
2017 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2017 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2018 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2018 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2019 A = numpy.asmatrix(A)
2019 A = numpy.asmatrix(A)
2020 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2020 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2021 velHor = numpy.dot(A1,velAux)
2021 velHor = numpy.dot(A1,velAux)
2022
2022
2023 velEst[i,:] = numpy.squeeze(velHor)
2023 velEst[i,:] = numpy.squeeze(velHor)
2024 return velEst
2024 return velEst
2025
2025
2026 def __getPhaseSlope(self, metArray, heightList, timeList):
2026 def __getPhaseSlope(self, metArray, heightList, timeList):
2027 meteorList = []
2027 meteorList = []
2028 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2028 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2029 #Putting back together the meteor matrix
2029 #Putting back together the meteor matrix
2030 utctime = metArray[:,0]
2030 utctime = metArray[:,0]
2031 uniqueTime = numpy.unique(utctime)
2031 uniqueTime = numpy.unique(utctime)
2032
2032
2033 phaseDerThresh = 0.5
2033 phaseDerThresh = 0.5
2034 ippSeconds = timeList[1] - timeList[0]
2034 ippSeconds = timeList[1] - timeList[0]
2035 sec = numpy.where(timeList>1)[0][0]
2035 sec = numpy.where(timeList>1)[0][0]
2036 nPairs = metArray.shape[1] - 6
2036 nPairs = metArray.shape[1] - 6
2037 nHeights = len(heightList)
2037 nHeights = len(heightList)
2038
2038
2039 for t in uniqueTime:
2039 for t in uniqueTime:
2040 metArray1 = metArray[utctime==t,:]
2040 metArray1 = metArray[utctime==t,:]
2041 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2041 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2042 tmet = metArray1[:,1].astype(int)
2042 tmet = metArray1[:,1].astype(int)
2043 hmet = metArray1[:,2].astype(int)
2043 hmet = metArray1[:,2].astype(int)
2044
2044
2045 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2045 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2046 metPhase[:,:] = numpy.nan
2046 metPhase[:,:] = numpy.nan
2047 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2047 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2048
2048
2049 #Delete short trails
2049 #Delete short trails
2050 metBool = ~numpy.isnan(metPhase[0,:,:])
2050 metBool = ~numpy.isnan(metPhase[0,:,:])
2051 heightVect = numpy.sum(metBool, axis = 1)
2051 heightVect = numpy.sum(metBool, axis = 1)
2052 metBool[heightVect<sec,:] = False
2052 metBool[heightVect<sec,:] = False
2053 metPhase[:,heightVect<sec,:] = numpy.nan
2053 metPhase[:,heightVect<sec,:] = numpy.nan
2054
2054
2055 #Derivative
2055 #Derivative
2056 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2056 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2057 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2057 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2058 metPhase[phDerAux] = numpy.nan
2058 metPhase[phDerAux] = numpy.nan
2059
2059
2060 #--------------------------METEOR DETECTION -----------------------------------------
2060 #--------------------------METEOR DETECTION -----------------------------------------
2061 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2061 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2062
2062
2063 for p in numpy.arange(nPairs):
2063 for p in numpy.arange(nPairs):
2064 phase = metPhase[p,:,:]
2064 phase = metPhase[p,:,:]
2065 phDer = metDer[p,:,:]
2065 phDer = metDer[p,:,:]
2066
2066
2067 for h in indMet:
2067 for h in indMet:
2068 height = heightList[h]
2068 height = heightList[h]
2069 phase1 = phase[h,:] #82
2069 phase1 = phase[h,:] #82
2070 phDer1 = phDer[h,:]
2070 phDer1 = phDer[h,:]
2071
2071
2072 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2072 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2073
2073
2074 indValid = numpy.where(~numpy.isnan(phase1))[0]
2074 indValid = numpy.where(~numpy.isnan(phase1))[0]
2075 initMet = indValid[0]
2075 initMet = indValid[0]
2076 endMet = 0
2076 endMet = 0
2077
2077
2078 for i in range(len(indValid)-1):
2078 for i in range(len(indValid)-1):
2079
2079
2080 #Time difference
2080 #Time difference
2081 inow = indValid[i]
2081 inow = indValid[i]
2082 inext = indValid[i+1]
2082 inext = indValid[i+1]
2083 idiff = inext - inow
2083 idiff = inext - inow
2084 #Phase difference
2084 #Phase difference
2085 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2085 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2086
2086
2087 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2087 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2088 sizeTrail = inow - initMet + 1
2088 sizeTrail = inow - initMet + 1
2089 if sizeTrail>3*sec: #Too short meteors
2089 if sizeTrail>3*sec: #Too short meteors
2090 x = numpy.arange(initMet,inow+1)*ippSeconds
2090 x = numpy.arange(initMet,inow+1)*ippSeconds
2091 y = phase1[initMet:inow+1]
2091 y = phase1[initMet:inow+1]
2092 ynnan = ~numpy.isnan(y)
2092 ynnan = ~numpy.isnan(y)
2093 x = x[ynnan]
2093 x = x[ynnan]
2094 y = y[ynnan]
2094 y = y[ynnan]
2095 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2095 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2096 ylin = x*slope + intercept
2096 ylin = x*slope + intercept
2097 rsq = r_value**2
2097 rsq = r_value**2
2098 if rsq > 0.5:
2098 if rsq > 0.5:
2099 vel = slope#*height*1000/(k*d)
2099 vel = slope#*height*1000/(k*d)
2100 estAux = numpy.array([utctime,p,height, vel, rsq])
2100 estAux = numpy.array([utctime,p,height, vel, rsq])
2101 meteorList.append(estAux)
2101 meteorList.append(estAux)
2102 initMet = inext
2102 initMet = inext
2103 metArray2 = numpy.array(meteorList)
2103 metArray2 = numpy.array(meteorList)
2104
2104
2105 return metArray2
2105 return metArray2
2106
2106
2107 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2107 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2108
2108
2109 azimuth1 = numpy.zeros(len(pairslist))
2109 azimuth1 = numpy.zeros(len(pairslist))
2110 dist = numpy.zeros(len(pairslist))
2110 dist = numpy.zeros(len(pairslist))
2111
2111
2112 for i in range(len(rx_location)):
2112 for i in range(len(rx_location)):
2113 ch0 = pairslist[i][0]
2113 ch0 = pairslist[i][0]
2114 ch1 = pairslist[i][1]
2114 ch1 = pairslist[i][1]
2115
2115
2116 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2116 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2117 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2117 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2118 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2118 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2119 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2119 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2120
2120
2121 azimuth1 -= azimuth0
2121 azimuth1 -= azimuth0
2122 return azimuth1, dist
2122 return azimuth1, dist
2123
2123
2124 def techniqueNSM_DBS(self, **kwargs):
2124 def techniqueNSM_DBS(self, **kwargs):
2125 metArray = kwargs['metArray']
2125 metArray = kwargs['metArray']
2126 heightList = kwargs['heightList']
2126 heightList = kwargs['heightList']
2127 timeList = kwargs['timeList']
2127 timeList = kwargs['timeList']
2128 azimuth = kwargs['azimuth']
2128 azimuth = kwargs['azimuth']
2129 theta_x = numpy.array(kwargs['theta_x'])
2129 theta_x = numpy.array(kwargs['theta_x'])
2130 theta_y = numpy.array(kwargs['theta_y'])
2130 theta_y = numpy.array(kwargs['theta_y'])
2131
2131
2132 utctime = metArray[:,0]
2132 utctime = metArray[:,0]
2133 cmet = metArray[:,1].astype(int)
2133 cmet = metArray[:,1].astype(int)
2134 hmet = metArray[:,3].astype(int)
2134 hmet = metArray[:,3].astype(int)
2135 SNRmet = metArray[:,4]
2135 SNRmet = metArray[:,4]
2136 vmet = metArray[:,5]
2136 vmet = metArray[:,5]
2137 spcmet = metArray[:,6]
2137 spcmet = metArray[:,6]
2138
2138
2139 nChan = numpy.max(cmet) + 1
2139 nChan = numpy.max(cmet) + 1
2140 nHeights = len(heightList)
2140 nHeights = len(heightList)
2141
2141
2142 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2142 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2143 hmet = heightList[hmet]
2143 hmet = heightList[hmet]
2144 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2144 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2145
2145
2146 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2146 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2147
2147
2148 for i in range(nHeights - 1):
2148 for i in range(nHeights - 1):
2149 hmin = heightList[i]
2149 hmin = heightList[i]
2150 hmax = heightList[i + 1]
2150 hmax = heightList[i + 1]
2151
2151
2152 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2152 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2153 indthisH = numpy.where(thisH)
2153 indthisH = numpy.where(thisH)
2154
2154
2155 if numpy.size(indthisH) > 3:
2155 if numpy.size(indthisH) > 3:
2156
2156
2157 vel_aux = vmet[thisH]
2157 vel_aux = vmet[thisH]
2158 chan_aux = cmet[thisH]
2158 chan_aux = cmet[thisH]
2159 cosu_aux = dir_cosu[chan_aux]
2159 cosu_aux = dir_cosu[chan_aux]
2160 cosv_aux = dir_cosv[chan_aux]
2160 cosv_aux = dir_cosv[chan_aux]
2161 cosw_aux = dir_cosw[chan_aux]
2161 cosw_aux = dir_cosw[chan_aux]
2162
2162
2163 nch = numpy.size(numpy.unique(chan_aux))
2163 nch = numpy.size(numpy.unique(chan_aux))
2164 if nch > 1:
2164 if nch > 1:
2165 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2165 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2166 velEst[i,:] = numpy.dot(A,vel_aux)
2166 velEst[i,:] = numpy.dot(A,vel_aux)
2167
2167
2168 return velEst
2168 return velEst
2169
2169
2170 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2170 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2171
2171
2172 param = dataOut.data_param
2172 param = dataOut.data_param
2173 if dataOut.abscissaList != None:
2173 if dataOut.abscissaList != None:
2174 absc = dataOut.abscissaList[:-1]
2174 absc = dataOut.abscissaList[:-1]
2175 # noise = dataOut.noise
2175 # noise = dataOut.noise
2176 heightList = dataOut.heightList
2176 heightList = dataOut.heightList
2177 SNR = dataOut.data_snr
2177 SNR = dataOut.data_snr
2178
2178
2179 if technique == 'DBS':
2179 if technique == 'DBS':
2180
2180
2181 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2181 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2182 kwargs['heightList'] = heightList
2182 kwargs['heightList'] = heightList
2183 kwargs['SNR'] = SNR
2183 kwargs['SNR'] = SNR
2184
2184
2185 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2185 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2186 dataOut.utctimeInit = dataOut.utctime
2186 dataOut.utctimeInit = dataOut.utctime
2187 dataOut.outputInterval = dataOut.paramInterval
2187 dataOut.outputInterval = dataOut.paramInterval
2188
2188
2189 elif technique == 'SA':
2189 elif technique == 'SA':
2190
2190
2191 #Parameters
2191 #Parameters
2192 # position_x = kwargs['positionX']
2192 # position_x = kwargs['positionX']
2193 # position_y = kwargs['positionY']
2193 # position_y = kwargs['positionY']
2194 # azimuth = kwargs['azimuth']
2194 # azimuth = kwargs['azimuth']
2195 #
2195 #
2196 # if kwargs.has_key('crosspairsList'):
2196 # if kwargs.has_key('crosspairsList'):
2197 # pairs = kwargs['crosspairsList']
2197 # pairs = kwargs['crosspairsList']
2198 # else:
2198 # else:
2199 # pairs = None
2199 # pairs = None
2200 #
2200 #
2201 # if kwargs.has_key('correctFactor'):
2201 # if kwargs.has_key('correctFactor'):
2202 # correctFactor = kwargs['correctFactor']
2202 # correctFactor = kwargs['correctFactor']
2203 # else:
2203 # else:
2204 # correctFactor = 1
2204 # correctFactor = 1
2205
2205
2206 # tau = dataOut.data_param
2206 # tau = dataOut.data_param
2207 # _lambda = dataOut.C/dataOut.frequency
2207 # _lambda = dataOut.C/dataOut.frequency
2208 # pairsList = dataOut.groupList
2208 # pairsList = dataOut.groupList
2209 # nChannels = dataOut.nChannels
2209 # nChannels = dataOut.nChannels
2210
2210
2211 kwargs['groupList'] = dataOut.groupList
2211 kwargs['groupList'] = dataOut.groupList
2212 kwargs['tau'] = dataOut.data_param
2212 kwargs['tau'] = dataOut.data_param
2213 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2213 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2214 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2214 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2215 dataOut.data_output = self.techniqueSA(kwargs)
2215 dataOut.data_output = self.techniqueSA(kwargs)
2216 dataOut.utctimeInit = dataOut.utctime
2216 dataOut.utctimeInit = dataOut.utctime
2217 dataOut.outputInterval = dataOut.timeInterval
2217 dataOut.outputInterval = dataOut.timeInterval
2218
2218
2219 elif technique == 'Meteors':
2219 elif technique == 'Meteors':
2220 dataOut.flagNoData = True
2220 dataOut.flagNoData = True
2221 self.__dataReady = False
2221 self.__dataReady = False
2222
2222
2223 if 'nHours' in kwargs:
2223 if 'nHours' in kwargs:
2224 nHours = kwargs['nHours']
2224 nHours = kwargs['nHours']
2225 else:
2225 else:
2226 nHours = 1
2226 nHours = 1
2227
2227
2228 if 'meteorsPerBin' in kwargs:
2228 if 'meteorsPerBin' in kwargs:
2229 meteorThresh = kwargs['meteorsPerBin']
2229 meteorThresh = kwargs['meteorsPerBin']
2230 else:
2230 else:
2231 meteorThresh = 6
2231 meteorThresh = 6
2232
2232
2233 if 'hmin' in kwargs:
2233 if 'hmin' in kwargs:
2234 hmin = kwargs['hmin']
2234 hmin = kwargs['hmin']
2235 else: hmin = 70
2235 else: hmin = 70
2236 if 'hmax' in kwargs:
2236 if 'hmax' in kwargs:
2237 hmax = kwargs['hmax']
2237 hmax = kwargs['hmax']
2238 else: hmax = 110
2238 else: hmax = 110
2239
2239
2240 dataOut.outputInterval = nHours*3600
2240 dataOut.outputInterval = nHours*3600
2241
2241
2242 if self.__isConfig == False:
2242 if self.__isConfig == False:
2243 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2243 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2244 #Get Initial LTC time
2244 #Get Initial LTC time
2245 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2245 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2246 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2246 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2247
2247
2248 self.__isConfig = True
2248 self.__isConfig = True
2249
2249
2250 if self.__buffer is None:
2250 if self.__buffer is None:
2251 self.__buffer = dataOut.data_param
2251 self.__buffer = dataOut.data_param
2252 self.__firstdata = copy.copy(dataOut)
2252 self.__firstdata = copy.copy(dataOut)
2253
2253
2254 else:
2254 else:
2255 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2255 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2256
2256
2257 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2257 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2258
2258
2259 if self.__dataReady:
2259 if self.__dataReady:
2260 dataOut.utctimeInit = self.__initime
2260 dataOut.utctimeInit = self.__initime
2261
2261
2262 self.__initime += dataOut.outputInterval #to erase time offset
2262 self.__initime += dataOut.outputInterval #to erase time offset
2263
2263
2264 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2264 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2265 dataOut.flagNoData = False
2265 dataOut.flagNoData = False
2266 self.__buffer = None
2266 self.__buffer = None
2267
2267
2268 elif technique == 'Meteors1':
2268 elif technique == 'Meteors1':
2269 dataOut.flagNoData = True
2269 dataOut.flagNoData = True
2270 self.__dataReady = False
2270 self.__dataReady = False
2271
2271
2272 if 'nMins' in kwargs:
2272 if 'nMins' in kwargs:
2273 nMins = kwargs['nMins']
2273 nMins = kwargs['nMins']
2274 else: nMins = 20
2274 else: nMins = 20
2275 if 'rx_location' in kwargs:
2275 if 'rx_location' in kwargs:
2276 rx_location = kwargs['rx_location']
2276 rx_location = kwargs['rx_location']
2277 else: rx_location = [(0,1),(1,1),(1,0)]
2277 else: rx_location = [(0,1),(1,1),(1,0)]
2278 if 'azimuth' in kwargs:
2278 if 'azimuth' in kwargs:
2279 azimuth = kwargs['azimuth']
2279 azimuth = kwargs['azimuth']
2280 else: azimuth = 51.06
2280 else: azimuth = 51.06
2281 if 'dfactor' in kwargs:
2281 if 'dfactor' in kwargs:
2282 dfactor = kwargs['dfactor']
2282 dfactor = kwargs['dfactor']
2283 if 'mode' in kwargs:
2283 if 'mode' in kwargs:
2284 mode = kwargs['mode']
2284 mode = kwargs['mode']
2285 if 'theta_x' in kwargs:
2285 if 'theta_x' in kwargs:
2286 theta_x = kwargs['theta_x']
2286 theta_x = kwargs['theta_x']
2287 if 'theta_y' in kwargs:
2287 if 'theta_y' in kwargs:
2288 theta_y = kwargs['theta_y']
2288 theta_y = kwargs['theta_y']
2289 else: mode = 'SA'
2289 else: mode = 'SA'
2290
2290
2291 #Borrar luego esto
2291 #Borrar luego esto
2292 if dataOut.groupList is None:
2292 if dataOut.groupList is None:
2293 dataOut.groupList = [(0,1),(0,2),(1,2)]
2293 dataOut.groupList = [(0,1),(0,2),(1,2)]
2294 groupList = dataOut.groupList
2294 groupList = dataOut.groupList
2295 C = 3e8
2295 C = 3e8
2296 freq = 50e6
2296 freq = 50e6
2297 lamb = C/freq
2297 lamb = C/freq
2298 k = 2*numpy.pi/lamb
2298 k = 2*numpy.pi/lamb
2299
2299
2300 timeList = dataOut.abscissaList
2300 timeList = dataOut.abscissaList
2301 heightList = dataOut.heightList
2301 heightList = dataOut.heightList
2302
2302
2303 if self.__isConfig == False:
2303 if self.__isConfig == False:
2304 dataOut.outputInterval = nMins*60
2304 dataOut.outputInterval = nMins*60
2305 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2305 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2306 #Get Initial LTC time
2306 #Get Initial LTC time
2307 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2307 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2308 minuteAux = initime.minute
2308 minuteAux = initime.minute
2309 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2309 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2310 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2310 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2311
2311
2312 self.__isConfig = True
2312 self.__isConfig = True
2313
2313
2314 if self.__buffer is None:
2314 if self.__buffer is None:
2315 self.__buffer = dataOut.data_param
2315 self.__buffer = dataOut.data_param
2316 self.__firstdata = copy.copy(dataOut)
2316 self.__firstdata = copy.copy(dataOut)
2317
2317
2318 else:
2318 else:
2319 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2319 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2320
2320
2321 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2321 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2322
2322
2323 if self.__dataReady:
2323 if self.__dataReady:
2324 dataOut.utctimeInit = self.__initime
2324 dataOut.utctimeInit = self.__initime
2325 self.__initime += dataOut.outputInterval #to erase time offset
2325 self.__initime += dataOut.outputInterval #to erase time offset
2326
2326
2327 metArray = self.__buffer
2327 metArray = self.__buffer
2328 if mode == 'SA':
2328 if mode == 'SA':
2329 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2329 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2330 elif mode == 'DBS':
2330 elif mode == 'DBS':
2331 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2331 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2332 dataOut.data_output = dataOut.data_output.T
2332 dataOut.data_output = dataOut.data_output.T
2333 dataOut.flagNoData = False
2333 dataOut.flagNoData = False
2334 self.__buffer = None
2334 self.__buffer = None
2335
2335
2336 return
2336 return
2337
2337
2338 class EWDriftsEstimation(Operation):
2338 class EWDriftsEstimation(Operation):
2339
2339
2340 def __init__(self):
2340 def __init__(self):
2341 Operation.__init__(self)
2341 Operation.__init__(self)
2342
2342
2343 def __correctValues(self, heiRang, phi, velRadial, SNR):
2343 def __correctValues(self, heiRang, phi, velRadial, SNR):
2344 listPhi = phi.tolist()
2344 listPhi = phi.tolist()
2345 maxid = listPhi.index(max(listPhi))
2345 maxid = listPhi.index(max(listPhi))
2346 minid = listPhi.index(min(listPhi))
2346 minid = listPhi.index(min(listPhi))
2347
2347
2348 rango = list(range(len(phi)))
2348 rango = list(range(len(phi)))
2349 # rango = numpy.delete(rango,maxid)
2349 # rango = numpy.delete(rango,maxid)
2350
2350
2351 heiRang1 = heiRang*math.cos(phi[maxid])
2351 heiRang1 = heiRang*math.cos(phi[maxid])
2352 heiRangAux = heiRang*math.cos(phi[minid])
2352 heiRangAux = heiRang*math.cos(phi[minid])
2353 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2353 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2354 heiRang1 = numpy.delete(heiRang1,indOut)
2354 heiRang1 = numpy.delete(heiRang1,indOut)
2355
2355
2356 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2356 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2357 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2357 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2358
2358
2359 for i in rango:
2359 for i in rango:
2360 x = heiRang*math.cos(phi[i])
2360 x = heiRang*math.cos(phi[i])
2361 y1 = velRadial[i,:]
2361 y1 = velRadial[i,:]
2362 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2362 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2363
2363
2364 x1 = heiRang1
2364 x1 = heiRang1
2365 y11 = f1(x1)
2365 y11 = f1(x1)
2366
2366
2367 y2 = SNR[i,:]
2367 y2 = SNR[i,:]
2368 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2368 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2369 y21 = f2(x1)
2369 y21 = f2(x1)
2370
2370
2371 velRadial1[i,:] = y11
2371 velRadial1[i,:] = y11
2372 SNR1[i,:] = y21
2372 SNR1[i,:] = y21
2373
2373
2374 return heiRang1, velRadial1, SNR1
2374 return heiRang1, velRadial1, SNR1
2375
2375
2376 def run(self, dataOut, zenith, zenithCorrection):
2376 def run(self, dataOut, zenith, zenithCorrection):
2377 heiRang = dataOut.heightList
2377 heiRang = dataOut.heightList
2378 velRadial = dataOut.data_param[:,3,:]
2378 velRadial = dataOut.data_param[:,3,:]
2379 SNR = dataOut.data_snr
2379 SNR = dataOut.data_snr
2380
2380
2381 zenith = numpy.array(zenith)
2381 zenith = numpy.array(zenith)
2382 zenith -= zenithCorrection
2382 zenith -= zenithCorrection
2383 zenith *= numpy.pi/180
2383 zenith *= numpy.pi/180
2384
2384
2385 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2385 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2386
2386
2387 alp = zenith[0]
2387 alp = zenith[0]
2388 bet = zenith[1]
2388 bet = zenith[1]
2389
2389
2390 w_w = velRadial1[0,:]
2390 w_w = velRadial1[0,:]
2391 w_e = velRadial1[1,:]
2391 w_e = velRadial1[1,:]
2392
2392
2393 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2393 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2394 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2394 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2395
2395
2396 winds = numpy.vstack((u,w))
2396 winds = numpy.vstack((u,w))
2397
2397
2398 dataOut.heightList = heiRang1
2398 dataOut.heightList = heiRang1
2399 dataOut.data_output = winds
2399 dataOut.data_output = winds
2400 dataOut.data_snr = SNR1
2400 dataOut.data_snr = SNR1
2401
2401
2402 dataOut.utctimeInit = dataOut.utctime
2402 dataOut.utctimeInit = dataOut.utctime
2403 dataOut.outputInterval = dataOut.timeInterval
2403 dataOut.outputInterval = dataOut.timeInterval
2404 return
2404 return
2405
2405
2406 #--------------- Non Specular Meteor ----------------
2406 #--------------- Non Specular Meteor ----------------
2407
2407
2408 class NonSpecularMeteorDetection(Operation):
2408 class NonSpecularMeteorDetection(Operation):
2409
2409
2410 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2410 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2411 data_acf = dataOut.data_pre[0]
2411 data_acf = dataOut.data_pre[0]
2412 data_ccf = dataOut.data_pre[1]
2412 data_ccf = dataOut.data_pre[1]
2413 pairsList = dataOut.groupList[1]
2413 pairsList = dataOut.groupList[1]
2414
2414
2415 lamb = dataOut.C/dataOut.frequency
2415 lamb = dataOut.C/dataOut.frequency
2416 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2416 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2417 paramInterval = dataOut.paramInterval
2417 paramInterval = dataOut.paramInterval
2418
2418
2419 nChannels = data_acf.shape[0]
2419 nChannels = data_acf.shape[0]
2420 nLags = data_acf.shape[1]
2420 nLags = data_acf.shape[1]
2421 nProfiles = data_acf.shape[2]
2421 nProfiles = data_acf.shape[2]
2422 nHeights = dataOut.nHeights
2422 nHeights = dataOut.nHeights
2423 nCohInt = dataOut.nCohInt
2423 nCohInt = dataOut.nCohInt
2424 sec = numpy.round(nProfiles/dataOut.paramInterval)
2424 sec = numpy.round(nProfiles/dataOut.paramInterval)
2425 heightList = dataOut.heightList
2425 heightList = dataOut.heightList
2426 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2426 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2427 utctime = dataOut.utctime
2427 utctime = dataOut.utctime
2428
2428
2429 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2429 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2430
2430
2431 #------------------------ SNR --------------------------------------
2431 #------------------------ SNR --------------------------------------
2432 power = data_acf[:,0,:,:].real
2432 power = data_acf[:,0,:,:].real
2433 noise = numpy.zeros(nChannels)
2433 noise = numpy.zeros(nChannels)
2434 SNR = numpy.zeros(power.shape)
2434 SNR = numpy.zeros(power.shape)
2435 for i in range(nChannels):
2435 for i in range(nChannels):
2436 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2436 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2437 SNR[i] = (power[i]-noise[i])/noise[i]
2437 SNR[i] = (power[i]-noise[i])/noise[i]
2438 SNRm = numpy.nanmean(SNR, axis = 0)
2438 SNRm = numpy.nanmean(SNR, axis = 0)
2439 SNRdB = 10*numpy.log10(SNR)
2439 SNRdB = 10*numpy.log10(SNR)
2440
2440
2441 if mode == 'SA':
2441 if mode == 'SA':
2442 dataOut.groupList = dataOut.groupList[1]
2442 dataOut.groupList = dataOut.groupList[1]
2443 nPairs = data_ccf.shape[0]
2443 nPairs = data_ccf.shape[0]
2444 #---------------------- Coherence and Phase --------------------------
2444 #---------------------- Coherence and Phase --------------------------
2445 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2445 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2446 # phase1 = numpy.copy(phase)
2446 # phase1 = numpy.copy(phase)
2447 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2447 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2448
2448
2449 for p in range(nPairs):
2449 for p in range(nPairs):
2450 ch0 = pairsList[p][0]
2450 ch0 = pairsList[p][0]
2451 ch1 = pairsList[p][1]
2451 ch1 = pairsList[p][1]
2452 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2452 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2453 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2453 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2454 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2454 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2455 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2455 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2456 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2456 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2457 coh = numpy.nanmax(coh1, axis = 0)
2457 coh = numpy.nanmax(coh1, axis = 0)
2458 # struc = numpy.ones((5,1))
2458 # struc = numpy.ones((5,1))
2459 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2459 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2460 #---------------------- Radial Velocity ----------------------------
2460 #---------------------- Radial Velocity ----------------------------
2461 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2461 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2462 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2462 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2463
2463
2464 if allData:
2464 if allData:
2465 boolMetFin = ~numpy.isnan(SNRm)
2465 boolMetFin = ~numpy.isnan(SNRm)
2466 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2466 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2467 else:
2467 else:
2468 #------------------------ Meteor mask ---------------------------------
2468 #------------------------ Meteor mask ---------------------------------
2469 # #SNR mask
2469 # #SNR mask
2470 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2470 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2471 #
2471 #
2472 # #Erase small objects
2472 # #Erase small objects
2473 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2473 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2474 #
2474 #
2475 # auxEEJ = numpy.sum(boolMet1,axis=0)
2475 # auxEEJ = numpy.sum(boolMet1,axis=0)
2476 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2476 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2477 # indEEJ = numpy.where(indOver)[0]
2477 # indEEJ = numpy.where(indOver)[0]
2478 # indNEEJ = numpy.where(~indOver)[0]
2478 # indNEEJ = numpy.where(~indOver)[0]
2479 #
2479 #
2480 # boolMetFin = boolMet1
2480 # boolMetFin = boolMet1
2481 #
2481 #
2482 # if indEEJ.size > 0:
2482 # if indEEJ.size > 0:
2483 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2483 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2484 #
2484 #
2485 # boolMet2 = coh > cohThresh
2485 # boolMet2 = coh > cohThresh
2486 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2486 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2487 #
2487 #
2488 # #Final Meteor mask
2488 # #Final Meteor mask
2489 # boolMetFin = boolMet1|boolMet2
2489 # boolMetFin = boolMet1|boolMet2
2490
2490
2491 #Coherence mask
2491 #Coherence mask
2492 boolMet1 = coh > 0.75
2492 boolMet1 = coh > 0.75
2493 struc = numpy.ones((30,1))
2493 struc = numpy.ones((30,1))
2494 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2494 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2495
2495
2496 #Derivative mask
2496 #Derivative mask
2497 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2497 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2498 boolMet2 = derPhase < 0.2
2498 boolMet2 = derPhase < 0.2
2499 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2499 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2500 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2500 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2501 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2501 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2502 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2502 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2503 # #Final mask
2503 # #Final mask
2504 # boolMetFin = boolMet2
2504 # boolMetFin = boolMet2
2505 boolMetFin = boolMet1&boolMet2
2505 boolMetFin = boolMet1&boolMet2
2506 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2506 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2507 #Creating data_param
2507 #Creating data_param
2508 coordMet = numpy.where(boolMetFin)
2508 coordMet = numpy.where(boolMetFin)
2509
2509
2510 tmet = coordMet[0]
2510 tmet = coordMet[0]
2511 hmet = coordMet[1]
2511 hmet = coordMet[1]
2512
2512
2513 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2513 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2514 data_param[:,0] = utctime
2514 data_param[:,0] = utctime
2515 data_param[:,1] = tmet
2515 data_param[:,1] = tmet
2516 data_param[:,2] = hmet
2516 data_param[:,2] = hmet
2517 data_param[:,3] = SNRm[tmet,hmet]
2517 data_param[:,3] = SNRm[tmet,hmet]
2518 data_param[:,4] = velRad[tmet,hmet]
2518 data_param[:,4] = velRad[tmet,hmet]
2519 data_param[:,5] = coh[tmet,hmet]
2519 data_param[:,5] = coh[tmet,hmet]
2520 data_param[:,6:] = phase[:,tmet,hmet].T
2520 data_param[:,6:] = phase[:,tmet,hmet].T
2521
2521
2522 elif mode == 'DBS':
2522 elif mode == 'DBS':
2523 dataOut.groupList = numpy.arange(nChannels)
2523 dataOut.groupList = numpy.arange(nChannels)
2524
2524
2525 #Radial Velocities
2525 #Radial Velocities
2526 phase = numpy.angle(data_acf[:,1,:,:])
2526 phase = numpy.angle(data_acf[:,1,:,:])
2527 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2527 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2528 velRad = phase*lamb/(4*numpy.pi*tSamp)
2528 velRad = phase*lamb/(4*numpy.pi*tSamp)
2529
2529
2530 #Spectral width
2530 #Spectral width
2531 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2531 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2532 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2532 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2533 acf1 = data_acf[:,1,:,:]
2533 acf1 = data_acf[:,1,:,:]
2534 acf2 = data_acf[:,2,:,:]
2534 acf2 = data_acf[:,2,:,:]
2535
2535
2536 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2536 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2537 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2537 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2538 if allData:
2538 if allData:
2539 boolMetFin = ~numpy.isnan(SNRdB)
2539 boolMetFin = ~numpy.isnan(SNRdB)
2540 else:
2540 else:
2541 #SNR
2541 #SNR
2542 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2542 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2543 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2543 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2544
2544
2545 #Radial velocity
2545 #Radial velocity
2546 boolMet2 = numpy.abs(velRad) < 20
2546 boolMet2 = numpy.abs(velRad) < 20
2547 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2547 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2548
2548
2549 #Spectral Width
2549 #Spectral Width
2550 boolMet3 = spcWidth < 30
2550 boolMet3 = spcWidth < 30
2551 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2551 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2552 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2552 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2553 boolMetFin = boolMet1&boolMet2&boolMet3
2553 boolMetFin = boolMet1&boolMet2&boolMet3
2554
2554
2555 #Creating data_param
2555 #Creating data_param
2556 coordMet = numpy.where(boolMetFin)
2556 coordMet = numpy.where(boolMetFin)
2557
2557
2558 cmet = coordMet[0]
2558 cmet = coordMet[0]
2559 tmet = coordMet[1]
2559 tmet = coordMet[1]
2560 hmet = coordMet[2]
2560 hmet = coordMet[2]
2561
2561
2562 data_param = numpy.zeros((tmet.size, 7))
2562 data_param = numpy.zeros((tmet.size, 7))
2563 data_param[:,0] = utctime
2563 data_param[:,0] = utctime
2564 data_param[:,1] = cmet
2564 data_param[:,1] = cmet
2565 data_param[:,2] = tmet
2565 data_param[:,2] = tmet
2566 data_param[:,3] = hmet
2566 data_param[:,3] = hmet
2567 data_param[:,4] = SNR[cmet,tmet,hmet].T
2567 data_param[:,4] = SNR[cmet,tmet,hmet].T
2568 data_param[:,5] = velRad[cmet,tmet,hmet].T
2568 data_param[:,5] = velRad[cmet,tmet,hmet].T
2569 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2569 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2570
2570
2571 # self.dataOut.data_param = data_int
2571 # self.dataOut.data_param = data_int
2572 if len(data_param) == 0:
2572 if len(data_param) == 0:
2573 dataOut.flagNoData = True
2573 dataOut.flagNoData = True
2574 else:
2574 else:
2575 dataOut.data_param = data_param
2575 dataOut.data_param = data_param
2576
2576
2577 def __erase_small(self, binArray, threshX, threshY):
2577 def __erase_small(self, binArray, threshX, threshY):
2578 labarray, numfeat = ndimage.measurements.label(binArray)
2578 labarray, numfeat = ndimage.measurements.label(binArray)
2579 binArray1 = numpy.copy(binArray)
2579 binArray1 = numpy.copy(binArray)
2580
2580
2581 for i in range(1,numfeat + 1):
2581 for i in range(1,numfeat + 1):
2582 auxBin = (labarray==i)
2582 auxBin = (labarray==i)
2583 auxSize = auxBin.sum()
2583 auxSize = auxBin.sum()
2584
2584
2585 x,y = numpy.where(auxBin)
2585 x,y = numpy.where(auxBin)
2586 widthX = x.max() - x.min()
2586 widthX = x.max() - x.min()
2587 widthY = y.max() - y.min()
2587 widthY = y.max() - y.min()
2588
2588
2589 #width X: 3 seg -> 12.5*3
2589 #width X: 3 seg -> 12.5*3
2590 #width Y:
2590 #width Y:
2591
2591
2592 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2592 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2593 binArray1[auxBin] = False
2593 binArray1[auxBin] = False
2594
2594
2595 return binArray1
2595 return binArray1
2596
2596
2597 #--------------- Specular Meteor ----------------
2597 #--------------- Specular Meteor ----------------
2598
2598
2599 class SMDetection(Operation):
2599 class SMDetection(Operation):
2600 '''
2600 '''
2601 Function DetectMeteors()
2601 Function DetectMeteors()
2602 Project developed with paper:
2602 Project developed with paper:
2603 HOLDSWORTH ET AL. 2004
2603 HOLDSWORTH ET AL. 2004
2604
2604
2605 Input:
2605 Input:
2606 self.dataOut.data_pre
2606 self.dataOut.data_pre
2607
2607
2608 centerReceiverIndex: From the channels, which is the center receiver
2608 centerReceiverIndex: From the channels, which is the center receiver
2609
2609
2610 hei_ref: Height reference for the Beacon signal extraction
2610 hei_ref: Height reference for the Beacon signal extraction
2611 tauindex:
2611 tauindex:
2612 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2612 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2613
2613
2614 cohDetection: Whether to user Coherent detection or not
2614 cohDetection: Whether to user Coherent detection or not
2615 cohDet_timeStep: Coherent Detection calculation time step
2615 cohDet_timeStep: Coherent Detection calculation time step
2616 cohDet_thresh: Coherent Detection phase threshold to correct phases
2616 cohDet_thresh: Coherent Detection phase threshold to correct phases
2617
2617
2618 noise_timeStep: Noise calculation time step
2618 noise_timeStep: Noise calculation time step
2619 noise_multiple: Noise multiple to define signal threshold
2619 noise_multiple: Noise multiple to define signal threshold
2620
2620
2621 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2621 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2622 multDet_rangeLimit: Multiple Detection Removal range limit in km
2622 multDet_rangeLimit: Multiple Detection Removal range limit in km
2623
2623
2624 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2624 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2625 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2625 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2626
2626
2627 hmin: Minimum Height of the meteor to use it in the further wind estimations
2627 hmin: Minimum Height of the meteor to use it in the further wind estimations
2628 hmax: Maximum Height of the meteor to use it in the further wind estimations
2628 hmax: Maximum Height of the meteor to use it in the further wind estimations
2629 azimuth: Azimuth angle correction
2629 azimuth: Azimuth angle correction
2630
2630
2631 Affected:
2631 Affected:
2632 self.dataOut.data_param
2632 self.dataOut.data_param
2633
2633
2634 Rejection Criteria (Errors):
2634 Rejection Criteria (Errors):
2635 0: No error; analysis OK
2635 0: No error; analysis OK
2636 1: SNR < SNR threshold
2636 1: SNR < SNR threshold
2637 2: angle of arrival (AOA) ambiguously determined
2637 2: angle of arrival (AOA) ambiguously determined
2638 3: AOA estimate not feasible
2638 3: AOA estimate not feasible
2639 4: Large difference in AOAs obtained from different antenna baselines
2639 4: Large difference in AOAs obtained from different antenna baselines
2640 5: echo at start or end of time series
2640 5: echo at start or end of time series
2641 6: echo less than 5 examples long; too short for analysis
2641 6: echo less than 5 examples long; too short for analysis
2642 7: echo rise exceeds 0.3s
2642 7: echo rise exceeds 0.3s
2643 8: echo decay time less than twice rise time
2643 8: echo decay time less than twice rise time
2644 9: large power level before echo
2644 9: large power level before echo
2645 10: large power level after echo
2645 10: large power level after echo
2646 11: poor fit to amplitude for estimation of decay time
2646 11: poor fit to amplitude for estimation of decay time
2647 12: poor fit to CCF phase variation for estimation of radial drift velocity
2647 12: poor fit to CCF phase variation for estimation of radial drift velocity
2648 13: height unresolvable echo: not valid height within 70 to 110 km
2648 13: height unresolvable echo: not valid height within 70 to 110 km
2649 14: height ambiguous echo: more then one possible height within 70 to 110 km
2649 14: height ambiguous echo: more then one possible height within 70 to 110 km
2650 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2650 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2651 16: oscilatory echo, indicating event most likely not an underdense echo
2651 16: oscilatory echo, indicating event most likely not an underdense echo
2652
2652
2653 17: phase difference in meteor Reestimation
2653 17: phase difference in meteor Reestimation
2654
2654
2655 Data Storage:
2655 Data Storage:
2656 Meteors for Wind Estimation (8):
2656 Meteors for Wind Estimation (8):
2657 Utc Time | Range Height
2657 Utc Time | Range Height
2658 Azimuth Zenith errorCosDir
2658 Azimuth Zenith errorCosDir
2659 VelRad errorVelRad
2659 VelRad errorVelRad
2660 Phase0 Phase1 Phase2 Phase3
2660 Phase0 Phase1 Phase2 Phase3
2661 TypeError
2661 TypeError
2662
2662
2663 '''
2663 '''
2664
2664
2665 def run(self, dataOut, hei_ref = None, tauindex = 0,
2665 def run(self, dataOut, hei_ref = None, tauindex = 0,
2666 phaseOffsets = None,
2666 phaseOffsets = None,
2667 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2667 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2668 noise_timeStep = 4, noise_multiple = 4,
2668 noise_timeStep = 4, noise_multiple = 4,
2669 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2669 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2670 phaseThresh = 20, SNRThresh = 5,
2670 phaseThresh = 20, SNRThresh = 5,
2671 hmin = 50, hmax=150, azimuth = 0,
2671 hmin = 50, hmax=150, azimuth = 0,
2672 channelPositions = None) :
2672 channelPositions = None) :
2673
2673
2674
2674
2675 #Getting Pairslist
2675 #Getting Pairslist
2676 if channelPositions is None:
2676 if channelPositions is None:
2677 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2677 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2678 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2678 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2679 meteorOps = SMOperations()
2679 meteorOps = SMOperations()
2680 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2680 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2681 heiRang = dataOut.heightList
2681 heiRang = dataOut.heightList
2682 #Get Beacon signal - No Beacon signal anymore
2682 #Get Beacon signal - No Beacon signal anymore
2683 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2683 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2684 #
2684 #
2685 # if hei_ref != None:
2685 # if hei_ref != None:
2686 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2686 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2687 #
2687 #
2688
2688
2689
2689
2690 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2690 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2691 # see if the user put in pre defined phase shifts
2691 # see if the user put in pre defined phase shifts
2692 voltsPShift = dataOut.data_pre.copy()
2692 voltsPShift = dataOut.data_pre.copy()
2693
2693
2694 # if predefinedPhaseShifts != None:
2694 # if predefinedPhaseShifts != None:
2695 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2695 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2696 #
2696 #
2697 # # elif beaconPhaseShifts:
2697 # # elif beaconPhaseShifts:
2698 # # #get hardware phase shifts using beacon signal
2698 # # #get hardware phase shifts using beacon signal
2699 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2699 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2700 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2700 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2701 #
2701 #
2702 # else:
2702 # else:
2703 # hardwarePhaseShifts = numpy.zeros(5)
2703 # hardwarePhaseShifts = numpy.zeros(5)
2704 #
2704 #
2705 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2705 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2706 # for i in range(self.dataOut.data_pre.shape[0]):
2706 # for i in range(self.dataOut.data_pre.shape[0]):
2707 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2707 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2708
2708
2709 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2709 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2710
2710
2711 #Remove DC
2711 #Remove DC
2712 voltsDC = numpy.mean(voltsPShift,1)
2712 voltsDC = numpy.mean(voltsPShift,1)
2713 voltsDC = numpy.mean(voltsDC,1)
2713 voltsDC = numpy.mean(voltsDC,1)
2714 for i in range(voltsDC.shape[0]):
2714 for i in range(voltsDC.shape[0]):
2715 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2715 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2716
2716
2717 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2717 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2718 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2718 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2719
2719
2720 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2720 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2721 #Coherent Detection
2721 #Coherent Detection
2722 if cohDetection:
2722 if cohDetection:
2723 #use coherent detection to get the net power
2723 #use coherent detection to get the net power
2724 cohDet_thresh = cohDet_thresh*numpy.pi/180
2724 cohDet_thresh = cohDet_thresh*numpy.pi/180
2725 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2725 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2726
2726
2727 #Non-coherent detection!
2727 #Non-coherent detection!
2728 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2728 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2729 #********** END OF COH/NON-COH POWER CALCULATION**********************
2729 #********** END OF COH/NON-COH POWER CALCULATION**********************
2730
2730
2731 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2731 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2732 #Get noise
2732 #Get noise
2733 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2733 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2734 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2734 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2735 #Get signal threshold
2735 #Get signal threshold
2736 signalThresh = noise_multiple*noise
2736 signalThresh = noise_multiple*noise
2737 #Meteor echoes detection
2737 #Meteor echoes detection
2738 listMeteors = self.__findMeteors(powerNet, signalThresh)
2738 listMeteors = self.__findMeteors(powerNet, signalThresh)
2739 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2739 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2740
2740
2741 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2741 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2742 #Parameters
2742 #Parameters
2743 heiRange = dataOut.heightList
2743 heiRange = dataOut.heightList
2744 rangeInterval = heiRange[1] - heiRange[0]
2744 rangeInterval = heiRange[1] - heiRange[0]
2745 rangeLimit = multDet_rangeLimit/rangeInterval
2745 rangeLimit = multDet_rangeLimit/rangeInterval
2746 timeLimit = multDet_timeLimit/dataOut.timeInterval
2746 timeLimit = multDet_timeLimit/dataOut.timeInterval
2747 #Multiple detection removals
2747 #Multiple detection removals
2748 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2748 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2749 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2749 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2750
2750
2751 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2751 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2752 #Parameters
2752 #Parameters
2753 phaseThresh = phaseThresh*numpy.pi/180
2753 phaseThresh = phaseThresh*numpy.pi/180
2754 thresh = [phaseThresh, noise_multiple, SNRThresh]
2754 thresh = [phaseThresh, noise_multiple, SNRThresh]
2755 #Meteor reestimation (Errors N 1, 6, 12, 17)
2755 #Meteor reestimation (Errors N 1, 6, 12, 17)
2756 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2756 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2757 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2757 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2758 #Estimation of decay times (Errors N 7, 8, 11)
2758 #Estimation of decay times (Errors N 7, 8, 11)
2759 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2759 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2760 #******************* END OF METEOR REESTIMATION *******************
2760 #******************* END OF METEOR REESTIMATION *******************
2761
2761
2762 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2762 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2763 #Calculating Radial Velocity (Error N 15)
2763 #Calculating Radial Velocity (Error N 15)
2764 radialStdThresh = 10
2764 radialStdThresh = 10
2765 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2765 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2766
2766
2767 if len(listMeteors4) > 0:
2767 if len(listMeteors4) > 0:
2768 #Setting New Array
2768 #Setting New Array
2769 date = dataOut.utctime
2769 date = dataOut.utctime
2770 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2770 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2771
2771
2772 #Correcting phase offset
2772 #Correcting phase offset
2773 if phaseOffsets != None:
2773 if phaseOffsets != None:
2774 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2774 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2775 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2775 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2776
2776
2777 #Second Pairslist
2777 #Second Pairslist
2778 pairsList = []
2778 pairsList = []
2779 pairx = (0,1)
2779 pairx = (0,1)
2780 pairy = (2,3)
2780 pairy = (2,3)
2781 pairsList.append(pairx)
2781 pairsList.append(pairx)
2782 pairsList.append(pairy)
2782 pairsList.append(pairy)
2783
2783
2784 jph = numpy.array([0,0,0,0])
2784 jph = numpy.array([0,0,0,0])
2785 h = (hmin,hmax)
2785 h = (hmin,hmax)
2786 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2786 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2787
2787
2788 # #Calculate AOA (Error N 3, 4)
2788 # #Calculate AOA (Error N 3, 4)
2789 # #JONES ET AL. 1998
2789 # #JONES ET AL. 1998
2790 # error = arrayParameters[:,-1]
2790 # error = arrayParameters[:,-1]
2791 # AOAthresh = numpy.pi/8
2791 # AOAthresh = numpy.pi/8
2792 # phases = -arrayParameters[:,9:13]
2792 # phases = -arrayParameters[:,9:13]
2793 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2793 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2794 #
2794 #
2795 # #Calculate Heights (Error N 13 and 14)
2795 # #Calculate Heights (Error N 13 and 14)
2796 # error = arrayParameters[:,-1]
2796 # error = arrayParameters[:,-1]
2797 # Ranges = arrayParameters[:,2]
2797 # Ranges = arrayParameters[:,2]
2798 # zenith = arrayParameters[:,5]
2798 # zenith = arrayParameters[:,5]
2799 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2799 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2800 # error = arrayParameters[:,-1]
2800 # error = arrayParameters[:,-1]
2801 #********************* END OF PARAMETERS CALCULATION **************************
2801 #********************* END OF PARAMETERS CALCULATION **************************
2802
2802
2803 #***************************+ PASS DATA TO NEXT STEP **********************
2803 #***************************+ PASS DATA TO NEXT STEP **********************
2804 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2804 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2805 dataOut.data_param = arrayParameters
2805 dataOut.data_param = arrayParameters
2806
2806
2807 if arrayParameters is None:
2807 if arrayParameters is None:
2808 dataOut.flagNoData = True
2808 dataOut.flagNoData = True
2809 else:
2809 else:
2810 dataOut.flagNoData = True
2810 dataOut.flagNoData = True
2811
2811
2812 return
2812 return
2813
2813
2814 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2814 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2815
2815
2816 minIndex = min(newheis[0])
2816 minIndex = min(newheis[0])
2817 maxIndex = max(newheis[0])
2817 maxIndex = max(newheis[0])
2818
2818
2819 voltage = voltage0[:,:,minIndex:maxIndex+1]
2819 voltage = voltage0[:,:,minIndex:maxIndex+1]
2820 nLength = voltage.shape[1]/n
2820 nLength = voltage.shape[1]/n
2821 nMin = 0
2821 nMin = 0
2822 nMax = 0
2822 nMax = 0
2823 phaseOffset = numpy.zeros((len(pairslist),n))
2823 phaseOffset = numpy.zeros((len(pairslist),n))
2824
2824
2825 for i in range(n):
2825 for i in range(n):
2826 nMax += nLength
2826 nMax += nLength
2827 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2827 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2828 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2828 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2829 phaseOffset[:,i] = phaseCCF.transpose()
2829 phaseOffset[:,i] = phaseCCF.transpose()
2830 nMin = nMax
2830 nMin = nMax
2831 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2831 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2832
2832
2833 #Remove Outliers
2833 #Remove Outliers
2834 factor = 2
2834 factor = 2
2835 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2835 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2836 dw = numpy.std(wt,axis = 1)
2836 dw = numpy.std(wt,axis = 1)
2837 dw = dw.reshape((dw.size,1))
2837 dw = dw.reshape((dw.size,1))
2838 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2838 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2839 phaseOffset[ind] = numpy.nan
2839 phaseOffset[ind] = numpy.nan
2840 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2840 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2841
2841
2842 return phaseOffset
2842 return phaseOffset
2843
2843
2844 def __shiftPhase(self, data, phaseShift):
2844 def __shiftPhase(self, data, phaseShift):
2845 #this will shift the phase of a complex number
2845 #this will shift the phase of a complex number
2846 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2846 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2847 return dataShifted
2847 return dataShifted
2848
2848
2849 def __estimatePhaseDifference(self, array, pairslist):
2849 def __estimatePhaseDifference(self, array, pairslist):
2850 nChannel = array.shape[0]
2850 nChannel = array.shape[0]
2851 nHeights = array.shape[2]
2851 nHeights = array.shape[2]
2852 numPairs = len(pairslist)
2852 numPairs = len(pairslist)
2853 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2853 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2854 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2854 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2855
2855
2856 #Correct phases
2856 #Correct phases
2857 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2857 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2858 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2858 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2859
2859
2860 if indDer[0].shape[0] > 0:
2860 if indDer[0].shape[0] > 0:
2861 for i in range(indDer[0].shape[0]):
2861 for i in range(indDer[0].shape[0]):
2862 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2862 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2863 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2863 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2864
2864
2865 # for j in range(numSides):
2865 # for j in range(numSides):
2866 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2866 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2867 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2867 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2868 #
2868 #
2869 #Linear
2869 #Linear
2870 phaseInt = numpy.zeros((numPairs,1))
2870 phaseInt = numpy.zeros((numPairs,1))
2871 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2871 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2872 for j in range(numPairs):
2872 for j in range(numPairs):
2873 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2873 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2874 phaseInt[j] = fit[1]
2874 phaseInt[j] = fit[1]
2875 #Phase Differences
2875 #Phase Differences
2876 phaseDiff = phaseInt - phaseCCF[:,2,:]
2876 phaseDiff = phaseInt - phaseCCF[:,2,:]
2877 phaseArrival = phaseInt.reshape(phaseInt.size)
2877 phaseArrival = phaseInt.reshape(phaseInt.size)
2878
2878
2879 #Dealias
2879 #Dealias
2880 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2880 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2881 # indAlias = numpy.where(phaseArrival > numpy.pi)
2881 # indAlias = numpy.where(phaseArrival > numpy.pi)
2882 # phaseArrival[indAlias] -= 2*numpy.pi
2882 # phaseArrival[indAlias] -= 2*numpy.pi
2883 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2883 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2884 # phaseArrival[indAlias] += 2*numpy.pi
2884 # phaseArrival[indAlias] += 2*numpy.pi
2885
2885
2886 return phaseDiff, phaseArrival
2886 return phaseDiff, phaseArrival
2887
2887
2888 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2888 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2889 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2889 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2890 #find the phase shifts of each channel over 1 second intervals
2890 #find the phase shifts of each channel over 1 second intervals
2891 #only look at ranges below the beacon signal
2891 #only look at ranges below the beacon signal
2892 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2892 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2893 numBlocks = int(volts.shape[1]/numProfPerBlock)
2893 numBlocks = int(volts.shape[1]/numProfPerBlock)
2894 numHeights = volts.shape[2]
2894 numHeights = volts.shape[2]
2895 nChannel = volts.shape[0]
2895 nChannel = volts.shape[0]
2896 voltsCohDet = volts.copy()
2896 voltsCohDet = volts.copy()
2897
2897
2898 pairsarray = numpy.array(pairslist)
2898 pairsarray = numpy.array(pairslist)
2899 indSides = pairsarray[:,1]
2899 indSides = pairsarray[:,1]
2900 # indSides = numpy.array(range(nChannel))
2900 # indSides = numpy.array(range(nChannel))
2901 # indSides = numpy.delete(indSides, indCenter)
2901 # indSides = numpy.delete(indSides, indCenter)
2902 #
2902 #
2903 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2903 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2904 listBlocks = numpy.array_split(volts, numBlocks, 1)
2904 listBlocks = numpy.array_split(volts, numBlocks, 1)
2905
2905
2906 startInd = 0
2906 startInd = 0
2907 endInd = 0
2907 endInd = 0
2908
2908
2909 for i in range(numBlocks):
2909 for i in range(numBlocks):
2910 startInd = endInd
2910 startInd = endInd
2911 endInd = endInd + listBlocks[i].shape[1]
2911 endInd = endInd + listBlocks[i].shape[1]
2912
2912
2913 arrayBlock = listBlocks[i]
2913 arrayBlock = listBlocks[i]
2914 # arrayBlockCenter = listCenter[i]
2914 # arrayBlockCenter = listCenter[i]
2915
2915
2916 #Estimate the Phase Difference
2916 #Estimate the Phase Difference
2917 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2917 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2918 #Phase Difference RMS
2918 #Phase Difference RMS
2919 arrayPhaseRMS = numpy.abs(phaseDiff)
2919 arrayPhaseRMS = numpy.abs(phaseDiff)
2920 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2920 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2921 indPhase = numpy.where(phaseRMSaux==4)
2921 indPhase = numpy.where(phaseRMSaux==4)
2922 #Shifting
2922 #Shifting
2923 if indPhase[0].shape[0] > 0:
2923 if indPhase[0].shape[0] > 0:
2924 for j in range(indSides.size):
2924 for j in range(indSides.size):
2925 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2925 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2926 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2926 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2927
2927
2928 return voltsCohDet
2928 return voltsCohDet
2929
2929
2930 def __calculateCCF(self, volts, pairslist ,laglist):
2930 def __calculateCCF(self, volts, pairslist ,laglist):
2931
2931
2932 nHeights = volts.shape[2]
2932 nHeights = volts.shape[2]
2933 nPoints = volts.shape[1]
2933 nPoints = volts.shape[1]
2934 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2934 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2935
2935
2936 for i in range(len(pairslist)):
2936 for i in range(len(pairslist)):
2937 volts1 = volts[pairslist[i][0]]
2937 volts1 = volts[pairslist[i][0]]
2938 volts2 = volts[pairslist[i][1]]
2938 volts2 = volts[pairslist[i][1]]
2939
2939
2940 for t in range(len(laglist)):
2940 for t in range(len(laglist)):
2941 idxT = laglist[t]
2941 idxT = laglist[t]
2942 if idxT >= 0:
2942 if idxT >= 0:
2943 vStacked = numpy.vstack((volts2[idxT:,:],
2943 vStacked = numpy.vstack((volts2[idxT:,:],
2944 numpy.zeros((idxT, nHeights),dtype='complex')))
2944 numpy.zeros((idxT, nHeights),dtype='complex')))
2945 else:
2945 else:
2946 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2946 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2947 volts2[:(nPoints + idxT),:]))
2947 volts2[:(nPoints + idxT),:]))
2948 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2948 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2949
2949
2950 vStacked = None
2950 vStacked = None
2951 return voltsCCF
2951 return voltsCCF
2952
2952
2953 def __getNoise(self, power, timeSegment, timeInterval):
2953 def __getNoise(self, power, timeSegment, timeInterval):
2954 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2954 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2955 numBlocks = int(power.shape[0]/numProfPerBlock)
2955 numBlocks = int(power.shape[0]/numProfPerBlock)
2956 numHeights = power.shape[1]
2956 numHeights = power.shape[1]
2957
2957
2958 listPower = numpy.array_split(power, numBlocks, 0)
2958 listPower = numpy.array_split(power, numBlocks, 0)
2959 noise = numpy.zeros((power.shape[0], power.shape[1]))
2959 noise = numpy.zeros((power.shape[0], power.shape[1]))
2960 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2960 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2961
2961
2962 startInd = 0
2962 startInd = 0
2963 endInd = 0
2963 endInd = 0
2964
2964
2965 for i in range(numBlocks): #split por canal
2965 for i in range(numBlocks): #split por canal
2966 startInd = endInd
2966 startInd = endInd
2967 endInd = endInd + listPower[i].shape[0]
2967 endInd = endInd + listPower[i].shape[0]
2968
2968
2969 arrayBlock = listPower[i]
2969 arrayBlock = listPower[i]
2970 noiseAux = numpy.mean(arrayBlock, 0)
2970 noiseAux = numpy.mean(arrayBlock, 0)
2971 # noiseAux = numpy.median(noiseAux)
2971 # noiseAux = numpy.median(noiseAux)
2972 # noiseAux = numpy.mean(arrayBlock)
2972 # noiseAux = numpy.mean(arrayBlock)
2973 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2973 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2974
2974
2975 noiseAux1 = numpy.mean(arrayBlock)
2975 noiseAux1 = numpy.mean(arrayBlock)
2976 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2976 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2977
2977
2978 return noise, noise1
2978 return noise, noise1
2979
2979
2980 def __findMeteors(self, power, thresh):
2980 def __findMeteors(self, power, thresh):
2981 nProf = power.shape[0]
2981 nProf = power.shape[0]
2982 nHeights = power.shape[1]
2982 nHeights = power.shape[1]
2983 listMeteors = []
2983 listMeteors = []
2984
2984
2985 for i in range(nHeights):
2985 for i in range(nHeights):
2986 powerAux = power[:,i]
2986 powerAux = power[:,i]
2987 threshAux = thresh[:,i]
2987 threshAux = thresh[:,i]
2988
2988
2989 indUPthresh = numpy.where(powerAux > threshAux)[0]
2989 indUPthresh = numpy.where(powerAux > threshAux)[0]
2990 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2990 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2991
2991
2992 j = 0
2992 j = 0
2993
2993
2994 while (j < indUPthresh.size - 2):
2994 while (j < indUPthresh.size - 2):
2995 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
2995 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
2996 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
2996 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
2997 indDNthresh = indDNthresh[indDNAux]
2997 indDNthresh = indDNthresh[indDNAux]
2998
2998
2999 if (indDNthresh.size > 0):
2999 if (indDNthresh.size > 0):
3000 indEnd = indDNthresh[0] - 1
3000 indEnd = indDNthresh[0] - 1
3001 indInit = indUPthresh[j]
3001 indInit = indUPthresh[j]
3002
3002
3003 meteor = powerAux[indInit:indEnd + 1]
3003 meteor = powerAux[indInit:indEnd + 1]
3004 indPeak = meteor.argmax() + indInit
3004 indPeak = meteor.argmax() + indInit
3005 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3005 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3006
3006
3007 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3007 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3008 j = numpy.where(indUPthresh == indEnd)[0] + 1
3008 j = numpy.where(indUPthresh == indEnd)[0] + 1
3009 else: j+=1
3009 else: j+=1
3010 else: j+=1
3010 else: j+=1
3011
3011
3012 return listMeteors
3012 return listMeteors
3013
3013
3014 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3014 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3015
3015
3016 arrayMeteors = numpy.asarray(listMeteors)
3016 arrayMeteors = numpy.asarray(listMeteors)
3017 listMeteors1 = []
3017 listMeteors1 = []
3018
3018
3019 while arrayMeteors.shape[0] > 0:
3019 while arrayMeteors.shape[0] > 0:
3020 FLAs = arrayMeteors[:,4]
3020 FLAs = arrayMeteors[:,4]
3021 maxFLA = FLAs.argmax()
3021 maxFLA = FLAs.argmax()
3022 listMeteors1.append(arrayMeteors[maxFLA,:])
3022 listMeteors1.append(arrayMeteors[maxFLA,:])
3023
3023
3024 MeteorInitTime = arrayMeteors[maxFLA,1]
3024 MeteorInitTime = arrayMeteors[maxFLA,1]
3025 MeteorEndTime = arrayMeteors[maxFLA,3]
3025 MeteorEndTime = arrayMeteors[maxFLA,3]
3026 MeteorHeight = arrayMeteors[maxFLA,0]
3026 MeteorHeight = arrayMeteors[maxFLA,0]
3027
3027
3028 #Check neighborhood
3028 #Check neighborhood
3029 maxHeightIndex = MeteorHeight + rangeLimit
3029 maxHeightIndex = MeteorHeight + rangeLimit
3030 minHeightIndex = MeteorHeight - rangeLimit
3030 minHeightIndex = MeteorHeight - rangeLimit
3031 minTimeIndex = MeteorInitTime - timeLimit
3031 minTimeIndex = MeteorInitTime - timeLimit
3032 maxTimeIndex = MeteorEndTime + timeLimit
3032 maxTimeIndex = MeteorEndTime + timeLimit
3033
3033
3034 #Check Heights
3034 #Check Heights
3035 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3035 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3036 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3036 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3037 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3037 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3038
3038
3039 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3039 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3040
3040
3041 return listMeteors1
3041 return listMeteors1
3042
3042
3043 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3043 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3044 numHeights = volts.shape[2]
3044 numHeights = volts.shape[2]
3045 nChannel = volts.shape[0]
3045 nChannel = volts.shape[0]
3046
3046
3047 thresholdPhase = thresh[0]
3047 thresholdPhase = thresh[0]
3048 thresholdNoise = thresh[1]
3048 thresholdNoise = thresh[1]
3049 thresholdDB = float(thresh[2])
3049 thresholdDB = float(thresh[2])
3050
3050
3051 thresholdDB1 = 10**(thresholdDB/10)
3051 thresholdDB1 = 10**(thresholdDB/10)
3052 pairsarray = numpy.array(pairslist)
3052 pairsarray = numpy.array(pairslist)
3053 indSides = pairsarray[:,1]
3053 indSides = pairsarray[:,1]
3054
3054
3055 pairslist1 = list(pairslist)
3055 pairslist1 = list(pairslist)
3056 pairslist1.append((0,1))
3056 pairslist1.append((0,1))
3057 pairslist1.append((3,4))
3057 pairslist1.append((3,4))
3058
3058
3059 listMeteors1 = []
3059 listMeteors1 = []
3060 listPowerSeries = []
3060 listPowerSeries = []
3061 listVoltageSeries = []
3061 listVoltageSeries = []
3062 #volts has the war data
3062 #volts has the war data
3063
3063
3064 if frequency == 30e6:
3064 if frequency == 30e6:
3065 timeLag = 45*10**-3
3065 timeLag = 45*10**-3
3066 else:
3066 else:
3067 timeLag = 15*10**-3
3067 timeLag = 15*10**-3
3068 lag = numpy.ceil(timeLag/timeInterval)
3068 lag = numpy.ceil(timeLag/timeInterval)
3069
3069
3070 for i in range(len(listMeteors)):
3070 for i in range(len(listMeteors)):
3071
3071
3072 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3072 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3073 meteorAux = numpy.zeros(16)
3073 meteorAux = numpy.zeros(16)
3074
3074
3075 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3075 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3076 mHeight = listMeteors[i][0]
3076 mHeight = listMeteors[i][0]
3077 mStart = listMeteors[i][1]
3077 mStart = listMeteors[i][1]
3078 mPeak = listMeteors[i][2]
3078 mPeak = listMeteors[i][2]
3079 mEnd = listMeteors[i][3]
3079 mEnd = listMeteors[i][3]
3080
3080
3081 #get the volt data between the start and end times of the meteor
3081 #get the volt data between the start and end times of the meteor
3082 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3082 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3083 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3083 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3084
3084
3085 #3.6. Phase Difference estimation
3085 #3.6. Phase Difference estimation
3086 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3086 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3087
3087
3088 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3088 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3089 #meteorVolts0.- all Channels, all Profiles
3089 #meteorVolts0.- all Channels, all Profiles
3090 meteorVolts0 = volts[:,:,mHeight]
3090 meteorVolts0 = volts[:,:,mHeight]
3091 meteorThresh = noise[:,mHeight]*thresholdNoise
3091 meteorThresh = noise[:,mHeight]*thresholdNoise
3092 meteorNoise = noise[:,mHeight]
3092 meteorNoise = noise[:,mHeight]
3093 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3093 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3094 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3094 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3095
3095
3096 #Times reestimation
3096 #Times reestimation
3097 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3097 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3098 if mStart1.size > 0:
3098 if mStart1.size > 0:
3099 mStart1 = mStart1[-1] + 1
3099 mStart1 = mStart1[-1] + 1
3100
3100
3101 else:
3101 else:
3102 mStart1 = mPeak
3102 mStart1 = mPeak
3103
3103
3104 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3104 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3105 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3105 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3106 if mEndDecayTime1.size == 0:
3106 if mEndDecayTime1.size == 0:
3107 mEndDecayTime1 = powerNet0.size
3107 mEndDecayTime1 = powerNet0.size
3108 else:
3108 else:
3109 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3109 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3110 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3110 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3111
3111
3112 #meteorVolts1.- all Channels, from start to end
3112 #meteorVolts1.- all Channels, from start to end
3113 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3113 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3114 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3114 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3115 if meteorVolts2.shape[1] == 0:
3115 if meteorVolts2.shape[1] == 0:
3116 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3116 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3117 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3117 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3118 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3118 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3119 ##################### END PARAMETERS REESTIMATION #########################
3119 ##################### END PARAMETERS REESTIMATION #########################
3120
3120
3121 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3121 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3122 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3122 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3123 if meteorVolts2.shape[1] > 0:
3123 if meteorVolts2.shape[1] > 0:
3124 #Phase Difference re-estimation
3124 #Phase Difference re-estimation
3125 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3125 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3126 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3126 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3127 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3127 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3128 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3128 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3129 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3129 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3130
3130
3131 #Phase Difference RMS
3131 #Phase Difference RMS
3132 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3132 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3133 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3133 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3134 #Data from Meteor
3134 #Data from Meteor
3135 mPeak1 = powerNet1.argmax() + mStart1
3135 mPeak1 = powerNet1.argmax() + mStart1
3136 mPeakPower1 = powerNet1.max()
3136 mPeakPower1 = powerNet1.max()
3137 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3137 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3138 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3138 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3139 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3139 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3140 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3140 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3141 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3141 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3142 #Vectorize
3142 #Vectorize
3143 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3143 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3144 meteorAux[7:11] = phaseDiffint[0:4]
3144 meteorAux[7:11] = phaseDiffint[0:4]
3145
3145
3146 #Rejection Criterions
3146 #Rejection Criterions
3147 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3147 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3148 meteorAux[-1] = 17
3148 meteorAux[-1] = 17
3149 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3149 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3150 meteorAux[-1] = 1
3150 meteorAux[-1] = 1
3151
3151
3152
3152
3153 else:
3153 else:
3154 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3154 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3155 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3155 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3156 PowerSeries = 0
3156 PowerSeries = 0
3157
3157
3158 listMeteors1.append(meteorAux)
3158 listMeteors1.append(meteorAux)
3159 listPowerSeries.append(PowerSeries)
3159 listPowerSeries.append(PowerSeries)
3160 listVoltageSeries.append(meteorVolts1)
3160 listVoltageSeries.append(meteorVolts1)
3161
3161
3162 return listMeteors1, listPowerSeries, listVoltageSeries
3162 return listMeteors1, listPowerSeries, listVoltageSeries
3163
3163
3164 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3164 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3165
3165
3166 threshError = 10
3166 threshError = 10
3167 #Depending if it is 30 or 50 MHz
3167 #Depending if it is 30 or 50 MHz
3168 if frequency == 30e6:
3168 if frequency == 30e6:
3169 timeLag = 45*10**-3
3169 timeLag = 45*10**-3
3170 else:
3170 else:
3171 timeLag = 15*10**-3
3171 timeLag = 15*10**-3
3172 lag = numpy.ceil(timeLag/timeInterval)
3172 lag = numpy.ceil(timeLag/timeInterval)
3173
3173
3174 listMeteors1 = []
3174 listMeteors1 = []
3175
3175
3176 for i in range(len(listMeteors)):
3176 for i in range(len(listMeteors)):
3177 meteorPower = listPower[i]
3177 meteorPower = listPower[i]
3178 meteorAux = listMeteors[i]
3178 meteorAux = listMeteors[i]
3179
3179
3180 if meteorAux[-1] == 0:
3180 if meteorAux[-1] == 0:
3181
3181
3182 try:
3182 try:
3183 indmax = meteorPower.argmax()
3183 indmax = meteorPower.argmax()
3184 indlag = indmax + lag
3184 indlag = indmax + lag
3185
3185
3186 y = meteorPower[indlag:]
3186 y = meteorPower[indlag:]
3187 x = numpy.arange(0, y.size)*timeLag
3187 x = numpy.arange(0, y.size)*timeLag
3188
3188
3189 #first guess
3189 #first guess
3190 a = y[0]
3190 a = y[0]
3191 tau = timeLag
3191 tau = timeLag
3192 #exponential fit
3192 #exponential fit
3193 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3193 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3194 y1 = self.__exponential_function(x, *popt)
3194 y1 = self.__exponential_function(x, *popt)
3195 #error estimation
3195 #error estimation
3196 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3196 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3197
3197
3198 decayTime = popt[1]
3198 decayTime = popt[1]
3199 riseTime = indmax*timeInterval
3199 riseTime = indmax*timeInterval
3200 meteorAux[11:13] = [decayTime, error]
3200 meteorAux[11:13] = [decayTime, error]
3201
3201
3202 #Table items 7, 8 and 11
3202 #Table items 7, 8 and 11
3203 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3203 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3204 meteorAux[-1] = 7
3204 meteorAux[-1] = 7
3205 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3205 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3206 meteorAux[-1] = 8
3206 meteorAux[-1] = 8
3207 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3207 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3208 meteorAux[-1] = 11
3208 meteorAux[-1] = 11
3209
3209
3210
3210
3211 except:
3211 except:
3212 meteorAux[-1] = 11
3212 meteorAux[-1] = 11
3213
3213
3214
3214
3215 listMeteors1.append(meteorAux)
3215 listMeteors1.append(meteorAux)
3216
3216
3217 return listMeteors1
3217 return listMeteors1
3218
3218
3219 #Exponential Function
3219 #Exponential Function
3220
3220
3221 def __exponential_function(self, x, a, tau):
3221 def __exponential_function(self, x, a, tau):
3222 y = a*numpy.exp(-x/tau)
3222 y = a*numpy.exp(-x/tau)
3223 return y
3223 return y
3224
3224
3225 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3225 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3226
3226
3227 pairslist1 = list(pairslist)
3227 pairslist1 = list(pairslist)
3228 pairslist1.append((0,1))
3228 pairslist1.append((0,1))
3229 pairslist1.append((3,4))
3229 pairslist1.append((3,4))
3230 numPairs = len(pairslist1)
3230 numPairs = len(pairslist1)
3231 #Time Lag
3231 #Time Lag
3232 timeLag = 45*10**-3
3232 timeLag = 45*10**-3
3233 c = 3e8
3233 c = 3e8
3234 lag = numpy.ceil(timeLag/timeInterval)
3234 lag = numpy.ceil(timeLag/timeInterval)
3235 freq = 30e6
3235 freq = 30e6
3236
3236
3237 listMeteors1 = []
3237 listMeteors1 = []
3238
3238
3239 for i in range(len(listMeteors)):
3239 for i in range(len(listMeteors)):
3240 meteorAux = listMeteors[i]
3240 meteorAux = listMeteors[i]
3241 if meteorAux[-1] == 0:
3241 if meteorAux[-1] == 0:
3242 mStart = listMeteors[i][1]
3242 mStart = listMeteors[i][1]
3243 mPeak = listMeteors[i][2]
3243 mPeak = listMeteors[i][2]
3244 mLag = mPeak - mStart + lag
3244 mLag = mPeak - mStart + lag
3245
3245
3246 #get the volt data between the start and end times of the meteor
3246 #get the volt data between the start and end times of the meteor
3247 meteorVolts = listVolts[i]
3247 meteorVolts = listVolts[i]
3248 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3248 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3249
3249
3250 #Get CCF
3250 #Get CCF
3251 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3251 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3252
3252
3253 #Method 2
3253 #Method 2
3254 slopes = numpy.zeros(numPairs)
3254 slopes = numpy.zeros(numPairs)
3255 time = numpy.array([-2,-1,1,2])*timeInterval
3255 time = numpy.array([-2,-1,1,2])*timeInterval
3256 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3256 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3257
3257
3258 #Correct phases
3258 #Correct phases
3259 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3259 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3260 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3260 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3261
3261
3262 if indDer[0].shape[0] > 0:
3262 if indDer[0].shape[0] > 0:
3263 for i in range(indDer[0].shape[0]):
3263 for i in range(indDer[0].shape[0]):
3264 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3264 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3265 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3265 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3266
3266
3267 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3267 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3268 for j in range(numPairs):
3268 for j in range(numPairs):
3269 fit = stats.linregress(time, angAllCCF[j,:])
3269 fit = stats.linregress(time, angAllCCF[j,:])
3270 slopes[j] = fit[0]
3270 slopes[j] = fit[0]
3271
3271
3272 #Remove Outlier
3272 #Remove Outlier
3273 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3273 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3274 # slopes = numpy.delete(slopes,indOut)
3274 # slopes = numpy.delete(slopes,indOut)
3275 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3275 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3276 # slopes = numpy.delete(slopes,indOut)
3276 # slopes = numpy.delete(slopes,indOut)
3277
3277
3278 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3278 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3279 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3279 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3280 meteorAux[-2] = radialError
3280 meteorAux[-2] = radialError
3281 meteorAux[-3] = radialVelocity
3281 meteorAux[-3] = radialVelocity
3282
3282
3283 #Setting Error
3283 #Setting Error
3284 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3284 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3285 if numpy.abs(radialVelocity) > 200:
3285 if numpy.abs(radialVelocity) > 200:
3286 meteorAux[-1] = 15
3286 meteorAux[-1] = 15
3287 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3287 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3288 elif radialError > radialStdThresh:
3288 elif radialError > radialStdThresh:
3289 meteorAux[-1] = 12
3289 meteorAux[-1] = 12
3290
3290
3291 listMeteors1.append(meteorAux)
3291 listMeteors1.append(meteorAux)
3292 return listMeteors1
3292 return listMeteors1
3293
3293
3294 def __setNewArrays(self, listMeteors, date, heiRang):
3294 def __setNewArrays(self, listMeteors, date, heiRang):
3295
3295
3296 #New arrays
3296 #New arrays
3297 arrayMeteors = numpy.array(listMeteors)
3297 arrayMeteors = numpy.array(listMeteors)
3298 arrayParameters = numpy.zeros((len(listMeteors), 13))
3298 arrayParameters = numpy.zeros((len(listMeteors), 13))
3299
3299
3300 #Date inclusion
3300 #Date inclusion
3301 # date = re.findall(r'\((.*?)\)', date)
3301 # date = re.findall(r'\((.*?)\)', date)
3302 # date = date[0].split(',')
3302 # date = date[0].split(',')
3303 # date = map(int, date)
3303 # date = map(int, date)
3304 #
3304 #
3305 # if len(date)<6:
3305 # if len(date)<6:
3306 # date.append(0)
3306 # date.append(0)
3307 #
3307 #
3308 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3308 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3309 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3309 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3310 arrayDate = numpy.tile(date, (len(listMeteors)))
3310 arrayDate = numpy.tile(date, (len(listMeteors)))
3311
3311
3312 #Meteor array
3312 #Meteor array
3313 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3313 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3314 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3314 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3315
3315
3316 #Parameters Array
3316 #Parameters Array
3317 arrayParameters[:,0] = arrayDate #Date
3317 arrayParameters[:,0] = arrayDate #Date
3318 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3318 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3319 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3319 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3320 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3320 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3321 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3321 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3322
3322
3323
3323
3324 return arrayParameters
3324 return arrayParameters
3325
3325
3326 class CorrectSMPhases(Operation):
3326 class CorrectSMPhases(Operation):
3327
3327
3328 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3328 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3329
3329
3330 arrayParameters = dataOut.data_param
3330 arrayParameters = dataOut.data_param
3331 pairsList = []
3331 pairsList = []
3332 pairx = (0,1)
3332 pairx = (0,1)
3333 pairy = (2,3)
3333 pairy = (2,3)
3334 pairsList.append(pairx)
3334 pairsList.append(pairx)
3335 pairsList.append(pairy)
3335 pairsList.append(pairy)
3336 jph = numpy.zeros(4)
3336 jph = numpy.zeros(4)
3337
3337
3338 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3338 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3339 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3339 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3340 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3340 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3341
3341
3342 meteorOps = SMOperations()
3342 meteorOps = SMOperations()
3343 if channelPositions is None:
3343 if channelPositions is None:
3344 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3344 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3345 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3345 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3346
3346
3347 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3347 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3348 h = (hmin,hmax)
3348 h = (hmin,hmax)
3349
3349
3350 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3350 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3351
3351
3352 dataOut.data_param = arrayParameters
3352 dataOut.data_param = arrayParameters
3353 return
3353 return
3354
3354
3355 class SMPhaseCalibration(Operation):
3355 class SMPhaseCalibration(Operation):
3356
3356
3357 __buffer = None
3357 __buffer = None
3358
3358
3359 __initime = None
3359 __initime = None
3360
3360
3361 __dataReady = False
3361 __dataReady = False
3362
3362
3363 __isConfig = False
3363 __isConfig = False
3364
3364
3365 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3365 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3366
3366
3367 dataTime = currentTime + paramInterval
3367 dataTime = currentTime + paramInterval
3368 deltaTime = dataTime - initTime
3368 deltaTime = dataTime - initTime
3369
3369
3370 if deltaTime >= outputInterval or deltaTime < 0:
3370 if deltaTime >= outputInterval or deltaTime < 0:
3371 return True
3371 return True
3372
3372
3373 return False
3373 return False
3374
3374
3375 def __getGammas(self, pairs, d, phases):
3375 def __getGammas(self, pairs, d, phases):
3376 gammas = numpy.zeros(2)
3376 gammas = numpy.zeros(2)
3377
3377
3378 for i in range(len(pairs)):
3378 for i in range(len(pairs)):
3379
3379
3380 pairi = pairs[i]
3380 pairi = pairs[i]
3381
3381
3382 phip3 = phases[:,pairi[0]]
3382 phip3 = phases[:,pairi[0]]
3383 d3 = d[pairi[0]]
3383 d3 = d[pairi[0]]
3384 phip2 = phases[:,pairi[1]]
3384 phip2 = phases[:,pairi[1]]
3385 d2 = d[pairi[1]]
3385 d2 = d[pairi[1]]
3386 #Calculating gamma
3386 #Calculating gamma
3387 # jdcos = alp1/(k*d1)
3387 # jdcos = alp1/(k*d1)
3388 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3388 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3389 jgamma = -phip2*d3/d2 - phip3
3389 jgamma = -phip2*d3/d2 - phip3
3390 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3390 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3391 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3391 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3392 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3392 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3393
3393
3394 #Revised distribution
3394 #Revised distribution
3395 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3395 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3396
3396
3397 #Histogram
3397 #Histogram
3398 nBins = 64
3398 nBins = 64
3399 rmin = -0.5*numpy.pi
3399 rmin = -0.5*numpy.pi
3400 rmax = 0.5*numpy.pi
3400 rmax = 0.5*numpy.pi
3401 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3401 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3402
3402
3403 meteorsY = phaseHisto[0]
3403 meteorsY = phaseHisto[0]
3404 phasesX = phaseHisto[1][:-1]
3404 phasesX = phaseHisto[1][:-1]
3405 width = phasesX[1] - phasesX[0]
3405 width = phasesX[1] - phasesX[0]
3406 phasesX += width/2
3406 phasesX += width/2
3407
3407
3408 #Gaussian aproximation
3408 #Gaussian aproximation
3409 bpeak = meteorsY.argmax()
3409 bpeak = meteorsY.argmax()
3410 peak = meteorsY.max()
3410 peak = meteorsY.max()
3411 jmin = bpeak - 5
3411 jmin = bpeak - 5
3412 jmax = bpeak + 5 + 1
3412 jmax = bpeak + 5 + 1
3413
3413
3414 if jmin<0:
3414 if jmin<0:
3415 jmin = 0
3415 jmin = 0
3416 jmax = 6
3416 jmax = 6
3417 elif jmax > meteorsY.size:
3417 elif jmax > meteorsY.size:
3418 jmin = meteorsY.size - 6
3418 jmin = meteorsY.size - 6
3419 jmax = meteorsY.size
3419 jmax = meteorsY.size
3420
3420
3421 x0 = numpy.array([peak,bpeak,50])
3421 x0 = numpy.array([peak,bpeak,50])
3422 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3422 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3423
3423
3424 #Gammas
3424 #Gammas
3425 gammas[i] = coeff[0][1]
3425 gammas[i] = coeff[0][1]
3426
3426
3427 return gammas
3427 return gammas
3428
3428
3429 def __residualFunction(self, coeffs, y, t):
3429 def __residualFunction(self, coeffs, y, t):
3430
3430
3431 return y - self.__gauss_function(t, coeffs)
3431 return y - self.__gauss_function(t, coeffs)
3432
3432
3433 def __gauss_function(self, t, coeffs):
3433 def __gauss_function(self, t, coeffs):
3434
3434
3435 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3435 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3436
3436
3437 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3437 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3438 meteorOps = SMOperations()
3438 meteorOps = SMOperations()
3439 nchan = 4
3439 nchan = 4
3440 pairx = pairsList[0] #x es 0
3440 pairx = pairsList[0] #x es 0
3441 pairy = pairsList[1] #y es 1
3441 pairy = pairsList[1] #y es 1
3442 center_xangle = 0
3442 center_xangle = 0
3443 center_yangle = 0
3443 center_yangle = 0
3444 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3444 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3445 ntimes = len(range_angle)
3445 ntimes = len(range_angle)
3446
3446
3447 nstepsx = 20
3447 nstepsx = 20
3448 nstepsy = 20
3448 nstepsy = 20
3449
3449
3450 for iz in range(ntimes):
3450 for iz in range(ntimes):
3451 min_xangle = -range_angle[iz]/2 + center_xangle
3451 min_xangle = -range_angle[iz]/2 + center_xangle
3452 max_xangle = range_angle[iz]/2 + center_xangle
3452 max_xangle = range_angle[iz]/2 + center_xangle
3453 min_yangle = -range_angle[iz]/2 + center_yangle
3453 min_yangle = -range_angle[iz]/2 + center_yangle
3454 max_yangle = range_angle[iz]/2 + center_yangle
3454 max_yangle = range_angle[iz]/2 + center_yangle
3455
3455
3456 inc_x = (max_xangle-min_xangle)/nstepsx
3456 inc_x = (max_xangle-min_xangle)/nstepsx
3457 inc_y = (max_yangle-min_yangle)/nstepsy
3457 inc_y = (max_yangle-min_yangle)/nstepsy
3458
3458
3459 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3459 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3460 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3460 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3461 penalty = numpy.zeros((nstepsx,nstepsy))
3461 penalty = numpy.zeros((nstepsx,nstepsy))
3462 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3462 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3463 jph = numpy.zeros(nchan)
3463 jph = numpy.zeros(nchan)
3464
3464
3465 # Iterations looking for the offset
3465 # Iterations looking for the offset
3466 for iy in range(int(nstepsy)):
3466 for iy in range(int(nstepsy)):
3467 for ix in range(int(nstepsx)):
3467 for ix in range(int(nstepsx)):
3468 d3 = d[pairsList[1][0]]
3468 d3 = d[pairsList[1][0]]
3469 d2 = d[pairsList[1][1]]
3469 d2 = d[pairsList[1][1]]
3470 d5 = d[pairsList[0][0]]
3470 d5 = d[pairsList[0][0]]
3471 d4 = d[pairsList[0][1]]
3471 d4 = d[pairsList[0][1]]
3472
3472
3473 alp2 = alpha_y[iy] #gamma 1
3473 alp2 = alpha_y[iy] #gamma 1
3474 alp4 = alpha_x[ix] #gamma 0
3474 alp4 = alpha_x[ix] #gamma 0
3475
3475
3476 alp3 = -alp2*d3/d2 - gammas[1]
3476 alp3 = -alp2*d3/d2 - gammas[1]
3477 alp5 = -alp4*d5/d4 - gammas[0]
3477 alp5 = -alp4*d5/d4 - gammas[0]
3478 # jph[pairy[1]] = alpha_y[iy]
3478 # jph[pairy[1]] = alpha_y[iy]
3479 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3479 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3480
3480
3481 # jph[pairx[1]] = alpha_x[ix]
3481 # jph[pairx[1]] = alpha_x[ix]
3482 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3482 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3483 jph[pairsList[0][1]] = alp4
3483 jph[pairsList[0][1]] = alp4
3484 jph[pairsList[0][0]] = alp5
3484 jph[pairsList[0][0]] = alp5
3485 jph[pairsList[1][0]] = alp3
3485 jph[pairsList[1][0]] = alp3
3486 jph[pairsList[1][1]] = alp2
3486 jph[pairsList[1][1]] = alp2
3487 jph_array[:,ix,iy] = jph
3487 jph_array[:,ix,iy] = jph
3488 # d = [2.0,2.5,2.5,2.0]
3488 # d = [2.0,2.5,2.5,2.0]
3489 #falta chequear si va a leer bien los meteoros
3489 #falta chequear si va a leer bien los meteoros
3490 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3490 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3491 error = meteorsArray1[:,-1]
3491 error = meteorsArray1[:,-1]
3492 ind1 = numpy.where(error==0)[0]
3492 ind1 = numpy.where(error==0)[0]
3493 penalty[ix,iy] = ind1.size
3493 penalty[ix,iy] = ind1.size
3494
3494
3495 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3495 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3496 phOffset = jph_array[:,i,j]
3496 phOffset = jph_array[:,i,j]
3497
3497
3498 center_xangle = phOffset[pairx[1]]
3498 center_xangle = phOffset[pairx[1]]
3499 center_yangle = phOffset[pairy[1]]
3499 center_yangle = phOffset[pairy[1]]
3500
3500
3501 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3501 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3502 phOffset = phOffset*180/numpy.pi
3502 phOffset = phOffset*180/numpy.pi
3503 return phOffset
3503 return phOffset
3504
3504
3505
3505
3506 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3506 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3507
3507
3508 dataOut.flagNoData = True
3508 dataOut.flagNoData = True
3509 self.__dataReady = False
3509 self.__dataReady = False
3510 dataOut.outputInterval = nHours*3600
3510 dataOut.outputInterval = nHours*3600
3511
3511
3512 if self.__isConfig == False:
3512 if self.__isConfig == False:
3513 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3513 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3514 #Get Initial LTC time
3514 #Get Initial LTC time
3515 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3515 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3516 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3516 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3517
3517
3518 self.__isConfig = True
3518 self.__isConfig = True
3519
3519
3520 if self.__buffer is None:
3520 if self.__buffer is None:
3521 self.__buffer = dataOut.data_param.copy()
3521 self.__buffer = dataOut.data_param.copy()
3522
3522
3523 else:
3523 else:
3524 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3524 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3525
3525
3526 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3526 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3527
3527
3528 if self.__dataReady:
3528 if self.__dataReady:
3529 dataOut.utctimeInit = self.__initime
3529 dataOut.utctimeInit = self.__initime
3530 self.__initime += dataOut.outputInterval #to erase time offset
3530 self.__initime += dataOut.outputInterval #to erase time offset
3531
3531
3532 freq = dataOut.frequency
3532 freq = dataOut.frequency
3533 c = dataOut.C #m/s
3533 c = dataOut.C #m/s
3534 lamb = c/freq
3534 lamb = c/freq
3535 k = 2*numpy.pi/lamb
3535 k = 2*numpy.pi/lamb
3536 azimuth = 0
3536 azimuth = 0
3537 h = (hmin, hmax)
3537 h = (hmin, hmax)
3538 # pairs = ((0,1),(2,3)) #Estrella
3538 # pairs = ((0,1),(2,3)) #Estrella
3539 # pairs = ((1,0),(2,3)) #T
3539 # pairs = ((1,0),(2,3)) #T
3540
3540
3541 if channelPositions is None:
3541 if channelPositions is None:
3542 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3542 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3543 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3543 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3544 meteorOps = SMOperations()
3544 meteorOps = SMOperations()
3545 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3545 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3546
3546
3547 #Checking correct order of pairs
3547 #Checking correct order of pairs
3548 pairs = []
3548 pairs = []
3549 if distances[1] > distances[0]:
3549 if distances[1] > distances[0]:
3550 pairs.append((1,0))
3550 pairs.append((1,0))
3551 else:
3551 else:
3552 pairs.append((0,1))
3552 pairs.append((0,1))
3553
3553
3554 if distances[3] > distances[2]:
3554 if distances[3] > distances[2]:
3555 pairs.append((3,2))
3555 pairs.append((3,2))
3556 else:
3556 else:
3557 pairs.append((2,3))
3557 pairs.append((2,3))
3558 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3558 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3559
3559
3560 meteorsArray = self.__buffer
3560 meteorsArray = self.__buffer
3561 error = meteorsArray[:,-1]
3561 error = meteorsArray[:,-1]
3562 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3562 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3563 ind1 = numpy.where(boolError)[0]
3563 ind1 = numpy.where(boolError)[0]
3564 meteorsArray = meteorsArray[ind1,:]
3564 meteorsArray = meteorsArray[ind1,:]
3565 meteorsArray[:,-1] = 0
3565 meteorsArray[:,-1] = 0
3566 phases = meteorsArray[:,8:12]
3566 phases = meteorsArray[:,8:12]
3567
3567
3568 #Calculate Gammas
3568 #Calculate Gammas
3569 gammas = self.__getGammas(pairs, distances, phases)
3569 gammas = self.__getGammas(pairs, distances, phases)
3570 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3570 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3571 #Calculate Phases
3571 #Calculate Phases
3572 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3572 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3573 phasesOff = phasesOff.reshape((1,phasesOff.size))
3573 phasesOff = phasesOff.reshape((1,phasesOff.size))
3574 dataOut.data_output = -phasesOff
3574 dataOut.data_output = -phasesOff
3575 dataOut.flagNoData = False
3575 dataOut.flagNoData = False
3576 self.__buffer = None
3576 self.__buffer = None
3577
3577
3578
3578
3579 return
3579 return
3580
3580
3581 class SMOperations():
3581 class SMOperations():
3582
3582
3583 def __init__(self):
3583 def __init__(self):
3584
3584
3585 return
3585 return
3586
3586
3587 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3587 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3588
3588
3589 arrayParameters = arrayParameters0.copy()
3589 arrayParameters = arrayParameters0.copy()
3590 hmin = h[0]
3590 hmin = h[0]
3591 hmax = h[1]
3591 hmax = h[1]
3592
3592
3593 #Calculate AOA (Error N 3, 4)
3593 #Calculate AOA (Error N 3, 4)
3594 #JONES ET AL. 1998
3594 #JONES ET AL. 1998
3595 AOAthresh = numpy.pi/8
3595 AOAthresh = numpy.pi/8
3596 error = arrayParameters[:,-1]
3596 error = arrayParameters[:,-1]
3597 phases = -arrayParameters[:,8:12] + jph
3597 phases = -arrayParameters[:,8:12] + jph
3598 # phases = numpy.unwrap(phases)
3598 # phases = numpy.unwrap(phases)
3599 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3599 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3600
3600
3601 #Calculate Heights (Error N 13 and 14)
3601 #Calculate Heights (Error N 13 and 14)
3602 error = arrayParameters[:,-1]
3602 error = arrayParameters[:,-1]
3603 Ranges = arrayParameters[:,1]
3603 Ranges = arrayParameters[:,1]
3604 zenith = arrayParameters[:,4]
3604 zenith = arrayParameters[:,4]
3605 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3605 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3606
3606
3607 #----------------------- Get Final data ------------------------------------
3607 #----------------------- Get Final data ------------------------------------
3608 # error = arrayParameters[:,-1]
3608 # error = arrayParameters[:,-1]
3609 # ind1 = numpy.where(error==0)[0]
3609 # ind1 = numpy.where(error==0)[0]
3610 # arrayParameters = arrayParameters[ind1,:]
3610 # arrayParameters = arrayParameters[ind1,:]
3611
3611
3612 return arrayParameters
3612 return arrayParameters
3613
3613
3614 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3614 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3615
3615
3616 arrayAOA = numpy.zeros((phases.shape[0],3))
3616 arrayAOA = numpy.zeros((phases.shape[0],3))
3617 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3617 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3618
3618
3619 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3619 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3620 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3620 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3621 arrayAOA[:,2] = cosDirError
3621 arrayAOA[:,2] = cosDirError
3622
3622
3623 azimuthAngle = arrayAOA[:,0]
3623 azimuthAngle = arrayAOA[:,0]
3624 zenithAngle = arrayAOA[:,1]
3624 zenithAngle = arrayAOA[:,1]
3625
3625
3626 #Setting Error
3626 #Setting Error
3627 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3627 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3628 error[indError] = 0
3628 error[indError] = 0
3629 #Number 3: AOA not fesible
3629 #Number 3: AOA not fesible
3630 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3630 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3631 error[indInvalid] = 3
3631 error[indInvalid] = 3
3632 #Number 4: Large difference in AOAs obtained from different antenna baselines
3632 #Number 4: Large difference in AOAs obtained from different antenna baselines
3633 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3633 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3634 error[indInvalid] = 4
3634 error[indInvalid] = 4
3635 return arrayAOA, error
3635 return arrayAOA, error
3636
3636
3637 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3637 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3638
3638
3639 #Initializing some variables
3639 #Initializing some variables
3640 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3640 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3641 ang_aux = ang_aux.reshape(1,ang_aux.size)
3641 ang_aux = ang_aux.reshape(1,ang_aux.size)
3642
3642
3643 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3643 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3644 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3644 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3645
3645
3646
3646
3647 for i in range(2):
3647 for i in range(2):
3648 ph0 = arrayPhase[:,pairsList[i][0]]
3648 ph0 = arrayPhase[:,pairsList[i][0]]
3649 ph1 = arrayPhase[:,pairsList[i][1]]
3649 ph1 = arrayPhase[:,pairsList[i][1]]
3650 d0 = distances[pairsList[i][0]]
3650 d0 = distances[pairsList[i][0]]
3651 d1 = distances[pairsList[i][1]]
3651 d1 = distances[pairsList[i][1]]
3652
3652
3653 ph0_aux = ph0 + ph1
3653 ph0_aux = ph0 + ph1
3654 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3654 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3655 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3655 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3656 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3656 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3657 #First Estimation
3657 #First Estimation
3658 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3658 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3659
3659
3660 #Most-Accurate Second Estimation
3660 #Most-Accurate Second Estimation
3661 phi1_aux = ph0 - ph1
3661 phi1_aux = ph0 - ph1
3662 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3662 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3663 #Direction Cosine 1
3663 #Direction Cosine 1
3664 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3664 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3665
3665
3666 #Searching the correct Direction Cosine
3666 #Searching the correct Direction Cosine
3667 cosdir0_aux = cosdir0[:,i]
3667 cosdir0_aux = cosdir0[:,i]
3668 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3668 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3669 #Minimum Distance
3669 #Minimum Distance
3670 cosDiff = (cosdir1 - cosdir0_aux)**2
3670 cosDiff = (cosdir1 - cosdir0_aux)**2
3671 indcos = cosDiff.argmin(axis = 1)
3671 indcos = cosDiff.argmin(axis = 1)
3672 #Saving Value obtained
3672 #Saving Value obtained
3673 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3673 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3674
3674
3675 return cosdir0, cosdir
3675 return cosdir0, cosdir
3676
3676
3677 def __calculateAOA(self, cosdir, azimuth):
3677 def __calculateAOA(self, cosdir, azimuth):
3678 cosdirX = cosdir[:,0]
3678 cosdirX = cosdir[:,0]
3679 cosdirY = cosdir[:,1]
3679 cosdirY = cosdir[:,1]
3680
3680
3681 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3681 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3682 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3682 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3683 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3683 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3684
3684
3685 return angles
3685 return angles
3686
3686
3687 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3687 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3688
3688
3689 Ramb = 375 #Ramb = c/(2*PRF)
3689 Ramb = 375 #Ramb = c/(2*PRF)
3690 Re = 6371 #Earth Radius
3690 Re = 6371 #Earth Radius
3691 heights = numpy.zeros(Ranges.shape)
3691 heights = numpy.zeros(Ranges.shape)
3692
3692
3693 R_aux = numpy.array([0,1,2])*Ramb
3693 R_aux = numpy.array([0,1,2])*Ramb
3694 R_aux = R_aux.reshape(1,R_aux.size)
3694 R_aux = R_aux.reshape(1,R_aux.size)
3695
3695
3696 Ranges = Ranges.reshape(Ranges.size,1)
3696 Ranges = Ranges.reshape(Ranges.size,1)
3697
3697
3698 Ri = Ranges + R_aux
3698 Ri = Ranges + R_aux
3699 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3699 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3700
3700
3701 #Check if there is a height between 70 and 110 km
3701 #Check if there is a height between 70 and 110 km
3702 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3702 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3703 ind_h = numpy.where(h_bool == 1)[0]
3703 ind_h = numpy.where(h_bool == 1)[0]
3704
3704
3705 hCorr = hi[ind_h, :]
3705 hCorr = hi[ind_h, :]
3706 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3706 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3707
3707
3708 hCorr = hi[ind_hCorr][:len(ind_h)]
3708 hCorr = hi[ind_hCorr][:len(ind_h)]
3709 heights[ind_h] = hCorr
3709 heights[ind_h] = hCorr
3710
3710
3711 #Setting Error
3711 #Setting Error
3712 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3712 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3713 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3713 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3714 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3714 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3715 error[indError] = 0
3715 error[indError] = 0
3716 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3716 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3717 error[indInvalid2] = 14
3717 error[indInvalid2] = 14
3718 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3718 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3719 error[indInvalid1] = 13
3719 error[indInvalid1] = 13
3720
3720
3721 return heights, error
3721 return heights, error
3722
3722
3723 def getPhasePairs(self, channelPositions):
3723 def getPhasePairs(self, channelPositions):
3724 chanPos = numpy.array(channelPositions)
3724 chanPos = numpy.array(channelPositions)
3725 listOper = list(itertools.combinations(list(range(5)),2))
3725 listOper = list(itertools.combinations(list(range(5)),2))
3726
3726
3727 distances = numpy.zeros(4)
3727 distances = numpy.zeros(4)
3728 axisX = []
3728 axisX = []
3729 axisY = []
3729 axisY = []
3730 distX = numpy.zeros(3)
3730 distX = numpy.zeros(3)
3731 distY = numpy.zeros(3)
3731 distY = numpy.zeros(3)
3732 ix = 0
3732 ix = 0
3733 iy = 0
3733 iy = 0
3734
3734
3735 pairX = numpy.zeros((2,2))
3735 pairX = numpy.zeros((2,2))
3736 pairY = numpy.zeros((2,2))
3736 pairY = numpy.zeros((2,2))
3737
3737
3738 for i in range(len(listOper)):
3738 for i in range(len(listOper)):
3739 pairi = listOper[i]
3739 pairi = listOper[i]
3740
3740
3741 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3741 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3742
3742
3743 if posDif[0] == 0:
3743 if posDif[0] == 0:
3744 axisY.append(pairi)
3744 axisY.append(pairi)
3745 distY[iy] = posDif[1]
3745 distY[iy] = posDif[1]
3746 iy += 1
3746 iy += 1
3747 elif posDif[1] == 0:
3747 elif posDif[1] == 0:
3748 axisX.append(pairi)
3748 axisX.append(pairi)
3749 distX[ix] = posDif[0]
3749 distX[ix] = posDif[0]
3750 ix += 1
3750 ix += 1
3751
3751
3752 for i in range(2):
3752 for i in range(2):
3753 if i==0:
3753 if i==0:
3754 dist0 = distX
3754 dist0 = distX
3755 axis0 = axisX
3755 axis0 = axisX
3756 else:
3756 else:
3757 dist0 = distY
3757 dist0 = distY
3758 axis0 = axisY
3758 axis0 = axisY
3759
3759
3760 side = numpy.argsort(dist0)[:-1]
3760 side = numpy.argsort(dist0)[:-1]
3761 axis0 = numpy.array(axis0)[side,:]
3761 axis0 = numpy.array(axis0)[side,:]
3762 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3762 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3763 axis1 = numpy.unique(numpy.reshape(axis0,4))
3763 axis1 = numpy.unique(numpy.reshape(axis0,4))
3764 side = axis1[axis1 != chanC]
3764 side = axis1[axis1 != chanC]
3765 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3765 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3766 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3766 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3767 if diff1<0:
3767 if diff1<0:
3768 chan2 = side[0]
3768 chan2 = side[0]
3769 d2 = numpy.abs(diff1)
3769 d2 = numpy.abs(diff1)
3770 chan1 = side[1]
3770 chan1 = side[1]
3771 d1 = numpy.abs(diff2)
3771 d1 = numpy.abs(diff2)
3772 else:
3772 else:
3773 chan2 = side[1]
3773 chan2 = side[1]
3774 d2 = numpy.abs(diff2)
3774 d2 = numpy.abs(diff2)
3775 chan1 = side[0]
3775 chan1 = side[0]
3776 d1 = numpy.abs(diff1)
3776 d1 = numpy.abs(diff1)
3777
3777
3778 if i==0:
3778 if i==0:
3779 chanCX = chanC
3779 chanCX = chanC
3780 chan1X = chan1
3780 chan1X = chan1
3781 chan2X = chan2
3781 chan2X = chan2
3782 distances[0:2] = numpy.array([d1,d2])
3782 distances[0:2] = numpy.array([d1,d2])
3783 else:
3783 else:
3784 chanCY = chanC
3784 chanCY = chanC
3785 chan1Y = chan1
3785 chan1Y = chan1
3786 chan2Y = chan2
3786 chan2Y = chan2
3787 distances[2:4] = numpy.array([d1,d2])
3787 distances[2:4] = numpy.array([d1,d2])
3788 # axisXsides = numpy.reshape(axisX[ix,:],4)
3788 # axisXsides = numpy.reshape(axisX[ix,:],4)
3789 #
3789 #
3790 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3790 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3791 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3791 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3792 #
3792 #
3793 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3793 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3794 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3794 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3795 # channel25X = int(pairX[0,ind25X])
3795 # channel25X = int(pairX[0,ind25X])
3796 # channel20X = int(pairX[1,ind20X])
3796 # channel20X = int(pairX[1,ind20X])
3797 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3797 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3798 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3798 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3799 # channel25Y = int(pairY[0,ind25Y])
3799 # channel25Y = int(pairY[0,ind25Y])
3800 # channel20Y = int(pairY[1,ind20Y])
3800 # channel20Y = int(pairY[1,ind20Y])
3801
3801
3802 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3802 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3803 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3803 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3804
3804
3805 return pairslist, distances
3805 return pairslist, distances
3806 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3806 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3807 #
3807 #
3808 # arrayAOA = numpy.zeros((phases.shape[0],3))
3808 # arrayAOA = numpy.zeros((phases.shape[0],3))
3809 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3809 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3810 #
3810 #
3811 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3811 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3812 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3812 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3813 # arrayAOA[:,2] = cosDirError
3813 # arrayAOA[:,2] = cosDirError
3814 #
3814 #
3815 # azimuthAngle = arrayAOA[:,0]
3815 # azimuthAngle = arrayAOA[:,0]
3816 # zenithAngle = arrayAOA[:,1]
3816 # zenithAngle = arrayAOA[:,1]
3817 #
3817 #
3818 # #Setting Error
3818 # #Setting Error
3819 # #Number 3: AOA not fesible
3819 # #Number 3: AOA not fesible
3820 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3820 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3821 # error[indInvalid] = 3
3821 # error[indInvalid] = 3
3822 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3822 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3823 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3823 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3824 # error[indInvalid] = 4
3824 # error[indInvalid] = 4
3825 # return arrayAOA, error
3825 # return arrayAOA, error
3826 #
3826 #
3827 # def __getDirectionCosines(self, arrayPhase, pairsList):
3827 # def __getDirectionCosines(self, arrayPhase, pairsList):
3828 #
3828 #
3829 # #Initializing some variables
3829 # #Initializing some variables
3830 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3830 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3831 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3831 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3832 #
3832 #
3833 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3833 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3834 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3834 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3835 #
3835 #
3836 #
3836 #
3837 # for i in range(2):
3837 # for i in range(2):
3838 # #First Estimation
3838 # #First Estimation
3839 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3839 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3840 # #Dealias
3840 # #Dealias
3841 # indcsi = numpy.where(phi0_aux > numpy.pi)
3841 # indcsi = numpy.where(phi0_aux > numpy.pi)
3842 # phi0_aux[indcsi] -= 2*numpy.pi
3842 # phi0_aux[indcsi] -= 2*numpy.pi
3843 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3843 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3844 # phi0_aux[indcsi] += 2*numpy.pi
3844 # phi0_aux[indcsi] += 2*numpy.pi
3845 # #Direction Cosine 0
3845 # #Direction Cosine 0
3846 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3846 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3847 #
3847 #
3848 # #Most-Accurate Second Estimation
3848 # #Most-Accurate Second Estimation
3849 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3849 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3850 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3850 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3851 # #Direction Cosine 1
3851 # #Direction Cosine 1
3852 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3852 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3853 #
3853 #
3854 # #Searching the correct Direction Cosine
3854 # #Searching the correct Direction Cosine
3855 # cosdir0_aux = cosdir0[:,i]
3855 # cosdir0_aux = cosdir0[:,i]
3856 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3856 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3857 # #Minimum Distance
3857 # #Minimum Distance
3858 # cosDiff = (cosdir1 - cosdir0_aux)**2
3858 # cosDiff = (cosdir1 - cosdir0_aux)**2
3859 # indcos = cosDiff.argmin(axis = 1)
3859 # indcos = cosDiff.argmin(axis = 1)
3860 # #Saving Value obtained
3860 # #Saving Value obtained
3861 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3861 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3862 #
3862 #
3863 # return cosdir0, cosdir
3863 # return cosdir0, cosdir
3864 #
3864 #
3865 # def __calculateAOA(self, cosdir, azimuth):
3865 # def __calculateAOA(self, cosdir, azimuth):
3866 # cosdirX = cosdir[:,0]
3866 # cosdirX = cosdir[:,0]
3867 # cosdirY = cosdir[:,1]
3867 # cosdirY = cosdir[:,1]
3868 #
3868 #
3869 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3869 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3870 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3870 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3871 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3871 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3872 #
3872 #
3873 # return angles
3873 # return angles
3874 #
3874 #
3875 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3875 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3876 #
3876 #
3877 # Ramb = 375 #Ramb = c/(2*PRF)
3877 # Ramb = 375 #Ramb = c/(2*PRF)
3878 # Re = 6371 #Earth Radius
3878 # Re = 6371 #Earth Radius
3879 # heights = numpy.zeros(Ranges.shape)
3879 # heights = numpy.zeros(Ranges.shape)
3880 #
3880 #
3881 # R_aux = numpy.array([0,1,2])*Ramb
3881 # R_aux = numpy.array([0,1,2])*Ramb
3882 # R_aux = R_aux.reshape(1,R_aux.size)
3882 # R_aux = R_aux.reshape(1,R_aux.size)
3883 #
3883 #
3884 # Ranges = Ranges.reshape(Ranges.size,1)
3884 # Ranges = Ranges.reshape(Ranges.size,1)
3885 #
3885 #
3886 # Ri = Ranges + R_aux
3886 # Ri = Ranges + R_aux
3887 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3887 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3888 #
3888 #
3889 # #Check if there is a height between 70 and 110 km
3889 # #Check if there is a height between 70 and 110 km
3890 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3890 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3891 # ind_h = numpy.where(h_bool == 1)[0]
3891 # ind_h = numpy.where(h_bool == 1)[0]
3892 #
3892 #
3893 # hCorr = hi[ind_h, :]
3893 # hCorr = hi[ind_h, :]
3894 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3894 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3895 #
3895 #
3896 # hCorr = hi[ind_hCorr]
3896 # hCorr = hi[ind_hCorr]
3897 # heights[ind_h] = hCorr
3897 # heights[ind_h] = hCorr
3898 #
3898 #
3899 # #Setting Error
3899 # #Setting Error
3900 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3900 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3901 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3901 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3902 #
3902 #
3903 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3903 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3904 # error[indInvalid2] = 14
3904 # error[indInvalid2] = 14
3905 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3905 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3906 # error[indInvalid1] = 13
3906 # error[indInvalid1] = 13
3907 #
3907 #
3908 # return heights, error
3908 # return heights, error
3909
3909
3910
3910
3911 class WeatherRadar(Operation):
3911 class WeatherRadar(Operation):
3912 '''
3912 '''
3913 Function tat implements Weather Radar operations-
3913 Function tat implements Weather Radar operations-
3914 Input:
3914 Input:
3915 Output:
3915 Output:
3916 Parameters affected:
3916 Parameters affected:
3917 '''
3917 '''
3918 isConfig = False
3918 isConfig = False
3919 variableList = None
3919 variableList = None
3920
3920
3921 def __init__(self):
3921 def __init__(self):
3922 Operation.__init__(self)
3922 Operation.__init__(self)
3923
3923
3924 def setup(self,dataOut,variableList= None,Pt=0,Gt=0,Gr=0,lambda_=0, aL=0,
3924 def setup(self,dataOut,variableList= None,Pt=0,Gt=0,Gr=0,lambda_=0, aL=0,
3925 tauW= 0,thetaT=0,thetaR=0,Km =0):
3925 tauW= 0,thetaT=0,thetaR=0,Km =0):
3926 self.nCh = dataOut.nChannels
3926 self.nCh = dataOut.nChannels
3927 self.nHeis = dataOut.nHeights
3927 self.nHeis = dataOut.nHeights
3928 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
3928 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
3929 self.Range = numpy.arange(dataOut.nHeights)*deltaHeight + dataOut.heightList[0]
3929 self.Range = numpy.arange(dataOut.nHeights)*deltaHeight + dataOut.heightList[0]
3930 self.Range = self.Range.reshape(1,self.nHeis)
3930 self.Range = self.Range.reshape(1,self.nHeis)
3931 self.Range = numpy.tile(self.Range,[self.nCh,1])
3931 self.Range = numpy.tile(self.Range,[self.nCh,1])
3932 '''-----------1 Constante del Radar----------'''
3932 '''-----------1 Constante del Radar----------'''
3933 self.Pt = Pt
3933 self.Pt = Pt
3934 self.Gt = Gt
3934 self.Gt = Gt
3935 self.Gr = Gr
3935 self.Gr = Gr
3936 self.lambda_ = lambda_
3936 self.lambda_ = lambda_
3937 self.aL = aL
3937 self.aL = aL
3938 self.tauW = tauW
3938 self.tauW = tauW
3939 self.thetaT = thetaT
3939 self.thetaT = thetaT
3940 self.thetaR = thetaR
3940 self.thetaR = thetaR
3941 self.Km = Km
3941 self.Km = Km
3942 Numerator = ((4*numpy.pi)**3 * aL**2 * 16 *numpy.log(2))
3942 Numerator = ((4*numpy.pi)**3 * aL**2 * 16 *numpy.log(2))
3943 Denominator = (Pt * Gt * Gr * lambda_**2 * SPEED_OF_LIGHT * tauW * numpy.pi*thetaT*thetaR)
3943 Denominator = (Pt * Gt * Gr * lambda_**2 * SPEED_OF_LIGHT * tauW * numpy.pi*thetaT*thetaR)
3944 self.RadarConstant = Numerator/Denominator
3944 self.RadarConstant = Numerator/Denominator
3945 self.variableList= variableList
3945 self.variableList= variableList
3946
3946
3947 def setMoments(self,dataOut,i):
3947 def setMoments(self,dataOut,i):
3948
3948
3949 type = dataOut.inputUnit
3949 type = dataOut.inputUnit
3950 nCh = dataOut.nChannels
3950 nCh = dataOut.nChannels
3951 nHeis = dataOut.nHeights
3951 nHeis = dataOut.nHeights
3952 data_param = numpy.zeros((nCh,4,nHeis))
3952 data_param = numpy.zeros((nCh,4,nHeis))
3953 if type == "Voltage":
3953 if type == "Voltage":
3954 factor = dataOut.normFactor
3954 factor = dataOut.normFactor
3955 data_param[:,0,:] = dataOut.dataPP_POW/(factor)
3955 data_param[:,0,:] = dataOut.dataPP_POW/(factor)
3956 data_param[:,1,:] = dataOut.dataPP_DOP
3956 data_param[:,1,:] = dataOut.dataPP_DOP
3957 data_param[:,2,:] = dataOut.dataPP_WIDTH
3957 data_param[:,2,:] = dataOut.dataPP_WIDTH
3958 data_param[:,3,:] = dataOut.dataPP_SNR
3958 data_param[:,3,:] = dataOut.dataPP_SNR
3959 if type == "Spectra":
3959 if type == "Spectra":
3960 data_param[:,0,:] = dataOut.data_POW
3960 data_param[:,0,:] = dataOut.data_POW
3961 data_param[:,1,:] = dataOut.data_DOP
3961 data_param[:,1,:] = dataOut.data_DOP
3962 data_param[:,2,:] = dataOut.data_WIDTH
3962 data_param[:,2,:] = dataOut.data_WIDTH
3963 data_param[:,3,:] = dataOut.data_SNR
3963 data_param[:,3,:] = dataOut.data_SNR
3964
3964
3965 return data_param[:,i,:]
3965 return data_param[:,i,:]
3966
3966
3967 def getCoeficienteCorrelacionROhv_R(self,dataOut):
3967 def getCoeficienteCorrelacionROhv_R(self,dataOut):
3968 type = dataOut.inputUnit
3968 type = dataOut.inputUnit
3969 nHeis = dataOut.nHeights
3969 nHeis = dataOut.nHeights
3970 data_RhoHV_R = numpy.zeros((nHeis))
3970 data_RhoHV_R = numpy.zeros((nHeis))
3971 if type == "Voltage":
3971 if type == "Voltage":
3972 powa = dataOut.dataPP_POWER[0]
3972 powa = dataOut.dataPP_POWER[0]
3973 powb = dataOut.dataPP_POWER[1]
3973 powb = dataOut.dataPP_POWER[1]
3974 ccf = dataOut.dataPP_CCF
3974 ccf = dataOut.dataPP_CCF
3975 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
3975 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
3976 data_RhoHV_R = numpy.abs(avgcoherenceComplex)
3976 data_RhoHV_R = numpy.abs(avgcoherenceComplex)
3977 if type == "Spectra":
3977 if type == "Spectra":
3978 data_RhoHV_R = dataOut.getCoherence()
3978 data_RhoHV_R = dataOut.getCoherence()
3979
3979
3980 return data_RhoHV_R
3980 return data_RhoHV_R
3981
3981
3982 def getFasediferencialPhiD_P(self,dataOut,phase= True):
3982 def getFasediferencialPhiD_P(self,dataOut,phase= True):
3983 type = dataOut.inputUnit
3983 type = dataOut.inputUnit
3984 nHeis = dataOut.nHeights
3984 nHeis = dataOut.nHeights
3985 data_PhiD_P = numpy.zeros((nHeis))
3985 data_PhiD_P = numpy.zeros((nHeis))
3986 if type == "Voltage":
3986 if type == "Voltage":
3987 powa = dataOut.dataPP_POWER[0]
3987 powa = dataOut.dataPP_POWER[0]
3988 powb = dataOut.dataPP_POWER[1]
3988 powb = dataOut.dataPP_POWER[1]
3989 ccf = dataOut.dataPP_CCF
3989 ccf = dataOut.dataPP_CCF
3990 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
3990 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
3991 if phase:
3991 if phase:
3992 data_PhiD_P = numpy.arctan2(avgcoherenceComplex.imag,
3992 data_PhiD_P = numpy.arctan2(avgcoherenceComplex.imag,
3993 avgcoherenceComplex.real) * 180 / numpy.pi
3993 avgcoherenceComplex.real) * 180 / numpy.pi
3994 if type == "Spectra":
3994 if type == "Spectra":
3995 data_PhiD_P = dataOut.getCoherence(phase = phase)
3995 data_PhiD_P = dataOut.getCoherence(phase = phase)
3996
3996
3997 return data_PhiD_P
3997 return data_PhiD_P
3998
3998
3999 def getReflectividad_D(self,dataOut):
3999 def getReflectividad_D(self,dataOut):
4000 '''-----------------------------Potencia de Radar -Signal S-----------------------------'''
4000 '''-----------------------------Potencia de Radar -Signal S-----------------------------'''
4001
4001
4002 Pr = self.setMoments(dataOut,0)
4002 Pr = self.setMoments(dataOut,0)
4003
4003
4004 '''-----------2 Reflectividad del Radar y Factor de Reflectividad------'''
4004 '''-----------2 Reflectividad del Radar y Factor de Reflectividad------'''
4005 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
4005 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
4006 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
4006 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
4007 for R in range(self.nHeis):
4007 for R in range(self.nHeis):
4008 self.n_radar[:,R] = self.RadarConstant*Pr[:,R]* (self.Range[:,R])**2
4008 self.n_radar[:,R] = self.RadarConstant*Pr[:,R]* (self.Range[:,R])**2
4009
4009
4010 self.Z_radar[:,R] = self.n_radar[:,R]* self.lambda_**4/( numpy.pi**5 * self.Km**2)
4010 self.Z_radar[:,R] = self.n_radar[:,R]* self.lambda_**4/( numpy.pi**5 * self.Km**2)
4011
4011
4012 '''----------- Factor de Reflectividad Equivalente lamda_ < 10 cm , lamda_= 3.2cm-------'''
4012 '''----------- Factor de Reflectividad Equivalente lamda_ < 10 cm , lamda_= 3.2cm-------'''
4013 Zeh = self.Z_radar
4013 Zeh = self.Z_radar
4014 dBZeh = 10*numpy.log10(Zeh)
4014 dBZeh = 10*numpy.log10(Zeh)
4015 Zdb_D = dBZeh[0] - dBZeh[1]
4015 Zdb_D = dBZeh[0] - dBZeh[1]
4016 return Zdb_D
4016 return Zdb_D
4017
4017
4018 def getRadialVelocity_V(self,dataOut):
4018 def getRadialVelocity_V(self,dataOut):
4019 velRadial_V = self.setMoments(dataOut,1)
4019 velRadial_V = self.setMoments(dataOut,1)
4020 return velRadial_V
4020 return velRadial_V
4021
4021
4022 def getAnchoEspectral_W(self,dataOut):
4022 def getAnchoEspectral_W(self,dataOut):
4023 Sigmav_W = self.setMoments(dataOut,2)
4023 Sigmav_W = self.setMoments(dataOut,2)
4024 return Sigmav_W
4024 return Sigmav_W
4025
4025
4026
4026
4027 def run(self,dataOut,variableList=None,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
4027 def run(self,dataOut,variableList=None,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
4028 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93):
4028 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93):
4029
4029
4030 if not self.isConfig:
4030 if not self.isConfig:
4031 self.setup(dataOut= dataOut,variableList=None,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
4031 self.setup(dataOut= dataOut,variableList=None,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
4032 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93)
4032 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93)
4033 self.isConfig = True
4033 self.isConfig = True
4034
4034
4035 for i in range(len(self.variableList)):
4035 for i in range(len(self.variableList)):
4036 if self.variableList[i]=='ReflectividadDiferencial':
4036 if self.variableList[i]=='ReflectividadDiferencial':
4037 dataOut.Zdb_D =self.getReflectividad_D(dataOut=dataOut)
4037 dataOut.Zdb_D =self.getReflectividad_D(dataOut=dataOut)
4038 if self.variableList[i]=='FaseDiferencial':
4038 if self.variableList[i]=='FaseDiferencial':
4039 dataOut.PhiD_P =self.getFasediferencialPhiD_P(dataOut=dataOut, phase=True)
4039 dataOut.PhiD_P =self.getFasediferencialPhiD_P(dataOut=dataOut, phase=True)
4040 if self.variableList[i] == "CoeficienteCorrelacion":
4040 if self.variableList[i] == "CoeficienteCorrelacion":
4041 dataOut.RhoHV_R = self.getCoeficienteCorrelacionROhv_R(dataOut)
4041 dataOut.RhoHV_R = self.getCoeficienteCorrelacionROhv_R(dataOut)
4042 if self.variableList[i] =="VelocidadRadial":
4042 if self.variableList[i] =="VelocidadRadial":
4043 dataOut.velRadial_V = self.getRadialVelocity_V(dataOut)
4043 dataOut.velRadial_V = self.getRadialVelocity_V(dataOut)
4044 if self.variableList[i] =="AnchoEspectral":
4044 if self.variableList[i] =="AnchoEspectral":
4045 dataOut.Sigmav_W = self.getAnchoEspectral_W(dataOut)
4045 dataOut.Sigmav_W = self.getAnchoEspectral_W(dataOut)
4046 return dataOut
4046 return dataOut
4047
4047
4048 class PedestalInformation(Operation):
4048 class PedestalInformation(Operation):
4049
4049
4050 def __init__(self):
4050 def __init__(self):
4051 Operation.__init__(self)
4051 Operation.__init__(self)
4052 self.filename = False
4052 self.filename = False
4053 self.delay = 30
4053 self.delay = 30
4054 self.nTries = 3
4054 self.nTries = 3
4055
4055
4056 def find_file(self, timestamp):
4056 def find_file(self, timestamp):
4057
4057
4058 dt = datetime.datetime.utcfromtimestamp(timestamp)
4058 dt = datetime.datetime.utcfromtimestamp(timestamp)
4059 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4059 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4060
4060
4061 if not os.path.exists(path):
4061 if not os.path.exists(path):
4062 return False, False
4062 return False, False
4063 fileList = glob.glob(os.path.join(path, '*.h5'))
4063 fileList = glob.glob(os.path.join(path, '*.h5'))
4064 fileList.sort()
4064 fileList.sort()
4065 return fileList
4065 return fileList
4066
4066
4067 def find_next_file(self):
4067 def find_next_file(self):
4068
4068
4069 while True:
4069 while True:
4070 if self.utctime < self.utcfile:
4070 if self.utctime < self.utcfile:
4071 self.flagNoData = True
4071 self.flagNoData = True
4072 break
4072 break
4073 self.flagNoData = False
4073 self.flagNoData = False
4074 file_size = len(self.fp['Data']['utc'])
4074 file_size = len(self.fp['Data']['utc'])
4075 if self.utctime < self.utcfile+file_size*self.interval:
4075 if self.utctime < self.utcfile+file_size*self.interval:
4076 break
4076 break
4077 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4077 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4078 if dt.second > 0:
4078 if dt.second > 0:
4079 self.utcfile -= dt.second
4079 self.utcfile -= dt.second
4080 self.utcfile += self.samples*self.interval
4080 self.utcfile += self.samples*self.interval
4081 dt = datetime.datetime.utcfromtimestamp(self.utctime)
4081 dt = datetime.datetime.utcfromtimestamp(self.utctime)
4082 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4082 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4083 self.filename = os.path.join(path, 'pos@{}.000.h5'.format(int(self.utcfile)))
4083 self.filename = os.path.join(path, 'pos@{}.000.h5'.format(int(self.utcfile)))
4084
4084
4085 for n in range(self.nTries):
4085 for n in range(self.nTries):
4086 ok = False
4086 ok = False
4087 try:
4087 try:
4088 if not os.path.exists(self.filename):
4088 if not os.path.exists(self.filename):
4089 log.warning('Waiting {}s for position files...'.format(self.delay), self.name)
4089 log.warning('Waiting {}s for position files...'.format(self.delay), self.name)
4090 time.sleep(self.delay)
4090 time.sleep(self.delay)
4091 continue
4091 continue
4092 self.fp.close()
4092 self.fp.close()
4093 self.fp = h5py.File(self.filename, 'r')
4093 self.fp = h5py.File(self.filename, 'r')
4094 log.log('Opening file: {}'.format(self.filename), self.name)
4094 log.log('Opening file: {}'.format(self.filename), self.name)
4095 ok = True
4095 ok = True
4096 break
4096 break
4097 except:
4097 except:
4098 log.warning('Waiting {}s for position file to be ready...'.format(self.delay), self.name)
4098 log.warning('Waiting {}s for position file to be ready...'.format(self.delay), self.name)
4099 time.sleep(self.delay)
4099 time.sleep(self.delay)
4100 continue
4100 continue
4101
4101
4102 if not ok:
4102 if not ok:
4103 log.error('No new position files found in {}'.format(path))
4103 log.error('No new position files found in {}'.format(path))
4104 raise IOError('No new position files found in {}'.format(path))
4104 raise IOError('No new position files found in {}'.format(path))
4105
4105
4106
4106
4107 def get_values(self):
4107 def get_values(self):
4108
4108
4109 if self.flagNoData:
4109 if self.flagNoData:
4110 return numpy.nan, numpy.nan
4110 return numpy.nan, numpy.nan
4111 else:
4111 else:
4112 index = int((self.utctime-self.utcfile)/self.interval)
4112 index = int((self.utctime-self.utcfile)/self.interval)
4113 return self.fp['Data']['azi_pos'][index], self.fp['Data']['ele_pos'][index]
4113 return self.fp['Data']['azi_pos'][index], self.fp['Data']['ele_pos'][index]
4114
4114
4115 def setup(self, dataOut, path, conf, samples, interval, az_offset):
4115 def setup(self, dataOut, path, conf, samples, interval, az_offset):
4116
4116
4117 self.path = path
4117 self.path = path
4118 self.conf = conf
4118 self.conf = conf
4119 self.samples = samples
4119 self.samples = samples
4120 self.interval = interval
4120 self.interval = interval
4121 filelist = self.find_file(dataOut.utctime)
4121 filelist = self.find_file(dataOut.utctime)
4122
4122
4123 if not filelist:
4123 if not filelist:
4124 log.error('No position files found in {}'.format(path), self.name)
4124 log.error('No position files found in {}'.format(path), self.name)
4125 raise IOError('No position files found in {}'.format(path))
4125 raise IOError('No position files found in {}'.format(path))
4126 else:
4126 else:
4127 self.filename = filelist[0]
4127 self.filename = filelist[0]
4128 self.utcfile = int(self.filename.split('/')[-1][4:14])
4128 self.utcfile = int(self.filename.split('/')[-1][4:14])
4129 log.log('Opening file: {}'.format(self.filename), self.name)
4129 log.log('Opening file: {}'.format(self.filename), self.name)
4130 self.fp = h5py.File(self.filename, 'r')
4130 self.fp = h5py.File(self.filename, 'r')
4131
4131
4132 def run(self, dataOut, path, conf=None, samples=1500, interval=0.04, az_offset=0, time_offset=0):
4132 def run(self, dataOut, path, conf=None, samples=1500, interval=0.04, az_offset=0, time_offset=0):
4133
4133
4134 if not self.isConfig:
4134 if not self.isConfig:
4135 self.setup(dataOut, path, conf, samples, interval, az_offset)
4135 self.setup(dataOut, path, conf, samples, interval, az_offset)
4136 self.isConfig = True
4136 self.isConfig = True
4137
4137
4138 self.utctime = dataOut.utctime + time_offset
4138 self.utctime = dataOut.utctime + time_offset
4139
4139
4140 self.find_next_file()
4140 self.find_next_file()
4141
4141
4142 az, el = self.get_values()
4142 az, el = self.get_values()
4143 dataOut.flagNoData = False
4143 dataOut.flagNoData = False
4144
4144
4145 if numpy.isnan(az) or numpy.isnan(el) :
4145 if numpy.isnan(az) or numpy.isnan(el) :
4146 dataOut.flagNoData = True
4146 dataOut.flagNoData = True
4147 return dataOut
4147 return dataOut
4148
4148
4149 dataOut.azimuth = az - az_offset
4149 dataOut.azimuth = az - az_offset
4150 if dataOut.azimuth < 0:
4150 if dataOut.azimuth < 0:
4151 dataOut.azimuth += 360
4151 dataOut.azimuth += 360
4152 dataOut.elevation = el
4152 dataOut.elevation = el
4153
4153
4154 return dataOut
4154 return dataOut
4155
4155
4156 class Block360(Operation):
4156 class Block360(Operation):
4157 '''
4157 '''
4158 '''
4158 '''
4159 isConfig = False
4159 isConfig = False
4160 __profIndex = 0
4160 __profIndex = 0
4161 __initime = None
4161 __initime = None
4162 __lastdatatime = None
4162 __lastdatatime = None
4163 __buffer = None
4163 __buffer = None
4164 __dataReady = False
4164 __dataReady = False
4165 n = None
4165 n = None
4166 __nch = 0
4166 __nch = 0
4167 __nHeis = 0
4167 __nHeis = 0
4168 index = 0
4168 index = 0
4169 mode = 0
4169 mode = 0
4170
4170
4171 def __init__(self,**kwargs):
4171 def __init__(self,**kwargs):
4172 Operation.__init__(self,**kwargs)
4172 Operation.__init__(self,**kwargs)
4173
4173
4174 def setup(self, dataOut, n = None, mode = None):
4174 def setup(self, dataOut, n = None, mode = None):
4175 '''
4175 '''
4176 n= Numero de PRF's de entrada
4176 n= Numero de PRF's de entrada
4177 '''
4177 '''
4178 self.__initime = None
4178 self.__initime = None
4179 self.__lastdatatime = 0
4179 self.__lastdatatime = 0
4180 self.__dataReady = False
4180 self.__dataReady = False
4181 self.__buffer = 0
4181 self.__buffer = 0
4182 self.__buffer_1D = 0
4182 self.__buffer_1D = 0
4183 self.__profIndex = 0
4183 self.__profIndex = 0
4184 self.index = 0
4184 self.index = 0
4185 self.__nch = dataOut.nChannels
4185 self.__nch = dataOut.nChannels
4186 self.__nHeis = dataOut.nHeights
4186 self.__nHeis = dataOut.nHeights
4187 ##print("ELVALOR DE n es:", n)
4187 ##print("ELVALOR DE n es:", n)
4188 if n == None:
4188 if n == None:
4189 raise ValueError("n should be specified.")
4189 raise ValueError("n should be specified.")
4190
4190
4191 if mode == None:
4191 if mode == None:
4192 raise ValueError("mode should be specified.")
4192 raise ValueError("mode should be specified.")
4193
4193
4194 if n != None:
4194 if n != None:
4195 if n<1:
4195 if n<1:
4196 print("n should be greater than 2")
4196 print("n should be greater than 2")
4197 raise ValueError("n should be greater than 2")
4197 raise ValueError("n should be greater than 2")
4198
4198
4199 self.n = n
4199 self.n = n
4200 self.mode = mode
4200 self.mode = mode
4201 #print("self.mode",self.mode)
4201 #print("self.mode",self.mode)
4202 #print("nHeights")
4202 #print("nHeights")
4203 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4203 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4204 self.__buffer2 = numpy.zeros(n)
4204 self.__buffer2 = numpy.zeros(n)
4205 self.__buffer3 = numpy.zeros(n)
4205 self.__buffer3 = numpy.zeros(n)
4206
4206
4207
4207
4208
4208
4209
4209
4210 def putData(self,data,mode):
4210 def putData(self,data,mode):
4211 '''
4211 '''
4212 Add a profile to he __buffer and increase in one the __profiel Index
4212 Add a profile to he __buffer and increase in one the __profiel Index
4213 '''
4213 '''
4214 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4214 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4215 #print("line 4049",data.azimuth.shape,data.azimuth)
4215 #print("line 4049",data.azimuth.shape,data.azimuth)
4216 if self.mode==0:
4216 if self.mode==0:
4217 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4217 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4218 if self.mode==1:
4218 if self.mode==1:
4219 self.__buffer[:,self.__profIndex,:]= data.data_pow
4219 self.__buffer[:,self.__profIndex,:]= data.data_pow
4220 #print("me casi",self.index,data.azimuth[self.index])
4220 #print("me casi",self.index,data.azimuth[self.index])
4221 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4221 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4222 #print("magic",data.profileIndex)
4222 #print("magic",data.profileIndex)
4223 #print(data.azimuth[self.index])
4223 #print(data.azimuth[self.index])
4224 #print("index",self.index)
4224 #print("index",self.index)
4225
4225
4226 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4226 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4227 self.__buffer2[self.__profIndex] = data.azimuth
4227 self.__buffer2[self.__profIndex] = data.azimuth
4228 self.__buffer3[self.__profIndex] = data.elevation
4228 self.__buffer3[self.__profIndex] = data.elevation
4229 #print("q pasa")
4229 #print("q pasa")
4230 #####self.index+=1
4230 #####self.index+=1
4231 #print("index",self.index,data.azimuth[:10])
4231 #print("index",self.index,data.azimuth[:10])
4232 self.__profIndex += 1
4232 self.__profIndex += 1
4233 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4233 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4234
4234
4235 def pushData(self,data):
4235 def pushData(self,data):
4236 '''
4236 '''
4237 Return the PULSEPAIR and the profiles used in the operation
4237 Return the PULSEPAIR and the profiles used in the operation
4238 Affected : self.__profileIndex
4238 Affected : self.__profileIndex
4239 '''
4239 '''
4240 #print("pushData")
4240 #print("pushData")
4241
4241
4242 data_360 = self.__buffer
4242 data_360 = self.__buffer
4243 data_p = self.__buffer2
4243 data_p = self.__buffer2
4244 data_e = self.__buffer3
4244 data_e = self.__buffer3
4245 n = self.__profIndex
4245 n = self.__profIndex
4246
4246
4247 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4247 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4248 self.__buffer2 = numpy.zeros(self.n)
4248 self.__buffer2 = numpy.zeros(self.n)
4249 self.__buffer3 = numpy.zeros(self.n)
4249 self.__buffer3 = numpy.zeros(self.n)
4250 self.__profIndex = 0
4250 self.__profIndex = 0
4251 #print("pushData")
4251 #print("pushData")
4252 return data_360,n,data_p,data_e
4252 return data_360,n,data_p,data_e
4253
4253
4254
4254
4255 def byProfiles(self,dataOut):
4255 def byProfiles(self,dataOut):
4256
4256
4257 self.__dataReady = False
4257 self.__dataReady = False
4258 data_360 = None
4258 data_360 = None
4259 data_p = None
4259 data_p = None
4260 data_e = None
4260 data_e = None
4261 #print("dataOu",dataOut.dataPP_POW)
4261 #print("dataOu",dataOut.dataPP_POW)
4262 self.putData(data=dataOut,mode = self.mode)
4262 self.putData(data=dataOut,mode = self.mode)
4263 ##### print("profIndex",self.__profIndex)
4263 ##### print("profIndex",self.__profIndex)
4264 if self.__profIndex == self.n:
4264 if self.__profIndex == self.n:
4265 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4265 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4266 self.__dataReady = True
4266 self.__dataReady = True
4267
4267
4268 return data_360,data_p,data_e
4268 return data_360,data_p,data_e
4269
4269
4270
4270
4271 def blockOp(self, dataOut, datatime= None):
4271 def blockOp(self, dataOut, datatime= None):
4272 if self.__initime == None:
4272 if self.__initime == None:
4273 self.__initime = datatime
4273 self.__initime = datatime
4274 data_360,data_p,data_e = self.byProfiles(dataOut)
4274 data_360,data_p,data_e = self.byProfiles(dataOut)
4275 self.__lastdatatime = datatime
4275 self.__lastdatatime = datatime
4276
4276
4277 if data_360 is None:
4277 if data_360 is None:
4278 return None, None,None,None
4278 return None, None,None,None
4279
4279
4280
4280
4281 avgdatatime = self.__initime
4281 avgdatatime = self.__initime
4282 if self.n==1:
4282 if self.n==1:
4283 avgdatatime = datatime
4283 avgdatatime = datatime
4284 deltatime = datatime - self.__lastdatatime
4284 deltatime = datatime - self.__lastdatatime
4285 self.__initime = datatime
4285 self.__initime = datatime
4286 #print(data_360.shape,avgdatatime,data_p.shape)
4286 #print(data_360.shape,avgdatatime,data_p.shape)
4287 return data_360,avgdatatime,data_p,data_e
4287 return data_360,avgdatatime,data_p,data_e
4288
4288
4289 def run(self, dataOut,n = None,mode=None,**kwargs):
4289 def run(self, dataOut,n = None,mode=None,**kwargs):
4290 #print("BLOCK 360 HERE WE GO MOMENTOS")
4290 #print("BLOCK 360 HERE WE GO MOMENTOS")
4291 print("Block 360")
4291 print("Block 360")
4292 #exit(1)
4292 #exit(1)
4293 if not self.isConfig:
4293 if not self.isConfig:
4294 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4294 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4295 ####self.index = 0
4295 ####self.index = 0
4296 #print("comova",self.isConfig)
4296 #print("comova",self.isConfig)
4297 self.isConfig = True
4297 self.isConfig = True
4298 ####if self.index==dataOut.azimuth.shape[0]:
4298 ####if self.index==dataOut.azimuth.shape[0]:
4299 #### self.index=0
4299 #### self.index=0
4300 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4300 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4301 dataOut.flagNoData = True
4301 dataOut.flagNoData = True
4302
4302
4303 if self.__dataReady:
4303 if self.__dataReady:
4304 dataOut.data_360 = data_360 # S
4304 dataOut.data_360 = data_360 # S
4305 #print("DATA 360")
4305 #print("DATA 360")
4306 #print(dataOut.data_360)
4306 #print(dataOut.data_360)
4307 #print("---------------------------------------------------------------------------------")
4307 #print("---------------------------------------------------------------------------------")
4308 print("---------------------------DATAREADY---------------------------------------------")
4308 print("---------------------------DATAREADY---------------------------------------------")
4309 #print("---------------------------------------------------------------------------------")
4309 #print("---------------------------------------------------------------------------------")
4310 #print("data_360",dataOut.data_360.shape)
4310 #print("data_360",dataOut.data_360.shape)
4311 dataOut.data_azi = data_p
4311 dataOut.data_azi = data_p
4312 dataOut.data_ele = data_e
4312 dataOut.data_ele = data_e
4313 ###print("azi: ",dataOut.data_azi)
4313 ###print("azi: ",dataOut.data_azi)
4314 #print("ele: ",dataOut.data_ele)
4314 #print("ele: ",dataOut.data_ele)
4315 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4315 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4316 dataOut.utctime = avgdatatime
4316 dataOut.utctime = avgdatatime
4317 dataOut.flagNoData = False
4317 dataOut.flagNoData = False
4318 return dataOut
4318 return dataOut
4319
4319
4320 class Block360_vRF(Operation):
4320 class Block360_vRF(Operation):
4321 '''
4321 '''
4322 '''
4322 '''
4323 isConfig = False
4323 isConfig = False
4324 __profIndex = 0
4324 __profIndex = 0
4325 __initime = None
4325 __initime = None
4326 __lastdatatime = None
4326 __lastdatatime = None
4327 __buffer = None
4327 __buffer = None
4328 __dataReady = False
4328 __dataReady = False
4329 n = None
4329 n = None
4330 __nch = 0
4330 __nch = 0
4331 __nHeis = 0
4331 __nHeis = 0
4332 index = 0
4332 index = 0
4333 mode = 0
4333 mode = 0
4334
4334
4335 def __init__(self,**kwargs):
4335 def __init__(self,**kwargs):
4336 Operation.__init__(self,**kwargs)
4336 Operation.__init__(self,**kwargs)
4337
4337
4338 def setup(self, dataOut, n = None, mode = None):
4338 def setup(self, dataOut, n = None, mode = None):
4339 '''
4339 '''
4340 n= Numero de PRF's de entrada
4340 n= Numero de PRF's de entrada
4341 '''
4341 '''
4342 self.__initime = None
4342 self.__initime = None
4343 self.__lastdatatime = 0
4343 self.__lastdatatime = 0
4344 self.__dataReady = False
4344 self.__dataReady = False
4345 self.__buffer = 0
4345 self.__buffer = 0
4346 self.__buffer_1D = 0
4346 self.__buffer_1D = 0
4347 self.__profIndex = 0
4347 self.__profIndex = 0
4348 self.index = 0
4348 self.index = 0
4349 self.__nch = dataOut.nChannels
4349 self.__nch = dataOut.nChannels
4350 self.__nHeis = dataOut.nHeights
4350 self.__nHeis = dataOut.nHeights
4351 ##print("ELVALOR DE n es:", n)
4351 ##print("ELVALOR DE n es:", n)
4352 if n == None:
4352 if n == None:
4353 raise ValueError("n should be specified.")
4353 raise ValueError("n should be specified.")
4354
4354
4355 if mode == None:
4355 if mode == None:
4356 raise ValueError("mode should be specified.")
4356 raise ValueError("mode should be specified.")
4357
4357
4358 if n != None:
4358 if n != None:
4359 if n<1:
4359 if n<1:
4360 print("n should be greater than 2")
4360 print("n should be greater than 2")
4361 raise ValueError("n should be greater than 2")
4361 raise ValueError("n should be greater than 2")
4362
4362
4363 self.n = n
4363 self.n = n
4364 self.mode = mode
4364 self.mode = mode
4365 #print("self.mode",self.mode)
4365 #print("self.mode",self.mode)
4366 #print("nHeights")
4366 #print("nHeights")
4367 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4367 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4368 self.__buffer2 = numpy.zeros(n)
4368 self.__buffer2 = numpy.zeros(n)
4369 self.__buffer3 = numpy.zeros(n)
4369 self.__buffer3 = numpy.zeros(n)
4370
4370
4371
4371
4372
4372
4373
4373
4374 def putData(self,data,mode):
4374 def putData(self,data,mode):
4375 '''
4375 '''
4376 Add a profile to he __buffer and increase in one the __profiel Index
4376 Add a profile to he __buffer and increase in one the __profiel Index
4377 '''
4377 '''
4378 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4378 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4379 #print("line 4049",data.azimuth.shape,data.azimuth)
4379 #print("line 4049",data.azimuth.shape,data.azimuth)
4380 if self.mode==0:
4380 if self.mode==0:
4381 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4381 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4382 if self.mode==1:
4382 if self.mode==1:
4383 self.__buffer[:,self.__profIndex,:]= data.data_pow
4383 self.__buffer[:,self.__profIndex,:]= data.data_pow
4384 #print("me casi",self.index,data.azimuth[self.index])
4384 #print("me casi",self.index,data.azimuth[self.index])
4385 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4385 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4386 #print("magic",data.profileIndex)
4386 #print("magic",data.profileIndex)
4387 #print(data.azimuth[self.index])
4387 #print(data.azimuth[self.index])
4388 #print("index",self.index)
4388 #print("index",self.index)
4389
4389
4390 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4390 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4391 self.__buffer2[self.__profIndex] = data.azimuth
4391 self.__buffer2[self.__profIndex] = data.azimuth
4392 self.__buffer3[self.__profIndex] = data.elevation
4392 self.__buffer3[self.__profIndex] = data.elevation
4393 #print("q pasa")
4393 #print("q pasa")
4394 #####self.index+=1
4394 #####self.index+=1
4395 #print("index",self.index,data.azimuth[:10])
4395 #print("index",self.index,data.azimuth[:10])
4396 self.__profIndex += 1
4396 self.__profIndex += 1
4397 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4397 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4398
4398
4399 def pushData(self,data):
4399 def pushData(self,data):
4400 '''
4400 '''
4401 Return the PULSEPAIR and the profiles used in the operation
4401 Return the PULSEPAIR and the profiles used in the operation
4402 Affected : self.__profileIndex
4402 Affected : self.__profileIndex
4403 '''
4403 '''
4404 #print("pushData")
4404 #print("pushData")
4405
4405
4406 data_360 = self.__buffer
4406 data_360 = self.__buffer
4407 data_p = self.__buffer2
4407 data_p = self.__buffer2
4408 data_e = self.__buffer3
4408 data_e = self.__buffer3
4409 n = self.__profIndex
4409 n = self.__profIndex
4410
4410
4411 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4411 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4412 self.__buffer2 = numpy.zeros(self.n)
4412 self.__buffer2 = numpy.zeros(self.n)
4413 self.__buffer3 = numpy.zeros(self.n)
4413 self.__buffer3 = numpy.zeros(self.n)
4414 self.__profIndex = 0
4414 self.__profIndex = 0
4415 #print("pushData")
4415 #print("pushData")
4416 return data_360,n,data_p,data_e
4416 return data_360,n,data_p,data_e
4417
4417
4418
4418
4419 def byProfiles(self,dataOut):
4419 def byProfiles(self,dataOut):
4420
4420
4421 self.__dataReady = False
4421 self.__dataReady = False
4422 data_360 = None
4422 data_360 = None
4423 data_p = None
4423 data_p = None
4424 data_e = None
4424 data_e = None
4425 #print("dataOu",dataOut.dataPP_POW)
4425 #print("dataOu",dataOut.dataPP_POW)
4426 self.putData(data=dataOut,mode = self.mode)
4426 self.putData(data=dataOut,mode = self.mode)
4427 ##### print("profIndex",self.__profIndex)
4427 ##### print("profIndex",self.__profIndex)
4428 if self.__profIndex == self.n:
4428 if self.__profIndex == self.n:
4429 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4429 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4430 self.__dataReady = True
4430 self.__dataReady = True
4431
4431
4432 return data_360,data_p,data_e
4432 return data_360,data_p,data_e
4433
4433
4434
4434
4435 def blockOp(self, dataOut, datatime= None):
4435 def blockOp(self, dataOut, datatime= None):
4436 if self.__initime == None:
4436 if self.__initime == None:
4437 self.__initime = datatime
4437 self.__initime = datatime
4438 data_360,data_p,data_e = self.byProfiles(dataOut)
4438 data_360,data_p,data_e = self.byProfiles(dataOut)
4439 self.__lastdatatime = datatime
4439 self.__lastdatatime = datatime
4440
4440
4441 if data_360 is None:
4441 if data_360 is None:
4442 return None, None,None,None
4442 return None, None,None,None
4443
4443
4444
4444
4445 avgdatatime = self.__initime
4445 avgdatatime = self.__initime
4446 if self.n==1:
4446 if self.n==1:
4447 avgdatatime = datatime
4447 avgdatatime = datatime
4448 deltatime = datatime - self.__lastdatatime
4448 deltatime = datatime - self.__lastdatatime
4449 self.__initime = datatime
4449 self.__initime = datatime
4450 #print(data_360.shape,avgdatatime,data_p.shape)
4450 #print(data_360.shape,avgdatatime,data_p.shape)
4451 return data_360,avgdatatime,data_p,data_e
4451 return data_360,avgdatatime,data_p,data_e
4452
4452
4453 def checkcase(self,data_ele):
4453 def checkcase(self,data_ele):
4454 start = data_ele[0]
4454 start = data_ele[0]
4455 end = data_ele[-1]
4455 end = data_ele[-1]
4456 diff_angle = (end-start)
4456 diff_angle = (end-start)
4457 len_ang=len(data_ele)
4457 len_ang=len(data_ele)
4458 print("start",start)
4458 print("start",start)
4459 print("end",end)
4459 print("end",end)
4460 print("number",diff_angle)
4460 print("number",diff_angle)
4461
4461
4462 print("len_ang",len_ang)
4462 print("len_ang",len_ang)
4463
4463
4464 aux = (data_ele<0).any(axis=0)
4464 aux = (data_ele<0).any(axis=0)
4465
4465
4466 #exit(1)
4466 #exit(1)
4467 if diff_angle<0 and aux!=1: #Bajada
4467 if diff_angle<0 and aux!=1: #Bajada
4468 return 1
4468 return 1
4469 elif diff_angle<0 and aux==1: #Bajada con angulos negativos
4469 elif diff_angle<0 and aux==1: #Bajada con angulos negativos
4470 return 0
4470 return 0
4471 elif diff_angle == 0: # This case happens when the angle reaches the max_angle if n = 2
4471 elif diff_angle == 0: # This case happens when the angle reaches the max_angle if n = 2
4472 self.flagEraseFirstData = 1
4472 self.flagEraseFirstData = 1
4473 print("ToDO this case")
4473 print("ToDO this case")
4474 exit(1)
4474 exit(1)
4475 elif diff_angle>0: #Subida
4475 elif diff_angle>0: #Subida
4476 return 0
4476 return 0
4477
4477
4478 def run(self, dataOut,n = None,mode=None,**kwargs):
4478 def run(self, dataOut,n = None,mode=None,**kwargs):
4479 #print("BLOCK 360 HERE WE GO MOMENTOS")
4479 #print("BLOCK 360 HERE WE GO MOMENTOS")
4480 print("Block 360")
4480 print("Block 360")
4481
4481
4482 #exit(1)
4482 #exit(1)
4483 if not self.isConfig:
4483 if not self.isConfig:
4484 if n == 1:
4484 if n == 1:
4485 print("*******************Min Value is 2. Setting n = 2*******************")
4485 print("*******************Min Value is 2. Setting n = 2*******************")
4486 n = 2
4486 n = 2
4487 #exit(1)
4487 #exit(1)
4488 print(n)
4488 print(n)
4489 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4489 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4490 ####self.index = 0
4490 ####self.index = 0
4491 #print("comova",self.isConfig)
4491 #print("comova",self.isConfig)
4492 self.isConfig = True
4492 self.isConfig = True
4493 ####if self.index==dataOut.azimuth.shape[0]:
4493 ####if self.index==dataOut.azimuth.shape[0]:
4494 #### self.index=0
4494 #### self.index=0
4495 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4495 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4496 dataOut.flagNoData = True
4496 dataOut.flagNoData = True
4497
4497
4498 if self.__dataReady:
4498 if self.__dataReady:
4499 dataOut.data_360 = data_360 # S
4499 dataOut.data_360 = data_360 # S
4500 #print("DATA 360")
4500 #print("DATA 360")
4501 #print(dataOut.data_360)
4501 #print(dataOut.data_360)
4502 #print("---------------------------------------------------------------------------------")
4502 #print("---------------------------------------------------------------------------------")
4503 print("---------------------------DATAREADY---------------------------------------------")
4503 print("---------------------------DATAREADY---------------------------------------------")
4504 #print("---------------------------------------------------------------------------------")
4504 #print("---------------------------------------------------------------------------------")
4505 #print("data_360",dataOut.data_360.shape)
4505 #print("data_360",dataOut.data_360.shape)
4506 dataOut.data_azi = data_p
4506 dataOut.data_azi = data_p
4507 dataOut.data_ele = data_e
4507 dataOut.data_ele = data_e
4508 ###print("azi: ",dataOut.data_azi)
4508 ###print("azi: ",dataOut.data_azi)
4509 #print("ele: ",dataOut.data_ele)
4509 #print("ele: ",dataOut.data_ele)
4510 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4510 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4511 dataOut.utctime = avgdatatime
4511 dataOut.utctime = avgdatatime
4512
4512
4513 dataOut.case_flag = self.checkcase(dataOut.data_ele)
4513 dataOut.case_flag = self.checkcase(dataOut.data_ele)
4514 if dataOut.case_flag: #Si estΓ‘ de bajada empieza a plotear
4514 if dataOut.case_flag: #Si estΓ‘ de bajada empieza a plotear
4515 print("INSIDE CASE FLAG BAJADA")
4515 print("INSIDE CASE FLAG BAJADA")
4516 dataOut.flagNoData = False
4516 dataOut.flagNoData = False
4517 else:
4517 else:
4518 print("CASE SUBIDA")
4518 print("CASE SUBIDA")
4519 dataOut.flagNoData = True
4519 dataOut.flagNoData = True
4520
4520
4521 #dataOut.flagNoData = False
4521 #dataOut.flagNoData = False
4522 return dataOut
4522 return dataOut
4523
4523
4524 class Block360_vRF2(Operation):
4524 class Block360_vRF2(Operation):
4525 '''
4525 '''
4526 '''
4526 '''
4527 isConfig = False
4527 isConfig = False
4528 __profIndex = 0
4528 __profIndex = 0
4529 __initime = None
4529 __initime = None
4530 __lastdatatime = None
4530 __lastdatatime = None
4531 __buffer = None
4531 __buffer = None
4532 __dataReady = False
4532 __dataReady = False
4533 n = None
4533 n = None
4534 __nch = 0
4534 __nch = 0
4535 __nHeis = 0
4535 __nHeis = 0
4536 index = 0
4536 index = 0
4537 mode = None
4537 mode = None
4538
4538
4539 def __init__(self,**kwargs):
4539 def __init__(self,**kwargs):
4540 Operation.__init__(self,**kwargs)
4540 Operation.__init__(self,**kwargs)
4541
4541
4542 def setup(self, dataOut, n = None, mode = None):
4542 def setup(self, dataOut, n = None, mode = None):
4543 '''
4543 '''
4544 n= Numero de PRF's de entrada
4544 n= Numero de PRF's de entrada
4545 '''
4545 '''
4546 self.__initime = None
4546 self.__initime = None
4547 self.__lastdatatime = 0
4547 self.__lastdatatime = 0
4548 self.__dataReady = False
4548 self.__dataReady = False
4549 self.__buffer = 0
4549 self.__buffer = 0
4550 self.__buffer_1D = 0
4550 self.__buffer_1D = 0
4551 #self.__profIndex = 0
4551 #self.__profIndex = 0
4552 self.index = 0
4552 self.index = 0
4553 self.__nch = dataOut.nChannels
4553 self.__nch = dataOut.nChannels
4554 self.__nHeis = dataOut.nHeights
4554 self.__nHeis = dataOut.nHeights
4555
4555
4556 self.mode = mode
4556 self.mode = mode
4557 #print("self.mode",self.mode)
4557 #print("self.mode",self.mode)
4558 #print("nHeights")
4558 #print("nHeights")
4559 self.__buffer = []
4559 self.__buffer = []
4560 self.__buffer2 = []
4560 self.__buffer2 = []
4561 self.__buffer3 = []
4561 self.__buffer3 = []
4562 self.__buffer4 = []
4562 self.__buffer4 = []
4563
4563
4564 def putData(self,data,mode):
4564 def putData(self,data,mode):
4565 '''
4565 '''
4566 Add a profile to he __buffer and increase in one the __profiel Index
4566 Add a profile to he __buffer and increase in one the __profiel Index
4567 '''
4567 '''
4568
4568
4569 if self.mode==0:
4569 if self.mode==0:
4570 self.__buffer.append(data.dataPP_POWER)# PRIMER MOMENTO
4570 self.__buffer.append(data.dataPP_POWER)# PRIMER MOMENTO
4571 if self.mode==1:
4571 if self.mode==1:
4572 self.__buffer.append(data.data_pow)
4572 self.__buffer.append(data.data_pow)
4573
4573
4574 self.__buffer4.append(data.dataPP_DOP)
4574 self.__buffer4.append(data.dataPP_DOP)
4575
4575
4576 self.__buffer2.append(data.azimuth)
4576 self.__buffer2.append(data.azimuth)
4577 self.__buffer3.append(data.elevation)
4577 self.__buffer3.append(data.elevation)
4578 self.__profIndex += 1
4578 self.__profIndex += 1
4579
4579
4580 return numpy.array(self.__buffer3) #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4580 return numpy.array(self.__buffer3) #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4581
4581
4582 def pushData(self,data):
4582 def pushData(self,data):
4583 '''
4583 '''
4584 Return the PULSEPAIR and the profiles used in the operation
4584 Return the PULSEPAIR and the profiles used in the operation
4585 Affected : self.__profileIndex
4585 Affected : self.__profileIndex
4586 '''
4586 '''
4587
4587
4588 data_360_Power = numpy.array(self.__buffer).transpose(1,0,2)
4588 data_360_Power = numpy.array(self.__buffer).transpose(1,0,2)
4589 data_360_Velocity = numpy.array(self.__buffer4).transpose(1,0,2)
4589 data_360_Velocity = numpy.array(self.__buffer4).transpose(1,0,2)
4590 data_p = numpy.array(self.__buffer2)
4590 data_p = numpy.array(self.__buffer2)
4591 data_e = numpy.array(self.__buffer3)
4591 data_e = numpy.array(self.__buffer3)
4592 n = self.__profIndex
4592 n = self.__profIndex
4593
4593
4594 self.__buffer = []
4594 self.__buffer = []
4595 self.__buffer4 = []
4595 self.__buffer4 = []
4596 self.__buffer2 = []
4596 self.__buffer2 = []
4597 self.__buffer3 = []
4597 self.__buffer3 = []
4598 self.__profIndex = 0
4598 self.__profIndex = 0
4599 return data_360_Power,data_360_Velocity,n,data_p,data_e
4599 return data_360_Power,data_360_Velocity,n,data_p,data_e
4600
4600
4601
4601
4602 def byProfiles(self,dataOut):
4602 def byProfiles(self,dataOut):
4603
4603
4604 self.__dataReady = False
4604 self.__dataReady = False
4605 data_360_Power = []
4605 data_360_Power = []
4606 data_360_Velocity = []
4606 data_360_Velocity = []
4607 data_p = None
4607 data_p = None
4608 data_e = None
4608 data_e = None
4609
4609
4610 elevations = self.putData(data=dataOut,mode = self.mode)
4610 elevations = self.putData(data=dataOut,mode = self.mode)
4611
4611
4612 if self.__profIndex > 1:
4612 if self.__profIndex > 1:
4613 case_flag = self.checkcase(elevations)
4613 case_flag = self.checkcase(elevations)
4614
4614
4615 if case_flag == 0: #Subida
4615 if case_flag == 0: #Subida
4616
4616
4617 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4617 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4618 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4618 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4619 self.__buffer.pop(0) #Erase first data
4619 self.__buffer.pop(0) #Erase first data
4620 self.__buffer2.pop(0)
4620 self.__buffer2.pop(0)
4621 self.__buffer3.pop(0)
4621 self.__buffer3.pop(0)
4622 self.__buffer4.pop(0)
4622 self.__buffer4.pop(0)
4623 self.__profIndex -= 1
4623 self.__profIndex -= 1
4624 else: #Cuando ha estado de bajada y ha vuelto a subir
4624 else: #Cuando ha estado de bajada y ha vuelto a subir
4625 #Se borra el ΓΊltimo dato
4625 #Se borra el ΓΊltimo dato
4626 self.__buffer.pop() #Erase last data
4626 self.__buffer.pop() #Erase last data
4627 self.__buffer2.pop()
4627 self.__buffer2.pop()
4628 self.__buffer3.pop()
4628 self.__buffer3.pop()
4629 self.__buffer4.pop()
4629 self.__buffer4.pop()
4630 data_360_Power,data_360_Velocity,n,data_p,data_e = self.pushData(data=dataOut)
4630 data_360_Power,data_360_Velocity,n,data_p,data_e = self.pushData(data=dataOut)
4631
4631
4632 self.__dataReady = True
4632 self.__dataReady = True
4633
4633
4634 return data_360_Power,data_360_Velocity,data_p,data_e
4634 return data_360_Power,data_360_Velocity,data_p,data_e
4635
4635
4636
4636
4637 def blockOp(self, dataOut, datatime= None):
4637 def blockOp(self, dataOut, datatime= None):
4638 if self.__initime == None:
4638 if self.__initime == None:
4639 self.__initime = datatime
4639 self.__initime = datatime
4640 data_360_Power,data_360_Velocity,data_p,data_e = self.byProfiles(dataOut)
4640 data_360_Power,data_360_Velocity,data_p,data_e = self.byProfiles(dataOut)
4641 self.__lastdatatime = datatime
4641 self.__lastdatatime = datatime
4642
4642
4643 avgdatatime = self.__initime
4643 avgdatatime = self.__initime
4644 if self.n==1:
4644 if self.n==1:
4645 avgdatatime = datatime
4645 avgdatatime = datatime
4646 deltatime = datatime - self.__lastdatatime
4646 deltatime = datatime - self.__lastdatatime
4647 self.__initime = datatime
4647 self.__initime = datatime
4648 return data_360_Power,data_360_Velocity,avgdatatime,data_p,data_e
4648 return data_360_Power,data_360_Velocity,avgdatatime,data_p,data_e
4649
4649
4650 def checkcase(self,data_ele):
4650 def checkcase(self,data_ele):
4651 #print(data_ele)
4651 #print(data_ele)
4652 start = data_ele[-2]
4652 start = data_ele[-2]
4653 end = data_ele[-1]
4653 end = data_ele[-1]
4654 diff_angle = (end-start)
4654 diff_angle = (end-start)
4655 len_ang=len(data_ele)
4655 len_ang=len(data_ele)
4656
4656
4657 if diff_angle > 0: #Subida
4657 if diff_angle > 0: #Subida
4658 return 0
4658 return 0
4659
4659
4660 def run(self, dataOut,mode='Power',**kwargs):
4660 def run(self, dataOut,mode='Power',**kwargs):
4661 #print("BLOCK 360 HERE WE GO MOMENTOS")
4661 #print("BLOCK 360 HERE WE GO MOMENTOS")
4662 #print("Block 360")
4662 #print("Block 360")
4663 dataOut.mode = mode
4663 dataOut.mode = mode
4664
4664
4665 if not self.isConfig:
4665 if not self.isConfig:
4666 self.setup(dataOut = dataOut ,mode= mode ,**kwargs)
4666 self.setup(dataOut = dataOut ,mode= mode ,**kwargs)
4667 self.isConfig = True
4667 self.isConfig = True
4668
4668
4669
4669
4670 data_360_Power, data_360_Velocity, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4670 data_360_Power, data_360_Velocity, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4671
4671
4672
4672
4673 dataOut.flagNoData = True
4673 dataOut.flagNoData = True
4674
4674
4675
4675
4676 if self.__dataReady:
4676 if self.__dataReady:
4677 dataOut.data_360_Power = data_360_Power # S
4677 dataOut.data_360_Power = data_360_Power # S
4678 dataOut.data_360_Velocity = data_360_Velocity
4678 dataOut.data_360_Velocity = data_360_Velocity
4679 dataOut.data_azi = data_p
4679 dataOut.data_azi = data_p
4680 dataOut.data_ele = data_e
4680 dataOut.data_ele = data_e
4681 dataOut.utctime = avgdatatime
4681 dataOut.utctime = avgdatatime
4682 dataOut.flagNoData = False
4682 dataOut.flagNoData = False
4683
4683
4684 return dataOut
4684 return dataOut
4685
4685
4686 class Block360_vRF3(Operation):
4686 class Block360_vRF3(Operation):
4687 '''
4687 '''
4688 '''
4688 '''
4689 isConfig = False
4689 isConfig = False
4690 __profIndex = 0
4690 __profIndex = 0
4691 __initime = None
4691 __initime = None
4692 __lastdatatime = None
4692 __lastdatatime = None
4693 __buffer = None
4693 __buffer = None
4694 __dataReady = False
4694 __dataReady = False
4695 n = None
4695 n = None
4696 __nch = 0
4696 __nch = 0
4697 __nHeis = 0
4697 __nHeis = 0
4698 index = 0
4698 index = 0
4699 mode = None
4699 mode = None
4700
4700
4701 def __init__(self,**kwargs):
4701 def __init__(self,**kwargs):
4702 Operation.__init__(self,**kwargs)
4702 Operation.__init__(self,**kwargs)
4703
4703
4704 def setup(self, dataOut, attr):
4704 def setup(self, dataOut, attr):
4705 '''
4705 '''
4706 n= Numero de PRF's de entrada
4706 n= Numero de PRF's de entrada
4707 '''
4707 '''
4708 self.__initime = None
4708 self.__initime = None
4709 self.__lastdatatime = 0
4709 self.__lastdatatime = 0
4710 self.__dataReady = False
4710 self.__dataReady = False
4711 self.__buffer = 0
4711 self.__buffer = 0
4712 self.__buffer_1D = 0
4712 self.__buffer_1D = 0
4713 self.index = 0
4713 self.index = 0
4714 self.__nch = dataOut.nChannels
4714 self.__nch = dataOut.nChannels
4715 self.__nHeis = dataOut.nHeights
4715 self.__nHeis = dataOut.nHeights
4716
4716
4717 self.attr = attr
4717 self.attr = attr
4718 #print("self.mode",self.mode)
4718 #print("self.mode",self.mode)
4719 #print("nHeights")
4719 #print("nHeights")
4720 self.__buffer = []
4720 self.__buffer = []
4721 self.__buffer2 = []
4721 self.__buffer2 = []
4722 self.__buffer3 = []
4722 self.__buffer3 = []
4723
4723
4724 def putData(self, data, attr):
4724 def putData(self, data, attr):
4725 '''
4725 '''
4726 Add a profile to he __buffer and increase in one the __profiel Index
4726 Add a profile to he __buffer and increase in one the __profiel Index
4727 '''
4727 '''
4728
4728
4729 self.__buffer.append(getattr(data, attr))
4729 self.__buffer.append(getattr(data, attr))
4730 self.__buffer2.append(data.azimuth)
4730 self.__buffer2.append(data.azimuth)
4731 self.__buffer3.append(data.elevation)
4731 self.__buffer3.append(data.elevation)
4732 self.__profIndex += 1
4732 self.__profIndex += 1
4733
4733
4734 return numpy.array(self.__buffer3)
4734 return numpy.array(self.__buffer3)
4735
4735
4736 def pushData(self, data):
4736 def pushData(self, data):
4737 '''
4737 '''
4738 Return the PULSEPAIR and the profiles used in the operation
4738 Return the PULSEPAIR and the profiles used in the operation
4739 Affected : self.__profileIndex
4739 Affected : self.__profileIndex
4740 '''
4740 '''
4741
4741
4742 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4742 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4743 data_p = numpy.array(self.__buffer2)
4743 data_p = numpy.array(self.__buffer2)
4744 data_e = numpy.array(self.__buffer3)
4744 data_e = numpy.array(self.__buffer3)
4745 n = self.__profIndex
4745 n = self.__profIndex
4746
4746
4747 self.__buffer = []
4747 self.__buffer = []
4748 self.__buffer2 = []
4748 self.__buffer2 = []
4749 self.__buffer3 = []
4749 self.__buffer3 = []
4750 self.__profIndex = 0
4750 self.__profIndex = 0
4751 return data_360, n, data_p, data_e
4751 return data_360, n, data_p, data_e
4752
4752
4753
4753
4754 def byProfiles(self,dataOut):
4754 def byProfiles(self,dataOut):
4755
4755
4756 self.__dataReady = False
4756 self.__dataReady = False
4757 data_360 = []
4757 data_360 = []
4758 data_p = None
4758 data_p = None
4759 data_e = None
4759 data_e = None
4760
4760
4761 elevations = self.putData(data=dataOut, attr = self.attr)
4761 elevations = self.putData(data=dataOut, attr = self.attr)
4762
4762
4763 if self.__profIndex > 1:
4763 if self.__profIndex > 1:
4764 case_flag = self.checkcase(elevations)
4764 case_flag = self.checkcase(elevations)
4765
4765
4766 if case_flag == 0: #Subida
4766 if case_flag == 0: #Subida
4767
4767
4768 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4768 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4769 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4769 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4770 self.__buffer.pop(0) #Erase first data
4770 self.__buffer.pop(0) #Erase first data
4771 self.__buffer2.pop(0)
4771 self.__buffer2.pop(0)
4772 self.__buffer3.pop(0)
4772 self.__buffer3.pop(0)
4773 self.__profIndex -= 1
4773 self.__profIndex -= 1
4774 else: #Cuando ha estado de bajada y ha vuelto a subir
4774 else: #Cuando ha estado de bajada y ha vuelto a subir
4775 #Se borra el ΓΊltimo dato
4775 #Se borra el ΓΊltimo dato
4776 self.__buffer.pop() #Erase last data
4776 self.__buffer.pop() #Erase last data
4777 self.__buffer2.pop()
4777 self.__buffer2.pop()
4778 self.__buffer3.pop()
4778 self.__buffer3.pop()
4779 data_360, n, data_p, data_e = self.pushData(data=dataOut)
4779 data_360, n, data_p, data_e = self.pushData(data=dataOut)
4780
4780
4781 self.__dataReady = True
4781 self.__dataReady = True
4782
4782
4783 return data_360, data_p, data_e
4783 return data_360, data_p, data_e
4784
4784
4785
4785
4786 def blockOp(self, dataOut, datatime= None):
4786 def blockOp(self, dataOut, datatime= None):
4787 if self.__initime == None:
4787 if self.__initime == None:
4788 self.__initime = datatime
4788 self.__initime = datatime
4789 data_360, data_p, data_e = self.byProfiles(dataOut)
4789 data_360, data_p, data_e = self.byProfiles(dataOut)
4790 self.__lastdatatime = datatime
4790 self.__lastdatatime = datatime
4791
4791
4792 avgdatatime = self.__initime
4792 avgdatatime = self.__initime
4793 if self.n==1:
4793 if self.n==1:
4794 avgdatatime = datatime
4794 avgdatatime = datatime
4795 deltatime = datatime - self.__lastdatatime
4795 deltatime = datatime - self.__lastdatatime
4796 self.__initime = datatime
4796 self.__initime = datatime
4797 return data_360, avgdatatime, data_p, data_e
4797 return data_360, avgdatatime, data_p, data_e
4798
4798
4799 def checkcase(self, data_ele):
4799 def checkcase(self, data_ele):
4800
4800
4801 start = data_ele[-2]
4801 start = data_ele[-2]
4802 end = data_ele[-1]
4802 end = data_ele[-1]
4803 diff_angle = (end-start)
4803 diff_angle = (end-start)
4804 len_ang=len(data_ele)
4804 len_ang=len(data_ele)
4805
4805
4806 if diff_angle > 0: #Subida
4806 if diff_angle > 0: #Subida
4807 return 0
4807 return 0
4808
4808
4809 def run(self, dataOut, attr_data='dataPP_POWER',**kwargs):
4809 def run(self, dataOut, attr_data='dataPP_POWER',**kwargs):
4810
4810
4811 dataOut.attr_data = attr_data
4811 dataOut.attr_data = attr_data
4812
4812
4813 if not self.isConfig:
4813 if not self.isConfig:
4814 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
4814 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
4815 self.isConfig = True
4815 self.isConfig = True
4816
4816
4817 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.utctime)
4817 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.utctime)
4818
4818
4819 dataOut.flagNoData = True
4819 dataOut.flagNoData = True
4820
4820
4821 if self.__dataReady:
4821 if self.__dataReady:
4822 setattr(dataOut, attr_data, data_360 )
4822 setattr(dataOut, attr_data, data_360 )
4823 dataOut.data_azi = data_p
4823 dataOut.data_azi = data_p
4824 dataOut.data_ele = data_e
4824 dataOut.data_ele = data_e
4825 dataOut.utctime = avgdatatime
4825 dataOut.utctime = avgdatatime
4826 dataOut.flagNoData = False
4826 dataOut.flagNoData = False
4827
4827
4828 return dataOut
4828 return dataOut
4829
4829
4830 class Block360_vRF4(Operation):
4830 class Block360_vRF4(Operation):
4831 '''
4831 '''
4832 '''
4832 '''
4833 isConfig = False
4833 isConfig = False
4834 __profIndex = 0
4834 __profIndex = 0
4835 __initime = None
4835 __initime = None
4836 __lastdatatime = None
4836 __lastdatatime = None
4837 __buffer = None
4837 __buffer = None
4838 __dataReady = False
4838 __dataReady = False
4839 n = None
4839 n = None
4840 __nch = 0
4840 __nch = 0
4841 __nHeis = 0
4841 __nHeis = 0
4842 index = 0
4842 index = 0
4843 mode = None
4843 mode = None
4844
4844
4845 def __init__(self,**kwargs):
4845 def __init__(self,**kwargs):
4846 Operation.__init__(self,**kwargs)
4846 Operation.__init__(self,**kwargs)
4847
4847
4848 def setup(self, dataOut, attr):
4848 def setup(self, dataOut, attr):
4849 '''
4849 '''
4850 n= Numero de PRF's de entrada
4850 n= Numero de PRF's de entrada
4851 '''
4851 '''
4852 self.__initime = None
4852 self.__initime = None
4853 self.__lastdatatime = 0
4853 self.__lastdatatime = 0
4854 self.__dataReady = False
4854 self.__dataReady = False
4855 self.__buffer = 0
4855 self.__buffer = 0
4856 self.__buffer_1D = 0
4856 self.__buffer_1D = 0
4857 self.index = 0
4857 self.index = 0
4858 self.__nch = dataOut.nChannels
4858 self.__nch = dataOut.nChannels
4859 self.__nHeis = dataOut.nHeights
4859 self.__nHeis = dataOut.nHeights
4860
4860
4861 self.attr = attr
4861 self.attr = attr
4862
4862
4863 self.__buffer = []
4863 self.__buffer = []
4864 self.__buffer2 = []
4864 self.__buffer2 = []
4865 self.__buffer3 = []
4865 self.__buffer3 = []
4866
4866
4867 def putData(self, data, attr, flagMode):
4867 def putData(self, data, attr, flagMode):
4868 '''
4868 '''
4869 Add a profile to he __buffer and increase in one the __profiel Index
4869 Add a profile to he __buffer and increase in one the __profiel Index
4870 '''
4870 '''
4871
4871
4872 self.__buffer.append(getattr(data, attr))
4872 self.__buffer.append(getattr(data, attr))
4873 self.__buffer2.append(data.azimuth)
4873 self.__buffer2.append(data.azimuth)
4874 self.__buffer3.append(data.elevation)
4874 self.__buffer3.append(data.elevation)
4875 self.__profIndex += 1
4875 self.__profIndex += 1
4876
4876
4877 if flagMode == 1: #'AZI'
4877 if flagMode == 1: #'AZI'
4878 return numpy.array(self.__buffer2)
4878 return numpy.array(self.__buffer2)
4879 elif flagMode == 0: #'ELE'
4879 elif flagMode == 0: #'ELE'
4880 return numpy.array(self.__buffer3)
4880 return numpy.array(self.__buffer3)
4881
4881
4882 def pushData(self, data,flagMode,case_flag):
4882 def pushData(self, data,flagMode,case_flag):
4883 '''
4883 '''
4884 Return the PULSEPAIR and the profiles used in the operation
4884 Return the PULSEPAIR and the profiles used in the operation
4885 Affected : self.__profileIndex
4885 Affected : self.__profileIndex
4886 '''
4886 '''
4887
4887
4888 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4888 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4889 data_p = numpy.array(self.__buffer2)
4889 data_p = numpy.array(self.__buffer2)
4890 data_e = numpy.array(self.__buffer3)
4890 data_e = numpy.array(self.__buffer3)
4891 n = self.__profIndex
4891 n = self.__profIndex
4892
4892
4893 self.__buffer = []
4893 self.__buffer = []
4894 self.__buffer2 = []
4894 self.__buffer2 = []
4895 self.__buffer3 = []
4895 self.__buffer3 = []
4896 self.__profIndex = 0
4896 self.__profIndex = 0
4897
4897
4898 if flagMode == 1 and case_flag == 0: #'AZI' y ha girado
4898 if flagMode == 1 and case_flag == 0: #'AZI' y ha girado
4899 self.putData(data=data, attr = self.attr, flagMode=flagMode)
4899 self.putData(data=data, attr = self.attr, flagMode=flagMode)
4900
4900
4901 return data_360, n, data_p, data_e
4901 return data_360, n, data_p, data_e
4902
4902
4903
4903
4904 def byProfiles(self,dataOut,flagMode):
4904 def byProfiles(self,dataOut,flagMode):
4905
4905
4906 self.__dataReady = False
4906 self.__dataReady = False
4907 data_360 = []
4907 data_360 = []
4908 data_p = None
4908 data_p = None
4909 data_e = None
4909 data_e = None
4910
4910
4911 angles = self.putData(data=dataOut, attr = self.attr, flagMode=flagMode)
4911 angles = self.putData(data=dataOut, attr = self.attr, flagMode=flagMode)
4912 #print(angles)
4912 #print(angles)
4913 if self.__profIndex > 1:
4913 if self.__profIndex > 1:
4914 case_flag = self.checkcase(angles,flagMode)
4914 case_flag = self.checkcase(angles,flagMode)
4915
4915
4916 if flagMode == 1: #'AZI':
4916 if flagMode == 1: #'AZI':
4917 if case_flag == 0: #Ya girΓ³
4917 if case_flag == 0: #Ya girΓ³
4918 self.__buffer.pop() #Erase last data
4918 self.__buffer.pop() #Erase last data
4919 self.__buffer2.pop()
4919 self.__buffer2.pop()
4920 self.__buffer3.pop()
4920 self.__buffer3.pop()
4921 data_360,n,data_p,data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
4921 data_360,n,data_p,data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
4922
4922
4923 self.__dataReady = True
4923 self.__dataReady = True
4924
4924
4925 elif flagMode == 0: #'ELE'
4925 elif flagMode == 0: #'ELE'
4926
4926
4927 if case_flag == 0: #Subida
4927 if case_flag == 0: #Subida
4928
4928
4929 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4929 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4930 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4930 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4931 self.__buffer.pop(0) #Erase first data
4931 self.__buffer.pop(0) #Erase first data
4932 self.__buffer2.pop(0)
4932 self.__buffer2.pop(0)
4933 self.__buffer3.pop(0)
4933 self.__buffer3.pop(0)
4934 self.__profIndex -= 1
4934 self.__profIndex -= 1
4935 else: #Cuando ha estado de bajada y ha vuelto a subir
4935 else: #Cuando ha estado de bajada y ha vuelto a subir
4936 #Se borra el ΓΊltimo dato
4936 #Se borra el ΓΊltimo dato
4937 self.__buffer.pop() #Erase last data
4937 self.__buffer.pop() #Erase last data
4938 self.__buffer2.pop()
4938 self.__buffer2.pop()
4939 self.__buffer3.pop()
4939 self.__buffer3.pop()
4940 data_360, n, data_p, data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
4940 data_360, n, data_p, data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
4941
4941
4942 self.__dataReady = True
4942 self.__dataReady = True
4943
4943
4944 return data_360, data_p, data_e
4944 return data_360, data_p, data_e
4945
4945
4946
4946
4947 def blockOp(self, dataOut, flagMode, datatime= None):
4947 def blockOp(self, dataOut, flagMode, datatime= None):
4948 if self.__initime == None:
4948 if self.__initime == None:
4949 self.__initime = datatime
4949 self.__initime = datatime
4950 data_360, data_p, data_e = self.byProfiles(dataOut,flagMode)
4950 data_360, data_p, data_e = self.byProfiles(dataOut,flagMode)
4951 self.__lastdatatime = datatime
4951 self.__lastdatatime = datatime
4952
4952
4953 avgdatatime = self.__initime
4953 avgdatatime = self.__initime
4954 if self.n==1:
4954 if self.n==1:
4955 avgdatatime = datatime
4955 avgdatatime = datatime
4956 deltatime = datatime - self.__lastdatatime
4956 deltatime = datatime - self.__lastdatatime
4957 self.__initime = datatime
4957 self.__initime = datatime
4958 return data_360, avgdatatime, data_p, data_e
4958 return data_360, avgdatatime, data_p, data_e
4959
4959
4960 def checkcase(self, angles, flagMode):
4960 def checkcase(self, angles, flagMode):
4961
4961
4962 if flagMode == 1: #'AZI'
4962 if flagMode == 1: #'AZI'
4963 start = angles[-2]
4963 start = angles[-2]
4964 end = angles[-1]
4964 end = angles[-1]
4965 diff_angle = (end-start)
4965 diff_angle = (end-start)
4966
4966
4967 if diff_angle < 0: #Ya girΓ³
4967 if diff_angle < 0: #Ya girΓ³
4968 return 0
4968 return 0
4969
4969
4970 elif flagMode == 0: #'ELE'
4970 elif flagMode == 0: #'ELE'
4971
4971
4972 start = angles[-2]
4972 start = angles[-2]
4973 end = angles[-1]
4973 end = angles[-1]
4974 diff_angle = (end-start)
4974 diff_angle = (end-start)
4975
4975
4976 if diff_angle > 0: #Subida
4976 if diff_angle > 0: #Subida
4977 return 0
4977 return 0
4978
4978
4979 def run(self, dataOut, attr_data='dataPP_POWER', axis=None,**kwargs):
4979 def run(self, dataOut, attr_data='dataPP_POWER', axis=None,**kwargs):
4980
4980
4981 dataOut.attr_data = attr_data
4981 dataOut.attr_data = attr_data
4982
4982
4983 dataOut.flagMode = axis[0] #Provisional, deberΓ­a venir del header
4983 dataOut.flagMode = axis[0] #Provisional, deberΓ­a venir del header
4984
4984
4985 if not self.isConfig:
4985 if not self.isConfig:
4986 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
4986 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
4987 self.isConfig = True
4987 self.isConfig = True
4988
4988
4989 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.flagMode, dataOut.utctime)
4989 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.flagMode, dataOut.utctime)
4990
4990
4991 dataOut.flagNoData = True
4991 dataOut.flagNoData = True
4992
4992
4993 if self.__dataReady:
4993 if self.__dataReady:
4994 setattr(dataOut, attr_data, data_360 )
4994 setattr(dataOut, attr_data, data_360 )
4995 dataOut.data_azi = data_p
4995 dataOut.data_azi = data_p
4996 dataOut.data_ele = data_e
4996 dataOut.data_ele = data_e
4997 dataOut.utctime = avgdatatime
4997 dataOut.utctime = avgdatatime
4998 dataOut.flagNoData = False
4998 dataOut.flagNoData = False
4999 print("********************attr_data********************",attr_data)
4999 #print(data_360.shape)
5000 #print(data_360.shape)
5000 #print(dataOut.heightList)
5001 #print(dataOut.heightList)
5001
5002
5002 return dataOut
5003 return dataOut
5003
5004
5004 class MergeProc(ProcessingUnit):
5005 class MergeProc(ProcessingUnit):
5005
5006
5006 def __init__(self):
5007 def __init__(self):
5007 ProcessingUnit.__init__(self)
5008 ProcessingUnit.__init__(self)
5008
5009
5009 def run(self, attr_data, mode=0):
5010 def run(self, attr_data, mode=0):
5010
5011
5011 #exit(1)
5012 #exit(1)
5012 self.dataOut = getattr(self, self.inputs[0])
5013 self.dataOut = getattr(self, self.inputs[0])
5013 data_inputs = [getattr(self, attr) for attr in self.inputs]
5014 data_inputs = [getattr(self, attr) for attr in self.inputs]
5014 #print(data_inputs)
5015 #print(data_inputs)
5015 #print(numpy.shape([getattr(data, attr_data) for data in data_inputs][1]))
5016 #print(numpy.shape([getattr(data, attr_data) for data in data_inputs][1]))
5016 #exit(1)
5017 #exit(1)
5017 if mode==0:
5018 if mode==0:
5018 data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs])
5019 data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs])
5019 setattr(self.dataOut, attr_data, data)
5020 setattr(self.dataOut, attr_data, data)
5020
5021
5021 if mode==1: #Hybrid
5022 if mode==1: #Hybrid
5022 #data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs],axis=1)
5023 #data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs],axis=1)
5023 #setattr(self.dataOut, attr_data, data)
5024 #setattr(self.dataOut, attr_data, data)
5024 setattr(self.dataOut, 'dataLag_spc', [getattr(data, attr_data) for data in data_inputs][0])
5025 setattr(self.dataOut, 'dataLag_spc', [getattr(data, attr_data) for data in data_inputs][0])
5025 setattr(self.dataOut, 'dataLag_spc_LP', [getattr(data, attr_data) for data in data_inputs][1])
5026 setattr(self.dataOut, 'dataLag_spc_LP', [getattr(data, attr_data) for data in data_inputs][1])
5026 setattr(self.dataOut, 'dataLag_cspc', [getattr(data, attr_data_2) for data in data_inputs][0])
5027 setattr(self.dataOut, 'dataLag_cspc', [getattr(data, attr_data_2) for data in data_inputs][0])
5027 setattr(self.dataOut, 'dataLag_cspc_LP', [getattr(data, attr_data_2) for data in data_inputs][1])
5028 setattr(self.dataOut, 'dataLag_cspc_LP', [getattr(data, attr_data_2) for data in data_inputs][1])
5028 #setattr(self.dataOut, 'nIncohInt', [getattr(data, attr_data_3) for data in data_inputs][0])
5029 #setattr(self.dataOut, 'nIncohInt', [getattr(data, attr_data_3) for data in data_inputs][0])
5029 #setattr(self.dataOut, 'nIncohInt_LP', [getattr(data, attr_data_3) for data in data_inputs][1])
5030 #setattr(self.dataOut, 'nIncohInt_LP', [getattr(data, attr_data_3) for data in data_inputs][1])
5030 '''
5031 '''
5031 print(self.dataOut.dataLag_spc_LP.shape)
5032 print(self.dataOut.dataLag_spc_LP.shape)
5032 print(self.dataOut.dataLag_cspc_LP.shape)
5033 print(self.dataOut.dataLag_cspc_LP.shape)
5033 exit(1)
5034 exit(1)
5034 '''
5035 '''
5035
5036
5036 #self.dataOut.dataLag_spc_LP = numpy.transpose(self.dataOut.dataLag_spc_LP[0],(2,0,1))
5037 #self.dataOut.dataLag_spc_LP = numpy.transpose(self.dataOut.dataLag_spc_LP[0],(2,0,1))
5037 #self.dataOut.dataLag_cspc_LP = numpy.transpose(self.dataOut.dataLag_cspc_LP,(3,1,2,0))
5038 #self.dataOut.dataLag_cspc_LP = numpy.transpose(self.dataOut.dataLag_cspc_LP,(3,1,2,0))
5038 '''
5039 '''
5039 print("Merge")
5040 print("Merge")
5040 print(numpy.shape(self.dataOut.dataLag_spc))
5041 print(numpy.shape(self.dataOut.dataLag_spc))
5041 print(numpy.shape(self.dataOut.dataLag_spc_LP))
5042 print(numpy.shape(self.dataOut.dataLag_spc_LP))
5042 print(numpy.shape(self.dataOut.dataLag_cspc))
5043 print(numpy.shape(self.dataOut.dataLag_cspc))
5043 print(numpy.shape(self.dataOut.dataLag_cspc_LP))
5044 print(numpy.shape(self.dataOut.dataLag_cspc_LP))
5044 exit(1)
5045 exit(1)
5045 '''
5046 '''
5046 #print(numpy.sum(self.dataOut.dataLag_spc_LP[2,:,164])/128)
5047 #print(numpy.sum(self.dataOut.dataLag_spc_LP[2,:,164])/128)
5047 #print(numpy.sum(self.dataOut.dataLag_cspc_LP[0,:,30,1])/128)
5048 #print(numpy.sum(self.dataOut.dataLag_cspc_LP[0,:,30,1])/128)
5048 #exit(1)
5049 #exit(1)
5049 #print(self.dataOut.NDP)
5050 #print(self.dataOut.NDP)
5050 #print(self.dataOut.nNoiseProfiles)
5051 #print(self.dataOut.nNoiseProfiles)
5051
5052
5052 #self.dataOut.nIncohInt_LP = 128
5053 #self.dataOut.nIncohInt_LP = 128
5053 self.dataOut.nProfiles_LP = 128#self.dataOut.nIncohInt_LP
5054 self.dataOut.nProfiles_LP = 128#self.dataOut.nIncohInt_LP
5054 self.dataOut.nIncohInt_LP = self.dataOut.nIncohInt
5055 self.dataOut.nIncohInt_LP = self.dataOut.nIncohInt
5055 self.dataOut.NLAG = 16
5056 self.dataOut.NLAG = 16
5056 self.dataOut.NRANGE = 200
5057 self.dataOut.NRANGE = 200
5057 self.dataOut.NSCAN = 128
5058 self.dataOut.NSCAN = 128
5058 #print(numpy.shape(self.dataOut.data_spc))
5059 #print(numpy.shape(self.dataOut.data_spc))
5059
5060
5060 #exit(1)
5061 #exit(1)
5061
5062
5062 if mode==2: #HAE 2022
5063 if mode==2: #HAE 2022
5063 data = numpy.sum([getattr(data, attr_data) for data in data_inputs],axis=0)
5064 data = numpy.sum([getattr(data, attr_data) for data in data_inputs],axis=0)
5064 setattr(self.dataOut, attr_data, data)
5065 setattr(self.dataOut, attr_data, data)
5065
5066
5066 self.dataOut.nIncohInt *= 2
5067 self.dataOut.nIncohInt *= 2
5067 #meta = self.dataOut.getFreqRange(1)/1000.
5068 #meta = self.dataOut.getFreqRange(1)/1000.
5068 self.dataOut.freqRange = self.dataOut.getFreqRange(1)/1000.
5069 self.dataOut.freqRange = self.dataOut.getFreqRange(1)/1000.
5069
5070
5070 #exit(1)
5071 #exit(1)
5071
5072
5072 if mode==7: #RM
5073 if mode==7: #RM
5073
5074
5074 f = [getattr(data, attr_data) for data in data_inputs][0]
5075 f = [getattr(data, attr_data) for data in data_inputs][0]
5075 g = [getattr(data, attr_data) for data in data_inputs][1]
5076 g = [getattr(data, attr_data) for data in data_inputs][1]
5076
5077
5077 data = numpy.concatenate((f,g),axis=2)
5078 data = numpy.concatenate((f,g),axis=2)
5078 #print(data)
5079 #print(data)
5079 setattr(self.dataOut, attr_data, data)
5080 setattr(self.dataOut, attr_data, data)
5080 #print(self.dataOut.dataPP_POWER.shape)
5081 #print(self.dataOut.dataPP_POWER.shape)
5081 #CONSTRUIR NUEVA ALTURAS
5082 #CONSTRUIR NUEVA ALTURAS
5082 #print("hei_merge",self.dataOut.heightList)
5083 #print("hei_merge",self.dataOut.heightList)
5083 dh = self.dataOut.heightList[1]-self.dataOut.heightList[0]
5084 dh = self.dataOut.heightList[1]-self.dataOut.heightList[0]
5084 heightList_2 = (self.dataOut.heightList[-1]+dh) + numpy.arange(g.shape[-1], dtype=numpy.float) * dh
5085 heightList_2 = (self.dataOut.heightList[-1]+dh) + numpy.arange(g.shape[-1], dtype=numpy.float) * dh
5085
5086
5086 self.dataOut.heightList = numpy.concatenate((self.dataOut.heightList,heightList_2))
5087 self.dataOut.heightList = numpy.concatenate((self.dataOut.heightList,heightList_2))
5087 #print("hei_merge_total",self.dataOut.heightList)
5088 #print("hei_merge_total",self.dataOut.heightList)
5088 #exit(1)
5089 #exit(1)
General Comments 0
You need to be logged in to leave comments. Login now