##// END OF EJS Templates
jroplot_parameters.py jroplot_spectra.py jroIO_digitalRF.py jroproc_parameters.py sophy_proc.py
eynilupu -
r1653:f661d02a9309
parent child
Show More

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

@@ -1,725 +1,736
1 import os
1 import os
2 import datetime
2 import datetime
3 import warnings
3 import warnings
4 import numpy
4 import numpy
5 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
5 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
6 from matplotlib.patches import Circle
6 from matplotlib.patches import Circle
7 import cartopy.crs as ccrs
7 import cartopy.crs as ccrs
8 from cartopy.feature import ShapelyFeature
8 from cartopy.feature import ShapelyFeature
9 import cartopy.io.shapereader as shpreader
9 import cartopy.io.shapereader as shpreader
10
10
11 from schainpy.model.graphics.jroplot_base import Plot, plt
11 from schainpy.model.graphics.jroplot_base import Plot, plt
12 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
12 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
13 from schainpy.utils import log
13 from schainpy.utils import log
14 from schainpy.model.graphics.plotting_codes import cb_tables
14 from schainpy.model.graphics.plotting_codes import cb_tables
15
15
16
16
17 EARTH_RADIUS = 6.3710e3
17 EARTH_RADIUS = 6.3710e3
18
18
19
19
20 def antenna_to_cartesian(ranges, azimuths, elevations):
20 def antenna_to_cartesian(ranges, azimuths, elevations):
21 """
21 """
22 Return Cartesian coordinates from antenna coordinates.
22 Return Cartesian coordinates from antenna coordinates.
23
23
24 Parameters
24 Parameters
25 ----------
25 ----------
26 ranges : array
26 ranges : array
27 Distances to the center of the radar gates (bins) in kilometers.
27 Distances to the center of the radar gates (bins) in kilometers.
28 azimuths : array
28 azimuths : array
29 Azimuth angle of the radar in degrees.
29 Azimuth angle of the radar in degrees.
30 elevations : array
30 elevations : array
31 Elevation angle of the radar in degrees.
31 Elevation angle of the radar in degrees.
32
32
33 Returns
33 Returns
34 -------
34 -------
35 x, y, z : array
35 x, y, z : array
36 Cartesian coordinates in meters from the radar.
36 Cartesian coordinates in meters from the radar.
37
37
38 Notes
38 Notes
39 -----
39 -----
40 The calculation for Cartesian coordinate is adapted from equations
40 The calculation for Cartesian coordinate is adapted from equations
41 2.28(b) and 2.28(c) of Doviak and Zrnic [1]_ assuming a
41 2.28(b) and 2.28(c) of Doviak and Zrnic [1]_ assuming a
42 standard atmosphere (4/3 Earth's radius model).
42 standard atmosphere (4/3 Earth's radius model).
43
43
44 .. math::
44 .. math::
45
45
46 z = \\sqrt{r^2+R^2+2*r*R*sin(\\theta_e)} - R
46 z = \\sqrt{r^2+R^2+2*r*R*sin(\\theta_e)} - R
47
47
48 s = R * arcsin(\\frac{r*cos(\\theta_e)}{R+z})
48 s = R * arcsin(\\frac{r*cos(\\theta_e)}{R+z})
49
49
50 x = s * sin(\\theta_a)
50 x = s * sin(\\theta_a)
51
51
52 y = s * cos(\\theta_a)
52 y = s * cos(\\theta_a)
53
53
54 Where r is the distance from the radar to the center of the gate,
54 Where r is the distance from the radar to the center of the gate,
55 :math:`\\theta_a` is the azimuth angle, :math:`\\theta_e` is the
55 :math:`\\theta_a` is the azimuth angle, :math:`\\theta_e` is the
56 elevation angle, s is the arc length, and R is the effective radius
56 elevation angle, s is the arc length, and R is the effective radius
57 of the earth, taken to be 4/3 the mean radius of earth (6371 km).
57 of the earth, taken to be 4/3 the mean radius of earth (6371 km).
58
58
59 References
59 References
60 ----------
60 ----------
61 .. [1] Doviak and Zrnic, Doppler Radar and Weather Observations, Second
61 .. [1] Doviak and Zrnic, Doppler Radar and Weather Observations, Second
62 Edition, 1993, p. 21.
62 Edition, 1993, p. 21.
63
63
64 """
64 """
65 theta_e = numpy.deg2rad(elevations) # elevation angle in radians.
65 theta_e = numpy.deg2rad(elevations) # elevation angle in radians.
66 theta_a = numpy.deg2rad(azimuths) # azimuth angle in radians.
66 theta_a = numpy.deg2rad(azimuths) # azimuth angle in radians.
67 R = 6371.0 * 1000.0 * 4.0 / 3.0 # effective radius of earth in meters.
67 R = 6371.0 * 1000.0 * 4.0 / 3.0 # effective radius of earth in meters.
68 r = ranges * 1000.0 # distances to gates in meters.
68 r = ranges * 1000.0 # distances to gates in meters.
69
69
70 z = (r ** 2 + R ** 2 + 2.0 * r * R * numpy.sin(theta_e)) ** 0.5 - R
70 z = (r ** 2 + R ** 2 + 2.0 * r * R * numpy.sin(theta_e)) ** 0.5 - R
71 s = R * numpy.arcsin(r * numpy.cos(theta_e) / (R + z)) # arc length in m.
71 s = R * numpy.arcsin(r * numpy.cos(theta_e) / (R + z)) # arc length in m.
72 x = s * numpy.sin(theta_a)
72 x = s * numpy.sin(theta_a)
73 y = s * numpy.cos(theta_a)
73 y = s * numpy.cos(theta_a)
74 return x, y, z
74 return x, y, z
75
75
76 def cartesian_to_geographic_aeqd(x, y, lon_0, lat_0, R=EARTH_RADIUS):
76 def cartesian_to_geographic_aeqd(x, y, lon_0, lat_0, R=EARTH_RADIUS):
77 """
77 """
78 Azimuthal equidistant Cartesian to geographic coordinate transform.
78 Azimuthal equidistant Cartesian to geographic coordinate transform.
79
79
80 Transform a set of Cartesian/Cartographic coordinates (x, y) to
80 Transform a set of Cartesian/Cartographic coordinates (x, y) to
81 geographic coordinate system (lat, lon) using a azimuthal equidistant
81 geographic coordinate system (lat, lon) using a azimuthal equidistant
82 map projection [1]_.
82 map projection [1]_.
83
83
84 .. math::
84 .. math::
85
85
86 lat = \\arcsin(\\cos(c) * \\sin(lat_0) +
86 lat = \\arcsin(\\cos(c) * \\sin(lat_0) +
87 (y * \\sin(c) * \\cos(lat_0) / \\rho))
87 (y * \\sin(c) * \\cos(lat_0) / \\rho))
88
88
89 lon = lon_0 + \\arctan2(
89 lon = lon_0 + \\arctan2(
90 x * \\sin(c),
90 x * \\sin(c),
91 \\rho * \\cos(lat_0) * \\cos(c) - y * \\sin(lat_0) * \\sin(c))
91 \\rho * \\cos(lat_0) * \\cos(c) - y * \\sin(lat_0) * \\sin(c))
92
92
93 \\rho = \\sqrt(x^2 + y^2)
93 \\rho = \\sqrt(x^2 + y^2)
94
94
95 c = \\rho / R
95 c = \\rho / R
96
96
97 Where x, y are the Cartesian position from the center of projection;
97 Where x, y are the Cartesian position from the center of projection;
98 lat, lon the corresponding latitude and longitude; lat_0, lon_0 are the
98 lat, lon the corresponding latitude and longitude; lat_0, lon_0 are the
99 latitude and longitude of the center of the projection; R is the radius of
99 latitude and longitude of the center of the projection; R is the radius of
100 the earth (defaults to ~6371 km). lon is adjusted to be between -180 and
100 the earth (defaults to ~6371 km). lon is adjusted to be between -180 and
101 180.
101 180.
102
102
103 Parameters
103 Parameters
104 ----------
104 ----------
105 x, y : array-like
105 x, y : array-like
106 Cartesian coordinates in the same units as R, typically meters.
106 Cartesian coordinates in the same units as R, typically meters.
107 lon_0, lat_0 : float
107 lon_0, lat_0 : float
108 Longitude and latitude, in degrees, of the center of the projection.
108 Longitude and latitude, in degrees, of the center of the projection.
109 R : float, optional
109 R : float, optional
110 Earth radius in the same units as x and y. The default value is in
110 Earth radius in the same units as x and y. The default value is in
111 units of meters.
111 units of meters.
112
112
113 Returns
113 Returns
114 -------
114 -------
115 lon, lat : array
115 lon, lat : array
116 Longitude and latitude of Cartesian coordinates in degrees.
116 Longitude and latitude of Cartesian coordinates in degrees.
117
117
118 References
118 References
119 ----------
119 ----------
120 .. [1] Snyder, J. P. Map Projections--A Working Manual. U. S. Geological
120 .. [1] Snyder, J. P. Map Projections--A Working Manual. U. S. Geological
121 Survey Professional Paper 1395, 1987, pp. 191-202.
121 Survey Professional Paper 1395, 1987, pp. 191-202.
122
122
123 """
123 """
124 x = numpy.atleast_1d(numpy.asarray(x))
124 x = numpy.atleast_1d(numpy.asarray(x))
125 y = numpy.atleast_1d(numpy.asarray(y))
125 y = numpy.atleast_1d(numpy.asarray(y))
126
126
127 lat_0_rad = numpy.deg2rad(lat_0)
127 lat_0_rad = numpy.deg2rad(lat_0)
128 lon_0_rad = numpy.deg2rad(lon_0)
128 lon_0_rad = numpy.deg2rad(lon_0)
129
129
130 rho = numpy.sqrt(x*x + y*y)
130 rho = numpy.sqrt(x*x + y*y)
131 c = rho / R
131 c = rho / R
132
132
133 with warnings.catch_warnings():
133 with warnings.catch_warnings():
134 # division by zero may occur here but is properly addressed below so
134 # division by zero may occur here but is properly addressed below so
135 # the warnings can be ignored
135 # the warnings can be ignored
136 warnings.simplefilter("ignore", RuntimeWarning)
136 warnings.simplefilter("ignore", RuntimeWarning)
137 lat_rad = numpy.arcsin(numpy.cos(c) * numpy.sin(lat_0_rad) +
137 lat_rad = numpy.arcsin(numpy.cos(c) * numpy.sin(lat_0_rad) +
138 y * numpy.sin(c) * numpy.cos(lat_0_rad) / rho)
138 y * numpy.sin(c) * numpy.cos(lat_0_rad) / rho)
139 lat_deg = numpy.rad2deg(lat_rad)
139 lat_deg = numpy.rad2deg(lat_rad)
140 # fix cases where the distance from the center of the projection is zero
140 # fix cases where the distance from the center of the projection is zero
141 lat_deg[rho == 0] = lat_0
141 lat_deg[rho == 0] = lat_0
142
142
143 x1 = x * numpy.sin(c)
143 x1 = x * numpy.sin(c)
144 x2 = rho*numpy.cos(lat_0_rad)*numpy.cos(c) - y*numpy.sin(lat_0_rad)*numpy.sin(c)
144 x2 = rho*numpy.cos(lat_0_rad)*numpy.cos(c) - y*numpy.sin(lat_0_rad)*numpy.sin(c)
145 lon_rad = lon_0_rad + numpy.arctan2(x1, x2)
145 lon_rad = lon_0_rad + numpy.arctan2(x1, x2)
146 lon_deg = numpy.rad2deg(lon_rad)
146 lon_deg = numpy.rad2deg(lon_rad)
147 # Longitudes should be from -180 to 180 degrees
147 # Longitudes should be from -180 to 180 degrees
148 lon_deg[lon_deg > 180] -= 360.
148 lon_deg[lon_deg > 180] -= 360.
149 lon_deg[lon_deg < -180] += 360.
149 lon_deg[lon_deg < -180] += 360.
150
150
151 return lon_deg, lat_deg
151 return lon_deg, lat_deg
152
152
153 def antenna_to_geographic(ranges, azimuths, elevations, site):
153 def antenna_to_geographic(ranges, azimuths, elevations, site):
154
154
155 x, y, z = antenna_to_cartesian(numpy.array(ranges), numpy.array(azimuths), numpy.array(elevations))
155 x, y, z = antenna_to_cartesian(numpy.array(ranges), numpy.array(azimuths), numpy.array(elevations))
156 lon, lat = cartesian_to_geographic_aeqd(x, y, site[0], site[1], R=6370997.)
156 lon, lat = cartesian_to_geographic_aeqd(x, y, site[0], site[1], R=6370997.)
157
157
158 return lon, lat
158 return lon, lat
159
159
160 def ll2xy(lat1, lon1, lat2, lon2):
160 def ll2xy(lat1, lon1, lat2, lon2):
161
161
162 p = 0.017453292519943295
162 p = 0.017453292519943295
163 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
163 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
164 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
164 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
165 r = 12742 * numpy.arcsin(numpy.sqrt(a))
165 r = 12742 * numpy.arcsin(numpy.sqrt(a))
166 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
166 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
167 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
167 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
168 theta = -theta + numpy.pi/2
168 theta = -theta + numpy.pi/2
169 return r*numpy.cos(theta), r*numpy.sin(theta)
169 return r*numpy.cos(theta), r*numpy.sin(theta)
170
170
171
171
172 def km2deg(km):
172 def km2deg(km):
173 '''
173 '''
174 Convert distance in km to degrees
174 Convert distance in km to degrees
175 '''
175 '''
176
176
177 return numpy.rad2deg(km/EARTH_RADIUS)
177 return numpy.rad2deg(km/EARTH_RADIUS)
178
178
179
179
180
180
181 class SpectralMomentsPlot(SpectraPlot):
181 class SpectralMomentsPlot(SpectraPlot):
182 '''
182 '''
183 Plot for Spectral Moments
183 Plot for Spectral Moments
184 '''
184 '''
185 CODE = 'spc_moments'
185 CODE = 'spc_moments'
186 # colormap = 'jet'
186 # colormap = 'jet'
187 # plot_type = 'pcolor'
187 # plot_type = 'pcolor'
188
188
189 class DobleGaussianPlot(SpectraPlot):
189 class DobleGaussianPlot(SpectraPlot):
190 '''
190 '''
191 Plot for Double Gaussian Plot
191 Plot for Double Gaussian Plot
192 '''
192 '''
193 CODE = 'gaussian_fit'
193 CODE = 'gaussian_fit'
194 # colormap = 'jet'
194 # colormap = 'jet'
195 # plot_type = 'pcolor'
195 # plot_type = 'pcolor'
196
196
197 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
197 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
198 '''
198 '''
199 Plot SpectraCut with Double Gaussian Fit
199 Plot SpectraCut with Double Gaussian Fit
200 '''
200 '''
201 CODE = 'cut_gaussian_fit'
201 CODE = 'cut_gaussian_fit'
202
202
203 class SnrPlot(RTIPlot):
203 class SnrPlot(RTIPlot):
204 '''
204 '''
205 Plot for SNR Data
205 Plot for SNR Data
206 '''
206 '''
207
207
208 CODE = 'snr'
208 CODE = 'snr'
209 colormap = 'jet'
209 colormap = 'jet'
210
210
211 def update(self, dataOut):
211 def update(self, dataOut):
212
212
213 data = {
213 data = {
214 'snr': 10*numpy.log10(dataOut.data_snr)
214 'snr': 10*numpy.log10(dataOut.data_snr)
215 }
215 }
216
216
217 return data, {}
217 return data, {}
218
218
219 class DopplerPlot(RTIPlot):
219 class DopplerPlot(RTIPlot):
220 '''
220 '''
221 Plot for DOPPLER Data (1st moment)
221 Plot for DOPPLER Data (1st moment)
222 '''
222 '''
223
223
224 CODE = 'dop'
224 CODE = 'dop'
225 colormap = 'jet'
225 colormap = 'jet'
226
226
227 def update(self, dataOut):
227 def update(self, dataOut):
228
228
229 data = {
229 data = {
230 'dop': 10*numpy.log10(dataOut.data_dop)
230 'dop': 10*numpy.log10(dataOut.data_dop)
231 }
231 }
232
232
233 return data, {}
233 return data, {}
234
234
235 class PowerPlot(RTIPlot):
235 class PowerPlot(RTIPlot):
236 '''
236 '''
237 Plot for Power Data (0 moment)
237 Plot for Power Data (0 moment)
238 '''
238 '''
239
239
240 CODE = 'pow'
240 CODE = 'pow'
241 colormap = 'jet'
241 colormap = 'jet'
242
242
243 def update(self, dataOut):
243 def update(self, dataOut):
244 data = {
244 data = {
245 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
245 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
246 }
246 }
247 return data, {}
247 return data, {}
248
248
249 class SpectralWidthPlot(RTIPlot):
249 class SpectralWidthPlot(RTIPlot):
250 '''
250 '''
251 Plot for Spectral Width Data (2nd moment)
251 Plot for Spectral Width Data (2nd moment)
252 '''
252 '''
253
253
254 CODE = 'width'
254 CODE = 'width'
255 colormap = 'jet'
255 colormap = 'jet'
256
256
257 def update(self, dataOut):
257 def update(self, dataOut):
258
258
259 data = {
259 data = {
260 'width': dataOut.data_width
260 'width': dataOut.data_width
261 }
261 }
262
262
263 return data, {}
263 return data, {}
264
264
265 class SkyMapPlot(Plot):
265 class SkyMapPlot(Plot):
266 '''
266 '''
267 Plot for meteors detection data
267 Plot for meteors detection data
268 '''
268 '''
269
269
270 CODE = 'param'
270 CODE = 'param'
271
271
272 def setup(self):
272 def setup(self):
273
273
274 self.ncols = 1
274 self.ncols = 1
275 self.nrows = 1
275 self.nrows = 1
276 self.width = 7.2
276 self.width = 7.2
277 self.height = 7.2
277 self.height = 7.2
278 self.nplots = 1
278 self.nplots = 1
279 self.xlabel = 'Zonal Zenith Angle (deg)'
279 self.xlabel = 'Zonal Zenith Angle (deg)'
280 self.ylabel = 'Meridional Zenith Angle (deg)'
280 self.ylabel = 'Meridional Zenith Angle (deg)'
281 self.polar = True
281 self.polar = True
282 self.ymin = -180
282 self.ymin = -180
283 self.ymax = 180
283 self.ymax = 180
284 self.colorbar = False
284 self.colorbar = False
285
285
286 def plot(self):
286 def plot(self):
287
287
288 arrayParameters = numpy.concatenate(self.data['param'])
288 arrayParameters = numpy.concatenate(self.data['param'])
289 error = arrayParameters[:, -1]
289 error = arrayParameters[:, -1]
290 indValid = numpy.where(error == 0)[0]
290 indValid = numpy.where(error == 0)[0]
291 finalMeteor = arrayParameters[indValid, :]
291 finalMeteor = arrayParameters[indValid, :]
292 finalAzimuth = finalMeteor[:, 3]
292 finalAzimuth = finalMeteor[:, 3]
293 finalZenith = finalMeteor[:, 4]
293 finalZenith = finalMeteor[:, 4]
294
294
295 x = finalAzimuth * numpy.pi / 180
295 x = finalAzimuth * numpy.pi / 180
296 y = finalZenith
296 y = finalZenith
297
297
298 ax = self.axes[0]
298 ax = self.axes[0]
299
299
300 if ax.firsttime:
300 if ax.firsttime:
301 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
301 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
302 else:
302 else:
303 ax.plot.set_data(x, y)
303 ax.plot.set_data(x, y)
304
304
305 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
305 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
306 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
306 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
307 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
307 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
308 dt2,
308 dt2,
309 len(x))
309 len(x))
310 self.titles[0] = title
310 self.titles[0] = title
311
311
312
312
313 class GenericRTIPlot(Plot):
313 class GenericRTIPlot(Plot):
314 '''
314 '''
315 Plot for data_xxxx object
315 Plot for data_xxxx object
316 '''
316 '''
317
317
318 CODE = 'param'
318 CODE = 'param'
319 colormap = 'viridis'
319 colormap = 'viridis'
320 plot_type = 'pcolorbuffer'
320 plot_type = 'pcolorbuffer'
321
321
322 def setup(self):
322 def setup(self):
323 self.xaxis = 'time'
323 self.xaxis = 'time'
324 self.ncols = 1
324 self.ncols = 1
325 self.nrows = self.data.shape('param')[0]
325 self.nrows = self.data.shape('param')[0]
326 self.nplots = self.nrows
326 self.nplots = self.nrows
327 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
327 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
328
328
329 if not self.xlabel:
329 if not self.xlabel:
330 self.xlabel = 'Time'
330 self.xlabel = 'Time'
331
331
332 self.ylabel = 'Range [km]'
332 self.ylabel = 'Range [km]'
333 if not self.titles:
333 if not self.titles:
334 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
334 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
335
335
336 def update(self, dataOut):
336 def update(self, dataOut):
337
337
338 data = {
338 data = {
339 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
339 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
340 }
340 }
341
341
342 meta = {}
342 meta = {}
343
343
344 return data, meta
344 return data, meta
345
345
346 def plot(self):
346 def plot(self):
347 # self.data.normalize_heights()
347 # self.data.normalize_heights()
348 self.x = self.data.times
348 self.x = self.data.times
349 self.y = self.data.yrange
349 self.y = self.data.yrange
350 self.z = self.data['param']
350 self.z = self.data['param']
351 self.z = 10*numpy.log10(self.z)
351 self.z = 10*numpy.log10(self.z)
352 self.z = numpy.ma.masked_invalid(self.z)
352 self.z = numpy.ma.masked_invalid(self.z)
353
353
354 if self.decimation is None:
354 if self.decimation is None:
355 x, y, z = self.fill_gaps(self.x, self.y, self.z)
355 x, y, z = self.fill_gaps(self.x, self.y, self.z)
356 else:
356 else:
357 x, y, z = self.fill_gaps(*self.decimate())
357 x, y, z = self.fill_gaps(*self.decimate())
358
358
359 for n, ax in enumerate(self.axes):
359 for n, ax in enumerate(self.axes):
360
360
361 self.zmax = self.zmax if self.zmax is not None else numpy.max(
361 self.zmax = self.zmax if self.zmax is not None else numpy.max(
362 self.z[n])
362 self.z[n])
363 self.zmin = self.zmin if self.zmin is not None else numpy.min(
363 self.zmin = self.zmin if self.zmin is not None else numpy.min(
364 self.z[n])
364 self.z[n])
365
365
366 if ax.firsttime:
366 if ax.firsttime:
367 if self.zlimits is not None:
367 if self.zlimits is not None:
368 self.zmin, self.zmax = self.zlimits[n]
368 self.zmin, self.zmax = self.zlimits[n]
369
369
370 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
370 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
371 vmin=self.zmin,
371 vmin=self.zmin,
372 vmax=self.zmax,
372 vmax=self.zmax,
373 cmap=self.cmaps[n]
373 cmap=self.cmaps[n]
374 )
374 )
375 else:
375 else:
376 if self.zlimits is not None:
376 if self.zlimits is not None:
377 self.zmin, self.zmax = self.zlimits[n]
377 self.zmin, self.zmax = self.zlimits[n]
378 ax.collections.remove(ax.collections[0])
378 ax.collections.remove(ax.collections[0])
379 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
379 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
380 vmin=self.zmin,
380 vmin=self.zmin,
381 vmax=self.zmax,
381 vmax=self.zmax,
382 cmap=self.cmaps[n]
382 cmap=self.cmaps[n]
383 )
383 )
384
384
385
385
386 class PolarMapPlot(Plot):
386 class PolarMapPlot(Plot):
387 '''
387 '''
388 Plot for weather radar
388 Plot for weather radar
389 '''
389 '''
390
390
391 CODE = 'param'
391 CODE = 'param'
392 colormap = 'seismic'
392 colormap = 'seismic'
393
393
394 def setup(self):
394 def setup(self):
395 self.ncols = 1
395 self.ncols = 1
396 self.nrows = 1
396 self.nrows = 1
397 self.width = 9
397 self.width = 9
398 self.height = 8
398 self.height = 8
399 self.mode = self.data.meta['mode']
399 self.mode = self.data.meta['mode']
400 if self.channels is not None:
400 if self.channels is not None:
401 self.nplots = len(self.channels)
401 self.nplots = len(self.channels)
402 self.nrows = len(self.channels)
402 self.nrows = len(self.channels)
403 else:
403 else:
404 self.nplots = self.data.shape(self.CODE)[0]
404 self.nplots = self.data.shape(self.CODE)[0]
405 self.nrows = self.nplots
405 self.nrows = self.nplots
406 self.channels = list(range(self.nplots))
406 self.channels = list(range(self.nplots))
407 if self.mode == 'E':
407 if self.mode == 'E':
408 self.xlabel = 'Longitude'
408 self.xlabel = 'Longitude'
409 self.ylabel = 'Latitude'
409 self.ylabel = 'Latitude'
410 else:
410 else:
411 self.xlabel = 'Range (km)'
411 self.xlabel = 'Range (km)'
412 self.ylabel = 'Height (km)'
412 self.ylabel = 'Height (km)'
413 self.bgcolor = 'white'
413 self.bgcolor = 'white'
414 self.cb_labels = self.data.meta['units']
414 self.cb_labels = self.data.meta['units']
415 self.lat = self.data.meta['latitude']
415 self.lat = self.data.meta['latitude']
416 self.lon = self.data.meta['longitude']
416 self.lon = self.data.meta['longitude']
417 self.xmin, self.xmax = float(
417 self.xmin, self.xmax = float(
418 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
418 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
419 self.ymin, self.ymax = float(
419 self.ymin, self.ymax = float(
420 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
420 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
421 # self.polar = True
421 # self.polar = True
422
422
423 def plot(self):
423 def plot(self):
424
424
425 for n, ax in enumerate(self.axes):
425 for n, ax in enumerate(self.axes):
426 data = self.data['param'][self.channels[n]]
426 data = self.data['param'][self.channels[n]]
427
427
428 zeniths = numpy.linspace(
428 zeniths = numpy.linspace(
429 0, self.data.meta['max_range'], data.shape[1])
429 0, self.data.meta['max_range'], data.shape[1])
430 if self.mode == 'E':
430 if self.mode == 'E':
431 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
431 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
432 r, theta = numpy.meshgrid(zeniths, azimuths)
432 r, theta = numpy.meshgrid(zeniths, azimuths)
433 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
433 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
434 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
434 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
435 x = km2deg(x) + self.lon
435 x = km2deg(x) + self.lon
436 y = km2deg(y) + self.lat
436 y = km2deg(y) + self.lat
437 else:
437 else:
438 azimuths = numpy.radians(self.data.yrange)
438 azimuths = numpy.radians(self.data.yrange)
439 r, theta = numpy.meshgrid(zeniths, azimuths)
439 r, theta = numpy.meshgrid(zeniths, azimuths)
440 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
440 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
441 self.y = zeniths
441 self.y = zeniths
442
442
443 if ax.firsttime:
443 if ax.firsttime:
444 if self.zlimits is not None:
444 if self.zlimits is not None:
445 self.zmin, self.zmax = self.zlimits[n]
445 self.zmin, self.zmax = self.zlimits[n]
446 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
446 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
447 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
447 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
448 vmin=self.zmin,
448 vmin=self.zmin,
449 vmax=self.zmax,
449 vmax=self.zmax,
450 cmap=self.cmaps[n])
450 cmap=self.cmaps[n])
451 else:
451 else:
452 if self.zlimits is not None:
452 if self.zlimits is not None:
453 self.zmin, self.zmax = self.zlimits[n]
453 self.zmin, self.zmax = self.zlimits[n]
454 ax.collections.remove(ax.collections[0])
454 ax.collections.remove(ax.collections[0])
455 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
455 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
456 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
456 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
457 vmin=self.zmin,
457 vmin=self.zmin,
458 vmax=self.zmax,
458 vmax=self.zmax,
459 cmap=self.cmaps[n])
459 cmap=self.cmaps[n])
460
460
461 if self.mode == 'A':
461 if self.mode == 'A':
462 continue
462 continue
463
463
464 # plot district names
464 # plot district names
465 f = open('/data/workspace/schain_scripts/distrito.csv')
465 f = open('/data/workspace/schain_scripts/distrito.csv')
466 for line in f:
466 for line in f:
467 label, lon, lat = [s.strip() for s in line.split(',') if s]
467 label, lon, lat = [s.strip() for s in line.split(',') if s]
468 lat = float(lat)
468 lat = float(lat)
469 lon = float(lon)
469 lon = float(lon)
470 # ax.plot(lon, lat, '.b', ms=2)
470 # ax.plot(lon, lat, '.b', ms=2)
471 ax.text(lon, lat, label.decode('utf8'), ha='center',
471 ax.text(lon, lat, label.decode('utf8'), ha='center',
472 va='bottom', size='8', color='black')
472 va='bottom', size='8', color='black')
473
473
474 # plot limites
474 # plot limites
475 limites = []
475 limites = []
476 tmp = []
476 tmp = []
477 for line in open('/data/workspace/schain_scripts/lima.csv'):
477 for line in open('/data/workspace/schain_scripts/lima.csv'):
478 if '#' in line:
478 if '#' in line:
479 if tmp:
479 if tmp:
480 limites.append(tmp)
480 limites.append(tmp)
481 tmp = []
481 tmp = []
482 continue
482 continue
483 values = line.strip().split(',')
483 values = line.strip().split(',')
484 tmp.append((float(values[0]), float(values[1])))
484 tmp.append((float(values[0]), float(values[1])))
485 for points in limites:
485 for points in limites:
486 ax.add_patch(
486 ax.add_patch(
487 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
487 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
488
488
489 # plot Cuencas
489 # plot Cuencas
490 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
490 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
491 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
491 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
492 values = [line.strip().split(',') for line in f]
492 values = [line.strip().split(',') for line in f]
493 points = [(float(s[0]), float(s[1])) for s in values]
493 points = [(float(s[0]), float(s[1])) for s in values]
494 ax.add_patch(Polygon(points, ec='b', fc='none'))
494 ax.add_patch(Polygon(points, ec='b', fc='none'))
495
495
496 # plot grid
496 # plot grid
497 for r in (15, 30, 45, 60):
497 for r in (15, 30, 45, 60):
498 ax.add_artist(plt.Circle((self.lon, self.lat),
498 ax.add_artist(plt.Circle((self.lon, self.lat),
499 km2deg(r), color='0.6', fill=False, lw=0.2))
499 km2deg(r), color='0.6', fill=False, lw=0.2))
500 ax.text(
500 ax.text(
501 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
501 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
502 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
502 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
503 '{}km'.format(r),
503 '{}km'.format(r),
504 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
504 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
505
505
506 if self.mode == 'E':
506 if self.mode == 'E':
507 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
507 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
508 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
508 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
509 else:
509 else:
510 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
510 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
511 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
511 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
512
512
513 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
513 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
514 self.titles = ['{} {}'.format(
514 self.titles = ['{} {}'.format(
515 self.data.parameters[x], title) for x in self.channels]
515 self.data.parameters[x], title) for x in self.channels]
516
516
517 class WeatherParamsPlot(Plot):
517 class WeatherParamsPlot(Plot):
518 #CODE = 'RHI'
518 #CODE = 'RHI'
519 #plot_name = 'RHI'
519 #plot_name = 'RHI'
520 plot_type = 'scattermap'
520 plot_type = 'scattermap'
521 buffering = False
521 buffering = False
522 projection = ccrs.PlateCarree()
522 projection = ccrs.PlateCarree()
523
523
524 def setup(self):
524 def setup(self):
525
525
526 self.ncols = 1
526 self.ncols = 1
527 self.nrows = 1
527 self.nrows = 1
528 self.nplots= 1
528 self.nplots= 1
529 self.ylabel= 'Height [km]'
529 self.ylabel= 'Height [km]'
530 self.xlabel= 'Distance from radar [km]'
530 self.xlabel= 'Distance from radar [km]'
531
531
532 if self.channels is not None:
532 if self.channels is not None:
533 self.nplots = len(self.channels)
533 self.nplots = len(self.channels)
534 self.ncols = len(self.channels)
534 self.ncols = len(self.channels)
535 else:
535 else:
536 self.nplots = self.data.shape(self.CODE)[0]
536 self.nplots = self.data.shape(self.CODE)[0]
537 self.ncols = self.nplots
537 self.ncols = self.nplots
538 self.channels = list(range(self.nplots))
538 self.channels = list(range(self.nplots))
539
539
540 self.colorbar=True
540 self.colorbar=True
541 if len(self.channels)>1:
541 if len(self.channels)>1:
542 self.width = 12
542 self.width = 12
543 else:
543 else:
544 self.width =8
544 self.width =8
545 self.height =7
545 self.height =7
546 self.ini =0
546 self.ini =0
547 self.len_azi =0
547 self.len_azi =0
548 self.buffer_ini = None
548 self.buffer_ini = None
549 self.buffer_ele = None
549 self.buffer_ele = None
550 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.1})
550 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.1})
551 self.flag =0
551 self.flag =0
552 self.indicador= 0
552 self.indicador= 0
553 self.last_data_ele = None
553 self.last_data_ele = None
554 self.val_mean = None
554 self.val_mean = None
555
555
556 def update(self, dataOut):
556 def update(self, dataOut):
557
557
558 vars = {
558 vars = {
559 'S' : 0,
559 'S' : 0,
560 'V' : 1,
560 'V' : 1,
561 'W' : 2,
561 'W' : 2,
562 'SNR' : 3,
562 'SNR' : 3,
563 'Z' : 4,
563 'Z' : 4,
564 'D' : 5,
564 'D' : 5,
565 'P' : 6,
565 'P' : 6,
566 'R' : 7,
566 'R' : 7,
567 }
567 }
568
568
569 data = {}
569 data = {}
570 meta = {}
570 meta = {}
571
571
572 if hasattr(dataOut, 'nFFTPoints'):
572 if hasattr(dataOut, 'nFFTPoints'):
573 factor = dataOut.normFactor
573 factor = dataOut.normFactor
574 else:
574 else:
575 factor = 1
575 factor = 1
576
576
577 if hasattr(dataOut, 'dparam'):
577 if hasattr(dataOut, 'dparam'):
578 tmp = getattr(dataOut, 'data_param')
578 tmp = getattr(dataOut, 'data_param')
579 else:
579 else:
580
580 #print("-------------------self.attr_data[0]",self.attr_data[0])
581 if 'S' in self.attr_data[0]:
581 if 'S' in self.attr_data[0]:
582 tmp = 10*numpy.log10(10.0*getattr(dataOut, 'data_param')[:,0,:]/(factor))
582 if self.attr_data[0]=='S':
583 tmp = 10*numpy.log10(10.0*getattr(dataOut, 'data_param')[:,0,:]/(factor))
584 if self.attr_data[0]=='SNR':
585 tmp = 10*numpy.log10(getattr(dataOut, 'data_param')[:,3,:])
583 else:
586 else:
584 tmp = getattr(dataOut, 'data_param')[:,vars[self.attr_data[0]],:]
587 tmp = getattr(dataOut, 'data_param')[:,vars[self.attr_data[0]],:]
585
588
586 if self.mask:
589 if self.mask:
587 mask = dataOut.data_param[:,3,:] < self.mask
590 mask = dataOut.data_param[:,3,:] < self.mask
588 tmp = numpy.ma.masked_array(tmp, mask=mask)
591 tmp = numpy.ma.masked_array(tmp, mask=mask)
589
592
590 r = dataOut.heightList
593 r = dataOut.heightList
591 delta_height = r[1]-r[0]
594 delta_height = r[1]-r[0]
592 valid = numpy.where(r>=0)[0]
595 valid = numpy.where(r>=0)[0]
593 data['r'] = numpy.arange(len(valid))*delta_height
596 data['r'] = numpy.arange(len(valid))*delta_height
594
597
595 data['data'] = [0, 0]
598 data['data'] = [0, 0]
596
599
597 try:
600 try:
598 data['data'][0] = tmp[0][:,valid]
601 data['data'][0] = tmp[0][:,valid]
599 data['data'][1] = tmp[1][:,valid]
602 data['data'][1] = tmp[1][:,valid]
600 except:
603 except:
601 data['data'][0] = tmp[0][:,valid]
604 data['data'][0] = tmp[0][:,valid]
602 data['data'][1] = tmp[0][:,valid]
605 data['data'][1] = tmp[0][:,valid]
603
606
604 if dataOut.mode_op == 'PPI':
607 if dataOut.mode_op == 'PPI':
605 self.CODE = 'PPI'
608 self.CODE = 'PPI'
606 self.title = self.CODE
609 self.title = self.CODE
607 elif dataOut.mode_op == 'RHI':
610 elif dataOut.mode_op == 'RHI':
608 self.CODE = 'RHI'
611 self.CODE = 'RHI'
609 self.title = self.CODE
612 self.title = self.CODE
610
613
611 data['azi'] = dataOut.data_azi
614 data['azi'] = dataOut.data_azi
612 data['ele'] = dataOut.data_ele
615 data['ele'] = dataOut.data_ele
616
617 if isinstance(dataOut.mode_op, bytes):
618 try:
619 dataOut.mode_op = dataOut.mode_op.decode()
620 except:
621 dataOut.mode_op = str(dataOut.mode_op, 'utf-8')
613 data['mode_op'] = dataOut.mode_op
622 data['mode_op'] = dataOut.mode_op
614 self.mode = dataOut.mode_op
623 self.mode = dataOut.mode_op
615
624
616 return data, meta
625 return data, meta
617
626
618 def plot(self):
627 def plot(self):
619 data = self.data[-1]
628 data = self.data[-1]
620 z = data['data']
629 z = data['data']
621 r = data['r']
630 r = data['r']
622 self.titles = []
631 self.titles = []
623
632
624 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
633 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
625 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
634 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
626 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
635 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
627 self.zmin = self.zmin if self.zmin is not None else numpy.nanmin(z)
636 self.zmin = self.zmin if self.zmin is not None else numpy.nanmin(z)
628
637
629 if isinstance(data['mode_op'], bytes):
638 if isinstance(data['mode_op'], bytes):
630 data['mode_op'] = data['mode_op'].decode()
639 data['mode_op'] = data['mode_op'].decode()
631
640
632 if data['mode_op'] == 'RHI':
641 if data['mode_op'] == 'RHI':
633 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']))
642 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']))
634 len_aux = int(data['azi'].shape[0]/4)
643 len_aux = int(data['azi'].shape[0]/4)
635 mean = numpy.mean(data['azi'][len_aux:-len_aux])
644 mean = numpy.mean(data['azi'][len_aux:-len_aux])
636 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
645 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
637 elif data['mode_op'] == 'PPI':
646 elif data['mode_op'] == 'PPI':
638 r, theta = numpy.meshgrid(r, -numpy.radians(data['azi'])+numpy.pi/2)
647 r, theta = numpy.meshgrid(r, -numpy.radians(data['azi'])+numpy.pi/2)
639 len_aux = int(data['ele'].shape[0]/4)
648 len_aux = int(data['ele'].shape[0]/4)
640 mean = numpy.mean(data['ele'][len_aux:-len_aux])
649 mean = numpy.mean(data['ele'][len_aux:-len_aux])
641 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(mean)), r*numpy.sin(
650 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(mean)), r*numpy.sin(
642 theta)*numpy.cos(numpy.radians(mean))
651 theta)*numpy.cos(numpy.radians(mean))
643 x = km2deg(x) + -75.295893
652 x = km2deg(x) + -75.295893
644 y = km2deg(y) + -12.040436
653 y = km2deg(y) + -12.040436
645
654
646 self.clear_figures()
655 self.clear_figures()
647
656
648 if data['mode_op'] == 'PPI':
657 if data['mode_op'] == 'PPI':
649 axes = self.axes['PPI']
658 axes = self.axes['PPI']
650 else:
659 else:
651 axes = self.axes['RHI']
660 axes = self.axes['RHI']
652
661
653 if self.colormap in cb_tables:
662 if self.colormap in cb_tables:
654 norm = cb_tables[self.colormap]['norm']
663 norm = cb_tables[self.colormap]['norm']
655 else:
664 else:
656 norm = None
665 norm = None
657
666
658 for i, ax in enumerate(axes):
667 for i, ax in enumerate(axes):
659 if data['mode_op'] == 'PPI':
668 if data['mode_op'] == 'PPI':
660 ax.set_extent([-75.745893, -74.845893, -12.490436, -11.590436])
669 ax.set_extent([-75.745893, -74.845893, -12.490436, -11.590436])
661
670
662 if norm is None:
671 if norm is None:
663 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
672 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
664 else:
673 else:
665 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, norm=norm)
674 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, norm=norm)
666
675
667 if data['mode_op'] == 'RHI':
676 if data['mode_op'] == 'RHI':
668 len_aux = int(data['azi'].shape[0]/4)
677 len_aux = int(data['azi'].shape[0]/4)
669 mean = numpy.mean(data['azi'][len_aux:-len_aux])
678 mean = numpy.mean(data['azi'][len_aux:-len_aux])
670 if len(self.channels) !=1:
679 if len(self.channels) !=1:
671 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
680 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
672 else:
681 else:
673 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
682 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
674 elif data['mode_op'] == 'PPI':
683 elif data['mode_op'] == 'PPI':
675 len_aux = int(data['ele'].shape[0]/4)
684 len_aux = int(data['ele'].shape[0]/4)
676 mean = numpy.mean(data['ele'][len_aux:-len_aux])
685 mean = numpy.mean(data['ele'][len_aux:-len_aux])
677 if len(self.channels) !=1:
686 if len(self.channels) !=1:
678 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
687 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
679 else:
688 else:
680 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
689 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
681 self.mode_value = round(mean,1)
690 self.mode_value = round(mean,1)
682
691
683 if data['mode_op'] == 'PPI':
692 if data['mode_op'] == 'PPI':
684 gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
693 gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
685 linewidth=1, color='gray', alpha=0.5, linestyle='--')
694 linewidth=1, color='gray', alpha=0.5, linestyle='--')
686 gl.xlabel_style = {'size': 8}
695 gl.xlabel_style = {'size': 8}
687 gl.ylabel_style = {'size': 8}
696 gl.ylabel_style = {'size': 8}
688 gl.xlabels_top = False
697 gl.xlabels_top = False
689 gl.ylabels_right = False
698 gl.ylabels_right = False
699 #self.shapes="/home/soporte/workspace/sirm/volumes/schain/shapes/"
700 #print("self.shapes",self.shapes)
690 shape_p = os.path.join(self.shapes,'PER_ADM2/PER_ADM2.shp')
701 shape_p = os.path.join(self.shapes,'PER_ADM2/PER_ADM2.shp')
691 shape_d = os.path.join(self.shapes,'PER_ADM1/PER_ADM1.shp')
702 shape_d = os.path.join(self.shapes,'PER_ADM1/PER_ADM1.shp')
692 capitales = os.path.join(self.shapes,'CAPITALES/cap_provincia.shp')
703 capitales = os.path.join(self.shapes,'CAPITALES/cap_provincia.shp')
693 vias = os.path.join(self.shapes,'Carreteras/VIAS_NACIONAL_250000.shp')
704 vias = os.path.join(self.shapes,'Carreteras/VIAS_NACIONAL_250000.shp')
694 reader_d = shpreader.BasicReader(shape_p, encoding='latin1')
705 reader_d = shpreader.BasicReader(shape_p, encoding='latin1')
695 reader_p = shpreader.BasicReader(shape_d, encoding='latin1')
706 reader_p = shpreader.BasicReader(shape_d, encoding='latin1')
696 reader_c = shpreader.BasicReader(capitales, encoding='latin1')
707 reader_c = shpreader.BasicReader(capitales, encoding='latin1')
697 reader_v = shpreader.BasicReader(vias, encoding='latin1')
708 reader_v = shpreader.BasicReader(vias, encoding='latin1')
698 caps = [x for x in reader_c.records() if x.attributes["Departa"] in ("JUNIN", "LIMA", "AYACUCHO", "HUANCAVELICA")]
709 caps = [x for x in reader_c.records() if x.attributes["Departa"] in ("JUNIN", "LIMA", "AYACUCHO", "HUANCAVELICA")]
699 districts = [x for x in reader_d.records() if x.attributes["Name"] in ("JUNÍN", "CHANCHAMAYO", "CHUPACA", "CONCEPCIΓ“N", "HUANCAYO", "JAUJA", "SATIPO", "TARMA", "YAUYOS", "HUAROCHIRÍ", "CANTA", "HUANTA", "TAYACAJA")]
710 districts = [x for x in reader_d.records() if x.attributes["Name"] in ("JUNÍN", "CHANCHAMAYO", "CHUPACA", "CONCEPCIΓ“N", "HUANCAYO", "JAUJA", "SATIPO", "TARMA", "YAUYOS", "HUAROCHIRÍ", "CANTA", "HUANTA", "TAYACAJA")]
700 provs = [x for x in reader_p.records() if x.attributes["NAME"] in ("JunΓ­n", "Lima")]
711 provs = [x for x in reader_p.records() if x.attributes["NAME"] in ("JunΓ­n", "Lima")]
701 vias = [x for x in reader_v.records() if x.attributes["DEP"] in ("JUNIN", "LIMA")]
712 vias = [x for x in reader_v.records() if x.attributes["DEP"] in ("JUNIN", "LIMA")]
702
713
703 # Display limits and streets
714 # Display limits and streets
704 shape_feature = ShapelyFeature([x.geometry for x in districts], ccrs.PlateCarree(), facecolor="none", edgecolor='grey', lw=0.5)
715 shape_feature = ShapelyFeature([x.geometry for x in districts], ccrs.PlateCarree(), facecolor="none", edgecolor='grey', lw=0.5)
705 ax.add_feature(shape_feature)
716 ax.add_feature(shape_feature)
706 shape_feature = ShapelyFeature([x.geometry for x in provs], ccrs.PlateCarree(), facecolor="none", edgecolor='white', lw=1)
717 shape_feature = ShapelyFeature([x.geometry for x in provs], ccrs.PlateCarree(), facecolor="none", edgecolor='white', lw=1)
707 ax.add_feature(shape_feature)
718 ax.add_feature(shape_feature)
708 shape_feature = ShapelyFeature([x.geometry for x in vias], ccrs.PlateCarree(), facecolor="none", edgecolor='yellow', lw=1)
719 shape_feature = ShapelyFeature([x.geometry for x in vias], ccrs.PlateCarree(), facecolor="none", edgecolor='yellow', lw=1)
709 ax.add_feature(shape_feature)
720 ax.add_feature(shape_feature)
710
721
711 for cap in caps:
722 for cap in caps:
712 if cap.attributes['Nombre'] in ("LA OROYA", "CONCEPCIΓ“N", "HUANCAYO", "JAUJA", "CHUPACA", "YAUYOS", "HUANTA", "PAMPAS"):
723 if cap.attributes['Nombre'] in ("LA OROYA", "CONCEPCIΓ“N", "HUANCAYO", "JAUJA", "CHUPACA", "YAUYOS", "HUANTA", "PAMPAS"):
713 ax.text(cap.attributes['X'], cap.attributes['Y'], cap.attributes['Nombre'].title(), size=7, color='white')
724 ax.text(cap.attributes['X'], cap.attributes['Y'], cap.attributes['Nombre'].title(), size=7, color='white')
714 ax.text(-75.052003, -11.915552, 'Huaytapallana', size=7, color='cyan')
725 ax.text(-75.052003, -11.915552, 'Huaytapallana', size=7, color='cyan')
715 ax.plot(-75.052003, -11.915552, '*')
726 ax.plot(-75.052003, -11.915552, '*')
716
727
717 for R in (10, 20, 30 , 40, 50):
728 for R in (10, 20, 30 , 40, 50):
718 circle = Circle((-75.295893, -12.040436), km2deg(R), facecolor='none',
729 circle = Circle((-75.295893, -12.040436), km2deg(R), facecolor='none',
719 edgecolor='skyblue', linewidth=1, alpha=0.5)
730 edgecolor='skyblue', linewidth=1, alpha=0.5)
720 ax.add_patch(circle)
731 ax.add_patch(circle)
721 ax.text(km2deg(R)*numpy.cos(numpy.radians(45))-75.295893,
732 ax.text(km2deg(R)*numpy.cos(numpy.radians(45))-75.295893,
722 km2deg(R)*numpy.sin(numpy.radians(45))-12.040436,
733 km2deg(R)*numpy.sin(numpy.radians(45))-12.040436,
723 '{}km'.format(R), color='skyblue', size=7)
734 '{}km'.format(R), color='skyblue', size=7)
724 elif data['mode_op'] == 'RHI':
735 elif data['mode_op'] == 'RHI':
725 ax.grid(color='grey', alpha=0.5, linestyle='--', linewidth=1)
736 ax.grid(color='grey', alpha=0.5, linestyle='--', linewidth=1)
@@ -1,743 +1,743
1 # Copyright (c) 2012-2021 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2021 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Classes to plot Spectra data
5 """Classes to plot Spectra data
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import numpy
10 import numpy
11
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13
13
14
14
15 class SpectraPlot(Plot):
15 class SpectraPlot(Plot):
16 '''
16 '''
17 Plot for Spectra data
17 Plot for Spectra data
18 '''
18 '''
19
19
20 CODE = 'spc'
20 CODE = 'spc'
21 colormap = 'jet'
21 colormap = 'jet'
22 plot_type = 'pcolor'
22 plot_type = 'pcolor'
23 buffering = False
23 buffering = False
24
24
25 def setup(self):
25 def setup(self):
26 self.nplots = len(self.data.channels)
26 self.nplots = len(self.data.channels)
27 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
27 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
28 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
28 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
29 self.height = 2.6 * self.nrows
29 self.height = 2.6 * self.nrows
30 self.cb_label = 'dB'
30 self.cb_label = 'dB'
31 if self.showprofile:
31 if self.showprofile:
32 self.width = 4 * self.ncols
32 self.width = 4 * self.ncols
33 else:
33 else:
34 self.width = 3.5 * self.ncols
34 self.width = 3.5 * self.ncols
35 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
35 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
36 self.ylabel = 'Range [km]'
36 self.ylabel = 'Range [km]'
37
37
38 def update(self, dataOut):
38 def update(self, dataOut):
39
39
40 data = {}
40 data = {}
41 meta = {}
41 meta = {}
42 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
42 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
43 data['spc'] = spc
43 data['spc'] = spc
44 data['rti'] = dataOut.getPower()
44 data['rti'] = dataOut.getPower()
45 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
45 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
46 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
46 meta['xrange'] = (dataOut.getFreqRange(0)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(0))
47
47
48 if self.CODE == 'spc_moments':
48 if self.CODE == 'spc_moments':
49 data['moments'] = dataOut.moments
49 data['moments'] = dataOut.moments
50 # data['spc'] = 10*numpy.log10(dataOut.data_pre[0]/dataOut.normFactor)
50 # data['spc'] = 10*numpy.log10(dataOut.data_pre[0]/dataOut.normFactor)
51 if self.CODE == 'gaussian_fit':
51 if self.CODE == 'gaussian_fit':
52 # data['moments'] = dataOut.moments
52 # data['moments'] = dataOut.moments
53 data['gaussfit'] = dataOut.DGauFitParams
53 data['gaussfit'] = dataOut.DGauFitParams
54 # data['spc'] = 10*numpy.log10(dataOut.data_pre[0]/dataOut.normFactor)
54 # data['spc'] = 10*numpy.log10(dataOut.data_pre[0]/dataOut.normFactor)
55
55
56 return data, meta
56 return data, meta
57
57
58 def plot(self):
58 def plot(self):
59 if self.xaxis == "frequency":
59 if self.xaxis == "frequency":
60 x = self.data.xrange[0]
60 x = self.data.xrange[0]
61 self.xlabel = "Frequency (kHz)"
61 self.xlabel = "Frequency (kHz)"
62 elif self.xaxis == "time":
62 elif self.xaxis == "time":
63 x = self.data.xrange[1]
63 x = self.data.xrange[1]
64 self.xlabel = "Time (ms)"
64 self.xlabel = "Time (ms)"
65 else:
65 else:
66 x = self.data.xrange[2]
66 x = self.data.xrange[2]
67 self.xlabel = "Velocity (m/s)"
67 self.xlabel = "Velocity (m/s)"
68
68
69 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
69 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
70 x = self.data.xrange[2]
70 x = self.data.xrange[2]
71 self.xlabel = "Velocity (m/s)"
71 self.xlabel = "Velocity (m/s)"
72
72
73 self.titles = []
73 self.titles = []
74
74
75 y = self.data.yrange
75 y = self.data.yrange
76 self.y = y
76 self.y = y
77
77
78 data = self.data[-1]
78 data = self.data[-1]
79 z = data['spc']
79 z = data['spc']
80
80
81 for n, ax in enumerate(self.axes):
81 for n, ax in enumerate(self.axes):
82 noise = data['noise'][n]
82 noise = data['noise'][n]
83 if self.CODE == 'spc_moments':
83 if self.CODE == 'spc_moments':
84 mean = data['moments'][n, 1]
84 mean = data['moments'][n, 1]
85 if self.CODE == 'gaussian_fit':
85 if self.CODE == 'gaussian_fit':
86 # mean = data['moments'][n, 1]
86 # mean = data['moments'][n, 1]
87 gau0 = data['gaussfit'][n][2,:,0]
87 gau0 = data['gaussfit'][n][2,:,0]
88 gau1 = data['gaussfit'][n][2,:,1]
88 gau1 = data['gaussfit'][n][2,:,1]
89 if ax.firsttime:
89 if ax.firsttime:
90 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
90 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
91 self.xmin = self.xmin if self.xmin else -self.xmax
91 self.xmin = self.xmin if self.xmin else -self.xmax
92 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
92 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
93 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
93 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
94 ax.plt = ax.pcolormesh(x, y, z[n].T,
94 ax.plt = ax.pcolormesh(x, y, z[n].T,
95 vmin=self.zmin,
95 vmin=self.zmin,
96 vmax=self.zmax,
96 vmax=self.zmax,
97 cmap=plt.get_cmap(self.colormap)
97 cmap=plt.get_cmap(self.colormap)
98 )
98 )
99
99
100 if self.showprofile:
100 if self.showprofile:
101 ax.plt_profile = self.pf_axes[n].plot(
101 ax.plt_profile = self.pf_axes[n].plot(
102 data['rti'][n], y)[0]
102 data['rti'][n], y)[0]
103 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
103 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
104 color="k", linestyle="dashed", lw=1)[0]
104 color="k", linestyle="dashed", lw=1)[0]
105 if self.CODE == 'spc_moments':
105 if self.CODE == 'spc_moments':
106 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
106 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
107 if self.CODE == 'gaussian_fit':
107 if self.CODE == 'gaussian_fit':
108 # ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
108 # ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
109 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
109 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
110 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
110 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
111 else:
111 else:
112 ax.plt.set_array(z[n].T.ravel())
112 ax.plt.set_array(z[n].T.ravel())
113 if self.showprofile:
113 if self.showprofile:
114 ax.plt_profile.set_data(data['rti'][n], y)
114 ax.plt_profile.set_data(data['rti'][n], y)
115 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
115 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
116 if self.CODE == 'spc_moments':
116 if self.CODE == 'spc_moments':
117 ax.plt_mean.set_data(mean, y)
117 ax.plt_mean.set_data(mean, y)
118 if self.CODE == 'gaussian_fit':
118 if self.CODE == 'gaussian_fit':
119 # ax.plt_mean.set_data(mean, y)
119 # ax.plt_mean.set_data(mean, y)
120 ax.plt_gau0.set_data(gau0, y)
120 ax.plt_gau0.set_data(gau0, y)
121 ax.plt_gau1.set_data(gau1, y)
121 ax.plt_gau1.set_data(gau1, y)
122 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
122 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
123
123
124
124
125 class CrossSpectraPlot(Plot):
125 class CrossSpectraPlot(Plot):
126
126
127 CODE = 'cspc'
127 CODE = 'cspc'
128 colormap = 'jet'
128 colormap = 'jet'
129 plot_type = 'pcolor'
129 plot_type = 'pcolor'
130 zmin_coh = None
130 zmin_coh = None
131 zmax_coh = None
131 zmax_coh = None
132 zmin_phase = None
132 zmin_phase = None
133 zmax_phase = None
133 zmax_phase = None
134
134
135 def setup(self):
135 def setup(self):
136
136
137 self.ncols = 4
137 self.ncols = 4
138 self.nplots = len(self.data.pairs) * 2
138 self.nplots = len(self.data.pairs) * 2
139 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
139 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
140 self.width = 3.1 * self.ncols
140 self.width = 3.1 * self.ncols
141 self.height = 2.6 * self.nrows
141 self.height = 2.6 * self.nrows
142 self.ylabel = 'Range [km]'
142 self.ylabel = 'Range [km]'
143 self.showprofile = False
143 self.showprofile = False
144 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
144 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
145
145
146 def update(self, dataOut):
146 def update(self, dataOut):
147
147
148 data = {}
148 data = {}
149 meta = {}
149 meta = {}
150
150
151 spc = dataOut.data_spc
151 spc = dataOut.data_spc
152 cspc = dataOut.data_cspc
152 cspc = dataOut.data_cspc
153 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
153 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
154 meta['pairs'] = dataOut.pairsList
154 meta['pairs'] = dataOut.pairsList
155
155
156 tmp = []
156 tmp = []
157
157
158 for n, pair in enumerate(meta['pairs']):
158 for n, pair in enumerate(meta['pairs']):
159 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
159 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
160 coh = numpy.abs(out)
160 coh = numpy.abs(out)
161 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
161 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
162 tmp.append(coh)
162 tmp.append(coh)
163 tmp.append(phase)
163 tmp.append(phase)
164
164
165 data['cspc'] = numpy.array(tmp)
165 data['cspc'] = numpy.array(tmp)
166
166
167 return data, meta
167 return data, meta
168
168
169 def plot(self):
169 def plot(self):
170
170
171 if self.xaxis == "frequency":
171 if self.xaxis == "frequency":
172 x = self.data.xrange[0]
172 x = self.data.xrange[0]
173 self.xlabel = "Frequency (kHz)"
173 self.xlabel = "Frequency (kHz)"
174 elif self.xaxis == "time":
174 elif self.xaxis == "time":
175 x = self.data.xrange[1]
175 x = self.data.xrange[1]
176 self.xlabel = "Time (ms)"
176 self.xlabel = "Time (ms)"
177 else:
177 else:
178 x = self.data.xrange[2]
178 x = self.data.xrange[2]
179 self.xlabel = "Velocity (m/s)"
179 self.xlabel = "Velocity (m/s)"
180
180
181 self.titles = []
181 self.titles = []
182
182
183 y = self.data.yrange
183 y = self.data.yrange
184 self.y = y
184 self.y = y
185
185
186 data = self.data[-1]
186 data = self.data[-1]
187 cspc = data['cspc']
187 cspc = data['cspc']
188
188
189 for n in range(len(self.data.pairs)):
189 for n in range(len(self.data.pairs)):
190 pair = self.data.pairs[n]
190 pair = self.data.pairs[n]
191 coh = cspc[n*2]
191 coh = cspc[n*2]
192 phase = cspc[n*2+1]
192 phase = cspc[n*2+1]
193 ax = self.axes[2 * n]
193 ax = self.axes[2 * n]
194 if ax.firsttime:
194 if ax.firsttime:
195 ax.plt = ax.pcolormesh(x, y, coh.T,
195 ax.plt = ax.pcolormesh(x, y, coh.T,
196 vmin=0,
196 vmin=0,
197 vmax=1,
197 vmax=1,
198 cmap=plt.get_cmap(self.colormap_coh)
198 cmap=plt.get_cmap(self.colormap_coh)
199 )
199 )
200 else:
200 else:
201 ax.plt.set_array(coh.T.ravel())
201 ax.plt.set_array(coh.T.ravel())
202 self.titles.append(
202 self.titles.append(
203 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
203 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
204
204
205 ax = self.axes[2 * n + 1]
205 ax = self.axes[2 * n + 1]
206 if ax.firsttime:
206 if ax.firsttime:
207 ax.plt = ax.pcolormesh(x, y, phase.T,
207 ax.plt = ax.pcolormesh(x, y, phase.T,
208 vmin=-180,
208 vmin=-180,
209 vmax=180,
209 vmax=180,
210 cmap=plt.get_cmap(self.colormap_phase)
210 cmap=plt.get_cmap(self.colormap_phase)
211 )
211 )
212 else:
212 else:
213 ax.plt.set_array(phase.T.ravel())
213 ax.plt.set_array(phase.T.ravel())
214 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
214 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
215
215
216
216
217 class RTIPlot(Plot):
217 class RTIPlot(Plot):
218 '''
218 '''
219 Plot for RTI data
219 Plot for RTI data
220 '''
220 '''
221
221
222 CODE = 'rti'
222 CODE = 'rti'
223 colormap = 'jet'
223 colormap = 'jet'
224 plot_type = 'pcolorbuffer'
224 plot_type = 'pcolorbuffer'
225
225
226 def setup(self):
226 def setup(self):
227 self.xaxis = 'time'
227 self.xaxis = 'time'
228 self.ncols = 1
228 self.ncols = 1
229 self.nrows = len(self.data.channels)
229 self.nrows = len(self.data.channels)
230 self.nplots = len(self.data.channels)
230 self.nplots = len(self.data.channels)
231 self.ylabel = 'Range [km]'
231 self.ylabel = 'Range [km]'
232 self.xlabel = 'Time'
232 self.xlabel = 'Time'
233 self.cb_label = 'dB'
233 self.cb_label = 'dB'
234 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
234 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
235 self.titles = ['{} Channel {}'.format(
235 self.titles = ['{} Channel {}'.format(
236 self.CODE.upper(), x) for x in range(self.nrows)]
236 self.CODE.upper(), x) for x in range(self.nrows)]
237
237
238 def update(self, dataOut):
238 def update(self, dataOut):
239
239
240 data = {}
240 data = {}
241 meta = {}
241 meta = {}
242 data['rti'] = dataOut.getPower()
242 data['rti'] = dataOut.getPower()
243 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
243 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
244
244
245 return data, meta
245 return data, meta
246
246
247 def plot(self):
247 def plot(self):
248 self.x = self.data.times
248 self.x = self.data.times
249 self.y = self.data.yrange
249 self.y = self.data.yrange
250 self.z = self.data[self.CODE]
250 self.z = self.data[self.CODE]
251 self.z = numpy.ma.masked_invalid(self.z)
251 self.z = numpy.ma.masked_invalid(self.z)
252
252
253 if self.decimation is None:
253 if self.decimation is None:
254 x, y, z = self.fill_gaps(self.x, self.y, self.z)
254 x, y, z = self.fill_gaps(self.x, self.y, self.z)
255 else:
255 else:
256 x, y, z = self.fill_gaps(*self.decimate())
256 x, y, z = self.fill_gaps(*self.decimate())
257
257
258 for n, ax in enumerate(self.axes):
258 for n, ax in enumerate(self.axes):
259 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
259 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
260 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
260 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
261 data = self.data[-1]
261 data = self.data[-1]
262 if ax.firsttime:
262 if ax.firsttime:
263 ax.plt = ax.pcolormesh(x, y, z[n].T,
263 ax.plt = ax.pcolormesh(x, y, z[n].T,
264 vmin=self.zmin,
264 vmin=self.zmin,
265 vmax=self.zmax,
265 vmax=self.zmax,
266 cmap=plt.get_cmap(self.colormap)
266 cmap=plt.get_cmap(self.colormap)
267 )
267 )
268 if self.showprofile:
268 if self.showprofile:
269 ax.plot_profile = self.pf_axes[n].plot(
269 ax.plot_profile = self.pf_axes[n].plot(
270 data['rti'][n], self.y)[0]
270 data['rti'][n], self.y)[0]
271 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
271 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
272 color="k", linestyle="dashed", lw=1)[0]
272 color="k", linestyle="dashed", lw=1)[0]
273 else:
273 else:
274 ax.collections.remove(ax.collections[0])
274 ax.collections.remove(ax.collections[0])
275 ax.plt = ax.pcolormesh(x, y, z[n].T,
275 ax.plt = ax.pcolormesh(x, y, z[n].T,
276 vmin=self.zmin,
276 vmin=self.zmin,
277 vmax=self.zmax,
277 vmax=self.zmax,
278 cmap=plt.get_cmap(self.colormap)
278 cmap=plt.get_cmap(self.colormap)
279 )
279 )
280 if self.showprofile:
280 if self.showprofile:
281 ax.plot_profile.set_data(data['rti'][n], self.y)
281 ax.plot_profile.set_data(data['rti'][n], self.y)
282 ax.plot_noise.set_data(numpy.repeat(
282 ax.plot_noise.set_data(numpy.repeat(
283 data['noise'][n], len(self.y)), self.y)
283 data['noise'][n], len(self.y)), self.y)
284
284
285
285
286 class CoherencePlot(RTIPlot):
286 class CoherencePlot(RTIPlot):
287 '''
287 '''
288 Plot for Coherence data
288 Plot for Coherence data
289 '''
289 '''
290
290
291 CODE = 'coh'
291 CODE = 'coh'
292
292
293 def setup(self):
293 def setup(self):
294 self.xaxis = 'time'
294 self.xaxis = 'time'
295 self.ncols = 1
295 self.ncols = 1
296 self.nrows = len(self.data.pairs)
296 self.nrows = len(self.data.pairs)
297 self.nplots = len(self.data.pairs)
297 self.nplots = len(self.data.pairs)
298 self.ylabel = 'Range [km]'
298 self.ylabel = 'Range [km]'
299 self.xlabel = 'Time'
299 self.xlabel = 'Time'
300 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
300 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
301 if self.CODE == 'coh':
301 if self.CODE == 'coh':
302 self.cb_label = ''
302 self.cb_label = ''
303 self.titles = [
303 self.titles = [
304 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
304 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
305 else:
305 else:
306 self.cb_label = 'Degrees'
306 self.cb_label = 'Degrees'
307 self.titles = [
307 self.titles = [
308 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
308 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
309
309
310 def update(self, dataOut):
310 def update(self, dataOut):
311
311
312 data = {}
312 data = {}
313 meta = {}
313 meta = {}
314 data['coh'] = dataOut.getCoherence()
314 data['coh'] = dataOut.getCoherence()
315 meta['pairs'] = dataOut.pairsList
315 meta['pairs'] = dataOut.pairsList
316
316
317 return data, meta
317 return data, meta
318
318
319 class PhasePlot(CoherencePlot):
319 class PhasePlot(CoherencePlot):
320 '''
320 '''
321 Plot for Phase map data
321 Plot for Phase map data
322 '''
322 '''
323
323
324 CODE = 'phase'
324 CODE = 'phase'
325 colormap = 'seismic'
325 colormap = 'seismic'
326
326
327 def update(self, dataOut):
327 def update(self, dataOut):
328
328
329 data = {}
329 data = {}
330 meta = {}
330 meta = {}
331 data['phase'] = dataOut.getCoherence(phase=True)
331 data['phase'] = dataOut.getCoherence(phase=True)
332 meta['pairs'] = dataOut.pairsList
332 meta['pairs'] = dataOut.pairsList
333
333
334 return data, meta
334 return data, meta
335
335
336 class NoisePlot(Plot):
336 class NoisePlot(Plot):
337 '''
337 '''
338 Plot for noise
338 Plot for noise
339 '''
339 '''
340
340
341 CODE = 'noise'
341 CODE = 'noise'
342 plot_type = 'scatterbuffer'
342 plot_type = 'scatterbuffer'
343
343
344 def setup(self):
344 def setup(self):
345 self.xaxis = 'time'
345 self.xaxis = 'time'
346 self.ncols = 1
346 self.ncols = 1
347 self.nrows = 1
347 self.nrows = 1
348 self.nplots = 1
348 self.nplots = 1
349 self.ylabel = 'Intensity [dB]'
349 self.ylabel = 'Intensity [dB]'
350 self.xlabel = 'Time'
350 self.xlabel = 'Time'
351 self.titles = ['Noise']
351 self.titles = ['Noise']
352 self.colorbar = False
352 self.colorbar = False
353 self.plots_adjust.update({'right': 0.85 })
353 self.plots_adjust.update({'right': 0.85 })
354
354
355 def update(self, dataOut):
355 def update(self, dataOut):
356
356
357 data = {}
357 data = {}
358 meta = {}
358 meta = {}
359 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
359 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
360 meta['yrange'] = numpy.array([])
360 meta['yrange'] = numpy.array([])
361
361
362 return data, meta
362 return data, meta
363
363
364 def plot(self):
364 def plot(self):
365
365
366 x = self.data.times
366 x = self.data.times
367 xmin = self.data.min_time
367 xmin = self.data.min_time
368 xmax = xmin + self.xrange * 60 * 60
368 xmax = xmin + self.xrange * 60 * 60
369 Y = self.data['noise']
369 Y = self.data['noise']
370
370
371 if self.axes[0].firsttime:
371 if self.axes[0].firsttime:
372 self.ymin = numpy.nanmin(Y) - 5
372 self.ymin = numpy.nanmin(Y) - 5
373 self.ymax = numpy.nanmax(Y) + 5
373 self.ymax = numpy.nanmax(Y) + 5
374 for ch in self.data.channels:
374 for ch in self.data.channels:
375 y = Y[ch]
375 y = Y[ch]
376 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
376 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
377 plt.legend(bbox_to_anchor=(1.18, 1.0))
377 plt.legend(bbox_to_anchor=(1.18, 1.0))
378 else:
378 else:
379 for ch in self.data.channels:
379 for ch in self.data.channels:
380 y = Y[ch]
380 y = Y[ch]
381 self.axes[0].lines[ch].set_data(x, y)
381 self.axes[0].lines[ch].set_data(x, y)
382
382
383
383
384 class PowerProfilePlot(Plot):
384 class PowerProfilePlot(Plot):
385
385
386 CODE = 'pow_profile'
386 CODE = 'pow_profile'
387 plot_type = 'scatter'
387 plot_type = 'scatter'
388
388
389 def setup(self):
389 def setup(self):
390
390
391 self.ncols = 1
391 self.ncols = 1
392 self.nrows = 1
392 self.nrows = 1
393 self.nplots = 1
393 self.nplots = 1
394 self.height = 4
394 self.height = 4
395 self.width = 3
395 self.width = 3
396 self.ylabel = 'Range [km]'
396 self.ylabel = 'Range [km]'
397 self.xlabel = 'Intensity [dB]'
397 self.xlabel = 'Intensity [dB]'
398 self.titles = ['Power Profile']
398 self.titles = ['Power Profile']
399 self.colorbar = False
399 self.colorbar = False
400
400
401 def update(self, dataOut):
401 def update(self, dataOut):
402
402
403 data = {}
403 data = {}
404 meta = {}
404 meta = {}
405 data[self.CODE] = dataOut.getPower()
405 data[self.CODE] = dataOut.getPower()
406
406
407 return data, meta
407 return data, meta
408
408
409 def plot(self):
409 def plot(self):
410
410
411 y = self.data.yrange
411 y = self.data.yrange
412 self.y = y
412 self.y = y
413
413
414 x = self.data[-1][self.CODE]
414 x = self.data[-1][self.CODE]
415
415
416 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
416 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
417 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
417 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
418
418
419 if self.axes[0].firsttime:
419 if self.axes[0].firsttime:
420 for ch in self.data.channels:
420 for ch in self.data.channels:
421 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
421 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
422 plt.legend()
422 plt.legend()
423 else:
423 else:
424 for ch in self.data.channels:
424 for ch in self.data.channels:
425 self.axes[0].lines[ch].set_data(x[ch], y)
425 self.axes[0].lines[ch].set_data(x[ch], y)
426
426
427
427
428 class SpectraCutPlot(Plot):
428 class SpectraCutPlot(Plot):
429
429
430 CODE = 'spc_cut'
430 CODE = 'spc_cut'
431 plot_type = 'scatter'
431 plot_type = 'scatter'
432 buffering = False
432 buffering = False
433
433
434 def setup(self):
434 def setup(self):
435
435
436 self.nplots = len(self.data.channels)
436 self.nplots = len(self.data.channels)
437 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
437 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
438 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
438 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
439 self.width = 3.4 * self.ncols + 1.5
439 self.width = 3.4 * self.ncols + 1.5
440 self.height = 3 * self.nrows
440 self.height = 3 * self.nrows
441 self.ylabel = 'Power [dB]'
441 self.ylabel = 'Power [dB]'
442 self.colorbar = False
442 self.colorbar = False
443 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
443 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
444
444
445 def update(self, dataOut):
445 def update(self, dataOut):
446
446
447 data = {}
447 data = {}
448 meta = {}
448 meta = {}
449 spc = 10*numpy.log10(dataOut.data_pre[0]/dataOut.normFactor)
449 spc = 10*numpy.log10(dataOut.data_pre[0]/dataOut.normFactor)
450 data['spc'] = spc
450 data['spc'] = spc
451 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
451 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
452 if self.CODE == 'cut_gaussian_fit':
452 if self.CODE == 'cut_gaussian_fit':
453 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
453 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
454 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
454 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
455 return data, meta
455 return data, meta
456
456
457 def plot(self):
457 def plot(self):
458 if self.xaxis == "frequency":
458 if self.xaxis == "frequency":
459 x = self.data.xrange[0][1:]
459 x = self.data.xrange[0][1:]
460 self.xlabel = "Frequency (kHz)"
460 self.xlabel = "Frequency (kHz)"
461 elif self.xaxis == "time":
461 elif self.xaxis == "time":
462 x = self.data.xrange[1]
462 x = self.data.xrange[1]
463 self.xlabel = "Time (ms)"
463 self.xlabel = "Time (ms)"
464 else:
464 else:
465 x = self.data.xrange[2][:-1]
465 x = self.data.xrange[2][:-1]
466 self.xlabel = "Velocity (m/s)"
466 self.xlabel = "Velocity (m/s)"
467
467
468 if self.CODE == 'cut_gaussian_fit':
468 if self.CODE == 'cut_gaussian_fit':
469 x = self.data.xrange[2][:-1]
469 x = self.data.xrange[2][:-1]
470 self.xlabel = "Velocity (m/s)"
470 self.xlabel = "Velocity (m/s)"
471
471
472 self.titles = []
472 self.titles = []
473
473
474 y = self.data.yrange
474 y = self.data.yrange
475 data = self.data[-1]
475 data = self.data[-1]
476 z = data['spc']
476 z = data['spc']
477
477
478 if self.height_index:
478 if self.height_index:
479 index = numpy.array(self.height_index)
479 index = numpy.array(self.height_index)
480 else:
480 else:
481 index = numpy.arange(0, len(y), int((len(y))/9))
481 index = numpy.arange(0, len(y), int((len(y))/9))
482
482
483 for n, ax in enumerate(self.axes):
483 for n, ax in enumerate(self.axes):
484 if self.CODE == 'cut_gaussian_fit':
484 if self.CODE == 'cut_gaussian_fit':
485 gau0 = data['gauss_fit0']
485 gau0 = data['gauss_fit0']
486 gau1 = data['gauss_fit1']
486 gau1 = data['gauss_fit1']
487 if ax.firsttime:
487 if ax.firsttime:
488 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
488 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
489 self.xmin = self.xmin if self.xmin else -self.xmax
489 self.xmin = self.xmin if self.xmin else -self.xmax
490 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
490 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
491 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
491 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
492 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
492 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
493 if self.CODE == 'cut_gaussian_fit':
493 if self.CODE == 'cut_gaussian_fit':
494 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
494 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
495 for i, line in enumerate(ax.plt_gau0):
495 for i, line in enumerate(ax.plt_gau0):
496 line.set_color(ax.plt[i].get_color())
496 line.set_color(ax.plt[i].get_color())
497 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
497 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
498 for i, line in enumerate(ax.plt_gau1):
498 for i, line in enumerate(ax.plt_gau1):
499 line.set_color(ax.plt[i].get_color())
499 line.set_color(ax.plt[i].get_color())
500 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
500 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
501 self.figures[0].legend(ax.plt, labels, loc='center right')
501 self.figures[0].legend(ax.plt, labels, loc='center right')
502 else:
502 else:
503 for i, line in enumerate(ax.plt):
503 for i, line in enumerate(ax.plt):
504 line.set_data(x, z[n, :, index[i]].T)
504 line.set_data(x, z[n, :, index[i]].T)
505 for i, line in enumerate(ax.plt_gau0):
505 for i, line in enumerate(ax.plt_gau0):
506 line.set_data(x, gau0[n, :, index[i]].T)
506 line.set_data(x, gau0[n, :, index[i]].T)
507 line.set_color(ax.plt[i].get_color())
507 line.set_color(ax.plt[i].get_color())
508 for i, line in enumerate(ax.plt_gau1):
508 for i, line in enumerate(ax.plt_gau1):
509 line.set_data(x, gau1[n, :, index[i]].T)
509 line.set_data(x, gau1[n, :, index[i]].T)
510 line.set_color(ax.plt[i].get_color())
510 line.set_color(ax.plt[i].get_color())
511 self.titles.append('CH {}'.format(n))
511 self.titles.append('CH {}'.format(n))
512
512
513
513
514 class BeaconPhase(Plot):
514 class BeaconPhase(Plot):
515
515
516 __isConfig = None
516 __isConfig = None
517 __nsubplots = None
517 __nsubplots = None
518
518
519 PREFIX = 'beacon_phase'
519 PREFIX = 'beacon_phase'
520
520
521 def __init__(self):
521 def __init__(self):
522 Plot.__init__(self)
522 Plot.__init__(self)
523 self.timerange = 24*60*60
523 self.timerange = 24*60*60
524 self.isConfig = False
524 self.isConfig = False
525 self.__nsubplots = 1
525 self.__nsubplots = 1
526 self.counter_imagwr = 0
526 self.counter_imagwr = 0
527 self.WIDTH = 800
527 self.WIDTH = 800
528 self.HEIGHT = 400
528 self.HEIGHT = 400
529 self.WIDTHPROF = 120
529 self.WIDTHPROF = 120
530 self.HEIGHTPROF = 0
530 self.HEIGHTPROF = 0
531 self.xdata = None
531 self.xdata = None
532 self.ydata = None
532 self.ydata = None
533
533
534 self.PLOT_CODE = BEACON_CODE
534 self.PLOT_CODE = BEACON_CODE
535
535
536 self.FTP_WEI = None
536 self.FTP_WEI = None
537 self.EXP_CODE = None
537 self.EXP_CODE = None
538 self.SUB_EXP_CODE = None
538 self.SUB_EXP_CODE = None
539 self.PLOT_POS = None
539 self.PLOT_POS = None
540
540
541 self.filename_phase = None
541 self.filename_phase = None
542
542
543 self.figfile = None
543 self.figfile = None
544
544
545 self.xmin = None
545 self.xmin = None
546 self.xmax = None
546 self.xmax = None
547
547
548 def getSubplots(self):
548 def getSubplots(self):
549
549
550 ncol = 1
550 ncol = 1
551 nrow = 1
551 nrow = 1
552
552
553 return nrow, ncol
553 return nrow, ncol
554
554
555 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
555 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
556
556
557 self.__showprofile = showprofile
557 self.__showprofile = showprofile
558 self.nplots = nplots
558 self.nplots = nplots
559
559
560 ncolspan = 7
560 ncolspan = 7
561 colspan = 6
561 colspan = 6
562 self.__nsubplots = 2
562 self.__nsubplots = 2
563
563
564 self.createFigure(id = id,
564 self.createFigure(id = id,
565 wintitle = wintitle,
565 wintitle = wintitle,
566 widthplot = self.WIDTH+self.WIDTHPROF,
566 widthplot = self.WIDTH+self.WIDTHPROF,
567 heightplot = self.HEIGHT+self.HEIGHTPROF,
567 heightplot = self.HEIGHT+self.HEIGHTPROF,
568 show=show)
568 show=show)
569
569
570 nrow, ncol = self.getSubplots()
570 nrow, ncol = self.getSubplots()
571
571
572 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
572 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
573
573
574 def save_phase(self, filename_phase):
574 def save_phase(self, filename_phase):
575 f = open(filename_phase,'w+')
575 f = open(filename_phase,'w+')
576 f.write('\n\n')
576 f.write('\n\n')
577 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
577 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
578 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
578 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
579 f.close()
579 f.close()
580
580
581 def save_data(self, filename_phase, data, data_datetime):
581 def save_data(self, filename_phase, data, data_datetime):
582 f=open(filename_phase,'a')
582 f=open(filename_phase,'a')
583 timetuple_data = data_datetime.timetuple()
583 timetuple_data = data_datetime.timetuple()
584 day = str(timetuple_data.tm_mday)
584 day = str(timetuple_data.tm_mday)
585 month = str(timetuple_data.tm_mon)
585 month = str(timetuple_data.tm_mon)
586 year = str(timetuple_data.tm_year)
586 year = str(timetuple_data.tm_year)
587 hour = str(timetuple_data.tm_hour)
587 hour = str(timetuple_data.tm_hour)
588 minute = str(timetuple_data.tm_min)
588 minute = str(timetuple_data.tm_min)
589 second = str(timetuple_data.tm_sec)
589 second = str(timetuple_data.tm_sec)
590 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
590 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
591 f.close()
591 f.close()
592
592
593 def plot(self):
593 def plot(self):
594 log.warning('TODO: Not yet implemented...')
594 log.warning('TODO: Not yet implemented...')
595
595
596 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
596 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
597 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
597 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
598 timerange=None,
598 timerange=None,
599 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
599 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
600 server=None, folder=None, username=None, password=None,
600 server=None, folder=None, username=None, password=None,
601 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
601 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
602
602
603 if dataOut.flagNoData:
603 if dataOut.flagNoData:
604 return dataOut
604 return dataOut
605
605
606 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
606 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
607 return
607 return
608
608
609 if pairsList == None:
609 if pairsList == None:
610 pairsIndexList = dataOut.pairsIndexList[:10]
610 pairsIndexList = dataOut.pairsIndexList[:10]
611 else:
611 else:
612 pairsIndexList = []
612 pairsIndexList = []
613 for pair in pairsList:
613 for pair in pairsList:
614 if pair not in dataOut.pairsList:
614 if pair not in dataOut.pairsList:
615 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
615 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
616 pairsIndexList.append(dataOut.pairsList.index(pair))
616 pairsIndexList.append(dataOut.pairsList.index(pair))
617
617
618 if pairsIndexList == []:
618 if pairsIndexList == []:
619 return
619 return
620
620
621 # if len(pairsIndexList) > 4:
621 # if len(pairsIndexList) > 4:
622 # pairsIndexList = pairsIndexList[0:4]
622 # pairsIndexList = pairsIndexList[0:4]
623
623
624 hmin_index = None
624 hmin_index = None
625 hmax_index = None
625 hmax_index = None
626
626
627 if hmin != None and hmax != None:
627 if hmin != None and hmax != None:
628 indexes = numpy.arange(dataOut.nHeights)
628 indexes = numpy.arange(dataOut.nHeights)
629 hmin_list = indexes[dataOut.heightList >= hmin]
629 hmin_list = indexes[dataOut.heightList >= hmin]
630 hmax_list = indexes[dataOut.heightList <= hmax]
630 hmax_list = indexes[dataOut.heightList <= hmax]
631
631
632 if hmin_list.any():
632 if hmin_list.any():
633 hmin_index = hmin_list[0]
633 hmin_index = hmin_list[0]
634
634
635 if hmax_list.any():
635 if hmax_list.any():
636 hmax_index = hmax_list[-1]+1
636 hmax_index = hmax_list[-1]+1
637
637
638 x = dataOut.getTimeRange()
638 x = dataOut.getTimeRange()
639
639
640 thisDatetime = dataOut.datatime
640 thisDatetime = dataOut.datatime
641
641
642 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
642 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
643 xlabel = "Local Time"
643 xlabel = "Local Time"
644 ylabel = "Phase (degrees)"
644 ylabel = "Phase (degrees)"
645
645
646 update_figfile = False
646 update_figfile = False
647
647
648 nplots = len(pairsIndexList)
648 nplots = len(pairsIndexList)
649 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
649 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
650 phase_beacon = numpy.zeros(len(pairsIndexList))
650 phase_beacon = numpy.zeros(len(pairsIndexList))
651 for i in range(nplots):
651 for i in range(nplots):
652 pair = dataOut.pairsList[pairsIndexList[i]]
652 pair = dataOut.pairsList[pairsIndexList[i]]
653 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
653 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
654 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
654 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
655 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
655 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
656 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
656 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
657 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
657 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
658
658
659 if dataOut.beacon_heiIndexList:
659 if dataOut.beacon_heiIndexList:
660 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
660 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
661 else:
661 else:
662 phase_beacon[i] = numpy.average(phase)
662 phase_beacon[i] = numpy.average(phase)
663
663
664 if not self.isConfig:
664 if not self.isConfig:
665
665
666 nplots = len(pairsIndexList)
666 nplots = len(pairsIndexList)
667
667
668 self.setup(id=id,
668 self.setup(id=id,
669 nplots=nplots,
669 nplots=nplots,
670 wintitle=wintitle,
670 wintitle=wintitle,
671 showprofile=showprofile,
671 showprofile=showprofile,
672 show=show)
672 show=show)
673
673
674 if timerange != None:
674 if timerange != None:
675 self.timerange = timerange
675 self.timerange = timerange
676
676
677 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
677 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
678
678
679 if ymin == None: ymin = 0
679 if ymin == None: ymin = 0
680 if ymax == None: ymax = 360
680 if ymax == None: ymax = 360
681
681
682 self.FTP_WEI = ftp_wei
682 self.FTP_WEI = ftp_wei
683 self.EXP_CODE = exp_code
683 self.EXP_CODE = exp_code
684 self.SUB_EXP_CODE = sub_exp_code
684 self.SUB_EXP_CODE = sub_exp_code
685 self.PLOT_POS = plot_pos
685 self.PLOT_POS = plot_pos
686
686
687 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
687 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
688 self.isConfig = True
688 self.isConfig = True
689 self.figfile = figfile
689 self.figfile = figfile
690 self.xdata = numpy.array([])
690 self.xdata = numpy.array([])
691 self.ydata = numpy.array([])
691 self.ydata = numpy.array([])
692
692
693 update_figfile = True
693 update_figfile = True
694
694
695 #open file beacon phase
695 #open file beacon phase
696 path = '%s%03d' %(self.PREFIX, self.id)
696 path = '%s%03d' %(self.PREFIX, self.id)
697 beacon_file = os.path.join(path,'%s.txt'%self.name)
697 beacon_file = os.path.join(path,'%s.txt'%self.name)
698 self.filename_phase = os.path.join(figpath,beacon_file)
698 self.filename_phase = os.path.join(figpath,beacon_file)
699 #self.save_phase(self.filename_phase)
699 #self.save_phase(self.filename_phase)
700
700
701
701
702 #store data beacon phase
702 #store data beacon phase
703 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
703 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
704
704
705 self.setWinTitle(title)
705 self.setWinTitle(title)
706
706
707
707
708 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
708 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
709
709
710 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
710 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
711
711
712 axes = self.axesList[0]
712 axes = self.axesList[0]
713
713
714 self.xdata = numpy.hstack((self.xdata, x[0:1]))
714 self.xdata = numpy.hstack((self.xdata, x[0:1]))
715
715
716 if len(self.ydata)==0:
716 if len(self.ydata)==0:
717 self.ydata = phase_beacon.reshape(-1,1)
717 self.ydata = phase_beacon.reshape(-1,1)
718 else:
718 else:
719 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
719 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
720
720
721
721
722 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
722 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
723 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
723 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
724 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
724 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
725 XAxisAsTime=True, grid='both'
725 XAxisAsTime=True, grid='both'
726 )
726 )
727
727
728 self.draw()
728 self.draw()
729
729
730 if dataOut.ltctime >= self.xmax:
730 if dataOut.ltctime >= self.xmax:
731 self.counter_imagwr = wr_period
731 self.counter_imagwr = wr_period
732 self.isConfig = False
732 self.isConfig = False
733 update_figfile = True
733 update_figfile = True
734
734
735 self.save(figpath=figpath,
735 self.save(figpath=figpath,
736 figfile=figfile,
736 figfile=figfile,
737 save=save,
737 save=save,
738 ftp=ftp,
738 ftp=ftp,
739 wr_period=wr_period,
739 wr_period=wr_period,
740 thisDatetime=thisDatetime,
740 thisDatetime=thisDatetime,
741 update_figfile=update_figfile)
741 update_figfile=update_figfile)
742
742
743 return dataOut
743 return dataOut
@@ -1,844 +1,863
1 '''
1 '''
2 Created on Jul 3, 2014
2 Created on Jul 3, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 # SUBCHANNELS EN VEZ DE CHANNELS
6 # SUBCHANNELS EN VEZ DE CHANNELS
7 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
7 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
8 # ACTUALIZACION DE VERSION
8 # ACTUALIZACION DE VERSION
9 # HEADERS
9 # HEADERS
10 # MODULO DE ESCRITURA
10 # MODULO DE ESCRITURA
11 # METADATA
11 # METADATA
12
12
13 import os
13 import os
14 import time
14 import time
15 import datetime
15 import datetime
16 import numpy
16 import numpy
17 import timeit
17 import timeit
18 from fractions import Fraction
18 from fractions import Fraction
19 from time import time
19 from time import time
20 from time import sleep
20 from time import sleep
21
21
22 import schainpy.admin
22 import schainpy.admin
23 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
23 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
24 from schainpy.model.data.jrodata import Voltage
24 from schainpy.model.data.jrodata import Voltage
25 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
25 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
26
26
27 import pickle
27 import pickle
28 try:
28 try:
29 os.environ["HDF5_USE_FILE_LOCKING"] = "FALSE"
29 import digital_rf
30 import digital_rf
30 except:
31 except:
31 pass
32 pass
32
33
33
34
34 class DigitalRFReader(ProcessingUnit):
35 class DigitalRFReader(ProcessingUnit):
35 '''
36 '''
36 classdocs
37 classdocs
37 '''
38 '''
38
39
39 def __init__(self):
40 def __init__(self):
40 '''
41 '''
41 Constructor
42 Constructor
42 '''
43 '''
43
44
44 ProcessingUnit.__init__(self)
45 ProcessingUnit.__init__(self)
45
46
46 self.dataOut = Voltage()
47 self.dataOut = Voltage()
47 self.__printInfo = True
48 self.__printInfo = True
48 self.__flagDiscontinuousBlock = False
49 self.__flagDiscontinuousBlock = False
49 self.__bufferIndex = 9999999
50 self.__bufferIndex = 9999999
50 self.__codeType = 0
51 self.__codeType = 0
51 self.__ippKm = None
52 self.__ippKm = None
52 self.__nCode = None
53 self.__nCode = None
53 self.__nBaud = None
54 self.__nBaud = None
54 self.__code = None
55 self.__code = None
55 self.dtype = None
56 self.dtype = None
56 self.oldAverage = None
57 self.oldAverage = None
57 self.path = None
58 self.path = None
58
59
59 def close(self):
60 def close(self):
60 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
61 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
61 return
62 return
62
63
63 def __getCurrentSecond(self):
64 def __getCurrentSecond(self):
64
65
65 return self.__thisUnixSample / self.__sample_rate
66 return self.__thisUnixSample / self.__sample_rate
66
67
67 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
68 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
68
69
69 def __setFileHeader(self):
70 def __setFileHeader(self):
70 '''
71 '''
71 In this method will be initialized every parameter of dataOut object (header, no data)
72 In this method will be initialized every parameter of dataOut object (header, no data)
72 '''
73 '''
73 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
74 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
74 if not self.getByBlock:
75 if not self.getByBlock:
75 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
76 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
76 else:
77 else:
77 nProfiles = self.nProfileBlocks # Number of profiles in one block
78 nProfiles = self.nProfileBlocks # Number of profiles in one block
78
79
79 try:
80 try:
80 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
81 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
81 self.__radarControllerHeader)
82 self.__radarControllerHeader)
82 except:
83 except:
83 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
84 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
84 txA=0,
85 txA=0,
85 txB=0,
86 txB=0,
86 nWindows=1,
87 nWindows=1,
87 nHeights=self.__nSamples,
88 nHeights=self.__nSamples,
88 firstHeight=self.__firstHeigth,
89 firstHeight=self.__firstHeigth,
89 deltaHeight=self.__deltaHeigth,
90 deltaHeight=self.__deltaHeigth,
90 codeType=self.__codeType,
91 codeType=self.__codeType,
91 nCode=self.__nCode, nBaud=self.__nBaud,
92 nCode=self.__nCode, nBaud=self.__nBaud,
92 code=self.__code)
93 code=self.__code)
93
94
94 try:
95 try:
95 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
96 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
96 except:
97 except:
97 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
98 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
98 nProfiles=nProfiles,
99 nProfiles=nProfiles,
99 nChannels=len(
100 nChannels=len(
100 self.__channelList),
101 self.__channelList),
101 adcResolution=14)
102 adcResolution=14)
102 self.dataOut.type = "Voltage"
103 self.dataOut.type = "Voltage"
103
104
104 self.dataOut.data = None
105 self.dataOut.data = None
105
106
106 self.dataOut.dtype = self.dtype
107 self.dataOut.dtype = self.dtype
107
108
108 # self.dataOut.nChannels = 0
109 # self.dataOut.nChannels = 0
109
110
110 # self.dataOut.nHeights = 0
111 # self.dataOut.nHeights = 0
111
112
112 self.dataOut.nProfiles = int(nProfiles)
113 self.dataOut.nProfiles = int(nProfiles)
113
114
114 self.dataOut.heightList = self.__firstHeigth + \
115 self.dataOut.heightList = self.__firstHeigth + \
115 numpy.arange(self.__nSamples, dtype=numpy.float) * \
116 numpy.arange(self.__nSamples, dtype=numpy.float) * \
116 self.__deltaHeigth
117 self.__deltaHeigth
117
118
118 #self.dataOut.channelList = list(range(self.__num_subchannels))
119 #self.dataOut.channelList = list(range(self.__num_subchannels))
119 self.dataOut.channelList = list(range(len(self.__channelList)))
120 self.dataOut.channelList = list(range(len(self.__channelList)))
120 if not self.getByBlock:
121 if not self.getByBlock:
121
122
122 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
123 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
123 else:
124 else:
124 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights*self.nProfileBlocks
125 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights*self.nProfileBlocks
125
126
126 # self.dataOut.channelIndexList = None
127 # self.dataOut.channelIndexList = None
127
128
128 self.dataOut.flagNoData = True
129 self.dataOut.flagNoData = True
129 if not self.getByBlock:
130 if not self.getByBlock:
130 self.dataOut.flagDataAsBlock = False
131 self.dataOut.flagDataAsBlock = False
131 else:
132 else:
132 self.dataOut.flagDataAsBlock = True
133 self.dataOut.flagDataAsBlock = True
133 # Set to TRUE if the data is discontinuous
134 # Set to TRUE if the data is discontinuous
134 self.dataOut.flagDiscontinuousBlock = False
135 self.dataOut.flagDiscontinuousBlock = False
135
136
136 self.dataOut.utctime = None
137 self.dataOut.utctime = None
137
138
138 # timezone like jroheader, difference in minutes between UTC and localtime
139 # timezone like jroheader, difference in minutes between UTC and localtime
139 self.dataOut.timeZone = self.__timezone / 60
140 self.dataOut.timeZone = self.__timezone / 60
140
141
141 self.dataOut.dstFlag = 0
142 self.dataOut.dstFlag = 0
142
143
143 self.dataOut.errorCount = 0
144 self.dataOut.errorCount = 0
144
145
145 try:
146 try:
146 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
147 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
147 'nCohInt', self.nCohInt)
148 'nCohInt', self.nCohInt)
148
149
149 # asumo que la data esta decodificada
150 # asumo que la data esta decodificada
150 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
151 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
151 'flagDecodeData', self.flagDecodeData)
152 'flagDecodeData', self.flagDecodeData)
152
153
153 # asumo que la data esta sin flip
154 # asumo que la data esta sin flip
154 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
155 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
155
156
156 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
157 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
157
158
158 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
159 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
159 except:
160 except:
160 pass
161 pass
161
162
162 self.dataOut.ippSeconds = ippSeconds
163 self.dataOut.ippSeconds = ippSeconds
163
164
164 # Time interval between profiles
165 # Time interval between profiles
165 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
166 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
166
167
167 self.dataOut.frequency = self.__frequency
168 self.dataOut.frequency = self.__frequency
168
169
169 self.dataOut.realtime = self.__online
170 self.dataOut.realtime = self.__online
170
171
171 def findDatafiles(self, path, startDate=None, endDate=None):
172 def findDatafiles(self, path, startDate=None, endDate=None):
172
173
173 if not os.path.isdir(path):
174 if not os.path.isdir(path):
174 return []
175 return []
175
176
176 try:
177 try:
177 digitalReadObj = digital_rf.DigitalRFReader(
178 digitalReadObj = digital_rf.DigitalRFReader(
178 path, load_all_metadata=True)
179 path, load_all_metadata=True)
179 except:
180 except:
180 digitalReadObj = digital_rf.DigitalRFReader(path)
181 digitalReadObj = digital_rf.DigitalRFReader(path)
181
182
182 channelNameList = digitalReadObj.get_channels()
183 channelNameList = digitalReadObj.get_channels()
183
184
184 if not channelNameList:
185 if not channelNameList:
185 return []
186 return []
186
187
187 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
188 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
188
189
189 sample_rate = metadata_dict['sample_rate'][0]
190 sample_rate = metadata_dict['sample_rate'][0]
190
191
191 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
192 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
192
193
193 try:
194 try:
194 timezone = this_metadata_file['timezone'].value
195 timezone = this_metadata_file['timezone'].value
195 except:
196 except:
196 timezone = 0
197 timezone = 0
197
198
198 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
199 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
199 channelNameList[0]) / sample_rate - timezone
200 channelNameList[0]) / sample_rate - timezone
200
201
201 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
202 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
202 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
203 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
203
204
204 if not startDate:
205 if not startDate:
205 startDate = startDatetime.date()
206 startDate = startDatetime.date()
206
207
207 if not endDate:
208 if not endDate:
208 endDate = endDatatime.date()
209 endDate = endDatatime.date()
209
210
210 dateList = []
211 dateList = []
211
212
212 thisDatetime = startDatetime
213 thisDatetime = startDatetime
213
214
214 while(thisDatetime <= endDatatime):
215 while(thisDatetime <= endDatatime):
215
216
216 thisDate = thisDatetime.date()
217 thisDate = thisDatetime.date()
217
218
218 if thisDate < startDate:
219 if thisDate < startDate:
219 continue
220 continue
220
221
221 if thisDate > endDate:
222 if thisDate > endDate:
222 break
223 break
223
224
224 dateList.append(thisDate)
225 dateList.append(thisDate)
225 thisDatetime += datetime.timedelta(1)
226 thisDatetime += datetime.timedelta(1)
226
227
227 return dateList
228 return dateList
228
229
229 def setup(self, path=None,
230 def setup(self, path=None,
230 startDate=None,
231 startDate=None,
231 endDate=None,
232 endDate=None,
232 startTime=datetime.time(0, 0, 0),
233 startTime=datetime.time(0, 0, 0),
233 endTime=datetime.time(23, 59, 59),
234 endTime=datetime.time(23, 59, 59),
234 channelList=None,
235 channelList=None,
235 nSamples=None,
236 nSamples=None,
236 online=False,
237 online=False,
237 delay=60,
238 delay=60,
238 buffer_size=1024,
239 buffer_size=1024,
239 ippKm=None,
240 ippKm=None,
240 nCohInt=1,
241 nCohInt=1,
241 nCode=1,
242 nCode=1,
242 nBaud=1,
243 nBaud=1,
243 flagDecodeData=False,
244 flagDecodeData=False,
244 code=numpy.ones((1, 1), dtype=numpy.int),
245 code=numpy.ones((1, 1), dtype=numpy.int),
245 getByBlock=0,
246 getByBlock=0,
246 nProfileBlocks=1,
247 nProfileBlocks=1,
247 **kwargs):
248 **kwargs):
248 '''
249 '''
249 In this method we should set all initial parameters.
250 In this method we should set all initial parameters.
250
251
251 Inputs:
252 Inputs:
252 path
253 path
253 startDate
254 startDate
254 endDate
255 endDate
255 startTime
256 startTime
256 endTime
257 endTime
257 set
258 set
258 expLabel
259 expLabel
259 ext
260 ext
260 online
261 online
261 delay
262 delay
262 '''
263 '''
263 self.path = path
264 self.path = path
264 self.nCohInt = nCohInt
265 self.nCohInt = nCohInt
265 self.flagDecodeData = flagDecodeData
266 self.flagDecodeData = flagDecodeData
266 self.i = 0
267 self.i = 0
267
268
268 self.getByBlock = getByBlock
269 self.getByBlock = getByBlock
269 self.nProfileBlocks = nProfileBlocks
270 self.nProfileBlocks = nProfileBlocks
271 if online:
272 print('Waiting for RF data..')
273 sleep(40)
274
270 if not os.path.isdir(path):
275 if not os.path.isdir(path):
271 raise ValueError("[Reading] Directory %s does not exist" % path)
276 raise ValueError("[Reading] Directory %s does not exist" % path)
272
277
278 #print("path",path)
273 try:
279 try:
274 self.digitalReadObj = digital_rf.DigitalRFReader(
280 self.digitalReadObj = digital_rf.DigitalRFReader(
275 path, load_all_metadata=True)
281 path, load_all_metadata=True)
276 except:
282 except:
277 self.digitalReadObj = digital_rf.DigitalRFReader(path)
283 self.digitalReadObj = digital_rf.DigitalRFReader(path)
278
284
279 channelNameList = self.digitalReadObj.get_channels()
285 channelNameList = self.digitalReadObj.get_channels()
280
286
281 if not channelNameList:
287 if not channelNameList:
282 raise ValueError("[Reading] Directory %s does not have any files" % path)
288 raise ValueError("[Reading] Directory %s does not have any files" % path)
283
289
284 if not channelList:
290 if not channelList:
285 channelList = list(range(len(channelNameList)))
291 channelList = list(range(len(channelNameList)))
286
292
287 ########## Reading metadata ######################
293 ########## Reading metadata ######################
288
294
289 top_properties = self.digitalReadObj.get_properties(
295 top_properties = self.digitalReadObj.get_properties(
290 channelNameList[channelList[0]])
296 channelNameList[channelList[0]])
291
297
292 self.__num_subchannels = top_properties['num_subchannels']
298 self.__num_subchannels = top_properties['num_subchannels']
293 self.__sample_rate = 1.0 * \
299 self.__sample_rate = 1.0 * \
294 top_properties['sample_rate_numerator'] / \
300 top_properties['sample_rate_numerator'] / \
295 top_properties['sample_rate_denominator']
301 top_properties['sample_rate_denominator']
296 # self.__samples_per_file = top_properties['samples_per_file'][0]
302 # self.__samples_per_file = top_properties['samples_per_file'][0]
297 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
303 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
298
304
299 this_metadata_file = self.digitalReadObj.get_digital_metadata(
305 this_metadata_file = self.digitalReadObj.get_digital_metadata(
300 channelNameList[channelList[0]])
306 channelNameList[channelList[0]])
301 metadata_bounds = this_metadata_file.get_bounds()
307 metadata_bounds = this_metadata_file.get_bounds()
302 self.fixed_metadata_dict = this_metadata_file.read(
308 self.fixed_metadata_dict = this_metadata_file.read(
303 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
309 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
304
310
305 try:
311 try:
306 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
312 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
307 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
313 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
308 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
314 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
309 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
315 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
310 except:
316 except:
311 pass
317 pass
312
318
313 self.__frequency = None
319 self.__frequency = None
314
320
315 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
321 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
316
322
317 self.__timezone = self.fixed_metadata_dict.get('timezone', 18000)
323 self.__timezone = self.fixed_metadata_dict.get('timezone', 18000)
318
324
319 try:
325 try:
320 nSamples = self.fixed_metadata_dict['nSamples']
326 nSamples = self.fixed_metadata_dict['nSamples']
321 except:
327 except:
322 nSamples = None
328 nSamples = None
323
329
324 self.__firstHeigth = 0
330 self.__firstHeigth = 0
325
331
326 try:
332 try:
327 codeType = self.__radarControllerHeader['codeType']
333 codeType = self.__radarControllerHeader['codeType']
328 except:
334 except:
329 codeType = 0
335 codeType = 0
330
336
331 try:
337 try:
332 if codeType:
338 if codeType:
333 nCode = self.__radarControllerHeader['nCode']
339 nCode = self.__radarControllerHeader['nCode']
334 nBaud = self.__radarControllerHeader['nBaud']
340 nBaud = self.__radarControllerHeader['nBaud']
335 code = self.__radarControllerHeader['code']
341 code = self.__radarControllerHeader['code']
336 except:
342 except:
337 pass
343 pass
338
344
339 if not ippKm:
345 if not ippKm:
340 try:
346 try:
341 # seconds to km
347 # seconds to km
342 ippKm = self.__radarControllerHeader['ipp']
348 ippKm = self.__radarControllerHeader['ipp']
343 except:
349 except:
344 ippKm = None
350 ippKm = None
345 ####################################################
351 ####################################################
346 self.__ippKm = ippKm
352 self.__ippKm = ippKm
347 startUTCSecond = None
353 startUTCSecond = None
348 endUTCSecond = None
354 endUTCSecond = None
349
355
350 if startDate:
356 if startDate:
351 startDatetime = datetime.datetime.combine(startDate, startTime)
357 startDatetime = datetime.datetime.combine(startDate, startTime)
352 startUTCSecond = (
358 startUTCSecond = (
353 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds() + self.__timezone
359 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds()# + self.__timezone
354
360
355 if endDate:
361 if endDate:
356 endDatetime = datetime.datetime.combine(endDate, endTime)
362 endDatetime = datetime.datetime.combine(endDate, endTime)
357 endUTCSecond = (endDatetime - datetime.datetime(1970,
363 endUTCSecond = (endDatetime - datetime.datetime(1970,
358 1, 1)).total_seconds() + self.__timezone
364 1, 1)).total_seconds()# + self.__timezone
359
365 start_index, end_index = self.digitalReadObj.get_bounds(channelNameList[channelList[0]])
360
366 if start_index==None or end_index==None:
361 #print(startUTCSecond,endUTCSecond)
367 print("Check error No data, start_index: ",start_index,",end_index: ",end_index)
362 start_index, end_index = self.digitalReadObj.get_bounds(
368 #return 0
363 channelNameList[channelList[0]])
364
365 #print("*****",start_index,end_index)
366 if not startUTCSecond:
369 if not startUTCSecond:
367 startUTCSecond = start_index / self.__sample_rate
370 startUTCSecond = start_index / self.__sample_rate
368
369 if start_index > startUTCSecond * self.__sample_rate:
371 if start_index > startUTCSecond * self.__sample_rate:
370 startUTCSecond = start_index / self.__sample_rate
372 startUTCSecond = start_index / self.__sample_rate
371
373
372 if not endUTCSecond:
374 if not endUTCSecond:
373 endUTCSecond = end_index / self.__sample_rate
375 endUTCSecond = end_index / self.__sample_rate
376
374 if end_index < endUTCSecond * self.__sample_rate:
377 if end_index < endUTCSecond * self.__sample_rate:
375 endUTCSecond = end_index / self.__sample_rate #Check UTC and LT time
378 endUTCSecond = end_index / self.__sample_rate #Check UTC and LT time
379
376 if not nSamples:
380 if not nSamples:
377 if not ippKm:
381 if not ippKm:
378 raise ValueError("[Reading] nSamples or ippKm should be defined")
382 raise ValueError("[Reading] nSamples or ippKm should be defined")
379 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
383 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
380
384
381 channelBoundList = []
385 channelBoundList = []
382 channelNameListFiltered = []
386 channelNameListFiltered = []
383
387
384 for thisIndexChannel in channelList:
388 for thisIndexChannel in channelList:
385 thisChannelName = channelNameList[thisIndexChannel]
389 thisChannelName = channelNameList[thisIndexChannel]
386 start_index, end_index = self.digitalReadObj.get_bounds(
390 start_index, end_index = self.digitalReadObj.get_bounds(
387 thisChannelName)
391 thisChannelName)
388 channelBoundList.append((start_index, end_index))
392 channelBoundList.append((start_index, end_index))
389 channelNameListFiltered.append(thisChannelName)
393 channelNameListFiltered.append(thisChannelName)
390
394
391 self.profileIndex = 0
395 self.profileIndex = 0
392 self.i = 0
396 self.i = 0
393 self.__delay = delay
397 self.__delay = delay
394
398
395 self.__codeType = codeType
399 self.__codeType = codeType
396 self.__nCode = nCode
400 self.__nCode = nCode
397 self.__nBaud = nBaud
401 self.__nBaud = nBaud
398 self.__code = code
402 self.__code = code
399
403
400 self.__datapath = path
404 self.__datapath = path
401 self.__online = online
405 self.__online = online
402 self.__channelList = channelList
406 self.__channelList = channelList
403 self.__channelNameList = channelNameListFiltered
407 self.__channelNameList = channelNameListFiltered
404 self.__channelBoundList = channelBoundList
408 self.__channelBoundList = channelBoundList
405 self.__nSamples = nSamples
409 self.__nSamples = nSamples
406 if self.getByBlock:
410 if self.getByBlock:
407 nSamples = nSamples*nProfileBlocks
411 nSamples = nSamples*nProfileBlocks
408
412
409
413
410 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
414 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
411 self.__nChannels = len(self.__channelList)
415 self.__nChannels = len(self.__channelList)
412 #print("------------------------------------------")
416 #print("------------------------------------------")
413 #print("self.__samples_to_read",self.__samples_to_read)
417 #print("self.__samples_to_read",self.__samples_to_read)
414 #print("self.__nSamples",self.__nSamples)
418 #print("self.__nSamples",self.__nSamples)
415 # son iguales y el buffer_index da 0
419 # son iguales y el buffer_index da 0
416 self.__startUTCSecond = startUTCSecond
420 self.__startUTCSecond = startUTCSecond
417 self.__endUTCSecond = endUTCSecond
421 self.__endUTCSecond = endUTCSecond
418
422
419 self.__timeInterval = 1.0 * self.__samples_to_read / \
423 self.__timeInterval = 1.0 * self.__samples_to_read / \
420 self.__sample_rate # Time interval
424 self.__sample_rate # Time interval
421
425
422 if online:
426 if online:
423 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
427 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
424 startUTCSecond = numpy.floor(endUTCSecond)
428 startUTCSecond = numpy.floor(endUTCSecond)
425
429
426 # por que en el otro metodo lo primero q se hace es sumar samplestoread
430 # por que en el otro metodo lo primero q se hace es sumar samplestoread
427 self.__thisUnixSample = int(startUTCSecond * self.__sample_rate) - self.__samples_to_read
431 self.__thisUnixSample = int(startUTCSecond * self.__sample_rate) - self.__samples_to_read
428
432
429 #self.__data_buffer = numpy.zeros(
433 #self.__data_buffer = numpy.zeros(
430 # (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
434 # (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
435 print("samplestoread",self.__samples_to_read)
431 self.__data_buffer = numpy.zeros((int(len(channelList)), self.__samples_to_read), dtype=numpy.complex)
436 self.__data_buffer = numpy.zeros((int(len(channelList)), self.__samples_to_read), dtype=numpy.complex)
432
437
433
438
434 self.__setFileHeader()
439 self.__setFileHeader()
435 self.isConfig = True
440 self.isConfig = True
436
441
437 print("[Reading] Digital RF Data was found from %s to %s " % (
442 print("[Reading] Digital RF Data was found from %s to %s " % (
438 datetime.datetime.utcfromtimestamp(
443 datetime.datetime.utcfromtimestamp(
439 self.__startUTCSecond - self.__timezone),
444 self.__startUTCSecond - self.__timezone),
440 datetime.datetime.utcfromtimestamp(
445 datetime.datetime.utcfromtimestamp(
441 self.__endUTCSecond - self.__timezone)
446 self.__endUTCSecond - self.__timezone)
442 ))
447 ))
443
448
444 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
449 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
445 datetime.datetime.utcfromtimestamp(
450 datetime.datetime.utcfromtimestamp(endUTCSecond - self.__timezone)))
446 endUTCSecond - self.__timezone)
447 ))
448 self.oldAverage = None
451 self.oldAverage = None
449 self.count = 0
452 self.count = 0
450 self.executionTime = 0
453 self.executionTime = 0
451
454
452 def __reload(self):
455 def __reload(self):
453 # print
456 # print
454 # print "%s not in range [%s, %s]" %(
457 # print "%s not in range [%s, %s]" %(
455 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
458 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
456 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
459 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
457 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
460 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
458 # )
461 # )
459 print("[Reading] reloading metadata ...")
462 print("[Reading] reloading metadata ...")
460
463
461 try:
464 try:
462 self.digitalReadObj.reload(complete_update=True)
465 self.digitalReadObj.reload(complete_update=True)
463 except:
466 except:
464 self.digitalReadObj = digital_rf.DigitalRFReader(self.path)
467 self.digitalReadObj = digital_rf.DigitalRFReader(self.path)
465
468
466 start_index, end_index = self.digitalReadObj.get_bounds(
469 start_index, end_index = self.digitalReadObj.get_bounds(
467 self.__channelNameList[self.__channelList[0]])
470 self.__channelNameList[self.__channelList[0]])
468
471
469 if start_index > self.__startUTCSecond * self.__sample_rate:
472 if start_index > self.__startUTCSecond * self.__sample_rate:
470 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
473 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
471
474
472 if end_index > self.__endUTCSecond * self.__sample_rate:
475 if end_index > self.__endUTCSecond * self.__sample_rate:
473 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
476 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
474 print()
477 print()
475 print("[Reading] New timerange found [%s, %s] " % (
478 print("[Reading] New timerange found [%s, %s] " % (
476 datetime.datetime.utcfromtimestamp(
479 datetime.datetime.utcfromtimestamp(
477 self.__startUTCSecond - self.__timezone),
480 self.__startUTCSecond - self.__timezone),
478 datetime.datetime.utcfromtimestamp(
481 datetime.datetime.utcfromtimestamp(
479 self.__endUTCSecond - self.__timezone)
482 self.__endUTCSecond - self.__timezone)
480 ))
483 ))
481
484
482 return True
485 return True
483
486
484 return False
487 return False
485
488
486 def timeit(self, toExecute):
489 def timeit(self, toExecute):
487 t0 = time.time()
490 t0 = time.time()
488 toExecute()
491 toExecute()
489 self.executionTime = time.time() - t0
492 self.executionTime = time.time() - t0
490 if self.oldAverage is None:
493 if self.oldAverage is None:
491 self.oldAverage = self.executionTime
494 self.oldAverage = self.executionTime
492 self.oldAverage = (self.executionTime + self.count *
495 self.oldAverage = (self.executionTime + self.count *
493 self.oldAverage) / (self.count + 1.0)
496 self.oldAverage) / (self.count + 1.0)
494 self.count = self.count + 1.0
497 self.count = self.count + 1.0
495 return
498 return
496
499
497 def __readNextBlock(self, seconds=30, volt_scale=1/20000.0):
500 def __readNextBlock(self, seconds=30, volt_scale=1/20000.0):
498 '''
501 '''
499 NOTA: APLICACION RADAR METEOROLOGICO
502 NOTA: APLICACION RADAR METEOROLOGICO
500 VALORES OBTENIDOS CON LA USRP, volt_scale = 1,conexion directa al Ch Rx.
503 VALORES OBTENIDOS CON LA USRP, volt_scale = 1,conexion directa al Ch Rx.
501
504
502 MAXIMO
505 MAXIMO
503 9886 -> 0.980 Voltiospp
506 9886 -> 0.980 Voltiospp
504 4939 -> 0.480 Voltiospp
507 4939 -> 0.480 Voltiospp
505 14825 -> 1.440 Voltiospp
508 14825 -> 1.440 Voltiospp
506 18129 -> 1.940 Voltiospp
509 18129 -> 1.940 Voltiospp
507 Para llevar al valor correspondiente de Voltaje, debemos dividir por 20000
510 Para llevar al valor correspondiente de Voltaje, debemos dividir por 20000
508 y obtenemos la Amplitud correspondiente de entrada IQ.
511 y obtenemos la Amplitud correspondiente de entrada IQ.
509 volt_scale = (1/20000.0)
512 volt_scale = (1/20000.0)
510 '''
513 '''
511 # Set the next data
514 # Set the next data
512 self.__flagDiscontinuousBlock = False
515 self.__flagDiscontinuousBlock = False
513 self.__thisUnixSample += self.__samples_to_read
516 self.__thisUnixSample += self.__samples_to_read
514
517
515 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
518 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
516 print ("[Reading] There are no more data into selected time-range")
519 print ("[Reading] There are no more data into selected time-range")
517 if self.__online:
520 if self.__online:
518 sleep(3)
521 sleep(3)
519 self.__reload()
522 self.__reload()
520 else:
523 else:
521 return False
524 return False
522
525
523 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
526 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
524 return False
527 return False
525 self.__thisUnixSample -= self.__samples_to_read
528 self.__thisUnixSample -= self.__samples_to_read
526
529
527 indexChannel = 0
530 indexChannel = 0
528
531
529 dataOk = False
532 dataOk = False
530
533
531 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
534 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
532 for indexSubchannel in range(self.__num_subchannels):
535 for indexSubchannel in range(self.__num_subchannels):
533 try:
536 try:
534 t0 = time()
537 t0 = time()
538 #print("thisUNixSample",self.__thisUnixSample)
535 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
539 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
536 self.__samples_to_read,
540 self.__samples_to_read,
537 thisChannelName, sub_channel=indexSubchannel)
541 thisChannelName, sub_channel=indexSubchannel)
542 #print("result--------------",result)
538 self.executionTime = time() - t0
543 self.executionTime = time() - t0
539 if self.oldAverage is None:
544 if self.oldAverage is None:
540 self.oldAverage = self.executionTime
545 self.oldAverage = self.executionTime
541 self.oldAverage = (
546 self.oldAverage = (
542 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
547 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
543 self.count = self.count + 1.0
548 self.count = self.count + 1.0
544
549
545 except IOError as e:
550 except IOError as e:
546 # read next profile
551 # read next profile
547 self.__flagDiscontinuousBlock = True
552 self.__flagDiscontinuousBlock = True
548 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
553 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
549 break
554 bot = 0
555 while(self.__flagDiscontinuousBlock):
556 bot +=1
557 self.__thisUnixSample += self.__sample_rate
558 try:
559 result = result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,self.__samples_to_read,thisChannelName, sub_channel=indexSubchannel)
560 self.__flagDiscontinuousBlock=False
561 print("Searching.. NΒ°: ",bot,"Success",self.__thisUnixSample)
562 except:
563 print("Searching...NΒ°: ",bot,"Fail", self.__thisUnixSample)
564 if self.__flagDiscontinuousBlock==True:
565 break
566 else:
567 print("New data index found...",self.__thisUnixSample)
568 #break
550
569
551 if result.shape[0] != self.__samples_to_read:
570 if result.shape[0] != self.__samples_to_read:
552 self.__flagDiscontinuousBlock = True
571 self.__flagDiscontinuousBlock = True
553 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
572 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
554 result.shape[0],
573 result.shape[0],
555 self.__samples_to_read))
574 self.__samples_to_read))
556 break
575 break
557
576
558 self.__data_buffer[indexChannel, :] = result * volt_scale
577 self.__data_buffer[indexChannel, :] = result * volt_scale
559 indexChannel+=1
578 indexChannel+=1
560
579
561 dataOk = True
580 dataOk = True
562
581
563 self.__utctime = self.__thisUnixSample / self.__sample_rate
582 self.__utctime = self.__thisUnixSample / self.__sample_rate
564
583
565 if not dataOk:
584 if not dataOk:
566 return False
585 return False
567
586
568 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
587 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
569 self.__samples_to_read,
588 self.__samples_to_read,
570 self.__timeInterval))
589 self.__timeInterval))
571
590
572 self.__bufferIndex = 0
591 self.__bufferIndex = 0
573
592
574 return True
593 return True
575
594
576 def __isBufferEmpty(self):
595 def __isBufferEmpty(self):
577
596
578 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
597 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
579
598
580 def getData(self, seconds=30, nTries=5):
599 def getData(self, seconds=30, nTries=5):
581 '''
600 '''
582 This method gets the data from files and put the data into the dataOut object
601 This method gets the data from files and put the data into the dataOut object
583
602
584 In addition, increase el the buffer counter in one.
603 In addition, increase el the buffer counter in one.
585
604
586 Return:
605 Return:
587 data : retorna un perfil de voltages (alturas * canales) copiados desde el
606 data : retorna un perfil de voltages (alturas * canales) copiados desde el
588 buffer. Si no hay mas archivos a leer retorna None.
607 buffer. Si no hay mas archivos a leer retorna None.
589
608
590 Affected:
609 Affected:
591 self.dataOut
610 self.dataOut
592 self.profileIndex
611 self.profileIndex
593 self.flagDiscontinuousBlock
612 self.flagDiscontinuousBlock
594 self.flagIsNewBlock
613 self.flagIsNewBlock
595 '''
614 '''
596 #print("getdata")
615 #print("getdata")
597 err_counter = 0
616 err_counter = 0
598 self.dataOut.flagNoData = True
617 self.dataOut.flagNoData = True
599
618
600
619
601 if self.__isBufferEmpty():
620 if self.__isBufferEmpty():
602 #print("hi")
621 #print("hi")
603 self.__flagDiscontinuousBlock = False
622 self.__flagDiscontinuousBlock = False
604
623
605 while True:
624 while True:
606 if self.__readNextBlock():
625 if self.__readNextBlock():
607 break
626 break
608 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
627 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
609 raise schainpy.admin.SchainError('Error')
628 raise schainpy.admin.SchainError('Error')
610 return
629 return
611
630
612 if self.__flagDiscontinuousBlock:
631 if self.__flagDiscontinuousBlock:
613 raise schainpy.admin.SchainError('discontinuous block found')
632 raise schainpy.admin.SchainError('discontinuous block found')
614 return
633 return
615
634
616 if not self.__online:
635 if not self.__online:
617 raise schainpy.admin.SchainError('Online?')
636 raise schainpy.admin.SchainError('Online?')
618 return
637 return
619
638
620 err_counter += 1
639 err_counter += 1
621 if err_counter > nTries:
640 if err_counter > nTries:
622 raise schainpy.admin.SchainError('Max retrys reach')
641 raise schainpy.admin.SchainError('Max retrys reach')
623 return
642 return
624
643
625 print('[Reading] waiting %d seconds to read a new block' % seconds)
644 print('[Reading] waiting %d seconds to read a new block' % seconds)
626 sleep(seconds)
645 sleep(seconds)
627
646
628
647
629 if not self.getByBlock:
648 if not self.getByBlock:
630
649
631 #print("self.__bufferIndex",self.__bufferIndex)# este valor siempre es cero aparentemente
650 #print("self.__bufferIndex",self.__bufferIndex)# este valor siempre es cero aparentemente
632 self.dataOut.data = self.__data_buffer[:, self.__bufferIndex:self.__bufferIndex + self.__nSamples]
651 self.dataOut.data = self.__data_buffer[:, self.__bufferIndex:self.__bufferIndex + self.__nSamples]
633 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
652 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
634 self.dataOut.flagNoData = False
653 self.dataOut.flagNoData = False
635 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
654 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
636 self.dataOut.profileIndex = self.profileIndex
655 self.dataOut.profileIndex = self.profileIndex
637
656
638 self.__bufferIndex += self.__nSamples
657 self.__bufferIndex += self.__nSamples
639 self.profileIndex += 1
658 self.profileIndex += 1
640
659
641 if self.profileIndex == self.dataOut.nProfiles:
660 if self.profileIndex == self.dataOut.nProfiles:
642 self.profileIndex = 0
661 self.profileIndex = 0
643 else:
662 else:
644 # ojo debo anadir el readNextBLock y el __isBufferEmpty(
663 # ojo debo anadir el readNextBLock y el __isBufferEmpty(
645 self.dataOut.flagNoData = False
664 self.dataOut.flagNoData = False
646 buffer = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex + self.__samples_to_read]
665 buffer = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex + self.__samples_to_read]
647 buffer = buffer.reshape((self.__nChannels, self.nProfileBlocks, int(self.__samples_to_read/self.nProfileBlocks)))
666 buffer = buffer.reshape((self.__nChannels, self.nProfileBlocks, int(self.__samples_to_read/self.nProfileBlocks)))
648 self.dataOut.nProfileBlocks = self.nProfileBlocks
667 self.dataOut.nProfileBlocks = self.nProfileBlocks
649 self.dataOut.data = buffer
668 self.dataOut.data = buffer
650 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
669 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
651 self.profileIndex += self.__samples_to_read
670 self.profileIndex += self.__samples_to_read
652 self.__bufferIndex += self.__samples_to_read
671 self.__bufferIndex += self.__samples_to_read
653 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
672 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
654 return True
673 return True
655
674
656
675
657 def printInfo(self):
676 def printInfo(self):
658 '''
677 '''
659 '''
678 '''
660 if self.__printInfo == False:
679 if self.__printInfo == False:
661 return
680 return
662
681
663 # self.systemHeaderObj.printInfo()
682 # self.systemHeaderObj.printInfo()
664 # self.radarControllerHeaderObj.printInfo()
683 # self.radarControllerHeaderObj.printInfo()
665
684
666 self.__printInfo = False
685 self.__printInfo = False
667
686
668 def printNumberOfBlock(self):
687 def printNumberOfBlock(self):
669 '''
688 '''
670 '''
689 '''
671 return
690 return
672 # print self.profileIndex
691 # print self.profileIndex
673
692
674 def run(self, **kwargs):
693 def run(self, **kwargs):
675 '''
694 '''
676 This method will be called many times so here you should put all your code
695 This method will be called many times so here you should put all your code
677 '''
696 '''
678
697
679 if not self.isConfig:
698 if not self.isConfig:
680 self.setup(**kwargs)
699 self.setup(**kwargs)
681
700
682 self.getData(seconds=self.__delay)
701 self.getData(seconds=self.__delay)
683
702
684 return
703 return
685
704
686 @MPDecorator
705 @MPDecorator
687 class DigitalRFWriter(Operation):
706 class DigitalRFWriter(Operation):
688 '''
707 '''
689 classdocs
708 classdocs
690 '''
709 '''
691
710
692 def __init__(self, **kwargs):
711 def __init__(self, **kwargs):
693 '''
712 '''
694 Constructor
713 Constructor
695 '''
714 '''
696 Operation.__init__(self, **kwargs)
715 Operation.__init__(self, **kwargs)
697 self.metadata_dict = {}
716 self.metadata_dict = {}
698 self.dataOut = None
717 self.dataOut = None
699 self.dtype = None
718 self.dtype = None
700 self.oldAverage = 0
719 self.oldAverage = 0
701
720
702 def setHeader(self):
721 def setHeader(self):
703
722
704 self.metadata_dict['frequency'] = self.dataOut.frequency
723 self.metadata_dict['frequency'] = self.dataOut.frequency
705 self.metadata_dict['timezone'] = self.dataOut.timeZone
724 self.metadata_dict['timezone'] = self.dataOut.timeZone
706 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
725 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
707 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
726 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
708 self.metadata_dict['heightList'] = self.dataOut.heightList
727 self.metadata_dict['heightList'] = self.dataOut.heightList
709 self.metadata_dict['channelList'] = self.dataOut.channelList
728 self.metadata_dict['channelList'] = self.dataOut.channelList
710 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
729 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
711 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
730 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
712 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
731 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
713 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
732 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
714 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
733 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
715 self.metadata_dict['type'] = self.dataOut.type
734 self.metadata_dict['type'] = self.dataOut.type
716 self.metadata_dict['flagDataAsBlock']= getattr(
735 self.metadata_dict['flagDataAsBlock']= getattr(
717 self.dataOut, 'flagDataAsBlock', None) # chequear
736 self.dataOut, 'flagDataAsBlock', None) # chequear
718
737
719 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
738 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
720 '''
739 '''
721 In this method we should set all initial parameters.
740 In this method we should set all initial parameters.
722 Input:
741 Input:
723 dataOut: Input data will also be outputa data
742 dataOut: Input data will also be outputa data
724 '''
743 '''
725 self.setHeader()
744 self.setHeader()
726 self.__ippSeconds = dataOut.ippSeconds
745 self.__ippSeconds = dataOut.ippSeconds
727 self.__deltaH = dataOut.getDeltaH()
746 self.__deltaH = dataOut.getDeltaH()
728 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
747 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
729 self.__dtype = dataOut.dtype
748 self.__dtype = dataOut.dtype
730 if len(dataOut.dtype) == 2:
749 if len(dataOut.dtype) == 2:
731 self.__dtype = dataOut.dtype[0]
750 self.__dtype = dataOut.dtype[0]
732 self.__nSamples = dataOut.systemHeaderObj.nSamples
751 self.__nSamples = dataOut.systemHeaderObj.nSamples
733 self.__nProfiles = dataOut.nProfiles
752 self.__nProfiles = dataOut.nProfiles
734
753
735 if self.dataOut.type != 'Voltage':
754 if self.dataOut.type != 'Voltage':
736 raise 'Digital RF cannot be used with this data type'
755 raise 'Digital RF cannot be used with this data type'
737 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
756 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
738 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
757 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
739 else:
758 else:
740 self.arr_data = numpy.ones((self.__nSamples, len(
759 self.arr_data = numpy.ones((self.__nSamples, len(
741 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
760 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
742
761
743 file_cadence_millisecs = 1000
762 file_cadence_millisecs = 1000
744
763
745 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
764 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
746 sample_rate_numerator = int(sample_rate_fraction.numerator)
765 sample_rate_numerator = int(sample_rate_fraction.numerator)
747 sample_rate_denominator = int(sample_rate_fraction.denominator)
766 sample_rate_denominator = int(sample_rate_fraction.denominator)
748 start_global_index = dataOut.utctime * self.__sample_rate
767 start_global_index = dataOut.utctime * self.__sample_rate
749
768
750 uuid = 'prueba'
769 uuid = 'prueba'
751 compression_level = 0
770 compression_level = 0
752 checksum = False
771 checksum = False
753 is_complex = True
772 is_complex = True
754 num_subchannels = len(dataOut.channelList)
773 num_subchannels = len(dataOut.channelList)
755 is_continuous = True
774 is_continuous = True
756 marching_periods = False
775 marching_periods = False
757
776
758 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
777 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
759 fileCadence, start_global_index,
778 fileCadence, start_global_index,
760 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
779 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
761 is_complex, num_subchannels, is_continuous, marching_periods)
780 is_complex, num_subchannels, is_continuous, marching_periods)
762 metadata_dir = os.path.join(path, 'metadata')
781 metadata_dir = os.path.join(path, 'metadata')
763 os.system('mkdir %s' % (metadata_dir))
782 os.system('mkdir %s' % (metadata_dir))
764 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
783 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
765 sample_rate_numerator, sample_rate_denominator,
784 sample_rate_numerator, sample_rate_denominator,
766 metadataFile)
785 metadataFile)
767 self.isConfig = True
786 self.isConfig = True
768 self.currentSample = 0
787 self.currentSample = 0
769 self.oldAverage = 0
788 self.oldAverage = 0
770 self.count = 0
789 self.count = 0
771 return
790 return
772
791
773 def writeMetadata(self):
792 def writeMetadata(self):
774 start_idx = self.__sample_rate * self.dataOut.utctime
793 start_idx = self.__sample_rate * self.dataOut.utctime
775
794
776 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
795 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
777 )
796 )
778 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
797 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
779 )
798 )
780 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
799 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
781 )
800 )
782 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
801 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
783 return
802 return
784
803
785 def timeit(self, toExecute):
804 def timeit(self, toExecute):
786 t0 = time()
805 t0 = time()
787 toExecute()
806 toExecute()
788 self.executionTime = time() - t0
807 self.executionTime = time() - t0
789 if self.oldAverage is None:
808 if self.oldAverage is None:
790 self.oldAverage = self.executionTime
809 self.oldAverage = self.executionTime
791 self.oldAverage = (self.executionTime + self.count *
810 self.oldAverage = (self.executionTime + self.count *
792 self.oldAverage) / (self.count + 1.0)
811 self.oldAverage) / (self.count + 1.0)
793 self.count = self.count + 1.0
812 self.count = self.count + 1.0
794 return
813 return
795
814
796 def writeData(self):
815 def writeData(self):
797 if self.dataOut.type != 'Voltage':
816 if self.dataOut.type != 'Voltage':
798 raise 'Digital RF cannot be used with this data type'
817 raise 'Digital RF cannot be used with this data type'
799 for channel in self.dataOut.channelList:
818 for channel in self.dataOut.channelList:
800 for i in range(self.dataOut.nFFTPoints):
819 for i in range(self.dataOut.nFFTPoints):
801 self.arr_data[1][channel * self.dataOut.nFFTPoints +
820 self.arr_data[1][channel * self.dataOut.nFFTPoints +
802 i]['r'] = self.dataOut.data[channel][i].real
821 i]['r'] = self.dataOut.data[channel][i].real
803 self.arr_data[1][channel * self.dataOut.nFFTPoints +
822 self.arr_data[1][channel * self.dataOut.nFFTPoints +
804 i]['i'] = self.dataOut.data[channel][i].imag
823 i]['i'] = self.dataOut.data[channel][i].imag
805 else:
824 else:
806 for i in range(self.dataOut.systemHeaderObj.nSamples):
825 for i in range(self.dataOut.systemHeaderObj.nSamples):
807 for channel in self.dataOut.channelList:
826 for channel in self.dataOut.channelList:
808 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
827 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
809 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
828 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
810
829
811 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
830 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
812 self.timeit(f)
831 self.timeit(f)
813
832
814 return
833 return
815
834
816 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
835 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
817 '''
836 '''
818 This method will be called many times so here you should put all your code
837 This method will be called many times so here you should put all your code
819 Inputs:
838 Inputs:
820 dataOut: object with the data
839 dataOut: object with the data
821 '''
840 '''
822 # print dataOut.__dict__
841 # print dataOut.__dict__
823 self.dataOut = dataOut
842 self.dataOut = dataOut
824 if not self.isConfig:
843 if not self.isConfig:
825 self.setup(dataOut, path, frequency, fileCadence,
844 self.setup(dataOut, path, frequency, fileCadence,
826 dirCadence, metadataCadence, **kwargs)
845 dirCadence, metadataCadence, **kwargs)
827 self.writeMetadata()
846 self.writeMetadata()
828
847
829 self.writeData()
848 self.writeData()
830
849
831 ## self.currentSample += 1
850 ## self.currentSample += 1
832 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
851 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
833 # self.writeMetadata()
852 # self.writeMetadata()
834 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
853 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
835
854
836 return dataOut# en la version 2.7 no aparece este return
855 return dataOut# en la version 2.7 no aparece este return
837
856
838 def close(self):
857 def close(self):
839 print('[Writing] - Closing files ')
858 print('[Writing] - Closing files ')
840 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
859 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
841 try:
860 try:
842 self.digitalWriteObj.close()
861 self.digitalWriteObj.close()
843 except:
862 except:
844 pass
863 pass
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,375 +1,375
1 # SOPHY PROC script
1 # SOPHY PROC script
2 import os, sys, json, argparse
2 import os, sys, json, argparse
3 import datetime
3 import datetime
4 import time
4 import time
5
5
6 PATH = '/DATA_RM/DATA'
6 PATH = '/DATA_RM/DATA'
7 PATH = '/media/jespinoza/Elements'
7 PATH = '/media/jespinoza/Elements'
8 PATH = '/media/jespinoza/data/SOPHY'
8 PATH = '/media/jespinoza/data/SOPHY'
9 PATH = '/home/soporte/Documents/EVENTO'
9 PATH = '/home/soporte/Documents/EVENTO'
10
10
11 PARAM = {
11 PARAM = {
12 'S': {'zmin': -45, 'zmax': -25, 'colormap': 'jet', 'label': 'Power', 'wrname': 'power','cb_label': 'dBm', 'ch':0},
12 'S': {'zmin': -45, 'zmax': -25, 'colormap': 'jet', 'label': 'Power', 'wrname': 'power','cb_label': 'dBm', 'ch':0},
13 'SNR': {'zmin': -40, 'zmax': -20, 'colormap': 'jet', 'label': 'SNR', 'wrname': 'snr','cb_label': 'dB', 'ch':0},
13 'SNR': {'zmin': -40, 'zmax': -20, 'colormap': 'jet', 'label': 'SNR', 'wrname': 'snr','cb_label': 'dB', 'ch':0},
14 'V': {'zmin': -12, 'zmax': 12, 'colormap': 'sophy_v', 'label': 'Velocity', 'wrname': 'velocity', 'cb_label': 'm/s', 'ch':0},
14 'V': {'zmin': -12, 'zmax': 12, 'colormap': 'sophy_v', 'label': 'Velocity', 'wrname': 'velocity', 'cb_label': 'm/s', 'ch':0},
15 'R': {'zmin': 0, 'zmax': 1, 'colormap': 'jet', 'label': 'RhoHV', 'wrname':'rhoHV', 'cb_label': '*', 'ch':0},
15 'R': {'zmin': 0, 'zmax': 1, 'colormap': 'jet', 'label': 'RhoHV', 'wrname':'rhoHV', 'cb_label': '*', 'ch':0},
16 'P': {'zmin': -180,'zmax': 180,'colormap': 'RdBu_r', 'label': 'PhiDP', 'wrname':'phiDP' , 'cb_label': 'ΒΊ', 'ch':0},
16 'P': {'zmin': -180,'zmax': 180,'colormap': 'RdBu_r', 'label': 'PhiDP', 'wrname':'phiDP' , 'cb_label': 'ΒΊ', 'ch':0},
17 'D': {'zmin': -30, 'zmax': 80, 'colormap': 'sophy_r','label': 'ZDR','wrname':'differential_reflectivity' , 'cb_label': 'dBz','ch':0},
17 'D': {'zmin': -30, 'zmax': 80, 'colormap': 'sophy_r','label': 'ZDR','wrname':'differential_reflectivity' , 'cb_label': 'dBz','ch':0},
18 'Z': {'zmin': -30, 'zmax': 80, 'colormap': 'sophy_r','label': 'Reflectivity ', 'wrname':'reflectivity', 'cb_label': 'dBz','ch':0},
18 'Z': {'zmin': -30, 'zmax': 80, 'colormap': 'sophy_r','label': 'Reflectivity ', 'wrname':'reflectivity', 'cb_label': 'dBz','ch':0},
19 'W': {'zmin': 0, 'zmax': 15, 'colormap': 'sophy_w','label': 'Spectral Width', 'wrname':'spectral_width', 'cb_label': 'm/s', 'ch':0}
19 'W': {'zmin': 0, 'zmax': 15, 'colormap': 'sophy_w','label': 'Spectral Width', 'wrname':'spectral_width', 'cb_label': 'm/s', 'ch':0}
20 }
20 }
21
21
22 def max_index(r, sample_rate, ipp):
22 def max_index(r, sample_rate, ipp):
23
23
24 return int(sample_rate*ipp*1e6 * r / 60) + int(sample_rate*ipp*1e6 * 1.2 / 60)
24 return int(sample_rate*ipp*1e6 * r / 60) + int(sample_rate*ipp*1e6 * 1.2 / 60)
25
25
26 def main(args):
26 def main(args):
27
27
28 experiment = args.experiment
28 experiment = args.experiment
29 fp = open(os.path.join(PATH, experiment, 'experiment.conf'))
29 fp = open(os.path.join(PATH, experiment, 'experiment.conf'))
30 conf = json.loads(fp.read())
30 conf = json.loads(fp.read())
31
31
32 ipp_km = conf['usrp_tx']['ipp']
32 ipp_km = conf['usrp_tx']['ipp']
33 ipp = ipp_km * 2 /300000
33 ipp = ipp_km * 2 /300000
34 sample_rate = conf['usrp_rx']['sample_rate']
34 sample_rate = conf['usrp_rx']['sample_rate']
35 axis = ['0' if x=='elevation' else '1' for x in conf['pedestal']['axis']] # AZIMUTH 1 ELEVACION 0
35 axis = ['0' if x=='elevation' else '1' for x in conf['pedestal']['axis']] # AZIMUTH 1 ELEVACION 0
36 speed_axis = conf['pedestal']['speed']
36 speed_axis = conf['pedestal']['speed']
37 steps = conf['pedestal']['table']
37 steps = conf['pedestal']['table']
38 time_offset = args.time_offset
38 time_offset = args.time_offset
39 parameters = args.parameters
39 parameters = args.parameters
40 start_date = experiment.split('@')[1].split('T')[0].replace('-', '/')
40 start_date = experiment.split('@')[1].split('T')[0].replace('-', '/')
41 end_date = start_date
41 end_date = start_date
42 if args.start_time:
42 if args.start_time:
43 start_time = args.start_time
43 start_time = args.start_time
44 else:
44 else:
45 start_time = experiment.split('@')[1].split('T')[1].replace('-', ':')
45 start_time = experiment.split('@')[1].split('T')[1].replace('-', ':')
46 end_time = '23:59:59'
46 end_time = '23:59:59'
47 N = int(1/(speed_axis[0]*ipp)) # 1 GRADO DE RESOLUCION
47 N = int(1/(speed_axis[0]*ipp)) # 1 GRADO DE RESOLUCION
48 path = os.path.join(PATH, experiment, 'rawdata')
48 path = os.path.join(PATH, experiment, 'rawdata')
49 path_ped = os.path.join(PATH, experiment, 'position')
49 path_ped = os.path.join(PATH, experiment, 'position')
50 path_plots = os.path.join(PATH, experiment, 'plotsC0N'+str(args.range))
50 path_plots = os.path.join(PATH, experiment, 'plotsC0N'+str(args.range))
51 path_save = os.path.join(PATH, experiment, 'paramC0N'+str(args.range))
51 path_save = os.path.join(PATH, experiment, 'paramC0N'+str(args.range))
52 RMIX = 1.62
52 RMIX = 1.62
53 H0 = -1.68
53 H0 = -1.68
54 MASK = 0.3
54 MASK = 0.3
55
55
56 from schainpy.controller import Project
56 from schainpy.controller import Project
57
57
58 project = Project()
58 project = Project()
59 project.setup(id='1', name='Sophy', description='sophy proc')
59 project.setup(id='1', name='Sophy', description='sophy proc')
60
60
61 reader = project.addReadUnit(datatype='DigitalRFReader',
61 reader = project.addReadUnit(datatype='DigitalRFReader',
62 path=path,
62 path=path,
63 startDate=start_date,
63 startDate=start_date,
64 endDate=end_date,
64 endDate=end_date,
65 startTime=start_time,
65 startTime=start_time,
66 endTime=end_time,
66 endTime=end_time,
67 delay=30,
67 delay=30,
68 online=args.online,
68 online=args.online,
69 walk=1,
69 walk=1,
70 ippKm = ipp_km,
70 ippKm = ipp_km,
71 getByBlock = 1,
71 getByBlock = 1,
72 nProfileBlocks = N,
72 nProfileBlocks = N,
73 )
73 )
74
74
75 if not conf['usrp_tx']['enable_2']: # One Pulse
75 if not conf['usrp_tx']['enable_2']: # One Pulse
76 voltage = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
76 voltage = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
77
77
78 if conf['usrp_tx']['code_type_1'] != 'None':
78 if conf['usrp_tx']['code_type_1'] != 'None':
79 codes = [ c.strip() for c in conf['usrp_tx']['code_1'].split(',')]
79 codes = [ c.strip() for c in conf['usrp_tx']['code_1'].split(',')]
80 code = []
80 code = []
81 for c in codes:
81 for c in codes:
82 code.append([int(x) for x in c])
82 code.append([int(x) for x in c])
83 op = voltage.addOperation(name='Decoder', optype='other')
83 op = voltage.addOperation(name='Decoder', optype='other')
84 op.addParameter(name='code', value=code)
84 op.addParameter(name='code', value=code)
85 op.addParameter(name='nCode', value=len(code), format='int')
85 op.addParameter(name='nCode', value=len(code), format='int')
86 op.addParameter(name='nBaud', value=len(code[0]), format='int')
86 op.addParameter(name='nBaud', value=len(code[0]), format='int')
87
87
88 op = voltage.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
88 op = voltage.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
89 op.addParameter(name='n', value=len(code), format='int')
89 op.addParameter(name='n', value=len(code), format='int')
90 ncode = len(code)
90 ncode = len(code)
91 else:
91 else:
92 ncode = 1
92 ncode = 1
93 code = ['0']
93 code = ['0']
94
94
95 op = voltage.addOperation(name='setH0')
95 op = voltage.addOperation(name='setH0')
96 op.addParameter(name='h0', value=H0)
96 op.addParameter(name='h0', value=H0)
97
97
98 if args.range > 0:
98 if args.range > 0:
99 op = voltage.addOperation(name='selectHeights')
99 op = voltage.addOperation(name='selectHeights')
100 op.addParameter(name='minIndex', value='0', format='int')
100 op.addParameter(name='minIndex', value='0', format='int')
101 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
101 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
102
102
103 op = voltage.addOperation(name='PulsePair_vRF', optype='other')
103 op = voltage.addOperation(name='PulsePair_vRF', optype='other')
104 op.addParameter(name='n', value=int(N)/ncode, format='int')
104 op.addParameter(name='n', value=int(N)/ncode, format='int')
105 #op.addParameter(name='removeDC', value=1, format='int')
105 #op.addParameter(name='removeDC', value=1, format='int')
106
106
107
107
108 proc = project.addProcUnit(datatype='ParametersProc', inputId=voltage.getId())
108 proc = project.addProcUnit(datatype='ParametersProc', inputId=voltage.getId())
109
109
110 opObj10 = proc.addOperation(name="WeatherRadar")
110 opObj10 = proc.addOperation(name="WeatherRadar")
111 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
111 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
112 opObj10.addParameter(name='Pt',value=((1e-6/sample_rate)*len(code[0])/ipp)*200)
112 opObj10.addParameter(name='Pt',value=((1e-6/sample_rate)*len(code[0])/ipp)*200)
113
113
114 op = proc.addOperation(name='PedestalInformation')
114 op = proc.addOperation(name='PedestalInformation')
115 op.addParameter(name='path', value=path_ped, format='str')
115 op.addParameter(name='path', value=path_ped, format='str')
116 op.addParameter(name='interval', value='0.04')
116 op.addParameter(name='interval', value='0.04')
117 op.addParameter(name='time_offset', value=time_offset)
117 op.addParameter(name='time_offset', value=time_offset)
118 op.addParameter(name='mode', value='PPI')
118 op.addParameter(name='mode', value='PPI')
119
119
120 for param in parameters:
120 for param in parameters:
121 op = proc.addOperation(name='Block360')
121 op = proc.addOperation(name='Block360')
122 op.addParameter(name='runNextOp', value=True)
122 op.addParameter(name='runNextOp', value=True)
123
123
124 op= proc.addOperation(name='WeatherParamsPlot')
124 op= proc.addOperation(name='WeatherParamsPlot')
125 if args.save: op.addParameter(name='save', value=path_plots, format='str')
125 if args.save: op.addParameter(name='save', value=path_plots, format='str')
126 op.addParameter(name='save_period', value=-1)
126 op.addParameter(name='save_period', value=-1)
127 op.addParameter(name='show', value=args.show)
127 op.addParameter(name='show', value=args.show)
128 op.addParameter(name='channels', value='1,')
128 op.addParameter(name='channels', value='1,')
129 op.addParameter(name='zmin', value=PARAM[param]['zmin'])
129 op.addParameter(name='zmin', value=PARAM[param]['zmin'])
130 op.addParameter(name='zmax', value=PARAM[param]['zmax'])
130 op.addParameter(name='zmax', value=PARAM[param]['zmax'])
131 op.addParameter(name='attr_data', value=param, format='str')
131 op.addParameter(name='attr_data', value=param, format='str')
132 op.addParameter(name='labels', value=[PARAM[param]['label']])
132 op.addParameter(name='labels', value=[PARAM[param]['label']])
133 op.addParameter(name='save_code', value=param)
133 op.addParameter(name='save_code', value=param)
134 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
134 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
135 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
135 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
136 op.addParameter(name='bgcolor', value='black')
136 op.addParameter(name='bgcolor', value='black')
137 if MASK: op.addParameter(name='mask', value=MASK, format='float')
137 if MASK: op.addParameter(name='mask', value=MASK, format='float')
138 if args.server:
138 if args.server:
139 op.addParameter(name='server', value='0.0.0.0:4444')
139 op.addParameter(name='server', value='0.0.0.0:4444')
140 op.addParameter(name='exp_code', value='400')
140 op.addParameter(name='exp_code', value='400')
141
141
142 desc = {
142 desc = {
143 'Data': {
143 'Data': {
144 param: PARAM[param]['wrname'],
144 param: PARAM[param]['wrname'],
145 'utctime': 'time'
145 'utctime': 'time'
146 },
146 },
147 'Metadata': {
147 'Metadata': {
148 'heightList': 'range',
148 'heightList': 'range',
149 'data_azi': 'azimuth',
149 'data_azi': 'azimuth',
150 'data_ele': 'elevation',
150 'data_ele': 'elevation',
151 'mode_op': 'scan_type',
151 'mode_op': 'scan_type',
152 'h0': 'range_correction',
152 'h0': 'range_correction',
153 }
153 }
154 }
154 }
155
155
156 if args.save:
156 if args.save:
157 opObj10 = proc.addOperation(name='HDFWriter')
157 opObj10 = proc.addOperation(name='HDFWriter')
158 writer.addParameter(name='path', value=path_save, format='str')
158 writer.addParameter(name='path', value=path_save, format='str')
159 writer.addParameter(name='Reset', value=True)
159 writer.addParameter(name='Reset', value=True)
160 writer.addParameter(name='setType', value='weather')
160 writer.addParameter(name='setType', value='weather')
161 writer.addParameter(name='description', value=json.dumps(desc))
161 writer.addParameter(name='description', value=json.dumps(desc))
162 writer.addParameter(name='blocksPerFile', value='1',format='int')
162 writer.addParameter(name='blocksPerFile', value='1',format='int')
163 writer.addParameter(name='metadataList', value='heightList,data_azi,data_ele,mode_op,latitude,longitude,altitude,heading,radar_name,institution,contact,h0,range_unit')
163 writer.addParameter(name='metadataList', value='heightList,data_azi,data_ele,mode_op,latitude,longitude,altitude,heading,radar_name,institution,contact,h0,range_unit')
164 writer.addParameter(name='dataList', value='{},utctime'.format(param))
164 writer.addParameter(name='dataList', value='{},utctime'.format(param))
165 writer.addParameter(name='mask', value=MASK, format='float')
165 writer.addParameter(name='mask', value=MASK, format='float')
166 # meta
166 # meta
167 writer.addParameter(name='latitude', value='-12.040436')
167 writer.addParameter(name='latitude', value='-12.040436')
168 writer.addParameter(name='longitude', value='-75.295893')
168 writer.addParameter(name='longitude', value='-75.295893')
169 writer.addParameter(name='altitude', value='3379.2147')
169 writer.addParameter(name='altitude', value='3379.2147')
170 writer.addParameter(name='heading', value='0')
170 writer.addParameter(name='heading', value='0')
171 writer.addParameter(name='radar_name', value='SOPHy')
171 writer.addParameter(name='radar_name', value='SOPHy')
172 writer.addParameter(name='institution', value='IGP')
172 writer.addParameter(name='institution', value='IGP')
173 writer.addParameter(name='contact', value='dscipion@igp.gob.pe')
173 writer.addParameter(name='contact', value='dscipion@igp.gob.pe')
174 writer.addParameter(name='created_by', value='Signal Chain (https://pypi.org/project/schainpy/)')
174 writer.addParameter(name='created_by', value='Signal Chain (https://pypi.org/project/schainpy/)')
175 writer.addParameter(name='range_unit', value='km')
175 writer.addParameter(name='range_unit', value='km')
176
176
177 else: #Two pulses
177 else: #Two pulses
178
178
179 voltage1 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
179 voltage1 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
180
180
181 op = voltage1.addOperation(name='ProfileSelector')
181 op = voltage1.addOperation(name='ProfileSelector')
182 op.addParameter(name='profileRangeList', value='0,{}'.format(conf['usrp_tx']['repetitions_1']-1))
182 op.addParameter(name='profileRangeList', value='0,{}'.format(conf['usrp_tx']['repetitions_1']-1))
183
183
184 if conf['usrp_tx']['code_type_1'] != 'None':
184 if conf['usrp_tx']['code_type_1'] != 'None':
185 codes = [ c.strip() for c in conf['usrp_tx']['code_1'].split(',')]
185 codes = [ c.strip() for c in conf['usrp_tx']['code_1'].split(',')]
186 code = []
186 code = []
187 for c in codes:
187 for c in codes:
188 code.append([int(x) for x in c])
188 code.append([int(x) for x in c])
189 op = voltage1.addOperation(name='Decoder', optype='other')
189 op = voltage1.addOperation(name='Decoder', optype='other')
190 op.addParameter(name='code', value=code)
190 op.addParameter(name='code', value=code)
191 op.addParameter(name='nCode', value=len(code), format='int')
191 op.addParameter(name='nCode', value=len(code), format='int')
192 op.addParameter(name='nBaud', value=len(code[0]), format='int')
192 op.addParameter(name='nBaud', value=len(code[0]), format='int')
193 else:
193 else:
194 code = ['0']
194 code = ['0']
195
195
196 op = voltage1.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
196 op = voltage1.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
197 op.addParameter(name='n', value=2, format='int')
197 op.addParameter(name='n', value=2, format='int')
198
198
199 if args.range > 0:
199 if args.range > 0:
200 op = voltage1.addOperation(name='selectHeights')
200 op = voltage1.addOperation(name='selectHeights')
201 op.addParameter(name='minIndex', value='0', format='int')
201 op.addParameter(name='minIndex', value='0', format='int')
202 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
202 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
203
203
204 op = voltage1.addOperation(name='setH0')
204 op = voltage1.addOperation(name='setH0')
205 op.addParameter(name='h0', value=H0, format='float')
205 op.addParameter(name='h0', value=H0, format='float')
206
206
207 op = voltage1.addOperation(name='PulsePair_vRF', optype='other')
207 op = voltage1.addOperation(name='PulsePair_vRF', optype='other')
208 op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_1'])/2, format='int')
208 op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_1'])/2, format='int')
209 #op.addParameter(name='removeDC', value=1, format='int')
209 #op.addParameter(name='removeDC', value=1, format='int')
210
210
211
211
212 proc1 = project.addProcUnit(datatype='ParametersProc', inputId=voltage1.getId())
212 proc1 = project.addProcUnit(datatype='ParametersProc', inputId=voltage1.getId())
213 proc1.addParameter(name='runNextUnit', value=True)
213 proc1.addParameter(name='runNextUnit', value=True)
214
214
215 opObj10 = proc1.addOperation(name="WeatherRadar")
215 opObj10 = proc1.addOperation(name="WeatherRadar")
216 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
216 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
217 opObj10.addParameter(name='Pt',value=((1e-6/sample_rate)*len(code[0])/ipp)*200)
217 opObj10.addParameter(name='Pt',value=200)
218
218
219 op = proc1.addOperation(name='PedestalInformation')
219 op = proc1.addOperation(name='PedestalInformation')
220 op.addParameter(name='path', value=path_ped, format='str')
220 op.addParameter(name='path', value=path_ped, format='str')
221 op.addParameter(name='interval', value='0.04')
221 op.addParameter(name='interval', value='0.04')
222 op.addParameter(name='time_offset', value=time_offset)
222 op.addParameter(name='time_offset', value=time_offset)
223 op.addParameter(name='mode', value='PPI')
223 op.addParameter(name='mode', value='PPI')
224
224
225 op = proc1.addOperation(name='Block360')
225 op = proc1.addOperation(name='Block360')
226 op.addParameter(name='attr_data', value='data_param')
226 op.addParameter(name='attr_data', value='data_param')
227 op.addParameter(name='runNextOp', value=True)
227 op.addParameter(name='runNextOp', value=True)
228
228
229
229
230 voltage2 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
230 voltage2 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
231
231
232 op = voltage2.addOperation(name='ProfileSelector')
232 op = voltage2.addOperation(name='ProfileSelector')
233 op.addParameter(name='profileRangeList', value='{},{}'.format(conf['usrp_tx']['repetitions_1'], conf['usrp_tx']['repetitions_1']+conf['usrp_tx']['repetitions_2']-1))
233 op.addParameter(name='profileRangeList', value='{},{}'.format(conf['usrp_tx']['repetitions_1'], conf['usrp_tx']['repetitions_1']+conf['usrp_tx']['repetitions_2']-1))
234
234
235 if conf['usrp_tx']['code_type_2']:
235 if conf['usrp_tx']['code_type_2']:
236 codes = [ c.strip() for c in conf['usrp_tx']['code_2'].split(',')]
236 codes = [ c.strip() for c in conf['usrp_tx']['code_2'].split(',')]
237 code = []
237 code = []
238 for c in codes:
238 for c in codes:
239 code.append([int(x) for x in c])
239 code.append([int(x) for x in c])
240 op = voltage2.addOperation(name='Decoder', optype='other')
240 op = voltage2.addOperation(name='Decoder', optype='other')
241 op.addParameter(name='code', value=code)
241 op.addParameter(name='code', value=code)
242 op.addParameter(name='nCode', value=len(code), format='int')
242 op.addParameter(name='nCode', value=len(code), format='int')
243 op.addParameter(name='nBaud', value=len(code[0]), format='int')
243 op.addParameter(name='nBaud', value=len(code[0]), format='int')
244
244
245 op = voltage2.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
245 op = voltage2.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
246 op.addParameter(name='n', value=len(code), format='int')
246 op.addParameter(name='n', value=len(code), format='int')
247 ncode = len(code)
247 ncode = len(code)
248 else:
248 else:
249 ncode = 1
249 ncode = 1
250
250
251 if args.range > 0:
251 if args.range > 0:
252 op = voltage2.addOperation(name='selectHeights')
252 op = voltage2.addOperation(name='selectHeights')
253 op.addParameter(name='minIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
253 op.addParameter(name='minIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
254 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
254 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
255
255
256 op = voltage2.addOperation(name='setH0')
256 op = voltage2.addOperation(name='setH0')
257 op.addParameter(name='h0', value=H0, format='float')
257 op.addParameter(name='h0', value=H0, format='float')
258
258
259 op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
259 op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
260 op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_2'])/ncode, format='int')
260 op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_2'])/ncode, format='int')
261 #op.addParameter(name='removeDC', value=1, format='int')
261 #op.addParameter(name='removeDC', value=1, format='int')
262
262
263
263
264 proc2 = project.addProcUnit(datatype='ParametersProc', inputId=voltage2.getId())
264 proc2 = project.addProcUnit(datatype='ParametersProc', inputId=voltage2.getId())
265 proc2.addParameter(name='runNextUnit', value=True)
265 proc2.addParameter(name='runNextUnit', value=True)
266
266
267 opObj10 = proc2.addOperation(name="WeatherRadar")
267 opObj10 = proc2.addOperation(name="WeatherRadar")
268 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
268 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
269 opObj10.addParameter(name='Pt',value=((1e-6/sample_rate)*len(code[0])/ipp)*200)
269 opObj10.addParameter(name='Pt',value=200)
270
270
271 op = proc2.addOperation(name='PedestalInformation')
271 op = proc2.addOperation(name='PedestalInformation')
272 op.addParameter(name='path', value=path_ped, format='str')
272 op.addParameter(name='path', value=path_ped, format='str')
273 op.addParameter(name='interval', value='0.04')
273 op.addParameter(name='interval', value='0.04')
274 op.addParameter(name='time_offset', value=time_offset)
274 op.addParameter(name='time_offset', value=time_offset)
275 op.addParameter(name='mode', value='PPI')
275 op.addParameter(name='mode', value='PPI')
276
276
277 op = proc2.addOperation(name='Block360')
277 op = proc2.addOperation(name='Block360')
278 op.addParameter(name='attr_data', value='data_param')
278 op.addParameter(name='attr_data', value='data_param')
279 op.addParameter(name='runNextOp', value=True)
279 op.addParameter(name='runNextOp', value=True)
280
280
281 merge = project.addProcUnit(datatype='MergeProc', inputId=[proc1.getId(), proc2.getId()])
281 merge = project.addProcUnit(datatype='MergeProc', inputId=[proc1.getId(), proc2.getId()])
282 merge.addParameter(name='attr_data', value='data_param')
282 merge.addParameter(name='attr_data', value='data_param')
283 merge.addParameter(name='mode', value='7') #RM
283 merge.addParameter(name='mode', value='7') #RM
284
284
285
285
286 for param in parameters:
286 for param in parameters:
287
287
288 if args.plot:
288 if args.plot:
289 op= merge.addOperation(name='WeatherParamsPlot')
289 op= merge.addOperation(name='WeatherParamsPlot')
290 if args.save:
290 if args.save:
291 op.addParameter(name='save', value=path_plots, format='str')
291 op.addParameter(name='save', value=path_plots, format='str')
292 op.addParameter(name='save_period', value=-1)
292 op.addParameter(name='save_period', value=-1)
293 op.addParameter(name='show', value=args.show)
293 op.addParameter(name='show', value=args.show)
294 op.addParameter(name='channels', value='0,')
294 op.addParameter(name='channels', value='0,')
295 op.addParameter(name='zmin', value=PARAM[param]['zmin'], format='int')
295 op.addParameter(name='zmin', value=PARAM[param]['zmin'], format='int')
296 op.addParameter(name='zmax', value=PARAM[param]['zmax'], format='int')
296 op.addParameter(name='zmax', value=PARAM[param]['zmax'], format='int')
297 op.addParameter(name='attr_data', value=param, format='str')
297 op.addParameter(name='attr_data', value=param, format='str')
298 op.addParameter(name='labels', value=[PARAM[param]['label']])
298 op.addParameter(name='labels', value=[PARAM[param]['label']])
299 op.addParameter(name='save_code', value=param)
299 op.addParameter(name='save_code', value=param)
300 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
300 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
301 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
301 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
302 op.addParameter(name='bgcolor', value='black')
302 op.addParameter(name='bgcolor', value='black')
303 if MASK: op.addParameter(name='mask', value=MASK, format='float')
303 if MASK: op.addParameter(name='mask', value=MASK, format='float')
304 if args.server:
304 if args.server:
305 op.addParameter(name='server', value='0.0.0.0:4444')
305 op.addParameter(name='server', value='0.0.0.0:4444')
306 op.addParameter(name='exp_code', value='400')
306 op.addParameter(name='exp_code', value='400')
307
307
308 desc = {
308 desc = {
309 'Data': {
309 'Data': {
310 'data_param': {PARAM[param]['wrname']: ['H', 'V']},
310 'data_param': {PARAM[param]['wrname']: ['H', 'V']},
311 'utctime': 'time'
311 'utctime': 'time'
312 },
312 },
313 'Metadata': {
313 'Metadata': {
314 'heightList': 'range',
314 'heightList': 'range',
315 'data_azi': 'azimuth',
315 'data_azi': 'azimuth',
316 'data_ele': 'elevation',
316 'data_ele': 'elevation',
317 'mode_op': 'scan_type',
317 'mode_op': 'scan_type',
318 'h0': 'range_correction',
318 'h0': 'range_correction',
319 }
319 }
320 }
320 }
321
321
322 if args.save:
322 if args.save:
323 writer = merge.addOperation(name='HDFWriter')
323 writer = merge.addOperation(name='HDFWriter')
324 writer.addParameter(name='path', value=path_save, format='str')
324 writer.addParameter(name='path', value=path_save, format='str')
325 writer.addParameter(name='Reset', value=True)
325 writer.addParameter(name='Reset', value=True)
326 writer.addParameter(name='setType', value='weather')
326 writer.addParameter(name='setType', value='weather')
327 writer.addParameter(name='description', value=json.dumps(desc))
327 writer.addParameter(name='description', value=json.dumps(desc))
328 writer.addParameter(name='blocksPerFile', value='1',format='int')
328 writer.addParameter(name='blocksPerFile', value='1',format='int')
329 writer.addParameter(name='metadataList', value='heightList,data_azi,data_ele,mode_op,latitude,longitude,altitude,heading,radar_name,institution,contact,h0,range_unit')
329 writer.addParameter(name='metadataList', value='heightList,data_azi,data_ele,mode_op,latitude,longitude,altitude,heading,radar_name,institution,contact,h0,range_unit')
330 writer.addParameter(name='dataList', value='data_param,utctime')
330 writer.addParameter(name='dataList', value='data_param,utctime')
331 writer.addParameter(name='weather_var', value=param)
331 writer.addParameter(name='weather_var', value=param)
332 writer.addParameter(name='mask', value=MASK, format='float')
332 writer.addParameter(name='mask', value=MASK, format='float')
333 # meta
333 # meta
334 writer.addParameter(name='latitude', value='-12.040436')
334 writer.addParameter(name='latitude', value='-12.040436')
335 writer.addParameter(name='longitude', value='-75.295893')
335 writer.addParameter(name='longitude', value='-75.295893')
336 writer.addParameter(name='altitude', value='3379.2147')
336 writer.addParameter(name='altitude', value='3379.2147')
337 writer.addParameter(name='heading', value='0')
337 writer.addParameter(name='heading', value='0')
338 writer.addParameter(name='radar_name', value='SOPHy')
338 writer.addParameter(name='radar_name', value='SOPHy')
339 writer.addParameter(name='institution', value='IGP')
339 writer.addParameter(name='institution', value='IGP')
340 writer.addParameter(name='contact', value='dscipion@igp.gob.pe')
340 writer.addParameter(name='contact', value='dscipion@igp.gob.pe')
341 writer.addParameter(name='created_by', value='Signal Chain (https://pypi.org/project/schainpy/)')
341 writer.addParameter(name='created_by', value='Signal Chain (https://pypi.org/project/schainpy/)')
342 writer.addParameter(name='range_unit', value='km')
342 writer.addParameter(name='range_unit', value='km')
343
343
344 project.start()
344 project.start()
345
345
346 if __name__ == '__main__':
346 if __name__ == '__main__':
347
347
348 parser = argparse.ArgumentParser(description='Script to process SOPHy data.')
348 parser = argparse.ArgumentParser(description='Script to process SOPHy data.')
349 parser.add_argument('experiment',
349 parser.add_argument('experiment',
350 help='Experiment name')
350 help='Experiment name')
351 parser.add_argument('--parameters', nargs='*', default=['S'],
351 parser.add_argument('--parameters', nargs='*', default=['S'],
352 help='Variables to process: P, Z, V')
352 help='Variables to process: P, Z, V')
353 parser.add_argument('--time_offset', default=0,
353 parser.add_argument('--time_offset', default=0,
354 help='Fix time offset')
354 help='Fix time offset')
355 parser.add_argument('--range', default=0, type=float,
355 parser.add_argument('--range', default=0, type=float,
356 help='Max range to plot')
356 help='Max range to plot')
357 parser.add_argument('--save', action='store_true',
357 parser.add_argument('--save', action='store_true',
358 help='Create output files')
358 help='Create output files')
359 parser.add_argument('--plot', action='store_true',
359 parser.add_argument('--plot', action='store_true',
360 help='Create plot files')
360 help='Create plot files')
361 parser.add_argument('--show', action='store_true',
361 parser.add_argument('--show', action='store_true',
362 help='Show matplotlib plot.')
362 help='Show matplotlib plot.')
363 parser.add_argument('--online', action='store_true',
363 parser.add_argument('--online', action='store_true',
364 help='Set online mode.')
364 help='Set online mode.')
365 parser.add_argument('--server', action='store_true',
365 parser.add_argument('--server', action='store_true',
366 help='Send to realtime')
366 help='Send to realtime')
367 parser.add_argument('--start_time', default='',
367 parser.add_argument('--start_time', default='',
368 help='Set start time.')
368 help='Set start time.')
369
369
370
370
371 args = parser.parse_args()
371 args = parser.parse_args()
372
372
373 main(args)
373 main(args)
374
374
375 # python sophy_proc.py HYO_PM@2022-06-09T15-05-12 --parameters V --plot --save --show --range 36S
375 # python sophy_proc.py HYO_PM@2022-06-09T15-05-12 --parameters V --plot --save --show --range 36S
General Comments 0
You need to be logged in to leave comments. Login now