##// END OF EJS Templates
plot
joabAM -
r1749:e3f1b2c53e4b
parent child
Show More
@@ -1,1935 +1,1935
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 import datetime
11 import datetime
12
12
13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
14 from itertools import combinations
14 from itertools import combinations
15 from matplotlib.ticker import LinearLocator
15 from matplotlib.ticker import LinearLocator
16
16
17 from schainpy.model.utils.BField import BField
17 from schainpy.model.utils.BField import BField
18 from scipy.interpolate import splrep
18 from scipy.interpolate import splrep
19 from scipy.interpolate import splev
19 from scipy.interpolate import splev
20
20
21 from matplotlib import __version__ as plt_version
21 from matplotlib import __version__ as plt_version
22
22
23 if plt_version >='3.3.4':
23 if plt_version >='3.3.4':
24 EXTRA_POINTS = 0
24 EXTRA_POINTS = 0
25 else:
25 else:
26 EXTRA_POINTS = 1
26 EXTRA_POINTS = 1
27 class SpectraPlot(Plot):
27 class SpectraPlot(Plot):
28 '''
28 '''
29 Plot for Spectra data
29 Plot for Spectra data
30 '''
30 '''
31
31
32 CODE = 'spc'
32 CODE = 'spc'
33 colormap = 'jet'
33 colormap = 'jet'
34 plot_type = 'pcolor'
34 plot_type = 'pcolor'
35 buffering = False
35 buffering = False
36 channelList = []
36 channelList = []
37 elevationList = []
37 elevationList = []
38 azimuthList = []
38 azimuthList = []
39
39
40 def setup(self):
40 def setup(self):
41
41
42 self.nplots = len(self.data.channels)
42 self.nplots = len(self.data.channels)
43 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
43 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
44 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
44 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
45 self.height = 3.4 * self.nrows
45 self.height = 3.4 * self.nrows
46 self.cb_label = 'dB'
46 self.cb_label = 'dB'
47 if self.showprofile:
47 if self.showprofile:
48 self.width = 5.2 * self.ncols
48 self.width = 5.2 * self.ncols
49 else:
49 else:
50 self.width = 4.2* self.ncols
50 self.width = 4.2* self.ncols
51 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.12})
51 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.12})
52 self.ylabel = 'Range [km]'
52 self.ylabel = 'Range [km]'
53
53
54 def update_list(self,dataOut):
54 def update_list(self,dataOut):
55
55
56 if len(self.channelList) == 0:
56 if len(self.channelList) == 0:
57 self.channelList = dataOut.channelList
57 self.channelList = dataOut.channelList
58 if len(self.elevationList) == 0:
58 if len(self.elevationList) == 0:
59 self.elevationList = dataOut.elevationList
59 self.elevationList = dataOut.elevationList
60 if len(self.azimuthList) == 0:
60 if len(self.azimuthList) == 0:
61 self.azimuthList = dataOut.azimuthList
61 self.azimuthList = dataOut.azimuthList
62
62
63 def update(self, dataOut):
63 def update(self, dataOut):
64
64
65 self.update_list(dataOut)
65 self.update_list(dataOut)
66 data = {}
66 data = {}
67 meta = {}
67 meta = {}
68 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
68 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
69 if dataOut.type == "Parameters":
69 if dataOut.type == "Parameters":
70 noise = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
70 noise = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
71 spc = 10*numpy.log10(dataOut.data_spc/(dataOut.nProfiles))
71 spc = 10*numpy.log10(dataOut.data_spc/(dataOut.nProfiles))
72 else:
72 else:
73 noise = 10*numpy.log10(dataOut.getNoise()/norm)
73 noise = 10*numpy.log10(dataOut.getNoise()/norm)
74
74
75 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
75 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
76 for ch in range(dataOut.nChannels):
76 for ch in range(dataOut.nChannels):
77 if hasattr(dataOut.normFactor,'ndim'):
77 if hasattr(dataOut.normFactor,'ndim'):
78 if dataOut.normFactor.ndim > 1:
78 if dataOut.normFactor.ndim > 1:
79 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
79 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
80
80
81 else:
81 else:
82 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
82 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
83 else:
83 else:
84 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
84 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
85
85
86 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
86 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
87 spc = 10*numpy.log10(z)
87 spc = 10*numpy.log10(z)
88
88
89 data['spc'] = spc
89 data['spc'] = spc
90 data['rti'] = spc.mean(axis=1)
90 data['rti'] = spc.mean(axis=1)
91 data['noise'] = noise
91 data['noise'] = noise
92 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
92 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
93 if self.CODE == 'spc_moments':
93 if self.CODE == 'spc_moments':
94 data['moments'] = dataOut.moments
94 data['moments'] = dataOut.moments
95
95
96 return data, meta
96 return data, meta
97
97
98 def plot(self):
98 def plot(self):
99
99
100 if self.xaxis == "frequency":
100 if self.xaxis == "frequency":
101 x = self.data.xrange[0]
101 x = self.data.xrange[0]
102 self.xlabel = "Frequency (kHz)"
102 self.xlabel = "Frequency (kHz)"
103 elif self.xaxis == "time":
103 elif self.xaxis == "time":
104 x = self.data.xrange[1]
104 x = self.data.xrange[1]
105 self.xlabel = "Time (ms)"
105 self.xlabel = "Time (ms)"
106 else:
106 else:
107 x = self.data.xrange[2]
107 x = self.data.xrange[2]
108 self.xlabel = "Velocity (m/s)"
108 self.xlabel = "Velocity (m/s)"
109
109
110 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
110 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
111 x = self.data.xrange[2]
111 x = self.data.xrange[2]
112 self.xlabel = "Velocity (m/s)"
112 self.xlabel = "Velocity (m/s)"
113
113
114 self.titles = []
114 self.titles = []
115
115
116 y = self.data.yrange
116 y = self.data.yrange
117 self.y = y
117 self.y = y
118
118
119 data = self.data[-1]
119 data = self.data[-1]
120 z = data['spc']
120 z = data['spc']
121
121
122 for n, ax in enumerate(self.axes):
122 for n, ax in enumerate(self.axes):
123 noise = self.data['noise'][n][0]
123 noise = self.data['noise'][n][0]
124 # noise = data['noise'][n]
124 # noise = data['noise'][n]
125
125
126 if self.CODE == 'spc_moments':
126 if self.CODE == 'spc_moments':
127 mean = data['moments'][n, 1]
127 mean = data['moments'][n, 1]
128 if self.CODE == 'gaussian_fit':
128 if self.CODE == 'gaussian_fit':
129 gau0 = data['gaussfit'][n][2,:,0]
129 gau0 = data['gaussfit'][n][2,:,0]
130 gau1 = data['gaussfit'][n][2,:,1]
130 gau1 = data['gaussfit'][n][2,:,1]
131 if ax.firsttime:
131 if ax.firsttime:
132 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
132 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
133 self.xmin = self.xmin if self.xmin else -self.xmax
133 self.xmin = self.xmin if self.xmin else -self.xmax
134 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
134 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
135 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
135 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
136 ax.plt = ax.pcolormesh(x, y, z[n].T,
136 ax.plt = ax.pcolormesh(x, y, z[n].T,
137 vmin=self.zmin,
137 vmin=self.zmin,
138 vmax=self.zmax,
138 vmax=self.zmax,
139 cmap=plt.get_cmap(self.colormap)
139 cmap=plt.get_cmap(self.colormap)
140 )
140 )
141
141
142 if self.showprofile:
142 if self.showprofile:
143 ax.plt_profile = self.pf_axes[n].plot(
143 ax.plt_profile = self.pf_axes[n].plot(
144 data['rti'][n], y)[0]
144 data['rti'][n], y)[0]
145 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
145 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
146 color="k", linestyle="dashed", lw=1)[0]
146 color="k", linestyle="dashed", lw=1)[0]
147 if self.CODE == 'spc_moments':
147 if self.CODE == 'spc_moments':
148 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
148 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
149 if self.CODE == 'gaussian_fit':
149 if self.CODE == 'gaussian_fit':
150 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
150 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
151 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
151 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
152 else:
152 else:
153 ax.plt.set_array(z[n].T.ravel())
153 ax.plt.set_array(z[n].T.ravel())
154 if self.showprofile:
154 if self.showprofile:
155 ax.plt_profile.set_data(data['rti'][n], y)
155 ax.plt_profile.set_data(data['rti'][n], y)
156 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
156 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
157 if self.CODE == 'spc_moments':
157 if self.CODE == 'spc_moments':
158 ax.plt_mean.set_data(mean, y)
158 ax.plt_mean.set_data(mean, y)
159 if self.CODE == 'gaussian_fit':
159 if self.CODE == 'gaussian_fit':
160 ax.plt_gau0.set_data(gau0, y)
160 ax.plt_gau0.set_data(gau0, y)
161 ax.plt_gau1.set_data(gau1, y)
161 ax.plt_gau1.set_data(gau1, y)
162 if len(self.azimuthList) > 0 and len(self.elevationList) > 0:
162 if len(self.azimuthList) > 0 and len(self.elevationList) > 0:
163 self.titles.append('CH {}: {:2.1f}elv {:2.1f}az {:3.2f}dB'.format(self.channelList[n], noise, self.elevationList[n], self.azimuthList[n]))
163 self.titles.append('CH {}: {:2.1f}elv {:2.1f}az {:3.2f}dB'.format(self.channelList[n], noise, self.elevationList[n], self.azimuthList[n]))
164 else:
164 else:
165 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
165 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
166
166
167 class SpectraObliquePlot(Plot):
167 class SpectraObliquePlot(Plot):
168 '''
168 '''
169 Plot for Spectra data
169 Plot for Spectra data
170 '''
170 '''
171
171
172 CODE = 'spc_oblique'
172 CODE = 'spc_oblique'
173 colormap = 'jet'
173 colormap = 'jet'
174 plot_type = 'pcolor'
174 plot_type = 'pcolor'
175
175
176 def setup(self):
176 def setup(self):
177 self.xaxis = "oblique"
177 self.xaxis = "oblique"
178 self.nplots = len(self.data.channels)
178 self.nplots = len(self.data.channels)
179 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
179 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
180 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
180 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
181 self.height = 2.6 * self.nrows
181 self.height = 2.6 * self.nrows
182 self.cb_label = 'dB'
182 self.cb_label = 'dB'
183 if self.showprofile:
183 if self.showprofile:
184 self.width = 4 * self.ncols
184 self.width = 4 * self.ncols
185 else:
185 else:
186 self.width = 3.5 * self.ncols
186 self.width = 3.5 * self.ncols
187 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
187 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
188 self.ylabel = 'Range [km]'
188 self.ylabel = 'Range [km]'
189
189
190 def update(self, dataOut):
190 def update(self, dataOut):
191
191
192 data = {}
192 data = {}
193 meta = {}
193 meta = {}
194
194
195 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
195 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
196 data['spc'] = spc
196 data['spc'] = spc
197 data['rti'] = dataOut.getPower()
197 data['rti'] = dataOut.getPower()
198 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
198 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
199 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
199 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
200
200
201 data['shift1'] = dataOut.Dop_EEJ_T1[0]
201 data['shift1'] = dataOut.Dop_EEJ_T1[0]
202 data['shift2'] = dataOut.Dop_EEJ_T2[0]
202 data['shift2'] = dataOut.Dop_EEJ_T2[0]
203 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
203 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
204 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
204 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
205 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
205 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
206
206
207 return data, meta
207 return data, meta
208
208
209 def plot(self):
209 def plot(self):
210
210
211 if self.xaxis == "frequency":
211 if self.xaxis == "frequency":
212 x = self.data.xrange[0]
212 x = self.data.xrange[0]
213 self.xlabel = "Frequency (kHz)"
213 self.xlabel = "Frequency (kHz)"
214 elif self.xaxis == "time":
214 elif self.xaxis == "time":
215 x = self.data.xrange[1]
215 x = self.data.xrange[1]
216 self.xlabel = "Time (ms)"
216 self.xlabel = "Time (ms)"
217 else:
217 else:
218 x = self.data.xrange[2]
218 x = self.data.xrange[2]
219 self.xlabel = "Velocity (m/s)"
219 self.xlabel = "Velocity (m/s)"
220
220
221 self.titles = []
221 self.titles = []
222
222
223 y = self.data.yrange
223 y = self.data.yrange
224 self.y = y
224 self.y = y
225
225
226 data = self.data[-1]
226 data = self.data[-1]
227 z = data['spc']
227 z = data['spc']
228
228
229 for n, ax in enumerate(self.axes):
229 for n, ax in enumerate(self.axes):
230 noise = self.data['noise'][n][-1]
230 noise = self.data['noise'][n][-1]
231 shift1 = data['shift1']
231 shift1 = data['shift1']
232 shift2 = data['shift2']
232 shift2 = data['shift2']
233 max_val_2 = data['max_val_2']
233 max_val_2 = data['max_val_2']
234 err1 = data['shift1_error']
234 err1 = data['shift1_error']
235 err2 = data['shift2_error']
235 err2 = data['shift2_error']
236 if ax.firsttime:
236 if ax.firsttime:
237
237
238 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
238 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
239 self.xmin = self.xmin if self.xmin else -self.xmax
239 self.xmin = self.xmin if self.xmin else -self.xmax
240 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
240 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
241 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
241 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
242 ax.plt = ax.pcolormesh(x, y, z[n].T,
242 ax.plt = ax.pcolormesh(x, y, z[n].T,
243 vmin=self.zmin,
243 vmin=self.zmin,
244 vmax=self.zmax,
244 vmax=self.zmax,
245 cmap=plt.get_cmap(self.colormap)
245 cmap=plt.get_cmap(self.colormap)
246 )
246 )
247
247
248 if self.showprofile:
248 if self.showprofile:
249 ax.plt_profile = self.pf_axes[n].plot(
249 ax.plt_profile = self.pf_axes[n].plot(
250 self.data['rti'][n][-1], y)[0]
250 self.data['rti'][n][-1], y)[0]
251 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
251 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
252 color="k", linestyle="dashed", lw=1)[0]
252 color="k", linestyle="dashed", lw=1)[0]
253
253
254 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
254 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
255 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
255 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
256 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
256 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
257
257
258 else:
258 else:
259 self.ploterr1.remove()
259 self.ploterr1.remove()
260 self.ploterr2.remove()
260 self.ploterr2.remove()
261 self.ploterr3.remove()
261 self.ploterr3.remove()
262 ax.plt.set_array(z[n].T.ravel())
262 ax.plt.set_array(z[n].T.ravel())
263 if self.showprofile:
263 if self.showprofile:
264 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
264 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
265 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
265 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
266 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
266 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
267 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
267 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
268 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
268 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
269
269
270 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
270 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
271
271
272
272
273 class CrossSpectraPlot(Plot):
273 class CrossSpectraPlot(Plot):
274
274
275 CODE = 'cspc'
275 CODE = 'cspc'
276 colormap = 'jet'
276 colormap = 'jet'
277 plot_type = 'pcolor'
277 plot_type = 'pcolor'
278 zmin_coh = None
278 zmin_coh = None
279 zmax_coh = None
279 zmax_coh = None
280 zmin_phase = None
280 zmin_phase = None
281 zmax_phase = None
281 zmax_phase = None
282 realChannels = None
282 realChannels = None
283 crossPairs = None
283 crossPairs = None
284
284
285 def setup(self):
285 def setup(self):
286
286
287 self.ncols = 4
287 self.ncols = 4
288 self.nplots = len(self.data.pairs) * 2
288 self.nplots = len(self.data.pairs) * 2
289 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
289 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
290 self.width = 3.1 * self.ncols
290 self.width = 3.1 * self.ncols
291 self.height = 2.6 * self.nrows
291 self.height = 2.6 * self.nrows
292 self.ylabel = 'Range [km]'
292 self.ylabel = 'Range [km]'
293 self.showprofile = False
293 self.showprofile = False
294 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
294 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
295
295
296 def update(self, dataOut):
296 def update(self, dataOut):
297
297
298 data = {}
298 data = {}
299 meta = {}
299 meta = {}
300
300
301 spc = dataOut.data_spc
301 spc = dataOut.data_spc
302 cspc = dataOut.data_cspc
302 cspc = dataOut.data_cspc
303 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
303 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
304 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
304 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
305 meta['pairs'] = rawPairs
305 meta['pairs'] = rawPairs
306 if self.crossPairs == None:
306 if self.crossPairs == None:
307 self.crossPairs = dataOut.pairsList
307 self.crossPairs = dataOut.pairsList
308 tmp = []
308 tmp = []
309
309
310 for n, pair in enumerate(meta['pairs']):
310 for n, pair in enumerate(meta['pairs']):
311 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
311 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
312 coh = numpy.abs(out)
312 coh = numpy.abs(out)
313 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
313 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
314 tmp.append(coh)
314 tmp.append(coh)
315 tmp.append(phase)
315 tmp.append(phase)
316
316
317 data['cspc'] = numpy.array(tmp)
317 data['cspc'] = numpy.array(tmp)
318
318
319 return data, meta
319 return data, meta
320
320
321 def plot(self):
321 def plot(self):
322
322
323 if self.xaxis == "frequency":
323 if self.xaxis == "frequency":
324 x = self.data.xrange[0]
324 x = self.data.xrange[0]
325 self.xlabel = "Frequency (kHz)"
325 self.xlabel = "Frequency (kHz)"
326 elif self.xaxis == "time":
326 elif self.xaxis == "time":
327 x = self.data.xrange[1]
327 x = self.data.xrange[1]
328 self.xlabel = "Time (ms)"
328 self.xlabel = "Time (ms)"
329 else:
329 else:
330 x = self.data.xrange[2]
330 x = self.data.xrange[2]
331 self.xlabel = "Velocity (m/s)"
331 self.xlabel = "Velocity (m/s)"
332
332
333 self.titles = []
333 self.titles = []
334
334
335 y = self.data.yrange
335 y = self.data.yrange
336 self.y = y
336 self.y = y
337
337
338 data = self.data[-1]
338 data = self.data[-1]
339 cspc = data['cspc']
339 cspc = data['cspc']
340
340
341 for n in range(len(self.data.pairs)):
341 for n in range(len(self.data.pairs)):
342 pair = self.crossPairs[n]
342 pair = self.crossPairs[n]
343 coh = cspc[n*2]
343 coh = cspc[n*2]
344 phase = cspc[n*2+1]
344 phase = cspc[n*2+1]
345 ax = self.axes[2 * n]
345 ax = self.axes[2 * n]
346 if ax.firsttime:
346 if ax.firsttime:
347 ax.plt = ax.pcolormesh(x, y, coh.T,
347 ax.plt = ax.pcolormesh(x, y, coh.T,
348 vmin=self.zmin_coh,
348 vmin=self.zmin_coh,
349 vmax=self.zmax_coh,
349 vmax=self.zmax_coh,
350 cmap=plt.get_cmap(self.colormap_coh)
350 cmap=plt.get_cmap(self.colormap_coh)
351 )
351 )
352 else:
352 else:
353 ax.plt.set_array(coh.T.ravel())
353 ax.plt.set_array(coh.T.ravel())
354 self.titles.append(
354 self.titles.append(
355 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
355 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
356
356
357 ax = self.axes[2 * n + 1]
357 ax = self.axes[2 * n + 1]
358 if ax.firsttime:
358 if ax.firsttime:
359 ax.plt = ax.pcolormesh(x, y, phase.T,
359 ax.plt = ax.pcolormesh(x, y, phase.T,
360 vmin=-180,
360 vmin=-180,
361 vmax=180,
361 vmax=180,
362 cmap=plt.get_cmap(self.colormap_phase)
362 cmap=plt.get_cmap(self.colormap_phase)
363 )
363 )
364 else:
364 else:
365 ax.plt.set_array(phase.T.ravel())
365 ax.plt.set_array(phase.T.ravel())
366 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
366 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
367
367
368
368
369 class CrossSpectra4Plot(Plot):
369 class CrossSpectra4Plot(Plot):
370
370
371 CODE = 'cspc'
371 CODE = 'cspc'
372 colormap = 'jet'
372 colormap = 'jet'
373 plot_type = 'pcolor'
373 plot_type = 'pcolor'
374 zmin_coh = None
374 zmin_coh = None
375 zmax_coh = None
375 zmax_coh = None
376 zmin_phase = None
376 zmin_phase = None
377 zmax_phase = None
377 zmax_phase = None
378
378
379 def setup(self):
379 def setup(self):
380
380
381 self.ncols = 4
381 self.ncols = 4
382 self.nrows = len(self.data.pairs)
382 self.nrows = len(self.data.pairs)
383 self.nplots = self.nrows * 4
383 self.nplots = self.nrows * 4
384 self.width = 3.1 * self.ncols
384 self.width = 3.1 * self.ncols
385 self.height = 5 * self.nrows
385 self.height = 5 * self.nrows
386 self.ylabel = 'Range [km]'
386 self.ylabel = 'Range [km]'
387 self.showprofile = False
387 self.showprofile = False
388 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
388 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
389
389
390 def plot(self):
390 def plot(self):
391
391
392 if self.xaxis == "frequency":
392 if self.xaxis == "frequency":
393 x = self.data.xrange[0]
393 x = self.data.xrange[0]
394 self.xlabel = "Frequency (kHz)"
394 self.xlabel = "Frequency (kHz)"
395 elif self.xaxis == "time":
395 elif self.xaxis == "time":
396 x = self.data.xrange[1]
396 x = self.data.xrange[1]
397 self.xlabel = "Time (ms)"
397 self.xlabel = "Time (ms)"
398 else:
398 else:
399 x = self.data.xrange[2]
399 x = self.data.xrange[2]
400 self.xlabel = "Velocity (m/s)"
400 self.xlabel = "Velocity (m/s)"
401
401
402 self.titles = []
402 self.titles = []
403
403
404
404
405 y = self.data.heights
405 y = self.data.heights
406 self.y = y
406 self.y = y
407 nspc = self.data['spc']
407 nspc = self.data['spc']
408 spc = self.data['cspc'][0]
408 spc = self.data['cspc'][0]
409 cspc = self.data['cspc'][1]
409 cspc = self.data['cspc'][1]
410
410
411 for n in range(self.nrows):
411 for n in range(self.nrows):
412 noise = self.data['noise'][:,-1]
412 noise = self.data['noise'][:,-1]
413 pair = self.data.pairs[n]
413 pair = self.data.pairs[n]
414
414
415 ax = self.axes[4 * n]
415 ax = self.axes[4 * n]
416 if ax.firsttime:
416 if ax.firsttime:
417 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
417 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
418 self.xmin = self.xmin if self.xmin else -self.xmax
418 self.xmin = self.xmin if self.xmin else -self.xmax
419 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
419 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
420 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
420 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
421 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
421 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
422 vmin=self.zmin,
422 vmin=self.zmin,
423 vmax=self.zmax,
423 vmax=self.zmax,
424 cmap=plt.get_cmap(self.colormap)
424 cmap=plt.get_cmap(self.colormap)
425 )
425 )
426 else:
426 else:
427
427
428 ax.plt.set_array(nspc[pair[0]].T.ravel())
428 ax.plt.set_array(nspc[pair[0]].T.ravel())
429 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
429 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
430
430
431 ax = self.axes[4 * n + 1]
431 ax = self.axes[4 * n + 1]
432
432
433 if ax.firsttime:
433 if ax.firsttime:
434 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
434 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
435 vmin=self.zmin,
435 vmin=self.zmin,
436 vmax=self.zmax,
436 vmax=self.zmax,
437 cmap=plt.get_cmap(self.colormap)
437 cmap=plt.get_cmap(self.colormap)
438 )
438 )
439 else:
439 else:
440
440
441 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
441 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
442 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
442 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
443
443
444 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
444 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
445 coh = numpy.abs(out)
445 coh = numpy.abs(out)
446 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
446 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
447
447
448 ax = self.axes[4 * n + 2]
448 ax = self.axes[4 * n + 2]
449 if ax.firsttime:
449 if ax.firsttime:
450 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
450 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
451 vmin=0,
451 vmin=0,
452 vmax=1,
452 vmax=1,
453 cmap=plt.get_cmap(self.colormap_coh)
453 cmap=plt.get_cmap(self.colormap_coh)
454 )
454 )
455 else:
455 else:
456 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
456 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
457 self.titles.append(
457 self.titles.append(
458 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
458 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
459
459
460 ax = self.axes[4 * n + 3]
460 ax = self.axes[4 * n + 3]
461 if ax.firsttime:
461 if ax.firsttime:
462 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
462 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
463 vmin=-180,
463 vmin=-180,
464 vmax=180,
464 vmax=180,
465 cmap=plt.get_cmap(self.colormap_phase)
465 cmap=plt.get_cmap(self.colormap_phase)
466 )
466 )
467 else:
467 else:
468 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
468 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
469 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
469 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
470
470
471
471
472 class CrossSpectra2Plot(Plot):
472 class CrossSpectra2Plot(Plot):
473
473
474 CODE = 'cspc'
474 CODE = 'cspc'
475 colormap = 'jet'
475 colormap = 'jet'
476 plot_type = 'pcolor'
476 plot_type = 'pcolor'
477 zmin_coh = None
477 zmin_coh = None
478 zmax_coh = None
478 zmax_coh = None
479 zmin_phase = None
479 zmin_phase = None
480 zmax_phase = None
480 zmax_phase = None
481
481
482 def setup(self):
482 def setup(self):
483
483
484 self.ncols = 1
484 self.ncols = 1
485 self.nrows = len(self.data.pairs)
485 self.nrows = len(self.data.pairs)
486 self.nplots = self.nrows * 1
486 self.nplots = self.nrows * 1
487 self.width = 3.1 * self.ncols
487 self.width = 3.1 * self.ncols
488 self.height = 5 * self.nrows
488 self.height = 5 * self.nrows
489 self.ylabel = 'Range [km]'
489 self.ylabel = 'Range [km]'
490 self.showprofile = False
490 self.showprofile = False
491 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
491 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
492
492
493 def plot(self):
493 def plot(self):
494
494
495 if self.xaxis == "frequency":
495 if self.xaxis == "frequency":
496 x = self.data.xrange[0]
496 x = self.data.xrange[0]
497 self.xlabel = "Frequency (kHz)"
497 self.xlabel = "Frequency (kHz)"
498 elif self.xaxis == "time":
498 elif self.xaxis == "time":
499 x = self.data.xrange[1]
499 x = self.data.xrange[1]
500 self.xlabel = "Time (ms)"
500 self.xlabel = "Time (ms)"
501 else:
501 else:
502 x = self.data.xrange[2]
502 x = self.data.xrange[2]
503 self.xlabel = "Velocity (m/s)"
503 self.xlabel = "Velocity (m/s)"
504
504
505 self.titles = []
505 self.titles = []
506
506
507
507
508 y = self.data.heights
508 y = self.data.heights
509 self.y = y
509 self.y = y
510 cspc = self.data['cspc'][1]
510 cspc = self.data['cspc'][1]
511
511
512 for n in range(self.nrows):
512 for n in range(self.nrows):
513 noise = self.data['noise'][:,-1]
513 noise = self.data['noise'][:,-1]
514 pair = self.data.pairs[n]
514 pair = self.data.pairs[n]
515 out = cspc[n]
515 out = cspc[n]
516 cross = numpy.abs(out)
516 cross = numpy.abs(out)
517 z = cross/self.data.nFactor
517 z = cross/self.data.nFactor
518 cross = 10*numpy.log10(z)
518 cross = 10*numpy.log10(z)
519
519
520 ax = self.axes[1 * n]
520 ax = self.axes[1 * n]
521 if ax.firsttime:
521 if ax.firsttime:
522 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
522 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
523 self.xmin = self.xmin if self.xmin else -self.xmax
523 self.xmin = self.xmin if self.xmin else -self.xmax
524 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
524 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
525 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
525 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
526 ax.plt = ax.pcolormesh(x, y, cross.T,
526 ax.plt = ax.pcolormesh(x, y, cross.T,
527 vmin=self.zmin,
527 vmin=self.zmin,
528 vmax=self.zmax,
528 vmax=self.zmax,
529 cmap=plt.get_cmap(self.colormap)
529 cmap=plt.get_cmap(self.colormap)
530 )
530 )
531 else:
531 else:
532 ax.plt.set_array(cross.T.ravel())
532 ax.plt.set_array(cross.T.ravel())
533 self.titles.append(
533 self.titles.append(
534 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
534 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
535
535
536
536
537 class CrossSpectra3Plot(Plot):
537 class CrossSpectra3Plot(Plot):
538
538
539 CODE = 'cspc'
539 CODE = 'cspc'
540 colormap = 'jet'
540 colormap = 'jet'
541 plot_type = 'pcolor'
541 plot_type = 'pcolor'
542 zmin_coh = None
542 zmin_coh = None
543 zmax_coh = None
543 zmax_coh = None
544 zmin_phase = None
544 zmin_phase = None
545 zmax_phase = None
545 zmax_phase = None
546
546
547 def setup(self):
547 def setup(self):
548
548
549 self.ncols = 3
549 self.ncols = 3
550 self.nrows = len(self.data.pairs)
550 self.nrows = len(self.data.pairs)
551 self.nplots = self.nrows * 3
551 self.nplots = self.nrows * 3
552 self.width = 3.1 * self.ncols
552 self.width = 3.1 * self.ncols
553 self.height = 5 * self.nrows
553 self.height = 5 * self.nrows
554 self.ylabel = 'Range [km]'
554 self.ylabel = 'Range [km]'
555 self.showprofile = False
555 self.showprofile = False
556 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
556 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
557
557
558 def plot(self):
558 def plot(self):
559
559
560 if self.xaxis == "frequency":
560 if self.xaxis == "frequency":
561 x = self.data.xrange[0]
561 x = self.data.xrange[0]
562 self.xlabel = "Frequency (kHz)"
562 self.xlabel = "Frequency (kHz)"
563 elif self.xaxis == "time":
563 elif self.xaxis == "time":
564 x = self.data.xrange[1]
564 x = self.data.xrange[1]
565 self.xlabel = "Time (ms)"
565 self.xlabel = "Time (ms)"
566 else:
566 else:
567 x = self.data.xrange[2]
567 x = self.data.xrange[2]
568 self.xlabel = "Velocity (m/s)"
568 self.xlabel = "Velocity (m/s)"
569
569
570 self.titles = []
570 self.titles = []
571
571
572
572
573 y = self.data.heights
573 y = self.data.heights
574 self.y = y
574 self.y = y
575
575
576 cspc = self.data['cspc'][1]
576 cspc = self.data['cspc'][1]
577
577
578 for n in range(self.nrows):
578 for n in range(self.nrows):
579 noise = self.data['noise'][:,-1]
579 noise = self.data['noise'][:,-1]
580 pair = self.data.pairs[n]
580 pair = self.data.pairs[n]
581 out = cspc[n]
581 out = cspc[n]
582
582
583 cross = numpy.abs(out)
583 cross = numpy.abs(out)
584 z = cross/self.data.nFactor
584 z = cross/self.data.nFactor
585 cross = 10*numpy.log10(z)
585 cross = 10*numpy.log10(z)
586
586
587 out_r= out.real/self.data.nFactor
587 out_r= out.real/self.data.nFactor
588
588
589 out_i= out.imag/self.data.nFactor
589 out_i= out.imag/self.data.nFactor
590
590
591 ax = self.axes[3 * n]
591 ax = self.axes[3 * n]
592 if ax.firsttime:
592 if ax.firsttime:
593 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
593 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
594 self.xmin = self.xmin if self.xmin else -self.xmax
594 self.xmin = self.xmin if self.xmin else -self.xmax
595 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
595 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
596 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
596 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
597 ax.plt = ax.pcolormesh(x, y, cross.T,
597 ax.plt = ax.pcolormesh(x, y, cross.T,
598 vmin=self.zmin,
598 vmin=self.zmin,
599 vmax=self.zmax,
599 vmax=self.zmax,
600 cmap=plt.get_cmap(self.colormap)
600 cmap=plt.get_cmap(self.colormap)
601 )
601 )
602 else:
602 else:
603 ax.plt.set_array(cross.T.ravel())
603 ax.plt.set_array(cross.T.ravel())
604 self.titles.append(
604 self.titles.append(
605 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
605 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
606
606
607 ax = self.axes[3 * n + 1]
607 ax = self.axes[3 * n + 1]
608 if ax.firsttime:
608 if ax.firsttime:
609 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
609 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
610 self.xmin = self.xmin if self.xmin else -self.xmax
610 self.xmin = self.xmin if self.xmin else -self.xmax
611 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
611 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
612 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
612 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
613 ax.plt = ax.pcolormesh(x, y, out_r.T,
613 ax.plt = ax.pcolormesh(x, y, out_r.T,
614 vmin=-1.e6,
614 vmin=-1.e6,
615 vmax=0,
615 vmax=0,
616 cmap=plt.get_cmap(self.colormap)
616 cmap=plt.get_cmap(self.colormap)
617 )
617 )
618 else:
618 else:
619 ax.plt.set_array(out_r.T.ravel())
619 ax.plt.set_array(out_r.T.ravel())
620 self.titles.append(
620 self.titles.append(
621 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
621 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
622
622
623 ax = self.axes[3 * n + 2]
623 ax = self.axes[3 * n + 2]
624
624
625
625
626 if ax.firsttime:
626 if ax.firsttime:
627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
628 self.xmin = self.xmin if self.xmin else -self.xmax
628 self.xmin = self.xmin if self.xmin else -self.xmax
629 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
629 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
631 ax.plt = ax.pcolormesh(x, y, out_i.T,
631 ax.plt = ax.pcolormesh(x, y, out_i.T,
632 vmin=-1.e6,
632 vmin=-1.e6,
633 vmax=1.e6,
633 vmax=1.e6,
634 cmap=plt.get_cmap(self.colormap)
634 cmap=plt.get_cmap(self.colormap)
635 )
635 )
636 else:
636 else:
637 ax.plt.set_array(out_i.T.ravel())
637 ax.plt.set_array(out_i.T.ravel())
638 self.titles.append(
638 self.titles.append(
639 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
639 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
640
640
641 class RTIPlot(Plot):
641 class RTIPlot(Plot):
642 '''
642 '''
643 Plot for RTI data
643 Plot for RTI data
644 '''
644 '''
645
645
646 CODE = 'rti'
646 CODE = 'rti'
647 colormap = 'jet'
647 colormap = 'jet'
648 plot_type = 'pcolorbuffer'
648 plot_type = 'pcolorbuffer'
649 titles = None
649 titles = None
650 channelList = []
650 channelList = []
651 elevationList = []
651 elevationList = []
652 azimuthList = []
652 azimuthList = []
653
653
654 def setup(self):
654 def setup(self):
655 self.xaxis = 'time'
655 self.xaxis = 'time'
656 self.ncols = 1
656 self.ncols = 1
657 self.nrows = len(self.data.channels)
657 self.nrows = len(self.data.channels)
658 self.nplots = len(self.data.channels)
658 self.nplots = len(self.data.channels)
659 self.ylabel = 'Range [km]'
659 self.ylabel = 'Range [km]'
660 #self.xlabel = 'Time'
660 #self.xlabel = 'Time'
661 self.cb_label = 'dB'
661 self.cb_label = 'dB'
662 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
662 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
663 self.titles = ['{} Channel {}'.format(
663 self.titles = ['{} Channel {}'.format(
664 self.CODE.upper(), x) for x in range(self.nplots)]
664 self.CODE.upper(), x) for x in range(self.nplots)]
665
665
666 def update_list(self,dataOut):
666 def update_list(self,dataOut):
667
667
668 if len(self.channelList) == 0:
668 if len(self.channelList) == 0:
669 self.channelList = dataOut.channelList
669 self.channelList = dataOut.channelList
670 if len(self.elevationList) == 0:
670 if len(self.elevationList) == 0:
671 self.elevationList = dataOut.elevationList
671 self.elevationList = dataOut.elevationList
672 if len(self.azimuthList) == 0:
672 if len(self.azimuthList) == 0:
673 self.azimuthList = dataOut.azimuthList
673 self.azimuthList = dataOut.azimuthList
674
674
675
675
676 def update(self, dataOut):
676 def update(self, dataOut):
677
677
678 if len(self.channelList) == 0:
678 if len(self.channelList) == 0:
679 self.update_list(dataOut)
679 self.update_list(dataOut)
680 data = {}
680 data = {}
681 meta = {}
681 meta = {}
682 data['rti'] = dataOut.getPower()
682 data['rti'] = dataOut.getPower()
683 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
683 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
684 noise = 10*numpy.log10(dataOut.getNoise()/norm)
684 noise = 10*numpy.log10(dataOut.getNoise()/norm)
685 data['noise'] = noise
685 data['noise'] = noise
686
686
687 return data, meta
687 return data, meta
688
688
689 def plot(self):
689 def plot(self):
690
690
691 self.x = self.data.times
691 self.x = self.data.times
692 self.y = self.data.yrange
692 self.y = self.data.yrange
693 self.z = self.data[self.CODE]
693 self.z = self.data[self.CODE]
694 self.z = numpy.array(self.z, dtype=float)
694 self.z = numpy.array(self.z, dtype=float)
695 self.z = numpy.ma.masked_invalid(self.z)
695 self.z = numpy.ma.masked_invalid(self.z)
696
696
697 try:
697 try:
698 if self.channelList != None:
698 if self.channelList != None:
699 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
699 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
700 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
700 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
701 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
701 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
702 else:
702 else:
703 self.titles = ['{} Channel {}'.format(
703 self.titles = ['{} Channel {}'.format(
704 self.CODE.upper(), x) for x in self.channelList]
704 self.CODE.upper(), x) for x in self.channelList]
705 except:
705 except:
706 if self.channelList.any() != None:
706 if self.channelList.any() != None:
707 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
707 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
708 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
708 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
709 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
709 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
710 else:
710 else:
711 self.titles = ['{} Channel {}'.format(
711 self.titles = ['{} Channel {}'.format(
712 self.CODE.upper(), x) for x in self.channelList]
712 self.CODE.upper(), x) for x in self.channelList]
713
713
714 if self.decimation is None:
714 if self.decimation is None:
715 x, y, z = self.fill_gaps(self.x, self.y, self.z)
715 x, y, z = self.fill_gaps(self.x, self.y, self.z)
716 else:
716 else:
717 x, y, z = self.fill_gaps(*self.decimate())
717 x, y, z = self.fill_gaps(*self.decimate())
718
718
719 for n, ax in enumerate(self.axes):
719 for n, ax in enumerate(self.axes):
720
720
721 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
721 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
722 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
722 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
723 data = self.data[-1]
723 data = self.data[-1]
724 if ax.firsttime:
724 if ax.firsttime:
725 ax.plt = ax.pcolormesh(x, y, z[n].T,
725 ax.plt = ax.pcolormesh(x, y, z[n].T,
726 vmin=self.zmin,
726 vmin=self.zmin,
727 vmax=self.zmax,
727 vmax=self.zmax,
728 cmap=plt.get_cmap(self.colormap)
728 cmap=plt.get_cmap(self.colormap)
729 )
729 )
730 if self.showprofile:
730 if self.showprofile:
731 ax.plot_profile = self.pf_axes[n].plot(
731 ax.plot_profile = self.pf_axes[n].plot(
732 data[self.CODE][n], self.y)[0]
732 data[self.CODE][n], self.y)[0]
733 if "noise" in self.data:
733 if "noise" in self.data:
734 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
734 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
735 color="k", linestyle="dashed", lw=1)[0]
735 color="k", linestyle="dashed", lw=1)[0]
736 else:
736 else:
737 # ax.collections.remove(ax.collections[0]) # error while running
737 ax.collections.remove(ax.collections[0]) # error while running in 3.12
738 ax.plt = ax.pcolormesh(x, y, z[n].T,
738 ax.plt = ax.pcolormesh(x, y, z[n].T,
739 vmin=self.zmin,
739 vmin=self.zmin,
740 vmax=self.zmax,
740 vmax=self.zmax,
741 cmap=plt.get_cmap(self.colormap)
741 cmap=plt.get_cmap(self.colormap)
742 )
742 )
743 if self.showprofile:
743 if self.showprofile:
744 ax.plot_profile.set_data(data[self.CODE][n], self.y)
744 ax.plot_profile.set_data(data[self.CODE][n], self.y)
745 if "noise" in self.data:
745 if "noise" in self.data:
746 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
746 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
747 color="k", linestyle="dashed", lw=1)[0]
747 color="k", linestyle="dashed", lw=1)[0]
748
748
749 class SpectrogramPlot(Plot):
749 class SpectrogramPlot(Plot):
750 '''
750 '''
751 Plot for Spectrogram data
751 Plot for Spectrogram data
752 '''
752 '''
753
753
754 CODE = 'Spectrogram_Profile'
754 CODE = 'Spectrogram_Profile'
755 colormap = 'binary'
755 colormap = 'binary'
756 plot_type = 'pcolorbuffer'
756 plot_type = 'pcolorbuffer'
757
757
758 def setup(self):
758 def setup(self):
759 self.xaxis = 'time'
759 self.xaxis = 'time'
760 self.ncols = 1
760 self.ncols = 1
761 self.nrows = len(self.data.channels)
761 self.nrows = len(self.data.channels)
762 self.nplots = len(self.data.channels)
762 self.nplots = len(self.data.channels)
763 self.xlabel = 'Time'
763 self.xlabel = 'Time'
764 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
764 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
765 self.titles = []
765 self.titles = []
766
766
767 self.titles = ['{} Channel {}'.format(
767 self.titles = ['{} Channel {}'.format(
768 self.CODE.upper(), x) for x in range(self.nrows)]
768 self.CODE.upper(), x) for x in range(self.nrows)]
769
769
770
770
771 def update(self, dataOut):
771 def update(self, dataOut):
772 data = {}
772 data = {}
773 meta = {}
773 meta = {}
774
774
775 maxHei = 1620#+12000
775 maxHei = 1620#+12000
776 indb = numpy.where(dataOut.heightList <= maxHei)
776 indb = numpy.where(dataOut.heightList <= maxHei)
777 hei = indb[0][-1]
777 hei = indb[0][-1]
778
778
779 factor = dataOut.nIncohInt
779 factor = dataOut.nIncohInt
780 z = dataOut.data_spc[:,:,hei] / factor
780 z = dataOut.data_spc[:,:,hei] / factor
781 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
781 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
782
782
783 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
783 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
784 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
784 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
785
785
786 data['hei'] = hei
786 data['hei'] = hei
787 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
787 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
788 data['nProfiles'] = dataOut.nProfiles
788 data['nProfiles'] = dataOut.nProfiles
789
789
790 return data, meta
790 return data, meta
791
791
792 def plot(self):
792 def plot(self):
793
793
794 self.x = self.data.times
794 self.x = self.data.times
795 self.z = self.data[self.CODE]
795 self.z = self.data[self.CODE]
796 self.y = self.data.xrange[0]
796 self.y = self.data.xrange[0]
797
797
798 hei = self.data['hei'][-1]
798 hei = self.data['hei'][-1]
799 DH = self.data['DH'][-1]
799 DH = self.data['DH'][-1]
800 nProfiles = self.data['nProfiles'][-1]
800 nProfiles = self.data['nProfiles'][-1]
801
801
802 self.ylabel = "Frequency (kHz)"
802 self.ylabel = "Frequency (kHz)"
803
803
804 self.z = numpy.ma.masked_invalid(self.z)
804 self.z = numpy.ma.masked_invalid(self.z)
805
805
806 if self.decimation is None:
806 if self.decimation is None:
807 x, y, z = self.fill_gaps(self.x, self.y, self.z)
807 x, y, z = self.fill_gaps(self.x, self.y, self.z)
808 else:
808 else:
809 x, y, z = self.fill_gaps(*self.decimate())
809 x, y, z = self.fill_gaps(*self.decimate())
810
810
811 for n, ax in enumerate(self.axes):
811 for n, ax in enumerate(self.axes):
812 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
812 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
813 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
813 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
814 data = self.data[-1]
814 data = self.data[-1]
815 if ax.firsttime:
815 if ax.firsttime:
816 ax.plt = ax.pcolormesh(x, y, z[n].T,
816 ax.plt = ax.pcolormesh(x, y, z[n].T,
817 vmin=self.zmin,
817 vmin=self.zmin,
818 vmax=self.zmax,
818 vmax=self.zmax,
819 cmap=plt.get_cmap(self.colormap)
819 cmap=plt.get_cmap(self.colormap)
820 )
820 )
821 else:
821 else:
822 # ax.collections.remove(ax.collections[0]) # error while running
822 # ax.collections.remove(ax.collections[0]) # error while running
823 ax.plt = ax.pcolormesh(x, y, z[n].T,
823 ax.plt = ax.pcolormesh(x, y, z[n].T,
824 vmin=self.zmin,
824 vmin=self.zmin,
825 vmax=self.zmax,
825 vmax=self.zmax,
826 cmap=plt.get_cmap(self.colormap)
826 cmap=plt.get_cmap(self.colormap)
827 )
827 )
828
828
829
829
830
830
831 class CoherencePlot(RTIPlot):
831 class CoherencePlot(RTIPlot):
832 '''
832 '''
833 Plot for Coherence data
833 Plot for Coherence data
834 '''
834 '''
835
835
836 CODE = 'coh'
836 CODE = 'coh'
837 titles = None
837 titles = None
838
838
839 def setup(self):
839 def setup(self):
840 self.xaxis = 'time'
840 self.xaxis = 'time'
841 self.ncols = 1
841 self.ncols = 1
842 self.nrows = len(self.data.pairs)
842 self.nrows = len(self.data.pairs)
843 self.nplots = len(self.data.pairs)
843 self.nplots = len(self.data.pairs)
844 self.ylabel = 'Range [km]'
844 self.ylabel = 'Range [km]'
845 self.xlabel = 'Time'
845 self.xlabel = 'Time'
846 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
846 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
847 if self.CODE == 'coh':
847 if self.CODE == 'coh':
848 self.cb_label = ''
848 self.cb_label = ''
849 self.titles = [
849 self.titles = [
850 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
850 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
851 else:
851 else:
852 self.cb_label = 'Degrees'
852 self.cb_label = 'Degrees'
853 self.titles = [
853 self.titles = [
854 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
854 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
855
855
856 def update(self, dataOut):
856 def update(self, dataOut):
857
857
858 data = {}
858 data = {}
859 meta = {}
859 meta = {}
860 data['coh'] = dataOut.getCoherence()
860 data['coh'] = dataOut.getCoherence()
861 meta['pairs'] = dataOut.pairsList
861 meta['pairs'] = dataOut.pairsList
862
862
863 return data, meta
863 return data, meta
864
864
865 class PhasePlot(CoherencePlot):
865 class PhasePlot(CoherencePlot):
866 '''
866 '''
867 Plot for Phase map data
867 Plot for Phase map data
868 '''
868 '''
869
869
870 CODE = 'phase'
870 CODE = 'phase'
871 colormap = 'seismic'
871 colormap = 'seismic'
872
872
873 def update(self, dataOut):
873 def update(self, dataOut):
874
874
875 data = {}
875 data = {}
876 meta = {}
876 meta = {}
877 data['phase'] = dataOut.getCoherence(phase=True)
877 data['phase'] = dataOut.getCoherence(phase=True)
878 meta['pairs'] = dataOut.pairsList
878 meta['pairs'] = dataOut.pairsList
879
879
880 return data, meta
880 return data, meta
881
881
882 class NoisePlot(Plot):
882 class NoisePlot(Plot):
883 '''
883 '''
884 Plot for noise
884 Plot for noise
885 '''
885 '''
886
886
887 CODE = 'noise'
887 CODE = 'noise'
888 plot_type = 'scatterbuffer'
888 plot_type = 'scatterbuffer'
889
889
890 def setup(self):
890 def setup(self):
891 self.xaxis = 'time'
891 self.xaxis = 'time'
892 self.ncols = 1
892 self.ncols = 1
893 self.nrows = 1
893 self.nrows = 1
894 self.nplots = 1
894 self.nplots = 1
895 self.ylabel = 'Intensity [dB]'
895 self.ylabel = 'Intensity [dB]'
896 self.xlabel = 'Time'
896 self.xlabel = 'Time'
897 self.titles = ['Noise']
897 self.titles = ['Noise']
898 self.colorbar = False
898 self.colorbar = False
899 self.plots_adjust.update({'right': 0.85 })
899 self.plots_adjust.update({'right': 0.85 })
900 self.titles = ['Noise Plot']
900 self.titles = ['Noise Plot']
901
901
902 def update(self, dataOut):
902 def update(self, dataOut):
903
903
904 data = {}
904 data = {}
905 meta = {}
905 meta = {}
906 noise = 10*numpy.log10(dataOut.getNoise())
906 noise = 10*numpy.log10(dataOut.getNoise())
907 noise = noise.reshape(dataOut.nChannels, 1)
907 noise = noise.reshape(dataOut.nChannels, 1)
908 data['noise'] = noise
908 data['noise'] = noise
909 meta['yrange'] = numpy.array([])
909 meta['yrange'] = numpy.array([])
910
910
911 return data, meta
911 return data, meta
912
912
913 def plot(self):
913 def plot(self):
914
914
915 x = self.data.times
915 x = self.data.times
916 xmin = self.data.min_time
916 xmin = self.data.min_time
917 xmax = xmin + self.xrange * 60 * 60
917 xmax = xmin + self.xrange * 60 * 60
918 Y = self.data['noise']
918 Y = self.data['noise']
919
919
920 if self.axes[0].firsttime:
920 if self.axes[0].firsttime:
921 self.ymin = numpy.nanmin(Y) - 5
921 self.ymin = numpy.nanmin(Y) - 5
922 self.ymax = numpy.nanmax(Y) + 5
922 self.ymax = numpy.nanmax(Y) + 5
923 for ch in self.data.channels:
923 for ch in self.data.channels:
924 y = Y[ch]
924 y = Y[ch]
925 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
925 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
926 plt.legend(bbox_to_anchor=(1.18, 1.0))
926 plt.legend(bbox_to_anchor=(1.18, 1.0))
927 else:
927 else:
928 for ch in self.data.channels:
928 for ch in self.data.channels:
929 y = Y[ch]
929 y = Y[ch]
930 self.axes[0].lines[ch].set_data(x, y)
930 self.axes[0].lines[ch].set_data(x, y)
931
931
932 class PowerProfilePlot(Plot):
932 class PowerProfilePlot(Plot):
933
933
934 CODE = 'pow_profile'
934 CODE = 'pow_profile'
935 plot_type = 'scatter'
935 plot_type = 'scatter'
936
936
937 def setup(self):
937 def setup(self):
938
938
939 self.ncols = 1
939 self.ncols = 1
940 self.nrows = 1
940 self.nrows = 1
941 self.nplots = 1
941 self.nplots = 1
942 self.height = 4
942 self.height = 4
943 self.width = 3
943 self.width = 3
944 self.ylabel = 'Range [km]'
944 self.ylabel = 'Range [km]'
945 self.xlabel = 'Intensity [dB]'
945 self.xlabel = 'Intensity [dB]'
946 self.titles = ['Power Profile']
946 self.titles = ['Power Profile']
947 self.colorbar = False
947 self.colorbar = False
948
948
949 def update(self, dataOut):
949 def update(self, dataOut):
950
950
951 data = {}
951 data = {}
952 meta = {}
952 meta = {}
953 data[self.CODE] = dataOut.getPower()
953 data[self.CODE] = dataOut.getPower()
954
954
955 return data, meta
955 return data, meta
956
956
957 def plot(self):
957 def plot(self):
958
958
959 y = self.data.yrange
959 y = self.data.yrange
960 self.y = y
960 self.y = y
961
961
962 x = self.data[-1][self.CODE]
962 x = self.data[-1][self.CODE]
963
963
964 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
964 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
965 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
965 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
966
966
967 if self.axes[0].firsttime:
967 if self.axes[0].firsttime:
968 for ch in self.data.channels:
968 for ch in self.data.channels:
969 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
969 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
970 plt.legend()
970 plt.legend()
971 else:
971 else:
972 for ch in self.data.channels:
972 for ch in self.data.channels:
973 self.axes[0].lines[ch].set_data(x[ch], y)
973 self.axes[0].lines[ch].set_data(x[ch], y)
974
974
975
975
976 class SpectraCutPlot(Plot):
976 class SpectraCutPlot(Plot):
977
977
978 CODE = 'spc_cut'
978 CODE = 'spc_cut'
979 plot_type = 'scatter'
979 plot_type = 'scatter'
980 buffering = False
980 buffering = False
981 heights = []
981 heights = []
982 channelList = []
982 channelList = []
983 maintitle = "Spectra Cuts"
983 maintitle = "Spectra Cuts"
984 flag_setIndex = False
984 flag_setIndex = False
985
985
986 def setup(self):
986 def setup(self):
987
987
988 self.nplots = len(self.data.channels)
988 self.nplots = len(self.data.channels)
989 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
989 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
990 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
990 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
991 self.width = 4.5 * self.ncols + 2.5
991 self.width = 4.5 * self.ncols + 2.5
992 self.height = 4.8 * self.nrows
992 self.height = 4.8 * self.nrows
993 self.ylabel = 'Power [dB]'
993 self.ylabel = 'Power [dB]'
994 self.colorbar = False
994 self.colorbar = False
995 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.9, 'bottom':0.08})
995 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.9, 'bottom':0.08})
996
996
997 if len(self.selectedHeightsList) > 0:
997 if len(self.selectedHeightsList) > 0:
998 self.maintitle = "Spectra Cut"# for %d km " %(int(self.selectedHeight))
998 self.maintitle = "Spectra Cut"# for %d km " %(int(self.selectedHeight))
999
999
1000
1000
1001
1001
1002 def update(self, dataOut):
1002 def update(self, dataOut):
1003 if len(self.channelList) == 0:
1003 if len(self.channelList) == 0:
1004 self.channelList = dataOut.channelList
1004 self.channelList = dataOut.channelList
1005
1005
1006 self.heights = dataOut.heightList
1006 self.heights = dataOut.heightList
1007 #print("sels: ",self.selectedHeightsList)
1007 #print("sels: ",self.selectedHeightsList)
1008 if len(self.selectedHeightsList)>0 and not self.flag_setIndex:
1008 if len(self.selectedHeightsList)>0 and not self.flag_setIndex:
1009
1009
1010 for sel_height in self.selectedHeightsList:
1010 for sel_height in self.selectedHeightsList:
1011 index_list = numpy.where(self.heights >= sel_height)
1011 index_list = numpy.where(self.heights >= sel_height)
1012 index_list = index_list[0]
1012 index_list = index_list[0]
1013 self.height_index.append(index_list[0])
1013 self.height_index.append(index_list[0])
1014 #print("sels i:"", self.height_index)
1014 #print("sels i:"", self.height_index)
1015 self.flag_setIndex = True
1015 self.flag_setIndex = True
1016 #print(self.height_index)
1016 #print(self.height_index)
1017 data = {}
1017 data = {}
1018 meta = {}
1018 meta = {}
1019
1019
1020 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter#*dataOut.nFFTPoints
1020 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter#*dataOut.nFFTPoints
1021 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1021 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1022 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1022 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1023
1023
1024
1024
1025 z = []
1025 z = []
1026 for ch in range(dataOut.nChannels):
1026 for ch in range(dataOut.nChannels):
1027 if hasattr(dataOut.normFactor,'shape'):
1027 if hasattr(dataOut.normFactor,'shape'):
1028 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1028 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1029 else:
1029 else:
1030 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1030 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1031
1031
1032 z = numpy.asarray(z)
1032 z = numpy.asarray(z)
1033 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1033 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1034 spc = 10*numpy.log10(z)
1034 spc = 10*numpy.log10(z)
1035
1035
1036
1036
1037 data['spc'] = spc - noise
1037 data['spc'] = spc - noise
1038 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1038 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1039
1039
1040 return data, meta
1040 return data, meta
1041
1041
1042 def plot(self):
1042 def plot(self):
1043 if self.xaxis == "frequency":
1043 if self.xaxis == "frequency":
1044 x = self.data.xrange[0][0:]
1044 x = self.data.xrange[0][0:]
1045 self.xlabel = "Frequency (kHz)"
1045 self.xlabel = "Frequency (kHz)"
1046 elif self.xaxis == "time":
1046 elif self.xaxis == "time":
1047 x = self.data.xrange[1]
1047 x = self.data.xrange[1]
1048 self.xlabel = "Time (ms)"
1048 self.xlabel = "Time (ms)"
1049 else:
1049 else:
1050 x = self.data.xrange[2]
1050 x = self.data.xrange[2]
1051 self.xlabel = "Velocity (m/s)"
1051 self.xlabel = "Velocity (m/s)"
1052
1052
1053 self.titles = []
1053 self.titles = []
1054
1054
1055 y = self.data.yrange
1055 y = self.data.yrange
1056 z = self.data[-1]['spc']
1056 z = self.data[-1]['spc']
1057 #print(z.shape)
1057 #print(z.shape)
1058 if len(self.height_index) > 0:
1058 if len(self.height_index) > 0:
1059 index = self.height_index
1059 index = self.height_index
1060 else:
1060 else:
1061 index = numpy.arange(0, len(y), int((len(y))/9))
1061 index = numpy.arange(0, len(y), int((len(y))/9))
1062 #print("inde x ", index, self.axes)
1062 #print("inde x ", index, self.axes)
1063
1063
1064 for n, ax in enumerate(self.axes):
1064 for n, ax in enumerate(self.axes):
1065
1065
1066 if ax.firsttime:
1066 if ax.firsttime:
1067
1067
1068
1068
1069 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1069 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1070 self.xmin = self.xmin if self.xmin else -self.xmax
1070 self.xmin = self.xmin if self.xmin else -self.xmax
1071 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
1071 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
1072 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
1072 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
1073
1073
1074
1074
1075 ax.plt = ax.plot(x, z[n, :, index].T)
1075 ax.plt = ax.plot(x, z[n, :, index].T)
1076 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1076 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1077 self.figures[0].legend(ax.plt, labels, loc='center right', prop={'size': 8})
1077 self.figures[0].legend(ax.plt, labels, loc='center right', prop={'size': 8})
1078 ax.minorticks_on()
1078 ax.minorticks_on()
1079 ax.grid(which='major', axis='both')
1079 ax.grid(which='major', axis='both')
1080 ax.grid(which='minor', axis='x')
1080 ax.grid(which='minor', axis='x')
1081 else:
1081 else:
1082 for i, line in enumerate(ax.plt):
1082 for i, line in enumerate(ax.plt):
1083 line.set_data(x, z[n, :, index[i]])
1083 line.set_data(x, z[n, :, index[i]])
1084
1084
1085
1085
1086 self.titles.append('CH {}'.format(self.channelList[n]))
1086 self.titles.append('CH {}'.format(self.channelList[n]))
1087 plt.suptitle(self.maintitle, fontsize=10)
1087 plt.suptitle(self.maintitle, fontsize=10)
1088
1088
1089
1089
1090 class BeaconPhase(Plot):
1090 class BeaconPhase(Plot):
1091
1091
1092 __isConfig = None
1092 __isConfig = None
1093 __nsubplots = None
1093 __nsubplots = None
1094
1094
1095 PREFIX = 'beacon_phase'
1095 PREFIX = 'beacon_phase'
1096
1096
1097 def __init__(self):
1097 def __init__(self):
1098 Plot.__init__(self)
1098 Plot.__init__(self)
1099 self.timerange = 24*60*60
1099 self.timerange = 24*60*60
1100 self.isConfig = False
1100 self.isConfig = False
1101 self.__nsubplots = 1
1101 self.__nsubplots = 1
1102 self.counter_imagwr = 0
1102 self.counter_imagwr = 0
1103 self.WIDTH = 800
1103 self.WIDTH = 800
1104 self.HEIGHT = 400
1104 self.HEIGHT = 400
1105 self.WIDTHPROF = 120
1105 self.WIDTHPROF = 120
1106 self.HEIGHTPROF = 0
1106 self.HEIGHTPROF = 0
1107 self.xdata = None
1107 self.xdata = None
1108 self.ydata = None
1108 self.ydata = None
1109
1109
1110 self.PLOT_CODE = BEACON_CODE
1110 self.PLOT_CODE = BEACON_CODE
1111
1111
1112 self.FTP_WEI = None
1112 self.FTP_WEI = None
1113 self.EXP_CODE = None
1113 self.EXP_CODE = None
1114 self.SUB_EXP_CODE = None
1114 self.SUB_EXP_CODE = None
1115 self.PLOT_POS = None
1115 self.PLOT_POS = None
1116
1116
1117 self.filename_phase = None
1117 self.filename_phase = None
1118
1118
1119 self.figfile = None
1119 self.figfile = None
1120
1120
1121 self.xmin = None
1121 self.xmin = None
1122 self.xmax = None
1122 self.xmax = None
1123
1123
1124 def getSubplots(self):
1124 def getSubplots(self):
1125
1125
1126 ncol = 1
1126 ncol = 1
1127 nrow = 1
1127 nrow = 1
1128
1128
1129 return nrow, ncol
1129 return nrow, ncol
1130
1130
1131 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1131 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1132
1132
1133 self.__showprofile = showprofile
1133 self.__showprofile = showprofile
1134 self.nplots = nplots
1134 self.nplots = nplots
1135
1135
1136 ncolspan = 7
1136 ncolspan = 7
1137 colspan = 6
1137 colspan = 6
1138 self.__nsubplots = 2
1138 self.__nsubplots = 2
1139
1139
1140 self.createFigure(id = id,
1140 self.createFigure(id = id,
1141 wintitle = wintitle,
1141 wintitle = wintitle,
1142 widthplot = self.WIDTH+self.WIDTHPROF,
1142 widthplot = self.WIDTH+self.WIDTHPROF,
1143 heightplot = self.HEIGHT+self.HEIGHTPROF,
1143 heightplot = self.HEIGHT+self.HEIGHTPROF,
1144 show=show)
1144 show=show)
1145
1145
1146 nrow, ncol = self.getSubplots()
1146 nrow, ncol = self.getSubplots()
1147
1147
1148 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1148 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1149
1149
1150 def save_phase(self, filename_phase):
1150 def save_phase(self, filename_phase):
1151 f = open(filename_phase,'w+')
1151 f = open(filename_phase,'w+')
1152 f.write('\n\n')
1152 f.write('\n\n')
1153 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1153 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1154 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1154 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1155 f.close()
1155 f.close()
1156
1156
1157 def save_data(self, filename_phase, data, data_datetime):
1157 def save_data(self, filename_phase, data, data_datetime):
1158 f=open(filename_phase,'a')
1158 f=open(filename_phase,'a')
1159 timetuple_data = data_datetime.timetuple()
1159 timetuple_data = data_datetime.timetuple()
1160 day = str(timetuple_data.tm_mday)
1160 day = str(timetuple_data.tm_mday)
1161 month = str(timetuple_data.tm_mon)
1161 month = str(timetuple_data.tm_mon)
1162 year = str(timetuple_data.tm_year)
1162 year = str(timetuple_data.tm_year)
1163 hour = str(timetuple_data.tm_hour)
1163 hour = str(timetuple_data.tm_hour)
1164 minute = str(timetuple_data.tm_min)
1164 minute = str(timetuple_data.tm_min)
1165 second = str(timetuple_data.tm_sec)
1165 second = str(timetuple_data.tm_sec)
1166 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1166 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1167 f.close()
1167 f.close()
1168
1168
1169 def plot(self):
1169 def plot(self):
1170 log.warning('TODO: Not yet implemented...')
1170 log.warning('TODO: Not yet implemented...')
1171
1171
1172 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1172 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1173 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1173 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1174 timerange=None,
1174 timerange=None,
1175 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1175 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1176 server=None, folder=None, username=None, password=None,
1176 server=None, folder=None, username=None, password=None,
1177 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1177 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1178
1178
1179 if dataOut.flagNoData:
1179 if dataOut.flagNoData:
1180 return dataOut
1180 return dataOut
1181
1181
1182 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1182 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1183 return
1183 return
1184
1184
1185 if pairsList == None:
1185 if pairsList == None:
1186 pairsIndexList = dataOut.pairsIndexList[:10]
1186 pairsIndexList = dataOut.pairsIndexList[:10]
1187 else:
1187 else:
1188 pairsIndexList = []
1188 pairsIndexList = []
1189 for pair in pairsList:
1189 for pair in pairsList:
1190 if pair not in dataOut.pairsList:
1190 if pair not in dataOut.pairsList:
1191 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1191 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1192 pairsIndexList.append(dataOut.pairsList.index(pair))
1192 pairsIndexList.append(dataOut.pairsList.index(pair))
1193
1193
1194 if pairsIndexList == []:
1194 if pairsIndexList == []:
1195 return
1195 return
1196
1196
1197 # if len(pairsIndexList) > 4:
1197 # if len(pairsIndexList) > 4:
1198 # pairsIndexList = pairsIndexList[0:4]
1198 # pairsIndexList = pairsIndexList[0:4]
1199
1199
1200 hmin_index = None
1200 hmin_index = None
1201 hmax_index = None
1201 hmax_index = None
1202
1202
1203 if hmin != None and hmax != None:
1203 if hmin != None and hmax != None:
1204 indexes = numpy.arange(dataOut.nHeights)
1204 indexes = numpy.arange(dataOut.nHeights)
1205 hmin_list = indexes[dataOut.heightList >= hmin]
1205 hmin_list = indexes[dataOut.heightList >= hmin]
1206 hmax_list = indexes[dataOut.heightList <= hmax]
1206 hmax_list = indexes[dataOut.heightList <= hmax]
1207
1207
1208 if hmin_list.any():
1208 if hmin_list.any():
1209 hmin_index = hmin_list[0]
1209 hmin_index = hmin_list[0]
1210
1210
1211 if hmax_list.any():
1211 if hmax_list.any():
1212 hmax_index = hmax_list[-1]+1
1212 hmax_index = hmax_list[-1]+1
1213
1213
1214 x = dataOut.getTimeRange()
1214 x = dataOut.getTimeRange()
1215
1215
1216 thisDatetime = dataOut.datatime
1216 thisDatetime = dataOut.datatime
1217
1217
1218 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1218 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1219 xlabel = "Local Time"
1219 xlabel = "Local Time"
1220 ylabel = "Phase (degrees)"
1220 ylabel = "Phase (degrees)"
1221
1221
1222 update_figfile = False
1222 update_figfile = False
1223
1223
1224 nplots = len(pairsIndexList)
1224 nplots = len(pairsIndexList)
1225 phase_beacon = numpy.zeros(len(pairsIndexList))
1225 phase_beacon = numpy.zeros(len(pairsIndexList))
1226 for i in range(nplots):
1226 for i in range(nplots):
1227 pair = dataOut.pairsList[pairsIndexList[i]]
1227 pair = dataOut.pairsList[pairsIndexList[i]]
1228 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1228 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1229 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1229 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1230 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1230 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1231 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1231 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1232 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1232 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1233
1233
1234 if dataOut.beacon_heiIndexList:
1234 if dataOut.beacon_heiIndexList:
1235 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1235 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1236 else:
1236 else:
1237 phase_beacon[i] = numpy.average(phase)
1237 phase_beacon[i] = numpy.average(phase)
1238
1238
1239 if not self.isConfig:
1239 if not self.isConfig:
1240
1240
1241 nplots = len(pairsIndexList)
1241 nplots = len(pairsIndexList)
1242
1242
1243 self.setup(id=id,
1243 self.setup(id=id,
1244 nplots=nplots,
1244 nplots=nplots,
1245 wintitle=wintitle,
1245 wintitle=wintitle,
1246 showprofile=showprofile,
1246 showprofile=showprofile,
1247 show=show)
1247 show=show)
1248
1248
1249 if timerange != None:
1249 if timerange != None:
1250 self.timerange = timerange
1250 self.timerange = timerange
1251
1251
1252 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1252 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1253
1253
1254 if ymin == None: ymin = 0
1254 if ymin == None: ymin = 0
1255 if ymax == None: ymax = 360
1255 if ymax == None: ymax = 360
1256
1256
1257 self.FTP_WEI = ftp_wei
1257 self.FTP_WEI = ftp_wei
1258 self.EXP_CODE = exp_code
1258 self.EXP_CODE = exp_code
1259 self.SUB_EXP_CODE = sub_exp_code
1259 self.SUB_EXP_CODE = sub_exp_code
1260 self.PLOT_POS = plot_pos
1260 self.PLOT_POS = plot_pos
1261
1261
1262 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1262 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1263 self.isConfig = True
1263 self.isConfig = True
1264 self.figfile = figfile
1264 self.figfile = figfile
1265 self.xdata = numpy.array([])
1265 self.xdata = numpy.array([])
1266 self.ydata = numpy.array([])
1266 self.ydata = numpy.array([])
1267
1267
1268 update_figfile = True
1268 update_figfile = True
1269
1269
1270 #open file beacon phase
1270 #open file beacon phase
1271 path = '%s%03d' %(self.PREFIX, self.id)
1271 path = '%s%03d' %(self.PREFIX, self.id)
1272 beacon_file = os.path.join(path,'%s.txt'%self.name)
1272 beacon_file = os.path.join(path,'%s.txt'%self.name)
1273 self.filename_phase = os.path.join(figpath,beacon_file)
1273 self.filename_phase = os.path.join(figpath,beacon_file)
1274
1274
1275 self.setWinTitle(title)
1275 self.setWinTitle(title)
1276
1276
1277
1277
1278 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1278 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1279
1279
1280 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1280 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1281
1281
1282 axes = self.axesList[0]
1282 axes = self.axesList[0]
1283
1283
1284 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1284 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1285
1285
1286 if len(self.ydata)==0:
1286 if len(self.ydata)==0:
1287 self.ydata = phase_beacon.reshape(-1,1)
1287 self.ydata = phase_beacon.reshape(-1,1)
1288 else:
1288 else:
1289 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1289 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1290
1290
1291
1291
1292 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1292 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1293 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1293 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1294 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1294 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1295 XAxisAsTime=True, grid='both'
1295 XAxisAsTime=True, grid='both'
1296 )
1296 )
1297
1297
1298 self.draw()
1298 self.draw()
1299
1299
1300 if dataOut.ltctime >= self.xmax:
1300 if dataOut.ltctime >= self.xmax:
1301 self.counter_imagwr = wr_period
1301 self.counter_imagwr = wr_period
1302 self.isConfig = False
1302 self.isConfig = False
1303 update_figfile = True
1303 update_figfile = True
1304
1304
1305 self.save(figpath=figpath,
1305 self.save(figpath=figpath,
1306 figfile=figfile,
1306 figfile=figfile,
1307 save=save,
1307 save=save,
1308 ftp=ftp,
1308 ftp=ftp,
1309 wr_period=wr_period,
1309 wr_period=wr_period,
1310 thisDatetime=thisDatetime,
1310 thisDatetime=thisDatetime,
1311 update_figfile=update_figfile)
1311 update_figfile=update_figfile)
1312
1312
1313 return dataOut
1313 return dataOut
1314
1314
1315 #####################################
1315 #####################################
1316 class NoiselessSpectraPlot(Plot):
1316 class NoiselessSpectraPlot(Plot):
1317 '''
1317 '''
1318 Plot for Spectra data, subtracting
1318 Plot for Spectra data, subtracting
1319 the noise in all channels, using for
1319 the noise in all channels, using for
1320 amisr-14 data
1320 amisr-14 data
1321 '''
1321 '''
1322
1322
1323 CODE = 'noiseless_spc'
1323 CODE = 'noiseless_spc'
1324 colormap = 'jet'
1324 colormap = 'jet'
1325 plot_type = 'pcolor'
1325 plot_type = 'pcolor'
1326 buffering = False
1326 buffering = False
1327 channelList = []
1327 channelList = []
1328 last_noise = None
1328 last_noise = None
1329
1329
1330 def setup(self):
1330 def setup(self):
1331
1331
1332 self.nplots = len(self.data.channels)
1332 self.nplots = len(self.data.channels)
1333 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1333 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1334 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1334 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1335 self.height = 3.5 * self.nrows
1335 self.height = 3.5 * self.nrows
1336
1336
1337 self.cb_label = 'dB'
1337 self.cb_label = 'dB'
1338 if self.showprofile:
1338 if self.showprofile:
1339 self.width = 5.8 * self.ncols
1339 self.width = 5.8 * self.ncols
1340 else:
1340 else:
1341 self.width = 4.8* self.ncols
1341 self.width = 4.8* self.ncols
1342 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.92, 'bottom': 0.12})
1342 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.92, 'bottom': 0.12})
1343
1343
1344 self.ylabel = 'Range [km]'
1344 self.ylabel = 'Range [km]'
1345
1345
1346
1346
1347 def update_list(self,dataOut):
1347 def update_list(self,dataOut):
1348 if len(self.channelList) == 0:
1348 if len(self.channelList) == 0:
1349 self.channelList = dataOut.channelList
1349 self.channelList = dataOut.channelList
1350
1350
1351 def update(self, dataOut):
1351 def update(self, dataOut):
1352
1352
1353 self.update_list(dataOut)
1353 self.update_list(dataOut)
1354 data = {}
1354 data = {}
1355 meta = {}
1355 meta = {}
1356
1356
1357 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1357 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1358 n0 = (dataOut.getNoise()/norm)
1358 n0 = (dataOut.getNoise()/norm)
1359 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1359 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1360 noise = 10*numpy.log10(noise)
1360 noise = 10*numpy.log10(noise)
1361
1361
1362 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
1362 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
1363 for ch in range(dataOut.nChannels):
1363 for ch in range(dataOut.nChannels):
1364 if hasattr(dataOut.normFactor,'ndim'):
1364 if hasattr(dataOut.normFactor,'ndim'):
1365 if dataOut.normFactor.ndim > 1:
1365 if dataOut.normFactor.ndim > 1:
1366 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1366 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1367 else:
1367 else:
1368 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1368 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1369 else:
1369 else:
1370 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1370 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1371
1371
1372 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1372 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1373 spc = 10*numpy.log10(z)
1373 spc = 10*numpy.log10(z)
1374
1374
1375
1375
1376 data['spc'] = spc - noise
1376 data['spc'] = spc - noise
1377 #print(spc.shape)
1377 #print(spc.shape)
1378 data['rti'] = spc.mean(axis=1)
1378 data['rti'] = spc.mean(axis=1)
1379 data['noise'] = noise
1379 data['noise'] = noise
1380
1380
1381
1381
1382
1382
1383 # data['noise'] = noise
1383 # data['noise'] = noise
1384 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1384 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1385
1385
1386 return data, meta
1386 return data, meta
1387
1387
1388 def plot(self):
1388 def plot(self):
1389 if self.xaxis == "frequency":
1389 if self.xaxis == "frequency":
1390 x = self.data.xrange[0]
1390 x = self.data.xrange[0]
1391 self.xlabel = "Frequency (kHz)"
1391 self.xlabel = "Frequency (kHz)"
1392 elif self.xaxis == "time":
1392 elif self.xaxis == "time":
1393 x = self.data.xrange[1]
1393 x = self.data.xrange[1]
1394 self.xlabel = "Time (ms)"
1394 self.xlabel = "Time (ms)"
1395 else:
1395 else:
1396 x = self.data.xrange[2]
1396 x = self.data.xrange[2]
1397 self.xlabel = "Velocity (m/s)"
1397 self.xlabel = "Velocity (m/s)"
1398
1398
1399 self.titles = []
1399 self.titles = []
1400 y = self.data.yrange
1400 y = self.data.yrange
1401 self.y = y
1401 self.y = y
1402
1402
1403 data = self.data[-1]
1403 data = self.data[-1]
1404 z = data['spc']
1404 z = data['spc']
1405
1405
1406 for n, ax in enumerate(self.axes):
1406 for n, ax in enumerate(self.axes):
1407 #noise = data['noise'][n]
1407 #noise = data['noise'][n]
1408
1408
1409 if ax.firsttime:
1409 if ax.firsttime:
1410 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1410 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1411 self.xmin = self.xmin if self.xmin else -self.xmax
1411 self.xmin = self.xmin if self.xmin else -self.xmax
1412 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1412 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1413 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1413 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1414 ax.plt = ax.pcolormesh(x, y, z[n].T,
1414 ax.plt = ax.pcolormesh(x, y, z[n].T,
1415 vmin=self.zmin,
1415 vmin=self.zmin,
1416 vmax=self.zmax,
1416 vmax=self.zmax,
1417 cmap=plt.get_cmap(self.colormap)
1417 cmap=plt.get_cmap(self.colormap)
1418 )
1418 )
1419
1419
1420 if self.showprofile:
1420 if self.showprofile:
1421 ax.plt_profile = self.pf_axes[n].plot(
1421 ax.plt_profile = self.pf_axes[n].plot(
1422 data['rti'][n], y)[0]
1422 data['rti'][n], y)[0]
1423
1423
1424
1424
1425 else:
1425 else:
1426 ax.plt.set_array(z[n].T.ravel())
1426 ax.plt.set_array(z[n].T.ravel())
1427 if self.showprofile:
1427 if self.showprofile:
1428 ax.plt_profile.set_data(data['rti'][n], y)
1428 ax.plt_profile.set_data(data['rti'][n], y)
1429
1429
1430
1430
1431 self.titles.append('CH {}'.format(self.channelList[n]))
1431 self.titles.append('CH {}'.format(self.channelList[n]))
1432
1432
1433
1433
1434 class NoiselessRTIPlot(RTIPlot):
1434 class NoiselessRTIPlot(RTIPlot):
1435 '''
1435 '''
1436 Plot for RTI data
1436 Plot for RTI data
1437 '''
1437 '''
1438
1438
1439 CODE = 'noiseless_rti'
1439 CODE = 'noiseless_rti'
1440 colormap = 'jet'
1440 colormap = 'jet'
1441 plot_type = 'pcolorbuffer'
1441 plot_type = 'pcolorbuffer'
1442 titles = None
1442 titles = None
1443 channelList = []
1443 channelList = []
1444 elevationList = []
1444 elevationList = []
1445 azimuthList = []
1445 azimuthList = []
1446 last_noise = None
1446 last_noise = None
1447
1447
1448 def setup(self):
1448 def setup(self):
1449 self.xaxis = 'time'
1449 self.xaxis = 'time'
1450 self.ncols = 1
1450 self.ncols = 1
1451 #print("dataChannels ",self.data.channels)
1451 #print("dataChannels ",self.data.channels)
1452 self.nrows = len(self.data.channels)
1452 self.nrows = len(self.data.channels)
1453 self.nplots = len(self.data.channels)
1453 self.nplots = len(self.data.channels)
1454 self.ylabel = 'Range [km]'
1454 self.ylabel = 'Range [km]'
1455 #self.xlabel = 'Time'
1455 #self.xlabel = 'Time'
1456 self.cb_label = 'dB'
1456 self.cb_label = 'dB'
1457 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1457 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1458 self.titles = ['{} Channel {}'.format(
1458 self.titles = ['{} Channel {}'.format(
1459 self.CODE.upper(), x) for x in range(self.nplots)]
1459 self.CODE.upper(), x) for x in range(self.nplots)]
1460
1460
1461 def update_list(self,dataOut):
1461 def update_list(self,dataOut):
1462 if len(self.channelList) == 0:
1462 if len(self.channelList) == 0:
1463 self.channelList = dataOut.channelList
1463 self.channelList = dataOut.channelList
1464 if len(self.elevationList) == 0:
1464 if len(self.elevationList) == 0:
1465 self.elevationList = dataOut.elevationList
1465 self.elevationList = dataOut.elevationList
1466 if len(self.azimuthList) == 0:
1466 if len(self.azimuthList) == 0:
1467 self.azimuthList = dataOut.azimuthList
1467 self.azimuthList = dataOut.azimuthList
1468
1468
1469 def update(self, dataOut):
1469 def update(self, dataOut):
1470 if len(self.channelList) == 0:
1470 if len(self.channelList) == 0:
1471 self.update_list(dataOut)
1471 self.update_list(dataOut)
1472
1472
1473 data = {}
1473 data = {}
1474 meta = {}
1474 meta = {}
1475 #print(dataOut.max_nIncohInt, dataOut.nIncohInt)
1475 #print(dataOut.max_nIncohInt, dataOut.nIncohInt)
1476 #print(dataOut.windowOfFilter,dataOut.nCohInt,dataOut.nProfiles,dataOut.max_nIncohInt,dataOut.nIncohInt
1476 #print(dataOut.windowOfFilter,dataOut.nCohInt,dataOut.nProfiles,dataOut.max_nIncohInt,dataOut.nIncohInt
1477 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1477 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1478 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1478 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1479 data['noise'] = n0
1479 data['noise'] = n0
1480 noise = numpy.repeat(n0,dataOut.nHeights).reshape(dataOut.nChannels,dataOut.nHeights)
1480 noise = numpy.repeat(n0,dataOut.nHeights).reshape(dataOut.nChannels,dataOut.nHeights)
1481 noiseless_data = dataOut.getPower() - noise
1481 noiseless_data = dataOut.getPower() - noise
1482
1482
1483 #print("power, noise:", dataOut.getPower(), n0)
1483 #print("power, noise:", dataOut.getPower(), n0)
1484 #print(noise)
1484 #print(noise)
1485 #print(noiseless_data)
1485 #print(noiseless_data)
1486
1486
1487 data['noiseless_rti'] = noiseless_data
1487 data['noiseless_rti'] = noiseless_data
1488
1488
1489 return data, meta
1489 return data, meta
1490
1490
1491 def plot(self):
1491 def plot(self):
1492 from matplotlib import pyplot as plt
1492 from matplotlib import pyplot as plt
1493 self.x = self.data.times
1493 self.x = self.data.times
1494 self.y = self.data.yrange
1494 self.y = self.data.yrange
1495 self.z = self.data['noiseless_rti']
1495 self.z = self.data['noiseless_rti']
1496 self.z = numpy.array(self.z, dtype=float)
1496 self.z = numpy.array(self.z, dtype=float)
1497 self.z = numpy.ma.masked_invalid(self.z)
1497 self.z = numpy.ma.masked_invalid(self.z)
1498
1498
1499
1499
1500 try:
1500 try:
1501 if self.channelList != None:
1501 if self.channelList != None:
1502 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1502 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1503 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1503 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1504 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1504 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1505 else:
1505 else:
1506 self.titles = ['{} Channel {}'.format(
1506 self.titles = ['{} Channel {}'.format(
1507 self.CODE.upper(), x) for x in self.channelList]
1507 self.CODE.upper(), x) for x in self.channelList]
1508 except:
1508 except:
1509 if self.channelList.any() != None:
1509 if self.channelList.any() != None:
1510 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1510 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1511 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1511 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1512 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1512 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1513 else:
1513 else:
1514 self.titles = ['{} Channel {}'.format(
1514 self.titles = ['{} Channel {}'.format(
1515 self.CODE.upper(), x) for x in self.channelList]
1515 self.CODE.upper(), x) for x in self.channelList]
1516
1516
1517
1517
1518 if self.decimation is None:
1518 if self.decimation is None:
1519 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1519 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1520 else:
1520 else:
1521 x, y, z = self.fill_gaps(*self.decimate())
1521 x, y, z = self.fill_gaps(*self.decimate())
1522
1522
1523 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
1523 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
1524 #print("plot shapes ", z.shape, x.shape, y.shape)
1524 #print("plot shapes ", z.shape, x.shape, y.shape)
1525 #print(self.axes)
1525 #print(self.axes)
1526 for n, ax in enumerate(self.axes):
1526 for n, ax in enumerate(self.axes):
1527
1527
1528
1528
1529 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
1529 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
1530 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
1530 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
1531 data = self.data[-1]
1531 data = self.data[-1]
1532 if ax.firsttime:
1532 if ax.firsttime:
1533 if (n+1) == len(self.channelList):
1533 if (n+1) == len(self.channelList):
1534 ax.set_xlabel('Time')
1534 ax.set_xlabel('Time')
1535 ax.plt = ax.pcolormesh(x, y, z[n].T,
1535 ax.plt = ax.pcolormesh(x, y, z[n].T,
1536 vmin=self.zmin,
1536 vmin=self.zmin,
1537 vmax=self.zmax,
1537 vmax=self.zmax,
1538 cmap=plt.get_cmap(self.colormap)
1538 cmap=plt.get_cmap(self.colormap)
1539 )
1539 )
1540 if self.showprofile:
1540 if self.showprofile:
1541 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
1541 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
1542
1542
1543 else:
1543 else:
1544 # ax.collections.remove(ax.collections[0]) # error while running
1544 # ax.collections.remove(ax.collections[0]) # error while running
1545 ax.plt = ax.pcolormesh(x, y, z[n].T,
1545 ax.plt = ax.pcolormesh(x, y, z[n].T,
1546 vmin=self.zmin,
1546 vmin=self.zmin,
1547 vmax=self.zmax,
1547 vmax=self.zmax,
1548 cmap=plt.get_cmap(self.colormap)
1548 cmap=plt.get_cmap(self.colormap)
1549 )
1549 )
1550 if self.showprofile:
1550 if self.showprofile:
1551 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
1551 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
1552 # if "noise" in self.data:
1552 # if "noise" in self.data:
1553 # #ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
1553 # #ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
1554 # ax.plot_noise.set_data(data['noise'][n], self.y)
1554 # ax.plot_noise.set_data(data['noise'][n], self.y)
1555
1555
1556
1556
1557 class OutliersRTIPlot(Plot):
1557 class OutliersRTIPlot(Plot):
1558 '''
1558 '''
1559 Plot for data_xxxx object
1559 Plot for data_xxxx object
1560 '''
1560 '''
1561
1561
1562 CODE = 'outlier_rtc' # Range Time Counts
1562 CODE = 'outlier_rtc' # Range Time Counts
1563 colormap = 'cool'
1563 colormap = 'cool'
1564 plot_type = 'pcolorbuffer'
1564 plot_type = 'pcolorbuffer'
1565
1565
1566 def setup(self):
1566 def setup(self):
1567 self.xaxis = 'time'
1567 self.xaxis = 'time'
1568 self.ncols = 1
1568 self.ncols = 1
1569 self.nrows = self.data.shape('outlier_rtc')[0]
1569 self.nrows = self.data.shape('outlier_rtc')[0]
1570 self.nplots = self.nrows
1570 self.nplots = self.nrows
1571 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1571 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1572
1572
1573
1573
1574 if not self.xlabel:
1574 if not self.xlabel:
1575 self.xlabel = 'Time'
1575 self.xlabel = 'Time'
1576
1576
1577 self.ylabel = 'Height [km]'
1577 self.ylabel = 'Height [km]'
1578 if not self.titles:
1578 if not self.titles:
1579 self.titles = ['Outliers Ch:{}'.format(x) for x in range(self.nrows)]
1579 self.titles = ['Outliers Ch:{}'.format(x) for x in range(self.nrows)]
1580
1580
1581 def update(self, dataOut):
1581 def update(self, dataOut):
1582
1582
1583 data = {}
1583 data = {}
1584 data['outlier_rtc'] = dataOut.data_outlier
1584 data['outlier_rtc'] = dataOut.data_outlier
1585
1585
1586 meta = {}
1586 meta = {}
1587
1587
1588 return data, meta
1588 return data, meta
1589
1589
1590 def plot(self):
1590 def plot(self):
1591 # self.data.normalize_heights()
1591 # self.data.normalize_heights()
1592 self.x = self.data.times
1592 self.x = self.data.times
1593 self.y = self.data.yrange
1593 self.y = self.data.yrange
1594 self.z = self.data['outlier_rtc']
1594 self.z = self.data['outlier_rtc']
1595
1595
1596 #self.z = numpy.ma.masked_invalid(self.z)
1596 #self.z = numpy.ma.masked_invalid(self.z)
1597
1597
1598 if self.decimation is None:
1598 if self.decimation is None:
1599 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1599 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1600 else:
1600 else:
1601 x, y, z = self.fill_gaps(*self.decimate())
1601 x, y, z = self.fill_gaps(*self.decimate())
1602
1602
1603 for n, ax in enumerate(self.axes):
1603 for n, ax in enumerate(self.axes):
1604
1604
1605 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1605 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1606 self.z[n])
1606 self.z[n])
1607 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1607 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1608 self.z[n])
1608 self.z[n])
1609 data = self.data[-1]
1609 data = self.data[-1]
1610 if ax.firsttime:
1610 if ax.firsttime:
1611 if self.zlimits is not None:
1611 if self.zlimits is not None:
1612 self.zmin, self.zmax = self.zlimits[n]
1612 self.zmin, self.zmax = self.zlimits[n]
1613
1613
1614 ax.plt = ax.pcolormesh(x, y, z[n].T,
1614 ax.plt = ax.pcolormesh(x, y, z[n].T,
1615 vmin=self.zmin,
1615 vmin=self.zmin,
1616 vmax=self.zmax,
1616 vmax=self.zmax,
1617 cmap=self.cmaps[n]
1617 cmap=self.cmaps[n]
1618 )
1618 )
1619 if self.showprofile:
1619 if self.showprofile:
1620 ax.plot_profile = self.pf_axes[n].plot(data['outlier_rtc'][n], self.y)[0]
1620 ax.plot_profile = self.pf_axes[n].plot(data['outlier_rtc'][n], self.y)[0]
1621 self.pf_axes[n].set_xlabel('')
1621 self.pf_axes[n].set_xlabel('')
1622 else:
1622 else:
1623 if self.zlimits is not None:
1623 if self.zlimits is not None:
1624 self.zmin, self.zmax = self.zlimits[n]
1624 self.zmin, self.zmax = self.zlimits[n]
1625 # ax.collections.remove(ax.collections[0]) # error while running
1625 # ax.collections.remove(ax.collections[0]) # error while running
1626 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1626 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1627 vmin=self.zmin,
1627 vmin=self.zmin,
1628 vmax=self.zmax,
1628 vmax=self.zmax,
1629 cmap=self.cmaps[n]
1629 cmap=self.cmaps[n]
1630 )
1630 )
1631 if self.showprofile:
1631 if self.showprofile:
1632 ax.plot_profile.set_data(data['outlier_rtc'][n], self.y)
1632 ax.plot_profile.set_data(data['outlier_rtc'][n], self.y)
1633 self.pf_axes[n].set_xlabel('')
1633 self.pf_axes[n].set_xlabel('')
1634
1634
1635 class NIncohIntRTIPlot(Plot):
1635 class NIncohIntRTIPlot(Plot):
1636 '''
1636 '''
1637 Plot for data_xxxx object
1637 Plot for data_xxxx object
1638 '''
1638 '''
1639
1639
1640 CODE = 'integrations_rtc' # Range Time Counts
1640 CODE = 'integrations_rtc' # Range Time Counts
1641 colormap = 'BuGn'
1641 colormap = 'BuGn'
1642 plot_type = 'pcolorbuffer'
1642 plot_type = 'pcolorbuffer'
1643
1643
1644 def setup(self):
1644 def setup(self):
1645 self.xaxis = 'time'
1645 self.xaxis = 'time'
1646 self.ncols = 1
1646 self.ncols = 1
1647 self.nrows = self.data.shape('integrations_rtc')[0]
1647 self.nrows = self.data.shape('integrations_rtc')[0]
1648 self.nplots = self.nrows
1648 self.nplots = self.nrows
1649 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1649 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1650
1650
1651
1651
1652 if not self.xlabel:
1652 if not self.xlabel:
1653 self.xlabel = 'Time'
1653 self.xlabel = 'Time'
1654
1654
1655 self.ylabel = 'Height [km]'
1655 self.ylabel = 'Height [km]'
1656 if not self.titles:
1656 if not self.titles:
1657 self.titles = ['Integration Ch:{}'.format(x) for x in range(self.nrows)]
1657 self.titles = ['Integration Ch:{}'.format(x) for x in range(self.nrows)]
1658
1658
1659 def update(self, dataOut):
1659 def update(self, dataOut):
1660
1660
1661 data = {}
1661 data = {}
1662 data['integrations_rtc'] = dataOut.nIncohInt
1662 data['integrations_rtc'] = dataOut.nIncohInt
1663
1663
1664 meta = {}
1664 meta = {}
1665
1665
1666 return data, meta
1666 return data, meta
1667
1667
1668 def plot(self):
1668 def plot(self):
1669 # self.data.normalize_heights()
1669 # self.data.normalize_heights()
1670 self.x = self.data.times
1670 self.x = self.data.times
1671 self.y = self.data.yrange
1671 self.y = self.data.yrange
1672 self.z = self.data['integrations_rtc']
1672 self.z = self.data['integrations_rtc']
1673
1673
1674 #self.z = numpy.ma.masked_invalid(self.z)
1674 #self.z = numpy.ma.masked_invalid(self.z)
1675
1675
1676 if self.decimation is None:
1676 if self.decimation is None:
1677 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1677 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1678 else:
1678 else:
1679 x, y, z = self.fill_gaps(*self.decimate())
1679 x, y, z = self.fill_gaps(*self.decimate())
1680
1680
1681 for n, ax in enumerate(self.axes):
1681 for n, ax in enumerate(self.axes):
1682
1682
1683 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1683 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1684 self.z[n])
1684 self.z[n])
1685 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1685 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1686 self.z[n])
1686 self.z[n])
1687 data = self.data[-1]
1687 data = self.data[-1]
1688 if ax.firsttime:
1688 if ax.firsttime:
1689 if self.zlimits is not None:
1689 if self.zlimits is not None:
1690 self.zmin, self.zmax = self.zlimits[n]
1690 self.zmin, self.zmax = self.zlimits[n]
1691
1691
1692 ax.plt = ax.pcolormesh(x, y, z[n].T,
1692 ax.plt = ax.pcolormesh(x, y, z[n].T,
1693 vmin=self.zmin,
1693 vmin=self.zmin,
1694 vmax=self.zmax,
1694 vmax=self.zmax,
1695 cmap=self.cmaps[n]
1695 cmap=self.cmaps[n]
1696 )
1696 )
1697 if self.showprofile:
1697 if self.showprofile:
1698 ax.plot_profile = self.pf_axes[n].plot(data['integrations_rtc'][n], self.y)[0]
1698 ax.plot_profile = self.pf_axes[n].plot(data['integrations_rtc'][n], self.y)[0]
1699 self.pf_axes[n].set_xlabel('')
1699 self.pf_axes[n].set_xlabel('')
1700 else:
1700 else:
1701 if self.zlimits is not None:
1701 if self.zlimits is not None:
1702 self.zmin, self.zmax = self.zlimits[n]
1702 self.zmin, self.zmax = self.zlimits[n]
1703 # ax.collections.remove(ax.collections[0]) # error while running
1703 # ax.collections.remove(ax.collections[0]) # error while running
1704 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1704 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1705 vmin=self.zmin,
1705 vmin=self.zmin,
1706 vmax=self.zmax,
1706 vmax=self.zmax,
1707 cmap=self.cmaps[n]
1707 cmap=self.cmaps[n]
1708 )
1708 )
1709 if self.showprofile:
1709 if self.showprofile:
1710 ax.plot_profile.set_data(data['integrations_rtc'][n], self.y)
1710 ax.plot_profile.set_data(data['integrations_rtc'][n], self.y)
1711 self.pf_axes[n].set_xlabel('')
1711 self.pf_axes[n].set_xlabel('')
1712
1712
1713
1713
1714
1714
1715 class RTIMapPlot(Plot):
1715 class RTIMapPlot(Plot):
1716 '''
1716 '''
1717 Plot for RTI data
1717 Plot for RTI data
1718
1718
1719 Example:
1719 Example:
1720
1720
1721 controllerObj = Project()
1721 controllerObj = Project()
1722 controllerObj.setup(id = '11', name='eej_proc', description=desc)
1722 controllerObj.setup(id = '11', name='eej_proc', description=desc)
1723 ##.......................................................................................
1723 ##.......................................................................................
1724 ##.......................................................................................
1724 ##.......................................................................................
1725 readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', path=inPath, startDate='2023/05/24',endDate='2023/05/24',
1725 readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', path=inPath, startDate='2023/05/24',endDate='2023/05/24',
1726 startTime='12:00:00',endTime='12:45:59',walk=1,timezone='lt',margin_days=1,code = code,nCode = nCode,
1726 startTime='12:00:00',endTime='12:45:59',walk=1,timezone='lt',margin_days=1,code = code,nCode = nCode,
1727 nBaud = nBaud,nOsamp = nosamp,nChannels=nChannels,nFFT=NFFT,
1727 nBaud = nBaud,nOsamp = nosamp,nChannels=nChannels,nFFT=NFFT,
1728 syncronization=False,shiftChannels=0)
1728 syncronization=False,shiftChannels=0)
1729
1729
1730 volts_proc = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
1730 volts_proc = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
1731
1731
1732 opObj01 = volts_proc.addOperation(name='Decoder', optype='other')
1732 opObj01 = volts_proc.addOperation(name='Decoder', optype='other')
1733 opObj01.addParameter(name='code', value=code, format='floatlist')
1733 opObj01.addParameter(name='code', value=code, format='floatlist')
1734 opObj01.addParameter(name='nCode', value=1, format='int')
1734 opObj01.addParameter(name='nCode', value=1, format='int')
1735 opObj01.addParameter(name='nBaud', value=nBaud, format='int')
1735 opObj01.addParameter(name='nBaud', value=nBaud, format='int')
1736 opObj01.addParameter(name='osamp', value=nosamp, format='int')
1736 opObj01.addParameter(name='osamp', value=nosamp, format='int')
1737
1737
1738 opObj12 = volts_proc.addOperation(name='selectHeights', optype='self')
1738 opObj12 = volts_proc.addOperation(name='selectHeights', optype='self')
1739 opObj12.addParameter(name='minHei', value='90', format='float')
1739 opObj12.addParameter(name='minHei', value='90', format='float')
1740 opObj12.addParameter(name='maxHei', value='150', format='float')
1740 opObj12.addParameter(name='maxHei', value='150', format='float')
1741
1741
1742 proc_spc = controllerObj.addProcUnit(datatype='SpectraProc', inputId=volts_proc.getId())
1742 proc_spc = controllerObj.addProcUnit(datatype='SpectraProc', inputId=volts_proc.getId())
1743 proc_spc.addParameter(name='nFFTPoints', value='8', format='int')
1743 proc_spc.addParameter(name='nFFTPoints', value='8', format='int')
1744
1744
1745 opObj11 = proc_spc.addOperation(name='IncohInt', optype='other')
1745 opObj11 = proc_spc.addOperation(name='IncohInt', optype='other')
1746 opObj11.addParameter(name='n', value='1', format='int')
1746 opObj11.addParameter(name='n', value='1', format='int')
1747
1747
1748 beamMapFile = "/home/japaza/Documents/AMISR_sky_mapper/UMET_beamcodes.csv"
1748 beamMapFile = "/home/japaza/Documents/AMISR_sky_mapper/UMET_beamcodes.csv"
1749
1749
1750 opObj12 = proc_spc.addOperation(name='RTIMapPlot', optype='external')
1750 opObj12 = proc_spc.addOperation(name='RTIMapPlot', optype='external')
1751 opObj12.addParameter(name='selectedHeightsList', value='95, 100, 105, 110 ', format='int')
1751 opObj12.addParameter(name='selectedHeightsList', value='95, 100, 105, 110 ', format='int')
1752 opObj12.addParameter(name='bField', value='100', format='int')
1752 opObj12.addParameter(name='bField', value='100', format='int')
1753 opObj12.addParameter(name='filename', value=beamMapFile, format='str')
1753 opObj12.addParameter(name='filename', value=beamMapFile, format='str')
1754
1754
1755 '''
1755 '''
1756
1756
1757 CODE = 'rti_skymap'
1757 CODE = 'rti_skymap'
1758
1758
1759 plot_type = 'scatter'
1759 plot_type = 'scatter'
1760 titles = None
1760 titles = None
1761 colormap = 'jet'
1761 colormap = 'jet'
1762 channelList = []
1762 channelList = []
1763 elevationList = []
1763 elevationList = []
1764 azimuthList = []
1764 azimuthList = []
1765 last_noise = None
1765 last_noise = None
1766 flag_setIndex = False
1766 flag_setIndex = False
1767 heights = []
1767 heights = []
1768 dcosx = []
1768 dcosx = []
1769 dcosy = []
1769 dcosy = []
1770 fullDcosy = None
1770 fullDcosy = None
1771 fullDcosy = None
1771 fullDcosy = None
1772 hindex = []
1772 hindex = []
1773 mapFile = False
1773 mapFile = False
1774 ##### BField ####
1774 ##### BField ####
1775 flagBField = False
1775 flagBField = False
1776 dcosxB = []
1776 dcosxB = []
1777 dcosyB = []
1777 dcosyB = []
1778 Bmarker = ['+','*','D','x','s','>','o','^']
1778 Bmarker = ['+','*','D','x','s','>','o','^']
1779
1779
1780
1780
1781 def setup(self):
1781 def setup(self):
1782
1782
1783 self.xaxis = 'Range (Km)'
1783 self.xaxis = 'Range (Km)'
1784 if len(self.selectedHeightsList) > 0:
1784 if len(self.selectedHeightsList) > 0:
1785 self.nplots = len(self.selectedHeightsList)
1785 self.nplots = len(self.selectedHeightsList)
1786 else:
1786 else:
1787 self.nplots = 4
1787 self.nplots = 4
1788 self.ncols = int(numpy.ceil(self.nplots/2))
1788 self.ncols = int(numpy.ceil(self.nplots/2))
1789 self.nrows = int(numpy.ceil(self.nplots/self.ncols))
1789 self.nrows = int(numpy.ceil(self.nplots/self.ncols))
1790 self.ylabel = 'dcosy'
1790 self.ylabel = 'dcosy'
1791 self.xlabel = 'dcosx'
1791 self.xlabel = 'dcosx'
1792 self.colorbar = True
1792 self.colorbar = True
1793 self.width = 6 + 4.1*self.nrows
1793 self.width = 6 + 4.1*self.nrows
1794 self.height = 3 + 3.5*self.ncols
1794 self.height = 3 + 3.5*self.ncols
1795
1795
1796
1796
1797 if self.extFile!=None:
1797 if self.extFile!=None:
1798 try:
1798 try:
1799 pointings = numpy.genfromtxt(self.extFile, delimiter=',')
1799 pointings = numpy.genfromtxt(self.extFile, delimiter=',')
1800 full_azi = pointings[:,1]
1800 full_azi = pointings[:,1]
1801 full_elev = pointings[:,2]
1801 full_elev = pointings[:,2]
1802 self.fullDcosx = numpy.cos(numpy.radians(full_elev))*numpy.sin(numpy.radians(full_azi))
1802 self.fullDcosx = numpy.cos(numpy.radians(full_elev))*numpy.sin(numpy.radians(full_azi))
1803 self.fullDcosy = numpy.cos(numpy.radians(full_elev))*numpy.cos(numpy.radians(full_azi))
1803 self.fullDcosy = numpy.cos(numpy.radians(full_elev))*numpy.cos(numpy.radians(full_azi))
1804 mapFile = True
1804 mapFile = True
1805 except Exception as e:
1805 except Exception as e:
1806 self.extFile = None
1806 self.extFile = None
1807 print(e)
1807 print(e)
1808
1808
1809
1809
1810 def update_list(self,dataOut):
1810 def update_list(self,dataOut):
1811 if len(self.channelList) == 0:
1811 if len(self.channelList) == 0:
1812 self.channelList = dataOut.channelList
1812 self.channelList = dataOut.channelList
1813 if len(self.elevationList) == 0:
1813 if len(self.elevationList) == 0:
1814 self.elevationList = dataOut.elevationList
1814 self.elevationList = dataOut.elevationList
1815 if len(self.azimuthList) == 0:
1815 if len(self.azimuthList) == 0:
1816 self.azimuthList = dataOut.azimuthList
1816 self.azimuthList = dataOut.azimuthList
1817 a = numpy.radians(numpy.asarray(self.azimuthList))
1817 a = numpy.radians(numpy.asarray(self.azimuthList))
1818 e = numpy.radians(numpy.asarray(self.elevationList))
1818 e = numpy.radians(numpy.asarray(self.elevationList))
1819 self.heights = dataOut.heightList
1819 self.heights = dataOut.heightList
1820 self.dcosx = numpy.cos(e)*numpy.sin(a)
1820 self.dcosx = numpy.cos(e)*numpy.sin(a)
1821 self.dcosy = numpy.cos(e)*numpy.cos(a)
1821 self.dcosy = numpy.cos(e)*numpy.cos(a)
1822
1822
1823 if len(self.bFieldList)>0:
1823 if len(self.bFieldList)>0:
1824 datetObj = datetime.datetime.fromtimestamp(dataOut.utctime)
1824 datetObj = datetime.datetime.fromtimestamp(dataOut.utctime)
1825 doy = datetObj.timetuple().tm_yday
1825 doy = datetObj.timetuple().tm_yday
1826 year = datetObj.year
1826 year = datetObj.year
1827 # self.dcosxB, self.dcosyB
1827 # self.dcosxB, self.dcosyB
1828 ObjB = BField(year=year,doy=doy,site=2,heights=self.bFieldList)
1828 ObjB = BField(year=year,doy=doy,site=2,heights=self.bFieldList)
1829 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1829 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1830
1830
1831 alpha_location = numpy.zeros((nlon,2,len(self.bFieldList)))
1831 alpha_location = numpy.zeros((nlon,2,len(self.bFieldList)))
1832 for ih in range(len(self.bFieldList)):
1832 for ih in range(len(self.bFieldList)):
1833 alpha_location[:,0,ih] = dcos[:,0,ih,0]
1833 alpha_location[:,0,ih] = dcos[:,0,ih,0]
1834 for ilon in numpy.arange(nlon):
1834 for ilon in numpy.arange(nlon):
1835 myx = (alpha[ilon,:,ih])[::-1]
1835 myx = (alpha[ilon,:,ih])[::-1]
1836 myy = (dcos[ilon,:,ih,0])[::-1]
1836 myy = (dcos[ilon,:,ih,0])[::-1]
1837 tck = splrep(myx,myy,s=0)
1837 tck = splrep(myx,myy,s=0)
1838 mydcosx = splev(ObjB.alpha_i,tck,der=0)
1838 mydcosx = splev(ObjB.alpha_i,tck,der=0)
1839
1839
1840 myx = (alpha[ilon,:,ih])[::-1]
1840 myx = (alpha[ilon,:,ih])[::-1]
1841 myy = (dcos[ilon,:,ih,1])[::-1]
1841 myy = (dcos[ilon,:,ih,1])[::-1]
1842 tck = splrep(myx,myy,s=0)
1842 tck = splrep(myx,myy,s=0)
1843 mydcosy = splev(ObjB.alpha_i,tck,der=0)
1843 mydcosy = splev(ObjB.alpha_i,tck,der=0)
1844 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
1844 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
1845 self.dcosxB.append(alpha_location[:,0,ih])
1845 self.dcosxB.append(alpha_location[:,0,ih])
1846 self.dcosyB.append(alpha_location[:,1,ih])
1846 self.dcosyB.append(alpha_location[:,1,ih])
1847 self.flagBField = True
1847 self.flagBField = True
1848
1848
1849 if len(self.celestialList)>0:
1849 if len(self.celestialList)>0:
1850 #getBField(self.bFieldList, date)
1850 #getBField(self.bFieldList, date)
1851 #pass = kwargs.get('celestial', [])
1851 #pass = kwargs.get('celestial', [])
1852 pass
1852 pass
1853
1853
1854
1854
1855 def update(self, dataOut):
1855 def update(self, dataOut):
1856
1856
1857 if len(self.channelList) == 0:
1857 if len(self.channelList) == 0:
1858 self.update_list(dataOut)
1858 self.update_list(dataOut)
1859
1859
1860 if not self.flag_setIndex:
1860 if not self.flag_setIndex:
1861 if len(self.selectedHeightsList)>0:
1861 if len(self.selectedHeightsList)>0:
1862 for sel_height in self.selectedHeightsList:
1862 for sel_height in self.selectedHeightsList:
1863 index_list = numpy.where(self.heights >= sel_height)
1863 index_list = numpy.where(self.heights >= sel_height)
1864 index_list = index_list[0]
1864 index_list = index_list[0]
1865 self.hindex.append(index_list[0])
1865 self.hindex.append(index_list[0])
1866 self.flag_setIndex = True
1866 self.flag_setIndex = True
1867
1867
1868 data = {}
1868 data = {}
1869 meta = {}
1869 meta = {}
1870
1870
1871 data['rti_skymap'] = dataOut.getPower()
1871 data['rti_skymap'] = dataOut.getPower()
1872 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1872 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1873 noise = 10*numpy.log10(dataOut.getNoise()/norm)
1873 noise = 10*numpy.log10(dataOut.getNoise()/norm)
1874 data['noise'] = noise
1874 data['noise'] = noise
1875
1875
1876 return data, meta
1876 return data, meta
1877
1877
1878 def plot(self):
1878 def plot(self):
1879
1879
1880 self.x = self.dcosx
1880 self.x = self.dcosx
1881 self.y = self.dcosy
1881 self.y = self.dcosy
1882 self.z = self.data[-1]['rti_skymap']
1882 self.z = self.data[-1]['rti_skymap']
1883 self.z = numpy.array(self.z, dtype=float)
1883 self.z = numpy.array(self.z, dtype=float)
1884
1884
1885 if len(self.hindex) > 0:
1885 if len(self.hindex) > 0:
1886 index = self.hindex
1886 index = self.hindex
1887 else:
1887 else:
1888 index = numpy.arange(0, len(self.heights), int((len(self.heights))/4.2))
1888 index = numpy.arange(0, len(self.heights), int((len(self.heights))/4.2))
1889
1889
1890 self.titles = ['Height {:.2f} km '.format(self.heights[i])+" " for i in index]
1890 self.titles = ['Height {:.2f} km '.format(self.heights[i])+" " for i in index]
1891 for n, ax in enumerate(self.axes):
1891 for n, ax in enumerate(self.axes):
1892
1892
1893 if ax.firsttime:
1893 if ax.firsttime:
1894
1894
1895 self.xmax = self.xmax if self.xmax else numpy.nanmax(self.x)
1895 self.xmax = self.xmax if self.xmax else numpy.nanmax(self.x)
1896 self.xmin = self.xmin if self.xmin else numpy.nanmin(self.x)
1896 self.xmin = self.xmin if self.xmin else numpy.nanmin(self.x)
1897 self.ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
1897 self.ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
1898 self.ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
1898 self.ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
1899 self.zmax = self.zmax if self.zmax else numpy.nanmax(self.z)
1899 self.zmax = self.zmax if self.zmax else numpy.nanmax(self.z)
1900 self.zmin = self.zmin if self.zmin else numpy.nanmin(self.z)
1900 self.zmin = self.zmin if self.zmin else numpy.nanmin(self.z)
1901
1901
1902 if self.extFile!=None:
1902 if self.extFile!=None:
1903 ax.scatter(self.fullDcosx, self.fullDcosy, marker="+", s=20)
1903 ax.scatter(self.fullDcosx, self.fullDcosy, marker="+", s=20)
1904
1904
1905 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1905 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1906 s=60, marker="s", vmax = self.zmax)
1906 s=60, marker="s", vmax = self.zmax)
1907
1907
1908
1908
1909 ax.minorticks_on()
1909 ax.minorticks_on()
1910 ax.grid(which='major', axis='both')
1910 ax.grid(which='major', axis='both')
1911 ax.grid(which='minor', axis='x')
1911 ax.grid(which='minor', axis='x')
1912
1912
1913 if self.flagBField :
1913 if self.flagBField :
1914
1914
1915 for ih in range(len(self.bFieldList)):
1915 for ih in range(len(self.bFieldList)):
1916 label = str(self.bFieldList[ih]) + ' km'
1916 label = str(self.bFieldList[ih]) + ' km'
1917 ax.plot(self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1917 ax.plot(self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1918 label=label, linestyle='--', ms=4.0,lw=0.5)
1918 label=label, linestyle='--', ms=4.0,lw=0.5)
1919 handles, labels = ax.get_legend_handles_labels()
1919 handles, labels = ax.get_legend_handles_labels()
1920 a = -0.05
1920 a = -0.05
1921 b = 1.15 - 1.19*(self.nrows)
1921 b = 1.15 - 1.19*(self.nrows)
1922 self.axes[0].legend(handles,labels, bbox_to_anchor=(a,b), prop={'size': (5.8+ 1.1*self.nplots)}, title='B Field βŠ₯')
1922 self.axes[0].legend(handles,labels, bbox_to_anchor=(a,b), prop={'size': (5.8+ 1.1*self.nplots)}, title='B Field βŠ₯')
1923
1923
1924 else:
1924 else:
1925
1925
1926 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1926 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1927 s=80, marker="s", vmax = self.zmax)
1927 s=80, marker="s", vmax = self.zmax)
1928
1928
1929 if self.flagBField :
1929 if self.flagBField :
1930 for ih in range(len(self.bFieldList)):
1930 for ih in range(len(self.bFieldList)):
1931 ax.plot (self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1931 ax.plot (self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1932 linestyle='--', ms=4.0,lw=0.5)
1932 linestyle='--', ms=4.0,lw=0.5)
1933
1933
1934
1934
1935
1935
@@ -1,779 +1,778
1 ''''
1 ''''
2 Created on Set 9, 2015
2 Created on Set 9, 2015
3
3
4 @author: roj-idl71 Karim Kuyeng
4 @author: roj-idl71 Karim Kuyeng
5
5
6 @upgrade: 2021, Joab Apaza
6 @upgrade: 2021, Joab Apaza
7
7
8 '''
8 '''
9
9
10 import os
10 import os
11 import sys
11 import sys
12 import glob
12 import glob
13 import fnmatch
13 import fnmatch
14 import datetime
14 import datetime
15 import time
15 import time
16 import re
16 import re
17 import h5py
17 import h5py
18 import numpy
18 import numpy
19
19
20 try:
20 try:
21 from gevent import sleep
21 from gevent import sleep
22 except:
22 except:
23 from time import sleep
23 from time import sleep
24
24
25 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader,ProcessingHeader
25 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader,ProcessingHeader
26 from schainpy.model.data.jrodata import Voltage
26 from schainpy.model.data.jrodata import Voltage
27 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
27 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
28 from numpy import imag
28 from numpy import imag
29 from schainpy.utils import log
29 from schainpy.utils import log
30
30
31
31
32 class AMISRReader(ProcessingUnit):
32 class AMISRReader(ProcessingUnit):
33 '''
33 '''
34 classdocs
34 classdocs
35 '''
35 '''
36
36
37 def __init__(self):
37 def __init__(self):
38 '''
38 '''
39 Constructor
39 Constructor
40 '''
40 '''
41
41
42 ProcessingUnit.__init__(self)
42 ProcessingUnit.__init__(self)
43
43
44 self.set = None
44 self.set = None
45 self.subset = None
45 self.subset = None
46 self.extension_file = '.h5'
46 self.extension_file = '.h5'
47 self.dtc_str = 'dtc'
47 self.dtc_str = 'dtc'
48 self.dtc_id = 0
48 self.dtc_id = 0
49 self.status = True
49 self.status = True
50 self.isConfig = False
50 self.isConfig = False
51 self.dirnameList = []
51 self.dirnameList = []
52 self.filenameList = []
52 self.filenameList = []
53 self.fileIndex = None
53 self.fileIndex = None
54 self.flagNoMoreFiles = False
54 self.flagNoMoreFiles = False
55 self.flagIsNewFile = 0
55 self.flagIsNewFile = 0
56 self.filename = ''
56 self.filename = ''
57 self.amisrFilePointer = None
57 self.amisrFilePointer = None
58
58
59 self.beamCodeMap = None
59 self.beamCodeMap = None
60 self.azimuthList = []
60 self.azimuthList = []
61 self.elevationList = []
61 self.elevationList = []
62 self.dataShape = None
62 self.dataShape = None
63 self.flag_old_beams = False
63 self.flag_old_beams = False
64
64
65 self.flagAsync = False #Use when the experiment has no syncronization
65 self.flagAsync = False #Use when the experiment has no syncronization
66 self.shiftChannels = 0
66 self.shiftChannels = 0
67 self.profileIndex = 0
67 self.profileIndex = 0
68
68
69
69
70 self.beamCodeByFrame = None
70 self.beamCodeByFrame = None
71 self.radacTimeByFrame = None
71 self.radacTimeByFrame = None
72
72
73 self.dataset = None
73 self.dataset = None
74
74
75 self.__firstFile = True
75 self.__firstFile = True
76
76
77 self.buffer = None
77 self.buffer = None
78
78
79 self.timezone = 'ut'
79 self.timezone = 'ut'
80
80
81 self.__waitForNewFile = 20
81 self.__waitForNewFile = 20
82 self.__filename_online = None
82 self.__filename_online = None
83 #Is really necessary create the output object in the initializer
83 #Is really necessary create the output object in the initializer
84 self.dataOut = Voltage()
84 self.dataOut = Voltage()
85 self.dataOut.error=False
85 self.dataOut.error=False
86 self.margin_days = 1
86 self.margin_days = 1
87 self.flag_ignoreFiles = False #to activate the ignoring Files flag
87 self.flag_ignoreFiles = False #to activate the ignoring Files flag
88 self.flag_standby = False # just keep waiting, use when ignoring files
88 self.flag_standby = False # just keep waiting, use when ignoring files
89 self.ignStartDateTime=None
89 self.ignStartDateTime=None
90 self.ignEndDateTime=None
90 self.ignEndDateTime=None
91
91
92 def setup(self,path=None,
92 def setup(self,path=None,
93 startDate=None,
93 startDate=None,
94 endDate=None,
94 endDate=None,
95 startTime=None,
95 startTime=None,
96 endTime=None,
96 endTime=None,
97 walk=True,
97 walk=True,
98 timezone='ut',
98 timezone='ut',
99 all=0,
99 all=0,
100 code = 1,
100 code = 1,
101 nCode = 1,
101 nCode = 1,
102 nBaud = 0,
102 nBaud = 0,
103 nOsamp = 0,
103 nOsamp = 0,
104 online=False,
104 online=False,
105 old_beams=False,
105 old_beams=False,
106 margin_days=1,
106 margin_days=1,
107 nFFT = None,
107 nFFT = None,
108 nChannels = None,
108 nChannels = None,
109 ignStartDate=None,
109 ignStartDate=None,
110 ignEndDate=None,
110 ignEndDate=None,
111 ignStartTime=None,
111 ignStartTime=None,
112 ignEndTime=None,
112 ignEndTime=None,
113 syncronization=True,
113 syncronization=True,
114 shiftChannels=0
114 shiftChannels=0
115 ):
115 ):
116
116
117
117
118
118
119 self.timezone = timezone
119 self.timezone = timezone
120 self.all = all
120 self.all = all
121 self.online = online
121 self.online = online
122 self.flag_old_beams = old_beams
122 self.flag_old_beams = old_beams
123 self.code = code
123 self.code = code
124 self.nCode = int(nCode)
124 self.nCode = int(nCode)
125 self.nBaud = int(nBaud)
125 self.nBaud = int(nBaud)
126 self.nOsamp = int(nOsamp)
126 self.nOsamp = int(nOsamp)
127 self.margin_days = margin_days
127 self.margin_days = margin_days
128 self.__sampleRate = None
128 self.__sampleRate = None
129 self.flagAsync = not syncronization
129 self.flagAsync = not syncronization
130 self.shiftChannels = shiftChannels
130 self.shiftChannels = shiftChannels
131 self.nFFT = nFFT
131 self.nFFT = nFFT
132 self.nChannels = nChannels
132 self.nChannels = nChannels
133 if ignStartTime!=None and ignEndTime!=None:
133 if ignStartTime!=None and ignEndTime!=None:
134 if ignStartDate!=None and ignEndDate!=None:
134 if ignStartDate!=None and ignEndDate!=None:
135 self.ignStartDateTime=datetime.datetime.combine(ignStartDate,ignStartTime)
135 self.ignStartDateTime=datetime.datetime.combine(ignStartDate,ignStartTime)
136 self.ignEndDateTime=datetime.datetime.combine(ignEndDate,ignEndTime)
136 self.ignEndDateTime=datetime.datetime.combine(ignEndDate,ignEndTime)
137 else:
137 else:
138 self.ignStartDateTime=datetime.datetime.combine(startDate,ignStartTime)
138 self.ignStartDateTime=datetime.datetime.combine(startDate,ignStartTime)
139 self.ignEndDateTime=datetime.datetime.combine(endDate,ignEndTime)
139 self.ignEndDateTime=datetime.datetime.combine(endDate,ignEndTime)
140 self.flag_ignoreFiles = True
140 self.flag_ignoreFiles = True
141
141
142 #self.findFiles()
142 #self.findFiles()
143 if not(online):
143 if not(online):
144 #Busqueda de archivos offline
144 #Busqueda de archivos offline
145 self.searchFilesOffLine(path, startDate, endDate, startTime, endTime, walk,)
145 self.searchFilesOffLine(path, startDate, endDate, startTime, endTime, walk,)
146 else:
146 else:
147 self.searchFilesOnLine(path, startDate, endDate, startTime,endTime,walk)
147 self.searchFilesOnLine(path, startDate, endDate, startTime,endTime,walk)
148
148
149 if not(self.filenameList):
149 if not(self.filenameList):
150 raise schainpy.admin.SchainWarning("There is no files into the folder: %s"%(path))
150 raise schainpy.admin.SchainWarning("There is no files into the folder: %s"%(path))
151 #sys.exit(0)
151 #sys.exit(0)
152 self.dataOut.error = True
152 self.dataOut.error = True
153
153
154 self.fileIndex = 0
154 self.fileIndex = 0
155
155
156 self.readNextFile(online)
156 self.readNextFile(online)
157
157
158 '''
158 '''
159 Add code
159 Add code
160 '''
160 '''
161 self.isConfig = True
161 self.isConfig = True
162 # print("Setup Done")
162 # print("Setup Done")
163 pass
163 pass
164
164
165
165
166 def readAMISRHeader(self,fp):
166 def readAMISRHeader(self,fp):
167
167
168 if self.isConfig and (not self.flagNoMoreFiles):
168 if self.isConfig and (not self.flagNoMoreFiles):
169 newShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
169 newShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
170 if self.dataShape != newShape and newShape != None and not self.flag_standby:
170 if self.dataShape != newShape and newShape != None and not self.flag_standby:
171 raise schainpy.admin.SchainError("NEW FILE HAS A DIFFERENT SHAPE: ")
171 raise schainpy.admin.SchainError("NEW FILE HAS A DIFFERENT SHAPE: ")
172 print(self.dataShape,newShape,"\n")
172 print(self.dataShape,newShape,"\n")
173 return 0
173 return 0
174 else:
174 else:
175 self.dataShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
175 self.dataShape = fp.get('Raw11/Data/Samples/Data').shape[1:]
176
176
177
177
178 header = 'Raw11/Data/RadacHeader'
178 header = 'Raw11/Data/RadacHeader'
179 if self.nChannels == None:
179 if self.nChannels == None:
180 expFile = fp['Setup/Experimentfile'][()].decode()
180 expFile = fp['Setup/Experimentfile'][()].decode()
181 linesExp = expFile.split("\n")
181 linesExp = expFile.split("\n")
182 a = [line for line in linesExp if "nbeamcodes" in line]
182 a = [line for line in linesExp if "nbeamcodes" in line]
183 self.nChannels = int(a[0][11:])
183 self.nChannels = int(a[0][11:])
184
184
185 if not self.flagAsync: #for experiments with no syncronization
185 if not self.flagAsync: #for experiments with no syncronization
186 self.shiftChannels = 0
186 self.shiftChannels = 0
187
187
188
188
189
189
190 self.beamCodeByPulse = fp.get(header+'/BeamCode') # LIST OF BEAMS PER PROFILE, TO BE USED ON REARRANGE
190 self.beamCodeByPulse = fp.get(header+'/BeamCode') # LIST OF BEAMS PER PROFILE, TO BE USED ON REARRANGE
191
191
192
192
193 if (self.startDate > datetime.date(2021, 7, 15)) or self.flag_old_beams: #Se cambiΓ³ la forma de extracciΓ³n de Apuntes el 17 o forzar con flag de reorganizaciΓ³n
193 if (self.startDate > datetime.date(2021, 7, 15)) or self.flag_old_beams: #Se cambiΓ³ la forma de extracciΓ³n de Apuntes el 17 o forzar con flag de reorganizaciΓ³n
194 self.beamcodeFile = fp['Setup/Beamcodefile'][()].decode()
194 self.beamcodeFile = fp['Setup/Beamcodefile'][()].decode()
195 self.trueBeams = self.beamcodeFile.split("\n")
195 self.trueBeams = self.beamcodeFile.split("\n")
196 self.trueBeams.pop()#remove last
196 self.trueBeams.pop()#remove last
197 if self.nFFT == None:
197 if self.nFFT == None:
198 log.error("FFT or number of repetitions per channels is needed",self.name)
198 log.error("FFT or number of repetitions per channels is needed",self.name)
199 beams_idx = [k*self.nFFT for k in range(self.nChannels)]
199 beams_idx = [k*self.nFFT for k in range(self.nChannels)]
200 beams = [self.trueBeams[b] for b in beams_idx]
200 beams = [self.trueBeams[b] for b in beams_idx]
201 self.beamCode = [int(x, 16) for x in beams]
201 self.beamCode = [int(x, 16) for x in beams]
202
202
203 if(self.flagAsync and self.shiftChannels == 0):
203 if(self.flagAsync and self.shiftChannels == 0):
204 initBeam = self.beamCodeByPulse[0, 0]
204 initBeam = self.beamCodeByPulse[0, 0]
205 self.shiftChannels = numpy.argwhere(self.beamCode ==initBeam)[0,0]
205 self.shiftChannels = numpy.argwhere(self.beamCode ==initBeam)[0,0]
206
206
207 else:
207 else:
208 _beamCode= fp.get('Raw11/Data/Beamcodes') #se usa la manera previa al cambio de apuntes
208 _beamCode= fp.get('Raw11/Data/Beamcodes') #se usa la manera previa al cambio de apuntes
209 self.beamCode = _beamCode[0,:]
209 self.beamCode = _beamCode[0,:]
210
210
211
211
212
212
213
213
214 if self.beamCodeMap == None:
214 if self.beamCodeMap == None:
215 self.beamCodeMap = fp['Setup/BeamcodeMap']
215 self.beamCodeMap = fp['Setup/BeamcodeMap']
216 for beam in self.beamCode:
216 for beam in self.beamCode:
217 beamAziElev = numpy.where(self.beamCodeMap[:,0]==beam)
217 beamAziElev = numpy.where(self.beamCodeMap[:,0]==beam)
218 beamAziElev = beamAziElev[0].squeeze()
218 beamAziElev = beamAziElev[0].squeeze()
219 self.azimuthList.append(self.beamCodeMap[beamAziElev,1])
219 self.azimuthList.append(self.beamCodeMap[beamAziElev,1])
220 self.elevationList.append(self.beamCodeMap[beamAziElev,2])
220 self.elevationList.append(self.beamCodeMap[beamAziElev,2])
221 #print("Beamssss: ",self.beamCodeMap[beamAziElev,1],self.beamCodeMap[beamAziElev,2])
221 #print("Beamssss: ",self.beamCodeMap[beamAziElev,1],self.beamCodeMap[beamAziElev,2])
222 #print(self.beamCode)
222 #print(self.beamCode)
223 #self.code = fp.get(header+'/Code') # NOT USE FOR THIS
223 #self.code = fp.get(header+'/Code') # NOT USE FOR THIS
224 self.frameCount = fp.get(header+'/FrameCount')# NOT USE FOR THIS
224 self.frameCount = fp.get(header+'/FrameCount')# NOT USE FOR THIS
225 self.modeGroup = fp.get(header+'/ModeGroup')# NOT USE FOR THIS
225 self.modeGroup = fp.get(header+'/ModeGroup')# NOT USE FOR THIS
226 self.nsamplesPulse = fp.get(header+'/NSamplesPulse')# TO GET NSA OR USING DATA FOR THAT
226 self.nsamplesPulse = fp.get(header+'/NSamplesPulse')# TO GET NSA OR USING DATA FOR THAT
227 self.pulseCount = fp.get(header+'/PulseCount')# NOT USE FOR THIS
227 self.pulseCount = fp.get(header+'/PulseCount')# NOT USE FOR THIS
228 self.radacTime = fp.get(header+'/RadacTime')# 1st TIME ON FILE ANDE CALCULATE THE REST WITH IPP*nindexprofile
228 self.radacTime = fp.get(header+'/RadacTime')# 1st TIME ON FILE ANDE CALCULATE THE REST WITH IPP*nindexprofile
229 self.timeCount = fp.get(header+'/TimeCount')# NOT USE FOR THIS
229 self.timeCount = fp.get(header+'/TimeCount')# NOT USE FOR THIS
230 self.timeStatus = fp.get(header+'/TimeStatus')# NOT USE FOR THIS
230 self.timeStatus = fp.get(header+'/TimeStatus')# NOT USE FOR THIS
231 self.rangeFromFile = fp.get('Raw11/Data/Samples/Range')
231 self.rangeFromFile = fp.get('Raw11/Data/Samples/Range')
232 self.frequency = fp.get('Rx/Frequency')
232 self.frequency = fp.get('Rx/Frequency')
233 txAus = fp.get('Raw11/Data/Pulsewidth') #seconds
233 txAus = fp.get('Raw11/Data/Pulsewidth') #seconds
234 self.baud = fp.get('Raw11/Data/TxBaud')
234 self.baud = fp.get('Raw11/Data/TxBaud')
235 sampleRate = fp.get('Rx/SampleRate')
235 sampleRate = fp.get('Rx/SampleRate')
236 self.__sampleRate = sampleRate[()]
236 self.__sampleRate = sampleRate[()]
237 self.nblocks = self.pulseCount.shape[0] #nblocks
237 self.nblocks = self.pulseCount.shape[0] #nblocks
238 self.profPerBlockRAW = self.pulseCount.shape[1] #profiles per block in raw data
238 self.profPerBlockRAW = self.pulseCount.shape[1] #profiles per block in raw data
239 self.nprofiles = self.pulseCount.shape[1] #nprofile
239 self.nprofiles = self.pulseCount.shape[1] #nprofile
240 #self.nsa = self.nsamplesPulse[0,0] #ngates
240 #self.nsa = self.nsamplesPulse[0,0] #ngates
241 self.nsa = len(self.rangeFromFile[0])
241 self.nsa = len(self.rangeFromFile[0])
242 self.nchannels = len(self.beamCode)
242 self.nchannels = len(self.beamCode)
243 self.ippSeconds = (self.radacTime[0][1] -self.radacTime[0][0]) #Ipp in seconds
243 self.ippSeconds = (self.radacTime[0][1] -self.radacTime[0][0]) #Ipp in seconds
244 #print("IPPS secs: ",self.ippSeconds)
244 #print("IPPS secs: ",self.ippSeconds)
245 #self.__waitForNewFile = self.nblocks # wait depending on the number of blocks since each block is 1 sec
245 #self.__waitForNewFile = self.nblocks # wait depending on the number of blocks since each block is 1 sec
246 self.__waitForNewFile = self.nblocks * self.nprofiles * self.ippSeconds # wait until new file is created
246 self.__waitForNewFile = self.nblocks * self.nprofiles * self.ippSeconds # wait until new file is created
247
247
248 #filling radar controller header parameters
248 #filling radar controller header parameters
249 self.__ippKm = self.ippSeconds *.15*1e6 # in km
249 self.__ippKm = self.ippSeconds *.15*1e6 # in km
250 #self.__txA = txAus[()]*.15 #(ipp[us]*.15km/1us) in km
250 #self.__txA = txAus[()]*.15 #(ipp[us]*.15km/1us) in km
251 self.__txA = txAus[()] #seconds
251 self.__txA = txAus[()] #seconds
252 self.__txAKm = self.__txA*1e6*.15
252 self.__txAKm = self.__txA*1e6*.15
253 self.__txB = 0
253 self.__txB = 0
254 nWindows=1
254 nWindows=1
255 self.__nSamples = self.nsa
255 self.__nSamples = self.nsa
256 self.__firstHeight = self.rangeFromFile[0][0]/1000 #in km
256 self.__firstHeight = self.rangeFromFile[0][0]/1000 #in km
257 self.__deltaHeight = (self.rangeFromFile[0][1] - self.rangeFromFile[0][0])/1000
257 self.__deltaHeight = (self.rangeFromFile[0][1] - self.rangeFromFile[0][0])/1000
258 #print("amisr-ipp:",self.ippSeconds, self.__ippKm)
258 #print("amisr-ipp:",self.ippSeconds, self.__ippKm)
259 #for now until understand why the code saved is different (code included even though code not in tuf file)
259 #for now until understand why the code saved is different (code included even though code not in tuf file)
260 #self.__codeType = 0
260 #self.__codeType = 0
261 # self.__nCode = None
261 # self.__nCode = None
262 # self.__nBaud = None
262 # self.__nBaud = None
263 self.__code = self.code
263 self.__code = self.code
264 self.__codeType = 0
264 self.__codeType = 0
265 if self.code != None:
265 if self.code != None:
266 self.__codeType = 1
266 self.__codeType = 1
267 self.__nCode = self.nCode
267 self.__nCode = self.nCode
268 self.__nBaud = self.nBaud
268 self.__nBaud = self.nBaud
269 self.__baudTX = self.__txA/(self.nBaud)
269 self.__baudTX = self.__txA/(self.nBaud)
270 #self.__code = 0
270 #self.__code = 0
271
271
272 #filling system header parameters
272 #filling system header parameters
273 self.__nSamples = self.nsa
273 self.__nSamples = self.nsa
274 self.newProfiles = self.nprofiles/self.nchannels
274 self.newProfiles = self.nprofiles/self.nchannels
275 self.__channelList = [n for n in range(self.nchannels)]
275 self.__channelList = [n for n in range(self.nchannels)]
276
276
277 self.__frequency = self.frequency[0][0]
277 self.__frequency = self.frequency[0][0]
278
278
279
279
280 return 1
280 return 1
281
281
282
282
283 def createBuffers(self):
283 def createBuffers(self):
284
284
285 pass
285 pass
286
286
287 def __setParameters(self,path='', startDate='',endDate='',startTime='', endTime='', walk=''):
287 def __setParameters(self,path='', startDate='',endDate='',startTime='', endTime='', walk=''):
288 self.path = path
288 self.path = path
289 self.startDate = startDate
289 self.startDate = startDate
290 self.endDate = endDate
290 self.endDate = endDate
291 self.startTime = startTime
291 self.startTime = startTime
292 self.endTime = endTime
292 self.endTime = endTime
293 self.walk = walk
293 self.walk = walk
294
294
295
295
296 def __checkPath(self):
296 def __checkPath(self):
297 if os.path.exists(self.path):
297 if os.path.exists(self.path):
298 self.status = 1
298 self.status = 1
299 else:
299 else:
300 self.status = 0
300 self.status = 0
301 print('Path:%s does not exists'%self.path)
301 print('Path:%s does not exists'%self.path)
302
302
303 return
303 return
304
304
305
305
306 def __selDates(self, amisr_dirname_format):
306 def __selDates(self, amisr_dirname_format):
307 try:
307 try:
308 year = int(amisr_dirname_format[0:4])
308 year = int(amisr_dirname_format[0:4])
309 month = int(amisr_dirname_format[4:6])
309 month = int(amisr_dirname_format[4:6])
310 dom = int(amisr_dirname_format[6:8])
310 dom = int(amisr_dirname_format[6:8])
311 thisDate = datetime.date(year,month,dom)
311 thisDate = datetime.date(year,month,dom)
312 #margen de un dΓ­a extra, igual luego se filtra for fecha y hora
312 #margen de un dΓ­a extra, igual luego se filtra for fecha y hora
313 if (thisDate>=(self.startDate - datetime.timedelta(days=self.margin_days)) and thisDate <= (self.endDate)+ datetime.timedelta(days=1)):
313 if (thisDate>=(self.startDate - datetime.timedelta(days=self.margin_days)) and thisDate <= (self.endDate)+ datetime.timedelta(days=1)):
314 return amisr_dirname_format
314 return amisr_dirname_format
315 except:
315 except:
316 return None
316 return None
317
317
318
318
319 def __findDataForDates(self,online=False):
319 def __findDataForDates(self,online=False):
320
320
321 if not(self.status):
321 if not(self.status):
322 return None
322 return None
323
323
324 pat = '\d+.\d+'
324 pat = '\d+.\d+'
325 dirnameList = [re.search(pat,x) for x in os.listdir(self.path)]
325 dirnameList = [re.search(pat,x) for x in os.listdir(self.path)]
326 dirnameList = [x for x in dirnameList if x!=None]
326 dirnameList = [x for x in dirnameList if x!=None]
327 dirnameList = [x.string for x in dirnameList]
327 dirnameList = [x.string for x in dirnameList]
328 if not(online):
328 if not(online):
329 dirnameList = [self.__selDates(x) for x in dirnameList]
329 dirnameList = [self.__selDates(x) for x in dirnameList]
330 dirnameList = [x for x in dirnameList if x!=None]
330 dirnameList = [x for x in dirnameList if x!=None]
331 if len(dirnameList)>0:
331 if len(dirnameList)>0:
332 self.status = 1
332 self.status = 1
333 self.dirnameList = dirnameList
333 self.dirnameList = dirnameList
334 self.dirnameList.sort()
334 self.dirnameList.sort()
335 else:
335 else:
336 self.status = 0
336 self.status = 0
337 return None
337 return None
338
338
339 def __getTimeFromData(self):
339 def __getTimeFromData(self):
340 startDateTime_Reader = datetime.datetime.combine(self.startDate,self.startTime)
340 startDateTime_Reader = datetime.datetime.combine(self.startDate,self.startTime)
341 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
341 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
342
342
343 print('Filtering Files from %s to %s'%(startDateTime_Reader, endDateTime_Reader))
343 print('Filtering Files from %s to %s'%(startDateTime_Reader, endDateTime_Reader))
344 print('........................................')
344 print('........................................')
345 filter_filenameList = []
345 filter_filenameList = []
346 self.filenameList.sort()
346 self.filenameList.sort()
347 total_files = len(self.filenameList)
347 total_files = len(self.filenameList)
348 #for i in range(len(self.filenameList)-1):
348 #for i in range(len(self.filenameList)-1):
349 for i in range(total_files):
349 for i in range(total_files):
350 filename = self.filenameList[i]
350 filename = self.filenameList[i]
351 #print("file-> ",filename)
351 #print("file-> ",filename)
352 try:
352 try:
353 fp = h5py.File(filename,'r')
353 fp = h5py.File(filename,'r')
354 time_str = fp.get('Time/RadacTimeString')
354 time_str = fp.get('Time/RadacTimeString')
355
355
356 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
356 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
357 #startDateTimeStr_File = "2019-12-16 09:21:11"
357 #startDateTimeStr_File = "2019-12-16 09:21:11"
358 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
358 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
359 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
359 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
360
360
361 #endDateTimeStr_File = "2019-12-16 11:10:11"
361 #endDateTimeStr_File = "2019-12-16 11:10:11"
362 endDateTimeStr_File = time_str[-1][-1].decode('UTF-8').split('.')[0]
362 endDateTimeStr_File = time_str[-1][-1].decode('UTF-8').split('.')[0]
363 junk = time.strptime(endDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
363 junk = time.strptime(endDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
364 endDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
364 endDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
365
365
366 fp.close()
366 fp.close()
367
367
368 #print("check time", startDateTime_File)
368 #print("check time", startDateTime_File)
369 if self.timezone == 'lt':
369 if self.timezone == 'lt':
370 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
370 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
371 endDateTime_File = endDateTime_File - datetime.timedelta(minutes = 300)
371 endDateTime_File = endDateTime_File - datetime.timedelta(minutes = 300)
372 if (startDateTime_File >=startDateTime_Reader and endDateTime_File<=endDateTime_Reader):
372 if (startDateTime_File >=startDateTime_Reader and endDateTime_File<=endDateTime_Reader):
373 filter_filenameList.append(filename)
373 filter_filenameList.append(filename)
374
374
375 if (startDateTime_File>endDateTime_Reader):
375 if (startDateTime_File>endDateTime_Reader):
376 break
376 break
377 except Exception as e:
377 except Exception as e:
378 log.warning("Error opening file {} -> {}".format(os.path.split(filename)[1],e))
378 log.warning("Error opening file {} -> {}".format(os.path.split(filename)[1],e))
379
379
380 filter_filenameList.sort()
380 filter_filenameList.sort()
381 self.filenameList = filter_filenameList
381 self.filenameList = filter_filenameList
382
382
383 return 1
383 return 1
384
384
385 def __filterByGlob1(self, dirName):
385 def __filterByGlob1(self, dirName):
386 filter_files = glob.glob1(dirName, '*.*%s'%self.extension_file)
386 filter_files = glob.glob1(dirName, '*.*%s'%self.extension_file)
387 filter_files.sort()
387 filter_files.sort()
388 filterDict = {}
388 filterDict = {}
389 filterDict.setdefault(dirName)
389 filterDict.setdefault(dirName)
390 filterDict[dirName] = filter_files
390 filterDict[dirName] = filter_files
391 return filterDict
391 return filterDict
392
392
393 def __getFilenameList(self, fileListInKeys, dirList):
393 def __getFilenameList(self, fileListInKeys, dirList):
394 for value in fileListInKeys:
394 for value in fileListInKeys:
395 dirName = list(value.keys())[0]
395 dirName = list(value.keys())[0]
396 for file in value[dirName]:
396 for file in value[dirName]:
397 filename = os.path.join(dirName, file)
397 filename = os.path.join(dirName, file)
398 self.filenameList.append(filename)
398 self.filenameList.append(filename)
399
399
400
400
401 def __selectDataForTimes(self, online=False):
401 def __selectDataForTimes(self, online=False):
402 #aun no esta implementado el filtro for tiempo-> implementado en readNextFile
402 #aun no esta implementado el filtro for tiempo-> implementado en readNextFile
403 if not(self.status):
403 if not(self.status):
404 return None
404 return None
405
405
406 dirList = [os.path.join(self.path,x) for x in self.dirnameList]
406 dirList = [os.path.join(self.path,x) for x in self.dirnameList]
407 fileListInKeys = [self.__filterByGlob1(x) for x in dirList]
407 fileListInKeys = [self.__filterByGlob1(x) for x in dirList]
408 self.__getFilenameList(fileListInKeys, dirList)
408 self.__getFilenameList(fileListInKeys, dirList)
409 if not(online):
409 if not(online):
410 #filtro por tiempo
410 #filtro por tiempo
411 if not(self.all):
411 if not(self.all):
412 self.__getTimeFromData()
412 self.__getTimeFromData()
413
413
414 if len(self.filenameList)>0:
414 if len(self.filenameList)>0:
415 self.status = 1
415 self.status = 1
416 self.filenameList.sort()
416 self.filenameList.sort()
417 else:
417 else:
418 self.status = 0
418 self.status = 0
419 return None
419 return None
420
420
421 else:
421 else:
422 #get the last file - 1
422 #get the last file - 1
423 self.filenameList = [self.filenameList[-2]]
423 self.filenameList = [self.filenameList[-2]]
424 new_dirnameList = []
424 new_dirnameList = []
425 for dirname in self.dirnameList:
425 for dirname in self.dirnameList:
426 junk = numpy.array([dirname in x for x in self.filenameList])
426 junk = numpy.array([dirname in x for x in self.filenameList])
427 junk_sum = junk.sum()
427 junk_sum = junk.sum()
428 if junk_sum > 0:
428 if junk_sum > 0:
429 new_dirnameList.append(dirname)
429 new_dirnameList.append(dirname)
430 self.dirnameList = new_dirnameList
430 self.dirnameList = new_dirnameList
431 return 1
431 return 1
432
432
433 def searchFilesOnLine(self, path, startDate, endDate, startTime=datetime.time(0,0,0),
433 def searchFilesOnLine(self, path, startDate, endDate, startTime=datetime.time(0,0,0),
434 endTime=datetime.time(23,59,59),walk=True):
434 endTime=datetime.time(23,59,59),walk=True):
435
435
436 if endDate ==None:
436 if endDate ==None:
437 startDate = datetime.datetime.utcnow().date()
437 startDate = datetime.datetime.utcnow().date()
438 endDate = datetime.datetime.utcnow().date()
438 endDate = datetime.datetime.utcnow().date()
439
439
440 self.__setParameters(path=path, startDate=startDate, endDate=endDate,startTime = startTime,endTime=endTime, walk=walk)
440 self.__setParameters(path=path, startDate=startDate, endDate=endDate,startTime = startTime,endTime=endTime, walk=walk)
441
441
442 self.__checkPath()
442 self.__checkPath()
443
443
444 self.__findDataForDates(online=True)
444 self.__findDataForDates(online=True)
445
445
446 self.dirnameList = [self.dirnameList[-1]]
446 self.dirnameList = [self.dirnameList[-1]]
447
447
448 self.__selectDataForTimes(online=True)
448 self.__selectDataForTimes(online=True)
449
449
450 return
450 return
451
451
452
452
453 def searchFilesOffLine(self,
453 def searchFilesOffLine(self,
454 path,
454 path,
455 startDate,
455 startDate,
456 endDate,
456 endDate,
457 startTime=datetime.time(0,0,0),
457 startTime=datetime.time(0,0,0),
458 endTime=datetime.time(23,59,59),
458 endTime=datetime.time(23,59,59),
459 walk=True):
459 walk=True):
460
460
461 self.__setParameters(path, startDate, endDate, startTime, endTime, walk)
461 self.__setParameters(path, startDate, endDate, startTime, endTime, walk)
462
462
463 self.__checkPath()
463 self.__checkPath()
464
464
465 self.__findDataForDates()
465 self.__findDataForDates()
466
466
467 self.__selectDataForTimes()
467 self.__selectDataForTimes()
468
468
469 for i in range(len(self.filenameList)):
469 for i in range(len(self.filenameList)):
470 print("%s" %(self.filenameList[i]))
470 print("%s" %(self.filenameList[i]))
471
471
472 return
472 return
473
473
474 def __setNextFileOffline(self):
474 def __setNextFileOffline(self):
475
475
476 try:
476 try:
477 self.filename = self.filenameList[self.fileIndex]
477 self.filename = self.filenameList[self.fileIndex]
478 self.amisrFilePointer = h5py.File(self.filename,'r')
478 self.amisrFilePointer = h5py.File(self.filename,'r')
479 self.fileIndex += 1
479 self.fileIndex += 1
480 except:
480 except:
481 self.flagNoMoreFiles = 1
481 self.flagNoMoreFiles = 1
482 raise schainpy.admin.SchainError('No more files to read')
482 raise schainpy.admin.SchainError('No more files to read')
483 return 0
483 return 0
484
484
485 self.flagIsNewFile = 1
485 self.flagIsNewFile = 1
486 print("Setting the file: %s"%self.filename)
486 print("Setting the file: %s"%self.filename)
487
487
488 return 1
488 return 1
489
489
490
490
491 def __setNextFileOnline(self):
491 def __setNextFileOnline(self):
492 filename = self.filenameList[0]
492 filename = self.filenameList[0]
493 if self.__filename_online != None:
493 if self.__filename_online != None:
494 self.__selectDataForTimes(online=True)
494 self.__selectDataForTimes(online=True)
495 filename = self.filenameList[0]
495 filename = self.filenameList[0]
496 wait = 0
496 wait = 0
497 self.__waitForNewFile=300 ## DEBUG:
497 self.__waitForNewFile=300 ## DEBUG:
498 while self.__filename_online == filename:
498 while self.__filename_online == filename:
499 print('waiting %d seconds to get a new file...'%(self.__waitForNewFile))
499 print('waiting %d seconds to get a new file...'%(self.__waitForNewFile))
500 if wait == 5:
500 if wait == 5:
501 self.flagNoMoreFiles = 1
501 self.flagNoMoreFiles = 1
502 return 0
502 return 0
503 sleep(self.__waitForNewFile)
503 sleep(self.__waitForNewFile)
504 self.__selectDataForTimes(online=True)
504 self.__selectDataForTimes(online=True)
505 filename = self.filenameList[0]
505 filename = self.filenameList[0]
506 wait += 1
506 wait += 1
507
507
508 self.__filename_online = filename
508 self.__filename_online = filename
509
509
510 self.amisrFilePointer = h5py.File(filename,'r')
510 self.amisrFilePointer = h5py.File(filename,'r')
511 self.flagIsNewFile = 1
511 self.flagIsNewFile = 1
512 self.filename = filename
512 self.filename = filename
513 print("Setting the file: %s"%self.filename)
513 print("Setting the file: %s"%self.filename)
514 return 1
514 return 1
515
515
516
516
517 def readData(self):
517 def readData(self):
518 buffer = self.amisrFilePointer.get('Raw11/Data/Samples/Data')
518 buffer = self.amisrFilePointer.get('Raw11/Data/Samples/Data')
519 re = buffer[:,:,:,0]
519 re = buffer[:,:,:,0]
520 im = buffer[:,:,:,1]
520 im = buffer[:,:,:,1]
521 dataset = re + im*1j
521 dataset = re + im*1j
522
522
523 self.radacTime = self.amisrFilePointer.get('Raw11/Data/RadacHeader/RadacTime')
523 self.radacTime = self.amisrFilePointer.get('Raw11/Data/RadacHeader/RadacTime')
524 timeset = self.radacTime[:,0]
524 timeset = self.radacTime[:,0]
525
525
526 return dataset,timeset
526 return dataset,timeset
527
527
528 def reshapeData(self):
528 def reshapeData(self):
529 #print(self.beamCodeByPulse, self.beamCode, self.nblocks, self.nprofiles, self.nsa)
529 #print(self.beamCodeByPulse, self.beamCode, self.nblocks, self.nprofiles, self.nsa)
530 channels = self.beamCodeByPulse[0,:]
530 channels = self.beamCodeByPulse[0,:]
531 nchan = self.nchannels
531 nchan = self.nchannels
532 #self.newProfiles = self.nprofiles/nchan #must be defined on filljroheader
532 #self.newProfiles = self.nprofiles/nchan #must be defined on filljroheader
533 nblocks = self.nblocks
533 nblocks = self.nblocks
534 nsamples = self.nsa
534 nsamples = self.nsa
535 #print("Channels: ",self.nChannels)
535 #print("Channels: ",self.nChannels)
536 #Dimensions : nChannels, nProfiles, nSamples
536 #Dimensions : nChannels, nProfiles, nSamples
537 new_block = numpy.empty((nblocks, nchan, numpy.int_(self.newProfiles), nsamples), dtype="complex64")
537 new_block = numpy.empty((nblocks, nchan, numpy.int_(self.newProfiles), nsamples), dtype="complex64")
538 ############################################
538 ############################################
539 profPerCH = int(self.profPerBlockRAW / (self.nFFT* self.nChannels))
539 profPerCH = int(self.profPerBlockRAW / (self.nFFT* self.nChannels))
540 #profPerCH = int(self.profPerBlockRAW / self.nChannels)
540 #profPerCH = int(self.profPerBlockRAW / self.nChannels)
541 for thisChannel in range(nchan):
541 for thisChannel in range(nchan):
542
542
543 ich = thisChannel
543 ich = thisChannel
544
544
545 idx_ch = [self.nFFT*(ich + nchan*k) for k in range(profPerCH)]
545 idx_ch = [self.nFFT*(ich + nchan*k) for k in range(profPerCH)]
546 #print(idx_ch)
546 #print(idx_ch)
547 if self.nFFT > 1:
547 if self.nFFT > 1:
548 aux = [numpy.arange(i, i+self.nFFT) for i in idx_ch]
548 aux = [numpy.arange(i, i+self.nFFT) for i in idx_ch]
549 idx_ch = None
549 idx_ch = None
550 idx_ch =aux
550 idx_ch =aux
551 idx_ch = numpy.array(idx_ch, dtype=int).flatten()
551 idx_ch = numpy.array(idx_ch, dtype=int).flatten()
552 else:
552 else:
553 idx_ch = numpy.array(idx_ch, dtype=int)
553 idx_ch = numpy.array(idx_ch, dtype=int)
554
554
555 #print(ich,profPerCH,idx_ch)
555 #print(ich,profPerCH,idx_ch)
556 #print(numpy.where(channels==self.beamCode[ich])[0])
556 #print(numpy.where(channels==self.beamCode[ich])[0])
557 #new_block[:,ich,:,:] = self.dataset[:,numpy.where(channels==self.beamCode[ich])[0],:]
557 #new_block[:,ich,:,:] = self.dataset[:,numpy.where(channels==self.beamCode[ich])[0],:]
558 new_block[:,ich,:,:] = self.dataset[:,idx_ch,:]
558 new_block[:,ich,:,:] = self.dataset[:,idx_ch,:]
559
559
560 new_block = numpy.transpose(new_block, (1,0,2,3))
560 new_block = numpy.transpose(new_block, (1,0,2,3))
561 new_block = numpy.reshape(new_block, (nchan,-1, nsamples))
561 new_block = numpy.reshape(new_block, (nchan,-1, nsamples))
562 if self.flagAsync:
562 if self.flagAsync:
563 new_block = numpy.roll(new_block, self.shiftChannels, axis=0)
563 new_block = numpy.roll(new_block, self.shiftChannels, axis=0)
564 return new_block
564 return new_block
565
565
566 def updateIndexes(self):
566 def updateIndexes(self):
567
567
568 pass
568 pass
569
569
570 def fillJROHeader(self):
570 def fillJROHeader(self):
571
571
572 #fill radar controller header
572 #fill radar controller header
573
573
574 #fill system header
574 #fill system header
575 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
575 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
576 nProfiles=self.newProfiles,
576 nProfiles=self.newProfiles,
577 nChannels=len(self.__channelList),
577 nChannels=len(self.__channelList),
578 adcResolution=14,
578 adcResolution=14,
579 pciDioBusWidth=32)
579 pciDioBusWidth=32)
580
580
581 self.dataOut.type = "Voltage"
581 self.dataOut.type = "Voltage"
582 self.dataOut.data = None
582 self.dataOut.data = None
583 self.dataOut.dtype = numpy.dtype([('real','<i8'),('imag','<i8')])
583 self.dataOut.dtype = numpy.dtype([('real','<i8'),('imag','<i8')])
584 # self.dataOut.nChannels = 0
584 # self.dataOut.nChannels = 0
585
585
586 # self.dataOut.nHeights = 0
586 # self.dataOut.nHeights = 0
587
587
588 self.dataOut.nProfiles = self.newProfiles*self.nblocks
588 self.dataOut.nProfiles = self.newProfiles*self.nblocks
589 #self.dataOut.heightList = self.__firstHeigth + numpy.arange(self.__nSamples, dtype = numpy.float)*self.__deltaHeigth
589 #self.dataOut.heightList = self.__firstHeigth + numpy.arange(self.__nSamples, dtype = numpy.float)*self.__deltaHeigth
590 ranges = numpy.reshape(self.rangeFromFile[()],(-1))
590 ranges = numpy.reshape(self.rangeFromFile[()],(-1))
591 self.dataOut.heightList = ranges/1000.0 #km
591 self.dataOut.heightList = ranges/1000.0 #km
592 self.dataOut.channelList = self.__channelList
592 self.dataOut.channelList = self.__channelList
593
593
594 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
594 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
595
595
596 # self.dataOut.channelIndexList = None
596 # self.dataOut.channelIndexList = None
597
597
598
598
599 # #self.dataOut.azimuthList = numpy.roll( numpy.array(self.azimuthList) ,self.shiftChannels)
599 # #self.dataOut.azimuthList = numpy.roll( numpy.array(self.azimuthList) ,self.shiftChannels)
600 # #self.dataOut.elevationList = numpy.roll(numpy.array(self.elevationList) ,self.shiftChannels)
600 # #self.dataOut.elevationList = numpy.roll(numpy.array(self.elevationList) ,self.shiftChannels)
601 # #self.dataOut.codeList = numpy.roll(numpy.array(self.beamCode), self.shiftChannels)
601 # #self.dataOut.codeList = numpy.roll(numpy.array(self.beamCode), self.shiftChannels)
602
602
603 self.dataOut.azimuthList = self.azimuthList
603 self.dataOut.azimuthList = self.azimuthList
604 self.dataOut.elevationList = self.elevationList
604 self.dataOut.elevationList = self.elevationList
605 self.dataOut.codeList = self.beamCode
605 self.dataOut.codeList = self.beamCode
606
606
607
607
608
608
609 #print(self.dataOut.elevationList)
609 #print(self.dataOut.elevationList)
610 self.dataOut.flagNoData = True
610 self.dataOut.flagNoData = True
611
611
612 #Set to TRUE if the data is discontinuous
612 #Set to TRUE if the data is discontinuous
613 self.dataOut.flagDiscontinuousBlock = False
613 self.dataOut.flagDiscontinuousBlock = False
614
614
615 self.dataOut.utctime = None
615 self.dataOut.utctime = None
616
616
617 #self.dataOut.timeZone = -5 #self.__timezone/60 #timezone like jroheader, difference in minutes between UTC and localtime
617 #self.dataOut.timeZone = -5 #self.__timezone/60 #timezone like jroheader, difference in minutes between UTC and localtime
618 if self.timezone == 'lt':
618 if self.timezone == 'lt':
619 self.dataOut.timeZone = time.timezone / 60. #get the timezone in minutes
619 self.dataOut.timeZone = time.timezone / 60. #get the timezone in minutes
620 else:
620 else:
621 self.dataOut.timeZone = 0 #by default time is UTC
621 self.dataOut.timeZone = 0 #by default time is UTC
622
622
623 self.dataOut.dstFlag = 0
623 self.dataOut.dstFlag = 0
624 self.dataOut.errorCount = 0
624 self.dataOut.errorCount = 0
625 self.dataOut.nCohInt = 1
625 self.dataOut.nCohInt = 1
626 self.dataOut.flagDecodeData = False #asumo que la data esta decodificada
626 self.dataOut.flagDecodeData = False #asumo que la data esta decodificada
627 self.dataOut.flagDeflipData = False #asumo que la data esta sin flip
627 self.dataOut.flagDeflipData = False #asumo que la data esta sin flip
628 self.dataOut.flagShiftFFT = False
628 self.dataOut.flagShiftFFT = False
629 self.dataOut.ippSeconds = self.ippSeconds
629 self.dataOut.ippSeconds = self.ippSeconds
630 self.dataOut.ipp = self.__ippKm
630 self.dataOut.ipp = self.__ippKm
631 self.dataOut.nCode = self.__nCode
631 self.dataOut.nCode = self.__nCode
632 self.dataOut.code = self.__code
632 self.dataOut.code = self.__code
633 self.dataOut.nBaud = self.__nBaud
633 self.dataOut.nBaud = self.__nBaud
634
634
635
635
636 self.dataOut.frequency = self.__frequency
636 self.dataOut.frequency = self.__frequency
637 self.dataOut.realtime = self.online
637 self.dataOut.realtime = self.online
638
638
639 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(ipp=self.__ippKm,
639 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(ipp=self.__ippKm,
640 txA=self.__txAKm,
640 txA=self.__txAKm,
641 txB=0,
641 txB=0,
642 nWindows=1,
642 nWindows=1,
643 nHeights=self.__nSamples,
643 nHeights=self.__nSamples,
644 firstHeight=self.__firstHeight,
644 firstHeight=self.__firstHeight,
645 codeType=self.__codeType,
645 codeType=self.__codeType,
646 nCode=self.__nCode, nBaud=self.__nBaud,
646 nCode=self.__nCode, nBaud=self.__nBaud,
647 code = self.__code,
647 code = self.__code,
648 nOsamp=self.nOsamp,
648 nOsamp=self.nOsamp,
649 frequency = self.__frequency,
649 frequency = self.__frequency,
650 sampleRate= self.__sampleRate,
650 sampleRate= self.__sampleRate,
651 fClock=self.__sampleRate)
651 fClock=self.__sampleRate)
652
652
653
653
654 self.dataOut.radarControllerHeaderObj.heightList = ranges/1000.0 #km
654 self.dataOut.radarControllerHeaderObj.heightList = ranges/1000.0 #km
655 self.dataOut.radarControllerHeaderObj.heightResolution = self.__deltaHeight
655 self.dataOut.radarControllerHeaderObj.heightResolution = self.__deltaHeight
656 self.dataOut.radarControllerHeaderObj.rangeIpp = self.__ippKm #km
656 self.dataOut.radarControllerHeaderObj.rangeIpp = self.__ippKm #km
657 self.dataOut.radarControllerHeaderObj.rangeTxA = self.__txA*1e6*.15 #km
657 self.dataOut.radarControllerHeaderObj.rangeTxA = self.__txA*1e6*.15 #km
658 self.dataOut.radarControllerHeaderObj.nChannels = self.nchannels
658 self.dataOut.radarControllerHeaderObj.nChannels = self.nchannels
659 self.dataOut.radarControllerHeaderObj.channelList = self.__channelList
659 self.dataOut.radarControllerHeaderObj.channelList = self.__channelList
660 self.dataOut.radarControllerHeaderObj.azimuthList = self.azimuthList
660 self.dataOut.radarControllerHeaderObj.azimuthList = self.azimuthList
661 self.dataOut.radarControllerHeaderObj.elevationList = self.elevationList
661 self.dataOut.radarControllerHeaderObj.elevationList = self.elevationList
662 self.dataOut.radarControllerHeaderObj.dtype = "Voltage"
662 self.dataOut.radarControllerHeaderObj.dtype = "Voltage"
663 self.dataOut.ippSeconds = self.ippSeconds
663 self.dataOut.ippSeconds = self.ippSeconds
664 self.dataOut.ippFactor = self.nFFT
664 self.dataOut.ippFactor = self.nFFT
665 pass
665 pass
666
666
667 def readNextFile(self,online=False):
667 def readNextFile(self,online=False):
668
668
669 if not(online):
669 if not(online):
670 newFile = self.__setNextFileOffline()
670 newFile = self.__setNextFileOffline()
671 else:
671 else:
672 newFile = self.__setNextFileOnline()
672 newFile = self.__setNextFileOnline()
673
673
674 if not(newFile):
674 if not(newFile):
675 self.dataOut.error = True
675 self.dataOut.error = True
676 return 0
676 return 0
677
677
678 if not self.readAMISRHeader(self.amisrFilePointer):
678 if not self.readAMISRHeader(self.amisrFilePointer):
679 self.dataOut.error = True
679 self.dataOut.error = True
680 return 0
680 return 0
681
681
682 #self.createBuffers()
682 #self.createBuffers()
683 self.fillJROHeader()
683 self.fillJROHeader()
684
684
685 #self.__firstFile = False
685 #self.__firstFile = False
686
686
687 self.dataset,self.timeset = self.readData()
687 self.dataset,self.timeset = self.readData()
688
689 if self.endDate!=None:
688 if self.endDate!=None:
690 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
689 endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime)
691 time_str = self.amisrFilePointer.get('Time/RadacTimeString')
690 time_str = self.amisrFilePointer.get('Time/RadacTimeString')
692 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
691 startDateTimeStr_File = time_str[0][0].decode('UTF-8').split('.')[0]
693 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
692 junk = time.strptime(startDateTimeStr_File, '%Y-%m-%d %H:%M:%S')
694 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
693 startDateTime_File = datetime.datetime(junk.tm_year,junk.tm_mon,junk.tm_mday,junk.tm_hour, junk.tm_min, junk.tm_sec)
695 if self.timezone == 'lt':
694 if self.timezone == 'lt':
696 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
695 startDateTime_File = startDateTime_File - datetime.timedelta(minutes = 300)
697 if (startDateTime_File>endDateTime_Reader):
696 if (startDateTime_File>endDateTime_Reader):
698 self.flag_standby = False
697 self.flag_standby = False
699 return 0
698 return 0
700 if self.flag_ignoreFiles and (startDateTime_File >= self.ignStartDateTime and startDateTime_File <= self.ignEndDateTime):
699 if self.flag_ignoreFiles and (startDateTime_File >= self.ignStartDateTime and startDateTime_File <= self.ignEndDateTime):
701 print("Ignoring...")
700 print("Ignoring...")
702 self.flag_standby = True
701 self.flag_standby = True
702 self.profileIndex = 99999999999999999
703 return 1
703 return 1
704 self.flag_standby = False
704 self.flag_standby = False
705
705
706 self.jrodataset = self.reshapeData()
706 self.jrodataset = self.reshapeData()
707 #----self.updateIndexes()
707 #----self.updateIndexes()
708 self.profileIndex = 0
708 self.profileIndex = 0
709
709
710 return 1
710 return 1
711
711
712
712
713 def __hasNotDataInBuffer(self):
713 def __hasNotDataInBuffer(self):
714 if self.profileIndex >= (self.newProfiles*self.nblocks):
714 if self.profileIndex >= (self.newProfiles*self.nblocks):
715 return 1
715 return 1
716 return 0
716 return 0
717
717
718
718
719 def getData(self):
719 def getData(self):
720
720
721 if self.flagNoMoreFiles:
721 if self.flagNoMoreFiles:
722 self.dataOut.flagNoData = True
722 self.dataOut.flagNoData = True
723 return 0
723 return 0
724
725 if self.profileIndex >= (self.newProfiles*self.nblocks): #
724 if self.profileIndex >= (self.newProfiles*self.nblocks): #
726 #if self.__hasNotDataInBuffer():
725 #if self.__hasNotDataInBuffer():
727 if not (self.readNextFile(self.online)):
726 if not (self.readNextFile(self.online)):
728 print("Profile Index break...")
727 print("Profile Index break...")
729 return 0
728 return 0
730
729
731 if self.flag_standby: #Standby mode, if files are being ignoring, just return with no error flag
730 if self.flag_standby: #Standby mode, if files are being ignoring, just return with no error flag
732 return 0
731 return 0
733
732
734 if self.dataset is None: # setear esta condicion cuando no hayan datos por leer
733 if self.dataset is None: # setear esta condicion cuando no hayan datos por leer
735 self.dataOut.flagNoData = True
734 self.dataOut.flagNoData = True
736 print("No more data break...")
735 print("No more data break...")
737 return 0
736 return 0
738
737
739 #self.dataOut.data = numpy.reshape(self.jrodataset[self.profileIndex,:],(1,-1))
738 #self.dataOut.data = numpy.reshape(self.jrodataset[self.profileIndex,:],(1,-1))
740
739
741 self.dataOut.data = self.jrodataset[:,self.profileIndex,:]
740 self.dataOut.data = self.jrodataset[:,self.profileIndex,:]
742
741
743 #print("R_t",self.timeset)
742 #print("R_t",self.timeset)
744
743
745 #self.dataOut.utctime = self.jrotimeset[self.profileIndex]
744 #self.dataOut.utctime = self.jrotimeset[self.profileIndex]
746 #verificar basic header de jro data y ver si es compatible con este valor
745 #verificar basic header de jro data y ver si es compatible con este valor
747 #self.dataOut.utctime = self.timeset + (self.profileIndex * self.ippSeconds * self.nchannels)
746 #self.dataOut.utctime = self.timeset + (self.profileIndex * self.ippSeconds * self.nchannels)
748 indexprof = numpy.mod(self.profileIndex, self.newProfiles)
747 indexprof = numpy.mod(self.profileIndex, self.newProfiles)
749 indexblock = self.profileIndex/self.newProfiles
748 indexblock = self.profileIndex/self.newProfiles
750 #print (indexblock, indexprof)
749 #print (indexblock, indexprof)
751 diffUTC = 0
750 diffUTC = 0
752 t_comp = (indexprof * self.ippSeconds * self.nchannels) + diffUTC #
751 t_comp = (indexprof * self.ippSeconds * self.nchannels) + diffUTC #
753
752
754 #print("utc :",indexblock," __ ",t_comp)
753 #print("utc :",indexblock," __ ",t_comp)
755 #print(numpy.shape(self.timeset))
754 #print(numpy.shape(self.timeset))
756 self.dataOut.utctime = self.timeset[numpy.int_(indexblock)] + t_comp
755 self.dataOut.utctime = self.timeset[numpy.int_(indexblock)] + t_comp
757 #self.dataOut.utctime = self.timeset[self.profileIndex] + t_comp
756 #self.dataOut.utctime = self.timeset[self.profileIndex] + t_comp
758
757
759 self.dataOut.profileIndex = self.profileIndex
758 self.dataOut.profileIndex = self.profileIndex
760 #print("N profile:",self.profileIndex,self.newProfiles,self.nblocks,self.dataOut.utctime)
759 #print("N profile:",self.profileIndex,self.newProfiles,self.nblocks,self.dataOut.utctime)
761 self.dataOut.flagNoData = False
760 self.dataOut.flagNoData = False
762 # if indexprof == 0:
761 # if indexprof == 0:
763 # print("kamisr: ",self.dataOut.utctime)
762 # print("kamisr: ",self.dataOut.utctime)
764
763
765 self.profileIndex += 1
764 self.profileIndex += 1
766
765
767 return self.dataOut.data #retorno necesario??
766 return self.dataOut.data #retorno necesario??
768
767
769
768
770 def run(self, **kwargs):
769 def run(self, **kwargs):
771 '''
770 '''
772 This method will be called many times so here you should put all your code
771 This method will be called many times so here you should put all your code
773 '''
772 '''
774 #print("running kamisr")
773 #print("running kamisr")
775 if not self.isConfig:
774 if not self.isConfig:
776 self.setup(**kwargs)
775 self.setup(**kwargs)
777 self.isConfig = True
776 self.isConfig = True
778
777
779 self.getData()
778 self.getData()
@@ -1,1735 +1,1737
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Spectra processing Unit and operations
5 """Spectra processing Unit and operations
6
6
7 Here you will find the processing unit `SpectraProc` and several operations
7 Here you will find the processing unit `SpectraProc` and several operations
8 to work with Spectra data type
8 to work with Spectra data type
9 """
9 """
10
10
11 import time
11 import time
12 import itertools
12 import itertools
13
13
14 import numpy
14 import numpy
15
15
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
17 from schainpy.model.data.jrodata import Spectra
17 from schainpy.model.data.jrodata import Spectra
18 from schainpy.model.data.jrodata import hildebrand_sekhon
18 from schainpy.model.data.jrodata import hildebrand_sekhon
19 from schainpy.model.data import _noise
19 from schainpy.model.data import _noise
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import matplotlib.pyplot as plt
21 import matplotlib.pyplot as plt
22 from schainpy.model.io.utilsIO import getHei_index
22 from schainpy.model.io.utilsIO import getHei_index
23 import datetime
23 import datetime
24
24
25 class SpectraProc(ProcessingUnit):
25 class SpectraProc(ProcessingUnit):
26
26
27 def __init__(self):
27 def __init__(self):
28
28
29 ProcessingUnit.__init__(self)
29 ProcessingUnit.__init__(self)
30
30
31 self.buffer = None
31 self.buffer = None
32 self.firstdatatime = None
32 self.firstdatatime = None
33 self.profIndex = 0
33 self.profIndex = 0
34 self.dataOut = Spectra()
34 self.dataOut = Spectra()
35 self.dataOut.error=False
35 self.id_min = None
36 self.id_min = None
36 self.id_max = None
37 self.id_max = None
37 self.setupReq = False #Agregar a todas las unidades de proc
38 self.setupReq = False #Agregar a todas las unidades de proc
38 self.nsamplesFFT = 0
39 self.nsamplesFFT = 0
39
40
40 def __updateSpecFromVoltage(self):
41 def __updateSpecFromVoltage(self):
41
42
42 self.dataOut.timeZone = self.dataIn.timeZone
43 self.dataOut.timeZone = self.dataIn.timeZone
43 self.dataOut.dstFlag = self.dataIn.dstFlag
44 self.dataOut.dstFlag = self.dataIn.dstFlag
44 self.dataOut.errorCount = self.dataIn.errorCount
45 self.dataOut.errorCount = self.dataIn.errorCount
45 self.dataOut.useLocalTime = self.dataIn.useLocalTime
46 self.dataOut.useLocalTime = self.dataIn.useLocalTime
46 try:
47 try:
47 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
48 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
48 except:
49 except:
49 pass
50 pass
50 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
51 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
51 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
52 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
52 self.dataOut.ippSeconds = self.dataIn.ippSeconds
53 self.dataOut.ippSeconds = self.dataIn.ippSeconds
53 self.dataOut.ipp = self.dataIn.ipp
54 self.dataOut.ipp = self.dataIn.ipp
54 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
55 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
55 self.dataOut.channelList = self.dataIn.channelList
56 self.dataOut.channelList = self.dataIn.channelList
56 self.dataOut.heightList = self.dataIn.heightList
57 self.dataOut.heightList = self.dataIn.heightList
57 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
58 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
58 self.dataOut.nProfiles = self.dataOut.nFFTPoints
59 self.dataOut.nProfiles = self.dataOut.nFFTPoints
59 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
60 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
60 self.dataOut.utctime = self.firstdatatime
61 self.dataOut.utctime = self.firstdatatime
61 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
62 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
62 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
63 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
63 self.dataOut.flagShiftFFT = False
64 self.dataOut.flagShiftFFT = False
64 self.dataOut.nCohInt = self.dataIn.nCohInt
65 self.dataOut.nCohInt = self.dataIn.nCohInt
65 self.dataOut.nIncohInt = 1
66 self.dataOut.nIncohInt = 1
66 self.dataOut.deltaHeight = self.dataIn.deltaHeight
67 self.dataOut.deltaHeight = self.dataIn.deltaHeight
67 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
68 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
68 self.dataOut.frequency = self.dataIn.frequency
69 self.dataOut.frequency = self.dataIn.frequency
69 self.dataOut.realtime = self.dataIn.realtime
70 self.dataOut.realtime = self.dataIn.realtime
70 self.dataOut.azimuth = self.dataIn.azimuth
71 self.dataOut.azimuth = self.dataIn.azimuth
71 self.dataOut.zenith = self.dataIn.zenith
72 self.dataOut.zenith = self.dataIn.zenith
72 self.dataOut.codeList = self.dataIn.codeList
73 self.dataOut.codeList = self.dataIn.codeList
73 self.dataOut.azimuthList = self.dataIn.azimuthList
74 self.dataOut.azimuthList = self.dataIn.azimuthList
74 self.dataOut.elevationList = self.dataIn.elevationList
75 self.dataOut.elevationList = self.dataIn.elevationList
75 self.dataOut.code = self.dataIn.code
76 self.dataOut.code = self.dataIn.code
76 self.dataOut.nCode = self.dataIn.nCode
77 self.dataOut.nCode = self.dataIn.nCode
77 self.dataOut.flagProfilesByRange = self.dataIn.flagProfilesByRange
78 self.dataOut.flagProfilesByRange = self.dataIn.flagProfilesByRange
78 self.dataOut.nProfilesByRange = self.dataIn.nProfilesByRange
79 self.dataOut.nProfilesByRange = self.dataIn.nProfilesByRange
79 self.dataOut.runNextUnit = self.dataIn.runNextUnit
80 self.dataOut.runNextUnit = self.dataIn.runNextUnit
80 try:
81 try:
81 self.dataOut.step = self.dataIn.step
82 self.dataOut.step = self.dataIn.step
82 except:
83 except:
83 pass
84 pass
84
85
85 def __getFft(self):
86 def __getFft(self):
86 """
87 """
87 Convierte valores de Voltaje a Spectra
88 Convierte valores de Voltaje a Spectra
88
89
89 Affected:
90 Affected:
90 self.dataOut.data_spc
91 self.dataOut.data_spc
91 self.dataOut.data_cspc
92 self.dataOut.data_cspc
92 self.dataOut.data_dc
93 self.dataOut.data_dc
93 self.dataOut.heightList
94 self.dataOut.heightList
94 self.profIndex
95 self.profIndex
95 self.buffer
96 self.buffer
96 self.dataOut.flagNoData
97 self.dataOut.flagNoData
97 """
98 """
98 fft_volt = numpy.fft.fft(
99 fft_volt = numpy.fft.fft(
99 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
100 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
100 fft_volt = fft_volt.astype(numpy.dtype('complex'))
101 fft_volt = fft_volt.astype(numpy.dtype('complex'))
101 dc = fft_volt[:, 0, :]
102 dc = fft_volt[:, 0, :]
102
103
103 # calculo de self-spectra
104 # calculo de self-spectra
104 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
105 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
105 spc = fft_volt * numpy.conjugate(fft_volt)
106 spc = fft_volt * numpy.conjugate(fft_volt)
106 spc = spc.real
107 spc = spc.real
107
108
108 blocksize = 0
109 blocksize = 0
109 blocksize += dc.size
110 blocksize += dc.size
110 blocksize += spc.size
111 blocksize += spc.size
111
112
112 cspc = None
113 cspc = None
113 pairIndex = 0
114 pairIndex = 0
114 if self.dataOut.pairsList != None:
115 if self.dataOut.pairsList != None:
115 # calculo de cross-spectra
116 # calculo de cross-spectra
116 cspc = numpy.zeros(
117 cspc = numpy.zeros(
117 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
118 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
118 for pair in self.dataOut.pairsList:
119 for pair in self.dataOut.pairsList:
119 if pair[0] not in self.dataOut.channelList:
120 if pair[0] not in self.dataOut.channelList:
120 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
121 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
121 str(pair), str(self.dataOut.channelList)))
122 str(pair), str(self.dataOut.channelList)))
122 if pair[1] not in self.dataOut.channelList:
123 if pair[1] not in self.dataOut.channelList:
123 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
124 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
124 str(pair), str(self.dataOut.channelList)))
125 str(pair), str(self.dataOut.channelList)))
125
126
126 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
127 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
127 numpy.conjugate(fft_volt[pair[1], :, :])
128 numpy.conjugate(fft_volt[pair[1], :, :])
128 pairIndex += 1
129 pairIndex += 1
129 blocksize += cspc.size
130 blocksize += cspc.size
130
131
131 self.dataOut.data_spc = spc
132 self.dataOut.data_spc = spc
132 self.dataOut.data_cspc = cspc
133 self.dataOut.data_cspc = cspc
133 self.dataOut.data_dc = dc
134 self.dataOut.data_dc = dc
134 self.dataOut.blockSize = blocksize
135 self.dataOut.blockSize = blocksize
135 self.dataOut.flagShiftFFT = False
136 self.dataOut.flagShiftFFT = False
136
137
137 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False,
138 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False,
138 zeroPad=False, zeroPoints=0, runNextUnit = 0):
139 zeroPad=False, zeroPoints=0, runNextUnit=0):
139
140 self.dataIn.runNextUnit = runNextUnit
140 self.dataIn.runNextUnit = runNextUnit
141 try:
141 try:
142 type = self.dataIn.type.decode("utf-8")
142 type = self.dataIn.type.decode("utf-8")
143 self.dataIn.type = type
143 self.dataIn.type = type
144 except:
144 except Exception as e:
145 # print("spc -> ",e)
145 pass
146 pass
146
147
147 if self.dataIn.type == "Spectra":
148 if self.dataIn.type == "Spectra":
149 #print("AQUI")
148 try:
150 try:
149 self.dataOut.copy(self.dataIn)
151 self.dataOut.copy(self.dataIn)
150 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
152 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
151 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
153 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
152 self.dataOut.nProfiles = self.dataOut.nFFTPoints
154 self.dataOut.nProfiles = self.dataOut.nFFTPoints
153 #self.dataOut.nHeights = len(self.dataOut.heightList)
155 #self.dataOut.nHeights = len(self.dataOut.heightList)
154 except Exception as e:
156 except Exception as e:
155 print("Error dataIn ",e)
157 print("Error dataIn ",e)
156
158
157 if shift_fft:
159 if shift_fft:
158 #desplaza a la derecha en el eje 2 determinadas posiciones
160 #desplaza a la derecha en el eje 2 determinadas posiciones
159 shift = int(self.dataOut.nFFTPoints/2)
161 shift = int(self.dataOut.nFFTPoints/2)
160 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
162 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
161
163
162 if self.dataOut.data_cspc is not None:
164 if self.dataOut.data_cspc is not None:
163 #desplaza a la derecha en el eje 2 determinadas posiciones
165 #desplaza a la derecha en el eje 2 determinadas posiciones
164 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
166 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
165 if pairsList:
167 if pairsList:
166 self.__selectPairs(pairsList)
168 self.__selectPairs(pairsList)
167
169
168 elif self.dataIn.type == "Voltage":
170 elif self.dataIn.type == "Voltage":
169
171
170 self.dataOut.flagNoData = True
172 self.dataOut.flagNoData = True
171 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
173 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
172 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
174 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
173
175
174 if nFFTPoints == None:
176 if nFFTPoints == None:
175 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
177 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
176
178
177 if nProfiles == None:
179 if nProfiles == None:
178 nProfiles = nFFTPoints
180 nProfiles = nFFTPoints
179
181
180 if ippFactor == None:
182 if ippFactor == None:
181 self.dataOut.ippFactor = self.dataIn.ippFactor
183 self.dataOut.ippFactor = self.dataIn.ippFactor
182 else:
184 else:
183 self.dataOut.ippFactor = ippFactor
185 self.dataOut.ippFactor = ippFactor
184
186
185 if self.buffer is None:
187 if self.buffer is None:
186 if not zeroPad:
188 if not zeroPad:
187 self.buffer = numpy.zeros((self.dataIn.nChannels,
189 self.buffer = numpy.zeros((self.dataIn.nChannels,
188 nProfiles,
190 nProfiles,
189 self.dataIn.nHeights),
191 self.dataIn.nHeights),
190 dtype='complex')
192 dtype='complex')
191 zeroPoints = 0
193 zeroPoints = 0
192 else:
194 else:
193 self.buffer = numpy.zeros((self.dataIn.nChannels,
195 self.buffer = numpy.zeros((self.dataIn.nChannels,
194 nFFTPoints+int(zeroPoints),
196 nFFTPoints+int(zeroPoints),
195 self.dataIn.nHeights),
197 self.dataIn.nHeights),
196 dtype='complex')
198 dtype='complex')
197
199
198 self.dataOut.nFFTPoints = nFFTPoints
200 self.dataOut.nFFTPoints = nFFTPoints
199
201
200 if self.buffer is None:
202 if self.buffer is None:
201 self.buffer = numpy.zeros((self.dataIn.nChannels,
203 self.buffer = numpy.zeros((self.dataIn.nChannels,
202 nProfiles,
204 nProfiles,
203 self.dataIn.nHeights),
205 self.dataIn.nHeights),
204 dtype='complex')
206 dtype='complex')
205
207
206 if self.dataIn.flagDataAsBlock:
208 if self.dataIn.flagDataAsBlock:
207 nVoltProfiles = self.dataIn.data.shape[1]
209 nVoltProfiles = self.dataIn.data.shape[1]
208 zeroPoints = 0
210 zeroPoints = 0
209 if nVoltProfiles == nProfiles or zeroPad:
211 if nVoltProfiles == nProfiles or zeroPad:
210 self.buffer = self.dataIn.data.copy()
212 self.buffer = self.dataIn.data.copy()
211 self.profIndex = nVoltProfiles
213 self.profIndex = nVoltProfiles
212
214
213 elif nVoltProfiles < nProfiles:
215 elif nVoltProfiles < nProfiles:
214
216
215 if self.profIndex == 0:
217 if self.profIndex == 0:
216 self.id_min = 0
218 self.id_min = 0
217 self.id_max = nVoltProfiles
219 self.id_max = nVoltProfiles
218
220
219 self.buffer[:, self.id_min:self.id_max,
221 self.buffer[:, self.id_min:self.id_max,
220 :] = self.dataIn.data
222 :] = self.dataIn.data
221 self.profIndex += nVoltProfiles
223 self.profIndex += nVoltProfiles
222 self.id_min += nVoltProfiles
224 self.id_min += nVoltProfiles
223 self.id_max += nVoltProfiles
225 self.id_max += nVoltProfiles
224 elif nVoltProfiles > nProfiles:
226 elif nVoltProfiles > nProfiles:
225 self.reader.bypass = True
227 self.reader.bypass = True
226 if self.profIndex == 0:
228 if self.profIndex == 0:
227 self.id_min = 0
229 self.id_min = 0
228 self.id_max = nProfiles
230 self.id_max = nProfiles
229
231
230 self.buffer = self.dataIn.data[:, self.id_min:self.id_max,:]
232 self.buffer = self.dataIn.data[:, self.id_min:self.id_max,:]
231 self.profIndex += nProfiles
233 self.profIndex += nProfiles
232 self.id_min += nProfiles
234 self.id_min += nProfiles
233 self.id_max += nProfiles
235 self.id_max += nProfiles
234 if self.id_max == nVoltProfiles:
236 if self.id_max == nVoltProfiles:
235 self.reader.bypass = False
237 self.reader.bypass = False
236
238
237 else:
239 else:
238 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
240 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
239 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
241 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
240 self.dataOut.flagNoData = True
242 self.dataOut.flagNoData = True
241 else:
243 else:
242 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
244 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
243 self.profIndex += 1
245 self.profIndex += 1
244
246
245 if self.firstdatatime == None:
247 if self.firstdatatime == None:
246 self.firstdatatime = self.dataIn.utctime
248 self.firstdatatime = self.dataIn.utctime
247
249
248 if self.profIndex == nProfiles or (zeroPad and zeroPoints==0):
250 if self.profIndex == nProfiles or (zeroPad and zeroPoints==0):
249
251
250 self.__updateSpecFromVoltage()
252 self.__updateSpecFromVoltage()
251 if pairsList == None:
253 if pairsList == None:
252 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
254 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
253 else:
255 else:
254 self.dataOut.pairsList = pairsList
256 self.dataOut.pairsList = pairsList
255 self.__getFft()
257 self.__getFft()
256 self.dataOut.flagNoData = False
258 self.dataOut.flagNoData = False
257 self.firstdatatime = None
259 self.firstdatatime = None
258 self.nsamplesFFT = self.profIndex
260 self.nsamplesFFT = self.profIndex
259 #if not self.reader.bypass:
261 #if not self.reader.bypass:
260 self.profIndex = 0
262 self.profIndex = 0
261 #update Processing Header:
263 #update Processing Header:
262 self.dataOut.processingHeaderObj.dtype = "Spectra"
264 self.dataOut.processingHeaderObj.dtype = "Spectra"
263 self.dataOut.processingHeaderObj.nFFTPoints = self.dataOut.nFFTPoints
265 self.dataOut.processingHeaderObj.nFFTPoints = self.dataOut.nFFTPoints
264 self.dataOut.processingHeaderObj.nSamplesFFT = self.nsamplesFFT
266 self.dataOut.processingHeaderObj.nSamplesFFT = self.nsamplesFFT
265 self.dataOut.processingHeaderObj.nIncohInt = 1
267 self.dataOut.processingHeaderObj.nIncohInt = 1
266
268
267 elif self.dataIn.type == "Parameters": #when get data from h5 spc file
269 elif self.dataIn.type == "Parameters": #when get data from h5 spc file
268
270
269 self.dataOut.data_spc = self.dataIn.data_spc
271 self.dataOut.data_spc = self.dataIn.data_spc
270 self.dataOut.data_cspc = self.dataIn.data_cspc
272 self.dataOut.data_cspc = self.dataIn.data_cspc
271 self.dataOut.data_outlier = self.dataIn.data_outlier
273 self.dataOut.data_outlier = self.dataIn.data_outlier
272 self.dataOut.nProfiles = self.dataIn.nProfiles
274 self.dataOut.nProfiles = self.dataIn.nProfiles
273 self.dataOut.nIncohInt = self.dataIn.nIncohInt
275 self.dataOut.nIncohInt = self.dataIn.nIncohInt
274 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
276 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
275 self.dataOut.ippFactor = self.dataIn.ippFactor
277 self.dataOut.ippFactor = self.dataIn.ippFactor
276 self.dataOut.max_nIncohInt = self.dataIn.max_nIncohInt
278 self.dataOut.max_nIncohInt = self.dataIn.max_nIncohInt
277 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
279 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
278 self.dataOut.ProcessingHeader = self.dataIn.ProcessingHeader.copy()
280 self.dataOut.ProcessingHeader = self.dataIn.ProcessingHeader.copy()
279 self.dataOut.ippSeconds = self.dataIn.ippSeconds
281 self.dataOut.ippSeconds = self.dataIn.ippSeconds
280 self.dataOut.ipp = self.dataIn.ipp
282 self.dataOut.ipp = self.dataIn.ipp
281 #self.dataOut.abscissaList = self.dataIn.getVelRange(1)
283 #self.dataOut.abscissaList = self.dataIn.getVelRange(1)
282 #self.dataOut.spc_noise = self.dataIn.getNoise()
284 #self.dataOut.spc_noise = self.dataIn.getNoise()
283 #self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
285 #self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
284 # self.dataOut.normFactor = self.dataIn.normFactor
286 # self.dataOut.normFactor = self.dataIn.normFactor
285 if hasattr(self.dataIn, 'channelList'):
287 if hasattr(self.dataIn, 'channelList'):
286 self.dataOut.channelList = self.dataIn.channelList
288 self.dataOut.channelList = self.dataIn.channelList
287 if hasattr(self.dataIn, 'pairsList'):
289 if hasattr(self.dataIn, 'pairsList'):
288 self.dataOut.pairsList = self.dataIn.pairsList
290 self.dataOut.pairsList = self.dataIn.pairsList
289 self.dataOut.groupList = self.dataIn.pairsList
291 self.dataOut.groupList = self.dataIn.pairsList
290
292
291 self.dataOut.flagNoData = False
293 self.dataOut.flagNoData = False
292
294
293 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
295 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
294 self.dataOut.ChanDist = self.dataIn.ChanDist
296 self.dataOut.ChanDist = self.dataIn.ChanDist
295 else: self.dataOut.ChanDist = None
297 else: self.dataOut.ChanDist = None
296
298
297 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
299 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
298 # self.dataOut.VelRange = self.dataIn.VelRange
300 # self.dataOut.VelRange = self.dataIn.VelRange
299 #else: self.dataOut.VelRange = None
301 #else: self.dataOut.VelRange = None
300
302
301 else:
303 else:
302 raise ValueError("The type of input object '%s' is not valid".format(
304 raise ValueError("The type of input object '%s' is not valid".format(
303 self.dataIn.type))
305 self.dataIn.type))
304
306 # print("SPC done")
305
307
306 def __selectPairs(self, pairsList):
308 def __selectPairs(self, pairsList):
307
309
308 if not pairsList:
310 if not pairsList:
309 return
311 return
310
312
311 pairs = []
313 pairs = []
312 pairsIndex = []
314 pairsIndex = []
313
315
314 for pair in pairsList:
316 for pair in pairsList:
315 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
317 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
316 continue
318 continue
317 pairs.append(pair)
319 pairs.append(pair)
318 pairsIndex.append(pairs.index(pair))
320 pairsIndex.append(pairs.index(pair))
319
321
320 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
322 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
321 self.dataOut.pairsList = pairs
323 self.dataOut.pairsList = pairs
322
324
323 return
325 return
324
326
325 def selectFFTs(self, minFFT, maxFFT ):
327 def selectFFTs(self, minFFT, maxFFT ):
326 """
328 """
327 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
329 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
328 minFFT<= FFT <= maxFFT
330 minFFT<= FFT <= maxFFT
329 """
331 """
330
332
331 if (minFFT > maxFFT):
333 if (minFFT > maxFFT):
332 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
334 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
333
335
334 if (minFFT < self.dataOut.getFreqRange()[0]):
336 if (minFFT < self.dataOut.getFreqRange()[0]):
335 minFFT = self.dataOut.getFreqRange()[0]
337 minFFT = self.dataOut.getFreqRange()[0]
336
338
337 if (maxFFT > self.dataOut.getFreqRange()[-1]):
339 if (maxFFT > self.dataOut.getFreqRange()[-1]):
338 maxFFT = self.dataOut.getFreqRange()[-1]
340 maxFFT = self.dataOut.getFreqRange()[-1]
339
341
340 minIndex = 0
342 minIndex = 0
341 maxIndex = 0
343 maxIndex = 0
342 FFTs = self.dataOut.getFreqRange()
344 FFTs = self.dataOut.getFreqRange()
343
345
344 inda = numpy.where(FFTs >= minFFT)
346 inda = numpy.where(FFTs >= minFFT)
345 indb = numpy.where(FFTs <= maxFFT)
347 indb = numpy.where(FFTs <= maxFFT)
346
348
347 try:
349 try:
348 minIndex = inda[0][0]
350 minIndex = inda[0][0]
349 except:
351 except:
350 minIndex = 0
352 minIndex = 0
351
353
352 try:
354 try:
353 maxIndex = indb[0][-1]
355 maxIndex = indb[0][-1]
354 except:
356 except:
355 maxIndex = len(FFTs)
357 maxIndex = len(FFTs)
356
358
357 self.selectFFTsByIndex(minIndex, maxIndex)
359 self.selectFFTsByIndex(minIndex, maxIndex)
358
360
359 return 1
361 return 1
360
362
361 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
363 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
362 newheis = numpy.where(
364 newheis = numpy.where(
363 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
365 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
364
366
365 if hei_ref != None:
367 if hei_ref != None:
366 newheis = numpy.where(self.dataOut.heightList > hei_ref)
368 newheis = numpy.where(self.dataOut.heightList > hei_ref)
367
369
368 minIndex = min(newheis[0])
370 minIndex = min(newheis[0])
369 maxIndex = max(newheis[0])
371 maxIndex = max(newheis[0])
370 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
372 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
371 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
373 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
372
374
373 # determina indices
375 # determina indices
374 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
376 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
375 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
377 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
376 avg_dB = 10 * \
378 avg_dB = 10 * \
377 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
379 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
378 beacon_dB = numpy.sort(avg_dB)[-nheis:]
380 beacon_dB = numpy.sort(avg_dB)[-nheis:]
379 beacon_heiIndexList = []
381 beacon_heiIndexList = []
380 for val in avg_dB.tolist():
382 for val in avg_dB.tolist():
381 if val >= beacon_dB[0]:
383 if val >= beacon_dB[0]:
382 beacon_heiIndexList.append(avg_dB.tolist().index(val))
384 beacon_heiIndexList.append(avg_dB.tolist().index(val))
383
385
384 data_cspc = None
386 data_cspc = None
385 if self.dataOut.data_cspc is not None:
387 if self.dataOut.data_cspc is not None:
386 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
388 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
387
389
388 data_dc = None
390 data_dc = None
389 if self.dataOut.data_dc is not None:
391 if self.dataOut.data_dc is not None:
390 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
392 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
391
393
392 self.dataOut.data_spc = data_spc
394 self.dataOut.data_spc = data_spc
393 self.dataOut.data_cspc = data_cspc
395 self.dataOut.data_cspc = data_cspc
394 self.dataOut.data_dc = data_dc
396 self.dataOut.data_dc = data_dc
395 self.dataOut.heightList = heightList
397 self.dataOut.heightList = heightList
396 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
398 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
397
399
398 return 1
400 return 1
399
401
400 def selectFFTsByIndex(self, minIndex, maxIndex):
402 def selectFFTsByIndex(self, minIndex, maxIndex):
401 """
403 """
402
404
403 """
405 """
404
406
405 if (minIndex < 0) or (minIndex > maxIndex):
407 if (minIndex < 0) or (minIndex > maxIndex):
406 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
408 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
407
409
408 if (maxIndex >= self.dataOut.nProfiles):
410 if (maxIndex >= self.dataOut.nProfiles):
409 maxIndex = self.dataOut.nProfiles-1
411 maxIndex = self.dataOut.nProfiles-1
410
412
411 #Spectra
413 #Spectra
412 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
414 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
413
415
414 data_cspc = None
416 data_cspc = None
415 if self.dataOut.data_cspc is not None:
417 if self.dataOut.data_cspc is not None:
416 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
418 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
417
419
418 data_dc = None
420 data_dc = None
419 if self.dataOut.data_dc is not None:
421 if self.dataOut.data_dc is not None:
420 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
422 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
421
423
422 self.dataOut.data_spc = data_spc
424 self.dataOut.data_spc = data_spc
423 self.dataOut.data_cspc = data_cspc
425 self.dataOut.data_cspc = data_cspc
424 self.dataOut.data_dc = data_dc
426 self.dataOut.data_dc = data_dc
425
427
426 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
428 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
427 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
429 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
428 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
430 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
429
431
430 return 1
432 return 1
431
433
432 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
434 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
433 # validacion de rango
435 # validacion de rango
434 if minHei == None:
436 if minHei == None:
435 minHei = self.dataOut.heightList[0]
437 minHei = self.dataOut.heightList[0]
436
438
437 if maxHei == None:
439 if maxHei == None:
438 maxHei = self.dataOut.heightList[-1]
440 maxHei = self.dataOut.heightList[-1]
439
441
440 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
442 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
441 print('minHei: %.2f is out of the heights range' % (minHei))
443 print('minHei: %.2f is out of the heights range' % (minHei))
442 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
444 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
443 minHei = self.dataOut.heightList[0]
445 minHei = self.dataOut.heightList[0]
444
446
445 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
447 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
446 print('maxHei: %.2f is out of the heights range' % (maxHei))
448 print('maxHei: %.2f is out of the heights range' % (maxHei))
447 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
449 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
448 maxHei = self.dataOut.heightList[-1]
450 maxHei = self.dataOut.heightList[-1]
449
451
450 # validacion de velocidades
452 # validacion de velocidades
451 velrange = self.dataOut.getVelRange(1)
453 velrange = self.dataOut.getVelRange(1)
452
454
453 if minVel == None:
455 if minVel == None:
454 minVel = velrange[0]
456 minVel = velrange[0]
455
457
456 if maxVel == None:
458 if maxVel == None:
457 maxVel = velrange[-1]
459 maxVel = velrange[-1]
458
460
459 if (minVel < velrange[0]) or (minVel > maxVel):
461 if (minVel < velrange[0]) or (minVel > maxVel):
460 print('minVel: %.2f is out of the velocity range' % (minVel))
462 print('minVel: %.2f is out of the velocity range' % (minVel))
461 print('minVel is setting to %.2f' % (velrange[0]))
463 print('minVel is setting to %.2f' % (velrange[0]))
462 minVel = velrange[0]
464 minVel = velrange[0]
463
465
464 if (maxVel > velrange[-1]) or (maxVel < minVel):
466 if (maxVel > velrange[-1]) or (maxVel < minVel):
465 print('maxVel: %.2f is out of the velocity range' % (maxVel))
467 print('maxVel: %.2f is out of the velocity range' % (maxVel))
466 print('maxVel is setting to %.2f' % (velrange[-1]))
468 print('maxVel is setting to %.2f' % (velrange[-1]))
467 maxVel = velrange[-1]
469 maxVel = velrange[-1]
468
470
469 # seleccion de indices para rango
471 # seleccion de indices para rango
470 minIndex = 0
472 minIndex = 0
471 maxIndex = 0
473 maxIndex = 0
472 heights = self.dataOut.heightList
474 heights = self.dataOut.heightList
473
475
474 inda = numpy.where(heights >= minHei)
476 inda = numpy.where(heights >= minHei)
475 indb = numpy.where(heights <= maxHei)
477 indb = numpy.where(heights <= maxHei)
476
478
477 try:
479 try:
478 minIndex = inda[0][0]
480 minIndex = inda[0][0]
479 except:
481 except:
480 minIndex = 0
482 minIndex = 0
481
483
482 try:
484 try:
483 maxIndex = indb[0][-1]
485 maxIndex = indb[0][-1]
484 except:
486 except:
485 maxIndex = len(heights)
487 maxIndex = len(heights)
486
488
487 if (minIndex < 0) or (minIndex > maxIndex):
489 if (minIndex < 0) or (minIndex > maxIndex):
488 raise ValueError("some value in (%d,%d) is not valid" % (
490 raise ValueError("some value in (%d,%d) is not valid" % (
489 minIndex, maxIndex))
491 minIndex, maxIndex))
490
492
491 if (maxIndex >= self.dataOut.nHeights):
493 if (maxIndex >= self.dataOut.nHeights):
492 maxIndex = self.dataOut.nHeights - 1
494 maxIndex = self.dataOut.nHeights - 1
493
495
494 # seleccion de indices para velocidades
496 # seleccion de indices para velocidades
495 indminvel = numpy.where(velrange >= minVel)
497 indminvel = numpy.where(velrange >= minVel)
496 indmaxvel = numpy.where(velrange <= maxVel)
498 indmaxvel = numpy.where(velrange <= maxVel)
497 try:
499 try:
498 minIndexVel = indminvel[0][0]
500 minIndexVel = indminvel[0][0]
499 except:
501 except:
500 minIndexVel = 0
502 minIndexVel = 0
501
503
502 try:
504 try:
503 maxIndexVel = indmaxvel[0][-1]
505 maxIndexVel = indmaxvel[0][-1]
504 except:
506 except:
505 maxIndexVel = len(velrange)
507 maxIndexVel = len(velrange)
506
508
507 # seleccion del espectro
509 # seleccion del espectro
508 data_spc = self.dataOut.data_spc[:,
510 data_spc = self.dataOut.data_spc[:,
509 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
511 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
510 # estimacion de ruido
512 # estimacion de ruido
511 noise = numpy.zeros(self.dataOut.nChannels)
513 noise = numpy.zeros(self.dataOut.nChannels)
512
514
513 for channel in range(self.dataOut.nChannels):
515 for channel in range(self.dataOut.nChannels):
514 daux = data_spc[channel, :, :]
516 daux = data_spc[channel, :, :]
515 sortdata = numpy.sort(daux, axis=None)
517 sortdata = numpy.sort(daux, axis=None)
516 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
518 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
517
519
518 self.dataOut.noise_estimation = noise.copy()
520 self.dataOut.noise_estimation = noise.copy()
519
521
520 return 1
522 return 1
521
523
522 class GetSNR(Operation):
524 class GetSNR(Operation):
523 '''
525 '''
524 Written by R. Flores
526 Written by R. Flores
525 '''
527 '''
526 """Operation to get SNR.
528 """Operation to get SNR.
527
529
528 Parameters:
530 Parameters:
529 -----------
531 -----------
530
532
531 Example
533 Example
532 --------
534 --------
533
535
534 op = proc_unit.addOperation(name='GetSNR', optype='other')
536 op = proc_unit.addOperation(name='GetSNR', optype='other')
535
537
536 """
538 """
537
539
538 def __init__(self, **kwargs):
540 def __init__(self, **kwargs):
539
541
540 Operation.__init__(self, **kwargs)
542 Operation.__init__(self, **kwargs)
541
543
542 def run(self,dataOut):
544 def run(self,dataOut):
543
545
544 noise = dataOut.getNoise(ymin_index=-10) #RegiΓ³n superior donde solo deberΓ­a de haber ruido
546 noise = dataOut.getNoise(ymin_index=-10) #RegiΓ³n superior donde solo deberΓ­a de haber ruido
545 dataOut.data_snr = (dataOut.data_spc.sum(axis=1)-noise[:,None]*dataOut.nFFTPoints)/(noise[:,None]*dataOut.nFFTPoints) #It works apparently
547 dataOut.data_snr = (dataOut.data_spc.sum(axis=1)-noise[:,None]*dataOut.nFFTPoints)/(noise[:,None]*dataOut.nFFTPoints) #It works apparently
546 dataOut.snl = numpy.log10(dataOut.data_snr)
548 dataOut.snl = numpy.log10(dataOut.data_snr)
547 dataOut.snl = numpy.where(dataOut.data_snr<.01, numpy.nan, dataOut.snl)
549 dataOut.snl = numpy.where(dataOut.data_snr<.01, numpy.nan, dataOut.snl)
548
550
549 return dataOut
551 return dataOut
550
552
551 class removeDC(Operation):
553 class removeDC(Operation):
552
554
553 def run(self, dataOut, mode=2):
555 def run(self, dataOut, mode=2):
554 self.dataOut = dataOut
556 self.dataOut = dataOut
555 jspectra = self.dataOut.data_spc
557 jspectra = self.dataOut.data_spc
556 jcspectra = self.dataOut.data_cspc
558 jcspectra = self.dataOut.data_cspc
557
559
558 num_chan = jspectra.shape[0]
560 num_chan = jspectra.shape[0]
559 num_hei = jspectra.shape[2]
561 num_hei = jspectra.shape[2]
560
562
561 if jcspectra is not None:
563 if jcspectra is not None:
562 jcspectraExist = True
564 jcspectraExist = True
563 num_pairs = jcspectra.shape[0]
565 num_pairs = jcspectra.shape[0]
564 else:
566 else:
565 jcspectraExist = False
567 jcspectraExist = False
566
568
567 freq_dc = int(jspectra.shape[1] / 2)
569 freq_dc = int(jspectra.shape[1] / 2)
568 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
570 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
569 ind_vel = ind_vel.astype(int)
571 ind_vel = ind_vel.astype(int)
570
572
571 if ind_vel[0] < 0:
573 if ind_vel[0] < 0:
572 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
574 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
573
575
574 if mode == 1:
576 if mode == 1:
575 jspectra[:, freq_dc, :] = (
577 jspectra[:, freq_dc, :] = (
576 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
578 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
577
579
578 if jcspectraExist:
580 if jcspectraExist:
579 jcspectra[:, freq_dc, :] = (
581 jcspectra[:, freq_dc, :] = (
580 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
582 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
581
583
582 if mode == 2:
584 if mode == 2:
583
585
584 vel = numpy.array([-2, -1, 1, 2])
586 vel = numpy.array([-2, -1, 1, 2])
585 xx = numpy.zeros([4, 4])
587 xx = numpy.zeros([4, 4])
586
588
587 for fil in range(4):
589 for fil in range(4):
588 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
590 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
589
591
590 xx_inv = numpy.linalg.inv(xx)
592 xx_inv = numpy.linalg.inv(xx)
591 xx_aux = xx_inv[0, :]
593 xx_aux = xx_inv[0, :]
592
594
593 for ich in range(num_chan):
595 for ich in range(num_chan):
594 yy = jspectra[ich, ind_vel, :]
596 yy = jspectra[ich, ind_vel, :]
595 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
597 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
596
598
597 junkid = jspectra[ich, freq_dc, :] <= 0
599 junkid = jspectra[ich, freq_dc, :] <= 0
598 cjunkid = sum(junkid)
600 cjunkid = sum(junkid)
599
601
600 if cjunkid.any():
602 if cjunkid.any():
601 jspectra[ich, freq_dc, junkid.nonzero()] = (
603 jspectra[ich, freq_dc, junkid.nonzero()] = (
602 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
604 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
603
605
604 if jcspectraExist:
606 if jcspectraExist:
605 for ip in range(num_pairs):
607 for ip in range(num_pairs):
606 yy = jcspectra[ip, ind_vel, :]
608 yy = jcspectra[ip, ind_vel, :]
607 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
609 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
608
610
609 self.dataOut.data_spc = jspectra
611 self.dataOut.data_spc = jspectra
610 self.dataOut.data_cspc = jcspectra
612 self.dataOut.data_cspc = jcspectra
611
613
612 return self.dataOut
614 return self.dataOut
613 class getNoiseB(Operation):
615 class getNoiseB(Operation):
614 """
616 """
615 Get noise from custom heights and frequency ranges,
617 Get noise from custom heights and frequency ranges,
616 offset for additional manual correction
618 offset for additional manual correction
617 J. Apaza -> developed to amisr isr spectra
619 J. Apaza -> developed to amisr isr spectra
618
620
619 """
621 """
620 __slots__ =('offset','warnings', 'isConfig', 'minIndex','maxIndex','minIndexFFT','maxIndexFFT')
622 __slots__ =('offset','warnings', 'isConfig', 'minIndex','maxIndex','minIndexFFT','maxIndexFFT')
621 def __init__(self):
623 def __init__(self):
622
624
623 Operation.__init__(self)
625 Operation.__init__(self)
624 self.isConfig = False
626 self.isConfig = False
625
627
626 def setup(self, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
628 def setup(self, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
627
629
628 self.warnings = warnings
630 self.warnings = warnings
629 if minHei == None:
631 if minHei == None:
630 minHei = self.dataOut.heightList[0]
632 minHei = self.dataOut.heightList[0]
631
633
632 if maxHei == None:
634 if maxHei == None:
633 maxHei = self.dataOut.heightList[-1]
635 maxHei = self.dataOut.heightList[-1]
634
636
635 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
637 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
636 if self.warnings:
638 if self.warnings:
637 print('minHei: %.2f is out of the heights range' % (minHei))
639 print('minHei: %.2f is out of the heights range' % (minHei))
638 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
640 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
639 minHei = self.dataOut.heightList[0]
641 minHei = self.dataOut.heightList[0]
640
642
641 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
643 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
642 if self.warnings:
644 if self.warnings:
643 print('maxHei: %.2f is out of the heights range' % (maxHei))
645 print('maxHei: %.2f is out of the heights range' % (maxHei))
644 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
646 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
645 maxHei = self.dataOut.heightList[-1]
647 maxHei = self.dataOut.heightList[-1]
646
648
647
649
648 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
650 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
649 minIndexFFT = 0
651 minIndexFFT = 0
650 maxIndexFFT = 0
652 maxIndexFFT = 0
651 # validacion de velocidades
653 # validacion de velocidades
652 indminPoint = None
654 indminPoint = None
653 indmaxPoint = None
655 indmaxPoint = None
654 if self.dataOut.type == 'Spectra':
656 if self.dataOut.type == 'Spectra':
655 if minVel == None and maxVel == None :
657 if minVel == None and maxVel == None :
656
658
657 freqrange = self.dataOut.getFreqRange(1)
659 freqrange = self.dataOut.getFreqRange(1)
658
660
659 if minFreq == None:
661 if minFreq == None:
660 minFreq = freqrange[0]
662 minFreq = freqrange[0]
661
663
662 if maxFreq == None:
664 if maxFreq == None:
663 maxFreq = freqrange[-1]
665 maxFreq = freqrange[-1]
664
666
665 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
667 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
666 if self.warnings:
668 if self.warnings:
667 print('minFreq: %.2f is out of the frequency range' % (minFreq))
669 print('minFreq: %.2f is out of the frequency range' % (minFreq))
668 print('minFreq is setting to %.2f' % (freqrange[0]))
670 print('minFreq is setting to %.2f' % (freqrange[0]))
669 minFreq = freqrange[0]
671 minFreq = freqrange[0]
670
672
671 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
673 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
672 if self.warnings:
674 if self.warnings:
673 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
675 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
674 print('maxFreq is setting to %.2f' % (freqrange[-1]))
676 print('maxFreq is setting to %.2f' % (freqrange[-1]))
675 maxFreq = freqrange[-1]
677 maxFreq = freqrange[-1]
676
678
677 indminPoint = numpy.where(freqrange >= minFreq)
679 indminPoint = numpy.where(freqrange >= minFreq)
678 indmaxPoint = numpy.where(freqrange <= maxFreq)
680 indmaxPoint = numpy.where(freqrange <= maxFreq)
679
681
680 else:
682 else:
681
683
682 velrange = self.dataOut.getVelRange(1)
684 velrange = self.dataOut.getVelRange(1)
683
685
684 if minVel == None:
686 if minVel == None:
685 minVel = velrange[0]
687 minVel = velrange[0]
686
688
687 if maxVel == None:
689 if maxVel == None:
688 maxVel = velrange[-1]
690 maxVel = velrange[-1]
689
691
690 if (minVel < velrange[0]) or (minVel > maxVel):
692 if (minVel < velrange[0]) or (minVel > maxVel):
691 if self.warnings:
693 if self.warnings:
692 print('minVel: %.2f is out of the velocity range' % (minVel))
694 print('minVel: %.2f is out of the velocity range' % (minVel))
693 print('minVel is setting to %.2f' % (velrange[0]))
695 print('minVel is setting to %.2f' % (velrange[0]))
694 minVel = velrange[0]
696 minVel = velrange[0]
695
697
696 if (maxVel > velrange[-1]) or (maxVel < minVel):
698 if (maxVel > velrange[-1]) or (maxVel < minVel):
697 if self.warnings:
699 if self.warnings:
698 print('maxVel: %.2f is out of the velocity range' % (maxVel))
700 print('maxVel: %.2f is out of the velocity range' % (maxVel))
699 print('maxVel is setting to %.2f' % (velrange[-1]))
701 print('maxVel is setting to %.2f' % (velrange[-1]))
700 maxVel = velrange[-1]
702 maxVel = velrange[-1]
701
703
702 indminPoint = numpy.where(velrange >= minVel)
704 indminPoint = numpy.where(velrange >= minVel)
703 indmaxPoint = numpy.where(velrange <= maxVel)
705 indmaxPoint = numpy.where(velrange <= maxVel)
704
706
705
707
706 # seleccion de indices para rango REEMPLAZAR FOR FUNCION EXTERNA LUEGO
708 # seleccion de indices para rango REEMPLAZAR FOR FUNCION EXTERNA LUEGO
707 # minIndex = 0
709 # minIndex = 0
708 # maxIndex = 0
710 # maxIndex = 0
709 # heights = self.dataOut.heightList
711 # heights = self.dataOut.heightList
710 # inda = numpy.where(heights >= minHei)
712 # inda = numpy.where(heights >= minHei)
711 # indb = numpy.where(heights <= maxHei)
713 # indb = numpy.where(heights <= maxHei)
712 # try:
714 # try:
713 # minIndex = inda[0][0]
715 # minIndex = inda[0][0]
714 # except:
716 # except:
715 # minIndex = 0
717 # minIndex = 0
716 # try:
718 # try:
717 # maxIndex = indb[0][-1]
719 # maxIndex = indb[0][-1]
718 # except:
720 # except:
719 # maxIndex = len(heights)
721 # maxIndex = len(heights)
720 # if (minIndex < 0) or (minIndex > maxIndex):
722 # if (minIndex < 0) or (minIndex > maxIndex):
721 # raise ValueError("some value in (%d,%d) is not valid" % (
723 # raise ValueError("some value in (%d,%d) is not valid" % (
722 # minIndex, maxIndex))
724 # minIndex, maxIndex))
723 # if (maxIndex >= self.dataOut.nHeights):
725 # if (maxIndex >= self.dataOut.nHeights):
724 # maxIndex = self.dataOut.nHeights - 1
726 # maxIndex = self.dataOut.nHeights - 1
725
727
726 minIndex, maxIndex = getHei_index(minHei,maxHei,self.dataOut.heightList)
728 minIndex, maxIndex = getHei_index(minHei,maxHei,self.dataOut.heightList)
727
729
728
730
729 #############################################################3
731 #############################################################3
730 # seleccion de indices para velocidades
732 # seleccion de indices para velocidades
731 if self.dataOut.type == 'Spectra':
733 if self.dataOut.type == 'Spectra':
732 try:
734 try:
733 minIndexFFT = indminPoint[0][0]
735 minIndexFFT = indminPoint[0][0]
734 except:
736 except:
735 minIndexFFT = 0
737 minIndexFFT = 0
736
738
737 try:
739 try:
738 maxIndexFFT = indmaxPoint[0][-1]
740 maxIndexFFT = indmaxPoint[0][-1]
739 except:
741 except:
740 maxIndexFFT = len( self.dataOut.getFreqRange(1))
742 maxIndexFFT = len( self.dataOut.getFreqRange(1))
741
743
742 self.minIndex, self.maxIndex, self.minIndexFFT, self.maxIndexFFT = minIndex, maxIndex, minIndexFFT, maxIndexFFT
744 self.minIndex, self.maxIndex, self.minIndexFFT, self.maxIndexFFT = minIndex, maxIndex, minIndexFFT, maxIndexFFT
743 self.isConfig = True
745 self.isConfig = True
744 self.offset = 1
746 self.offset = 1
745 if offset!=None:
747 if offset!=None:
746 self.offset = 10**(offset/10)
748 self.offset = 10**(offset/10)
747
749
748
750
749 def run(self, dataOut, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
751 def run(self, dataOut, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
750 self.dataOut = dataOut
752 self.dataOut = dataOut
751
753
752 if not self.isConfig:
754 if not self.isConfig:
753 self.setup(offset, minHei, maxHei,minVel, maxVel, minFreq, maxFreq, warnings)
755 self.setup(offset, minHei, maxHei,minVel, maxVel, minFreq, maxFreq, warnings)
754
756
755 self.dataOut.noise_estimation = None
757 self.dataOut.noise_estimation = None
756 noise = None
758 noise = None
757 if self.dataOut.type == 'Voltage':
759 if self.dataOut.type == 'Voltage':
758 noise = self.dataOut.getNoise(ymin_index=self.minIndex, ymax_index=self.maxIndex)
760 noise = self.dataOut.getNoise(ymin_index=self.minIndex, ymax_index=self.maxIndex)
759 elif self.dataOut.type == 'Spectra':
761 elif self.dataOut.type == 'Spectra':
760 noise = numpy.zeros( self.dataOut.nChannels)
762 noise = numpy.zeros( self.dataOut.nChannels)
761 norm = 1
763 norm = 1
762
764
763 for channel in range( self.dataOut.nChannels):
765 for channel in range( self.dataOut.nChannels):
764 if not hasattr(self.dataOut.nIncohInt,'__len__'):
766 if not hasattr(self.dataOut.nIncohInt,'__len__'):
765 norm = 1
767 norm = 1
766 else:
768 else:
767 norm = self.dataOut.max_nIncohInt[channel]/self.dataOut.nIncohInt[channel, self.minIndex:self.maxIndex]
769 norm = self.dataOut.max_nIncohInt[channel]/self.dataOut.nIncohInt[channel, self.minIndex:self.maxIndex]
768
770
769 daux = self.dataOut.data_spc[channel,self.minIndexFFT:self.maxIndexFFT, self.minIndex:self.maxIndex]
771 daux = self.dataOut.data_spc[channel,self.minIndexFFT:self.maxIndexFFT, self.minIndex:self.maxIndex]
770 daux = numpy.multiply(daux, norm)
772 daux = numpy.multiply(daux, norm)
771 sortdata = numpy.sort(daux, axis=None)
773 sortdata = numpy.sort(daux, axis=None)
772 noise[channel] = _noise.hildebrand_sekhon(sortdata, self.dataOut.max_nIncohInt[channel])/self.offset
774 noise[channel] = _noise.hildebrand_sekhon(sortdata, self.dataOut.max_nIncohInt[channel])/self.offset
773
775
774 else:
776 else:
775 noise = self.dataOut.getNoise(xmin_index=self.minIndexFFT, xmax_index=self.maxIndexFFT, ymin_index=self.minIndex, ymax_index=self.maxIndex)
777 noise = self.dataOut.getNoise(xmin_index=self.minIndexFFT, xmax_index=self.maxIndexFFT, ymin_index=self.minIndex, ymax_index=self.maxIndex)
776
778
777 self.dataOut.noise_estimation = noise.copy() # dataOut.noise
779 self.dataOut.noise_estimation = noise.copy() # dataOut.noise
778
780
779 return self.dataOut
781 return self.dataOut
780
782
781 def getNoiseByMean(self,data):
783 def getNoiseByMean(self,data):
782 #data debe estar ordenado
784 #data debe estar ordenado
783 data = numpy.mean(data,axis=1)
785 data = numpy.mean(data,axis=1)
784 sortdata = numpy.sort(data, axis=None)
786 sortdata = numpy.sort(data, axis=None)
785 pnoise = None
787 pnoise = None
786 j = 0
788 j = 0
787
789
788 mean = numpy.mean(sortdata)
790 mean = numpy.mean(sortdata)
789 min = numpy.min(sortdata)
791 min = numpy.min(sortdata)
790 delta = mean - min
792 delta = mean - min
791 indexes = numpy.where(sortdata > (mean+delta))[0] #only array of indexes
793 indexes = numpy.where(sortdata > (mean+delta))[0] #only array of indexes
792 #print(len(indexes))
794 #print(len(indexes))
793 if len(indexes)==0:
795 if len(indexes)==0:
794 pnoise = numpy.mean(sortdata)
796 pnoise = numpy.mean(sortdata)
795 else:
797 else:
796 j = indexes[0]
798 j = indexes[0]
797 pnoise = numpy.mean(sortdata[0:j])
799 pnoise = numpy.mean(sortdata[0:j])
798
800
799 return pnoise
801 return pnoise
800
802
801 def getNoiseByHS(self,data, navg):
803 def getNoiseByHS(self,data, navg):
802 #data debe estar ordenado
804 #data debe estar ordenado
803 #data = numpy.mean(data,axis=1)
805 #data = numpy.mean(data,axis=1)
804 sortdata = numpy.sort(data, axis=None)
806 sortdata = numpy.sort(data, axis=None)
805
807
806 lenOfData = len(sortdata)
808 lenOfData = len(sortdata)
807 nums_min = lenOfData*0.2
809 nums_min = lenOfData*0.2
808
810
809 if nums_min <= 5:
811 if nums_min <= 5:
810
812
811 nums_min = 5
813 nums_min = 5
812
814
813 sump = 0.
815 sump = 0.
814 sumq = 0.
816 sumq = 0.
815
817
816 j = 0
818 j = 0
817 cont = 1
819 cont = 1
818
820
819 while((cont == 1)and(j < lenOfData)):
821 while((cont == 1)and(j < lenOfData)):
820
822
821 sump += sortdata[j]
823 sump += sortdata[j]
822 sumq += sortdata[j]**2
824 sumq += sortdata[j]**2
823 #sumq -= sump**2
825 #sumq -= sump**2
824 if j > nums_min:
826 if j > nums_min:
825 rtest = float(j)/(j-1) + 1.0/navg
827 rtest = float(j)/(j-1) + 1.0/navg
826 #if ((sumq*j) > (sump**2)):
828 #if ((sumq*j) > (sump**2)):
827 if ((sumq*j) > (rtest*sump**2)):
829 if ((sumq*j) > (rtest*sump**2)):
828 j = j - 1
830 j = j - 1
829 sump = sump - sortdata[j]
831 sump = sump - sortdata[j]
830 sumq = sumq - sortdata[j]**2
832 sumq = sumq - sortdata[j]**2
831 cont = 0
833 cont = 0
832
834
833 j += 1
835 j += 1
834
836
835 lnoise = sump / j
837 lnoise = sump / j
836
838
837 return lnoise
839 return lnoise
838
840
839 class removeInterference(Operation):
841 class removeInterference(Operation):
840
842
841 def removeInterference2(self):
843 def removeInterference2(self):
842
844
843 cspc = self.dataOut.data_cspc
845 cspc = self.dataOut.data_cspc
844 spc = self.dataOut.data_spc
846 spc = self.dataOut.data_spc
845 Heights = numpy.arange(cspc.shape[2])
847 Heights = numpy.arange(cspc.shape[2])
846 realCspc = numpy.abs(cspc)
848 realCspc = numpy.abs(cspc)
847
849
848 for i in range(cspc.shape[0]):
850 for i in range(cspc.shape[0]):
849 LinePower= numpy.sum(realCspc[i], axis=0)
851 LinePower= numpy.sum(realCspc[i], axis=0)
850 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
852 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
851 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
853 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
852 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
854 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
853 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
855 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
854 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
856 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
855
857
856
858
857 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
859 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
858 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
860 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
859 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
861 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
860 cspc[i,InterferenceRange,:] = numpy.NaN
862 cspc[i,InterferenceRange,:] = numpy.NaN
861
863
862 self.dataOut.data_cspc = cspc
864 self.dataOut.data_cspc = cspc
863
865
864 def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None):
866 def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None):
865
867
866 jspectra = self.dataOut.data_spc
868 jspectra = self.dataOut.data_spc
867 jcspectra = self.dataOut.data_cspc
869 jcspectra = self.dataOut.data_cspc
868 jnoise = self.dataOut.getNoise()
870 jnoise = self.dataOut.getNoise()
869 num_incoh = self.dataOut.nIncohInt
871 num_incoh = self.dataOut.nIncohInt
870
872
871 num_channel = jspectra.shape[0]
873 num_channel = jspectra.shape[0]
872 num_prof = jspectra.shape[1]
874 num_prof = jspectra.shape[1]
873 num_hei = jspectra.shape[2]
875 num_hei = jspectra.shape[2]
874
876
875 # hei_interf
877 # hei_interf
876 if hei_interf is None:
878 if hei_interf is None:
877 count_hei = int(num_hei / 2)
879 count_hei = int(num_hei / 2)
878 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
880 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
879 hei_interf = numpy.asarray(hei_interf)[0]
881 hei_interf = numpy.asarray(hei_interf)[0]
880 # nhei_interf
882 # nhei_interf
881 if (nhei_interf == None):
883 if (nhei_interf == None):
882 nhei_interf = 5
884 nhei_interf = 5
883 if (nhei_interf < 1):
885 if (nhei_interf < 1):
884 nhei_interf = 1
886 nhei_interf = 1
885 if (nhei_interf > count_hei):
887 if (nhei_interf > count_hei):
886 nhei_interf = count_hei
888 nhei_interf = count_hei
887 if (offhei_interf == None):
889 if (offhei_interf == None):
888 offhei_interf = 0
890 offhei_interf = 0
889
891
890 ind_hei = list(range(num_hei))
892 ind_hei = list(range(num_hei))
891 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
893 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
892 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
894 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
893 mask_prof = numpy.asarray(list(range(num_prof)))
895 mask_prof = numpy.asarray(list(range(num_prof)))
894 num_mask_prof = mask_prof.size
896 num_mask_prof = mask_prof.size
895 comp_mask_prof = [0, num_prof / 2]
897 comp_mask_prof = [0, num_prof / 2]
896
898
897 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
899 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
898 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
900 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
899 jnoise = numpy.nan
901 jnoise = numpy.nan
900 noise_exist = jnoise[0] < numpy.Inf
902 noise_exist = jnoise[0] < numpy.Inf
901
903
902 # Subrutina de Remocion de la Interferencia
904 # Subrutina de Remocion de la Interferencia
903 for ich in range(num_channel):
905 for ich in range(num_channel):
904 # Se ordena los espectros segun su potencia (menor a mayor)
906 # Se ordena los espectros segun su potencia (menor a mayor)
905 power = jspectra[ich, mask_prof, :]
907 power = jspectra[ich, mask_prof, :]
906 power = power[:, hei_interf]
908 power = power[:, hei_interf]
907 power = power.sum(axis=0)
909 power = power.sum(axis=0)
908 psort = power.ravel().argsort()
910 psort = power.ravel().argsort()
909
911
910 # Se estima la interferencia promedio en los Espectros de Potencia empleando
912 # Se estima la interferencia promedio en los Espectros de Potencia empleando
911 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
913 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
912 offhei_interf, nhei_interf + offhei_interf))]]]
914 offhei_interf, nhei_interf + offhei_interf))]]]
913
915
914 if noise_exist:
916 if noise_exist:
915 # tmp_noise = jnoise[ich] / num_prof
917 # tmp_noise = jnoise[ich] / num_prof
916 tmp_noise = jnoise[ich]
918 tmp_noise = jnoise[ich]
917 junkspc_interf = junkspc_interf - tmp_noise
919 junkspc_interf = junkspc_interf - tmp_noise
918 #junkspc_interf[:,comp_mask_prof] = 0
920 #junkspc_interf[:,comp_mask_prof] = 0
919
921
920 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
922 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
921 jspc_interf = jspc_interf.transpose()
923 jspc_interf = jspc_interf.transpose()
922 # Calculando el espectro de interferencia promedio
924 # Calculando el espectro de interferencia promedio
923 noiseid = numpy.where(
925 noiseid = numpy.where(
924 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
926 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
925 noiseid = noiseid[0]
927 noiseid = noiseid[0]
926 cnoiseid = noiseid.size
928 cnoiseid = noiseid.size
927 interfid = numpy.where(
929 interfid = numpy.where(
928 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
930 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
929 interfid = interfid[0]
931 interfid = interfid[0]
930 cinterfid = interfid.size
932 cinterfid = interfid.size
931
933
932 if (cnoiseid > 0):
934 if (cnoiseid > 0):
933 jspc_interf[noiseid] = 0
935 jspc_interf[noiseid] = 0
934
936
935 # Expandiendo los perfiles a limpiar
937 # Expandiendo los perfiles a limpiar
936 if (cinterfid > 0):
938 if (cinterfid > 0):
937 new_interfid = (
939 new_interfid = (
938 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
940 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
939 new_interfid = numpy.asarray(new_interfid)
941 new_interfid = numpy.asarray(new_interfid)
940 new_interfid = {x for x in new_interfid}
942 new_interfid = {x for x in new_interfid}
941 new_interfid = numpy.array(list(new_interfid))
943 new_interfid = numpy.array(list(new_interfid))
942 new_cinterfid = new_interfid.size
944 new_cinterfid = new_interfid.size
943 else:
945 else:
944 new_cinterfid = 0
946 new_cinterfid = 0
945
947
946 for ip in range(new_cinterfid):
948 for ip in range(new_cinterfid):
947 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
949 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
948 jspc_interf[new_interfid[ip]
950 jspc_interf[new_interfid[ip]
949 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
951 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
950
952
951 jspectra[ich, :, ind_hei] = jspectra[ich, :,
953 jspectra[ich, :, ind_hei] = jspectra[ich, :,
952 ind_hei] - jspc_interf # Corregir indices
954 ind_hei] - jspc_interf # Corregir indices
953
955
954 # Removiendo la interferencia del punto de mayor interferencia
956 # Removiendo la interferencia del punto de mayor interferencia
955 ListAux = jspc_interf[mask_prof].tolist()
957 ListAux = jspc_interf[mask_prof].tolist()
956 maxid = ListAux.index(max(ListAux))
958 maxid = ListAux.index(max(ListAux))
957
959
958 if cinterfid > 0:
960 if cinterfid > 0:
959 for ip in range(cinterfid * (interf == 2) - 1):
961 for ip in range(cinterfid * (interf == 2) - 1):
960 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
962 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
961 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
963 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
962 cind = len(ind)
964 cind = len(ind)
963
965
964 if (cind > 0):
966 if (cind > 0):
965 jspectra[ich, interfid[ip], ind] = tmp_noise * \
967 jspectra[ich, interfid[ip], ind] = tmp_noise * \
966 (1 + (numpy.random.uniform(cind) - 0.5) /
968 (1 + (numpy.random.uniform(cind) - 0.5) /
967 numpy.sqrt(num_incoh))
969 numpy.sqrt(num_incoh))
968
970
969 ind = numpy.array([-2, -1, 1, 2])
971 ind = numpy.array([-2, -1, 1, 2])
970 xx = numpy.zeros([4, 4])
972 xx = numpy.zeros([4, 4])
971
973
972 for id1 in range(4):
974 for id1 in range(4):
973 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
975 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
974
976
975 xx_inv = numpy.linalg.inv(xx)
977 xx_inv = numpy.linalg.inv(xx)
976 xx = xx_inv[:, 0]
978 xx = xx_inv[:, 0]
977 ind = (ind + maxid + num_mask_prof) % num_mask_prof
979 ind = (ind + maxid + num_mask_prof) % num_mask_prof
978 yy = jspectra[ich, mask_prof[ind], :]
980 yy = jspectra[ich, mask_prof[ind], :]
979 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
981 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
980 yy.transpose(), xx)
982 yy.transpose(), xx)
981
983
982 indAux = (jspectra[ich, :, :] < tmp_noise *
984 indAux = (jspectra[ich, :, :] < tmp_noise *
983 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
985 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
984 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
986 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
985 (1 - 1 / numpy.sqrt(num_incoh))
987 (1 - 1 / numpy.sqrt(num_incoh))
986
988
987 # Remocion de Interferencia en el Cross Spectra
989 # Remocion de Interferencia en el Cross Spectra
988 if jcspectra is None:
990 if jcspectra is None:
989 return jspectra, jcspectra
991 return jspectra, jcspectra
990 num_pairs = int(jcspectra.size / (num_prof * num_hei))
992 num_pairs = int(jcspectra.size / (num_prof * num_hei))
991 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
993 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
992
994
993 for ip in range(num_pairs):
995 for ip in range(num_pairs):
994
996
995 #-------------------------------------------
997 #-------------------------------------------
996
998
997 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
999 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
998 cspower = cspower[:, hei_interf]
1000 cspower = cspower[:, hei_interf]
999 cspower = cspower.sum(axis=0)
1001 cspower = cspower.sum(axis=0)
1000
1002
1001 cspsort = cspower.ravel().argsort()
1003 cspsort = cspower.ravel().argsort()
1002 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1004 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1003 offhei_interf, nhei_interf + offhei_interf))]]]
1005 offhei_interf, nhei_interf + offhei_interf))]]]
1004 junkcspc_interf = junkcspc_interf.transpose()
1006 junkcspc_interf = junkcspc_interf.transpose()
1005 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1007 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1006
1008
1007 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1009 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1008
1010
1009 median_real = int(numpy.median(numpy.real(
1011 median_real = int(numpy.median(numpy.real(
1010 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1012 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1011 median_imag = int(numpy.median(numpy.imag(
1013 median_imag = int(numpy.median(numpy.imag(
1012 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1014 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1013 comp_mask_prof = [int(e) for e in comp_mask_prof]
1015 comp_mask_prof = [int(e) for e in comp_mask_prof]
1014 junkcspc_interf[comp_mask_prof, :] = numpy.complex_(
1016 junkcspc_interf[comp_mask_prof, :] = numpy.complex_(
1015 median_real, median_imag)
1017 median_real, median_imag)
1016
1018
1017 for iprof in range(num_prof):
1019 for iprof in range(num_prof):
1018 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1020 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1019 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1021 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1020
1022
1021 # Removiendo la Interferencia
1023 # Removiendo la Interferencia
1022 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1024 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1023 :, ind_hei] - jcspc_interf
1025 :, ind_hei] - jcspc_interf
1024
1026
1025 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1027 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1026 maxid = ListAux.index(max(ListAux))
1028 maxid = ListAux.index(max(ListAux))
1027
1029
1028 ind = numpy.array([-2, -1, 1, 2])
1030 ind = numpy.array([-2, -1, 1, 2])
1029 xx = numpy.zeros([4, 4])
1031 xx = numpy.zeros([4, 4])
1030
1032
1031 for id1 in range(4):
1033 for id1 in range(4):
1032 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1034 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1033
1035
1034 xx_inv = numpy.linalg.inv(xx)
1036 xx_inv = numpy.linalg.inv(xx)
1035 xx = xx_inv[:, 0]
1037 xx = xx_inv[:, 0]
1036
1038
1037 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1039 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1038 yy = jcspectra[ip, mask_prof[ind], :]
1040 yy = jcspectra[ip, mask_prof[ind], :]
1039 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1041 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1040
1042
1041 # Guardar Resultados
1043 # Guardar Resultados
1042 self.dataOut.data_spc = jspectra
1044 self.dataOut.data_spc = jspectra
1043 self.dataOut.data_cspc = jcspectra
1045 self.dataOut.data_cspc = jcspectra
1044
1046
1045 return 1
1047 return 1
1046
1048
1047
1049
1048 def run(self, dataOut, interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None, mode=1):
1050 def run(self, dataOut, interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None, mode=1):
1049
1051
1050 self.dataOut = dataOut
1052 self.dataOut = dataOut
1051
1053
1052 if mode == 1:
1054 if mode == 1:
1053 self.removeInterference(interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None)
1055 self.removeInterference(interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None)
1054 elif mode == 2:
1056 elif mode == 2:
1055 self.removeInterference2()
1057 self.removeInterference2()
1056
1058
1057 return self.dataOut
1059 return self.dataOut
1058
1060
1059
1061
1060 class deflip(Operation):
1062 class deflip(Operation):
1061
1063
1062 def run(self, dataOut):
1064 def run(self, dataOut):
1063 # arreglo 1: (num_chan, num_profiles, num_heights)
1065 # arreglo 1: (num_chan, num_profiles, num_heights)
1064 self.dataOut = dataOut
1066 self.dataOut = dataOut
1065
1067
1066 # JULIA-oblicua, indice 2
1068 # JULIA-oblicua, indice 2
1067 # arreglo 2: (num_profiles, num_heights)
1069 # arreglo 2: (num_profiles, num_heights)
1068 jspectra = self.dataOut.data_spc[2]
1070 jspectra = self.dataOut.data_spc[2]
1069 jspectra_tmp=numpy.zeros(jspectra.shape)
1071 jspectra_tmp=numpy.zeros(jspectra.shape)
1070 num_profiles=jspectra.shape[0]
1072 num_profiles=jspectra.shape[0]
1071 freq_dc = int(num_profiles / 2)
1073 freq_dc = int(num_profiles / 2)
1072 # Flip con for
1074 # Flip con for
1073 for j in range(num_profiles):
1075 for j in range(num_profiles):
1074 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1076 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1075 # Intercambio perfil de DC con perfil inmediato anterior
1077 # Intercambio perfil de DC con perfil inmediato anterior
1076 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1078 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1077 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1079 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1078 # canal modificado es re-escrito en el arreglo de canales
1080 # canal modificado es re-escrito en el arreglo de canales
1079 self.dataOut.data_spc[2] = jspectra_tmp
1081 self.dataOut.data_spc[2] = jspectra_tmp
1080
1082
1081 return self.dataOut
1083 return self.dataOut
1082
1084
1083
1085
1084 class IncohInt(Operation):
1086 class IncohInt(Operation):
1085
1087
1086 __profIndex = 0
1088 __profIndex = 0
1087 __withOverapping = False
1089 __withOverapping = False
1088
1090
1089 __byTime = False
1091 __byTime = False
1090 __initime = None
1092 __initime = None
1091 __lastdatatime = None
1093 __lastdatatime = None
1092 __integrationtime = None
1094 __integrationtime = None
1093
1095
1094 __buffer_spc = None
1096 __buffer_spc = None
1095 __buffer_cspc = None
1097 __buffer_cspc = None
1096 __buffer_dc = None
1098 __buffer_dc = None
1097
1099
1098 __dataReady = False
1100 __dataReady = False
1099
1101
1100 __timeInterval = None
1102 __timeInterval = None
1101 incohInt = 0
1103 incohInt = 0
1102 nOutliers = 0
1104 nOutliers = 0
1103 n = None
1105 n = None
1104
1106
1105 _flagProfilesByRange = False
1107 _flagProfilesByRange = False
1106 _nProfilesByRange = 0
1108 _nProfilesByRange = 0
1107 def __init__(self):
1109 def __init__(self):
1108
1110
1109 Operation.__init__(self)
1111 Operation.__init__(self)
1110
1112
1111 def setup(self, n=None, timeInterval=None, overlapping=False):
1113 def setup(self, n=None, timeInterval=None, overlapping=False):
1112 """
1114 """
1113 Set the parameters of the integration class.
1115 Set the parameters of the integration class.
1114
1116
1115 Inputs:
1117 Inputs:
1116
1118
1117 n : Number of coherent integrations
1119 n : Number of coherent integrations
1118 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1120 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1119 overlapping :
1121 overlapping :
1120
1122
1121 """
1123 """
1122
1124
1123 self.__initime = None
1125 self.__initime = None
1124 self.__lastdatatime = 0
1126 self.__lastdatatime = 0
1125
1127
1126 self.__buffer_spc = 0
1128 self.__buffer_spc = 0
1127 self.__buffer_cspc = 0
1129 self.__buffer_cspc = 0
1128 self.__buffer_dc = 0
1130 self.__buffer_dc = 0
1129
1131
1130 self.__profIndex = 0
1132 self.__profIndex = 0
1131 self.__dataReady = False
1133 self.__dataReady = False
1132 self.__byTime = False
1134 self.__byTime = False
1133 self.incohInt = 0
1135 self.incohInt = 0
1134 self.nOutliers = 0
1136 self.nOutliers = 0
1135 if n is None and timeInterval is None:
1137 if n is None and timeInterval is None:
1136 raise ValueError("n or timeInterval should be specified ...")
1138 raise ValueError("n or timeInterval should be specified ...")
1137
1139
1138 if n is not None:
1140 if n is not None:
1139 self.n = int(n)
1141 self.n = int(n)
1140 else:
1142 else:
1141
1143
1142 self.__integrationtime = int(timeInterval)
1144 self.__integrationtime = int(timeInterval)
1143 self.n = None
1145 self.n = None
1144 self.__byTime = True
1146 self.__byTime = True
1145
1147
1146
1148
1147
1149
1148 def putData(self, data_spc, data_cspc, data_dc):
1150 def putData(self, data_spc, data_cspc, data_dc):
1149 """
1151 """
1150 Add a profile to the __buffer_spc and increase in one the __profileIndex
1152 Add a profile to the __buffer_spc and increase in one the __profileIndex
1151
1153
1152 """
1154 """
1153 if data_spc.all() == numpy.nan :
1155 if data_spc.all() == numpy.nan :
1154 print("nan ")
1156 print("nan ")
1155 return
1157 return
1156 self.__buffer_spc += data_spc
1158 self.__buffer_spc += data_spc
1157
1159
1158 if data_cspc is None:
1160 if data_cspc is None:
1159 self.__buffer_cspc = None
1161 self.__buffer_cspc = None
1160 else:
1162 else:
1161 self.__buffer_cspc += data_cspc
1163 self.__buffer_cspc += data_cspc
1162
1164
1163 if data_dc is None:
1165 if data_dc is None:
1164 self.__buffer_dc = None
1166 self.__buffer_dc = None
1165 else:
1167 else:
1166 self.__buffer_dc += data_dc
1168 self.__buffer_dc += data_dc
1167
1169
1168 self.__profIndex += 1
1170 self.__profIndex += 1
1169
1171
1170 return
1172 return
1171
1173
1172 def pushData(self):
1174 def pushData(self):
1173 """
1175 """
1174 Return the sum of the last profiles and the profiles used in the sum.
1176 Return the sum of the last profiles and the profiles used in the sum.
1175
1177
1176 Affected:
1178 Affected:
1177
1179
1178 self.__profileIndex
1180 self.__profileIndex
1179
1181
1180 """
1182 """
1181
1183
1182 data_spc = self.__buffer_spc
1184 data_spc = self.__buffer_spc
1183 data_cspc = self.__buffer_cspc
1185 data_cspc = self.__buffer_cspc
1184 data_dc = self.__buffer_dc
1186 data_dc = self.__buffer_dc
1185 n = self.__profIndex
1187 n = self.__profIndex
1186
1188
1187 self.__buffer_spc = 0
1189 self.__buffer_spc = 0
1188 self.__buffer_cspc = 0
1190 self.__buffer_cspc = 0
1189 self.__buffer_dc = 0
1191 self.__buffer_dc = 0
1190
1192
1191
1193
1192 return data_spc, data_cspc, data_dc, n
1194 return data_spc, data_cspc, data_dc, n
1193
1195
1194 def byProfiles(self, *args):
1196 def byProfiles(self, *args):
1195
1197
1196 self.__dataReady = False
1198 self.__dataReady = False
1197 avgdata_spc = None
1199 avgdata_spc = None
1198 avgdata_cspc = None
1200 avgdata_cspc = None
1199 avgdata_dc = None
1201 avgdata_dc = None
1200
1202
1201 self.putData(*args)
1203 self.putData(*args)
1202
1204
1203 if self.__profIndex == self.n:
1205 if self.__profIndex == self.n:
1204
1206
1205 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1207 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1206 self.n = n
1208 self.n = n
1207 self.__dataReady = True
1209 self.__dataReady = True
1208
1210
1209 return avgdata_spc, avgdata_cspc, avgdata_dc
1211 return avgdata_spc, avgdata_cspc, avgdata_dc
1210
1212
1211 def byTime(self, datatime, *args):
1213 def byTime(self, datatime, *args):
1212
1214
1213 self.__dataReady = False
1215 self.__dataReady = False
1214 avgdata_spc = None
1216 avgdata_spc = None
1215 avgdata_cspc = None
1217 avgdata_cspc = None
1216 avgdata_dc = None
1218 avgdata_dc = None
1217
1219
1218 self.putData(*args)
1220 self.putData(*args)
1219
1221
1220 if (datatime - self.__initime) >= self.__integrationtime:
1222 if (datatime - self.__initime) >= self.__integrationtime:
1221 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1223 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1222 self.n = n
1224 self.n = n
1223 self.__dataReady = True
1225 self.__dataReady = True
1224
1226
1225 return avgdata_spc, avgdata_cspc, avgdata_dc
1227 return avgdata_spc, avgdata_cspc, avgdata_dc
1226
1228
1227 def integrate(self, datatime, *args):
1229 def integrate(self, datatime, *args):
1228
1230
1229 if self.__profIndex == 0:
1231 if self.__profIndex == 0:
1230 self.__initime = datatime
1232 self.__initime = datatime
1231
1233
1232 if self.__byTime:
1234 if self.__byTime:
1233 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1235 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1234 datatime, *args)
1236 datatime, *args)
1235 else:
1237 else:
1236 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1238 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1237
1239
1238 if not self.__dataReady:
1240 if not self.__dataReady:
1239 return None, None, None, None
1241 return None, None, None, None
1240
1242
1241 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1243 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1242
1244
1243 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1245 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1244 if n == 1:
1246 if n == 1:
1245 return dataOut
1247 return dataOut
1246
1248
1247 if dataOut.flagNoData == True:
1249 if dataOut.flagNoData == True:
1248 return dataOut
1250 return dataOut
1249
1251
1250 if dataOut.flagProfilesByRange == True:
1252 if dataOut.flagProfilesByRange == True:
1251 self._flagProfilesByRange = True
1253 self._flagProfilesByRange = True
1252
1254
1253 dataOut.flagNoData = True
1255 dataOut.flagNoData = True
1254 dataOut.processingHeaderObj.timeIncohInt = timeInterval
1256 dataOut.processingHeaderObj.timeIncohInt = timeInterval
1255 if not self.isConfig:
1257 if not self.isConfig:
1256 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1258 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1257 self.setup(n, timeInterval, overlapping)
1259 self.setup(n, timeInterval, overlapping)
1258 self.isConfig = True
1260 self.isConfig = True
1259
1261
1260
1262
1261 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1263 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1262 dataOut.data_spc,
1264 dataOut.data_spc,
1263 dataOut.data_cspc,
1265 dataOut.data_cspc,
1264 dataOut.data_dc)
1266 dataOut.data_dc)
1265
1267
1266 self.incohInt += dataOut.nIncohInt
1268 self.incohInt += dataOut.nIncohInt
1267
1269
1268
1270
1269 if isinstance(dataOut.data_outlier,numpy.ndarray) or isinstance(dataOut.data_outlier,int) or isinstance(dataOut.data_outlier, float):
1271 if isinstance(dataOut.data_outlier,numpy.ndarray) or isinstance(dataOut.data_outlier,int) or isinstance(dataOut.data_outlier, float):
1270 self.nOutliers += dataOut.data_outlier
1272 self.nOutliers += dataOut.data_outlier
1271
1273
1272 if self._flagProfilesByRange:
1274 if self._flagProfilesByRange:
1273 dataOut.flagProfilesByRange = True
1275 dataOut.flagProfilesByRange = True
1274 self._nProfilesByRange += dataOut.nProfilesByRange
1276 self._nProfilesByRange += dataOut.nProfilesByRange
1275
1277
1276 if self.__dataReady:
1278 if self.__dataReady:
1277 #print("prof: ",dataOut.max_nIncohInt,self.__profIndex)
1279 #print("prof: ",dataOut.max_nIncohInt,self.__profIndex)
1278 dataOut.data_spc = avgdata_spc
1280 dataOut.data_spc = avgdata_spc
1279 dataOut.data_cspc = avgdata_cspc
1281 dataOut.data_cspc = avgdata_cspc
1280 dataOut.data_dc = avgdata_dc
1282 dataOut.data_dc = avgdata_dc
1281 dataOut.nIncohInt = self.incohInt
1283 dataOut.nIncohInt = self.incohInt
1282 dataOut.data_outlier = self.nOutliers
1284 dataOut.data_outlier = self.nOutliers
1283 dataOut.utctime = avgdatatime
1285 dataOut.utctime = avgdatatime
1284 dataOut.flagNoData = False
1286 dataOut.flagNoData = False
1285 self.incohInt = 0
1287 self.incohInt = 0
1286 self.nOutliers = 0
1288 self.nOutliers = 0
1287 self.__profIndex = 0
1289 self.__profIndex = 0
1288 dataOut.nProfilesByRange = self._nProfilesByRange
1290 dataOut.nProfilesByRange = self._nProfilesByRange
1289 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1291 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1290 self._flagProfilesByRange = False
1292 self._flagProfilesByRange = False
1291 # print("IncohInt Done")
1293 # print("IncohInt Done")
1292 return dataOut
1294 return dataOut
1293
1295
1294
1296
1295 class IntegrationFaradaySpectra(Operation):
1297 class IntegrationFaradaySpectra(Operation):
1296
1298
1297 __profIndex = 0
1299 __profIndex = 0
1298 __withOverapping = False
1300 __withOverapping = False
1299
1301
1300 __byTime = False
1302 __byTime = False
1301 __initime = None
1303 __initime = None
1302 __lastdatatime = None
1304 __lastdatatime = None
1303 __integrationtime = None
1305 __integrationtime = None
1304
1306
1305 __buffer_spc = None
1307 __buffer_spc = None
1306 __buffer_cspc = None
1308 __buffer_cspc = None
1307 __buffer_dc = None
1309 __buffer_dc = None
1308
1310
1309 __dataReady = False
1311 __dataReady = False
1310
1312
1311 __timeInterval = None
1313 __timeInterval = None
1312 n_ints = None #matriz de numero de integracions (CH,HEI)
1314 n_ints = None #matriz de numero de integracions (CH,HEI)
1313 n = None
1315 n = None
1314 minHei_ind = None
1316 minHei_ind = None
1315 maxHei_ind = None
1317 maxHei_ind = None
1316 navg = 1.0
1318 navg = 1.0
1317 factor = 0.0
1319 factor = 0.0
1318 dataoutliers = None # (CHANNELS, HEIGHTS)
1320 dataoutliers = None # (CHANNELS, HEIGHTS)
1319
1321
1320 _flagProfilesByRange = False
1322 _flagProfilesByRange = False
1321 _nProfilesByRange = 0
1323 _nProfilesByRange = 0
1322
1324
1323 def __init__(self):
1325 def __init__(self):
1324
1326
1325 Operation.__init__(self)
1327 Operation.__init__(self)
1326
1328
1327 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None, minHei=None, maxHei=None, avg=1,factor=0.75):
1329 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None, minHei=None, maxHei=None, avg=1,factor=0.75):
1328 """
1330 """
1329 Set the parameters of the integration class.
1331 Set the parameters of the integration class.
1330
1332
1331 Inputs:
1333 Inputs:
1332
1334
1333 n : Number of coherent integrations
1335 n : Number of coherent integrations
1334 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1336 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1335 overlapping :
1337 overlapping :
1336
1338
1337 """
1339 """
1338
1340
1339 self.__initime = None
1341 self.__initime = None
1340 self.__lastdatatime = 0
1342 self.__lastdatatime = 0
1341
1343
1342 self.__buffer_spc = []
1344 self.__buffer_spc = []
1343 self.__buffer_cspc = []
1345 self.__buffer_cspc = []
1344 self.__buffer_dc = 0
1346 self.__buffer_dc = 0
1345
1347
1346 self.__profIndex = 0
1348 self.__profIndex = 0
1347 self.__dataReady = False
1349 self.__dataReady = False
1348 self.__byTime = False
1350 self.__byTime = False
1349
1351
1350 self.factor = factor
1352 self.factor = factor
1351 self.navg = avg
1353 self.navg = avg
1352 #self.ByLags = dataOut.ByLags ###REDEFINIR
1354 #self.ByLags = dataOut.ByLags ###REDEFINIR
1353 self.ByLags = False
1355 self.ByLags = False
1354 self.maxProfilesInt = 0
1356 self.maxProfilesInt = 0
1355 self.__nChannels = dataOut.nChannels
1357 self.__nChannels = dataOut.nChannels
1356 if DPL != None:
1358 if DPL != None:
1357 self.DPL=DPL
1359 self.DPL=DPL
1358 else:
1360 else:
1359 #self.DPL=dataOut.DPL ###REDEFINIR
1361 #self.DPL=dataOut.DPL ###REDEFINIR
1360 self.DPL=0
1362 self.DPL=0
1361
1363
1362 if n is None and timeInterval is None:
1364 if n is None and timeInterval is None:
1363 raise ValueError("n or timeInterval should be specified ...")
1365 raise ValueError("n or timeInterval should be specified ...")
1364
1366
1365 if n is not None:
1367 if n is not None:
1366 self.n = int(n)
1368 self.n = int(n)
1367 else:
1369 else:
1368 self.__integrationtime = int(timeInterval)
1370 self.__integrationtime = int(timeInterval)
1369 self.n = None
1371 self.n = None
1370 self.__byTime = True
1372 self.__byTime = True
1371
1373
1372
1374
1373 if minHei == None:
1375 if minHei == None:
1374 minHei = self.dataOut.heightList[0]
1376 minHei = self.dataOut.heightList[0]
1375
1377
1376 if maxHei == None:
1378 if maxHei == None:
1377 maxHei = self.dataOut.heightList[-1]
1379 maxHei = self.dataOut.heightList[-1]
1378
1380
1379 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
1381 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
1380 print('minHei: %.2f is out of the heights range' % (minHei))
1382 print('minHei: %.2f is out of the heights range' % (minHei))
1381 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
1383 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
1382 minHei = self.dataOut.heightList[0]
1384 minHei = self.dataOut.heightList[0]
1383
1385
1384 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
1386 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
1385 print('maxHei: %.2f is out of the heights range' % (maxHei))
1387 print('maxHei: %.2f is out of the heights range' % (maxHei))
1386 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
1388 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
1387 maxHei = self.dataOut.heightList[-1]
1389 maxHei = self.dataOut.heightList[-1]
1388
1390
1389 ind_list1 = numpy.where(self.dataOut.heightList >= minHei)
1391 ind_list1 = numpy.where(self.dataOut.heightList >= minHei)
1390 ind_list2 = numpy.where(self.dataOut.heightList <= maxHei)
1392 ind_list2 = numpy.where(self.dataOut.heightList <= maxHei)
1391 self.minHei_ind = ind_list1[0][0]
1393 self.minHei_ind = ind_list1[0][0]
1392 self.maxHei_ind = ind_list2[0][-1]
1394 self.maxHei_ind = ind_list2[0][-1]
1393
1395
1394 def putData(self, data_spc, data_cspc, data_dc):
1396 def putData(self, data_spc, data_cspc, data_dc):
1395 """
1397 """
1396 Add a profile to the __buffer_spc and increase in one the __profileIndex
1398 Add a profile to the __buffer_spc and increase in one the __profileIndex
1397
1399
1398 """
1400 """
1399
1401
1400 self.__buffer_spc.append(data_spc)
1402 self.__buffer_spc.append(data_spc)
1401
1403
1402 if self.__nChannels < 2:
1404 if self.__nChannels < 2:
1403 self.__buffer_cspc = None
1405 self.__buffer_cspc = None
1404 else:
1406 else:
1405 self.__buffer_cspc.append(data_cspc)
1407 self.__buffer_cspc.append(data_cspc)
1406
1408
1407 if data_dc is None:
1409 if data_dc is None:
1408 self.__buffer_dc = None
1410 self.__buffer_dc = None
1409 else:
1411 else:
1410 self.__buffer_dc += data_dc
1412 self.__buffer_dc += data_dc
1411
1413
1412 self.__profIndex += 1
1414 self.__profIndex += 1
1413
1415
1414 return
1416 return
1415
1417
1416 def hildebrand_sekhon_Integration(self,sortdata,navg, factor):
1418 def hildebrand_sekhon_Integration(self,sortdata,navg, factor):
1417 #data debe estar ordenado
1419 #data debe estar ordenado
1418 #sortdata = numpy.sort(data, axis=None)
1420 #sortdata = numpy.sort(data, axis=None)
1419 #sortID=data.argsort()
1421 #sortID=data.argsort()
1420 lenOfData = len(sortdata)
1422 lenOfData = len(sortdata)
1421 nums_min = lenOfData*factor
1423 nums_min = lenOfData*factor
1422 if nums_min <= 5:
1424 if nums_min <= 5:
1423 nums_min = 5
1425 nums_min = 5
1424 sump = 0.
1426 sump = 0.
1425 sumq = 0.
1427 sumq = 0.
1426 j = 0
1428 j = 0
1427 cont = 1
1429 cont = 1
1428 while((cont == 1)and(j < lenOfData)):
1430 while((cont == 1)and(j < lenOfData)):
1429 sump += sortdata[j]
1431 sump += sortdata[j]
1430 sumq += sortdata[j]**2
1432 sumq += sortdata[j]**2
1431 if j > nums_min:
1433 if j > nums_min:
1432 rtest = float(j)/(j-1) + 1.0/navg
1434 rtest = float(j)/(j-1) + 1.0/navg
1433 if ((sumq*j) > (rtest*sump**2)):
1435 if ((sumq*j) > (rtest*sump**2)):
1434 j = j - 1
1436 j = j - 1
1435 sump = sump - sortdata[j]
1437 sump = sump - sortdata[j]
1436 sumq = sumq - sortdata[j]**2
1438 sumq = sumq - sortdata[j]**2
1437 cont = 0
1439 cont = 0
1438 j += 1
1440 j += 1
1439 #lnoise = sump / j
1441 #lnoise = sump / j
1440 #print("H S done")
1442 #print("H S done")
1441 #return j,sortID
1443 #return j,sortID
1442 return j
1444 return j
1443
1445
1444
1446
1445 def pushData(self):
1447 def pushData(self):
1446 """
1448 """
1447 Return the sum of the last profiles and the profiles used in the sum.
1449 Return the sum of the last profiles and the profiles used in the sum.
1448
1450
1449 Affected:
1451 Affected:
1450
1452
1451 self.__profileIndex
1453 self.__profileIndex
1452
1454
1453 """
1455 """
1454 bufferH=None
1456 bufferH=None
1455 buffer=None
1457 buffer=None
1456 buffer1=None
1458 buffer1=None
1457 buffer_cspc=None
1459 buffer_cspc=None
1458 #print("aes: ", self.__buffer_cspc)
1460 #print("aes: ", self.__buffer_cspc)
1459 self.__buffer_spc=numpy.array(self.__buffer_spc)
1461 self.__buffer_spc=numpy.array(self.__buffer_spc)
1460 if self.__nChannels > 1 :
1462 if self.__nChannels > 1 :
1461 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1463 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1462
1464
1463 #print("FREQ_DC",self.__buffer_spc.shape,self.__buffer_cspc.shape)
1465 #print("FREQ_DC",self.__buffer_spc.shape,self.__buffer_cspc.shape)
1464
1466
1465 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1467 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1466 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1468 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1467
1469
1468 self.dataOutliers = numpy.zeros((self.nChannels,self.nHeights)) # --> almacen de outliers
1470 self.dataOutliers = numpy.zeros((self.nChannels,self.nHeights)) # --> almacen de outliers
1469
1471
1470 for k in range(self.minHei_ind,self.maxHei_ind):
1472 for k in range(self.minHei_ind,self.maxHei_ind):
1471 if self.__nChannels > 1:
1473 if self.__nChannels > 1:
1472 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1474 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1473
1475
1474 outliers_IDs_cspc=[]
1476 outliers_IDs_cspc=[]
1475 cspc_outliers_exist=False
1477 cspc_outliers_exist=False
1476 for i in range(self.nChannels):#dataOut.nChannels):
1478 for i in range(self.nChannels):#dataOut.nChannels):
1477
1479
1478 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1480 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1479 indexes=[]
1481 indexes=[]
1480 #sortIDs=[]
1482 #sortIDs=[]
1481 outliers_IDs=[]
1483 outliers_IDs=[]
1482
1484
1483 for j in range(self.nProfiles): #frecuencias en el tiempo
1485 for j in range(self.nProfiles): #frecuencias en el tiempo
1484 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1486 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1485 # continue
1487 # continue
1486 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1488 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1487 # continue
1489 # continue
1488 buffer=buffer1[:,j]
1490 buffer=buffer1[:,j]
1489 sortdata = numpy.sort(buffer, axis=None)
1491 sortdata = numpy.sort(buffer, axis=None)
1490
1492
1491 sortID=buffer.argsort()
1493 sortID=buffer.argsort()
1492 index = _noise.hildebrand_sekhon2(sortdata,self.navg)
1494 index = _noise.hildebrand_sekhon2(sortdata,self.navg)
1493
1495
1494 #index,sortID=self.hildebrand_sekhon_Integration(buffer,1,self.factor)
1496 #index,sortID=self.hildebrand_sekhon_Integration(buffer,1,self.factor)
1495
1497
1496 # fig,ax = plt.subplots()
1498 # fig,ax = plt.subplots()
1497 # ax.set_title(str(k)+" "+str(j))
1499 # ax.set_title(str(k)+" "+str(j))
1498 # x=range(len(sortdata))
1500 # x=range(len(sortdata))
1499 # ax.scatter(x,sortdata)
1501 # ax.scatter(x,sortdata)
1500 # ax.axvline(index)
1502 # ax.axvline(index)
1501 # plt.show()
1503 # plt.show()
1502
1504
1503 indexes.append(index)
1505 indexes.append(index)
1504 #sortIDs.append(sortID)
1506 #sortIDs.append(sortID)
1505 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1507 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1506
1508
1507 #print("Outliers: ",outliers_IDs)
1509 #print("Outliers: ",outliers_IDs)
1508 outliers_IDs=numpy.array(outliers_IDs)
1510 outliers_IDs=numpy.array(outliers_IDs)
1509 outliers_IDs=outliers_IDs.ravel()
1511 outliers_IDs=outliers_IDs.ravel()
1510 outliers_IDs=numpy.unique(outliers_IDs)
1512 outliers_IDs=numpy.unique(outliers_IDs)
1511 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1513 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1512 indexes=numpy.array(indexes)
1514 indexes=numpy.array(indexes)
1513 indexmin=numpy.min(indexes)
1515 indexmin=numpy.min(indexes)
1514
1516
1515
1517
1516 #print(indexmin,buffer1.shape[0], k)
1518 #print(indexmin,buffer1.shape[0], k)
1517
1519
1518 # fig,ax = plt.subplots()
1520 # fig,ax = plt.subplots()
1519 # ax.plot(sortdata)
1521 # ax.plot(sortdata)
1520 # ax2 = ax.twinx()
1522 # ax2 = ax.twinx()
1521 # x=range(len(indexes))
1523 # x=range(len(indexes))
1522 # #plt.scatter(x,indexes)
1524 # #plt.scatter(x,indexes)
1523 # ax2.scatter(x,indexes)
1525 # ax2.scatter(x,indexes)
1524 # plt.show()
1526 # plt.show()
1525
1527
1526 if indexmin != buffer1.shape[0]:
1528 if indexmin != buffer1.shape[0]:
1527 if self.__nChannels > 1:
1529 if self.__nChannels > 1:
1528 cspc_outliers_exist= True
1530 cspc_outliers_exist= True
1529
1531
1530 lt=outliers_IDs
1532 lt=outliers_IDs
1531 #avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1533 #avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1532
1534
1533 for p in list(outliers_IDs):
1535 for p in list(outliers_IDs):
1534 #buffer1[p,:]=avg
1536 #buffer1[p,:]=avg
1535 buffer1[p,:] = numpy.NaN
1537 buffer1[p,:] = numpy.NaN
1536
1538
1537 self.dataOutliers[i,k] = len(outliers_IDs)
1539 self.dataOutliers[i,k] = len(outliers_IDs)
1538
1540
1539
1541
1540 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1542 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1541
1543
1542
1544
1543 if self.__nChannels > 1:
1545 if self.__nChannels > 1:
1544 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1546 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1545
1547
1546
1548
1547 if self.__nChannels > 1:
1549 if self.__nChannels > 1:
1548 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1550 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1549 if cspc_outliers_exist:
1551 if cspc_outliers_exist:
1550
1552
1551 lt=outliers_IDs_cspc
1553 lt=outliers_IDs_cspc
1552
1554
1553 #avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1555 #avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1554 for p in list(outliers_IDs_cspc):
1556 for p in list(outliers_IDs_cspc):
1555 #buffer_cspc[p,:]=avg
1557 #buffer_cspc[p,:]=avg
1556 buffer_cspc[p,:] = numpy.NaN
1558 buffer_cspc[p,:] = numpy.NaN
1557
1559
1558 if self.__nChannels > 1:
1560 if self.__nChannels > 1:
1559 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1561 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1560
1562
1561
1563
1562
1564
1563
1565
1564 nOutliers = len(outliers_IDs)
1566 nOutliers = len(outliers_IDs)
1565 #print("Outliers n: ",self.dataOutliers,nOutliers)
1567 #print("Outliers n: ",self.dataOutliers,nOutliers)
1566 buffer=None
1568 buffer=None
1567 bufferH=None
1569 bufferH=None
1568 buffer1=None
1570 buffer1=None
1569 buffer_cspc=None
1571 buffer_cspc=None
1570
1572
1571
1573
1572 buffer=None
1574 buffer=None
1573
1575
1574 #data_spc = numpy.sum(self.__buffer_spc,axis=0)
1576 #data_spc = numpy.sum(self.__buffer_spc,axis=0)
1575 data_spc = numpy.nansum(self.__buffer_spc,axis=0)
1577 data_spc = numpy.nansum(self.__buffer_spc,axis=0)
1576 if self.__nChannels > 1:
1578 if self.__nChannels > 1:
1577 #data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1579 #data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1578 data_cspc = numpy.nansum(self.__buffer_cspc,axis=0)
1580 data_cspc = numpy.nansum(self.__buffer_cspc,axis=0)
1579 else:
1581 else:
1580 data_cspc = None
1582 data_cspc = None
1581 data_dc = self.__buffer_dc
1583 data_dc = self.__buffer_dc
1582 #(CH, HEIGH)
1584 #(CH, HEIGH)
1583 self.maxProfilesInt = self.__profIndex - 1
1585 self.maxProfilesInt = self.__profIndex - 1
1584 n = self.__profIndex - self.dataOutliers # n becomes a matrix
1586 n = self.__profIndex - self.dataOutliers # n becomes a matrix
1585
1587
1586 self.__buffer_spc = []
1588 self.__buffer_spc = []
1587 self.__buffer_cspc = []
1589 self.__buffer_cspc = []
1588 self.__buffer_dc = 0
1590 self.__buffer_dc = 0
1589 self.__profIndex = 0
1591 self.__profIndex = 0
1590 #print("cleaned ",data_cspc)
1592 #print("cleaned ",data_cspc)
1591 return data_spc, data_cspc, data_dc, n
1593 return data_spc, data_cspc, data_dc, n
1592
1594
1593 def byProfiles(self, *args):
1595 def byProfiles(self, *args):
1594
1596
1595 self.__dataReady = False
1597 self.__dataReady = False
1596 avgdata_spc = None
1598 avgdata_spc = None
1597 avgdata_cspc = None
1599 avgdata_cspc = None
1598 avgdata_dc = None
1600 avgdata_dc = None
1599
1601
1600 self.putData(*args)
1602 self.putData(*args)
1601
1603
1602 if self.__profIndex >= self.n:
1604 if self.__profIndex >= self.n:
1603
1605
1604 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1606 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1605 self.n_ints = n
1607 self.n_ints = n
1606 self.__dataReady = True
1608 self.__dataReady = True
1607
1609
1608 return avgdata_spc, avgdata_cspc, avgdata_dc
1610 return avgdata_spc, avgdata_cspc, avgdata_dc
1609
1611
1610 def byTime(self, datatime, *args):
1612 def byTime(self, datatime, *args):
1611
1613
1612 self.__dataReady = False
1614 self.__dataReady = False
1613 avgdata_spc = None
1615 avgdata_spc = None
1614 avgdata_cspc = None
1616 avgdata_cspc = None
1615 avgdata_dc = None
1617 avgdata_dc = None
1616
1618
1617 self.putData(*args)
1619 self.putData(*args)
1618
1620
1619 if (datatime - self.__initime) >= self.__integrationtime:
1621 if (datatime - self.__initime) >= self.__integrationtime:
1620 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1622 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1621 self.n_ints = n
1623 self.n_ints = n
1622 self.__dataReady = True
1624 self.__dataReady = True
1623
1625
1624 return avgdata_spc, avgdata_cspc, avgdata_dc
1626 return avgdata_spc, avgdata_cspc, avgdata_dc
1625
1627
1626 def integrate(self, datatime, *args):
1628 def integrate(self, datatime, *args):
1627
1629
1628 if self.__profIndex == 0:
1630 if self.__profIndex == 0:
1629 self.__initime = datatime
1631 self.__initime = datatime
1630
1632
1631 if self.__byTime:
1633 if self.__byTime:
1632 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1634 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1633 datatime, *args)
1635 datatime, *args)
1634 else:
1636 else:
1635 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1637 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1636
1638
1637 if not self.__dataReady:
1639 if not self.__dataReady:
1638 return None, None, None, None
1640 return None, None, None, None
1639
1641
1640 #print("integrate", avgdata_cspc)
1642 #print("integrate", avgdata_cspc)
1641 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1643 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1642
1644
1643 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False, minHei=None, maxHei=None, avg=1, factor=0.75):
1645 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False, minHei=None, maxHei=None, avg=1, factor=0.75):
1644 self.dataOut = dataOut
1646 self.dataOut = dataOut
1645 if n == 1:
1647 if n == 1:
1646 return self.dataOut
1648 return self.dataOut
1647 self.dataOut.processingHeaderObj.timeIncohInt = timeInterval
1649 self.dataOut.processingHeaderObj.timeIncohInt = timeInterval
1648
1650
1649 if dataOut.flagProfilesByRange:
1651 if dataOut.flagProfilesByRange:
1650 self._flagProfilesByRange = True
1652 self._flagProfilesByRange = True
1651
1653
1652 if self.dataOut.nChannels == 1:
1654 if self.dataOut.nChannels == 1:
1653 self.dataOut.data_cspc = None #si es un solo canal no vale la pena acumular DATOS
1655 self.dataOut.data_cspc = None #si es un solo canal no vale la pena acumular DATOS
1654 #print("IN spc:", self.dataOut.data_spc.shape, self.dataOut.data_cspc)
1656 #print("IN spc:", self.dataOut.data_spc.shape, self.dataOut.data_cspc)
1655 if not self.isConfig:
1657 if not self.isConfig:
1656 self.setup(self.dataOut, n, timeInterval, overlapping,DPL ,minHei, maxHei, avg, factor)
1658 self.setup(self.dataOut, n, timeInterval, overlapping,DPL ,minHei, maxHei, avg, factor)
1657 self.isConfig = True
1659 self.isConfig = True
1658
1660
1659 if not self.ByLags:
1661 if not self.ByLags:
1660 self.nProfiles=self.dataOut.nProfiles
1662 self.nProfiles=self.dataOut.nProfiles
1661 self.nChannels=self.dataOut.nChannels
1663 self.nChannels=self.dataOut.nChannels
1662 self.nHeights=self.dataOut.nHeights
1664 self.nHeights=self.dataOut.nHeights
1663 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1665 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1664 self.dataOut.data_spc,
1666 self.dataOut.data_spc,
1665 self.dataOut.data_cspc,
1667 self.dataOut.data_cspc,
1666 self.dataOut.data_dc)
1668 self.dataOut.data_dc)
1667 else:
1669 else:
1668 self.nProfiles=self.dataOut.nProfiles
1670 self.nProfiles=self.dataOut.nProfiles
1669 self.nChannels=self.dataOut.nChannels
1671 self.nChannels=self.dataOut.nChannels
1670 self.nHeights=self.dataOut.nHeights
1672 self.nHeights=self.dataOut.nHeights
1671 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1673 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1672 self.dataOut.dataLag_spc,
1674 self.dataOut.dataLag_spc,
1673 self.dataOut.dataLag_cspc,
1675 self.dataOut.dataLag_cspc,
1674 self.dataOut.dataLag_dc)
1676 self.dataOut.dataLag_dc)
1675 self.dataOut.flagNoData = True
1677 self.dataOut.flagNoData = True
1676
1678
1677 if self._flagProfilesByRange:
1679 if self._flagProfilesByRange:
1678 dataOut.flagProfilesByRange = True
1680 dataOut.flagProfilesByRange = True
1679 self._nProfilesByRange += dataOut.nProfilesByRange
1681 self._nProfilesByRange += dataOut.nProfilesByRange
1680
1682
1681 if self.__dataReady:
1683 if self.__dataReady:
1682
1684
1683 if not self.ByLags:
1685 if not self.ByLags:
1684 if self.nChannels == 1:
1686 if self.nChannels == 1:
1685 #print("f int", avgdata_spc.shape)
1687 #print("f int", avgdata_spc.shape)
1686 self.dataOut.data_spc = avgdata_spc
1688 self.dataOut.data_spc = avgdata_spc
1687 self.dataOut.data_cspc = None
1689 self.dataOut.data_cspc = None
1688 else:
1690 else:
1689 self.dataOut.data_spc = numpy.squeeze(avgdata_spc)
1691 self.dataOut.data_spc = numpy.squeeze(avgdata_spc)
1690 self.dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1692 self.dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1691 self.dataOut.data_dc = avgdata_dc
1693 self.dataOut.data_dc = avgdata_dc
1692 self.dataOut.data_outlier = self.dataOutliers
1694 self.dataOut.data_outlier = self.dataOutliers
1693
1695
1694
1696
1695 else:
1697 else:
1696 self.dataOut.dataLag_spc = avgdata_spc
1698 self.dataOut.dataLag_spc = avgdata_spc
1697 self.dataOut.dataLag_cspc = avgdata_cspc
1699 self.dataOut.dataLag_cspc = avgdata_cspc
1698 self.dataOut.dataLag_dc = avgdata_dc
1700 self.dataOut.dataLag_dc = avgdata_dc
1699
1701
1700 self.dataOut.data_spc=self.dataOut.dataLag_spc[:,:,:,self.dataOut.LagPlot]
1702 self.dataOut.data_spc=self.dataOut.dataLag_spc[:,:,:,self.dataOut.LagPlot]
1701 self.dataOut.data_cspc=self.dataOut.dataLag_cspc[:,:,:,self.dataOut.LagPlot]
1703 self.dataOut.data_cspc=self.dataOut.dataLag_cspc[:,:,:,self.dataOut.LagPlot]
1702 self.dataOut.data_dc=self.dataOut.dataLag_dc[:,:,self.dataOut.LagPlot]
1704 self.dataOut.data_dc=self.dataOut.dataLag_dc[:,:,self.dataOut.LagPlot]
1703
1705
1704 self.dataOut.nIncohInt *= self.n_ints
1706 self.dataOut.nIncohInt *= self.n_ints
1705
1707
1706 self.dataOut.utctime = avgdatatime
1708 self.dataOut.utctime = avgdatatime
1707 self.dataOut.flagNoData = False
1709 self.dataOut.flagNoData = False
1708
1710
1709 dataOut.nProfilesByRange = self._nProfilesByRange
1711 dataOut.nProfilesByRange = self._nProfilesByRange
1710 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1712 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1711 self._flagProfilesByRange = False
1713 self._flagProfilesByRange = False
1712
1714
1713 return self.dataOut
1715 return self.dataOut
1714
1716
1715 class dopplerFlip(Operation):
1717 class dopplerFlip(Operation):
1716
1718
1717 def run(self, dataOut, chann = None):
1719 def run(self, dataOut, chann = None):
1718 # arreglo 1: (num_chan, num_profiles, num_heights)
1720 # arreglo 1: (num_chan, num_profiles, num_heights)
1719 self.dataOut = dataOut
1721 self.dataOut = dataOut
1720 # JULIA-oblicua, indice 2
1722 # JULIA-oblicua, indice 2
1721 # arreglo 2: (num_profiles, num_heights)
1723 # arreglo 2: (num_profiles, num_heights)
1722 jspectra = self.dataOut.data_spc[chann]
1724 jspectra = self.dataOut.data_spc[chann]
1723 jspectra_tmp = numpy.zeros(jspectra.shape)
1725 jspectra_tmp = numpy.zeros(jspectra.shape)
1724 num_profiles = jspectra.shape[0]
1726 num_profiles = jspectra.shape[0]
1725 freq_dc = int(num_profiles / 2)
1727 freq_dc = int(num_profiles / 2)
1726 # Flip con for
1728 # Flip con for
1727 for j in range(num_profiles):
1729 for j in range(num_profiles):
1728 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1730 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1729 # Intercambio perfil de DC con perfil inmediato anterior
1731 # Intercambio perfil de DC con perfil inmediato anterior
1730 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1732 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1731 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1733 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1732 # canal modificado es re-escrito en el arreglo de canales
1734 # canal modificado es re-escrito en el arreglo de canales
1733 self.dataOut.data_spc[chann] = jspectra_tmp
1735 self.dataOut.data_spc[chann] = jspectra_tmp
1734
1736
1735 return self.dataOut No newline at end of file
1737 return self.dataOut
General Comments 0
You need to be logged in to leave comments. Login now