##// END OF EJS Templates
cambios para amisr ISR getNoise
joabAM -
r1468:1fb12846b034
parent child
Show More
@@ -1,1076 +1,1076
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 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 '''
79 '''
80 lenOfData = len(sortdata)
80 lenOfData = len(sortdata)
81 nums_min = lenOfData*0.2
81 nums_min = lenOfData*0.2
82
82
83 if nums_min <= 5:
83 if nums_min <= 5:
84
84
85 nums_min = 5
85 nums_min = 5
86
86
87 sump = 0.
87 sump = 0.
88 sumq = 0.
88 sumq = 0.
89
89
90 j = 0
90 j = 0
91 cont = 1
91 cont = 1
92
92
93 while((cont == 1)and(j < lenOfData)):
93 while((cont == 1)and(j < lenOfData)):
94
94
95 sump += sortdata[j]
95 sump += sortdata[j]
96 sumq += sortdata[j]**2
96 sumq += sortdata[j]**2
97
97
98 if j > nums_min:
98 if j > nums_min:
99 rtest = float(j)/(j-1) + 1.0/navg
99 rtest = float(j)/(j-1) + 1.0/navg
100 if ((sumq*j) > (rtest*sump**2)):
100 if ((sumq*j) > (rtest*sump**2)):
101 j = j - 1
101 j = j - 1
102 sump = sump - sortdata[j]
102 sump = sump - sortdata[j]
103 sumq = sumq - sortdata[j]**2
103 sumq = sumq - sortdata[j]**2
104 cont = 0
104 cont = 0
105
105
106 j += 1
106 j += 1
107
107
108 lnoise = sump / j
108 lnoise = sump / j
109 '''
109 '''
110 return _noise.hildebrand_sekhon(sortdata, navg)
110 return _noise.hildebrand_sekhon(sortdata, navg)
111
111
112
112
113 class Beam:
113 class Beam:
114
114
115 def __init__(self):
115 def __init__(self):
116 self.codeList = []
116 self.codeList = []
117 self.azimuthList = []
117 self.azimuthList = []
118 self.zenithList = []
118 self.zenithList = []
119
119
120
120
121
121
122 class GenericData(object):
122 class GenericData(object):
123
123
124 flagNoData = True
124 flagNoData = True
125
125
126 def copy(self, inputObj=None):
126 def copy(self, inputObj=None):
127
127
128 if inputObj == None:
128 if inputObj == None:
129 return copy.deepcopy(self)
129 return copy.deepcopy(self)
130
130
131 for key in list(inputObj.__dict__.keys()):
131 for key in list(inputObj.__dict__.keys()):
132
132
133 attribute = inputObj.__dict__[key]
133 attribute = inputObj.__dict__[key]
134
134
135 # If this attribute is a tuple or list
135 # If this attribute is a tuple or list
136 if type(inputObj.__dict__[key]) in (tuple, list):
136 if type(inputObj.__dict__[key]) in (tuple, list):
137 self.__dict__[key] = attribute[:]
137 self.__dict__[key] = attribute[:]
138 continue
138 continue
139
139
140 # If this attribute is another object or instance
140 # If this attribute is another object or instance
141 if hasattr(attribute, '__dict__'):
141 if hasattr(attribute, '__dict__'):
142 self.__dict__[key] = attribute.copy()
142 self.__dict__[key] = attribute.copy()
143 continue
143 continue
144
144
145 self.__dict__[key] = inputObj.__dict__[key]
145 self.__dict__[key] = inputObj.__dict__[key]
146
146
147 def deepcopy(self):
147 def deepcopy(self):
148
148
149 return copy.deepcopy(self)
149 return copy.deepcopy(self)
150
150
151 def isEmpty(self):
151 def isEmpty(self):
152
152
153 return self.flagNoData
153 return self.flagNoData
154
154
155 def isReady(self):
155 def isReady(self):
156
156
157 return not self.flagNoData
157 return not self.flagNoData
158
158
159
159
160 class JROData(GenericData):
160 class JROData(GenericData):
161
161
162 systemHeaderObj = SystemHeader()
162 systemHeaderObj = SystemHeader()
163 radarControllerHeaderObj = RadarControllerHeader()
163 radarControllerHeaderObj = RadarControllerHeader()
164 type = None
164 type = None
165 datatype = None # dtype but in string
165 datatype = None # dtype but in string
166 nProfiles = None
166 nProfiles = None
167 heightList = None
167 heightList = None
168 channelList = None
168 channelList = None
169 flagDiscontinuousBlock = False
169 flagDiscontinuousBlock = False
170 useLocalTime = False
170 useLocalTime = False
171 utctime = None
171 utctime = None
172 timeZone = None
172 timeZone = None
173 dstFlag = None
173 dstFlag = None
174 errorCount = None
174 errorCount = None
175 blocksize = None
175 blocksize = None
176 flagDecodeData = False # asumo q la data no esta decodificada
176 flagDecodeData = False # asumo q la data no esta decodificada
177 flagDeflipData = False # asumo q la data no esta sin flip
177 flagDeflipData = False # asumo q la data no esta sin flip
178 flagShiftFFT = False
178 flagShiftFFT = False
179 nCohInt = None
179 nCohInt = None
180 windowOfFilter = 1
180 windowOfFilter = 1
181 C = 3e8
181 C = 3e8
182 frequency = 49.92e6
182 frequency = 49.92e6
183 realtime = False
183 realtime = False
184 beacon_heiIndexList = None
184 beacon_heiIndexList = None
185 last_block = None
185 last_block = None
186 blocknow = None
186 blocknow = None
187 azimuth = None
187 azimuth = None
188 zenith = None
188 zenith = None
189 beam = Beam()
189 beam = Beam()
190 profileIndex = None
190 profileIndex = None
191 error = None
191 error = None
192 data = None
192 data = None
193 nmodes = None
193 nmodes = None
194 metadata_list = ['heightList', 'timeZone', 'type']
194 metadata_list = ['heightList', 'timeZone', 'type']
195 codeList = None
195 codeList = None
196 azimuthList = None
196 azimuthList = None
197 elevationList = None
197 elevationList = None
198
198
199 def __str__(self):
199 def __str__(self):
200
200
201 return '{} - {}'.format(self.type, self.datatime())
201 return '{} - {}'.format(self.type, self.datatime())
202
202
203 def getNoise(self):
203 def getNoise(self):
204
204
205 raise NotImplementedError
205 raise NotImplementedError
206
206
207 @property
207 @property
208 def nChannels(self):
208 def nChannels(self):
209
209
210 return len(self.channelList)
210 return len(self.channelList)
211
211
212 @property
212 @property
213 def channelIndexList(self):
213 def channelIndexList(self):
214
214
215 return list(range(self.nChannels))
215 return list(range(self.nChannels))
216
216
217 @property
217 @property
218 def nHeights(self):
218 def nHeights(self):
219
219
220 return len(self.heightList)
220 return len(self.heightList)
221
221
222 def getDeltaH(self):
222 def getDeltaH(self):
223
223
224 return self.heightList[1] - self.heightList[0]
224 return self.heightList[1] - self.heightList[0]
225
225
226 @property
226 @property
227 def ltctime(self):
227 def ltctime(self):
228
228
229 if self.useLocalTime:
229 if self.useLocalTime:
230 return self.utctime - self.timeZone * 60
230 return self.utctime - self.timeZone * 60
231
231
232 return self.utctime
232 return self.utctime
233
233
234 @property
234 @property
235 def datatime(self):
235 def datatime(self):
236
236
237 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
237 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
238 return datatimeValue
238 return datatimeValue
239
239
240 def getTimeRange(self):
240 def getTimeRange(self):
241
241
242 datatime = []
242 datatime = []
243
243
244 datatime.append(self.ltctime)
244 datatime.append(self.ltctime)
245 datatime.append(self.ltctime + self.timeInterval + 1)
245 datatime.append(self.ltctime + self.timeInterval + 1)
246
246
247 datatime = numpy.array(datatime)
247 datatime = numpy.array(datatime)
248
248
249 return datatime
249 return datatime
250
250
251 def getFmaxTimeResponse(self):
251 def getFmaxTimeResponse(self):
252
252
253 period = (10**-6) * self.getDeltaH() / (0.15)
253 period = (10**-6) * self.getDeltaH() / (0.15)
254
254
255 PRF = 1. / (period * self.nCohInt)
255 PRF = 1. / (period * self.nCohInt)
256
256
257 fmax = PRF
257 fmax = PRF
258
258
259 return fmax
259 return fmax
260
260
261 def getFmax(self):
261 def getFmax(self):
262 PRF = 1. / (self.ippSeconds * self.nCohInt)
262 PRF = 1. / (self.ippSeconds * self.nCohInt)
263
263
264 fmax = PRF
264 fmax = PRF
265 return fmax
265 return fmax
266
266
267 def getVmax(self):
267 def getVmax(self):
268
268
269 _lambda = self.C / self.frequency
269 _lambda = self.C / self.frequency
270
270
271 vmax = self.getFmax() * _lambda / 2
271 vmax = self.getFmax() * _lambda / 2
272
272
273 return vmax
273 return vmax
274
274
275 @property
275 @property
276 def ippSeconds(self):
276 def ippSeconds(self):
277 '''
277 '''
278 '''
278 '''
279 return self.radarControllerHeaderObj.ippSeconds
279 return self.radarControllerHeaderObj.ippSeconds
280
280
281 @ippSeconds.setter
281 @ippSeconds.setter
282 def ippSeconds(self, ippSeconds):
282 def ippSeconds(self, ippSeconds):
283 '''
283 '''
284 '''
284 '''
285 self.radarControllerHeaderObj.ippSeconds = ippSeconds
285 self.radarControllerHeaderObj.ippSeconds = ippSeconds
286
286
287 @property
287 @property
288 def code(self):
288 def code(self):
289 '''
289 '''
290 '''
290 '''
291 return self.radarControllerHeaderObj.code
291 return self.radarControllerHeaderObj.code
292
292
293 @code.setter
293 @code.setter
294 def code(self, code):
294 def code(self, code):
295 '''
295 '''
296 '''
296 '''
297 self.radarControllerHeaderObj.code = code
297 self.radarControllerHeaderObj.code = code
298
298
299 @property
299 @property
300 def nCode(self):
300 def nCode(self):
301 '''
301 '''
302 '''
302 '''
303 return self.radarControllerHeaderObj.nCode
303 return self.radarControllerHeaderObj.nCode
304
304
305 @nCode.setter
305 @nCode.setter
306 def nCode(self, ncode):
306 def nCode(self, ncode):
307 '''
307 '''
308 '''
308 '''
309 self.radarControllerHeaderObj.nCode = ncode
309 self.radarControllerHeaderObj.nCode = ncode
310
310
311 @property
311 @property
312 def nBaud(self):
312 def nBaud(self):
313 '''
313 '''
314 '''
314 '''
315 return self.radarControllerHeaderObj.nBaud
315 return self.radarControllerHeaderObj.nBaud
316
316
317 @nBaud.setter
317 @nBaud.setter
318 def nBaud(self, nbaud):
318 def nBaud(self, nbaud):
319 '''
319 '''
320 '''
320 '''
321 self.radarControllerHeaderObj.nBaud = nbaud
321 self.radarControllerHeaderObj.nBaud = nbaud
322
322
323 @property
323 @property
324 def ipp(self):
324 def ipp(self):
325 '''
325 '''
326 '''
326 '''
327 return self.radarControllerHeaderObj.ipp
327 return self.radarControllerHeaderObj.ipp
328
328
329 @ipp.setter
329 @ipp.setter
330 def ipp(self, ipp):
330 def ipp(self, ipp):
331 '''
331 '''
332 '''
332 '''
333 self.radarControllerHeaderObj.ipp = ipp
333 self.radarControllerHeaderObj.ipp = ipp
334
334
335 @property
335 @property
336 def metadata(self):
336 def metadata(self):
337 '''
337 '''
338 '''
338 '''
339
339
340 return {attr: getattr(self, attr) for attr in self.metadata_list}
340 return {attr: getattr(self, attr) for attr in self.metadata_list}
341
341
342
342
343 class Voltage(JROData):
343 class Voltage(JROData):
344
344
345 dataPP_POW = None
345 dataPP_POW = None
346 dataPP_DOP = None
346 dataPP_DOP = None
347 dataPP_WIDTH = None
347 dataPP_WIDTH = None
348 dataPP_SNR = None
348 dataPP_SNR = None
349
349
350 def __init__(self):
350 def __init__(self):
351 '''
351 '''
352 Constructor
352 Constructor
353 '''
353 '''
354
354
355 self.useLocalTime = True
355 self.useLocalTime = True
356 self.radarControllerHeaderObj = RadarControllerHeader()
356 self.radarControllerHeaderObj = RadarControllerHeader()
357 self.systemHeaderObj = SystemHeader()
357 self.systemHeaderObj = SystemHeader()
358 self.type = "Voltage"
358 self.type = "Voltage"
359 self.data = None
359 self.data = None
360 self.nProfiles = None
360 self.nProfiles = None
361 self.heightList = None
361 self.heightList = None
362 self.channelList = None
362 self.channelList = None
363 self.flagNoData = True
363 self.flagNoData = True
364 self.flagDiscontinuousBlock = False
364 self.flagDiscontinuousBlock = False
365 self.utctime = None
365 self.utctime = None
366 self.timeZone = 0
366 self.timeZone = 0
367 self.dstFlag = None
367 self.dstFlag = None
368 self.errorCount = None
368 self.errorCount = None
369 self.nCohInt = None
369 self.nCohInt = None
370 self.blocksize = None
370 self.blocksize = None
371 self.flagCohInt = False
371 self.flagCohInt = False
372 self.flagDecodeData = False # asumo q la data no esta decodificada
372 self.flagDecodeData = False # asumo q la data no esta decodificada
373 self.flagDeflipData = False # asumo q la data no esta sin flip
373 self.flagDeflipData = False # asumo q la data no esta sin flip
374 self.flagShiftFFT = False
374 self.flagShiftFFT = False
375 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
375 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
376 self.profileIndex = 0
376 self.profileIndex = 0
377 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
377 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
378 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
378 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
379
379
380 def getNoisebyHildebrand(self, channel=None):
380 def getNoisebyHildebrand(self, channel=None):
381 """
381 """
382 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
382 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
383
383
384 Return:
384 Return:
385 noiselevel
385 noiselevel
386 """
386 """
387
387
388 if channel != None:
388 if channel != None:
389 data = self.data[channel]
389 data = self.data[channel]
390 nChannels = 1
390 nChannels = 1
391 else:
391 else:
392 data = self.data
392 data = self.data
393 nChannels = self.nChannels
393 nChannels = self.nChannels
394
394
395 noise = numpy.zeros(nChannels)
395 noise = numpy.zeros(nChannels)
396 power = data * numpy.conjugate(data)
396 power = data * numpy.conjugate(data)
397
397
398 for thisChannel in range(nChannels):
398 for thisChannel in range(nChannels):
399 if nChannels == 1:
399 if nChannels == 1:
400 daux = power[:].real
400 daux = power[:].real
401 else:
401 else:
402 daux = power[thisChannel, :].real
402 daux = power[thisChannel, :].real
403 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
403 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
404
404
405 return noise
405 return noise
406
406
407 def getNoise(self, type=1, channel=None):
407 def getNoise(self, type=1, channel=None):
408
408
409 if type == 1:
409 if type == 1:
410 noise = self.getNoisebyHildebrand(channel)
410 noise = self.getNoisebyHildebrand(channel)
411
411
412 return noise
412 return noise
413
413
414 def getPower(self, channel=None):
414 def getPower(self, channel=None):
415
415
416 if channel != None:
416 if channel != None:
417 data = self.data[channel]
417 data = self.data[channel]
418 else:
418 else:
419 data = self.data
419 data = self.data
420
420
421 power = data * numpy.conjugate(data)
421 power = data * numpy.conjugate(data)
422 powerdB = 10 * numpy.log10(power.real)
422 powerdB = 10 * numpy.log10(power.real)
423 powerdB = numpy.squeeze(powerdB)
423 powerdB = numpy.squeeze(powerdB)
424
424
425 return powerdB
425 return powerdB
426
426
427 @property
427 @property
428 def timeInterval(self):
428 def timeInterval(self):
429
429
430 return self.ippSeconds * self.nCohInt
430 return self.ippSeconds * self.nCohInt
431
431
432 noise = property(getNoise, "I'm the 'nHeights' property.")
432 noise = property(getNoise, "I'm the 'nHeights' property.")
433
433
434
434
435 class Spectra(JROData):
435 class Spectra(JROData):
436
436
437 def __init__(self):
437 def __init__(self):
438 '''
438 '''
439 Constructor
439 Constructor
440 '''
440 '''
441
441
442 self.data_dc = None
442 self.data_dc = None
443 self.data_spc = None
443 self.data_spc = None
444 self.data_cspc = None
444 self.data_cspc = None
445 self.useLocalTime = True
445 self.useLocalTime = True
446 self.radarControllerHeaderObj = RadarControllerHeader()
446 self.radarControllerHeaderObj = RadarControllerHeader()
447 self.systemHeaderObj = SystemHeader()
447 self.systemHeaderObj = SystemHeader()
448 self.type = "Spectra"
448 self.type = "Spectra"
449 self.timeZone = 0
449 self.timeZone = 0
450 self.nProfiles = None
450 self.nProfiles = None
451 self.heightList = None
451 self.heightList = None
452 self.channelList = None
452 self.channelList = None
453 self.pairsList = None
453 self.pairsList = None
454 self.flagNoData = True
454 self.flagNoData = True
455 self.flagDiscontinuousBlock = False
455 self.flagDiscontinuousBlock = False
456 self.utctime = None
456 self.utctime = None
457 self.nCohInt = None
457 self.nCohInt = None
458 self.nIncohInt = None
458 self.nIncohInt = None
459 self.blocksize = None
459 self.blocksize = None
460 self.nFFTPoints = None
460 self.nFFTPoints = None
461 self.wavelength = None
461 self.wavelength = None
462 self.flagDecodeData = False # asumo q la data no esta decodificada
462 self.flagDecodeData = False # asumo q la data no esta decodificada
463 self.flagDeflipData = False # asumo q la data no esta sin flip
463 self.flagDeflipData = False # asumo q la data no esta sin flip
464 self.flagShiftFFT = False
464 self.flagShiftFFT = False
465 self.ippFactor = 1
465 self.ippFactor = 1
466 self.beacon_heiIndexList = []
466 self.beacon_heiIndexList = []
467 self.noise_estimation = None
467 self.noise_estimation = None
468 self.codeList = []
468 self.codeList = []
469 self.azimuthList = []
469 self.azimuthList = []
470 self.elevationList = []
470 self.elevationList = []
471 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
471 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
472 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
472 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
473
473
474
474
475 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
475 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
476 """
476 """
477 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
477 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
478
478
479 Return:
479 Return:
480 noiselevel
480 noiselevel
481 """
481 """
482
482
483 noise = numpy.zeros(self.nChannels)
483 noise = numpy.zeros(self.nChannels)
484 for channel in range(self.nChannels):
484 for channel in range(self.nChannels):
485 daux = self.data_spc[channel,
485 daux = self.data_spc[channel,
486 xmin_index:xmax_index, ymin_index:ymax_index]
486 xmin_index:xmax_index, ymin_index:ymax_index]
487 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
487 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
488
488
489 return noise
489 return noise
490
490
491 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
491 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
492
492
493 if self.noise_estimation is not None:
493 if self.noise_estimation is not None:
494 # this was estimated by getNoise Operation defined in jroproc_spectra.py
494 # this was estimated by getNoise Operation defined in jroproc_spectra.py
495 return self.noise_estimation
495 return self.noise_estimation
496 else:
496 else:
497 noise = self.getNoisebyHildebrand(
497 noise = self.getNoisebyHildebrand(
498 xmin_index, xmax_index, ymin_index, ymax_index)
498 xmin_index, xmax_index, ymin_index, ymax_index)
499 return noise
499 return noise
500
500
501 def getFreqRangeTimeResponse(self, extrapoints=0):
501 def getFreqRangeTimeResponse(self, extrapoints=0):
502
502
503 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
503 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
504 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
504 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
505
505
506 return freqrange
506 return freqrange
507
507
508 def getAcfRange(self, extrapoints=0):
508 def getAcfRange(self, extrapoints=0):
509
509
510 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
510 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
511 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
511 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
512
512
513 return freqrange
513 return freqrange
514
514
515 def getFreqRange(self, extrapoints=0):
515 def getFreqRange(self, extrapoints=0):
516
516
517 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
517 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
518 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
518 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
519
519
520 return freqrange
520 return freqrange
521
521
522 def getVelRange(self, extrapoints=0):
522 def getVelRange(self, extrapoints=0):
523
523
524 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
524 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
525 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
525 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
526
526
527 if self.nmodes:
527 if self.nmodes:
528 return velrange/self.nmodes
528 return velrange/self.nmodes
529 else:
529 else:
530 return velrange
530 return velrange
531
531
532 @property
532 @property
533 def nPairs(self):
533 def nPairs(self):
534
534
535 return len(self.pairsList)
535 return len(self.pairsList)
536
536
537 @property
537 @property
538 def pairsIndexList(self):
538 def pairsIndexList(self):
539
539
540 return list(range(self.nPairs))
540 return list(range(self.nPairs))
541
541
542 @property
542 @property
543 def normFactor(self):
543 def normFactor(self):
544
544
545 pwcode = 1
545 pwcode = 1
546
546
547 if self.flagDecodeData:
547 if self.flagDecodeData:
548 pwcode = numpy.sum(self.code[0]**2)
548 pwcode = numpy.sum(self.code[0]**2)
549 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
549 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
550 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
550 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
551
551
552 return normFactor
552 return normFactor
553
553
554 @property
554 @property
555 def flag_cspc(self):
555 def flag_cspc(self):
556
556
557 if self.data_cspc is None:
557 if self.data_cspc is None:
558 return True
558 return True
559
559
560 return False
560 return False
561
561
562 @property
562 @property
563 def flag_dc(self):
563 def flag_dc(self):
564
564
565 if self.data_dc is None:
565 if self.data_dc is None:
566 return True
566 return True
567
567
568 return False
568 return False
569
569
570 @property
570 @property
571 def timeInterval(self):
571 def timeInterval(self):
572
572
573 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
573 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
574 if self.nmodes:
574 if self.nmodes:
575 return self.nmodes*timeInterval
575 return self.nmodes*timeInterval
576 else:
576 else:
577 return timeInterval
577 return timeInterval
578
578
579 def getPower(self):
579 def getPower(self):
580
580
581 factor = self.normFactor
581 factor = self.normFactor
582 z = self.data_spc / factor
582 z = self.data_spc / factor
583 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
583 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
584 avg = numpy.average(z, axis=1)
584 avg = numpy.average(z, axis=1)
585
585
586 return 10 * numpy.log10(avg)
586 return 10 * numpy.log10(avg)
587
587
588 def getCoherence(self, pairsList=None, phase=False):
588 def getCoherence(self, pairsList=None, phase=False):
589
589
590 z = []
590 z = []
591 if pairsList is None:
591 if pairsList is None:
592 pairsIndexList = self.pairsIndexList
592 pairsIndexList = self.pairsIndexList
593 else:
593 else:
594 pairsIndexList = []
594 pairsIndexList = []
595 for pair in pairsList:
595 for pair in pairsList:
596 if pair not in self.pairsList:
596 if pair not in self.pairsList:
597 raise ValueError("Pair %s is not in dataOut.pairsList" % (
597 raise ValueError("Pair %s is not in dataOut.pairsList" % (
598 pair))
598 pair))
599 pairsIndexList.append(self.pairsList.index(pair))
599 pairsIndexList.append(self.pairsList.index(pair))
600 for i in range(len(pairsIndexList)):
600 for i in range(len(pairsIndexList)):
601 pair = self.pairsList[pairsIndexList[i]]
601 pair = self.pairsList[pairsIndexList[i]]
602 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
602 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
603 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
603 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
604 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
604 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
605 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
605 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
606 if phase:
606 if phase:
607 data = numpy.arctan2(avgcoherenceComplex.imag,
607 data = numpy.arctan2(avgcoherenceComplex.imag,
608 avgcoherenceComplex.real) * 180 / numpy.pi
608 avgcoherenceComplex.real) * 180 / numpy.pi
609 else:
609 else:
610 data = numpy.abs(avgcoherenceComplex)
610 data = numpy.abs(avgcoherenceComplex)
611
611
612 z.append(data)
612 z.append(data)
613
613
614 return numpy.array(z)
614 return numpy.array(z)
615
615
616 def setValue(self, value):
616 def setValue(self, value):
617
617
618 print("This property should not be initialized")
618 print("This property should not be initialized")
619
619
620 return
620 return
621
621
622 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
622 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
623
623
624
624
625 class SpectraHeis(Spectra):
625 class SpectraHeis(Spectra):
626
626
627 def __init__(self):
627 def __init__(self):
628
628
629 self.radarControllerHeaderObj = RadarControllerHeader()
629 self.radarControllerHeaderObj = RadarControllerHeader()
630 self.systemHeaderObj = SystemHeader()
630 self.systemHeaderObj = SystemHeader()
631 self.type = "SpectraHeis"
631 self.type = "SpectraHeis"
632 self.nProfiles = None
632 self.nProfiles = None
633 self.heightList = None
633 self.heightList = None
634 self.channelList = None
634 self.channelList = None
635 self.flagNoData = True
635 self.flagNoData = True
636 self.flagDiscontinuousBlock = False
636 self.flagDiscontinuousBlock = False
637 self.utctime = None
637 self.utctime = None
638 self.blocksize = None
638 self.blocksize = None
639 self.profileIndex = 0
639 self.profileIndex = 0
640 self.nCohInt = 1
640 self.nCohInt = 1
641 self.nIncohInt = 1
641 self.nIncohInt = 1
642
642
643 @property
643 @property
644 def normFactor(self):
644 def normFactor(self):
645 pwcode = 1
645 pwcode = 1
646 if self.flagDecodeData:
646 if self.flagDecodeData:
647 pwcode = numpy.sum(self.code[0]**2)
647 pwcode = numpy.sum(self.code[0]**2)
648
648
649 normFactor = self.nIncohInt * self.nCohInt * pwcode
649 normFactor = self.nIncohInt * self.nCohInt * pwcode
650
650
651 return normFactor
651 return normFactor
652
652
653 @property
653 @property
654 def timeInterval(self):
654 def timeInterval(self):
655
655
656 return self.ippSeconds * self.nCohInt * self.nIncohInt
656 return self.ippSeconds * self.nCohInt * self.nIncohInt
657
657
658
658
659 class Fits(JROData):
659 class Fits(JROData):
660
660
661 def __init__(self):
661 def __init__(self):
662
662
663 self.type = "Fits"
663 self.type = "Fits"
664 self.nProfiles = None
664 self.nProfiles = None
665 self.heightList = None
665 self.heightList = None
666 self.channelList = None
666 self.channelList = None
667 self.flagNoData = True
667 self.flagNoData = True
668 self.utctime = None
668 self.utctime = None
669 self.nCohInt = 1
669 self.nCohInt = 1
670 self.nIncohInt = 1
670 self.nIncohInt = 1
671 self.useLocalTime = True
671 self.useLocalTime = True
672 self.profileIndex = 0
672 self.profileIndex = 0
673 self.timeZone = 0
673 self.timeZone = 0
674
674
675 def getTimeRange(self):
675 def getTimeRange(self):
676
676
677 datatime = []
677 datatime = []
678
678
679 datatime.append(self.ltctime)
679 datatime.append(self.ltctime)
680 datatime.append(self.ltctime + self.timeInterval)
680 datatime.append(self.ltctime + self.timeInterval)
681
681
682 datatime = numpy.array(datatime)
682 datatime = numpy.array(datatime)
683
683
684 return datatime
684 return datatime
685
685
686 def getChannelIndexList(self):
686 def getChannelIndexList(self):
687
687
688 return list(range(self.nChannels))
688 return list(range(self.nChannels))
689
689
690 def getNoise(self, type=1):
690 def getNoise(self, type=1):
691
691
692
692
693 if type == 1:
693 if type == 1:
694 noise = self.getNoisebyHildebrand()
694 noise = self.getNoisebyHildebrand()
695
695
696 if type == 2:
696 if type == 2:
697 noise = self.getNoisebySort()
697 noise = self.getNoisebySort()
698
698
699 if type == 3:
699 if type == 3:
700 noise = self.getNoisebyWindow()
700 noise = self.getNoisebyWindow()
701
701
702 return noise
702 return noise
703
703
704 @property
704 @property
705 def timeInterval(self):
705 def timeInterval(self):
706
706
707 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
707 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
708
708
709 return timeInterval
709 return timeInterval
710
710
711 @property
711 @property
712 def ippSeconds(self):
712 def ippSeconds(self):
713 '''
713 '''
714 '''
714 '''
715 return self.ipp_sec
715 return self.ipp_sec
716
716
717 noise = property(getNoise, "I'm the 'nHeights' property.")
717 noise = property(getNoise, "I'm the 'nHeights' property.")
718
718
719
719
720 class Correlation(JROData):
720 class Correlation(JROData):
721
721
722 def __init__(self):
722 def __init__(self):
723 '''
723 '''
724 Constructor
724 Constructor
725 '''
725 '''
726 self.radarControllerHeaderObj = RadarControllerHeader()
726 self.radarControllerHeaderObj = RadarControllerHeader()
727 self.systemHeaderObj = SystemHeader()
727 self.systemHeaderObj = SystemHeader()
728 self.type = "Correlation"
728 self.type = "Correlation"
729 self.data = None
729 self.data = None
730 self.dtype = None
730 self.dtype = None
731 self.nProfiles = None
731 self.nProfiles = None
732 self.heightList = None
732 self.heightList = None
733 self.channelList = None
733 self.channelList = None
734 self.flagNoData = True
734 self.flagNoData = True
735 self.flagDiscontinuousBlock = False
735 self.flagDiscontinuousBlock = False
736 self.utctime = None
736 self.utctime = None
737 self.timeZone = 0
737 self.timeZone = 0
738 self.dstFlag = None
738 self.dstFlag = None
739 self.errorCount = None
739 self.errorCount = None
740 self.blocksize = None
740 self.blocksize = None
741 self.flagDecodeData = False # asumo q la data no esta decodificada
741 self.flagDecodeData = False # asumo q la data no esta decodificada
742 self.flagDeflipData = False # asumo q la data no esta sin flip
742 self.flagDeflipData = False # asumo q la data no esta sin flip
743 self.pairsList = None
743 self.pairsList = None
744 self.nPoints = None
744 self.nPoints = None
745
745
746 def getPairsList(self):
746 def getPairsList(self):
747
747
748 return self.pairsList
748 return self.pairsList
749
749
750 def getNoise(self, mode=2):
750 def getNoise(self, mode=2):
751
751
752 indR = numpy.where(self.lagR == 0)[0][0]
752 indR = numpy.where(self.lagR == 0)[0][0]
753 indT = numpy.where(self.lagT == 0)[0][0]
753 indT = numpy.where(self.lagT == 0)[0][0]
754
754
755 jspectra0 = self.data_corr[:, :, indR, :]
755 jspectra0 = self.data_corr[:, :, indR, :]
756 jspectra = copy.copy(jspectra0)
756 jspectra = copy.copy(jspectra0)
757
757
758 num_chan = jspectra.shape[0]
758 num_chan = jspectra.shape[0]
759 num_hei = jspectra.shape[2]
759 num_hei = jspectra.shape[2]
760
760
761 freq_dc = jspectra.shape[1] / 2
761 freq_dc = jspectra.shape[1] / 2
762 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
762 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
763
763
764 if ind_vel[0] < 0:
764 if ind_vel[0] < 0:
765 ind_vel[list(range(0, 1))] = ind_vel[list(
765 ind_vel[list(range(0, 1))] = ind_vel[list(
766 range(0, 1))] + self.num_prof
766 range(0, 1))] + self.num_prof
767
767
768 if mode == 1:
768 if mode == 1:
769 jspectra[:, freq_dc, :] = (
769 jspectra[:, freq_dc, :] = (
770 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
770 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
771
771
772 if mode == 2:
772 if mode == 2:
773
773
774 vel = numpy.array([-2, -1, 1, 2])
774 vel = numpy.array([-2, -1, 1, 2])
775 xx = numpy.zeros([4, 4])
775 xx = numpy.zeros([4, 4])
776
776
777 for fil in range(4):
777 for fil in range(4):
778 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
778 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
779
779
780 xx_inv = numpy.linalg.inv(xx)
780 xx_inv = numpy.linalg.inv(xx)
781 xx_aux = xx_inv[0, :]
781 xx_aux = xx_inv[0, :]
782
782
783 for ich in range(num_chan):
783 for ich in range(num_chan):
784 yy = jspectra[ich, ind_vel, :]
784 yy = jspectra[ich, ind_vel, :]
785 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
785 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
786
786
787 junkid = jspectra[ich, freq_dc, :] <= 0
787 junkid = jspectra[ich, freq_dc, :] <= 0
788 cjunkid = sum(junkid)
788 cjunkid = sum(junkid)
789
789
790 if cjunkid.any():
790 if cjunkid.any():
791 jspectra[ich, freq_dc, junkid.nonzero()] = (
791 jspectra[ich, freq_dc, junkid.nonzero()] = (
792 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
792 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
793
793
794 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
794 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
795
795
796 return noise
796 return noise
797
797
798 @property
798 @property
799 def timeInterval(self):
799 def timeInterval(self):
800
800
801 return self.ippSeconds * self.nCohInt * self.nProfiles
801 return self.ippSeconds * self.nCohInt * self.nProfiles
802
802
803 def splitFunctions(self):
803 def splitFunctions(self):
804
804
805 pairsList = self.pairsList
805 pairsList = self.pairsList
806 ccf_pairs = []
806 ccf_pairs = []
807 acf_pairs = []
807 acf_pairs = []
808 ccf_ind = []
808 ccf_ind = []
809 acf_ind = []
809 acf_ind = []
810 for l in range(len(pairsList)):
810 for l in range(len(pairsList)):
811 chan0 = pairsList[l][0]
811 chan0 = pairsList[l][0]
812 chan1 = pairsList[l][1]
812 chan1 = pairsList[l][1]
813
813
814 # Obteniendo pares de Autocorrelacion
814 # Obteniendo pares de Autocorrelacion
815 if chan0 == chan1:
815 if chan0 == chan1:
816 acf_pairs.append(chan0)
816 acf_pairs.append(chan0)
817 acf_ind.append(l)
817 acf_ind.append(l)
818 else:
818 else:
819 ccf_pairs.append(pairsList[l])
819 ccf_pairs.append(pairsList[l])
820 ccf_ind.append(l)
820 ccf_ind.append(l)
821
821
822 data_acf = self.data_cf[acf_ind]
822 data_acf = self.data_cf[acf_ind]
823 data_ccf = self.data_cf[ccf_ind]
823 data_ccf = self.data_cf[ccf_ind]
824
824
825 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
825 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
826
826
827 @property
827 @property
828 def normFactor(self):
828 def normFactor(self):
829 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
829 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
830 acf_pairs = numpy.array(acf_pairs)
830 acf_pairs = numpy.array(acf_pairs)
831 normFactor = numpy.zeros((self.nPairs, self.nHeights))
831 normFactor = numpy.zeros((self.nPairs, self.nHeights))
832
832
833 for p in range(self.nPairs):
833 for p in range(self.nPairs):
834 pair = self.pairsList[p]
834 pair = self.pairsList[p]
835
835
836 ch0 = pair[0]
836 ch0 = pair[0]
837 ch1 = pair[1]
837 ch1 = pair[1]
838
838
839 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
839 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
840 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
840 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
841 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
841 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
842
842
843 return normFactor
843 return normFactor
844
844
845
845
846 class Parameters(Spectra):
846 class Parameters(Spectra):
847
847
848 groupList = None # List of Pairs, Groups, etc
848 groupList = None # List of Pairs, Groups, etc
849 data_param = None # Parameters obtained
849 data_param = None # Parameters obtained
850 data_pre = None # Data Pre Parametrization
850 data_pre = None # Data Pre Parametrization
851 data_SNR = None # Signal to Noise Ratio
851 data_SNR = None # Signal to Noise Ratio
852 abscissaList = None # Abscissa, can be velocities, lags or time
852 abscissaList = None # Abscissa, can be velocities, lags or time
853 utctimeInit = None # Initial UTC time
853 utctimeInit = None # Initial UTC time
854 paramInterval = None # Time interval to calculate Parameters in seconds
854 paramInterval = None # Time interval to calculate Parameters in seconds
855 useLocalTime = True
855 useLocalTime = True
856 # Fitting
856 # Fitting
857 data_error = None # Error of the estimation
857 data_error = None # Error of the estimation
858 constants = None
858 constants = None
859 library = None
859 library = None
860 # Output signal
860 # Output signal
861 outputInterval = None # Time interval to calculate output signal in seconds
861 outputInterval = None # Time interval to calculate output signal in seconds
862 data_output = None # Out signal
862 data_output = None # Out signal
863 nAvg = None
863 nAvg = None
864 noise_estimation = None
864 noise_estimation = None
865 GauSPC = None # Fit gaussian SPC
865 GauSPC = None # Fit gaussian SPC
866
866
867 def __init__(self):
867 def __init__(self):
868 '''
868 '''
869 Constructor
869 Constructor
870 '''
870 '''
871 self.radarControllerHeaderObj = RadarControllerHeader()
871 self.radarControllerHeaderObj = RadarControllerHeader()
872 self.systemHeaderObj = SystemHeader()
872 self.systemHeaderObj = SystemHeader()
873 self.type = "Parameters"
873 self.type = "Parameters"
874 self.timeZone = 0
874 self.timeZone = 0
875
875
876 def getTimeRange1(self, interval):
876 def getTimeRange1(self, interval):
877
877
878 datatime = []
878 datatime = []
879
879
880 if self.useLocalTime:
880 if self.useLocalTime:
881 time1 = self.utctimeInit - self.timeZone * 60
881 time1 = self.utctimeInit - self.timeZone * 60
882 else:
882 else:
883 time1 = self.utctimeInit
883 time1 = self.utctimeInit
884
884
885 datatime.append(time1)
885 datatime.append(time1)
886 datatime.append(time1 + interval)
886 datatime.append(time1 + interval)
887 datatime = numpy.array(datatime)
887 datatime = numpy.array(datatime)
888
888
889 return datatime
889 return datatime
890
890
891 @property
891 @property
892 def timeInterval(self):
892 def timeInterval(self):
893
893
894 if hasattr(self, 'timeInterval1'):
894 if hasattr(self, 'timeInterval1'):
895 return self.timeInterval1
895 return self.timeInterval1
896 else:
896 else:
897 return self.paramInterval
897 return self.paramInterval
898
898
899 def setValue(self, value):
899 def setValue(self, value):
900
900
901 print("This property should not be initialized")
901 print("This property should not be initialized")
902
902
903 return
903 return
904
904
905 def getNoise(self):
905 def getNoise(self):
906
906
907 return self.spc_noise
907 return self.spc_noise
908
908
909 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
909 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
910
910
911
911
912 class PlotterData(object):
912 class PlotterData(object):
913 '''
913 '''
914 Object to hold data to be plotted
914 Object to hold data to be plotted
915 '''
915 '''
916
916
917 MAXNUMX = 200
917 MAXNUMX = 200
918 MAXNUMY = 200
918 MAXNUMY = 200
919
919
920 def __init__(self, code, exp_code, localtime=True):
920 def __init__(self, code, exp_code, localtime=True):
921
921
922 self.key = code
922 self.key = code
923 self.exp_code = exp_code
923 self.exp_code = exp_code
924 self.ready = False
924 self.ready = False
925 self.flagNoData = False
925 self.flagNoData = False
926 self.localtime = localtime
926 self.localtime = localtime
927 self.data = {}
927 self.data = {}
928 self.meta = {}
928 self.meta = {}
929 self.__heights = []
929 self.__heights = []
930
930
931 def __str__(self):
931 def __str__(self):
932 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
932 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
933 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
933 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
934
934
935 def __len__(self):
935 def __len__(self):
936 return len(self.data)
936 return len(self.data)
937
937
938 def __getitem__(self, key):
938 def __getitem__(self, key):
939 if isinstance(key, int):
939 if isinstance(key, int):
940 return self.data[self.times[key]]
940 return self.data[self.times[key]]
941 elif isinstance(key, str):
941 elif isinstance(key, str):
942 ret = numpy.array([self.data[x][key] for x in self.times])
942 ret = numpy.array([self.data[x][key] for x in self.times])
943 if ret.ndim > 1:
943 if ret.ndim > 1:
944 ret = numpy.swapaxes(ret, 0, 1)
944 ret = numpy.swapaxes(ret, 0, 1)
945 return ret
945 return ret
946
946
947 def __contains__(self, key):
947 def __contains__(self, key):
948 return key in self.data[self.min_time]
948 return key in self.data[self.min_time]
949
949
950 def setup(self):
950 def setup(self):
951 '''
951 '''
952 Configure object
952 Configure object
953 '''
953 '''
954 self.type = ''
954 self.type = ''
955 self.ready = False
955 self.ready = False
956 del self.data
956 del self.data
957 self.data = {}
957 self.data = {}
958 self.__heights = []
958 self.__heights = []
959 self.__all_heights = set()
959 self.__all_heights = set()
960
960
961 def shape(self, key):
961 def shape(self, key):
962 '''
962 '''
963 Get the shape of the one-element data for the given key
963 Get the shape of the one-element data for the given key
964 '''
964 '''
965
965
966 if len(self.data[self.min_time][key]):
966 if len(self.data[self.min_time][key]):
967 return self.data[self.min_time][key].shape
967 return self.data[self.min_time][key].shape
968 return (0,)
968 return (0,)
969
969
970 def update(self, data, tm, meta={}):
970 def update(self, data, tm, meta={}):
971 '''
971 '''
972 Update data object with new dataOut
972 Update data object with new dataOut
973 '''
973 '''
974
974
975 self.data[tm] = data
975 self.data[tm] = data
976
976
977 for key, value in meta.items():
977 for key, value in meta.items():
978 setattr(self, key, value)
978 setattr(self, key, value)
979
979
980 def normalize_heights(self):
980 def normalize_heights(self):
981 '''
981 '''
982 Ensure same-dimension of the data for different heighList
982 Ensure same-dimension of the data for different heighList
983 '''
983 '''
984
984
985 H = numpy.array(list(self.__all_heights))
985 H = numpy.array(list(self.__all_heights))
986 H.sort()
986 H.sort()
987 for key in self.data:
987 for key in self.data:
988 shape = self.shape(key)[:-1] + H.shape
988 shape = self.shape(key)[:-1] + H.shape
989 for tm, obj in list(self.data[key].items()):
989 for tm, obj in list(self.data[key].items()):
990 h = self.__heights[self.times.tolist().index(tm)]
990 h = self.__heights[self.times.tolist().index(tm)]
991 if H.size == h.size:
991 if H.size == h.size:
992 continue
992 continue
993 index = numpy.where(numpy.in1d(H, h))[0]
993 index = numpy.where(numpy.in1d(H, h))[0]
994 dummy = numpy.zeros(shape) + numpy.nan
994 dummy = numpy.zeros(shape) + numpy.nan
995 if len(shape) == 2:
995 if len(shape) == 2:
996 dummy[:, index] = obj
996 dummy[:, index] = obj
997 else:
997 else:
998 dummy[index] = obj
998 dummy[index] = obj
999 self.data[key][tm] = dummy
999 self.data[key][tm] = dummy
1000
1000
1001 self.__heights = [H for tm in self.times]
1001 self.__heights = [H for tm in self.times]
1002
1002
1003 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1003 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1004 '''
1004 '''
1005 Convert data to json
1005 Convert data to json
1006 '''
1006 '''
1007
1007
1008 meta = {}
1008 meta = {}
1009 meta['xrange'] = []
1009 meta['xrange'] = []
1010 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1010 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1011 tmp = self.data[tm][self.key]
1011 tmp = self.data[tm][self.key]
1012 shape = tmp.shape
1012 shape = tmp.shape
1013 if len(shape) == 2:
1013 if len(shape) == 2:
1014 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1014 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1015 elif len(shape) == 3:
1015 elif len(shape) == 3:
1016 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1016 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1017 data = self.roundFloats(
1017 data = self.roundFloats(
1018 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1018 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1019 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1019 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1020 else:
1020 else:
1021 data = self.roundFloats(self.data[tm][self.key].tolist())
1021 data = self.roundFloats(self.data[tm][self.key].tolist())
1022
1022
1023 ret = {
1023 ret = {
1024 'plot': plot_name,
1024 'plot': plot_name,
1025 'code': self.exp_code,
1025 'code': self.exp_code,
1026 'time': float(tm),
1026 'time': float(tm),
1027 'data': data,
1027 'data': data,
1028 }
1028 }
1029 meta['type'] = plot_type
1029 meta['type'] = plot_type
1030 meta['interval'] = float(self.interval)
1030 meta['interval'] = float(self.interval)
1031 meta['localtime'] = self.localtime
1031 meta['localtime'] = self.localtime
1032 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1032 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1033 meta.update(self.meta)
1033 meta.update(self.meta)
1034 ret['metadata'] = meta
1034 ret['metadata'] = meta
1035 return json.dumps(ret)
1035 return json.dumps(ret)
1036
1036
1037 @property
1037 @property
1038 def times(self):
1038 def times(self):
1039 '''
1039 '''
1040 Return the list of times of the current data
1040 Return the list of times of the current data
1041 '''
1041 '''
1042
1042
1043 ret = [t for t in self.data]
1043 ret = [t for t in self.data]
1044 ret.sort()
1044 ret.sort()
1045 return numpy.array(ret)
1045 return numpy.array(ret)
1046
1046
1047 @property
1047 @property
1048 def min_time(self):
1048 def min_time(self):
1049 '''
1049 '''
1050 Return the minimun time value
1050 Return the minimun time value
1051 '''
1051 '''
1052
1052
1053 return self.times[0]
1053 return self.times[0]
1054
1054
1055 @property
1055 @property
1056 def max_time(self):
1056 def max_time(self):
1057 '''
1057 '''
1058 Return the maximun time value
1058 Return the maximun time value
1059 '''
1059 '''
1060
1060
1061 return self.times[-1]
1061 return self.times[-1]
1062
1062
1063 # @property
1063 # @property
1064 # def heights(self):
1064 # def heights(self):
1065 # '''
1065 # '''
1066 # Return the list of heights of the current data
1066 # Return the list of heights of the current data
1067 # '''
1067 # '''
1068
1068
1069 # return numpy.array(self.__heights[-1])
1069 # return numpy.array(self.__heights[-1])
1070
1070
1071 @staticmethod
1071 @staticmethod
1072 def roundFloats(obj):
1072 def roundFloats(obj):
1073 if isinstance(obj, list):
1073 if isinstance(obj, list):
1074 return list(map(PlotterData.roundFloats, obj))
1074 return list(map(PlotterData.roundFloats, obj))
1075 elif isinstance(obj, float):
1075 elif isinstance(obj, float):
1076 return round(obj, 2)
1076 return round(obj, 2)
@@ -1,961 +1,962
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 """Classes to plot Spectra data
5 """Classes to plot Spectra data
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import numpy
10 import numpy
11
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 from itertools import combinations
13 from itertools import combinations
14
14
15
15
16 class SpectraPlot(Plot):
16 class SpectraPlot(Plot):
17 '''
17 '''
18 Plot for Spectra data
18 Plot for Spectra data
19 '''
19 '''
20
20
21 CODE = 'spc'
21 CODE = 'spc'
22 colormap = 'jet'
22 colormap = 'jet'
23 plot_type = 'pcolor'
23 plot_type = 'pcolor'
24 buffering = False
24 buffering = False
25 channelList = []
25 channelList = []
26
26
27 def setup(self):
27 def setup(self):
28
28
29 self.nplots = len(self.data.channels)
29 self.nplots = len(self.data.channels)
30 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
30 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
31 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
31 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
32 self.height = 2.6 * self.nrows
32 self.height = 2.6 * self.nrows
33
33
34 self.cb_label = 'dB'
34 self.cb_label = 'dB'
35 if self.showprofile:
35 if self.showprofile:
36 self.width = 4 * self.ncols
36 self.width = 4 * self.ncols
37 else:
37 else:
38 self.width = 3.5 * self.ncols
38 self.width = 3.5 * self.ncols
39 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
39 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
40 self.ylabel = 'Range [km]'
40 self.ylabel = 'Range [km]'
41
41
42
42
43 def update_list(self,dataOut):
43 def update_list(self,dataOut):
44 if len(self.channelList) == 0:
44 if len(self.channelList) == 0:
45 self.channelList = dataOut.channelList
45 self.channelList = dataOut.channelList
46
46
47 def update(self, dataOut):
47 def update(self, dataOut):
48
48
49 self.update_list(dataOut)
49 self.update_list(dataOut)
50 data = {}
50 data = {}
51 meta = {}
51 meta = {}
52 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
52 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
53 data['spc'] = spc
53 data['spc'] = spc
54 data['rti'] = dataOut.getPower()
54 data['rti'] = dataOut.getPower()
55 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
55 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
56 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
56 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
57 if self.CODE == 'spc_moments':
57 if self.CODE == 'spc_moments':
58 data['moments'] = dataOut.moments
58 data['moments'] = dataOut.moments
59
59
60 return data, meta
60 return data, meta
61
61
62 def plot(self):
62 def plot(self):
63 if self.xaxis == "frequency":
63 if self.xaxis == "frequency":
64 x = self.data.xrange[0]
64 x = self.data.xrange[0]
65 self.xlabel = "Frequency (kHz)"
65 self.xlabel = "Frequency (kHz)"
66 elif self.xaxis == "time":
66 elif self.xaxis == "time":
67 x = self.data.xrange[1]
67 x = self.data.xrange[1]
68 self.xlabel = "Time (ms)"
68 self.xlabel = "Time (ms)"
69 else:
69 else:
70 x = self.data.xrange[2]
70 x = self.data.xrange[2]
71 self.xlabel = "Velocity (m/s)"
71 self.xlabel = "Velocity (m/s)"
72
72
73 if self.CODE == 'spc_moments':
73 if self.CODE == 'spc_moments':
74 x = self.data.xrange[2]
74 x = self.data.xrange[2]
75 self.xlabel = "Velocity (m/s)"
75 self.xlabel = "Velocity (m/s)"
76
76
77 self.titles = []
77 self.titles = []
78 y = self.data.yrange
78 y = self.data.yrange
79 self.y = y
79 self.y = y
80
80
81 data = self.data[-1]
81 data = self.data[-1]
82 z = data['spc']
82 z = data['spc']
83
83
84 for n, ax in enumerate(self.axes):
84 for n, ax in enumerate(self.axes):
85 noise = data['noise'][n]
85 noise = data['noise'][n]
86 if self.CODE == 'spc_moments':
86 if self.CODE == 'spc_moments':
87 mean = data['moments'][n, 1]
87 mean = data['moments'][n, 1]
88 if ax.firsttime:
88 if ax.firsttime:
89 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
89 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
90 self.xmin = self.xmin if self.xmin else -self.xmax
90 self.xmin = self.xmin if self.xmin else -self.xmax
91 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
91 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
92 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
92 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
93 ax.plt = ax.pcolormesh(x, y, z[n].T,
93 ax.plt = ax.pcolormesh(x, y, z[n].T,
94 vmin=self.zmin,
94 vmin=self.zmin,
95 vmax=self.zmax,
95 vmax=self.zmax,
96 cmap=plt.get_cmap(self.colormap)
96 cmap=plt.get_cmap(self.colormap)
97 )
97 )
98
98
99 if self.showprofile:
99 if self.showprofile:
100 ax.plt_profile = self.pf_axes[n].plot(
100 ax.plt_profile = self.pf_axes[n].plot(
101 data['rti'][n], y)[0]
101 data['rti'][n], y)[0]
102 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
102 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
103 color="k", linestyle="dashed", lw=1)[0]
103 color="k", linestyle="dashed", lw=1)[0]
104 if self.CODE == 'spc_moments':
104 if self.CODE == 'spc_moments':
105 ax.plt_mean = ax.plot(mean, y, color='k')[0]
105 ax.plt_mean = ax.plot(mean, y, color='k')[0]
106 else:
106 else:
107 ax.plt.set_array(z[n].T.ravel())
107 ax.plt.set_array(z[n].T.ravel())
108 if self.showprofile:
108 if self.showprofile:
109 ax.plt_profile.set_data(data['rti'][n], y)
109 ax.plt_profile.set_data(data['rti'][n], y)
110 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
110 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
111 if self.CODE == 'spc_moments':
111 if self.CODE == 'spc_moments':
112 ax.plt_mean.set_data(mean, y)
112 ax.plt_mean.set_data(mean, y)
113 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
113 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
114
114
115
115
116 class CrossSpectraPlot(Plot):
116 class CrossSpectraPlot(Plot):
117
117
118 CODE = 'cspc'
118 CODE = 'cspc'
119 colormap = 'jet'
119 colormap = 'jet'
120 plot_type = 'pcolor'
120 plot_type = 'pcolor'
121 zmin_coh = None
121 zmin_coh = None
122 zmax_coh = None
122 zmax_coh = None
123 zmin_phase = None
123 zmin_phase = None
124 zmax_phase = None
124 zmax_phase = None
125 realChannels = None
125 realChannels = None
126 crossPairs = None
126 crossPairs = None
127
127
128 def setup(self):
128 def setup(self):
129
129
130 self.ncols = 4
130 self.ncols = 4
131 self.nplots = len(self.data.pairs) * 2
131 self.nplots = len(self.data.pairs) * 2
132 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
132 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
133 self.width = 3.1 * self.ncols
133 self.width = 3.1 * self.ncols
134 self.height = 2.6 * self.nrows
134 self.height = 2.6 * self.nrows
135 self.ylabel = 'Range [km]'
135 self.ylabel = 'Range [km]'
136 self.showprofile = False
136 self.showprofile = False
137 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
137 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
138
138
139 def update(self, dataOut):
139 def update(self, dataOut):
140
140
141 data = {}
141 data = {}
142 meta = {}
142 meta = {}
143
143
144 spc = dataOut.data_spc
144 spc = dataOut.data_spc
145 cspc = dataOut.data_cspc
145 cspc = dataOut.data_cspc
146 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
146 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
147 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
147 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
148 meta['pairs'] = rawPairs
148 meta['pairs'] = rawPairs
149
149
150 if self.crossPairs == None:
150 if self.crossPairs == None:
151 self.crossPairs = dataOut.pairsList
151 self.crossPairs = dataOut.pairsList
152
152
153 tmp = []
153 tmp = []
154
154
155 for n, pair in enumerate(meta['pairs']):
155 for n, pair in enumerate(meta['pairs']):
156
156
157 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
157 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
158 coh = numpy.abs(out)
158 coh = numpy.abs(out)
159 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
159 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
160 tmp.append(coh)
160 tmp.append(coh)
161 tmp.append(phase)
161 tmp.append(phase)
162
162
163 data['cspc'] = numpy.array(tmp)
163 data['cspc'] = numpy.array(tmp)
164
164
165 return data, meta
165 return data, meta
166
166
167 def plot(self):
167 def plot(self):
168
168
169 if self.xaxis == "frequency":
169 if self.xaxis == "frequency":
170 x = self.data.xrange[0]
170 x = self.data.xrange[0]
171 self.xlabel = "Frequency (kHz)"
171 self.xlabel = "Frequency (kHz)"
172 elif self.xaxis == "time":
172 elif self.xaxis == "time":
173 x = self.data.xrange[1]
173 x = self.data.xrange[1]
174 self.xlabel = "Time (ms)"
174 self.xlabel = "Time (ms)"
175 else:
175 else:
176 x = self.data.xrange[2]
176 x = self.data.xrange[2]
177 self.xlabel = "Velocity (m/s)"
177 self.xlabel = "Velocity (m/s)"
178
178
179 self.titles = []
179 self.titles = []
180
180
181 y = self.data.yrange
181 y = self.data.yrange
182 self.y = y
182 self.y = y
183
183
184 data = self.data[-1]
184 data = self.data[-1]
185 cspc = data['cspc']
185 cspc = data['cspc']
186
186
187 for n in range(len(self.data.pairs)):
187 for n in range(len(self.data.pairs)):
188
188
189 pair = self.crossPairs[n]
189 pair = self.crossPairs[n]
190
190
191 coh = cspc[n*2]
191 coh = cspc[n*2]
192 phase = cspc[n*2+1]
192 phase = cspc[n*2+1]
193 ax = self.axes[2 * n]
193 ax = self.axes[2 * n]
194
194
195 if ax.firsttime:
195 if ax.firsttime:
196 ax.plt = ax.pcolormesh(x, y, coh.T,
196 ax.plt = ax.pcolormesh(x, y, coh.T,
197 vmin=self.zmin_coh,
197 vmin=self.zmin_coh,
198 vmax=self.zmax_coh,
198 vmax=self.zmax_coh,
199 cmap=plt.get_cmap(self.colormap_coh)
199 cmap=plt.get_cmap(self.colormap_coh)
200 )
200 )
201 else:
201 else:
202 ax.plt.set_array(coh.T.ravel())
202 ax.plt.set_array(coh.T.ravel())
203 self.titles.append(
203 self.titles.append(
204 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
204 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
205
205
206 ax = self.axes[2 * n + 1]
206 ax = self.axes[2 * n + 1]
207 if ax.firsttime:
207 if ax.firsttime:
208 ax.plt = ax.pcolormesh(x, y, phase.T,
208 ax.plt = ax.pcolormesh(x, y, phase.T,
209 vmin=-180,
209 vmin=-180,
210 vmax=180,
210 vmax=180,
211 cmap=plt.get_cmap(self.colormap_phase)
211 cmap=plt.get_cmap(self.colormap_phase)
212 )
212 )
213 else:
213 else:
214 ax.plt.set_array(phase.T.ravel())
214 ax.plt.set_array(phase.T.ravel())
215
215
216 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
216 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
217
217
218
218
219 class RTIPlot(Plot):
219 class RTIPlot(Plot):
220 '''
220 '''
221 Plot for RTI data
221 Plot for RTI data
222 '''
222 '''
223
223
224 CODE = 'rti'
224 CODE = 'rti'
225 colormap = 'jet'
225 colormap = 'jet'
226 plot_type = 'pcolorbuffer'
226 plot_type = 'pcolorbuffer'
227 titles = None
227 titles = None
228 channelList = []
228 channelList = []
229
229
230 def setup(self):
230 def setup(self):
231 self.xaxis = 'time'
231 self.xaxis = 'time'
232 self.ncols = 1
232 self.ncols = 1
233 #print("dataChannels ",self.data.channels)
233 #print("dataChannels ",self.data.channels)
234 self.nrows = len(self.data.channels)
234 self.nrows = len(self.data.channels)
235 self.nplots = len(self.data.channels)
235 self.nplots = len(self.data.channels)
236 self.ylabel = 'Range [km]'
236 self.ylabel = 'Range [km]'
237 self.xlabel = 'Time'
237 self.xlabel = 'Time'
238 self.cb_label = 'dB'
238 self.cb_label = 'dB'
239 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
239 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
240 self.titles = ['{} Channel {}'.format(
240 self.titles = ['{} Channel {}'.format(
241 self.CODE.upper(), x) for x in range(self.nplots)]
241 self.CODE.upper(), x) for x in range(self.nplots)]
242
242
243 def update_list(self,dataOut):
243 def update_list(self,dataOut):
244
244
245 self.channelList = dataOut.channelList
245 self.channelList = dataOut.channelList
246
246
247
247
248 def update(self, dataOut):
248 def update(self, dataOut):
249 if len(self.channelList) == 0:
249 if len(self.channelList) == 0:
250 self.update_list(dataOut)
250 self.update_list(dataOut)
251 data = {}
251 data = {}
252 meta = {}
252 meta = {}
253 data['rti'] = dataOut.getPower()
253 data['rti'] = dataOut.getPower()
254 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
254 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
255 return data, meta
255 return data, meta
256
256
257 def plot(self):
257 def plot(self):
258
258
259 self.x = self.data.times
259 self.x = self.data.times
260 self.y = self.data.yrange
260 self.y = self.data.yrange
261 self.z = self.data[self.CODE]
261 self.z = self.data[self.CODE]
262 self.z = numpy.array(self.z, dtype=float)
262 self.z = numpy.array(self.z, dtype=float)
263 self.z = numpy.ma.masked_invalid(self.z)
263 self.z = numpy.ma.masked_invalid(self.z)
264
264
265 try:
265 try:
266 if self.channelList != None:
266 if self.channelList != None:
267 self.titles = ['{} Channel {}'.format(
267 self.titles = ['{} Channel {}'.format(
268 self.CODE.upper(), x) for x in self.channelList]
268 self.CODE.upper(), x) for x in self.channelList]
269 except:
269 except:
270 if self.channelList.any() != None:
270 if self.channelList.any() != None:
271 self.titles = ['{} Channel {}'.format(
271 self.titles = ['{} Channel {}'.format(
272 self.CODE.upper(), x) for x in self.channelList]
272 self.CODE.upper(), x) for x in self.channelList]
273 if self.decimation is None:
273 if self.decimation is None:
274 x, y, z = self.fill_gaps(self.x, self.y, self.z)
274 x, y, z = self.fill_gaps(self.x, self.y, self.z)
275 else:
275 else:
276 x, y, z = self.fill_gaps(*self.decimate())
276 x, y, z = self.fill_gaps(*self.decimate())
277 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
277 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
278 for n, ax in enumerate(self.axes):
278 for n, ax in enumerate(self.axes):
279 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
279 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
280 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
280 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
281 data = self.data[-1]
281 data = self.data[-1]
282 if ax.firsttime:
282 if ax.firsttime:
283 ax.plt = ax.pcolormesh(x, y, z[n].T,
283 ax.plt = ax.pcolormesh(x, y, z[n].T,
284 vmin=self.zmin,
284 vmin=self.zmin,
285 vmax=self.zmax,
285 vmax=self.zmax,
286 cmap=plt.get_cmap(self.colormap)
286 cmap=plt.get_cmap(self.colormap)
287 )
287 )
288 if self.showprofile:
288 if self.showprofile:
289 ax.plot_profile = self.pf_axes[n].plot(data[self.CODE][n], self.y)[0]
289 ax.plot_profile = self.pf_axes[n].plot(data[self.CODE][n], self.y)[0]
290
290
291 if "noise" in self.data:
291 if "noise" in self.data:
292 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
292 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
293 color="k", linestyle="dashed", lw=1)[0]
293 color="k", linestyle="dashed", lw=1)[0]
294 else:
294 else:
295 ax.collections.remove(ax.collections[0])
295 ax.collections.remove(ax.collections[0])
296 ax.plt = ax.pcolormesh(x, y, z[n].T,
296 ax.plt = ax.pcolormesh(x, y, z[n].T,
297 vmin=self.zmin,
297 vmin=self.zmin,
298 vmax=self.zmax,
298 vmax=self.zmax,
299 cmap=plt.get_cmap(self.colormap)
299 cmap=plt.get_cmap(self.colormap)
300 )
300 )
301 if self.showprofile:
301 if self.showprofile:
302 ax.plot_profile.set_data(data[self.CODE][n], self.y)
302 ax.plot_profile.set_data(data[self.CODE][n], self.y)
303 if "noise" in self.data:
303 if "noise" in self.data:
304 ax.plot_noise.set_data(numpy.repeat(
304 ax.plot_noise.set_data(numpy.repeat(
305 data['noise'][n], len(self.y)), self.y)
305 data['noise'][n], len(self.y)), self.y)
306
306
307
307
308 class CoherencePlot(RTIPlot):
308 class CoherencePlot(RTIPlot):
309 '''
309 '''
310 Plot for Coherence data
310 Plot for Coherence data
311 '''
311 '''
312
312
313 CODE = 'coh'
313 CODE = 'coh'
314
314
315 def setup(self):
315 def setup(self):
316 self.xaxis = 'time'
316 self.xaxis = 'time'
317 self.ncols = 1
317 self.ncols = 1
318 self.nrows = len(self.data.pairs)
318 self.nrows = len(self.data.pairs)
319 self.nplots = len(self.data.pairs)
319 self.nplots = len(self.data.pairs)
320 self.ylabel = 'Range [km]'
320 self.ylabel = 'Range [km]'
321 self.xlabel = 'Time'
321 self.xlabel = 'Time'
322 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
322 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
323 if self.CODE == 'coh':
323 if self.CODE == 'coh':
324 self.cb_label = ''
324 self.cb_label = ''
325 self.titles = [
325 self.titles = [
326 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
326 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
327 else:
327 else:
328 self.cb_label = 'Degrees'
328 self.cb_label = 'Degrees'
329 self.titles = [
329 self.titles = [
330 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
330 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
331
331
332 def update(self, dataOut):
332 def update(self, dataOut):
333 self.update_list(dataOut)
333 self.update_list(dataOut)
334 data = {}
334 data = {}
335 meta = {}
335 meta = {}
336 data['coh'] = dataOut.getCoherence()
336 data['coh'] = dataOut.getCoherence()
337 meta['pairs'] = dataOut.pairsList
337 meta['pairs'] = dataOut.pairsList
338
338
339
339
340 return data, meta
340 return data, meta
341
341
342 class PhasePlot(CoherencePlot):
342 class PhasePlot(CoherencePlot):
343 '''
343 '''
344 Plot for Phase map data
344 Plot for Phase map data
345 '''
345 '''
346
346
347 CODE = 'phase'
347 CODE = 'phase'
348 colormap = 'seismic'
348 colormap = 'seismic'
349
349
350 def update(self, dataOut):
350 def update(self, dataOut):
351
351
352 data = {}
352 data = {}
353 meta = {}
353 meta = {}
354 data['phase'] = dataOut.getCoherence(phase=True)
354 data['phase'] = dataOut.getCoherence(phase=True)
355 meta['pairs'] = dataOut.pairsList
355 meta['pairs'] = dataOut.pairsList
356
356
357 return data, meta
357 return data, meta
358
358
359 class NoisePlot(Plot):
359 class NoisePlot(Plot):
360 '''
360 '''
361 Plot for noise
361 Plot for noise
362 '''
362 '''
363
363
364 CODE = 'noise'
364 CODE = 'noise'
365 plot_type = 'scatterbuffer'
365 plot_type = 'scatterbuffer'
366
366
367 def setup(self):
367 def setup(self):
368 self.xaxis = 'time'
368 self.xaxis = 'time'
369 self.ncols = 1
369 self.ncols = 1
370 self.nrows = 1
370 self.nrows = 1
371 self.nplots = 1
371 self.nplots = 1
372 self.ylabel = 'Intensity [dB]'
372 self.ylabel = 'Intensity [dB]'
373 self.xlabel = 'Time'
373 self.xlabel = 'Time'
374 self.titles = ['Noise']
374 self.titles = ['Noise']
375 self.colorbar = False
375 self.colorbar = False
376 self.plots_adjust.update({'right': 0.85 })
376 self.plots_adjust.update({'right': 0.85 })
377
377
378 def update(self, dataOut):
378 def update(self, dataOut):
379
379
380 data = {}
380 data = {}
381 meta = {}
381 meta = {}
382 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
382 noise = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
383 data['noise'] = noise
383 meta['yrange'] = numpy.array([])
384 meta['yrange'] = numpy.array([])
384
385
385 return data, meta
386 return data, meta
386
387
387 def plot(self):
388 def plot(self):
388
389
389 x = self.data.times
390 x = self.data.times
390 xmin = self.data.min_time
391 xmin = self.data.min_time
391 xmax = xmin + self.xrange * 60 * 60
392 xmax = xmin + self.xrange * 60 * 60
392 Y = self.data['noise']
393 Y = self.data['noise']
393
394
394 if self.axes[0].firsttime:
395 if self.axes[0].firsttime:
395 self.ymin = numpy.nanmin(Y) - 5
396 if self.ymin is None: self.ymin = numpy.nanmin(Y) - 5
396 self.ymax = numpy.nanmax(Y) + 5
397 if self.ymax is None: self.ymax = numpy.nanmax(Y) + 5
397 for ch in self.data.channels:
398 for ch in self.data.channels:
398 y = Y[ch]
399 y = Y[ch]
399 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
400 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
400 plt.legend(bbox_to_anchor=(1.18, 1.0))
401 plt.legend(bbox_to_anchor=(1.18, 1.0))
401 else:
402 else:
402 for ch in self.data.channels:
403 for ch in self.data.channels:
403 y = Y[ch]
404 y = Y[ch]
404 self.axes[0].lines[ch].set_data(x, y)
405 self.axes[0].lines[ch].set_data(x, y)
405
406
406
407
407 class PowerProfilePlot(Plot):
408 class PowerProfilePlot(Plot):
408
409
409 CODE = 'pow_profile'
410 CODE = 'pow_profile'
410 plot_type = 'scatter'
411 plot_type = 'scatter'
411
412
412 def setup(self):
413 def setup(self):
413
414
414 self.ncols = 1
415 self.ncols = 1
415 self.nrows = 1
416 self.nrows = 1
416 self.nplots = 1
417 self.nplots = 1
417 self.height = 4
418 self.height = 4
418 self.width = 3
419 self.width = 3
419 self.ylabel = 'Range [km]'
420 self.ylabel = 'Range [km]'
420 self.xlabel = 'Intensity [dB]'
421 self.xlabel = 'Intensity [dB]'
421 self.titles = ['Power Profile']
422 self.titles = ['Power Profile']
422 self.colorbar = False
423 self.colorbar = False
423
424
424 def update(self, dataOut):
425 def update(self, dataOut):
425
426
426 data = {}
427 data = {}
427 meta = {}
428 meta = {}
428 data[self.CODE] = dataOut.getPower()
429 data[self.CODE] = dataOut.getPower()
429
430
430 return data, meta
431 return data, meta
431
432
432 def plot(self):
433 def plot(self):
433
434
434 y = self.data.yrange
435 y = self.data.yrange
435 self.y = y
436 self.y = y
436
437
437 x = self.data[-1][self.CODE]
438 x = self.data[-1][self.CODE]
438
439
439 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
440 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
440 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
441 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
441
442
442 if self.axes[0].firsttime:
443 if self.axes[0].firsttime:
443 for ch in self.data.channels:
444 for ch in self.data.channels:
444 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
445 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
445 plt.legend()
446 plt.legend()
446 else:
447 else:
447 for ch in self.data.channels:
448 for ch in self.data.channels:
448 self.axes[0].lines[ch].set_data(x[ch], y)
449 self.axes[0].lines[ch].set_data(x[ch], y)
449
450
450
451
451 class SpectraCutPlot(Plot):
452 class SpectraCutPlot(Plot):
452
453
453 CODE = 'spc_cut'
454 CODE = 'spc_cut'
454 plot_type = 'scatter'
455 plot_type = 'scatter'
455 buffering = False
456 buffering = False
456 heights = []
457 heights = []
457 channelList = []
458 channelList = []
458 maintitle = "Spectra Cuts"
459 maintitle = "Spectra Cuts"
459
460
460 def setup(self):
461 def setup(self):
461
462
462 self.nplots = len(self.data.channels)
463 self.nplots = len(self.data.channels)
463 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
464 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
464 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
465 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
465 self.width = 3.6 * self.ncols + 1.5
466 self.width = 3.6 * self.ncols + 1.5
466 self.height = 3 * self.nrows
467 self.height = 3 * self.nrows
467 self.ylabel = 'Power [dB]'
468 self.ylabel = 'Power [dB]'
468 self.colorbar = False
469 self.colorbar = False
469 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
470 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
470 if self.selectedHeight:
471 if self.selectedHeight:
471 self.maintitle = "Spectra Cut for %d km " %(int(self.selectedHeight))
472 self.maintitle = "Spectra Cut for %d km " %(int(self.selectedHeight))
472
473
473 def update(self, dataOut):
474 def update(self, dataOut):
474 if len(self.channelList) == 0:
475 if len(self.channelList) == 0:
475 self.channelList = dataOut.channelList
476 self.channelList = dataOut.channelList
476
477
477 self.heights = dataOut.heightList
478 self.heights = dataOut.heightList
478 if self.selectedHeight:
479 if self.selectedHeight:
479 index_list = numpy.where(self.heights >= self.selectedHeight)
480 index_list = numpy.where(self.heights >= self.selectedHeight)
480 self.height_index = index_list[0]
481 self.height_index = index_list[0]
481 self.height_index = self.height_index[0]
482 self.height_index = self.height_index[0]
482 #print(self.height_index)
483 #print(self.height_index)
483 data = {}
484 data = {}
484 meta = {}
485 meta = {}
485 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
486 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
486 if self.selectedHeight:
487 if self.selectedHeight:
487 data['spc'] = spc[:,:,self.height_index]
488 data['spc'] = spc[:,:,self.height_index]
488 else:
489 else:
489 data['spc'] = spc
490 data['spc'] = spc
490 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
491 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
491
492
492 return data, meta
493 return data, meta
493
494
494 def plot(self):
495 def plot(self):
495 if self.xaxis == "frequency":
496 if self.xaxis == "frequency":
496 x = self.data.xrange[0][1:]
497 x = self.data.xrange[0][1:]
497 self.xlabel = "Frequency (kHz)"
498 self.xlabel = "Frequency (kHz)"
498 elif self.xaxis == "time":
499 elif self.xaxis == "time":
499 x = self.data.xrange[1]
500 x = self.data.xrange[1]
500 self.xlabel = "Time (ms)"
501 self.xlabel = "Time (ms)"
501 else:
502 else:
502 x = self.data.xrange[2]
503 x = self.data.xrange[2]
503 self.xlabel = "Velocity (m/s)"
504 self.xlabel = "Velocity (m/s)"
504
505
505 self.titles = []
506 self.titles = []
506
507
507 y = self.data.yrange
508 y = self.data.yrange
508 z = self.data[-1]['spc']
509 z = self.data[-1]['spc']
509 #print(z.shape)
510 #print(z.shape)
510 if self.height_index:
511 if self.height_index:
511 index = numpy.array(self.height_index)
512 index = numpy.array(self.height_index)
512 else:
513 else:
513 index = numpy.arange(0, len(y), int((len(y))/9))
514 index = numpy.arange(0, len(y), int((len(y))/9))
514
515
515 for n, ax in enumerate(self.axes):
516 for n, ax in enumerate(self.axes):
516 if ax.firsttime:
517 if ax.firsttime:
517 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
518 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
518 self.xmin = self.xmin if self.xmin else -self.xmax
519 self.xmin = self.xmin if self.xmin else -self.xmax
519 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
520 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
520 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
521 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
521 if self.selectedHeight:
522 if self.selectedHeight:
522 ax.plt = ax.plot(x, z[n,:])
523 ax.plt = ax.plot(x, z[n,:])
523
524
524 else:
525 else:
525 ax.plt = ax.plot(x, z[n, :, index].T)
526 ax.plt = ax.plot(x, z[n, :, index].T)
526 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
527 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
527 self.figures[0].legend(ax.plt, labels, loc='center right')
528 self.figures[0].legend(ax.plt, labels, loc='center right')
528 else:
529 else:
529 for i, line in enumerate(ax.plt):
530 for i, line in enumerate(ax.plt):
530 if self.selectedHeight:
531 if self.selectedHeight:
531 line.set_data(x, z[n, :])
532 line.set_data(x, z[n, :])
532 else:
533 else:
533 line.set_data(x, z[n, :, index[i]])
534 line.set_data(x, z[n, :, index[i]])
534 self.titles.append('CH {}'.format(self.channelList[n]))
535 self.titles.append('CH {}'.format(self.channelList[n]))
535 plt.suptitle(self.maintitle)
536 plt.suptitle(self.maintitle)
536
537
537 class BeaconPhase(Plot):
538 class BeaconPhase(Plot):
538
539
539 __isConfig = None
540 __isConfig = None
540 __nsubplots = None
541 __nsubplots = None
541
542
542 PREFIX = 'beacon_phase'
543 PREFIX = 'beacon_phase'
543
544
544 def __init__(self):
545 def __init__(self):
545 Plot.__init__(self)
546 Plot.__init__(self)
546 self.timerange = 24*60*60
547 self.timerange = 24*60*60
547 self.isConfig = False
548 self.isConfig = False
548 self.__nsubplots = 1
549 self.__nsubplots = 1
549 self.counter_imagwr = 0
550 self.counter_imagwr = 0
550 self.WIDTH = 800
551 self.WIDTH = 800
551 self.HEIGHT = 400
552 self.HEIGHT = 400
552 self.WIDTHPROF = 120
553 self.WIDTHPROF = 120
553 self.HEIGHTPROF = 0
554 self.HEIGHTPROF = 0
554 self.xdata = None
555 self.xdata = None
555 self.ydata = None
556 self.ydata = None
556
557
557 self.PLOT_CODE = BEACON_CODE
558 self.PLOT_CODE = BEACON_CODE
558
559
559 self.FTP_WEI = None
560 self.FTP_WEI = None
560 self.EXP_CODE = None
561 self.EXP_CODE = None
561 self.SUB_EXP_CODE = None
562 self.SUB_EXP_CODE = None
562 self.PLOT_POS = None
563 self.PLOT_POS = None
563
564
564 self.filename_phase = None
565 self.filename_phase = None
565
566
566 self.figfile = None
567 self.figfile = None
567
568
568 self.xmin = None
569 self.xmin = None
569 self.xmax = None
570 self.xmax = None
570
571
571 def getSubplots(self):
572 def getSubplots(self):
572
573
573 ncol = 1
574 ncol = 1
574 nrow = 1
575 nrow = 1
575
576
576 return nrow, ncol
577 return nrow, ncol
577
578
578 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
579 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
579
580
580 self.__showprofile = showprofile
581 self.__showprofile = showprofile
581 self.nplots = nplots
582 self.nplots = nplots
582
583
583 ncolspan = 7
584 ncolspan = 7
584 colspan = 6
585 colspan = 6
585 self.__nsubplots = 2
586 self.__nsubplots = 2
586
587
587 self.createFigure(id = id,
588 self.createFigure(id = id,
588 wintitle = wintitle,
589 wintitle = wintitle,
589 widthplot = self.WIDTH+self.WIDTHPROF,
590 widthplot = self.WIDTH+self.WIDTHPROF,
590 heightplot = self.HEIGHT+self.HEIGHTPROF,
591 heightplot = self.HEIGHT+self.HEIGHTPROF,
591 show=show)
592 show=show)
592
593
593 nrow, ncol = self.getSubplots()
594 nrow, ncol = self.getSubplots()
594
595
595 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
596 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
596
597
597 def save_phase(self, filename_phase):
598 def save_phase(self, filename_phase):
598 f = open(filename_phase,'w+')
599 f = open(filename_phase,'w+')
599 f.write('\n\n')
600 f.write('\n\n')
600 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
601 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
601 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
602 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
602 f.close()
603 f.close()
603
604
604 def save_data(self, filename_phase, data, data_datetime):
605 def save_data(self, filename_phase, data, data_datetime):
605 f=open(filename_phase,'a')
606 f=open(filename_phase,'a')
606 timetuple_data = data_datetime.timetuple()
607 timetuple_data = data_datetime.timetuple()
607 day = str(timetuple_data.tm_mday)
608 day = str(timetuple_data.tm_mday)
608 month = str(timetuple_data.tm_mon)
609 month = str(timetuple_data.tm_mon)
609 year = str(timetuple_data.tm_year)
610 year = str(timetuple_data.tm_year)
610 hour = str(timetuple_data.tm_hour)
611 hour = str(timetuple_data.tm_hour)
611 minute = str(timetuple_data.tm_min)
612 minute = str(timetuple_data.tm_min)
612 second = str(timetuple_data.tm_sec)
613 second = str(timetuple_data.tm_sec)
613 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
614 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
614 f.close()
615 f.close()
615
616
616 def plot(self):
617 def plot(self):
617 log.warning('TODO: Not yet implemented...')
618 log.warning('TODO: Not yet implemented...')
618
619
619 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
620 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
620 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
621 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
621 timerange=None,
622 timerange=None,
622 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
623 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
623 server=None, folder=None, username=None, password=None,
624 server=None, folder=None, username=None, password=None,
624 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
625 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
625
626
626 if dataOut.flagNoData:
627 if dataOut.flagNoData:
627 return dataOut
628 return dataOut
628
629
629 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
630 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
630 return
631 return
631
632
632 if pairsList == None:
633 if pairsList == None:
633 pairsIndexList = dataOut.pairsIndexList[:10]
634 pairsIndexList = dataOut.pairsIndexList[:10]
634 else:
635 else:
635 pairsIndexList = []
636 pairsIndexList = []
636 for pair in pairsList:
637 for pair in pairsList:
637 if pair not in dataOut.pairsList:
638 if pair not in dataOut.pairsList:
638 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
639 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
639 pairsIndexList.append(dataOut.pairsList.index(pair))
640 pairsIndexList.append(dataOut.pairsList.index(pair))
640
641
641 if pairsIndexList == []:
642 if pairsIndexList == []:
642 return
643 return
643
644
644 # if len(pairsIndexList) > 4:
645 # if len(pairsIndexList) > 4:
645 # pairsIndexList = pairsIndexList[0:4]
646 # pairsIndexList = pairsIndexList[0:4]
646
647
647 hmin_index = None
648 hmin_index = None
648 hmax_index = None
649 hmax_index = None
649
650
650 if hmin != None and hmax != None:
651 if hmin != None and hmax != None:
651 indexes = numpy.arange(dataOut.nHeights)
652 indexes = numpy.arange(dataOut.nHeights)
652 hmin_list = indexes[dataOut.heightList >= hmin]
653 hmin_list = indexes[dataOut.heightList >= hmin]
653 hmax_list = indexes[dataOut.heightList <= hmax]
654 hmax_list = indexes[dataOut.heightList <= hmax]
654
655
655 if hmin_list.any():
656 if hmin_list.any():
656 hmin_index = hmin_list[0]
657 hmin_index = hmin_list[0]
657
658
658 if hmax_list.any():
659 if hmax_list.any():
659 hmax_index = hmax_list[-1]+1
660 hmax_index = hmax_list[-1]+1
660
661
661 x = dataOut.getTimeRange()
662 x = dataOut.getTimeRange()
662
663
663 thisDatetime = dataOut.datatime
664 thisDatetime = dataOut.datatime
664
665
665 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
666 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
666 xlabel = "Local Time"
667 xlabel = "Local Time"
667 ylabel = "Phase (degrees)"
668 ylabel = "Phase (degrees)"
668
669
669 update_figfile = False
670 update_figfile = False
670
671
671 nplots = len(pairsIndexList)
672 nplots = len(pairsIndexList)
672 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
673 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
673 phase_beacon = numpy.zeros(len(pairsIndexList))
674 phase_beacon = numpy.zeros(len(pairsIndexList))
674 for i in range(nplots):
675 for i in range(nplots):
675 pair = dataOut.pairsList[pairsIndexList[i]]
676 pair = dataOut.pairsList[pairsIndexList[i]]
676 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
677 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
677 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
678 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
678 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
679 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
679 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
680 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
680 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
681 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
681
682
682 if dataOut.beacon_heiIndexList:
683 if dataOut.beacon_heiIndexList:
683 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
684 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
684 else:
685 else:
685 phase_beacon[i] = numpy.average(phase)
686 phase_beacon[i] = numpy.average(phase)
686
687
687 if not self.isConfig:
688 if not self.isConfig:
688
689
689 nplots = len(pairsIndexList)
690 nplots = len(pairsIndexList)
690
691
691 self.setup(id=id,
692 self.setup(id=id,
692 nplots=nplots,
693 nplots=nplots,
693 wintitle=wintitle,
694 wintitle=wintitle,
694 showprofile=showprofile,
695 showprofile=showprofile,
695 show=show)
696 show=show)
696
697
697 if timerange != None:
698 if timerange != None:
698 self.timerange = timerange
699 self.timerange = timerange
699
700
700 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
701 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
701
702
702 if ymin == None: ymin = 0
703 if ymin == None: ymin = 0
703 if ymax == None: ymax = 360
704 if ymax == None: ymax = 360
704
705
705 self.FTP_WEI = ftp_wei
706 self.FTP_WEI = ftp_wei
706 self.EXP_CODE = exp_code
707 self.EXP_CODE = exp_code
707 self.SUB_EXP_CODE = sub_exp_code
708 self.SUB_EXP_CODE = sub_exp_code
708 self.PLOT_POS = plot_pos
709 self.PLOT_POS = plot_pos
709
710
710 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
711 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
711 self.isConfig = True
712 self.isConfig = True
712 self.figfile = figfile
713 self.figfile = figfile
713 self.xdata = numpy.array([])
714 self.xdata = numpy.array([])
714 self.ydata = numpy.array([])
715 self.ydata = numpy.array([])
715
716
716 update_figfile = True
717 update_figfile = True
717
718
718 #open file beacon phase
719 #open file beacon phase
719 path = '%s%03d' %(self.PREFIX, self.id)
720 path = '%s%03d' %(self.PREFIX, self.id)
720 beacon_file = os.path.join(path,'%s.txt'%self.name)
721 beacon_file = os.path.join(path,'%s.txt'%self.name)
721 self.filename_phase = os.path.join(figpath,beacon_file)
722 self.filename_phase = os.path.join(figpath,beacon_file)
722 #self.save_phase(self.filename_phase)
723 #self.save_phase(self.filename_phase)
723
724
724
725
725 #store data beacon phase
726 #store data beacon phase
726 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
727 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
727
728
728 self.setWinTitle(title)
729 self.setWinTitle(title)
729
730
730
731
731 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
732 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
732
733
733 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
734 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
734
735
735 axes = self.axesList[0]
736 axes = self.axesList[0]
736
737
737 self.xdata = numpy.hstack((self.xdata, x[0:1]))
738 self.xdata = numpy.hstack((self.xdata, x[0:1]))
738
739
739 if len(self.ydata)==0:
740 if len(self.ydata)==0:
740 self.ydata = phase_beacon.reshape(-1,1)
741 self.ydata = phase_beacon.reshape(-1,1)
741 else:
742 else:
742 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
743 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
743
744
744
745
745 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
746 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
746 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
747 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
747 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
748 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
748 XAxisAsTime=True, grid='both'
749 XAxisAsTime=True, grid='both'
749 )
750 )
750
751
751 self.draw()
752 self.draw()
752
753
753 if dataOut.ltctime >= self.xmax:
754 if dataOut.ltctime >= self.xmax:
754 self.counter_imagwr = wr_period
755 self.counter_imagwr = wr_period
755 self.isConfig = False
756 self.isConfig = False
756 update_figfile = True
757 update_figfile = True
757
758
758 self.save(figpath=figpath,
759 self.save(figpath=figpath,
759 figfile=figfile,
760 figfile=figfile,
760 save=save,
761 save=save,
761 ftp=ftp,
762 ftp=ftp,
762 wr_period=wr_period,
763 wr_period=wr_period,
763 thisDatetime=thisDatetime,
764 thisDatetime=thisDatetime,
764 update_figfile=update_figfile)
765 update_figfile=update_figfile)
765
766
766 return dataOut
767 return dataOut
767
768
768 class NoiselessSpectraPlot(Plot):
769 class NoiselessSpectraPlot(Plot):
769 '''
770 '''
770 Plot for Spectra data, subtracting
771 Plot for Spectra data, subtracting
771 the noise in all channels, using for
772 the noise in all channels, using for
772 amisr-14 data
773 amisr-14 data
773 '''
774 '''
774
775
775 CODE = 'noiseless_spc'
776 CODE = 'noiseless_spc'
776 colormap = 'nipy_spectral'
777 colormap = 'nipy_spectral'
777 plot_type = 'pcolor'
778 plot_type = 'pcolor'
778 buffering = False
779 buffering = False
779 channelList = []
780 channelList = []
780
781
781 def setup(self):
782 def setup(self):
782
783
783 self.nplots = len(self.data.channels)
784 self.nplots = len(self.data.channels)
784 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
785 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
785 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
786 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
786 self.height = 2.6 * self.nrows
787 self.height = 2.6 * self.nrows
787
788
788 self.cb_label = 'dB'
789 self.cb_label = 'dB'
789 if self.showprofile:
790 if self.showprofile:
790 self.width = 4 * self.ncols
791 self.width = 4 * self.ncols
791 else:
792 else:
792 self.width = 3.5 * self.ncols
793 self.width = 3.5 * self.ncols
793 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
794 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
794 self.ylabel = 'Range [km]'
795 self.ylabel = 'Range [km]'
795
796
796
797
797 def update_list(self,dataOut):
798 def update_list(self,dataOut):
798 if len(self.channelList) == 0:
799 if len(self.channelList) == 0:
799 self.channelList = dataOut.channelList
800 self.channelList = dataOut.channelList
800
801
801 def update(self, dataOut):
802 def update(self, dataOut):
802
803
803 self.update_list(dataOut)
804 self.update_list(dataOut)
804 data = {}
805 data = {}
805 meta = {}
806 meta = {}
806 n0 = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
807 n0 = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
807 (nch, nff, nh) = dataOut.data_spc.shape
808 (nch, nff, nh) = dataOut.data_spc.shape
808 n1 = numpy.repeat(n0,nh, axis=0).reshape((nch,nh))
809 n1 = numpy.repeat(n0,nh, axis=0).reshape((nch,nh))
809 noise = numpy.repeat(n1,nff, axis=1).reshape((nch,nff,nh))
810 noise = numpy.repeat(n1,nff, axis=1).reshape((nch,nff,nh))
810 #print(noise.shape, "noise", noise)
811 #print(noise.shape, "noise", noise)
811
812
812 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor) - noise
813 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor) - noise
813
814
814 data['spc'] = spc
815 data['spc'] = spc
815 data['rti'] = dataOut.getPower() - n1
816 data['rti'] = dataOut.getPower() - n1
816
817
817 data['noise'] = n0
818 data['noise'] = n0
818 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
819 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
819
820
820 return data, meta
821 return data, meta
821
822
822 def plot(self):
823 def plot(self):
823 if self.xaxis == "frequency":
824 if self.xaxis == "frequency":
824 x = self.data.xrange[0]
825 x = self.data.xrange[0]
825 self.xlabel = "Frequency (kHz)"
826 self.xlabel = "Frequency (kHz)"
826 elif self.xaxis == "time":
827 elif self.xaxis == "time":
827 x = self.data.xrange[1]
828 x = self.data.xrange[1]
828 self.xlabel = "Time (ms)"
829 self.xlabel = "Time (ms)"
829 else:
830 else:
830 x = self.data.xrange[2]
831 x = self.data.xrange[2]
831 self.xlabel = "Velocity (m/s)"
832 self.xlabel = "Velocity (m/s)"
832
833
833 self.titles = []
834 self.titles = []
834 y = self.data.yrange
835 y = self.data.yrange
835 self.y = y
836 self.y = y
836
837
837 data = self.data[-1]
838 data = self.data[-1]
838 z = data['spc']
839 z = data['spc']
839
840
840 for n, ax in enumerate(self.axes):
841 for n, ax in enumerate(self.axes):
841 noise = data['noise'][n]
842 noise = data['noise'][n]
842
843
843 if ax.firsttime:
844 if ax.firsttime:
844 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
845 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
845 self.xmin = self.xmin if self.xmin else -self.xmax
846 self.xmin = self.xmin if self.xmin else -self.xmax
846 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
847 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
847 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
848 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
848 ax.plt = ax.pcolormesh(x, y, z[n].T,
849 ax.plt = ax.pcolormesh(x, y, z[n].T,
849 vmin=self.zmin,
850 vmin=self.zmin,
850 vmax=self.zmax,
851 vmax=self.zmax,
851 cmap=plt.get_cmap(self.colormap)
852 cmap=plt.get_cmap(self.colormap)
852 )
853 )
853
854
854 if self.showprofile:
855 if self.showprofile:
855 ax.plt_profile = self.pf_axes[n].plot(
856 ax.plt_profile = self.pf_axes[n].plot(
856 data['rti'][n], y)[0]
857 data['rti'][n], y)[0]
857 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
858 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
858 color="k", linestyle="dashed", lw=1)[0]
859 color="k", linestyle="dashed", lw=1)[0]
859
860
860 else:
861 else:
861 ax.plt.set_array(z[n].T.ravel())
862 ax.plt.set_array(z[n].T.ravel())
862 if self.showprofile:
863 if self.showprofile:
863 ax.plt_profile.set_data(data['rti'][n], y)
864 ax.plt_profile.set_data(data['rti'][n], y)
864 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
865 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
865
866
866 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
867 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
867
868
868
869
869 class NoiselessRTIPlot(Plot):
870 class NoiselessRTIPlot(Plot):
870 '''
871 '''
871 Plot for RTI data
872 Plot for RTI data
872 '''
873 '''
873
874
874 CODE = 'noiseless_rti'
875 CODE = 'noiseless_rti'
875 colormap = 'jet'
876 colormap = 'jet'
876 plot_type = 'pcolorbuffer'
877 plot_type = 'pcolorbuffer'
877 titles = None
878 titles = None
878 channelList = []
879 channelList = []
879
880
880 def setup(self):
881 def setup(self):
881 self.xaxis = 'time'
882 self.xaxis = 'time'
882 self.ncols = 1
883 self.ncols = 1
883 #print("dataChannels ",self.data.channels)
884 #print("dataChannels ",self.data.channels)
884 self.nrows = len(self.data.channels)
885 self.nrows = len(self.data.channels)
885 self.nplots = len(self.data.channels)
886 self.nplots = len(self.data.channels)
886 self.ylabel = 'Range [km]'
887 self.ylabel = 'Range [km]'
887 self.xlabel = 'Time'
888 self.xlabel = 'Time'
888 self.cb_label = 'dB'
889 self.cb_label = 'dB'
889 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
890 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
890 self.titles = ['{} Channel {}'.format(
891 self.titles = ['{} Channel {}'.format(
891 self.CODE.upper(), x) for x in range(self.nplots)]
892 self.CODE.upper(), x) for x in range(self.nplots)]
892
893
893 def update_list(self,dataOut):
894 def update_list(self,dataOut):
894
895
895 self.channelList = dataOut.channelList
896 self.channelList = dataOut.channelList
896
897
897
898
898 def update(self, dataOut):
899 def update(self, dataOut):
899 if len(self.channelList) == 0:
900 if len(self.channelList) == 0:
900 self.update_list(dataOut)
901 self.update_list(dataOut)
901 data = {}
902 data = {}
902 meta = {}
903 meta = {}
903
904
904 n0 = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
905 n0 = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
905 (nch, nff, nh) = dataOut.data_spc.shape
906 (nch, nff, nh) = dataOut.data_spc.shape
906 noise = numpy.repeat(n0,nh, axis=0).reshape((nch,nh))
907 noise = numpy.repeat(n0,nh, axis=0).reshape((nch,nh))
907
908
908
909
909 data['noiseless_rti'] = dataOut.getPower() - noise
910 data['noiseless_rti'] = dataOut.getPower() - noise
910 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
911 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
911 return data, meta
912 return data, meta
912
913
913 def plot(self):
914 def plot(self):
914
915
915 self.x = self.data.times
916 self.x = self.data.times
916 self.y = self.data.yrange
917 self.y = self.data.yrange
917 self.z = self.data['noiseless_rti']
918 self.z = self.data['noiseless_rti']
918 self.z = numpy.array(self.z, dtype=float)
919 self.z = numpy.array(self.z, dtype=float)
919 self.z = numpy.ma.masked_invalid(self.z)
920 self.z = numpy.ma.masked_invalid(self.z)
920
921
921 try:
922 try:
922 if self.channelList != None:
923 if self.channelList != None:
923 self.titles = ['{} Channel {}'.format(
924 self.titles = ['{} Channel {}'.format(
924 self.CODE.upper(), x) for x in self.channelList]
925 self.CODE.upper(), x) for x in self.channelList]
925 except:
926 except:
926 if self.channelList.any() != None:
927 if self.channelList.any() != None:
927 self.titles = ['{} Channel {}'.format(
928 self.titles = ['{} Channel {}'.format(
928 self.CODE.upper(), x) for x in self.channelList]
929 self.CODE.upper(), x) for x in self.channelList]
929 if self.decimation is None:
930 if self.decimation is None:
930 x, y, z = self.fill_gaps(self.x, self.y, self.z)
931 x, y, z = self.fill_gaps(self.x, self.y, self.z)
931 else:
932 else:
932 x, y, z = self.fill_gaps(*self.decimate())
933 x, y, z = self.fill_gaps(*self.decimate())
933 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
934 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
934 for n, ax in enumerate(self.axes):
935 for n, ax in enumerate(self.axes):
935 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
936 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
936 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
937 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
937 data = self.data[-1]
938 data = self.data[-1]
938 if ax.firsttime:
939 if ax.firsttime:
939 ax.plt = ax.pcolormesh(x, y, z[n].T,
940 ax.plt = ax.pcolormesh(x, y, z[n].T,
940 vmin=self.zmin,
941 vmin=self.zmin,
941 vmax=self.zmax,
942 vmax=self.zmax,
942 cmap=plt.get_cmap(self.colormap)
943 cmap=plt.get_cmap(self.colormap)
943 )
944 )
944 if self.showprofile:
945 if self.showprofile:
945 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
946 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
946
947
947 if "noise" in self.data:
948 if "noise" in self.data:
948 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
949 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
949 color="k", linestyle="dashed", lw=1)[0]
950 color="k", linestyle="dashed", lw=1)[0]
950 else:
951 else:
951 ax.collections.remove(ax.collections[0])
952 ax.collections.remove(ax.collections[0])
952 ax.plt = ax.pcolormesh(x, y, z[n].T,
953 ax.plt = ax.pcolormesh(x, y, z[n].T,
953 vmin=self.zmin,
954 vmin=self.zmin,
954 vmax=self.zmax,
955 vmax=self.zmax,
955 cmap=plt.get_cmap(self.colormap)
956 cmap=plt.get_cmap(self.colormap)
956 )
957 )
957 if self.showprofile:
958 if self.showprofile:
958 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
959 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
959 if "noise" in self.data:
960 if "noise" in self.data:
960 ax.plot_noise.set_data(numpy.repeat(
961 ax.plot_noise.set_data(numpy.repeat(
961 data['noise'][n], len(self.y)), self.y)
962 data['noise'][n], len(self.y)), self.y)
@@ -1,1688 +1,1814
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 import math
15 import math
16
16
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
18 from schainpy.model.data.jrodata import Spectra
18 from schainpy.model.data.jrodata import Spectra
19 from schainpy.model.data.jrodata import hildebrand_sekhon
19 from schainpy.model.data.jrodata import hildebrand_sekhon
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 from scipy.optimize import curve_fit
22 from scipy.optimize import curve_fit
23
23
24 class SpectraProc(ProcessingUnit):
24 class SpectraProc(ProcessingUnit):
25
25
26 def __init__(self):
26 def __init__(self):
27
27
28 ProcessingUnit.__init__(self)
28 ProcessingUnit.__init__(self)
29
29
30 self.buffer = None
30 self.buffer = None
31 self.firstdatatime = None
31 self.firstdatatime = None
32 self.profIndex = 0
32 self.profIndex = 0
33 self.dataOut = Spectra()
33 self.dataOut = Spectra()
34 self.id_min = None
34 self.id_min = None
35 self.id_max = None
35 self.id_max = None
36 self.setupReq = False #Agregar a todas las unidades de proc
36 self.setupReq = False #Agregar a todas las unidades de proc
37
37
38 def __updateSpecFromVoltage(self):
38 def __updateSpecFromVoltage(self):
39
39
40 self.dataOut.timeZone = self.dataIn.timeZone
40 self.dataOut.timeZone = self.dataIn.timeZone
41 self.dataOut.dstFlag = self.dataIn.dstFlag
41 self.dataOut.dstFlag = self.dataIn.dstFlag
42 self.dataOut.errorCount = self.dataIn.errorCount
42 self.dataOut.errorCount = self.dataIn.errorCount
43 self.dataOut.useLocalTime = self.dataIn.useLocalTime
43 self.dataOut.useLocalTime = self.dataIn.useLocalTime
44 try:
44 try:
45 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
45 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
46 except:
46 except:
47 pass
47 pass
48 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
48 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
49 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
49 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
50 self.dataOut.channelList = self.dataIn.channelList
50 self.dataOut.channelList = self.dataIn.channelList
51 self.dataOut.heightList = self.dataIn.heightList
51 self.dataOut.heightList = self.dataIn.heightList
52 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
52 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
53 self.dataOut.nProfiles = self.dataOut.nFFTPoints
53 self.dataOut.nProfiles = self.dataOut.nFFTPoints
54 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
54 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
55 self.dataOut.utctime = self.firstdatatime
55 self.dataOut.utctime = self.firstdatatime
56 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
56 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
57 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
57 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
58 self.dataOut.flagShiftFFT = False
58 self.dataOut.flagShiftFFT = False
59 self.dataOut.nCohInt = self.dataIn.nCohInt
59 self.dataOut.nCohInt = self.dataIn.nCohInt
60 self.dataOut.nIncohInt = 1
60 self.dataOut.nIncohInt = 1
61 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
61 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
62 self.dataOut.frequency = self.dataIn.frequency
62 self.dataOut.frequency = self.dataIn.frequency
63 self.dataOut.realtime = self.dataIn.realtime
63 self.dataOut.realtime = self.dataIn.realtime
64 self.dataOut.azimuth = self.dataIn.azimuth
64 self.dataOut.azimuth = self.dataIn.azimuth
65 self.dataOut.zenith = self.dataIn.zenith
65 self.dataOut.zenith = self.dataIn.zenith
66 self.dataOut.codeList = self.dataIn.codeList
66 self.dataOut.codeList = self.dataIn.codeList
67 self.dataOut.azimuthList = self.dataIn.azimuthList
67 self.dataOut.azimuthList = self.dataIn.azimuthList
68 self.dataOut.elevationList = self.dataIn.elevationList
68 self.dataOut.elevationList = self.dataIn.elevationList
69
69
70
70
71 def __getFft(self):
71 def __getFft(self):
72 """
72 """
73 Convierte valores de Voltaje a Spectra
73 Convierte valores de Voltaje a Spectra
74
74
75 Affected:
75 Affected:
76 self.dataOut.data_spc
76 self.dataOut.data_spc
77 self.dataOut.data_cspc
77 self.dataOut.data_cspc
78 self.dataOut.data_dc
78 self.dataOut.data_dc
79 self.dataOut.heightList
79 self.dataOut.heightList
80 self.profIndex
80 self.profIndex
81 self.buffer
81 self.buffer
82 self.dataOut.flagNoData
82 self.dataOut.flagNoData
83 """
83 """
84 fft_volt = numpy.fft.fft(
84 fft_volt = numpy.fft.fft(
85 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
85 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
86 fft_volt = fft_volt.astype(numpy.dtype('complex'))
86 fft_volt = fft_volt.astype(numpy.dtype('complex'))
87 dc = fft_volt[:, 0, :]
87 dc = fft_volt[:, 0, :]
88
88
89 # calculo de self-spectra
89 # calculo de self-spectra
90 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
90 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
91 spc = fft_volt * numpy.conjugate(fft_volt)
91 spc = fft_volt * numpy.conjugate(fft_volt)
92 spc = spc.real
92 spc = spc.real
93
93
94 blocksize = 0
94 blocksize = 0
95 blocksize += dc.size
95 blocksize += dc.size
96 blocksize += spc.size
96 blocksize += spc.size
97
97
98 cspc = None
98 cspc = None
99 pairIndex = 0
99 pairIndex = 0
100 if self.dataOut.pairsList != None:
100 if self.dataOut.pairsList != None:
101 # calculo de cross-spectra
101 # calculo de cross-spectra
102 cspc = numpy.zeros(
102 cspc = numpy.zeros(
103 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
103 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
104 for pair in self.dataOut.pairsList:
104 for pair in self.dataOut.pairsList:
105 if pair[0] not in self.dataOut.channelList:
105 if pair[0] not in self.dataOut.channelList:
106 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
106 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
107 str(pair), str(self.dataOut.channelList)))
107 str(pair), str(self.dataOut.channelList)))
108 if pair[1] not in self.dataOut.channelList:
108 if pair[1] not in self.dataOut.channelList:
109 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
109 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
110 str(pair), str(self.dataOut.channelList)))
110 str(pair), str(self.dataOut.channelList)))
111
111
112 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
112 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
113 numpy.conjugate(fft_volt[pair[1], :, :])
113 numpy.conjugate(fft_volt[pair[1], :, :])
114 pairIndex += 1
114 pairIndex += 1
115 blocksize += cspc.size
115 blocksize += cspc.size
116
116
117 self.dataOut.data_spc = spc
117 self.dataOut.data_spc = spc
118 self.dataOut.data_cspc = cspc
118 self.dataOut.data_cspc = cspc
119 self.dataOut.data_dc = dc
119 self.dataOut.data_dc = dc
120 self.dataOut.blockSize = blocksize
120 self.dataOut.blockSize = blocksize
121 self.dataOut.flagShiftFFT = False
121 self.dataOut.flagShiftFFT = False
122
122
123 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
123 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
124
124
125 if self.dataIn.type == "Spectra":
125 if self.dataIn.type == "Spectra":
126
126
127 try:
127 try:
128 self.dataOut.copy(self.dataIn)
128 self.dataOut.copy(self.dataIn)
129
129
130 except Exception as e:
130 except Exception as e:
131 print(e)
131 print(e)
132
132
133 if shift_fft:
133 if shift_fft:
134 #desplaza a la derecha en el eje 2 determinadas posiciones
134 #desplaza a la derecha en el eje 2 determinadas posiciones
135 shift = int(self.dataOut.nFFTPoints/2)
135 shift = int(self.dataOut.nFFTPoints/2)
136 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
136 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
137
137
138 if self.dataOut.data_cspc is not None:
138 if self.dataOut.data_cspc is not None:
139 #desplaza a la derecha en el eje 2 determinadas posiciones
139 #desplaza a la derecha en el eje 2 determinadas posiciones
140 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
140 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
141 if pairsList:
141 if pairsList:
142 self.__selectPairs(pairsList)
142 self.__selectPairs(pairsList)
143
143
144
144
145 elif self.dataIn.type == "Voltage":
145 elif self.dataIn.type == "Voltage":
146
146
147 self.dataOut.flagNoData = True
147 self.dataOut.flagNoData = True
148
148
149 if nFFTPoints == None:
149 if nFFTPoints == None:
150 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
150 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
151
151
152 if nProfiles == None:
152 if nProfiles == None:
153 nProfiles = nFFTPoints
153 nProfiles = nFFTPoints
154
154
155 if ippFactor == None:
155 if ippFactor == None:
156 self.dataOut.ippFactor = 1
156 self.dataOut.ippFactor = 1
157
157
158 self.dataOut.nFFTPoints = nFFTPoints
158 self.dataOut.nFFTPoints = nFFTPoints
159
159
160 if self.buffer is None:
160 if self.buffer is None:
161 self.buffer = numpy.zeros((self.dataIn.nChannels,
161 self.buffer = numpy.zeros((self.dataIn.nChannels,
162 nProfiles,
162 nProfiles,
163 self.dataIn.nHeights),
163 self.dataIn.nHeights),
164 dtype='complex')
164 dtype='complex')
165
165
166 if self.dataIn.flagDataAsBlock:
166 if self.dataIn.flagDataAsBlock:
167 nVoltProfiles = self.dataIn.data.shape[1]
167 nVoltProfiles = self.dataIn.data.shape[1]
168
168
169 if nVoltProfiles == nProfiles:
169 if nVoltProfiles == nProfiles:
170 self.buffer = self.dataIn.data.copy()
170 self.buffer = self.dataIn.data.copy()
171 self.profIndex = nVoltProfiles
171 self.profIndex = nVoltProfiles
172
172
173 elif nVoltProfiles < nProfiles:
173 elif nVoltProfiles < nProfiles:
174
174
175 if self.profIndex == 0:
175 if self.profIndex == 0:
176 self.id_min = 0
176 self.id_min = 0
177 self.id_max = nVoltProfiles
177 self.id_max = nVoltProfiles
178
178
179 self.buffer[:, self.id_min:self.id_max,
179 self.buffer[:, self.id_min:self.id_max,
180 :] = self.dataIn.data
180 :] = self.dataIn.data
181 self.profIndex += nVoltProfiles
181 self.profIndex += nVoltProfiles
182 self.id_min += nVoltProfiles
182 self.id_min += nVoltProfiles
183 self.id_max += nVoltProfiles
183 self.id_max += nVoltProfiles
184 else:
184 else:
185 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
185 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
186 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
186 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
187 self.dataOut.flagNoData = True
187 self.dataOut.flagNoData = True
188 else:
188 else:
189 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
189 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
190 self.profIndex += 1
190 self.profIndex += 1
191
191
192 if self.firstdatatime == None:
192 if self.firstdatatime == None:
193 self.firstdatatime = self.dataIn.utctime
193 self.firstdatatime = self.dataIn.utctime
194
194
195 if self.profIndex == nProfiles:
195 if self.profIndex == nProfiles:
196 self.__updateSpecFromVoltage()
196 self.__updateSpecFromVoltage()
197 if pairsList == None:
197 if pairsList == None:
198 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
198 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
199 else:
199 else:
200 self.dataOut.pairsList = pairsList
200 self.dataOut.pairsList = pairsList
201 self.__getFft()
201 self.__getFft()
202 self.dataOut.flagNoData = False
202 self.dataOut.flagNoData = False
203 self.firstdatatime = None
203 self.firstdatatime = None
204 self.profIndex = 0
204 self.profIndex = 0
205 self.dataOut.noise_estimation = None
205 else:
206 else:
206 raise ValueError("The type of input object '%s' is not valid".format(
207 raise ValueError("The type of input object '%s' is not valid".format(
207 self.dataIn.type))
208 self.dataIn.type))
208
209
209 def __selectPairs(self, pairsList):
210 def __selectPairs(self, pairsList):
210
211
211 if not pairsList:
212 if not pairsList:
212 return
213 return
213
214
214 pairs = []
215 pairs = []
215 pairsIndex = []
216 pairsIndex = []
216
217
217 for pair in pairsList:
218 for pair in pairsList:
218 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
219 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
219 continue
220 continue
220 pairs.append(pair)
221 pairs.append(pair)
221 pairsIndex.append(pairs.index(pair))
222 pairsIndex.append(pairs.index(pair))
222
223
223 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
224 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
224 self.dataOut.pairsList = pairs
225 self.dataOut.pairsList = pairs
225
226
226 return
227 return
227
228
228 def selectFFTs(self, minFFT, maxFFT ):
229 def selectFFTs(self, minFFT, maxFFT ):
229 """
230 """
230 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
231 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
231 minFFT<= FFT <= maxFFT
232 minFFT<= FFT <= maxFFT
232 """
233 """
233
234
234 if (minFFT > maxFFT):
235 if (minFFT > maxFFT):
235 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
236 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
236
237
237 if (minFFT < self.dataOut.getFreqRange()[0]):
238 if (minFFT < self.dataOut.getFreqRange()[0]):
238 minFFT = self.dataOut.getFreqRange()[0]
239 minFFT = self.dataOut.getFreqRange()[0]
239
240
240 if (maxFFT > self.dataOut.getFreqRange()[-1]):
241 if (maxFFT > self.dataOut.getFreqRange()[-1]):
241 maxFFT = self.dataOut.getFreqRange()[-1]
242 maxFFT = self.dataOut.getFreqRange()[-1]
242
243
243 minIndex = 0
244 minIndex = 0
244 maxIndex = 0
245 maxIndex = 0
245 FFTs = self.dataOut.getFreqRange()
246 FFTs = self.dataOut.getFreqRange()
246
247
247 inda = numpy.where(FFTs >= minFFT)
248 inda = numpy.where(FFTs >= minFFT)
248 indb = numpy.where(FFTs <= maxFFT)
249 indb = numpy.where(FFTs <= maxFFT)
249
250
250 try:
251 try:
251 minIndex = inda[0][0]
252 minIndex = inda[0][0]
252 except:
253 except:
253 minIndex = 0
254 minIndex = 0
254
255
255 try:
256 try:
256 maxIndex = indb[0][-1]
257 maxIndex = indb[0][-1]
257 except:
258 except:
258 maxIndex = len(FFTs)
259 maxIndex = len(FFTs)
259
260
260 self.selectFFTsByIndex(minIndex, maxIndex)
261 self.selectFFTsByIndex(minIndex, maxIndex)
261
262
262 return 1
263 return 1
263
264
264 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
265 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
265 newheis = numpy.where(
266 newheis = numpy.where(
266 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
267 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
267
268
268 if hei_ref != None:
269 if hei_ref != None:
269 newheis = numpy.where(self.dataOut.heightList > hei_ref)
270 newheis = numpy.where(self.dataOut.heightList > hei_ref)
270
271
271 minIndex = min(newheis[0])
272 minIndex = min(newheis[0])
272 maxIndex = max(newheis[0])
273 maxIndex = max(newheis[0])
273 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
274 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
274 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
275 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
275
276
276 # determina indices
277 # determina indices
277 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
278 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
278 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
279 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
279 avg_dB = 10 * \
280 avg_dB = 10 * \
280 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
281 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
281 beacon_dB = numpy.sort(avg_dB)[-nheis:]
282 beacon_dB = numpy.sort(avg_dB)[-nheis:]
282 beacon_heiIndexList = []
283 beacon_heiIndexList = []
283 for val in avg_dB.tolist():
284 for val in avg_dB.tolist():
284 if val >= beacon_dB[0]:
285 if val >= beacon_dB[0]:
285 beacon_heiIndexList.append(avg_dB.tolist().index(val))
286 beacon_heiIndexList.append(avg_dB.tolist().index(val))
286
287
287 #data_spc = data_spc[:,:,beacon_heiIndexList]
288 #data_spc = data_spc[:,:,beacon_heiIndexList]
288 data_cspc = None
289 data_cspc = None
289 if self.dataOut.data_cspc is not None:
290 if self.dataOut.data_cspc is not None:
290 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
291 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
291 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
292 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
292
293
293 data_dc = None
294 data_dc = None
294 if self.dataOut.data_dc is not None:
295 if self.dataOut.data_dc is not None:
295 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
296 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
296 #data_dc = data_dc[:,beacon_heiIndexList]
297 #data_dc = data_dc[:,beacon_heiIndexList]
297
298
298 self.dataOut.data_spc = data_spc
299 self.dataOut.data_spc = data_spc
299 self.dataOut.data_cspc = data_cspc
300 self.dataOut.data_cspc = data_cspc
300 self.dataOut.data_dc = data_dc
301 self.dataOut.data_dc = data_dc
301 self.dataOut.heightList = heightList
302 self.dataOut.heightList = heightList
302 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
303 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
303
304
304 return 1
305 return 1
305
306
306 def selectFFTsByIndex(self, minIndex, maxIndex):
307 def selectFFTsByIndex(self, minIndex, maxIndex):
307 """
308 """
308
309
309 """
310 """
310
311
311 if (minIndex < 0) or (minIndex > maxIndex):
312 if (minIndex < 0) or (minIndex > maxIndex):
312 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
313 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
313
314
314 if (maxIndex >= self.dataOut.nProfiles):
315 if (maxIndex >= self.dataOut.nProfiles):
315 maxIndex = self.dataOut.nProfiles-1
316 maxIndex = self.dataOut.nProfiles-1
316
317
317 #Spectra
318 #Spectra
318 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
319 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
319
320
320 data_cspc = None
321 data_cspc = None
321 if self.dataOut.data_cspc is not None:
322 if self.dataOut.data_cspc is not None:
322 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
323 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
323
324
324 data_dc = None
325 data_dc = None
325 if self.dataOut.data_dc is not None:
326 if self.dataOut.data_dc is not None:
326 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
327 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
327
328
328 self.dataOut.data_spc = data_spc
329 self.dataOut.data_spc = data_spc
329 self.dataOut.data_cspc = data_cspc
330 self.dataOut.data_cspc = data_cspc
330 self.dataOut.data_dc = data_dc
331 self.dataOut.data_dc = data_dc
331
332
332 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
333 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
333 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
334 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
334 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
335 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
335
336
336 return 1
337 return 1
337
338
338 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
339 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
339 # validacion de rango
340 # validacion de rango
340 if minHei == None:
341 if minHei == None:
341 minHei = self.dataOut.heightList[0]
342 minHei = self.dataOut.heightList[0]
342
343
343 if maxHei == None:
344 if maxHei == None:
344 maxHei = self.dataOut.heightList[-1]
345 maxHei = self.dataOut.heightList[-1]
345
346
346 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
347 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
347 print('minHei: %.2f is out of the heights range' % (minHei))
348 print('minHei: %.2f is out of the heights range' % (minHei))
348 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
349 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
349 minHei = self.dataOut.heightList[0]
350 minHei = self.dataOut.heightList[0]
350
351
351 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
352 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
352 print('maxHei: %.2f is out of the heights range' % (maxHei))
353 print('maxHei: %.2f is out of the heights range' % (maxHei))
353 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
354 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
354 maxHei = self.dataOut.heightList[-1]
355 maxHei = self.dataOut.heightList[-1]
355
356
356 # validacion de velocidades
357 # validacion de velocidades
357 velrange = self.dataOut.getVelRange(1)
358 velrange = self.dataOut.getVelRange(1)
358
359
359 if minVel == None:
360 if minVel == None:
360 minVel = velrange[0]
361 minVel = velrange[0]
361
362
362 if maxVel == None:
363 if maxVel == None:
363 maxVel = velrange[-1]
364 maxVel = velrange[-1]
364
365
365 if (minVel < velrange[0]) or (minVel > maxVel):
366 if (minVel < velrange[0]) or (minVel > maxVel):
366 print('minVel: %.2f is out of the velocity range' % (minVel))
367 print('minVel: %.2f is out of the velocity range' % (minVel))
367 print('minVel is setting to %.2f' % (velrange[0]))
368 print('minVel is setting to %.2f' % (velrange[0]))
368 minVel = velrange[0]
369 minVel = velrange[0]
369
370
370 if (maxVel > velrange[-1]) or (maxVel < minVel):
371 if (maxVel > velrange[-1]) or (maxVel < minVel):
371 print('maxVel: %.2f is out of the velocity range' % (maxVel))
372 print('maxVel: %.2f is out of the velocity range' % (maxVel))
372 print('maxVel is setting to %.2f' % (velrange[-1]))
373 print('maxVel is setting to %.2f' % (velrange[-1]))
373 maxVel = velrange[-1]
374 maxVel = velrange[-1]
374
375
375 # seleccion de indices para rango
376 # seleccion de indices para rango
376 minIndex = 0
377 minIndex = 0
377 maxIndex = 0
378 maxIndex = 0
378 heights = self.dataOut.heightList
379 heights = self.dataOut.heightList
379
380
380 inda = numpy.where(heights >= minHei)
381 inda = numpy.where(heights >= minHei)
381 indb = numpy.where(heights <= maxHei)
382 indb = numpy.where(heights <= maxHei)
382
383
383 try:
384 try:
384 minIndex = inda[0][0]
385 minIndex = inda[0][0]
385 except:
386 except:
386 minIndex = 0
387 minIndex = 0
387
388
388 try:
389 try:
389 maxIndex = indb[0][-1]
390 maxIndex = indb[0][-1]
390 except:
391 except:
391 maxIndex = len(heights)
392 maxIndex = len(heights)
392
393
393 if (minIndex < 0) or (minIndex > maxIndex):
394 if (minIndex < 0) or (minIndex > maxIndex):
394 raise ValueError("some value in (%d,%d) is not valid" % (
395 raise ValueError("some value in (%d,%d) is not valid" % (
395 minIndex, maxIndex))
396 minIndex, maxIndex))
396
397
397 if (maxIndex >= self.dataOut.nHeights):
398 if (maxIndex >= self.dataOut.nHeights):
398 maxIndex = self.dataOut.nHeights - 1
399 maxIndex = self.dataOut.nHeights - 1
399
400
400 # seleccion de indices para velocidades
401 # seleccion de indices para velocidades
401 indminvel = numpy.where(velrange >= minVel)
402 indminvel = numpy.where(velrange >= minVel)
402 indmaxvel = numpy.where(velrange <= maxVel)
403 indmaxvel = numpy.where(velrange <= maxVel)
403 try:
404 try:
404 minIndexVel = indminvel[0][0]
405 minIndexVel = indminvel[0][0]
405 except:
406 except:
406 minIndexVel = 0
407 minIndexVel = 0
407
408
408 try:
409 try:
409 maxIndexVel = indmaxvel[0][-1]
410 maxIndexVel = indmaxvel[0][-1]
410 except:
411 except:
411 maxIndexVel = len(velrange)
412 maxIndexVel = len(velrange)
412
413
413 # seleccion del espectro
414 # seleccion del espectro
414 data_spc = self.dataOut.data_spc[:,
415 data_spc = self.dataOut.data_spc[:,
415 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
416 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
416 # estimacion de ruido
417 # estimacion de ruido
417 noise = numpy.zeros(self.dataOut.nChannels)
418 noise = numpy.zeros(self.dataOut.nChannels)
418
419
419 for channel in range(self.dataOut.nChannels):
420 for channel in range(self.dataOut.nChannels):
420 daux = data_spc[channel, :, :]
421 daux = data_spc[channel, :, :]
421 sortdata = numpy.sort(daux, axis=None)
422 sortdata = numpy.sort(daux, axis=None)
422 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
423 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
423
424
424 self.dataOut.noise_estimation = noise.copy()
425 self.dataOut.noise_estimation = noise.copy()
425
426
426 return 1
427 return 1
427
428
428 class removeDC(Operation):
429 class removeDC(Operation):
429
430
430 def run(self, dataOut, mode=2):
431 def run(self, dataOut, mode=2):
431 self.dataOut = dataOut
432 self.dataOut = dataOut
432 jspectra = self.dataOut.data_spc
433 jspectra = self.dataOut.data_spc
433 jcspectra = self.dataOut.data_cspc
434 jcspectra = self.dataOut.data_cspc
434
435
435 num_chan = jspectra.shape[0]
436 num_chan = jspectra.shape[0]
436 num_hei = jspectra.shape[2]
437 num_hei = jspectra.shape[2]
437
438
438 if jcspectra is not None:
439 if jcspectra is not None:
439 jcspectraExist = True
440 jcspectraExist = True
440 num_pairs = jcspectra.shape[0]
441 num_pairs = jcspectra.shape[0]
441 else:
442 else:
442 jcspectraExist = False
443 jcspectraExist = False
443
444
444 freq_dc = int(jspectra.shape[1] / 2)
445 freq_dc = int(jspectra.shape[1] / 2)
445 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
446 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
446 ind_vel = ind_vel.astype(int)
447 ind_vel = ind_vel.astype(int)
447
448
448 if ind_vel[0] < 0:
449 if ind_vel[0] < 0:
449 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
450 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
450
451
451 if mode == 1:
452 if mode == 1:
452 jspectra[:, freq_dc, :] = (
453 jspectra[:, freq_dc, :] = (
453 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
454 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
454
455
455 if jcspectraExist:
456 if jcspectraExist:
456 jcspectra[:, freq_dc, :] = (
457 jcspectra[:, freq_dc, :] = (
457 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
458 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
458
459
459 if mode == 2:
460 if mode == 2:
460
461
461 vel = numpy.array([-2, -1, 1, 2])
462 vel = numpy.array([-2, -1, 1, 2])
462 xx = numpy.zeros([4, 4])
463 xx = numpy.zeros([4, 4])
463
464
464 for fil in range(4):
465 for fil in range(4):
465 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
466 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
466
467
467 xx_inv = numpy.linalg.inv(xx)
468 xx_inv = numpy.linalg.inv(xx)
468 xx_aux = xx_inv[0, :]
469 xx_aux = xx_inv[0, :]
469
470
470 for ich in range(num_chan):
471 for ich in range(num_chan):
471 yy = jspectra[ich, ind_vel, :]
472 yy = jspectra[ich, ind_vel, :]
472 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
473 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
473
474
474 junkid = jspectra[ich, freq_dc, :] <= 0
475 junkid = jspectra[ich, freq_dc, :] <= 0
475 cjunkid = sum(junkid)
476 cjunkid = sum(junkid)
476
477
477 if cjunkid.any():
478 if cjunkid.any():
478 jspectra[ich, freq_dc, junkid.nonzero()] = (
479 jspectra[ich, freq_dc, junkid.nonzero()] = (
479 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
480 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
480
481
481 if jcspectraExist:
482 if jcspectraExist:
482 for ip in range(num_pairs):
483 for ip in range(num_pairs):
483 yy = jcspectra[ip, ind_vel, :]
484 yy = jcspectra[ip, ind_vel, :]
484 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
485 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
485
486
486 self.dataOut.data_spc = jspectra
487 self.dataOut.data_spc = jspectra
487 self.dataOut.data_cspc = jcspectra
488 self.dataOut.data_cspc = jcspectra
488
489
489 return self.dataOut
490 return self.dataOut
490
491
492 class getNoise(Operation):
493 def __init__(self):
494
495 Operation.__init__(self)
496
497 def run(self, dataOut, minHei=None, maxHei=None, minVel=None, maxVel=None, minFreq= None, maxFreq=None,):
498 self.dataOut = dataOut.copy()
499 print("1: ",dataOut.noise_estimation, dataOut.normFactor)
500
501 if minHei == None:
502 minHei = self.dataOut.heightList[0]
503
504 if maxHei == None:
505 maxHei = self.dataOut.heightList[-1]
506
507 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
508 print('minHei: %.2f is out of the heights range' % (minHei))
509 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
510 minHei = self.dataOut.heightList[0]
511
512 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
513 print('maxHei: %.2f is out of the heights range' % (maxHei))
514 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
515 maxHei = self.dataOut.heightList[-1]
516
517
518 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
519 minIndexFFT = 0
520 maxIndexFFT = 0
521 # validacion de velocidades
522 indminPoint = None
523 indmaxPoint = None
524
525 if minVel == None and maxVel == None:
526
527 freqrange = self.dataOut.getFreqRange(1)
528
529 if minFreq == None:
530 minFreq = freqrange[0]
531
532 if maxFreq == None:
533 maxFreq = freqrange[-1]
534
535 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
536 print('minFreq: %.2f is out of the frequency range' % (minFreq))
537 print('minFreq is setting to %.2f' % (freqrange[0]))
538 minFreq = freqrange[0]
539
540 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
541 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
542 print('maxFreq is setting to %.2f' % (freqrange[-1]))
543 maxFreq = freqrange[-1]
544
545 indminPoint = numpy.where(freqrange >= minFreq)
546 indmaxPoint = numpy.where(freqrange <= maxFreq)
547
548 else:
549 velrange = self.dataOut.getVelRange(1)
550
551 if minVel == None:
552 minVel = velrange[0]
553
554 if maxVel == None:
555 maxVel = velrange[-1]
556
557 if (minVel < velrange[0]) or (minVel > maxVel):
558 print('minVel: %.2f is out of the velocity range' % (minVel))
559 print('minVel is setting to %.2f' % (velrange[0]))
560 minVel = velrange[0]
561
562 if (maxVel > velrange[-1]) or (maxVel < minVel):
563 print('maxVel: %.2f is out of the velocity range' % (maxVel))
564 print('maxVel is setting to %.2f' % (velrange[-1]))
565 maxVel = velrange[-1]
566
567 indminPoint = numpy.where(velrange >= minVel)
568 indmaxPoint = numpy.where(velrange <= maxVel)
569
570
571 # seleccion de indices para rango
572 minIndex = 0
573 maxIndex = 0
574 heights = self.dataOut.heightList
575
576 inda = numpy.where(heights >= minHei)
577 indb = numpy.where(heights <= maxHei)
578
579 try:
580 minIndex = inda[0][0]
581 except:
582 minIndex = 0
583
584 try:
585 maxIndex = indb[0][-1]
586 except:
587 maxIndex = len(heights)
588
589 if (minIndex < 0) or (minIndex > maxIndex):
590 raise ValueError("some value in (%d,%d) is not valid" % (
591 minIndex, maxIndex))
592
593 if (maxIndex >= self.dataOut.nHeights):
594 maxIndex = self.dataOut.nHeights - 1
595 #############################################################3
596 # seleccion de indices para velocidades
597
598 try:
599 minIndexFFT = indminPoint[0][0]
600 except:
601 minIndexFFT = 0
602
603 try:
604 maxIndexFFT = indmaxPoint[0][-1]
605 except:
606 maxIndexFFT = len( self.dataOut.getFreqRange(1))
607
608 #print(minIndex, maxIndex,minIndexVel, maxIndexVel)
609 noise = self.dataOut.getNoise(xmin_index=minIndexFFT, xmax_index=maxIndexFFT, ymin_index=minIndex, ymax_index=maxIndex)
610
611 self.dataOut.noise_estimation = noise.copy()
612 #print("2: ",10*numpy.log10(self.dataOut.noise_estimation/64))
613 return self.dataOut
614
615
616
491 # import matplotlib.pyplot as plt
617 # import matplotlib.pyplot as plt
492
618
493 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
619 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
494 z = (x - a1) / a2
620 z = (x - a1) / a2
495 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
621 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
496 return y
622 return y
497
623
498
624
499 class CleanRayleigh(Operation):
625 class CleanRayleigh(Operation):
500
626
501 def __init__(self):
627 def __init__(self):
502
628
503 Operation.__init__(self)
629 Operation.__init__(self)
504 self.i=0
630 self.i=0
505 self.isConfig = False
631 self.isConfig = False
506 self.__dataReady = False
632 self.__dataReady = False
507 self.__profIndex = 0
633 self.__profIndex = 0
508 self.byTime = False
634 self.byTime = False
509 self.byProfiles = False
635 self.byProfiles = False
510
636
511 self.bloques = None
637 self.bloques = None
512 self.bloque0 = None
638 self.bloque0 = None
513
639
514 self.index = 0
640 self.index = 0
515
641
516 self.buffer = 0
642 self.buffer = 0
517 self.buffer2 = 0
643 self.buffer2 = 0
518 self.buffer3 = 0
644 self.buffer3 = 0
519
645
520
646
521 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
647 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
522
648
523 self.nChannels = dataOut.nChannels
649 self.nChannels = dataOut.nChannels
524 self.nProf = dataOut.nProfiles
650 self.nProf = dataOut.nProfiles
525 self.nPairs = dataOut.data_cspc.shape[0]
651 self.nPairs = dataOut.data_cspc.shape[0]
526 self.pairsArray = numpy.array(dataOut.pairsList)
652 self.pairsArray = numpy.array(dataOut.pairsList)
527 self.spectra = dataOut.data_spc
653 self.spectra = dataOut.data_spc
528 self.cspectra = dataOut.data_cspc
654 self.cspectra = dataOut.data_cspc
529 self.heights = dataOut.heightList #alturas totales
655 self.heights = dataOut.heightList #alturas totales
530 self.nHeights = len(self.heights)
656 self.nHeights = len(self.heights)
531 self.min_hei = min_hei
657 self.min_hei = min_hei
532 self.max_hei = max_hei
658 self.max_hei = max_hei
533 if (self.min_hei == None):
659 if (self.min_hei == None):
534 self.min_hei = 0
660 self.min_hei = 0
535 if (self.max_hei == None):
661 if (self.max_hei == None):
536 self.max_hei = dataOut.heightList[-1]
662 self.max_hei = dataOut.heightList[-1]
537 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
663 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
538 self.heightsClean = self.heights[self.hval] #alturas filtradas
664 self.heightsClean = self.heights[self.hval] #alturas filtradas
539 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
665 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
540 self.nHeightsClean = len(self.heightsClean)
666 self.nHeightsClean = len(self.heightsClean)
541 self.channels = dataOut.channelList
667 self.channels = dataOut.channelList
542 self.nChan = len(self.channels)
668 self.nChan = len(self.channels)
543 self.nIncohInt = dataOut.nIncohInt
669 self.nIncohInt = dataOut.nIncohInt
544 self.__initime = dataOut.utctime
670 self.__initime = dataOut.utctime
545 self.maxAltInd = self.hval[-1]+1
671 self.maxAltInd = self.hval[-1]+1
546 self.minAltInd = self.hval[0]
672 self.minAltInd = self.hval[0]
547
673
548 self.crosspairs = dataOut.pairsList
674 self.crosspairs = dataOut.pairsList
549 self.nPairs = len(self.crosspairs)
675 self.nPairs = len(self.crosspairs)
550 self.normFactor = dataOut.normFactor
676 self.normFactor = dataOut.normFactor
551 self.nFFTPoints = dataOut.nFFTPoints
677 self.nFFTPoints = dataOut.nFFTPoints
552 self.ippSeconds = dataOut.ippSeconds
678 self.ippSeconds = dataOut.ippSeconds
553 self.currentTime = self.__initime
679 self.currentTime = self.__initime
554 self.pairsArray = numpy.array(dataOut.pairsList)
680 self.pairsArray = numpy.array(dataOut.pairsList)
555 self.factor_stdv = factor_stdv
681 self.factor_stdv = factor_stdv
556
682
557 if n != None :
683 if n != None :
558 self.byProfiles = True
684 self.byProfiles = True
559 self.nIntProfiles = n
685 self.nIntProfiles = n
560 else:
686 else:
561 self.__integrationtime = timeInterval
687 self.__integrationtime = timeInterval
562
688
563 self.__dataReady = False
689 self.__dataReady = False
564 self.isConfig = True
690 self.isConfig = True
565
691
566
692
567
693
568 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
694 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
569
695
570 if not self.isConfig :
696 if not self.isConfig :
571
697
572 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
698 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
573
699
574 tini=dataOut.utctime
700 tini=dataOut.utctime
575
701
576 if self.byProfiles:
702 if self.byProfiles:
577 if self.__profIndex == self.nIntProfiles:
703 if self.__profIndex == self.nIntProfiles:
578 self.__dataReady = True
704 self.__dataReady = True
579 else:
705 else:
580 if (tini - self.__initime) >= self.__integrationtime:
706 if (tini - self.__initime) >= self.__integrationtime:
581
707
582 self.__dataReady = True
708 self.__dataReady = True
583 self.__initime = tini
709 self.__initime = tini
584
710
585 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
711 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
586
712
587 if self.__dataReady:
713 if self.__dataReady:
588
714
589 self.__profIndex = 0
715 self.__profIndex = 0
590 jspc = self.buffer
716 jspc = self.buffer
591 jcspc = self.buffer2
717 jcspc = self.buffer2
592 #jnoise = self.buffer3
718 #jnoise = self.buffer3
593 self.buffer = dataOut.data_spc
719 self.buffer = dataOut.data_spc
594 self.buffer2 = dataOut.data_cspc
720 self.buffer2 = dataOut.data_cspc
595 #self.buffer3 = dataOut.noise
721 #self.buffer3 = dataOut.noise
596 self.currentTime = dataOut.utctime
722 self.currentTime = dataOut.utctime
597 if numpy.any(jspc) :
723 if numpy.any(jspc) :
598 #print( jspc.shape, jcspc.shape)
724 #print( jspc.shape, jcspc.shape)
599 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
725 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
600 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
726 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
601 self.__dataReady = False
727 self.__dataReady = False
602 #print( jspc.shape, jcspc.shape)
728 #print( jspc.shape, jcspc.shape)
603 dataOut.flagNoData = False
729 dataOut.flagNoData = False
604 else:
730 else:
605 dataOut.flagNoData = True
731 dataOut.flagNoData = True
606 self.__dataReady = False
732 self.__dataReady = False
607 return dataOut
733 return dataOut
608 else:
734 else:
609 #print( len(self.buffer))
735 #print( len(self.buffer))
610 if numpy.any(self.buffer):
736 if numpy.any(self.buffer):
611 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
737 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
612 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
738 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
613 self.buffer3 += dataOut.data_dc
739 self.buffer3 += dataOut.data_dc
614 else:
740 else:
615 self.buffer = dataOut.data_spc
741 self.buffer = dataOut.data_spc
616 self.buffer2 = dataOut.data_cspc
742 self.buffer2 = dataOut.data_cspc
617 self.buffer3 = dataOut.data_dc
743 self.buffer3 = dataOut.data_dc
618 #print self.index, self.fint
744 #print self.index, self.fint
619 #print self.buffer2.shape
745 #print self.buffer2.shape
620 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
746 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
621 self.__profIndex += 1
747 self.__profIndex += 1
622 return dataOut ## NOTE: REV
748 return dataOut ## NOTE: REV
623
749
624
750
625 #index = tini.tm_hour*12+tini.tm_min/5
751 #index = tini.tm_hour*12+tini.tm_min/5
626 '''REVISAR'''
752 '''REVISAR'''
627 # jspc = jspc/self.nFFTPoints/self.normFactor
753 # jspc = jspc/self.nFFTPoints/self.normFactor
628 # jcspc = jcspc/self.nFFTPoints/self.normFactor
754 # jcspc = jcspc/self.nFFTPoints/self.normFactor
629
755
630
756
631
757
632 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
758 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
633 dataOut.data_spc = tmp_spectra
759 dataOut.data_spc = tmp_spectra
634 dataOut.data_cspc = tmp_cspectra
760 dataOut.data_cspc = tmp_cspectra
635
761
636 #dataOut.data_spc,dataOut.data_cspc = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
762 #dataOut.data_spc,dataOut.data_cspc = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
637
763
638 dataOut.data_dc = self.buffer3
764 dataOut.data_dc = self.buffer3
639 dataOut.nIncohInt *= self.nIntProfiles
765 dataOut.nIncohInt *= self.nIntProfiles
640 dataOut.utctime = self.currentTime #tiempo promediado
766 dataOut.utctime = self.currentTime #tiempo promediado
641 #print("Time: ",time.localtime(dataOut.utctime))
767 #print("Time: ",time.localtime(dataOut.utctime))
642 # dataOut.data_spc = sat_spectra
768 # dataOut.data_spc = sat_spectra
643 # dataOut.data_cspc = sat_cspectra
769 # dataOut.data_cspc = sat_cspectra
644 self.buffer = 0
770 self.buffer = 0
645 self.buffer2 = 0
771 self.buffer2 = 0
646 self.buffer3 = 0
772 self.buffer3 = 0
647
773
648 return dataOut
774 return dataOut
649
775
650 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
776 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
651 #print("OP cleanRayleigh")
777 #print("OP cleanRayleigh")
652 #import matplotlib.pyplot as plt
778 #import matplotlib.pyplot as plt
653 #for k in range(149):
779 #for k in range(149):
654 #channelsProcssd = []
780 #channelsProcssd = []
655 #channelA_ok = False
781 #channelA_ok = False
656 #rfunc = cspectra.copy() #self.bloques
782 #rfunc = cspectra.copy() #self.bloques
657 rfunc = spectra.copy()
783 rfunc = spectra.copy()
658 #rfunc = cspectra
784 #rfunc = cspectra
659 #val_spc = spectra*0.0 #self.bloque0*0.0
785 #val_spc = spectra*0.0 #self.bloque0*0.0
660 #val_cspc = cspectra*0.0 #self.bloques*0.0
786 #val_cspc = cspectra*0.0 #self.bloques*0.0
661 #in_sat_spectra = spectra.copy() #self.bloque0
787 #in_sat_spectra = spectra.copy() #self.bloque0
662 #in_sat_cspectra = cspectra.copy() #self.bloques
788 #in_sat_cspectra = cspectra.copy() #self.bloques
663
789
664
790
665 ###ONLY FOR TEST:
791 ###ONLY FOR TEST:
666 raxs = math.ceil(math.sqrt(self.nPairs))
792 raxs = math.ceil(math.sqrt(self.nPairs))
667 caxs = math.ceil(self.nPairs/raxs)
793 caxs = math.ceil(self.nPairs/raxs)
668 if self.nPairs <4:
794 if self.nPairs <4:
669 raxs = 2
795 raxs = 2
670 caxs = 2
796 caxs = 2
671 #print(raxs, caxs)
797 #print(raxs, caxs)
672 fft_rev = 14 #nFFT to plot
798 fft_rev = 14 #nFFT to plot
673 hei_rev = ((self.heights >= 550) & (self.heights <= 551)).nonzero() #hei to plot
799 hei_rev = ((self.heights >= 550) & (self.heights <= 551)).nonzero() #hei to plot
674 hei_rev = hei_rev[0]
800 hei_rev = hei_rev[0]
675 #print(hei_rev)
801 #print(hei_rev)
676
802
677 #print numpy.absolute(rfunc[:,0,0,14])
803 #print numpy.absolute(rfunc[:,0,0,14])
678
804
679 gauss_fit, covariance = None, None
805 gauss_fit, covariance = None, None
680 for ih in range(self.minAltInd,self.maxAltInd):
806 for ih in range(self.minAltInd,self.maxAltInd):
681 for ifreq in range(self.nFFTPoints):
807 for ifreq in range(self.nFFTPoints):
682 '''
808 '''
683 ###ONLY FOR TEST:
809 ###ONLY FOR TEST:
684 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
810 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
685 fig, axs = plt.subplots(raxs, caxs)
811 fig, axs = plt.subplots(raxs, caxs)
686 fig2, axs2 = plt.subplots(raxs, caxs)
812 fig2, axs2 = plt.subplots(raxs, caxs)
687 col_ax = 0
813 col_ax = 0
688 row_ax = 0
814 row_ax = 0
689 '''
815 '''
690 #print(self.nPairs)
816 #print(self.nPairs)
691 for ii in range(self.nChan): #PARES DE CANALES SELF y CROSS
817 for ii in range(self.nChan): #PARES DE CANALES SELF y CROSS
692 # if self.crosspairs[ii][1]-self.crosspairs[ii][0] > 1: # APLICAR SOLO EN PARES CONTIGUOS
818 # if self.crosspairs[ii][1]-self.crosspairs[ii][0] > 1: # APLICAR SOLO EN PARES CONTIGUOS
693 # continue
819 # continue
694 # if not self.crosspairs[ii][0] in channelsProcssd:
820 # if not self.crosspairs[ii][0] in channelsProcssd:
695 # channelA_ok = True
821 # channelA_ok = True
696 #print("pair: ",self.crosspairs[ii])
822 #print("pair: ",self.crosspairs[ii])
697 '''
823 '''
698 ###ONLY FOR TEST:
824 ###ONLY FOR TEST:
699 if (col_ax%caxs==0 and col_ax!=0 and self.nPairs !=1):
825 if (col_ax%caxs==0 and col_ax!=0 and self.nPairs !=1):
700 col_ax = 0
826 col_ax = 0
701 row_ax += 1
827 row_ax += 1
702 '''
828 '''
703 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
829 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
704 #print(func2clean.shape)
830 #print(func2clean.shape)
705 val = (numpy.isfinite(func2clean)==True).nonzero()
831 val = (numpy.isfinite(func2clean)==True).nonzero()
706
832
707 if len(val)>0: #limitador
833 if len(val)>0: #limitador
708 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
834 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
709 if min_val <= -40 :
835 if min_val <= -40 :
710 min_val = -40
836 min_val = -40
711 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
837 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
712 if max_val >= 200 :
838 if max_val >= 200 :
713 max_val = 200
839 max_val = 200
714 #print min_val, max_val
840 #print min_val, max_val
715 step = 1
841 step = 1
716 #print("Getting bins and the histogram")
842 #print("Getting bins and the histogram")
717 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
843 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
718 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
844 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
719 #print(len(y_dist),len(binstep[:-1]))
845 #print(len(y_dist),len(binstep[:-1]))
720 #print(row_ax,col_ax, " ..")
846 #print(row_ax,col_ax, " ..")
721 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
847 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
722 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
848 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
723 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
849 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
724 parg = [numpy.amax(y_dist),mean,sigma]
850 parg = [numpy.amax(y_dist),mean,sigma]
725
851
726 newY = None
852 newY = None
727
853
728 try :
854 try :
729 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
855 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
730 mode = gauss_fit[1]
856 mode = gauss_fit[1]
731 stdv = gauss_fit[2]
857 stdv = gauss_fit[2]
732 #print(" FIT OK",gauss_fit)
858 #print(" FIT OK",gauss_fit)
733 '''
859 '''
734 ###ONLY FOR TEST:
860 ###ONLY FOR TEST:
735 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
861 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
736 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
862 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
737 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
863 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
738 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
864 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
739 axs[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
865 axs[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
740 '''
866 '''
741 except:
867 except:
742 mode = mean
868 mode = mean
743 stdv = sigma
869 stdv = sigma
744 #print("FIT FAIL")
870 #print("FIT FAIL")
745 #continue
871 #continue
746
872
747
873
748 #print(mode,stdv)
874 #print(mode,stdv)
749 #Removing echoes greater than mode + std_factor*stdv
875 #Removing echoes greater than mode + std_factor*stdv
750 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
876 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
751 #noval tiene los indices que se van a remover
877 #noval tiene los indices que se van a remover
752 #print("Chan ",ii," novals: ",len(noval[0]))
878 #print("Chan ",ii," novals: ",len(noval[0]))
753 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
879 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
754 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
880 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
755 #print(novall)
881 #print(novall)
756 #print(" ",self.pairsArray[ii])
882 #print(" ",self.pairsArray[ii])
757 #cross_pairs = self.pairsArray[ii]
883 #cross_pairs = self.pairsArray[ii]
758 #Getting coherent echoes which are removed.
884 #Getting coherent echoes which are removed.
759 # if len(novall[0]) > 0:
885 # if len(novall[0]) > 0:
760 #
886 #
761 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
887 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
762 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
888 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
763 # val_cspc[novall[0],ii,ifreq,ih] = 1
889 # val_cspc[novall[0],ii,ifreq,ih] = 1
764 #print("OUT NOVALL 1")
890 #print("OUT NOVALL 1")
765 try:
891 try:
766 pair = (self.channels[ii],self.channels[ii + 1])
892 pair = (self.channels[ii],self.channels[ii + 1])
767 except:
893 except:
768 pair = (99,99)
894 pair = (99,99)
769 #print("par ", pair)
895 #print("par ", pair)
770 if ( pair in self.crosspairs):
896 if ( pair in self.crosspairs):
771 q = self.crosspairs.index(pair)
897 q = self.crosspairs.index(pair)
772 #print("estΓ‘ aqui: ", q, (ii,ii + 1))
898 #print("estΓ‘ aqui: ", q, (ii,ii + 1))
773 new_a = numpy.delete(cspectra[:,q,ifreq,ih], noval[0])
899 new_a = numpy.delete(cspectra[:,q,ifreq,ih], noval[0])
774 cspectra[noval,q,ifreq,ih] = numpy.mean(new_a) #mean CrossSpectra
900 cspectra[noval,q,ifreq,ih] = numpy.mean(new_a) #mean CrossSpectra
775
901
776 #if channelA_ok:
902 #if channelA_ok:
777 #chA = self.channels.index(cross_pairs[0])
903 #chA = self.channels.index(cross_pairs[0])
778 new_b = numpy.delete(spectra[:,ii,ifreq,ih], noval[0])
904 new_b = numpy.delete(spectra[:,ii,ifreq,ih], noval[0])
779 spectra[noval,ii,ifreq,ih] = numpy.mean(new_b) #mean Spectra Pair A
905 spectra[noval,ii,ifreq,ih] = numpy.mean(new_b) #mean Spectra Pair A
780 #channelA_ok = False
906 #channelA_ok = False
781
907
782 # chB = self.channels.index(cross_pairs[1])
908 # chB = self.channels.index(cross_pairs[1])
783 # new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
909 # new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
784 # spectra[noval,chB,ifreq,ih] = numpy.mean(new_c) #mean Spectra Pair B
910 # spectra[noval,chB,ifreq,ih] = numpy.mean(new_c) #mean Spectra Pair B
785 #
911 #
786 # channelsProcssd.append(self.crosspairs[ii][0]) # save channel A
912 # channelsProcssd.append(self.crosspairs[ii][0]) # save channel A
787 # channelsProcssd.append(self.crosspairs[ii][1]) # save channel B
913 # channelsProcssd.append(self.crosspairs[ii][1]) # save channel B
788 '''
914 '''
789 ###ONLY FOR TEST:
915 ###ONLY FOR TEST:
790 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
916 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
791 func2clean = 10*numpy.log10(numpy.absolute(spectra[:,ii,ifreq,ih]))
917 func2clean = 10*numpy.log10(numpy.absolute(spectra[:,ii,ifreq,ih]))
792 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
918 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
793 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
919 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
794 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
920 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
795 axs2[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
921 axs2[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
796 '''
922 '''
797 '''
923 '''
798 ###ONLY FOR TEST:
924 ###ONLY FOR TEST:
799 col_ax += 1 #contador de ploteo columnas
925 col_ax += 1 #contador de ploteo columnas
800 ##print(col_ax)
926 ##print(col_ax)
801 ###ONLY FOR TEST:
927 ###ONLY FOR TEST:
802 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
928 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
803 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
929 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
804 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
930 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
805 fig.suptitle(title)
931 fig.suptitle(title)
806 fig2.suptitle(title2)
932 fig2.suptitle(title2)
807 plt.show()
933 plt.show()
808 '''
934 '''
809 ##################################################################################################
935 ##################################################################################################
810
936
811 #print("Getting average of the spectra and cross-spectra from incoherent echoes.")
937 #print("Getting average of the spectra and cross-spectra from incoherent echoes.")
812 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
938 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
813 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
939 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
814 for ih in range(self.nHeights):
940 for ih in range(self.nHeights):
815 for ifreq in range(self.nFFTPoints):
941 for ifreq in range(self.nFFTPoints):
816 for ich in range(self.nChan):
942 for ich in range(self.nChan):
817 tmp = spectra[:,ich,ifreq,ih]
943 tmp = spectra[:,ich,ifreq,ih]
818 valid = (numpy.isfinite(tmp[:])==True).nonzero()
944 valid = (numpy.isfinite(tmp[:])==True).nonzero()
819
945
820 if len(valid[0]) >0 :
946 if len(valid[0]) >0 :
821 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
947 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
822
948
823 for icr in range(self.nPairs):
949 for icr in range(self.nPairs):
824 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
950 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
825 valid = (numpy.isfinite(tmp)==True).nonzero()
951 valid = (numpy.isfinite(tmp)==True).nonzero()
826 if len(valid[0]) > 0:
952 if len(valid[0]) > 0:
827 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
953 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
828
954
829 return out_spectra, out_cspectra
955 return out_spectra, out_cspectra
830
956
831 def REM_ISOLATED_POINTS(self,array,rth):
957 def REM_ISOLATED_POINTS(self,array,rth):
832 # import matplotlib.pyplot as plt
958 # import matplotlib.pyplot as plt
833 if rth == None :
959 if rth == None :
834 rth = 4
960 rth = 4
835 #print("REM ISO")
961 #print("REM ISO")
836 num_prof = len(array[0,:,0])
962 num_prof = len(array[0,:,0])
837 num_hei = len(array[0,0,:])
963 num_hei = len(array[0,0,:])
838 n2d = len(array[:,0,0])
964 n2d = len(array[:,0,0])
839
965
840 for ii in range(n2d) :
966 for ii in range(n2d) :
841 #print ii,n2d
967 #print ii,n2d
842 tmp = array[ii,:,:]
968 tmp = array[ii,:,:]
843 #print tmp.shape, array[ii,101,:],array[ii,102,:]
969 #print tmp.shape, array[ii,101,:],array[ii,102,:]
844
970
845 # fig = plt.figure(figsize=(6,5))
971 # fig = plt.figure(figsize=(6,5))
846 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
972 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
847 # ax = fig.add_axes([left, bottom, width, height])
973 # ax = fig.add_axes([left, bottom, width, height])
848 # x = range(num_prof)
974 # x = range(num_prof)
849 # y = range(num_hei)
975 # y = range(num_hei)
850 # cp = ax.contour(y,x,tmp)
976 # cp = ax.contour(y,x,tmp)
851 # ax.clabel(cp, inline=True,fontsize=10)
977 # ax.clabel(cp, inline=True,fontsize=10)
852 # plt.show()
978 # plt.show()
853
979
854 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
980 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
855 tmp = numpy.reshape(tmp,num_prof*num_hei)
981 tmp = numpy.reshape(tmp,num_prof*num_hei)
856 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
982 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
857 indxs2 = (tmp > 0).nonzero()
983 indxs2 = (tmp > 0).nonzero()
858
984
859 indxs1 = (indxs1[0])
985 indxs1 = (indxs1[0])
860 indxs2 = indxs2[0]
986 indxs2 = indxs2[0]
861 #indxs1 = numpy.array(indxs1[0])
987 #indxs1 = numpy.array(indxs1[0])
862 #indxs2 = numpy.array(indxs2[0])
988 #indxs2 = numpy.array(indxs2[0])
863 indxs = None
989 indxs = None
864 #print indxs1 , indxs2
990 #print indxs1 , indxs2
865 for iv in range(len(indxs2)):
991 for iv in range(len(indxs2)):
866 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
992 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
867 #print len(indxs2), indv
993 #print len(indxs2), indv
868 if len(indv[0]) > 0 :
994 if len(indv[0]) > 0 :
869 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
995 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
870 # print indxs
996 # print indxs
871 indxs = indxs[1:]
997 indxs = indxs[1:]
872 #print(indxs, len(indxs))
998 #print(indxs, len(indxs))
873 if len(indxs) < 4 :
999 if len(indxs) < 4 :
874 array[ii,:,:] = 0.
1000 array[ii,:,:] = 0.
875 return
1001 return
876
1002
877 xpos = numpy.mod(indxs ,num_hei)
1003 xpos = numpy.mod(indxs ,num_hei)
878 ypos = (indxs / num_hei)
1004 ypos = (indxs / num_hei)
879 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
1005 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
880 #print sx
1006 #print sx
881 xpos = xpos[sx]
1007 xpos = xpos[sx]
882 ypos = ypos[sx]
1008 ypos = ypos[sx]
883
1009
884 # *********************************** Cleaning isolated points **********************************
1010 # *********************************** Cleaning isolated points **********************************
885 ic = 0
1011 ic = 0
886 while True :
1012 while True :
887 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
1013 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
888 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
1014 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
889 #plt.plot(r)
1015 #plt.plot(r)
890 #plt.show()
1016 #plt.show()
891 no_coh1 = (numpy.isfinite(r)==True).nonzero()
1017 no_coh1 = (numpy.isfinite(r)==True).nonzero()
892 no_coh2 = (r <= rth).nonzero()
1018 no_coh2 = (r <= rth).nonzero()
893 #print r, no_coh1, no_coh2
1019 #print r, no_coh1, no_coh2
894 no_coh1 = numpy.array(no_coh1[0])
1020 no_coh1 = numpy.array(no_coh1[0])
895 no_coh2 = numpy.array(no_coh2[0])
1021 no_coh2 = numpy.array(no_coh2[0])
896 no_coh = None
1022 no_coh = None
897 #print valid1 , valid2
1023 #print valid1 , valid2
898 for iv in range(len(no_coh2)):
1024 for iv in range(len(no_coh2)):
899 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
1025 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
900 if len(indv[0]) > 0 :
1026 if len(indv[0]) > 0 :
901 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
1027 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
902 no_coh = no_coh[1:]
1028 no_coh = no_coh[1:]
903 #print len(no_coh), no_coh
1029 #print len(no_coh), no_coh
904 if len(no_coh) < 4 :
1030 if len(no_coh) < 4 :
905 #print xpos[ic], ypos[ic], ic
1031 #print xpos[ic], ypos[ic], ic
906 # plt.plot(r)
1032 # plt.plot(r)
907 # plt.show()
1033 # plt.show()
908 xpos[ic] = numpy.nan
1034 xpos[ic] = numpy.nan
909 ypos[ic] = numpy.nan
1035 ypos[ic] = numpy.nan
910
1036
911 ic = ic + 1
1037 ic = ic + 1
912 if (ic == len(indxs)) :
1038 if (ic == len(indxs)) :
913 break
1039 break
914 #print( xpos, ypos)
1040 #print( xpos, ypos)
915
1041
916 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
1042 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
917 #print indxs[0]
1043 #print indxs[0]
918 if len(indxs[0]) < 4 :
1044 if len(indxs[0]) < 4 :
919 array[ii,:,:] = 0.
1045 array[ii,:,:] = 0.
920 return
1046 return
921
1047
922 xpos = xpos[indxs[0]]
1048 xpos = xpos[indxs[0]]
923 ypos = ypos[indxs[0]]
1049 ypos = ypos[indxs[0]]
924 for i in range(0,len(ypos)):
1050 for i in range(0,len(ypos)):
925 ypos[i]=int(ypos[i])
1051 ypos[i]=int(ypos[i])
926 junk = tmp
1052 junk = tmp
927 tmp = junk*0.0
1053 tmp = junk*0.0
928
1054
929 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
1055 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
930 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
1056 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
931
1057
932 #print array.shape
1058 #print array.shape
933 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
1059 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
934 #print tmp.shape
1060 #print tmp.shape
935
1061
936 # fig = plt.figure(figsize=(6,5))
1062 # fig = plt.figure(figsize=(6,5))
937 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
1063 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
938 # ax = fig.add_axes([left, bottom, width, height])
1064 # ax = fig.add_axes([left, bottom, width, height])
939 # x = range(num_prof)
1065 # x = range(num_prof)
940 # y = range(num_hei)
1066 # y = range(num_hei)
941 # cp = ax.contour(y,x,array[ii,:,:])
1067 # cp = ax.contour(y,x,array[ii,:,:])
942 # ax.clabel(cp, inline=True,fontsize=10)
1068 # ax.clabel(cp, inline=True,fontsize=10)
943 # plt.show()
1069 # plt.show()
944 return array
1070 return array
945
1071
946
1072
947 class IntegrationFaradaySpectra(Operation):
1073 class IntegrationFaradaySpectra(Operation):
948
1074
949 __profIndex = 0
1075 __profIndex = 0
950 __withOverapping = False
1076 __withOverapping = False
951
1077
952 __byTime = False
1078 __byTime = False
953 __initime = None
1079 __initime = None
954 __lastdatatime = None
1080 __lastdatatime = None
955 __integrationtime = None
1081 __integrationtime = None
956
1082
957 __buffer_spc = None
1083 __buffer_spc = None
958 __buffer_cspc = None
1084 __buffer_cspc = None
959 __buffer_dc = None
1085 __buffer_dc = None
960
1086
961 __dataReady = False
1087 __dataReady = False
962
1088
963 __timeInterval = None
1089 __timeInterval = None
964
1090
965 n = None
1091 n = None
966
1092
967 def __init__(self):
1093 def __init__(self):
968
1094
969 Operation.__init__(self)
1095 Operation.__init__(self)
970
1096
971 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None):
1097 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None):
972 """
1098 """
973 Set the parameters of the integration class.
1099 Set the parameters of the integration class.
974
1100
975 Inputs:
1101 Inputs:
976
1102
977 n : Number of coherent integrations
1103 n : Number of coherent integrations
978 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1104 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
979 overlapping :
1105 overlapping :
980
1106
981 """
1107 """
982
1108
983 self.__initime = None
1109 self.__initime = None
984 self.__lastdatatime = 0
1110 self.__lastdatatime = 0
985
1111
986 self.__buffer_spc = []
1112 self.__buffer_spc = []
987 self.__buffer_cspc = []
1113 self.__buffer_cspc = []
988 self.__buffer_dc = 0
1114 self.__buffer_dc = 0
989
1115
990 self.__profIndex = 0
1116 self.__profIndex = 0
991 self.__dataReady = False
1117 self.__dataReady = False
992 self.__byTime = False
1118 self.__byTime = False
993
1119
994 #self.ByLags = dataOut.ByLags ###REDEFINIR
1120 #self.ByLags = dataOut.ByLags ###REDEFINIR
995 self.ByLags = False
1121 self.ByLags = False
996
1122
997 if DPL != None:
1123 if DPL != None:
998 self.DPL=DPL
1124 self.DPL=DPL
999 else:
1125 else:
1000 #self.DPL=dataOut.DPL ###REDEFINIR
1126 #self.DPL=dataOut.DPL ###REDEFINIR
1001 self.DPL=0
1127 self.DPL=0
1002
1128
1003 if n is None and timeInterval is None:
1129 if n is None and timeInterval is None:
1004 raise ValueError("n or timeInterval should be specified ...")
1130 raise ValueError("n or timeInterval should be specified ...")
1005
1131
1006 if n is not None:
1132 if n is not None:
1007 self.n = int(n)
1133 self.n = int(n)
1008 else:
1134 else:
1009
1135
1010 self.__integrationtime = int(timeInterval)
1136 self.__integrationtime = int(timeInterval)
1011 self.n = None
1137 self.n = None
1012 self.__byTime = True
1138 self.__byTime = True
1013
1139
1014 def putData(self, data_spc, data_cspc, data_dc):
1140 def putData(self, data_spc, data_cspc, data_dc):
1015 """
1141 """
1016 Add a profile to the __buffer_spc and increase in one the __profileIndex
1142 Add a profile to the __buffer_spc and increase in one the __profileIndex
1017
1143
1018 """
1144 """
1019
1145
1020 self.__buffer_spc.append(data_spc)
1146 self.__buffer_spc.append(data_spc)
1021
1147
1022 if data_cspc is None:
1148 if data_cspc is None:
1023 self.__buffer_cspc = None
1149 self.__buffer_cspc = None
1024 else:
1150 else:
1025 self.__buffer_cspc.append(data_cspc)
1151 self.__buffer_cspc.append(data_cspc)
1026
1152
1027 if data_dc is None:
1153 if data_dc is None:
1028 self.__buffer_dc = None
1154 self.__buffer_dc = None
1029 else:
1155 else:
1030 self.__buffer_dc += data_dc
1156 self.__buffer_dc += data_dc
1031
1157
1032 self.__profIndex += 1
1158 self.__profIndex += 1
1033
1159
1034 return
1160 return
1035
1161
1036 def hildebrand_sekhon_Integration(self,data,navg):
1162 def hildebrand_sekhon_Integration(self,data,navg):
1037
1163
1038 sortdata = numpy.sort(data, axis=None)
1164 sortdata = numpy.sort(data, axis=None)
1039 sortID=data.argsort()
1165 sortID=data.argsort()
1040 lenOfData = len(sortdata)
1166 lenOfData = len(sortdata)
1041 nums_min = lenOfData*0.75
1167 nums_min = lenOfData*0.75
1042 if nums_min <= 5:
1168 if nums_min <= 5:
1043 nums_min = 5
1169 nums_min = 5
1044 sump = 0.
1170 sump = 0.
1045 sumq = 0.
1171 sumq = 0.
1046 j = 0
1172 j = 0
1047 cont = 1
1173 cont = 1
1048 while((cont == 1)and(j < lenOfData)):
1174 while((cont == 1)and(j < lenOfData)):
1049 sump += sortdata[j]
1175 sump += sortdata[j]
1050 sumq += sortdata[j]**2
1176 sumq += sortdata[j]**2
1051 if j > nums_min:
1177 if j > nums_min:
1052 rtest = float(j)/(j-1) + 1.0/navg
1178 rtest = float(j)/(j-1) + 1.0/navg
1053 if ((sumq*j) > (rtest*sump**2)):
1179 if ((sumq*j) > (rtest*sump**2)):
1054 j = j - 1
1180 j = j - 1
1055 sump = sump - sortdata[j]
1181 sump = sump - sortdata[j]
1056 sumq = sumq - sortdata[j]**2
1182 sumq = sumq - sortdata[j]**2
1057 cont = 0
1183 cont = 0
1058 j += 1
1184 j += 1
1059 #lnoise = sump / j
1185 #lnoise = sump / j
1060
1186
1061 return j,sortID
1187 return j,sortID
1062
1188
1063 def pushData(self):
1189 def pushData(self):
1064 """
1190 """
1065 Return the sum of the last profiles and the profiles used in the sum.
1191 Return the sum of the last profiles and the profiles used in the sum.
1066
1192
1067 Affected:
1193 Affected:
1068
1194
1069 self.__profileIndex
1195 self.__profileIndex
1070
1196
1071 """
1197 """
1072 bufferH=None
1198 bufferH=None
1073 buffer=None
1199 buffer=None
1074 buffer1=None
1200 buffer1=None
1075 buffer_cspc=None
1201 buffer_cspc=None
1076 self.__buffer_spc=numpy.array(self.__buffer_spc)
1202 self.__buffer_spc=numpy.array(self.__buffer_spc)
1077 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1203 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1078 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1204 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1079 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1205 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1080 for k in range(7,self.nHeights):
1206 for k in range(7,self.nHeights):
1081 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1207 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1082 outliers_IDs_cspc=[]
1208 outliers_IDs_cspc=[]
1083 cspc_outliers_exist=False
1209 cspc_outliers_exist=False
1084 for i in range(self.nChannels):#dataOut.nChannels):
1210 for i in range(self.nChannels):#dataOut.nChannels):
1085
1211
1086 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1212 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1087 indexes=[]
1213 indexes=[]
1088 #sortIDs=[]
1214 #sortIDs=[]
1089 outliers_IDs=[]
1215 outliers_IDs=[]
1090
1216
1091 for j in range(self.nProfiles):
1217 for j in range(self.nProfiles):
1092 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1218 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1093 # continue
1219 # continue
1094 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1220 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1095 # continue
1221 # continue
1096 buffer=buffer1[:,j]
1222 buffer=buffer1[:,j]
1097 index,sortID=self.hildebrand_sekhon_Integration(buffer,1)
1223 index,sortID=self.hildebrand_sekhon_Integration(buffer,1)
1098
1224
1099 indexes.append(index)
1225 indexes.append(index)
1100 #sortIDs.append(sortID)
1226 #sortIDs.append(sortID)
1101 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1227 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1102
1228
1103 outliers_IDs=numpy.array(outliers_IDs)
1229 outliers_IDs=numpy.array(outliers_IDs)
1104 outliers_IDs=outliers_IDs.ravel()
1230 outliers_IDs=outliers_IDs.ravel()
1105 outliers_IDs=numpy.unique(outliers_IDs)
1231 outliers_IDs=numpy.unique(outliers_IDs)
1106 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1232 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1107 indexes=numpy.array(indexes)
1233 indexes=numpy.array(indexes)
1108 indexmin=numpy.min(indexes)
1234 indexmin=numpy.min(indexes)
1109
1235
1110 if indexmin != buffer1.shape[0]:
1236 if indexmin != buffer1.shape[0]:
1111 cspc_outliers_exist=True
1237 cspc_outliers_exist=True
1112 ###sortdata=numpy.sort(buffer1,axis=0)
1238 ###sortdata=numpy.sort(buffer1,axis=0)
1113 ###avg2=numpy.mean(sortdata[:indexmin,:],axis=0)
1239 ###avg2=numpy.mean(sortdata[:indexmin,:],axis=0)
1114 lt=outliers_IDs
1240 lt=outliers_IDs
1115 avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1241 avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1116
1242
1117 for p in list(outliers_IDs):
1243 for p in list(outliers_IDs):
1118 buffer1[p,:]=avg
1244 buffer1[p,:]=avg
1119
1245
1120 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1246 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1121 ###cspc IDs
1247 ###cspc IDs
1122 #indexmin_cspc+=indexmin_cspc
1248 #indexmin_cspc+=indexmin_cspc
1123 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1249 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1124
1250
1125 #if not breakFlag:
1251 #if not breakFlag:
1126 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1252 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1127 if cspc_outliers_exist:
1253 if cspc_outliers_exist:
1128 #sortdata=numpy.sort(buffer_cspc,axis=0)
1254 #sortdata=numpy.sort(buffer_cspc,axis=0)
1129 #avg=numpy.mean(sortdata[:indexmin_cpsc,:],axis=0)
1255 #avg=numpy.mean(sortdata[:indexmin_cpsc,:],axis=0)
1130 lt=outliers_IDs_cspc
1256 lt=outliers_IDs_cspc
1131
1257
1132 avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1258 avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1133 for p in list(outliers_IDs_cspc):
1259 for p in list(outliers_IDs_cspc):
1134 buffer_cspc[p,:]=avg
1260 buffer_cspc[p,:]=avg
1135
1261
1136 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1262 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1137 #else:
1263 #else:
1138 #break
1264 #break
1139
1265
1140
1266
1141
1267
1142
1268
1143 buffer=None
1269 buffer=None
1144 bufferH=None
1270 bufferH=None
1145 buffer1=None
1271 buffer1=None
1146 buffer_cspc=None
1272 buffer_cspc=None
1147
1273
1148 #print("cpsc",self.__buffer_cspc[:,0,0,0,0])
1274 #print("cpsc",self.__buffer_cspc[:,0,0,0,0])
1149 #print(self.__profIndex)
1275 #print(self.__profIndex)
1150 #exit()
1276 #exit()
1151
1277
1152 buffer=None
1278 buffer=None
1153 #print(self.__buffer_spc[:,1,3,20,0])
1279 #print(self.__buffer_spc[:,1,3,20,0])
1154 #print(self.__buffer_spc[:,1,5,37,0])
1280 #print(self.__buffer_spc[:,1,5,37,0])
1155 data_spc = numpy.sum(self.__buffer_spc,axis=0)
1281 data_spc = numpy.sum(self.__buffer_spc,axis=0)
1156 data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1282 data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1157
1283
1158 #print(numpy.shape(data_spc))
1284 #print(numpy.shape(data_spc))
1159 #data_spc[1,4,20,0]=numpy.nan
1285 #data_spc[1,4,20,0]=numpy.nan
1160
1286
1161 #data_cspc = self.__buffer_cspc
1287 #data_cspc = self.__buffer_cspc
1162 data_dc = self.__buffer_dc
1288 data_dc = self.__buffer_dc
1163 n = self.__profIndex
1289 n = self.__profIndex
1164
1290
1165 self.__buffer_spc = []
1291 self.__buffer_spc = []
1166 self.__buffer_cspc = []
1292 self.__buffer_cspc = []
1167 self.__buffer_dc = 0
1293 self.__buffer_dc = 0
1168 self.__profIndex = 0
1294 self.__profIndex = 0
1169
1295
1170 return data_spc, data_cspc, data_dc, n
1296 return data_spc, data_cspc, data_dc, n
1171
1297
1172 def byProfiles(self, *args):
1298 def byProfiles(self, *args):
1173
1299
1174 self.__dataReady = False
1300 self.__dataReady = False
1175 avgdata_spc = None
1301 avgdata_spc = None
1176 avgdata_cspc = None
1302 avgdata_cspc = None
1177 avgdata_dc = None
1303 avgdata_dc = None
1178
1304
1179 self.putData(*args)
1305 self.putData(*args)
1180
1306
1181 if self.__profIndex == self.n:
1307 if self.__profIndex == self.n:
1182
1308
1183 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1309 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1184 self.n = n
1310 self.n = n
1185 self.__dataReady = True
1311 self.__dataReady = True
1186
1312
1187 return avgdata_spc, avgdata_cspc, avgdata_dc
1313 return avgdata_spc, avgdata_cspc, avgdata_dc
1188
1314
1189 def byTime(self, datatime, *args):
1315 def byTime(self, datatime, *args):
1190
1316
1191 self.__dataReady = False
1317 self.__dataReady = False
1192 avgdata_spc = None
1318 avgdata_spc = None
1193 avgdata_cspc = None
1319 avgdata_cspc = None
1194 avgdata_dc = None
1320 avgdata_dc = None
1195
1321
1196 self.putData(*args)
1322 self.putData(*args)
1197
1323
1198 if (datatime - self.__initime) >= self.__integrationtime:
1324 if (datatime - self.__initime) >= self.__integrationtime:
1199 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1325 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1200 self.n = n
1326 self.n = n
1201 self.__dataReady = True
1327 self.__dataReady = True
1202
1328
1203 return avgdata_spc, avgdata_cspc, avgdata_dc
1329 return avgdata_spc, avgdata_cspc, avgdata_dc
1204
1330
1205 def integrate(self, datatime, *args):
1331 def integrate(self, datatime, *args):
1206
1332
1207 if self.__profIndex == 0:
1333 if self.__profIndex == 0:
1208 self.__initime = datatime
1334 self.__initime = datatime
1209
1335
1210 if self.__byTime:
1336 if self.__byTime:
1211 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1337 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1212 datatime, *args)
1338 datatime, *args)
1213 else:
1339 else:
1214 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1340 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1215
1341
1216 if not self.__dataReady:
1342 if not self.__dataReady:
1217 return None, None, None, None
1343 return None, None, None, None
1218
1344
1219 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1345 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1220
1346
1221 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False):
1347 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False):
1222 if n == 1:
1348 if n == 1:
1223 return dataOut
1349 return dataOut
1224
1350
1225 dataOut.flagNoData = True
1351 dataOut.flagNoData = True
1226
1352
1227 if not self.isConfig:
1353 if not self.isConfig:
1228 self.setup(dataOut, n, timeInterval, overlapping,DPL )
1354 self.setup(dataOut, n, timeInterval, overlapping,DPL )
1229 self.isConfig = True
1355 self.isConfig = True
1230
1356
1231 if not self.ByLags:
1357 if not self.ByLags:
1232 self.nProfiles=dataOut.nProfiles
1358 self.nProfiles=dataOut.nProfiles
1233 self.nChannels=dataOut.nChannels
1359 self.nChannels=dataOut.nChannels
1234 self.nHeights=dataOut.nHeights
1360 self.nHeights=dataOut.nHeights
1235 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1361 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1236 dataOut.data_spc,
1362 dataOut.data_spc,
1237 dataOut.data_cspc,
1363 dataOut.data_cspc,
1238 dataOut.data_dc)
1364 dataOut.data_dc)
1239 else:
1365 else:
1240 self.nProfiles=dataOut.nProfiles
1366 self.nProfiles=dataOut.nProfiles
1241 self.nChannels=dataOut.nChannels
1367 self.nChannels=dataOut.nChannels
1242 self.nHeights=dataOut.nHeights
1368 self.nHeights=dataOut.nHeights
1243 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1369 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1244 dataOut.dataLag_spc,
1370 dataOut.dataLag_spc,
1245 dataOut.dataLag_cspc,
1371 dataOut.dataLag_cspc,
1246 dataOut.dataLag_dc)
1372 dataOut.dataLag_dc)
1247
1373
1248 if self.__dataReady:
1374 if self.__dataReady:
1249
1375
1250 if not self.ByLags:
1376 if not self.ByLags:
1251
1377
1252 dataOut.data_spc = numpy.squeeze(avgdata_spc)
1378 dataOut.data_spc = numpy.squeeze(avgdata_spc)
1253 dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1379 dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1254 dataOut.data_dc = avgdata_dc
1380 dataOut.data_dc = avgdata_dc
1255 else:
1381 else:
1256 dataOut.dataLag_spc = avgdata_spc
1382 dataOut.dataLag_spc = avgdata_spc
1257 dataOut.dataLag_cspc = avgdata_cspc
1383 dataOut.dataLag_cspc = avgdata_cspc
1258 dataOut.dataLag_dc = avgdata_dc
1384 dataOut.dataLag_dc = avgdata_dc
1259
1385
1260 dataOut.data_spc=dataOut.dataLag_spc[:,:,:,dataOut.LagPlot]
1386 dataOut.data_spc=dataOut.dataLag_spc[:,:,:,dataOut.LagPlot]
1261 dataOut.data_cspc=dataOut.dataLag_cspc[:,:,:,dataOut.LagPlot]
1387 dataOut.data_cspc=dataOut.dataLag_cspc[:,:,:,dataOut.LagPlot]
1262 dataOut.data_dc=dataOut.dataLag_dc[:,:,dataOut.LagPlot]
1388 dataOut.data_dc=dataOut.dataLag_dc[:,:,dataOut.LagPlot]
1263
1389
1264
1390
1265 dataOut.nIncohInt *= self.n
1391 dataOut.nIncohInt *= self.n
1266 dataOut.utctime = avgdatatime
1392 dataOut.utctime = avgdatatime
1267 dataOut.flagNoData = False
1393 dataOut.flagNoData = False
1268
1394
1269 return dataOut
1395 return dataOut
1270
1396
1271 class removeInterference(Operation):
1397 class removeInterference(Operation):
1272
1398
1273 def removeInterference2(self):
1399 def removeInterference2(self):
1274
1400
1275 cspc = self.dataOut.data_cspc
1401 cspc = self.dataOut.data_cspc
1276 spc = self.dataOut.data_spc
1402 spc = self.dataOut.data_spc
1277 Heights = numpy.arange(cspc.shape[2])
1403 Heights = numpy.arange(cspc.shape[2])
1278 realCspc = numpy.abs(cspc)
1404 realCspc = numpy.abs(cspc)
1279
1405
1280 for i in range(cspc.shape[0]):
1406 for i in range(cspc.shape[0]):
1281 LinePower= numpy.sum(realCspc[i], axis=0)
1407 LinePower= numpy.sum(realCspc[i], axis=0)
1282 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1408 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1283 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1409 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1284 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1410 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1285 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1411 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1286 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1412 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1287
1413
1288
1414
1289 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1415 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1290 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1416 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1291 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1417 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1292 cspc[i,InterferenceRange,:] = numpy.NaN
1418 cspc[i,InterferenceRange,:] = numpy.NaN
1293
1419
1294 self.dataOut.data_cspc = cspc
1420 self.dataOut.data_cspc = cspc
1295
1421
1296 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1422 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1297
1423
1298 jspectra = self.dataOut.data_spc
1424 jspectra = self.dataOut.data_spc
1299 jcspectra = self.dataOut.data_cspc
1425 jcspectra = self.dataOut.data_cspc
1300 jnoise = self.dataOut.getNoise()
1426 jnoise = self.dataOut.getNoise()
1301 num_incoh = self.dataOut.nIncohInt
1427 num_incoh = self.dataOut.nIncohInt
1302
1428
1303 num_channel = jspectra.shape[0]
1429 num_channel = jspectra.shape[0]
1304 num_prof = jspectra.shape[1]
1430 num_prof = jspectra.shape[1]
1305 num_hei = jspectra.shape[2]
1431 num_hei = jspectra.shape[2]
1306
1432
1307 # hei_interf
1433 # hei_interf
1308 if hei_interf is None:
1434 if hei_interf is None:
1309 count_hei = int(num_hei / 2)
1435 count_hei = int(num_hei / 2)
1310 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1436 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1311 hei_interf = numpy.asarray(hei_interf)[0]
1437 hei_interf = numpy.asarray(hei_interf)[0]
1312 # nhei_interf
1438 # nhei_interf
1313 if (nhei_interf == None):
1439 if (nhei_interf == None):
1314 nhei_interf = 5
1440 nhei_interf = 5
1315 if (nhei_interf < 1):
1441 if (nhei_interf < 1):
1316 nhei_interf = 1
1442 nhei_interf = 1
1317 if (nhei_interf > count_hei):
1443 if (nhei_interf > count_hei):
1318 nhei_interf = count_hei
1444 nhei_interf = count_hei
1319 if (offhei_interf == None):
1445 if (offhei_interf == None):
1320 offhei_interf = 0
1446 offhei_interf = 0
1321
1447
1322 ind_hei = list(range(num_hei))
1448 ind_hei = list(range(num_hei))
1323 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1449 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1324 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1450 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1325 mask_prof = numpy.asarray(list(range(num_prof)))
1451 mask_prof = numpy.asarray(list(range(num_prof)))
1326 num_mask_prof = mask_prof.size
1452 num_mask_prof = mask_prof.size
1327 comp_mask_prof = [0, num_prof / 2]
1453 comp_mask_prof = [0, num_prof / 2]
1328
1454
1329 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1455 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1330 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1456 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1331 jnoise = numpy.nan
1457 jnoise = numpy.nan
1332 noise_exist = jnoise[0] < numpy.Inf
1458 noise_exist = jnoise[0] < numpy.Inf
1333
1459
1334 # Subrutina de Remocion de la Interferencia
1460 # Subrutina de Remocion de la Interferencia
1335 for ich in range(num_channel):
1461 for ich in range(num_channel):
1336 # Se ordena los espectros segun su potencia (menor a mayor)
1462 # Se ordena los espectros segun su potencia (menor a mayor)
1337 power = jspectra[ich, mask_prof, :]
1463 power = jspectra[ich, mask_prof, :]
1338 power = power[:, hei_interf]
1464 power = power[:, hei_interf]
1339 power = power.sum(axis=0)
1465 power = power.sum(axis=0)
1340 psort = power.ravel().argsort()
1466 psort = power.ravel().argsort()
1341
1467
1342 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1468 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1343 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1469 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1344 offhei_interf, nhei_interf + offhei_interf))]]]
1470 offhei_interf, nhei_interf + offhei_interf))]]]
1345
1471
1346 if noise_exist:
1472 if noise_exist:
1347 # tmp_noise = jnoise[ich] / num_prof
1473 # tmp_noise = jnoise[ich] / num_prof
1348 tmp_noise = jnoise[ich]
1474 tmp_noise = jnoise[ich]
1349 junkspc_interf = junkspc_interf - tmp_noise
1475 junkspc_interf = junkspc_interf - tmp_noise
1350 #junkspc_interf[:,comp_mask_prof] = 0
1476 #junkspc_interf[:,comp_mask_prof] = 0
1351
1477
1352 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1478 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1353 jspc_interf = jspc_interf.transpose()
1479 jspc_interf = jspc_interf.transpose()
1354 # Calculando el espectro de interferencia promedio
1480 # Calculando el espectro de interferencia promedio
1355 noiseid = numpy.where(
1481 noiseid = numpy.where(
1356 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1482 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1357 noiseid = noiseid[0]
1483 noiseid = noiseid[0]
1358 cnoiseid = noiseid.size
1484 cnoiseid = noiseid.size
1359 interfid = numpy.where(
1485 interfid = numpy.where(
1360 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1486 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1361 interfid = interfid[0]
1487 interfid = interfid[0]
1362 cinterfid = interfid.size
1488 cinterfid = interfid.size
1363
1489
1364 if (cnoiseid > 0):
1490 if (cnoiseid > 0):
1365 jspc_interf[noiseid] = 0
1491 jspc_interf[noiseid] = 0
1366
1492
1367 # Expandiendo los perfiles a limpiar
1493 # Expandiendo los perfiles a limpiar
1368 if (cinterfid > 0):
1494 if (cinterfid > 0):
1369 new_interfid = (
1495 new_interfid = (
1370 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1496 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1371 new_interfid = numpy.asarray(new_interfid)
1497 new_interfid = numpy.asarray(new_interfid)
1372 new_interfid = {x for x in new_interfid}
1498 new_interfid = {x for x in new_interfid}
1373 new_interfid = numpy.array(list(new_interfid))
1499 new_interfid = numpy.array(list(new_interfid))
1374 new_cinterfid = new_interfid.size
1500 new_cinterfid = new_interfid.size
1375 else:
1501 else:
1376 new_cinterfid = 0
1502 new_cinterfid = 0
1377
1503
1378 for ip in range(new_cinterfid):
1504 for ip in range(new_cinterfid):
1379 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1505 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1380 jspc_interf[new_interfid[ip]
1506 jspc_interf[new_interfid[ip]
1381 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1507 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1382
1508
1383 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1509 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1384 ind_hei] - jspc_interf # Corregir indices
1510 ind_hei] - jspc_interf # Corregir indices
1385
1511
1386 # Removiendo la interferencia del punto de mayor interferencia
1512 # Removiendo la interferencia del punto de mayor interferencia
1387 ListAux = jspc_interf[mask_prof].tolist()
1513 ListAux = jspc_interf[mask_prof].tolist()
1388 maxid = ListAux.index(max(ListAux))
1514 maxid = ListAux.index(max(ListAux))
1389
1515
1390 if cinterfid > 0:
1516 if cinterfid > 0:
1391 for ip in range(cinterfid * (interf == 2) - 1):
1517 for ip in range(cinterfid * (interf == 2) - 1):
1392 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1518 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1393 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1519 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1394 cind = len(ind)
1520 cind = len(ind)
1395
1521
1396 if (cind > 0):
1522 if (cind > 0):
1397 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1523 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1398 (1 + (numpy.random.uniform(cind) - 0.5) /
1524 (1 + (numpy.random.uniform(cind) - 0.5) /
1399 numpy.sqrt(num_incoh))
1525 numpy.sqrt(num_incoh))
1400
1526
1401 ind = numpy.array([-2, -1, 1, 2])
1527 ind = numpy.array([-2, -1, 1, 2])
1402 xx = numpy.zeros([4, 4])
1528 xx = numpy.zeros([4, 4])
1403
1529
1404 for id1 in range(4):
1530 for id1 in range(4):
1405 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1531 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1406
1532
1407 xx_inv = numpy.linalg.inv(xx)
1533 xx_inv = numpy.linalg.inv(xx)
1408 xx = xx_inv[:, 0]
1534 xx = xx_inv[:, 0]
1409 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1535 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1410 yy = jspectra[ich, mask_prof[ind], :]
1536 yy = jspectra[ich, mask_prof[ind], :]
1411 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1537 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1412 yy.transpose(), xx)
1538 yy.transpose(), xx)
1413
1539
1414 indAux = (jspectra[ich, :, :] < tmp_noise *
1540 indAux = (jspectra[ich, :, :] < tmp_noise *
1415 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1541 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1416 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1542 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1417 (1 - 1 / numpy.sqrt(num_incoh))
1543 (1 - 1 / numpy.sqrt(num_incoh))
1418
1544
1419 # Remocion de Interferencia en el Cross Spectra
1545 # Remocion de Interferencia en el Cross Spectra
1420 if jcspectra is None:
1546 if jcspectra is None:
1421 return jspectra, jcspectra
1547 return jspectra, jcspectra
1422 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1548 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1423 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1549 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1424
1550
1425 for ip in range(num_pairs):
1551 for ip in range(num_pairs):
1426
1552
1427 #-------------------------------------------
1553 #-------------------------------------------
1428
1554
1429 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1555 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1430 cspower = cspower[:, hei_interf]
1556 cspower = cspower[:, hei_interf]
1431 cspower = cspower.sum(axis=0)
1557 cspower = cspower.sum(axis=0)
1432
1558
1433 cspsort = cspower.ravel().argsort()
1559 cspsort = cspower.ravel().argsort()
1434 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1560 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1435 offhei_interf, nhei_interf + offhei_interf))]]]
1561 offhei_interf, nhei_interf + offhei_interf))]]]
1436 junkcspc_interf = junkcspc_interf.transpose()
1562 junkcspc_interf = junkcspc_interf.transpose()
1437 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1563 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1438
1564
1439 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1565 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1440
1566
1441 median_real = int(numpy.median(numpy.real(
1567 median_real = int(numpy.median(numpy.real(
1442 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1568 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1443 median_imag = int(numpy.median(numpy.imag(
1569 median_imag = int(numpy.median(numpy.imag(
1444 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1570 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1445 comp_mask_prof = [int(e) for e in comp_mask_prof]
1571 comp_mask_prof = [int(e) for e in comp_mask_prof]
1446 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1572 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1447 median_real, median_imag)
1573 median_real, median_imag)
1448
1574
1449 for iprof in range(num_prof):
1575 for iprof in range(num_prof):
1450 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1576 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1451 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1577 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1452
1578
1453 # Removiendo la Interferencia
1579 # Removiendo la Interferencia
1454 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1580 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1455 :, ind_hei] - jcspc_interf
1581 :, ind_hei] - jcspc_interf
1456
1582
1457 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1583 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1458 maxid = ListAux.index(max(ListAux))
1584 maxid = ListAux.index(max(ListAux))
1459
1585
1460 ind = numpy.array([-2, -1, 1, 2])
1586 ind = numpy.array([-2, -1, 1, 2])
1461 xx = numpy.zeros([4, 4])
1587 xx = numpy.zeros([4, 4])
1462
1588
1463 for id1 in range(4):
1589 for id1 in range(4):
1464 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1590 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1465
1591
1466 xx_inv = numpy.linalg.inv(xx)
1592 xx_inv = numpy.linalg.inv(xx)
1467 xx = xx_inv[:, 0]
1593 xx = xx_inv[:, 0]
1468
1594
1469 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1595 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1470 yy = jcspectra[ip, mask_prof[ind], :]
1596 yy = jcspectra[ip, mask_prof[ind], :]
1471 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1597 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1472
1598
1473 # Guardar Resultados
1599 # Guardar Resultados
1474 self.dataOut.data_spc = jspectra
1600 self.dataOut.data_spc = jspectra
1475 self.dataOut.data_cspc = jcspectra
1601 self.dataOut.data_cspc = jcspectra
1476
1602
1477 return 1
1603 return 1
1478
1604
1479 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1605 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1480
1606
1481 self.dataOut = dataOut
1607 self.dataOut = dataOut
1482
1608
1483 if mode == 1:
1609 if mode == 1:
1484 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1610 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1485 elif mode == 2:
1611 elif mode == 2:
1486 self.removeInterference2()
1612 self.removeInterference2()
1487
1613
1488 return self.dataOut
1614 return self.dataOut
1489
1615
1490
1616
1491 class IncohInt(Operation):
1617 class IncohInt(Operation):
1492
1618
1493 __profIndex = 0
1619 __profIndex = 0
1494 __withOverapping = False
1620 __withOverapping = False
1495
1621
1496 __byTime = False
1622 __byTime = False
1497 __initime = None
1623 __initime = None
1498 __lastdatatime = None
1624 __lastdatatime = None
1499 __integrationtime = None
1625 __integrationtime = None
1500
1626
1501 __buffer_spc = None
1627 __buffer_spc = None
1502 __buffer_cspc = None
1628 __buffer_cspc = None
1503 __buffer_dc = None
1629 __buffer_dc = None
1504
1630
1505 __dataReady = False
1631 __dataReady = False
1506
1632
1507 __timeInterval = None
1633 __timeInterval = None
1508
1634
1509 n = None
1635 n = None
1510
1636
1511 def __init__(self):
1637 def __init__(self):
1512
1638
1513 Operation.__init__(self)
1639 Operation.__init__(self)
1514
1640
1515 def setup(self, n=None, timeInterval=None, overlapping=False):
1641 def setup(self, n=None, timeInterval=None, overlapping=False):
1516 """
1642 """
1517 Set the parameters of the integration class.
1643 Set the parameters of the integration class.
1518
1644
1519 Inputs:
1645 Inputs:
1520
1646
1521 n : Number of coherent integrations
1647 n : Number of coherent integrations
1522 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1648 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1523 overlapping :
1649 overlapping :
1524
1650
1525 """
1651 """
1526
1652
1527 self.__initime = None
1653 self.__initime = None
1528 self.__lastdatatime = 0
1654 self.__lastdatatime = 0
1529
1655
1530 self.__buffer_spc = 0
1656 self.__buffer_spc = 0
1531 self.__buffer_cspc = 0
1657 self.__buffer_cspc = 0
1532 self.__buffer_dc = 0
1658 self.__buffer_dc = 0
1533
1659
1534 self.__profIndex = 0
1660 self.__profIndex = 0
1535 self.__dataReady = False
1661 self.__dataReady = False
1536 self.__byTime = False
1662 self.__byTime = False
1537
1663
1538 if n is None and timeInterval is None:
1664 if n is None and timeInterval is None:
1539 raise ValueError("n or timeInterval should be specified ...")
1665 raise ValueError("n or timeInterval should be specified ...")
1540
1666
1541 if n is not None:
1667 if n is not None:
1542 self.n = int(n)
1668 self.n = int(n)
1543 else:
1669 else:
1544
1670
1545 self.__integrationtime = int(timeInterval)
1671 self.__integrationtime = int(timeInterval)
1546 self.n = None
1672 self.n = None
1547 self.__byTime = True
1673 self.__byTime = True
1548
1674
1549 def putData(self, data_spc, data_cspc, data_dc):
1675 def putData(self, data_spc, data_cspc, data_dc):
1550 """
1676 """
1551 Add a profile to the __buffer_spc and increase in one the __profileIndex
1677 Add a profile to the __buffer_spc and increase in one the __profileIndex
1552
1678
1553 """
1679 """
1554
1680
1555 self.__buffer_spc += data_spc
1681 self.__buffer_spc += data_spc
1556
1682
1557 if data_cspc is None:
1683 if data_cspc is None:
1558 self.__buffer_cspc = None
1684 self.__buffer_cspc = None
1559 else:
1685 else:
1560 self.__buffer_cspc += data_cspc
1686 self.__buffer_cspc += data_cspc
1561
1687
1562 if data_dc is None:
1688 if data_dc is None:
1563 self.__buffer_dc = None
1689 self.__buffer_dc = None
1564 else:
1690 else:
1565 self.__buffer_dc += data_dc
1691 self.__buffer_dc += data_dc
1566
1692
1567 self.__profIndex += 1
1693 self.__profIndex += 1
1568
1694
1569 return
1695 return
1570
1696
1571 def pushData(self):
1697 def pushData(self):
1572 """
1698 """
1573 Return the sum of the last profiles and the profiles used in the sum.
1699 Return the sum of the last profiles and the profiles used in the sum.
1574
1700
1575 Affected:
1701 Affected:
1576
1702
1577 self.__profileIndex
1703 self.__profileIndex
1578
1704
1579 """
1705 """
1580
1706
1581 data_spc = self.__buffer_spc
1707 data_spc = self.__buffer_spc
1582 data_cspc = self.__buffer_cspc
1708 data_cspc = self.__buffer_cspc
1583 data_dc = self.__buffer_dc
1709 data_dc = self.__buffer_dc
1584 n = self.__profIndex
1710 n = self.__profIndex
1585
1711
1586 self.__buffer_spc = 0
1712 self.__buffer_spc = 0
1587 self.__buffer_cspc = 0
1713 self.__buffer_cspc = 0
1588 self.__buffer_dc = 0
1714 self.__buffer_dc = 0
1589 self.__profIndex = 0
1715 self.__profIndex = 0
1590
1716
1591 return data_spc, data_cspc, data_dc, n
1717 return data_spc, data_cspc, data_dc, n
1592
1718
1593 def byProfiles(self, *args):
1719 def byProfiles(self, *args):
1594
1720
1595 self.__dataReady = False
1721 self.__dataReady = False
1596 avgdata_spc = None
1722 avgdata_spc = None
1597 avgdata_cspc = None
1723 avgdata_cspc = None
1598 avgdata_dc = None
1724 avgdata_dc = None
1599
1725
1600 self.putData(*args)
1726 self.putData(*args)
1601
1727
1602 if self.__profIndex == self.n:
1728 if self.__profIndex == self.n:
1603
1729
1604 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1730 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1605 self.n = n
1731 self.n = n
1606 self.__dataReady = True
1732 self.__dataReady = True
1607
1733
1608 return avgdata_spc, avgdata_cspc, avgdata_dc
1734 return avgdata_spc, avgdata_cspc, avgdata_dc
1609
1735
1610 def byTime(self, datatime, *args):
1736 def byTime(self, datatime, *args):
1611
1737
1612 self.__dataReady = False
1738 self.__dataReady = False
1613 avgdata_spc = None
1739 avgdata_spc = None
1614 avgdata_cspc = None
1740 avgdata_cspc = None
1615 avgdata_dc = None
1741 avgdata_dc = None
1616
1742
1617 self.putData(*args)
1743 self.putData(*args)
1618
1744
1619 if (datatime - self.__initime) >= self.__integrationtime:
1745 if (datatime - self.__initime) >= self.__integrationtime:
1620 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1746 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1621 self.n = n
1747 self.n = n
1622 self.__dataReady = True
1748 self.__dataReady = True
1623
1749
1624 return avgdata_spc, avgdata_cspc, avgdata_dc
1750 return avgdata_spc, avgdata_cspc, avgdata_dc
1625
1751
1626 def integrate(self, datatime, *args):
1752 def integrate(self, datatime, *args):
1627
1753
1628 if self.__profIndex == 0:
1754 if self.__profIndex == 0:
1629 self.__initime = datatime
1755 self.__initime = datatime
1630
1756
1631 if self.__byTime:
1757 if self.__byTime:
1632 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1758 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1633 datatime, *args)
1759 datatime, *args)
1634 else:
1760 else:
1635 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1761 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1636
1762
1637 if not self.__dataReady:
1763 if not self.__dataReady:
1638 return None, None, None, None
1764 return None, None, None, None
1639
1765
1640 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1766 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1641
1767
1642 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1768 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1643 if n == 1:
1769 if n == 1:
1644 return dataOut
1770 return dataOut
1645
1771
1646 dataOut.flagNoData = True
1772 dataOut.flagNoData = True
1647
1773
1648 if not self.isConfig:
1774 if not self.isConfig:
1649 self.setup(n, timeInterval, overlapping)
1775 self.setup(n, timeInterval, overlapping)
1650 self.isConfig = True
1776 self.isConfig = True
1651
1777
1652 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1778 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1653 dataOut.data_spc,
1779 dataOut.data_spc,
1654 dataOut.data_cspc,
1780 dataOut.data_cspc,
1655 dataOut.data_dc)
1781 dataOut.data_dc)
1656
1782
1657 if self.__dataReady:
1783 if self.__dataReady:
1658
1784
1659 dataOut.data_spc = avgdata_spc
1785 dataOut.data_spc = avgdata_spc
1660 dataOut.data_cspc = avgdata_cspc
1786 dataOut.data_cspc = avgdata_cspc
1661 dataOut.data_dc = avgdata_dc
1787 dataOut.data_dc = avgdata_dc
1662 dataOut.nIncohInt *= self.n
1788 dataOut.nIncohInt *= self.n
1663 dataOut.utctime = avgdatatime
1789 dataOut.utctime = avgdatatime
1664 dataOut.flagNoData = False
1790 dataOut.flagNoData = False
1665
1791
1666 return dataOut
1792 return dataOut
1667
1793
1668 class dopplerFlip(Operation):
1794 class dopplerFlip(Operation):
1669
1795
1670 def run(self, dataOut):
1796 def run(self, dataOut):
1671 # arreglo 1: (num_chan, num_profiles, num_heights)
1797 # arreglo 1: (num_chan, num_profiles, num_heights)
1672 self.dataOut = dataOut
1798 self.dataOut = dataOut
1673 # JULIA-oblicua, indice 2
1799 # JULIA-oblicua, indice 2
1674 # arreglo 2: (num_profiles, num_heights)
1800 # arreglo 2: (num_profiles, num_heights)
1675 jspectra = self.dataOut.data_spc[2]
1801 jspectra = self.dataOut.data_spc[2]
1676 jspectra_tmp = numpy.zeros(jspectra.shape)
1802 jspectra_tmp = numpy.zeros(jspectra.shape)
1677 num_profiles = jspectra.shape[0]
1803 num_profiles = jspectra.shape[0]
1678 freq_dc = int(num_profiles / 2)
1804 freq_dc = int(num_profiles / 2)
1679 # Flip con for
1805 # Flip con for
1680 for j in range(num_profiles):
1806 for j in range(num_profiles):
1681 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1807 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1682 # Intercambio perfil de DC con perfil inmediato anterior
1808 # Intercambio perfil de DC con perfil inmediato anterior
1683 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1809 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1684 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1810 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1685 # canal modificado es re-escrito en el arreglo de canales
1811 # canal modificado es re-escrito en el arreglo de canales
1686 self.dataOut.data_spc[2] = jspectra_tmp
1812 self.dataOut.data_spc[2] = jspectra_tmp
1687
1813
1688 return self.dataOut
1814 return self.dataOut
General Comments 0
You need to be logged in to leave comments. Login now