##// END OF EJS Templates
Wind and rainfall processing of CLAIRE radar with V3.0
George Yong -
r1205:45d75be01895
parent child
Show More
@@ -1,1363 +1,1353
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
5 '''
5 '''
6
6
7 import copy
7 import copy
8 import numpy
8 import numpy
9 import datetime
9 import datetime
10 import json
10 import json
11
11
12 from schainpy.utils import log
12 from schainpy.utils import log
13 from .jroheaderIO import SystemHeader, RadarControllerHeader
13 from .jroheaderIO import SystemHeader, RadarControllerHeader
14
14
15
15
16 def getNumpyDtype(dataTypeCode):
16 def getNumpyDtype(dataTypeCode):
17
17
18 if dataTypeCode == 0:
18 if dataTypeCode == 0:
19 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
19 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
20 elif dataTypeCode == 1:
20 elif dataTypeCode == 1:
21 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
21 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
22 elif dataTypeCode == 2:
22 elif dataTypeCode == 2:
23 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
23 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
24 elif dataTypeCode == 3:
24 elif dataTypeCode == 3:
25 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
25 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
26 elif dataTypeCode == 4:
26 elif dataTypeCode == 4:
27 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
27 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
28 elif dataTypeCode == 5:
28 elif dataTypeCode == 5:
29 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
29 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
30 else:
30 else:
31 raise ValueError('dataTypeCode was not defined')
31 raise ValueError('dataTypeCode was not defined')
32
32
33 return numpyDtype
33 return numpyDtype
34
34
35
35
36 def getDataTypeCode(numpyDtype):
36 def getDataTypeCode(numpyDtype):
37
37
38 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
38 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
39 datatype = 0
39 datatype = 0
40 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
40 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
41 datatype = 1
41 datatype = 1
42 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
42 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
43 datatype = 2
43 datatype = 2
44 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
44 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
45 datatype = 3
45 datatype = 3
46 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
46 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
47 datatype = 4
47 datatype = 4
48 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
48 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
49 datatype = 5
49 datatype = 5
50 else:
50 else:
51 datatype = None
51 datatype = None
52
52
53 return datatype
53 return datatype
54
54
55
55
56 def hildebrand_sekhon(data, navg):
56 def hildebrand_sekhon(data, navg):
57 """
57 """
58 This method is for the objective determination of the noise level in Doppler spectra. This
58 This method is for the objective determination of the noise level in Doppler spectra. This
59 implementation technique is based on the fact that the standard deviation of the spectral
59 implementation technique is based on the fact that the standard deviation of the spectral
60 densities is equal to the mean spectral density for white Gaussian noise
60 densities is equal to the mean spectral density for white Gaussian noise
61
61
62 Inputs:
62 Inputs:
63 Data : heights
63 Data : heights
64 navg : numbers of averages
64 navg : numbers of averages
65
65
66 Return:
66 Return:
67 mean : noise's level
67 mean : noise's level
68 """
68 """
69
69
70 sortdata = numpy.sort(data, axis=None)
70 sortdata = numpy.sort(data, axis=None)
71 lenOfData = len(sortdata)
71 lenOfData = len(sortdata)
72 nums_min = lenOfData*0.2
72 nums_min = lenOfData*0.2
73
73
74 if nums_min <= 5:
74 if nums_min <= 5:
75
75
76 nums_min = 5
76 nums_min = 5
77
77
78 sump = 0.
78 sump = 0.
79 sumq = 0.
79 sumq = 0.
80
80
81 j = 0
81 j = 0
82 cont = 1
82 cont = 1
83
83
84 while((cont == 1)and(j < lenOfData)):
84 while((cont == 1)and(j < lenOfData)):
85
85
86 sump += sortdata[j]
86 sump += sortdata[j]
87 sumq += sortdata[j]**2
87 sumq += sortdata[j]**2
88
88
89 if j > nums_min:
89 if j > nums_min:
90 rtest = float(j)/(j-1) + 1.0/navg
90 rtest = float(j)/(j-1) + 1.0/navg
91 if ((sumq*j) > (rtest*sump**2)):
91 if ((sumq*j) > (rtest*sump**2)):
92 j = j - 1
92 j = j - 1
93 sump = sump - sortdata[j]
93 sump = sump - sortdata[j]
94 sumq = sumq - sortdata[j]**2
94 sumq = sumq - sortdata[j]**2
95 cont = 0
95 cont = 0
96
96
97 j += 1
97 j += 1
98
98
99 lnoise = sump / j
99 lnoise = sump / j
100
100
101 return lnoise
101 return lnoise
102
102
103
103
104 class Beam:
104 class Beam:
105
105
106 def __init__(self):
106 def __init__(self):
107 self.codeList = []
107 self.codeList = []
108 self.azimuthList = []
108 self.azimuthList = []
109 self.zenithList = []
109 self.zenithList = []
110
110
111
111
112 class GenericData(object):
112 class GenericData(object):
113
113
114 flagNoData = True
114 flagNoData = True
115
115
116 def copy(self, inputObj=None):
116 def copy(self, inputObj=None):
117
117
118 if inputObj == None:
118 if inputObj == None:
119 return copy.deepcopy(self)
119 return copy.deepcopy(self)
120
120
121 for key in list(inputObj.__dict__.keys()):
121 for key in list(inputObj.__dict__.keys()):
122
122
123 attribute = inputObj.__dict__[key]
123 attribute = inputObj.__dict__[key]
124
124
125 # If this attribute is a tuple or list
125 # If this attribute is a tuple or list
126 if type(inputObj.__dict__[key]) in (tuple, list):
126 if type(inputObj.__dict__[key]) in (tuple, list):
127 self.__dict__[key] = attribute[:]
127 self.__dict__[key] = attribute[:]
128 continue
128 continue
129
129
130 # If this attribute is another object or instance
130 # If this attribute is another object or instance
131 if hasattr(attribute, '__dict__'):
131 if hasattr(attribute, '__dict__'):
132 self.__dict__[key] = attribute.copy()
132 self.__dict__[key] = attribute.copy()
133 continue
133 continue
134
134
135 self.__dict__[key] = inputObj.__dict__[key]
135 self.__dict__[key] = inputObj.__dict__[key]
136
136
137 def deepcopy(self):
137 def deepcopy(self):
138
138
139 return copy.deepcopy(self)
139 return copy.deepcopy(self)
140
140
141 def isEmpty(self):
141 def isEmpty(self):
142
142
143 return self.flagNoData
143 return self.flagNoData
144
144
145
145
146 class JROData(GenericData):
146 class JROData(GenericData):
147
147
148 # m_BasicHeader = BasicHeader()
148 # m_BasicHeader = BasicHeader()
149 # m_ProcessingHeader = ProcessingHeader()
149 # m_ProcessingHeader = ProcessingHeader()
150
150
151 systemHeaderObj = SystemHeader()
151 systemHeaderObj = SystemHeader()
152 radarControllerHeaderObj = RadarControllerHeader()
152 radarControllerHeaderObj = RadarControllerHeader()
153 # data = None
153 # data = None
154 type = None
154 type = None
155 datatype = None # dtype but in string
155 datatype = None # dtype but in string
156 # dtype = None
156 # dtype = None
157 # nChannels = None
157 # nChannels = None
158 # nHeights = None
158 # nHeights = None
159 nProfiles = None
159 nProfiles = None
160 heightList = None
160 heightList = None
161 channelList = None
161 channelList = None
162 flagDiscontinuousBlock = False
162 flagDiscontinuousBlock = False
163 useLocalTime = False
163 useLocalTime = False
164 utctime = None
164 utctime = None
165 timeZone = None
165 timeZone = None
166 dstFlag = None
166 dstFlag = None
167 errorCount = None
167 errorCount = None
168 blocksize = None
168 blocksize = None
169 # nCode = None
169 # nCode = None
170 # nBaud = None
170 # nBaud = None
171 # code = None
171 # code = None
172 flagDecodeData = False # asumo q la data no esta decodificada
172 flagDecodeData = False # asumo q la data no esta decodificada
173 flagDeflipData = False # asumo q la data no esta sin flip
173 flagDeflipData = False # asumo q la data no esta sin flip
174 flagShiftFFT = False
174 flagShiftFFT = False
175 # ippSeconds = None
175 # ippSeconds = None
176 # timeInterval = None
176 # timeInterval = None
177 nCohInt = None
177 nCohInt = None
178 # noise = None
178 # noise = None
179 windowOfFilter = 1
179 windowOfFilter = 1
180 # Speed of ligth
180 # Speed of ligth
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
194
195 def __str__(self):
195 def __str__(self):
196
196
197 return '{} - {}'.format(self.type, self.getDatatime())
197 return '{} - {}'.format(self.type, self.getDatatime())
198
198
199 def getNoise(self):
199 def getNoise(self):
200
200
201 raise NotImplementedError
201 raise NotImplementedError
202
202
203 def getNChannels(self):
203 def getNChannels(self):
204
204
205 return len(self.channelList)
205 return len(self.channelList)
206
206
207 def getChannelIndexList(self):
207 def getChannelIndexList(self):
208
208
209 return list(range(self.nChannels))
209 return list(range(self.nChannels))
210
210
211 def getNHeights(self):
211 def getNHeights(self):
212
212
213 return len(self.heightList)
213 return len(self.heightList)
214
214
215 def getHeiRange(self, extrapoints=0):
215 def getHeiRange(self, extrapoints=0):
216
216
217 heis = self.heightList
217 heis = self.heightList
218 # deltah = self.heightList[1] - self.heightList[0]
218 # deltah = self.heightList[1] - self.heightList[0]
219 #
219 #
220 # heis.append(self.heightList[-1])
220 # heis.append(self.heightList[-1])
221
221
222 return heis
222 return heis
223
223
224 def getDeltaH(self):
224 def getDeltaH(self):
225
225
226 delta = self.heightList[1] - self.heightList[0]
226 delta = self.heightList[1] - self.heightList[0]
227
227
228 return delta
228 return delta
229
229
230 def getltctime(self):
230 def getltctime(self):
231
231
232 if self.useLocalTime:
232 if self.useLocalTime:
233 return self.utctime - self.timeZone * 60
233 return self.utctime - self.timeZone * 60
234
234
235 return self.utctime
235 return self.utctime
236
236
237 def getDatatime(self):
237 def getDatatime(self):
238
238
239 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
239 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
240 return datatimeValue
240 return datatimeValue
241
241
242 def getTimeRange(self):
242 def getTimeRange(self):
243
243
244 datatime = []
244 datatime = []
245
245
246 datatime.append(self.ltctime)
246 datatime.append(self.ltctime)
247 datatime.append(self.ltctime + self.timeInterval + 1)
247 datatime.append(self.ltctime + self.timeInterval + 1)
248
248
249 datatime = numpy.array(datatime)
249 datatime = numpy.array(datatime)
250
250
251 return datatime
251 return datatime
252
252
253 def getFmaxTimeResponse(self):
253 def getFmaxTimeResponse(self):
254
254
255 period = (10**-6) * self.getDeltaH() / (0.15)
255 period = (10**-6) * self.getDeltaH() / (0.15)
256
256
257 PRF = 1. / (period * self.nCohInt)
257 PRF = 1. / (period * self.nCohInt)
258
258
259 fmax = PRF
259 fmax = PRF
260
260
261 return fmax
261 return fmax
262
262
263 def getFmax(self):
263 def getFmax(self):
264 PRF = 1. / (self.ippSeconds * self.nCohInt)
264 PRF = 1. / (self.ippSeconds * self.nCohInt)
265
265
266 fmax = PRF
266 fmax = PRF
267 return fmax
267 return fmax
268
268
269 def getVmax(self):
269 def getVmax(self):
270
270
271 _lambda = self.C / self.frequency
271 _lambda = self.C / self.frequency
272
272
273 vmax = self.getFmax() * _lambda / 2
273 vmax = self.getFmax() * _lambda / 2
274
274
275 return vmax
275 return vmax
276
276
277 def get_ippSeconds(self):
277 def get_ippSeconds(self):
278 '''
278 '''
279 '''
279 '''
280 return self.radarControllerHeaderObj.ippSeconds
280 return self.radarControllerHeaderObj.ippSeconds
281
281
282 def set_ippSeconds(self, ippSeconds):
282 def set_ippSeconds(self, ippSeconds):
283 '''
283 '''
284 '''
284 '''
285
285
286 self.radarControllerHeaderObj.ippSeconds = ippSeconds
286 self.radarControllerHeaderObj.ippSeconds = ippSeconds
287
287
288 return
288 return
289
289
290 def get_dtype(self):
290 def get_dtype(self):
291 '''
291 '''
292 '''
292 '''
293 return getNumpyDtype(self.datatype)
293 return getNumpyDtype(self.datatype)
294
294
295 def set_dtype(self, numpyDtype):
295 def set_dtype(self, numpyDtype):
296 '''
296 '''
297 '''
297 '''
298
298
299 self.datatype = getDataTypeCode(numpyDtype)
299 self.datatype = getDataTypeCode(numpyDtype)
300
300
301 def get_code(self):
301 def get_code(self):
302 '''
302 '''
303 '''
303 '''
304 return self.radarControllerHeaderObj.code
304 return self.radarControllerHeaderObj.code
305
305
306 def set_code(self, code):
306 def set_code(self, code):
307 '''
307 '''
308 '''
308 '''
309 self.radarControllerHeaderObj.code = code
309 self.radarControllerHeaderObj.code = code
310
310
311 return
311 return
312
312
313 def get_ncode(self):
313 def get_ncode(self):
314 '''
314 '''
315 '''
315 '''
316 return self.radarControllerHeaderObj.nCode
316 return self.radarControllerHeaderObj.nCode
317
317
318 def set_ncode(self, nCode):
318 def set_ncode(self, nCode):
319 '''
319 '''
320 '''
320 '''
321 self.radarControllerHeaderObj.nCode = nCode
321 self.radarControllerHeaderObj.nCode = nCode
322
322
323 return
323 return
324
324
325 def get_nbaud(self):
325 def get_nbaud(self):
326 '''
326 '''
327 '''
327 '''
328 return self.radarControllerHeaderObj.nBaud
328 return self.radarControllerHeaderObj.nBaud
329
329
330 def set_nbaud(self, nBaud):
330 def set_nbaud(self, nBaud):
331 '''
331 '''
332 '''
332 '''
333 self.radarControllerHeaderObj.nBaud = nBaud
333 self.radarControllerHeaderObj.nBaud = nBaud
334
334
335 return
335 return
336
336
337 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
337 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
338 channelIndexList = property(
338 channelIndexList = property(
339 getChannelIndexList, "I'm the 'channelIndexList' property.")
339 getChannelIndexList, "I'm the 'channelIndexList' property.")
340 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
340 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
341 #noise = property(getNoise, "I'm the 'nHeights' property.")
341 #noise = property(getNoise, "I'm the 'nHeights' property.")
342 datatime = property(getDatatime, "I'm the 'datatime' property")
342 datatime = property(getDatatime, "I'm the 'datatime' property")
343 ltctime = property(getltctime, "I'm the 'ltctime' property")
343 ltctime = property(getltctime, "I'm the 'ltctime' property")
344 ippSeconds = property(get_ippSeconds, set_ippSeconds)
344 ippSeconds = property(get_ippSeconds, set_ippSeconds)
345 dtype = property(get_dtype, set_dtype)
345 dtype = property(get_dtype, set_dtype)
346 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
346 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
347 code = property(get_code, set_code)
347 code = property(get_code, set_code)
348 nCode = property(get_ncode, set_ncode)
348 nCode = property(get_ncode, set_ncode)
349 nBaud = property(get_nbaud, set_nbaud)
349 nBaud = property(get_nbaud, set_nbaud)
350
350
351
351
352 class Voltage(JROData):
352 class Voltage(JROData):
353
353
354 # data es un numpy array de 2 dmensiones (canales, alturas)
354 # data es un numpy array de 2 dmensiones (canales, alturas)
355 data = None
355 data = None
356
356
357 def __init__(self):
357 def __init__(self):
358 '''
358 '''
359 Constructor
359 Constructor
360 '''
360 '''
361
361
362 self.useLocalTime = True
362 self.useLocalTime = True
363 self.radarControllerHeaderObj = RadarControllerHeader()
363 self.radarControllerHeaderObj = RadarControllerHeader()
364 self.systemHeaderObj = SystemHeader()
364 self.systemHeaderObj = SystemHeader()
365 self.type = "Voltage"
365 self.type = "Voltage"
366 self.data = None
366 self.data = None
367 # self.dtype = None
367 # self.dtype = None
368 # self.nChannels = 0
368 # self.nChannels = 0
369 # self.nHeights = 0
369 # self.nHeights = 0
370 self.nProfiles = None
370 self.nProfiles = None
371 self.heightList = None
371 self.heightList = None
372 self.channelList = None
372 self.channelList = None
373 # self.channelIndexList = None
373 # self.channelIndexList = None
374 self.flagNoData = True
374 self.flagNoData = True
375 self.flagDiscontinuousBlock = False
375 self.flagDiscontinuousBlock = False
376 self.utctime = None
376 self.utctime = None
377 self.timeZone = None
377 self.timeZone = None
378 self.dstFlag = None
378 self.dstFlag = None
379 self.errorCount = None
379 self.errorCount = None
380 self.nCohInt = None
380 self.nCohInt = None
381 self.blocksize = None
381 self.blocksize = None
382 self.flagDecodeData = False # asumo q la data no esta decodificada
382 self.flagDecodeData = False # asumo q la data no esta decodificada
383 self.flagDeflipData = False # asumo q la data no esta sin flip
383 self.flagDeflipData = False # asumo q la data no esta sin flip
384 self.flagShiftFFT = False
384 self.flagShiftFFT = False
385 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
385 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
386 self.profileIndex = 0
386 self.profileIndex = 0
387
387
388 def getNoisebyHildebrand(self, channel=None):
388 def getNoisebyHildebrand(self, channel=None):
389 """
389 """
390 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
390 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
391
391
392 Return:
392 Return:
393 noiselevel
393 noiselevel
394 """
394 """
395
395
396 if channel != None:
396 if channel != None:
397 data = self.data[channel]
397 data = self.data[channel]
398 nChannels = 1
398 nChannels = 1
399 else:
399 else:
400 data = self.data
400 data = self.data
401 nChannels = self.nChannels
401 nChannels = self.nChannels
402
402
403 noise = numpy.zeros(nChannels)
403 noise = numpy.zeros(nChannels)
404 power = data * numpy.conjugate(data)
404 power = data * numpy.conjugate(data)
405
405
406 for thisChannel in range(nChannels):
406 for thisChannel in range(nChannels):
407 if nChannels == 1:
407 if nChannels == 1:
408 daux = power[:].real
408 daux = power[:].real
409 else:
409 else:
410 daux = power[thisChannel, :].real
410 daux = power[thisChannel, :].real
411 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
411 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
412
412
413 return noise
413 return noise
414
414
415 def getNoise(self, type=1, channel=None):
415 def getNoise(self, type=1, channel=None):
416
416
417 if type == 1:
417 if type == 1:
418 noise = self.getNoisebyHildebrand(channel)
418 noise = self.getNoisebyHildebrand(channel)
419
419
420 return noise
420 return noise
421
421
422 def getPower(self, channel=None):
422 def getPower(self, channel=None):
423
423
424 if channel != None:
424 if channel != None:
425 data = self.data[channel]
425 data = self.data[channel]
426 else:
426 else:
427 data = self.data
427 data = self.data
428
428
429 power = data * numpy.conjugate(data)
429 power = data * numpy.conjugate(data)
430 powerdB = 10 * numpy.log10(power.real)
430 powerdB = 10 * numpy.log10(power.real)
431 powerdB = numpy.squeeze(powerdB)
431 powerdB = numpy.squeeze(powerdB)
432
432
433 return powerdB
433 return powerdB
434
434
435 def getTimeInterval(self):
435 def getTimeInterval(self):
436
436
437 timeInterval = self.ippSeconds * self.nCohInt
437 timeInterval = self.ippSeconds * self.nCohInt
438
438
439 return timeInterval
439 return timeInterval
440
440
441 noise = property(getNoise, "I'm the 'nHeights' property.")
441 noise = property(getNoise, "I'm the 'nHeights' property.")
442 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
442 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
443
443
444
444
445 class Spectra(JROData):
445 class Spectra(JROData):
446
446
447 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
447 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
448 data_spc = None
448 data_spc = None
449 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
449 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
450 data_cspc = None
450 data_cspc = None
451 # data dc es un numpy array de 2 dmensiones (canales, alturas)
451 # data dc es un numpy array de 2 dmensiones (canales, alturas)
452 data_dc = None
452 data_dc = None
453 # data power
453 # data power
454 data_pwr = None
454 data_pwr = None
455 nFFTPoints = None
455 nFFTPoints = None
456 # nPairs = None
456 # nPairs = None
457 pairsList = None
457 pairsList = None
458 nIncohInt = None
458 nIncohInt = None
459 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
459 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
460 nCohInt = None # se requiere para determinar el valor de timeInterval
460 nCohInt = None # se requiere para determinar el valor de timeInterval
461 ippFactor = None
461 ippFactor = None
462 profileIndex = 0
462 profileIndex = 0
463 plotting = "spectra"
463 plotting = "spectra"
464
464
465 def __init__(self):
465 def __init__(self):
466 '''
466 '''
467 Constructor
467 Constructor
468 '''
468 '''
469
469
470 self.useLocalTime = True
470 self.useLocalTime = True
471 self.radarControllerHeaderObj = RadarControllerHeader()
471 self.radarControllerHeaderObj = RadarControllerHeader()
472 self.systemHeaderObj = SystemHeader()
472 self.systemHeaderObj = SystemHeader()
473 self.type = "Spectra"
473 self.type = "Spectra"
474 # self.data = None
474 # self.data = None
475 # self.dtype = None
475 # self.dtype = None
476 # self.nChannels = 0
476 # self.nChannels = 0
477 # self.nHeights = 0
477 # self.nHeights = 0
478 self.nProfiles = None
478 self.nProfiles = None
479 self.heightList = None
479 self.heightList = None
480 self.channelList = None
480 self.channelList = None
481 # self.channelIndexList = None
481 # self.channelIndexList = None
482 self.pairsList = None
482 self.pairsList = None
483 self.flagNoData = True
483 self.flagNoData = True
484 self.flagDiscontinuousBlock = False
484 self.flagDiscontinuousBlock = False
485 self.utctime = None
485 self.utctime = None
486 self.nCohInt = None
486 self.nCohInt = None
487 self.nIncohInt = None
487 self.nIncohInt = None
488 self.blocksize = None
488 self.blocksize = None
489 self.nFFTPoints = None
489 self.nFFTPoints = None
490 self.wavelength = None
490 self.wavelength = None
491 self.flagDecodeData = False # asumo q la data no esta decodificada
491 self.flagDecodeData = False # asumo q la data no esta decodificada
492 self.flagDeflipData = False # asumo q la data no esta sin flip
492 self.flagDeflipData = False # asumo q la data no esta sin flip
493 self.flagShiftFFT = False
493 self.flagShiftFFT = False
494 self.ippFactor = 1
494 self.ippFactor = 1
495 #self.noise = None
495 #self.noise = None
496 self.beacon_heiIndexList = []
496 self.beacon_heiIndexList = []
497 self.noise_estimation = None
497 self.noise_estimation = None
498
498
499 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
499 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
500 """
500 """
501 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
501 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
502
502
503 Return:
503 Return:
504 noiselevel
504 noiselevel
505 """
505 """
506
506
507 noise = numpy.zeros(self.nChannels)
507 noise = numpy.zeros(self.nChannels)
508
508
509 for channel in range(self.nChannels):
509 for channel in range(self.nChannels):
510 daux = self.data_spc[channel,
510 daux = self.data_spc[channel,
511 xmin_index:xmax_index, ymin_index:ymax_index]
511 xmin_index:xmax_index, ymin_index:ymax_index]
512 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
512 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
513
513
514 return noise
514 return noise
515
515
516 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
516 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
517
517
518 if self.noise_estimation is not None:
518 if self.noise_estimation is not None:
519 # this was estimated by getNoise Operation defined in jroproc_spectra.py
519 # this was estimated by getNoise Operation defined in jroproc_spectra.py
520 return self.noise_estimation
520 return self.noise_estimation
521 else:
521 else:
522 noise = self.getNoisebyHildebrand(
522 noise = self.getNoisebyHildebrand(
523 xmin_index, xmax_index, ymin_index, ymax_index)
523 xmin_index, xmax_index, ymin_index, ymax_index)
524 return noise
524 return noise
525
525
526 def getFreqRangeTimeResponse(self, extrapoints=0):
526 def getFreqRangeTimeResponse(self, extrapoints=0):
527
527
528 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
528 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
529 freqrange = deltafreq * \
529 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
530 (numpy.arange(self.nFFTPoints + extrapoints) -
531 self.nFFTPoints / 2.) - deltafreq / 2
532
530
533 return freqrange
531 return freqrange
534
532
535 def getAcfRange(self, extrapoints=0):
533 def getAcfRange(self, extrapoints=0):
536
534
537 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
535 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
538 freqrange = deltafreq * \
536 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
539 (numpy.arange(self.nFFTPoints + extrapoints) -
540 self.nFFTPoints / 2.) - deltafreq / 2
541
537
542 return freqrange
538 return freqrange
543
539
544 def getFreqRange(self, extrapoints=0):
540 def getFreqRange(self, extrapoints=0):
545
541
546 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
542 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
547 freqrange = deltafreq * \
543 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
548 (numpy.arange(self.nFFTPoints + extrapoints) -
549 self.nFFTPoints / 2.) - deltafreq / 2
550
544
551 return freqrange
545 return freqrange
552
546
553 def getVelRange(self, extrapoints=0):
547 def getVelRange(self, extrapoints=0):
554
548
555 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
549 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
556 velrange = deltav * (numpy.arange(self.nFFTPoints +
550 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
557 extrapoints) - self.nFFTPoints / 2.)
551
558
559 if self.nmodes:
552 if self.nmodes:
560 return velrange/self.nmodes
553 return velrange/self.nmodes
561 else:
554 else:
562 return velrange
555 return velrange
563
556
564 def getNPairs(self):
557 def getNPairs(self):
565
558
566 return len(self.pairsList)
559 return len(self.pairsList)
567
560
568 def getPairsIndexList(self):
561 def getPairsIndexList(self):
569
562
570 return list(range(self.nPairs))
563 return list(range(self.nPairs))
571
564
572 def getNormFactor(self):
565 def getNormFactor(self):
573
566
574 pwcode = 1
567 pwcode = 1
575
568
576 if self.flagDecodeData:
569 if self.flagDecodeData:
577 pwcode = numpy.sum(self.code[0]**2)
570 pwcode = numpy.sum(self.code[0]**2)
578 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
571 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
579 normFactor = self.nProfiles * self.nIncohInt * \
572 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
580 self.nCohInt * pwcode * self.windowOfFilter
581
573
582 return normFactor
574 return normFactor
583
575
584 def getFlagCspc(self):
576 def getFlagCspc(self):
585
577
586 if self.data_cspc is None:
578 if self.data_cspc is None:
587 return True
579 return True
588
580
589 return False
581 return False
590
582
591 def getFlagDc(self):
583 def getFlagDc(self):
592
584
593 if self.data_dc is None:
585 if self.data_dc is None:
594 return True
586 return True
595
587
596 return False
588 return False
597
589
598 def getTimeInterval(self):
590 def getTimeInterval(self):
599
591
600 timeInterval = self.ippSeconds * self.nCohInt * \
592 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
601 self.nIncohInt * self.nProfiles * self.ippFactor
602
593
603 return timeInterval
594 return timeInterval
604
595
605 def getPower(self):
596 def getPower(self):
606
597
607 factor = self.normFactor
598 factor = self.normFactor
608 z = self.data_spc / factor
599 z = self.data_spc / factor
609 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
600 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
610 avg = numpy.average(z, axis=1)
601 avg = numpy.average(z, axis=1)
611
602
612 return 10 * numpy.log10(avg)
603 return 10 * numpy.log10(avg)
613
604
614 def getCoherence(self, pairsList=None, phase=False):
605 def getCoherence(self, pairsList=None, phase=False):
615
606
616 z = []
607 z = []
617 if pairsList is None:
608 if pairsList is None:
618 pairsIndexList = self.pairsIndexList
609 pairsIndexList = self.pairsIndexList
619 else:
610 else:
620 pairsIndexList = []
611 pairsIndexList = []
621 for pair in pairsList:
612 for pair in pairsList:
622 if pair not in self.pairsList:
613 if pair not in self.pairsList:
623 raise ValueError("Pair %s is not in dataOut.pairsList" % (
614 raise ValueError("Pair %s is not in dataOut.pairsList" % (
624 pair))
615 pair))
625 pairsIndexList.append(self.pairsList.index(pair))
616 pairsIndexList.append(self.pairsList.index(pair))
626 for i in range(len(pairsIndexList)):
617 for i in range(len(pairsIndexList)):
627 pair = self.pairsList[pairsIndexList[i]]
618 pair = self.pairsList[pairsIndexList[i]]
628 ccf = numpy.average(
619 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
629 self.data_cspc[pairsIndexList[i], :, :], axis=0)
630 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
620 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
631 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
621 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
632 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
622 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
633 if phase:
623 if phase:
634 data = numpy.arctan2(avgcoherenceComplex.imag,
624 data = numpy.arctan2(avgcoherenceComplex.imag,
635 avgcoherenceComplex.real) * 180 / numpy.pi
625 avgcoherenceComplex.real) * 180 / numpy.pi
636 else:
626 else:
637 data = numpy.abs(avgcoherenceComplex)
627 data = numpy.abs(avgcoherenceComplex)
638
628
639 z.append(data)
629 z.append(data)
640
630
641 return numpy.array(z)
631 return numpy.array(z)
642
632
643 def setValue(self, value):
633 def setValue(self, value):
644
634
645 print("This property should not be initialized")
635 print("This property should not be initialized")
646
636
647 return
637 return
648
638
649 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
639 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
650 pairsIndexList = property(
640 pairsIndexList = property(
651 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
641 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
652 normFactor = property(getNormFactor, setValue,
642 normFactor = property(getNormFactor, setValue,
653 "I'm the 'getNormFactor' property.")
643 "I'm the 'getNormFactor' property.")
654 flag_cspc = property(getFlagCspc, setValue)
644 flag_cspc = property(getFlagCspc, setValue)
655 flag_dc = property(getFlagDc, setValue)
645 flag_dc = property(getFlagDc, setValue)
656 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
646 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
657 timeInterval = property(getTimeInterval, setValue,
647 timeInterval = property(getTimeInterval, setValue,
658 "I'm the 'timeInterval' property")
648 "I'm the 'timeInterval' property")
659
649
660
650
661 class SpectraHeis(Spectra):
651 class SpectraHeis(Spectra):
662
652
663 data_spc = None
653 data_spc = None
664 data_cspc = None
654 data_cspc = None
665 data_dc = None
655 data_dc = None
666 nFFTPoints = None
656 nFFTPoints = None
667 # nPairs = None
657 # nPairs = None
668 pairsList = None
658 pairsList = None
669 nCohInt = None
659 nCohInt = None
670 nIncohInt = None
660 nIncohInt = None
671
661
672 def __init__(self):
662 def __init__(self):
673
663
674 self.radarControllerHeaderObj = RadarControllerHeader()
664 self.radarControllerHeaderObj = RadarControllerHeader()
675
665
676 self.systemHeaderObj = SystemHeader()
666 self.systemHeaderObj = SystemHeader()
677
667
678 self.type = "SpectraHeis"
668 self.type = "SpectraHeis"
679
669
680 # self.dtype = None
670 # self.dtype = None
681
671
682 # self.nChannels = 0
672 # self.nChannels = 0
683
673
684 # self.nHeights = 0
674 # self.nHeights = 0
685
675
686 self.nProfiles = None
676 self.nProfiles = None
687
677
688 self.heightList = None
678 self.heightList = None
689
679
690 self.channelList = None
680 self.channelList = None
691
681
692 # self.channelIndexList = None
682 # self.channelIndexList = None
693
683
694 self.flagNoData = True
684 self.flagNoData = True
695
685
696 self.flagDiscontinuousBlock = False
686 self.flagDiscontinuousBlock = False
697
687
698 # self.nPairs = 0
688 # self.nPairs = 0
699
689
700 self.utctime = None
690 self.utctime = None
701
691
702 self.blocksize = None
692 self.blocksize = None
703
693
704 self.profileIndex = 0
694 self.profileIndex = 0
705
695
706 self.nCohInt = 1
696 self.nCohInt = 1
707
697
708 self.nIncohInt = 1
698 self.nIncohInt = 1
709
699
710 def getNormFactor(self):
700 def getNormFactor(self):
711 pwcode = 1
701 pwcode = 1
712 if self.flagDecodeData:
702 if self.flagDecodeData:
713 pwcode = numpy.sum(self.code[0]**2)
703 pwcode = numpy.sum(self.code[0]**2)
714
704
715 normFactor = self.nIncohInt * self.nCohInt * pwcode
705 normFactor = self.nIncohInt * self.nCohInt * pwcode
716
706
717 return normFactor
707 return normFactor
718
708
719 def getTimeInterval(self):
709 def getTimeInterval(self):
720
710
721 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
711 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
722
712
723 return timeInterval
713 return timeInterval
724
714
725 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
715 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
726 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
716 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
727
717
728
718
729 class Fits(JROData):
719 class Fits(JROData):
730
720
731 heightList = None
721 heightList = None
732 channelList = None
722 channelList = None
733 flagNoData = True
723 flagNoData = True
734 flagDiscontinuousBlock = False
724 flagDiscontinuousBlock = False
735 useLocalTime = False
725 useLocalTime = False
736 utctime = None
726 utctime = None
737 timeZone = None
727 timeZone = None
738 # ippSeconds = None
728 # ippSeconds = None
739 # timeInterval = None
729 # timeInterval = None
740 nCohInt = None
730 nCohInt = None
741 nIncohInt = None
731 nIncohInt = None
742 noise = None
732 noise = None
743 windowOfFilter = 1
733 windowOfFilter = 1
744 # Speed of ligth
734 # Speed of ligth
745 C = 3e8
735 C = 3e8
746 frequency = 49.92e6
736 frequency = 49.92e6
747 realtime = False
737 realtime = False
748
738
749 def __init__(self):
739 def __init__(self):
750
740
751 self.type = "Fits"
741 self.type = "Fits"
752
742
753 self.nProfiles = None
743 self.nProfiles = None
754
744
755 self.heightList = None
745 self.heightList = None
756
746
757 self.channelList = None
747 self.channelList = None
758
748
759 # self.channelIndexList = None
749 # self.channelIndexList = None
760
750
761 self.flagNoData = True
751 self.flagNoData = True
762
752
763 self.utctime = None
753 self.utctime = None
764
754
765 self.nCohInt = 1
755 self.nCohInt = 1
766
756
767 self.nIncohInt = 1
757 self.nIncohInt = 1
768
758
769 self.useLocalTime = True
759 self.useLocalTime = True
770
760
771 self.profileIndex = 0
761 self.profileIndex = 0
772
762
773 # self.utctime = None
763 # self.utctime = None
774 # self.timeZone = None
764 # self.timeZone = None
775 # self.ltctime = None
765 # self.ltctime = None
776 # self.timeInterval = None
766 # self.timeInterval = None
777 # self.header = None
767 # self.header = None
778 # self.data_header = None
768 # self.data_header = None
779 # self.data = None
769 # self.data = None
780 # self.datatime = None
770 # self.datatime = None
781 # self.flagNoData = False
771 # self.flagNoData = False
782 # self.expName = ''
772 # self.expName = ''
783 # self.nChannels = None
773 # self.nChannels = None
784 # self.nSamples = None
774 # self.nSamples = None
785 # self.dataBlocksPerFile = None
775 # self.dataBlocksPerFile = None
786 # self.comments = ''
776 # self.comments = ''
787 #
777 #
788
778
789 def getltctime(self):
779 def getltctime(self):
790
780
791 if self.useLocalTime:
781 if self.useLocalTime:
792 return self.utctime - self.timeZone * 60
782 return self.utctime - self.timeZone * 60
793
783
794 return self.utctime
784 return self.utctime
795
785
796 def getDatatime(self):
786 def getDatatime(self):
797
787
798 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
788 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
799 return datatime
789 return datatime
800
790
801 def getTimeRange(self):
791 def getTimeRange(self):
802
792
803 datatime = []
793 datatime = []
804
794
805 datatime.append(self.ltctime)
795 datatime.append(self.ltctime)
806 datatime.append(self.ltctime + self.timeInterval)
796 datatime.append(self.ltctime + self.timeInterval)
807
797
808 datatime = numpy.array(datatime)
798 datatime = numpy.array(datatime)
809
799
810 return datatime
800 return datatime
811
801
812 def getHeiRange(self):
802 def getHeiRange(self):
813
803
814 heis = self.heightList
804 heis = self.heightList
815
805
816 return heis
806 return heis
817
807
818 def getNHeights(self):
808 def getNHeights(self):
819
809
820 return len(self.heightList)
810 return len(self.heightList)
821
811
822 def getNChannels(self):
812 def getNChannels(self):
823
813
824 return len(self.channelList)
814 return len(self.channelList)
825
815
826 def getChannelIndexList(self):
816 def getChannelIndexList(self):
827
817
828 return list(range(self.nChannels))
818 return list(range(self.nChannels))
829
819
830 def getNoise(self, type=1):
820 def getNoise(self, type=1):
831
821
832 #noise = numpy.zeros(self.nChannels)
822 #noise = numpy.zeros(self.nChannels)
833
823
834 if type == 1:
824 if type == 1:
835 noise = self.getNoisebyHildebrand()
825 noise = self.getNoisebyHildebrand()
836
826
837 if type == 2:
827 if type == 2:
838 noise = self.getNoisebySort()
828 noise = self.getNoisebySort()
839
829
840 if type == 3:
830 if type == 3:
841 noise = self.getNoisebyWindow()
831 noise = self.getNoisebyWindow()
842
832
843 return noise
833 return noise
844
834
845 def getTimeInterval(self):
835 def getTimeInterval(self):
846
836
847 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
837 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
848
838
849 return timeInterval
839 return timeInterval
850
840
851 def get_ippSeconds(self):
841 def get_ippSeconds(self):
852 '''
842 '''
853 '''
843 '''
854 return self.ipp_sec
844 return self.ipp_sec
855
845
856
846
857 datatime = property(getDatatime, "I'm the 'datatime' property")
847 datatime = property(getDatatime, "I'm the 'datatime' property")
858 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
848 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
859 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
849 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
860 channelIndexList = property(
850 channelIndexList = property(
861 getChannelIndexList, "I'm the 'channelIndexList' property.")
851 getChannelIndexList, "I'm the 'channelIndexList' property.")
862 noise = property(getNoise, "I'm the 'nHeights' property.")
852 noise = property(getNoise, "I'm the 'nHeights' property.")
863
853
864 ltctime = property(getltctime, "I'm the 'ltctime' property")
854 ltctime = property(getltctime, "I'm the 'ltctime' property")
865 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
855 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
866 ippSeconds = property(get_ippSeconds, '')
856 ippSeconds = property(get_ippSeconds, '')
867
857
868 class Correlation(JROData):
858 class Correlation(JROData):
869
859
870 noise = None
860 noise = None
871 SNR = None
861 SNR = None
872 #--------------------------------------------------
862 #--------------------------------------------------
873 mode = None
863 mode = None
874 split = False
864 split = False
875 data_cf = None
865 data_cf = None
876 lags = None
866 lags = None
877 lagRange = None
867 lagRange = None
878 pairsList = None
868 pairsList = None
879 normFactor = None
869 normFactor = None
880 #--------------------------------------------------
870 #--------------------------------------------------
881 # calculateVelocity = None
871 # calculateVelocity = None
882 nLags = None
872 nLags = None
883 nPairs = None
873 nPairs = None
884 nAvg = None
874 nAvg = None
885
875
886 def __init__(self):
876 def __init__(self):
887 '''
877 '''
888 Constructor
878 Constructor
889 '''
879 '''
890 self.radarControllerHeaderObj = RadarControllerHeader()
880 self.radarControllerHeaderObj = RadarControllerHeader()
891
881
892 self.systemHeaderObj = SystemHeader()
882 self.systemHeaderObj = SystemHeader()
893
883
894 self.type = "Correlation"
884 self.type = "Correlation"
895
885
896 self.data = None
886 self.data = None
897
887
898 self.dtype = None
888 self.dtype = None
899
889
900 self.nProfiles = None
890 self.nProfiles = None
901
891
902 self.heightList = None
892 self.heightList = None
903
893
904 self.channelList = None
894 self.channelList = None
905
895
906 self.flagNoData = True
896 self.flagNoData = True
907
897
908 self.flagDiscontinuousBlock = False
898 self.flagDiscontinuousBlock = False
909
899
910 self.utctime = None
900 self.utctime = None
911
901
912 self.timeZone = None
902 self.timeZone = None
913
903
914 self.dstFlag = None
904 self.dstFlag = None
915
905
916 self.errorCount = None
906 self.errorCount = None
917
907
918 self.blocksize = None
908 self.blocksize = None
919
909
920 self.flagDecodeData = False # asumo q la data no esta decodificada
910 self.flagDecodeData = False # asumo q la data no esta decodificada
921
911
922 self.flagDeflipData = False # asumo q la data no esta sin flip
912 self.flagDeflipData = False # asumo q la data no esta sin flip
923
913
924 self.pairsList = None
914 self.pairsList = None
925
915
926 self.nPoints = None
916 self.nPoints = None
927
917
928 def getPairsList(self):
918 def getPairsList(self):
929
919
930 return self.pairsList
920 return self.pairsList
931
921
932 def getNoise(self, mode=2):
922 def getNoise(self, mode=2):
933
923
934 indR = numpy.where(self.lagR == 0)[0][0]
924 indR = numpy.where(self.lagR == 0)[0][0]
935 indT = numpy.where(self.lagT == 0)[0][0]
925 indT = numpy.where(self.lagT == 0)[0][0]
936
926
937 jspectra0 = self.data_corr[:, :, indR, :]
927 jspectra0 = self.data_corr[:, :, indR, :]
938 jspectra = copy.copy(jspectra0)
928 jspectra = copy.copy(jspectra0)
939
929
940 num_chan = jspectra.shape[0]
930 num_chan = jspectra.shape[0]
941 num_hei = jspectra.shape[2]
931 num_hei = jspectra.shape[2]
942
932
943 freq_dc = jspectra.shape[1] / 2
933 freq_dc = jspectra.shape[1] / 2
944 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
934 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
945
935
946 if ind_vel[0] < 0:
936 if ind_vel[0] < 0:
947 ind_vel[list(range(0, 1))] = ind_vel[list(
937 ind_vel[list(range(0, 1))] = ind_vel[list(
948 range(0, 1))] + self.num_prof
938 range(0, 1))] + self.num_prof
949
939
950 if mode == 1:
940 if mode == 1:
951 jspectra[:, freq_dc, :] = (
941 jspectra[:, freq_dc, :] = (
952 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
942 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
953
943
954 if mode == 2:
944 if mode == 2:
955
945
956 vel = numpy.array([-2, -1, 1, 2])
946 vel = numpy.array([-2, -1, 1, 2])
957 xx = numpy.zeros([4, 4])
947 xx = numpy.zeros([4, 4])
958
948
959 for fil in range(4):
949 for fil in range(4):
960 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
950 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
961
951
962 xx_inv = numpy.linalg.inv(xx)
952 xx_inv = numpy.linalg.inv(xx)
963 xx_aux = xx_inv[0, :]
953 xx_aux = xx_inv[0, :]
964
954
965 for ich in range(num_chan):
955 for ich in range(num_chan):
966 yy = jspectra[ich, ind_vel, :]
956 yy = jspectra[ich, ind_vel, :]
967 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
957 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
968
958
969 junkid = jspectra[ich, freq_dc, :] <= 0
959 junkid = jspectra[ich, freq_dc, :] <= 0
970 cjunkid = sum(junkid)
960 cjunkid = sum(junkid)
971
961
972 if cjunkid.any():
962 if cjunkid.any():
973 jspectra[ich, freq_dc, junkid.nonzero()] = (
963 jspectra[ich, freq_dc, junkid.nonzero()] = (
974 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
964 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
975
965
976 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
966 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
977
967
978 return noise
968 return noise
979
969
980 def getTimeInterval(self):
970 def getTimeInterval(self):
981
971
982 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
972 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
983
973
984 return timeInterval
974 return timeInterval
985
975
986 def splitFunctions(self):
976 def splitFunctions(self):
987
977
988 pairsList = self.pairsList
978 pairsList = self.pairsList
989 ccf_pairs = []
979 ccf_pairs = []
990 acf_pairs = []
980 acf_pairs = []
991 ccf_ind = []
981 ccf_ind = []
992 acf_ind = []
982 acf_ind = []
993 for l in range(len(pairsList)):
983 for l in range(len(pairsList)):
994 chan0 = pairsList[l][0]
984 chan0 = pairsList[l][0]
995 chan1 = pairsList[l][1]
985 chan1 = pairsList[l][1]
996
986
997 # Obteniendo pares de Autocorrelacion
987 # Obteniendo pares de Autocorrelacion
998 if chan0 == chan1:
988 if chan0 == chan1:
999 acf_pairs.append(chan0)
989 acf_pairs.append(chan0)
1000 acf_ind.append(l)
990 acf_ind.append(l)
1001 else:
991 else:
1002 ccf_pairs.append(pairsList[l])
992 ccf_pairs.append(pairsList[l])
1003 ccf_ind.append(l)
993 ccf_ind.append(l)
1004
994
1005 data_acf = self.data_cf[acf_ind]
995 data_acf = self.data_cf[acf_ind]
1006 data_ccf = self.data_cf[ccf_ind]
996 data_ccf = self.data_cf[ccf_ind]
1007
997
1008 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
998 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1009
999
1010 def getNormFactor(self):
1000 def getNormFactor(self):
1011 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1001 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1012 acf_pairs = numpy.array(acf_pairs)
1002 acf_pairs = numpy.array(acf_pairs)
1013 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1003 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1014
1004
1015 for p in range(self.nPairs):
1005 for p in range(self.nPairs):
1016 pair = self.pairsList[p]
1006 pair = self.pairsList[p]
1017
1007
1018 ch0 = pair[0]
1008 ch0 = pair[0]
1019 ch1 = pair[1]
1009 ch1 = pair[1]
1020
1010
1021 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1011 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1022 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1012 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1023 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1013 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1024
1014
1025 return normFactor
1015 return normFactor
1026
1016
1027 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1017 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1028 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1018 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1029
1019
1030
1020
1031 class Parameters(Spectra):
1021 class Parameters(Spectra):
1032
1022
1033 experimentInfo = None # Information about the experiment
1023 experimentInfo = None # Information about the experiment
1034 # Information from previous data
1024 # Information from previous data
1035 inputUnit = None # Type of data to be processed
1025 inputUnit = None # Type of data to be processed
1036 operation = None # Type of operation to parametrize
1026 operation = None # Type of operation to parametrize
1037 # normFactor = None #Normalization Factor
1027 # normFactor = None #Normalization Factor
1038 groupList = None # List of Pairs, Groups, etc
1028 groupList = None # List of Pairs, Groups, etc
1039 # Parameters
1029 # Parameters
1040 data_param = None # Parameters obtained
1030 data_param = None # Parameters obtained
1041 data_pre = None # Data Pre Parametrization
1031 data_pre = None # Data Pre Parametrization
1042 data_SNR = None # Signal to Noise Ratio
1032 data_SNR = None # Signal to Noise Ratio
1043 # heightRange = None #Heights
1033 # heightRange = None #Heights
1044 abscissaList = None # Abscissa, can be velocities, lags or time
1034 abscissaList = None # Abscissa, can be velocities, lags or time
1045 # noise = None #Noise Potency
1035 # noise = None #Noise Potency
1046 utctimeInit = None # Initial UTC time
1036 utctimeInit = None # Initial UTC time
1047 paramInterval = None # Time interval to calculate Parameters in seconds
1037 paramInterval = None # Time interval to calculate Parameters in seconds
1048 useLocalTime = True
1038 useLocalTime = True
1049 # Fitting
1039 # Fitting
1050 data_error = None # Error of the estimation
1040 data_error = None # Error of the estimation
1051 constants = None
1041 constants = None
1052 library = None
1042 library = None
1053 # Output signal
1043 # Output signal
1054 outputInterval = None # Time interval to calculate output signal in seconds
1044 outputInterval = None # Time interval to calculate output signal in seconds
1055 data_output = None # Out signal
1045 data_output = None # Out signal
1056 nAvg = None
1046 nAvg = None
1057 noise_estimation = None
1047 noise_estimation = None
1058 GauSPC = None # Fit gaussian SPC
1048 GauSPC = None # Fit gaussian SPC
1059
1049
1060 def __init__(self):
1050 def __init__(self):
1061 '''
1051 '''
1062 Constructor
1052 Constructor
1063 '''
1053 '''
1064 self.radarControllerHeaderObj = RadarControllerHeader()
1054 self.radarControllerHeaderObj = RadarControllerHeader()
1065
1055
1066 self.systemHeaderObj = SystemHeader()
1056 self.systemHeaderObj = SystemHeader()
1067
1057
1068 self.type = "Parameters"
1058 self.type = "Parameters"
1069
1059
1070 def getTimeRange1(self, interval):
1060 def getTimeRange1(self, interval):
1071
1061
1072 datatime = []
1062 datatime = []
1073
1063
1074 if self.useLocalTime:
1064 if self.useLocalTime:
1075 time1 = self.utctimeInit - self.timeZone * 60
1065 time1 = self.utctimeInit - self.timeZone * 60
1076 else:
1066 else:
1077 time1 = self.utctimeInit
1067 time1 = self.utctimeInit
1078
1068
1079 datatime.append(time1)
1069 datatime.append(time1)
1080 datatime.append(time1 + interval)
1070 datatime.append(time1 + interval)
1081 datatime = numpy.array(datatime)
1071 datatime = numpy.array(datatime)
1082
1072
1083 return datatime
1073 return datatime
1084
1074
1085 def getTimeInterval(self):
1075 def getTimeInterval(self):
1086
1076
1087 if hasattr(self, 'timeInterval1'):
1077 if hasattr(self, 'timeInterval1'):
1088 return self.timeInterval1
1078 return self.timeInterval1
1089 else:
1079 else:
1090 return self.paramInterval
1080 return self.paramInterval
1091
1081
1092 def setValue(self, value):
1082 def setValue(self, value):
1093
1083
1094 print("This property should not be initialized")
1084 print("This property should not be initialized")
1095
1085
1096 return
1086 return
1097
1087
1098 def getNoise(self):
1088 def getNoise(self):
1099
1089
1100 return self.spc_noise
1090 return self.spc_noise
1101
1091
1102 timeInterval = property(getTimeInterval)
1092 timeInterval = property(getTimeInterval)
1103 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1093 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1104
1094
1105
1095
1106 class PlotterData(object):
1096 class PlotterData(object):
1107 '''
1097 '''
1108 Object to hold data to be plotted
1098 Object to hold data to be plotted
1109 '''
1099 '''
1110
1100
1111 MAXNUMX = 100
1101 MAXNUMX = 100
1112 MAXNUMY = 100
1102 MAXNUMY = 100
1113
1103
1114 def __init__(self, code, throttle_value, exp_code, buffering=True):
1104 def __init__(self, code, throttle_value, exp_code, buffering=True):
1115
1105
1116 self.throttle = throttle_value
1106 self.throttle = throttle_value
1117 self.exp_code = exp_code
1107 self.exp_code = exp_code
1118 self.buffering = buffering
1108 self.buffering = buffering
1119 self.ready = False
1109 self.ready = False
1120 self.localtime = False
1110 self.localtime = False
1121 self.data = {}
1111 self.data = {}
1122 self.meta = {}
1112 self.meta = {}
1123 self.__times = []
1113 self.__times = []
1124 self.__heights = []
1114 self.__heights = []
1125
1115
1126 if 'snr' in code:
1116 if 'snr' in code:
1127 self.plottypes = ['snr']
1117 self.plottypes = ['snr']
1128 elif code == 'spc':
1118 elif code == 'spc':
1129 self.plottypes = ['spc', 'noise', 'rti']
1119 self.plottypes = ['spc', 'noise', 'rti']
1130 elif code == 'rti':
1120 elif code == 'rti':
1131 self.plottypes = ['noise', 'rti']
1121 self.plottypes = ['noise', 'rti']
1132 else:
1122 else:
1133 self.plottypes = [code]
1123 self.plottypes = [code]
1134
1124
1135 for plot in self.plottypes:
1125 for plot in self.plottypes:
1136 self.data[plot] = {}
1126 self.data[plot] = {}
1137
1127
1138 def __str__(self):
1128 def __str__(self):
1139 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1129 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1140 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
1130 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
1141
1131
1142 def __len__(self):
1132 def __len__(self):
1143 return len(self.__times)
1133 return len(self.__times)
1144
1134
1145 def __getitem__(self, key):
1135 def __getitem__(self, key):
1146
1136
1147 if key not in self.data:
1137 if key not in self.data:
1148 raise KeyError(log.error('Missing key: {}'.format(key)))
1138 raise KeyError(log.error('Missing key: {}'.format(key)))
1149 if 'spc' in key or not self.buffering:
1139 if 'spc' in key or not self.buffering:
1150 ret = self.data[key]
1140 ret = self.data[key]
1151 elif 'scope' in key:
1141 elif 'scope' in key:
1152 ret = numpy.array(self.data[key][float(self.tm)])
1142 ret = numpy.array(self.data[key][float(self.tm)])
1153 else:
1143 else:
1154 ret = numpy.array([self.data[key][x] for x in self.times])
1144 ret = numpy.array([self.data[key][x] for x in self.times])
1155 if ret.ndim > 1:
1145 if ret.ndim > 1:
1156 ret = numpy.swapaxes(ret, 0, 1)
1146 ret = numpy.swapaxes(ret, 0, 1)
1157 return ret
1147 return ret
1158
1148
1159 def __contains__(self, key):
1149 def __contains__(self, key):
1160 return key in self.data
1150 return key in self.data
1161
1151
1162 def setup(self):
1152 def setup(self):
1163 '''
1153 '''
1164 Configure object
1154 Configure object
1165 '''
1155 '''
1166
1156
1167 self.type = ''
1157 self.type = ''
1168 self.ready = False
1158 self.ready = False
1169 self.data = {}
1159 self.data = {}
1170 self.__times = []
1160 self.__times = []
1171 self.__heights = []
1161 self.__heights = []
1172 self.__all_heights = set()
1162 self.__all_heights = set()
1173 for plot in self.plottypes:
1163 for plot in self.plottypes:
1174 if 'snr' in plot:
1164 if 'snr' in plot:
1175 plot = 'snr'
1165 plot = 'snr'
1176 self.data[plot] = {}
1166 self.data[plot] = {}
1177
1167
1178 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data:
1168 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data:
1179 self.data['noise'] = {}
1169 self.data['noise'] = {}
1180 if 'noise' not in self.plottypes:
1170 if 'noise' not in self.plottypes:
1181 self.plottypes.append('noise')
1171 self.plottypes.append('noise')
1182
1172
1183 def shape(self, key):
1173 def shape(self, key):
1184 '''
1174 '''
1185 Get the shape of the one-element data for the given key
1175 Get the shape of the one-element data for the given key
1186 '''
1176 '''
1187
1177
1188 if len(self.data[key]):
1178 if len(self.data[key]):
1189 if 'spc' in key or not self.buffering:
1179 if 'spc' in key or not self.buffering:
1190 return self.data[key].shape
1180 return self.data[key].shape
1191 return self.data[key][self.__times[0]].shape
1181 return self.data[key][self.__times[0]].shape
1192 return (0,)
1182 return (0,)
1193
1183
1194 def update(self, dataOut, tm):
1184 def update(self, dataOut, tm):
1195 '''
1185 '''
1196 Update data object with new dataOut
1186 Update data object with new dataOut
1197 '''
1187 '''
1198
1188
1199 if tm in self.__times:
1189 if tm in self.__times:
1200 return
1190 return
1201 self.profileIndex = dataOut.profileIndex
1191 self.profileIndex = dataOut.profileIndex
1202 self.tm = tm
1192 self.tm = tm
1203 self.type = dataOut.type
1193 self.type = dataOut.type
1204 self.parameters = getattr(dataOut, 'parameters', [])
1194 self.parameters = getattr(dataOut, 'parameters', [])
1205 if hasattr(dataOut, 'pairsList'):
1195 if hasattr(dataOut, 'pairsList'):
1206 self.pairs = dataOut.pairsList
1196 self.pairs = dataOut.pairsList
1207 if hasattr(dataOut, 'meta'):
1197 if hasattr(dataOut, 'meta'):
1208 self.meta = dataOut.meta
1198 self.meta = dataOut.meta
1209 self.channels = dataOut.channelList
1199 self.channels = dataOut.channelList
1210 self.interval = dataOut.getTimeInterval()
1200 self.interval = dataOut.getTimeInterval()
1211 self.localtime = dataOut.useLocalTime
1201 self.localtime = dataOut.useLocalTime
1212 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
1202 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
1213 self.xrange = (dataOut.getFreqRange(1)/1000.,
1203 self.xrange = (dataOut.getFreqRange(1)/1000.,
1214 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1204 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1215 self.factor = dataOut.normFactor
1205 self.factor = dataOut.normFactor
1216 self.__heights.append(dataOut.heightList)
1206 self.__heights.append(dataOut.heightList)
1217 self.__all_heights.update(dataOut.heightList)
1207 self.__all_heights.update(dataOut.heightList)
1218 self.__times.append(tm)
1208 self.__times.append(tm)
1219
1209
1220 for plot in self.plottypes:
1210 for plot in self.plottypes:
1221 if plot == 'spc':
1211 if plot == 'spc':
1222 z = dataOut.data_spc/dataOut.normFactor
1212 z = dataOut.data_spc/dataOut.normFactor
1223 buffer = 10*numpy.log10(z)
1213 buffer = 10*numpy.log10(z)
1224 if plot == 'cspc':
1214 if plot == 'cspc':
1225 z = dataOut.data_spc/dataOut.normFactor
1215 z = dataOut.data_spc/dataOut.normFactor
1226 buffer = (dataOut.data_spc, dataOut.data_cspc)
1216 buffer = (dataOut.data_spc, dataOut.data_cspc)
1227 if plot == 'noise':
1217 if plot == 'noise':
1228 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1218 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1229 if plot == 'rti':
1219 if plot == 'rti':
1230 buffer = dataOut.getPower()
1220 buffer = dataOut.getPower()
1231 if plot == 'snr_db':
1221 if plot == 'snr_db':
1232 buffer = dataOut.data_SNR
1222 buffer = dataOut.data_SNR
1233 if plot == 'snr':
1223 if plot == 'snr':
1234 buffer = 10*numpy.log10(dataOut.data_SNR)
1224 buffer = 10*numpy.log10(dataOut.data_SNR)
1235 if plot == 'dop':
1225 if plot == 'dop':
1236 buffer = 10*numpy.log10(dataOut.data_DOP)
1226 buffer = 10*numpy.log10(dataOut.data_DOP)
1237 if plot == 'mean':
1227 if plot == 'mean':
1238 buffer = dataOut.data_MEAN
1228 buffer = dataOut.data_MEAN
1239 if plot == 'std':
1229 if plot == 'std':
1240 buffer = dataOut.data_STD
1230 buffer = dataOut.data_STD
1241 if plot == 'coh':
1231 if plot == 'coh':
1242 buffer = dataOut.getCoherence()
1232 buffer = dataOut.getCoherence()
1243 if plot == 'phase':
1233 if plot == 'phase':
1244 buffer = dataOut.getCoherence(phase=True)
1234 buffer = dataOut.getCoherence(phase=True)
1245 if plot == 'output':
1235 if plot == 'output':
1246 buffer = dataOut.data_output
1236 buffer = dataOut.data_output
1247 if plot == 'param':
1237 if plot == 'param':
1248 buffer = dataOut.data_param
1238 buffer = dataOut.data_param
1249 if plot == 'scope':
1239 if plot == 'scope':
1250 buffer = dataOut.data
1240 buffer = dataOut.data
1251 self.flagDataAsBlock = dataOut.flagDataAsBlock
1241 self.flagDataAsBlock = dataOut.flagDataAsBlock
1252 self.nProfiles = dataOut.nProfiles
1242 self.nProfiles = dataOut.nProfiles
1253
1243
1254 if plot == 'spc':
1244 if plot == 'spc':
1255 self.data[plot] = buffer
1245 self.data[plot] = buffer
1256 elif plot == 'cspc':
1246 elif plot == 'cspc':
1257 self.data['spc'] = buffer[0]
1247 self.data['spc'] = buffer[0]
1258 self.data['cspc'] = buffer[1]
1248 self.data['cspc'] = buffer[1]
1259 else:
1249 else:
1260 if self.buffering:
1250 if self.buffering:
1261 self.data[plot][tm] = buffer
1251 self.data[plot][tm] = buffer
1262 else:
1252 else:
1263 self.data[plot] = buffer
1253 self.data[plot] = buffer
1264
1254
1265 def normalize_heights(self):
1255 def normalize_heights(self):
1266 '''
1256 '''
1267 Ensure same-dimension of the data for different heighList
1257 Ensure same-dimension of the data for different heighList
1268 '''
1258 '''
1269
1259
1270 H = numpy.array(list(self.__all_heights))
1260 H = numpy.array(list(self.__all_heights))
1271 H.sort()
1261 H.sort()
1272 for key in self.data:
1262 for key in self.data:
1273 shape = self.shape(key)[:-1] + H.shape
1263 shape = self.shape(key)[:-1] + H.shape
1274 for tm, obj in list(self.data[key].items()):
1264 for tm, obj in list(self.data[key].items()):
1275 h = self.__heights[self.__times.index(tm)]
1265 h = self.__heights[self.__times.index(tm)]
1276 if H.size == h.size:
1266 if H.size == h.size:
1277 continue
1267 continue
1278 index = numpy.where(numpy.in1d(H, h))[0]
1268 index = numpy.where(numpy.in1d(H, h))[0]
1279 dummy = numpy.zeros(shape) + numpy.nan
1269 dummy = numpy.zeros(shape) + numpy.nan
1280 if len(shape) == 2:
1270 if len(shape) == 2:
1281 dummy[:, index] = obj
1271 dummy[:, index] = obj
1282 else:
1272 else:
1283 dummy[index] = obj
1273 dummy[index] = obj
1284 self.data[key][tm] = dummy
1274 self.data[key][tm] = dummy
1285
1275
1286 self.__heights = [H for tm in self.__times]
1276 self.__heights = [H for tm in self.__times]
1287
1277
1288 def jsonify(self, decimate=False):
1278 def jsonify(self, decimate=False):
1289 '''
1279 '''
1290 Convert data to json
1280 Convert data to json
1291 '''
1281 '''
1292
1282
1293 data = {}
1283 data = {}
1294 tm = self.times[-1]
1284 tm = self.times[-1]
1295 dy = int(self.heights.size/self.MAXNUMY) + 1
1285 dy = int(self.heights.size/self.MAXNUMY) + 1
1296 for key in self.data:
1286 for key in self.data:
1297 if key in ('spc', 'cspc') or not self.buffering:
1287 if key in ('spc', 'cspc') or not self.buffering:
1298 dx = int(self.data[key].shape[1]/self.MAXNUMX) + 1
1288 dx = int(self.data[key].shape[1]/self.MAXNUMX) + 1
1299 data[key] = self.roundFloats(
1289 data[key] = self.roundFloats(
1300 self.data[key][::, ::dx, ::dy].tolist())
1290 self.data[key][::, ::dx, ::dy].tolist())
1301 else:
1291 else:
1302 data[key] = self.roundFloats(self.data[key][tm].tolist())
1292 data[key] = self.roundFloats(self.data[key][tm].tolist())
1303
1293
1304 ret = {'data': data}
1294 ret = {'data': data}
1305 ret['exp_code'] = self.exp_code
1295 ret['exp_code'] = self.exp_code
1306 ret['time'] = float(tm)
1296 ret['time'] = float(tm)
1307 ret['interval'] = float(self.interval)
1297 ret['interval'] = float(self.interval)
1308 ret['localtime'] = self.localtime
1298 ret['localtime'] = self.localtime
1309 ret['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1299 ret['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1310 if 'spc' in self.data or 'cspc' in self.data:
1300 if 'spc' in self.data or 'cspc' in self.data:
1311 ret['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1301 ret['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1312 else:
1302 else:
1313 ret['xrange'] = []
1303 ret['xrange'] = []
1314 if hasattr(self, 'pairs'):
1304 if hasattr(self, 'pairs'):
1315 ret['pairs'] = [(int(p[0]), int(p[1])) for p in self.pairs]
1305 ret['pairs'] = [(int(p[0]), int(p[1])) for p in self.pairs]
1316 else:
1306 else:
1317 ret['pairs'] = []
1307 ret['pairs'] = []
1318
1308
1319 for key, value in list(self.meta.items()):
1309 for key, value in list(self.meta.items()):
1320 ret[key] = value
1310 ret[key] = value
1321
1311
1322 return json.dumps(ret)
1312 return json.dumps(ret)
1323
1313
1324 @property
1314 @property
1325 def times(self):
1315 def times(self):
1326 '''
1316 '''
1327 Return the list of times of the current data
1317 Return the list of times of the current data
1328 '''
1318 '''
1329
1319
1330 ret = numpy.array(self.__times)
1320 ret = numpy.array(self.__times)
1331 ret.sort()
1321 ret.sort()
1332 return ret
1322 return ret
1333
1323
1334 @property
1324 @property
1335 def min_time(self):
1325 def min_time(self):
1336 '''
1326 '''
1337 Return the minimun time value
1327 Return the minimun time value
1338 '''
1328 '''
1339
1329
1340 return self.times[0]
1330 return self.times[0]
1341
1331
1342 @property
1332 @property
1343 def max_time(self):
1333 def max_time(self):
1344 '''
1334 '''
1345 Return the maximun time value
1335 Return the maximun time value
1346 '''
1336 '''
1347
1337
1348 return self.times[-1]
1338 return self.times[-1]
1349
1339
1350 @property
1340 @property
1351 def heights(self):
1341 def heights(self):
1352 '''
1342 '''
1353 Return the list of heights of the current data
1343 Return the list of heights of the current data
1354 '''
1344 '''
1355
1345
1356 return numpy.array(self.__heights[-1])
1346 return numpy.array(self.__heights[-1])
1357
1347
1358 @staticmethod
1348 @staticmethod
1359 def roundFloats(obj):
1349 def roundFloats(obj):
1360 if isinstance(obj, list):
1350 if isinstance(obj, list):
1361 return list(map(PlotterData.roundFloats, obj))
1351 return list(map(PlotterData.roundFloats, obj))
1362 elif isinstance(obj, float):
1352 elif isinstance(obj, float):
1363 return round(obj, 2)
1353 return round(obj, 2)
@@ -1,2389 +1,2394
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4 import inspect
4 import inspect
5 from .figure import Figure, isRealtime, isTimeInHourRange
5 from .figure import Figure, isRealtime, isTimeInHourRange
6 from .plotting_codes import *
6 from .plotting_codes import *
7 from schainpy.model.proc.jroproc_base import MPDecorator
7 from schainpy.model.proc.jroproc_base import MPDecorator
8 from schainpy.utils import log
8 from schainpy.utils import log
9
9
10 class ParamLine_(Figure):
10 class ParamLine_(Figure):
11
11
12 isConfig = None
12 isConfig = None
13
13
14 def __init__(self):
14 def __init__(self):
15
15
16 self.isConfig = False
16 self.isConfig = False
17 self.WIDTH = 300
17 self.WIDTH = 300
18 self.HEIGHT = 200
18 self.HEIGHT = 200
19 self.counter_imagwr = 0
19 self.counter_imagwr = 0
20
20
21 def getSubplots(self):
21 def getSubplots(self):
22
22
23 nrow = self.nplots
23 nrow = self.nplots
24 ncol = 3
24 ncol = 3
25 return nrow, ncol
25 return nrow, ncol
26
26
27 def setup(self, id, nplots, wintitle, show):
27 def setup(self, id, nplots, wintitle, show):
28
28
29 self.nplots = nplots
29 self.nplots = nplots
30
30
31 self.createFigure(id=id,
31 self.createFigure(id=id,
32 wintitle=wintitle,
32 wintitle=wintitle,
33 show=show)
33 show=show)
34
34
35 nrow,ncol = self.getSubplots()
35 nrow,ncol = self.getSubplots()
36 colspan = 3
36 colspan = 3
37 rowspan = 1
37 rowspan = 1
38
38
39 for i in range(nplots):
39 for i in range(nplots):
40 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
40 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
41
41
42 def plot_iq(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
42 def plot_iq(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
43 yreal = y[channelIndexList,:].real
43 yreal = y[channelIndexList,:].real
44 yimag = y[channelIndexList,:].imag
44 yimag = y[channelIndexList,:].imag
45
45
46 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
46 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
47 xlabel = "Range (Km)"
47 xlabel = "Range (Km)"
48 ylabel = "Intensity - IQ"
48 ylabel = "Intensity - IQ"
49
49
50 if not self.isConfig:
50 if not self.isConfig:
51 nplots = len(channelIndexList)
51 nplots = len(channelIndexList)
52
52
53 self.setup(id=id,
53 self.setup(id=id,
54 nplots=nplots,
54 nplots=nplots,
55 wintitle='',
55 wintitle='',
56 show=show)
56 show=show)
57
57
58 if xmin == None: xmin = numpy.nanmin(x)
58 if xmin == None: xmin = numpy.nanmin(x)
59 if xmax == None: xmax = numpy.nanmax(x)
59 if xmax == None: xmax = numpy.nanmax(x)
60 if ymin == None: ymin = min(numpy.nanmin(yreal),numpy.nanmin(yimag))
60 if ymin == None: ymin = min(numpy.nanmin(yreal),numpy.nanmin(yimag))
61 if ymax == None: ymax = max(numpy.nanmax(yreal),numpy.nanmax(yimag))
61 if ymax == None: ymax = max(numpy.nanmax(yreal),numpy.nanmax(yimag))
62
62
63 self.isConfig = True
63 self.isConfig = True
64
64
65 self.setWinTitle(title)
65 self.setWinTitle(title)
66
66
67 for i in range(len(self.axesList)):
67 for i in range(len(self.axesList)):
68 title = "Channel %d" %(i)
68 title = "Channel %d" %(i)
69 axes = self.axesList[i]
69 axes = self.axesList[i]
70
70
71 axes.pline(x, yreal[i,:],
71 axes.pline(x, yreal[i,:],
72 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
72 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
73 xlabel=xlabel, ylabel=ylabel, title=title)
73 xlabel=xlabel, ylabel=ylabel, title=title)
74
74
75 axes.addpline(x, yimag[i,:], idline=1, color="red", linestyle="solid", lw=2)
75 axes.addpline(x, yimag[i,:], idline=1, color="red", linestyle="solid", lw=2)
76
76
77 def plot_power(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
77 def plot_power(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
78 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
78 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
79 yreal = y.real
79 yreal = y.real
80
80
81 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
81 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
82 xlabel = "Range (Km)"
82 xlabel = "Range (Km)"
83 ylabel = "Intensity"
83 ylabel = "Intensity"
84
84
85 if not self.isConfig:
85 if not self.isConfig:
86 nplots = len(channelIndexList)
86 nplots = len(channelIndexList)
87
87
88 self.setup(id=id,
88 self.setup(id=id,
89 nplots=nplots,
89 nplots=nplots,
90 wintitle='',
90 wintitle='',
91 show=show)
91 show=show)
92
92
93 if xmin == None: xmin = numpy.nanmin(x)
93 if xmin == None: xmin = numpy.nanmin(x)
94 if xmax == None: xmax = numpy.nanmax(x)
94 if xmax == None: xmax = numpy.nanmax(x)
95 if ymin == None: ymin = numpy.nanmin(yreal)
95 if ymin == None: ymin = numpy.nanmin(yreal)
96 if ymax == None: ymax = numpy.nanmax(yreal)
96 if ymax == None: ymax = numpy.nanmax(yreal)
97
97
98 self.isConfig = True
98 self.isConfig = True
99
99
100 self.setWinTitle(title)
100 self.setWinTitle(title)
101
101
102 for i in range(len(self.axesList)):
102 for i in range(len(self.axesList)):
103 title = "Channel %d" %(i)
103 title = "Channel %d" %(i)
104 axes = self.axesList[i]
104 axes = self.axesList[i]
105 ychannel = yreal[i,:]
105 ychannel = yreal[i,:]
106 axes.pline(x, ychannel,
106 axes.pline(x, ychannel,
107 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
107 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
108 xlabel=xlabel, ylabel=ylabel, title=title)
108 xlabel=xlabel, ylabel=ylabel, title=title)
109
109
110
110
111 def run(self, dataOut, id, wintitle="", channelList=None,
111 def run(self, dataOut, id, wintitle="", channelList=None,
112 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
112 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
113 figpath='./', figfile=None, show=True, wr_period=1,
113 figpath='./', figfile=None, show=True, wr_period=1,
114 ftp=False, server=None, folder=None, username=None, password=None):
114 ftp=False, server=None, folder=None, username=None, password=None):
115
115
116 """
116 """
117
117
118 Input:
118 Input:
119 dataOut :
119 dataOut :
120 id :
120 id :
121 wintitle :
121 wintitle :
122 channelList :
122 channelList :
123 xmin : None,
123 xmin : None,
124 xmax : None,
124 xmax : None,
125 ymin : None,
125 ymin : None,
126 ymax : None,
126 ymax : None,
127 """
127 """
128
128
129 if channelList == None:
129 if channelList == None:
130 channelIndexList = dataOut.channelIndexList
130 channelIndexList = dataOut.channelIndexList
131 else:
131 else:
132 channelIndexList = []
132 channelIndexList = []
133 for channel in channelList:
133 for channel in channelList:
134 if channel not in dataOut.channelList:
134 if channel not in dataOut.channelList:
135 raise ValueError("Channel %d is not in dataOut.channelList" % channel)
135 raise ValueError("Channel %d is not in dataOut.channelList" % channel)
136 channelIndexList.append(dataOut.channelList.index(channel))
136 channelIndexList.append(dataOut.channelList.index(channel))
137
137
138 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
138 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
139
139
140 y = dataOut.RR
140 y = dataOut.RR
141
141
142 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
142 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
143 xlabel = "Range (Km)"
143 xlabel = "Range (Km)"
144 ylabel = "Intensity"
144 ylabel = "Intensity"
145
145
146 if not self.isConfig:
146 if not self.isConfig:
147 nplots = len(channelIndexList)
147 nplots = len(channelIndexList)
148
148
149 self.setup(id=id,
149 self.setup(id=id,
150 nplots=nplots,
150 nplots=nplots,
151 wintitle='',
151 wintitle='',
152 show=show)
152 show=show)
153
153
154 if xmin == None: xmin = numpy.nanmin(x)
154 if xmin == None: xmin = numpy.nanmin(x)
155 if xmax == None: xmax = numpy.nanmax(x)
155 if xmax == None: xmax = numpy.nanmax(x)
156 if ymin == None: ymin = numpy.nanmin(y)
156 if ymin == None: ymin = numpy.nanmin(y)
157 if ymax == None: ymax = numpy.nanmax(y)
157 if ymax == None: ymax = numpy.nanmax(y)
158
158
159 self.isConfig = True
159 self.isConfig = True
160
160
161 self.setWinTitle(title)
161 self.setWinTitle(title)
162
162
163 for i in range(len(self.axesList)):
163 for i in range(len(self.axesList)):
164 title = "Channel %d" %(i)
164 title = "Channel %d" %(i)
165 axes = self.axesList[i]
165 axes = self.axesList[i]
166 ychannel = y[i,:]
166 ychannel = y[i,:]
167 axes.pline(x, ychannel,
167 axes.pline(x, ychannel,
168 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
168 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
169 xlabel=xlabel, ylabel=ylabel, title=title)
169 xlabel=xlabel, ylabel=ylabel, title=title)
170
170
171
171
172 self.draw()
172 self.draw()
173
173
174 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + "_" + str(dataOut.profileIndex)
174 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + "_" + str(dataOut.profileIndex)
175 figfile = self.getFilename(name = str_datetime)
175 figfile = self.getFilename(name = str_datetime)
176
176
177 self.save(figpath=figpath,
177 self.save(figpath=figpath,
178 figfile=figfile,
178 figfile=figfile,
179 save=save,
179 save=save,
180 ftp=ftp,
180 ftp=ftp,
181 wr_period=wr_period,
181 wr_period=wr_period,
182 thisDatetime=thisDatetime)
182 thisDatetime=thisDatetime)
183
183
184
184
185
185
186 class SpcParamPlot_(Figure):
186 class SpcParamPlot_(Figure):
187
187
188 isConfig = None
188 isConfig = None
189 __nsubplots = None
189 __nsubplots = None
190
190
191 WIDTHPROF = None
191 WIDTHPROF = None
192 HEIGHTPROF = None
192 HEIGHTPROF = None
193 PREFIX = 'SpcParam'
193 PREFIX = 'SpcParam'
194
194
195 def __init__(self, **kwargs):
195 def __init__(self, **kwargs):
196 Figure.__init__(self, **kwargs)
196 Figure.__init__(self, **kwargs)
197 self.isConfig = False
197 self.isConfig = False
198 self.__nsubplots = 1
198 self.__nsubplots = 1
199
199
200 self.WIDTH = 250
200 self.WIDTH = 250
201 self.HEIGHT = 250
201 self.HEIGHT = 250
202 self.WIDTHPROF = 120
202 self.WIDTHPROF = 120
203 self.HEIGHTPROF = 0
203 self.HEIGHTPROF = 0
204 self.counter_imagwr = 0
204 self.counter_imagwr = 0
205
205
206 self.PLOT_CODE = SPEC_CODE
206 self.PLOT_CODE = SPEC_CODE
207
207
208 self.FTP_WEI = None
208 self.FTP_WEI = None
209 self.EXP_CODE = None
209 self.EXP_CODE = None
210 self.SUB_EXP_CODE = None
210 self.SUB_EXP_CODE = None
211 self.PLOT_POS = None
211 self.PLOT_POS = None
212
212
213 self.__xfilter_ena = False
213 self.__xfilter_ena = False
214 self.__yfilter_ena = False
214 self.__yfilter_ena = False
215
215
216 def getSubplots(self):
216 def getSubplots(self):
217
217
218 ncol = int(numpy.sqrt(self.nplots)+0.9)
218 ncol = int(numpy.sqrt(self.nplots)+0.9)
219 nrow = int(self.nplots*1./ncol + 0.9)
219 nrow = int(self.nplots*1./ncol + 0.9)
220
220
221 return nrow, ncol
221 return nrow, ncol
222
222
223 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
223 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
224
224
225 self.__showprofile = showprofile
225 self.__showprofile = showprofile
226 self.nplots = nplots
226 self.nplots = nplots
227
227
228 ncolspan = 1
228 ncolspan = 1
229 colspan = 1
229 colspan = 1
230 if showprofile:
230 if showprofile:
231 ncolspan = 3
231 ncolspan = 3
232 colspan = 2
232 colspan = 2
233 self.__nsubplots = 2
233 self.__nsubplots = 2
234
234
235 self.createFigure(id = id,
235 self.createFigure(id = id,
236 wintitle = wintitle,
236 wintitle = wintitle,
237 widthplot = self.WIDTH + self.WIDTHPROF,
237 widthplot = self.WIDTH + self.WIDTHPROF,
238 heightplot = self.HEIGHT + self.HEIGHTPROF,
238 heightplot = self.HEIGHT + self.HEIGHTPROF,
239 show=show)
239 show=show)
240
240
241 nrow, ncol = self.getSubplots()
241 nrow, ncol = self.getSubplots()
242
242
243 counter = 0
243 counter = 0
244 for y in range(nrow):
244 for y in range(nrow):
245 for x in range(ncol):
245 for x in range(ncol):
246
246
247 if counter >= self.nplots:
247 if counter >= self.nplots:
248 break
248 break
249
249
250 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
250 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
251
251
252 if showprofile:
252 if showprofile:
253 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
253 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
254
254
255 counter += 1
255 counter += 1
256
256
257 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
257 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
258 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
258 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
259 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
259 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
260 server=None, folder=None, username=None, password=None,
260 server=None, folder=None, username=None, password=None,
261 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
261 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
262 xaxis="frequency", colormap='jet', normFactor=None , Selector = 0):
262 xaxis="frequency", colormap='jet', normFactor=None , Selector = 0):
263
263
264 """
264 """
265
265
266 Input:
266 Input:
267 dataOut :
267 dataOut :
268 id :
268 id :
269 wintitle :
269 wintitle :
270 channelList :
270 channelList :
271 showProfile :
271 showProfile :
272 xmin : None,
272 xmin : None,
273 xmax : None,
273 xmax : None,
274 ymin : None,
274 ymin : None,
275 ymax : None,
275 ymax : None,
276 zmin : None,
276 zmin : None,
277 zmax : None
277 zmax : None
278 """
278 """
279 if realtime:
279 if realtime:
280 if not(isRealtime(utcdatatime = dataOut.utctime)):
280 if not(isRealtime(utcdatatime = dataOut.utctime)):
281 print('Skipping this plot function')
281 print('Skipping this plot function')
282 return
282 return
283
283
284 if channelList == None:
284 if channelList == None:
285 channelIndexList = dataOut.channelIndexList
285 channelIndexList = dataOut.channelIndexList
286 else:
286 else:
287 channelIndexList = []
287 channelIndexList = []
288 for channel in channelList:
288 for channel in channelList:
289 if channel not in dataOut.channelList:
289 if channel not in dataOut.channelList:
290 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
290 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
291 channelIndexList.append(dataOut.channelList.index(channel))
291 channelIndexList.append(dataOut.channelList.index(channel))
292
292
293 # if normFactor is None:
293 # if normFactor is None:
294 # factor = dataOut.normFactor
294 # factor = dataOut.normFactor
295 # else:
295 # else:
296 # factor = normFactor
296 # factor = normFactor
297 if xaxis == "frequency":
297 if xaxis == "frequency":
298 x = dataOut.spcparam_range[0]
298 x = dataOut.spcparam_range[0]
299 xlabel = "Frequency (kHz)"
299 xlabel = "Frequency (kHz)"
300
300
301 elif xaxis == "time":
301 elif xaxis == "time":
302 x = dataOut.spcparam_range[1]
302 x = dataOut.spcparam_range[1]
303 xlabel = "Time (ms)"
303 xlabel = "Time (ms)"
304
304
305 else:
305 else:
306 x = dataOut.spcparam_range[2]
306 x = dataOut.spcparam_range[2]
307 xlabel = "Velocity (m/s)"
307 xlabel = "Velocity (m/s)"
308
308
309 ylabel = "Range (km)"
309 ylabel = "Range (km)"
310
310
311 y = dataOut.getHeiRange()
311 y = dataOut.getHeiRange()
312
312
313 z = dataOut.SPCparam[Selector] /1966080.0#/ dataOut.normFactor#GauSelector] #dataOut.data_spc/factor
313 z = dataOut.SPCparam[Selector] /1966080.0#/ dataOut.normFactor#GauSelector] #dataOut.data_spc/factor
314 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
314 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
315 zdB = 10*numpy.log10(z)
315 zdB = 10*numpy.log10(z)
316
316
317 avg = numpy.average(z, axis=1)
317 avg = numpy.average(z, axis=1)
318 avgdB = 10*numpy.log10(avg)
318 avgdB = 10*numpy.log10(avg)
319
319
320 noise = dataOut.spc_noise
320 noise = dataOut.spc_noise
321 noisedB = 10*numpy.log10(noise)
321 noisedB = 10*numpy.log10(noise)
322
322
323 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
323 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
324 title = wintitle + " Spectra"
324 title = wintitle + " Spectra"
325 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
325 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
326 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
326 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
327
327
328 if not self.isConfig:
328 if not self.isConfig:
329
329
330 nplots = len(channelIndexList)
330 nplots = len(channelIndexList)
331
331
332 self.setup(id=id,
332 self.setup(id=id,
333 nplots=nplots,
333 nplots=nplots,
334 wintitle=wintitle,
334 wintitle=wintitle,
335 showprofile=showprofile,
335 showprofile=showprofile,
336 show=show)
336 show=show)
337
337
338 if xmin == None: xmin = numpy.nanmin(x)
338 if xmin == None: xmin = numpy.nanmin(x)
339 if xmax == None: xmax = numpy.nanmax(x)
339 if xmax == None: xmax = numpy.nanmax(x)
340 if ymin == None: ymin = numpy.nanmin(y)
340 if ymin == None: ymin = numpy.nanmin(y)
341 if ymax == None: ymax = numpy.nanmax(y)
341 if ymax == None: ymax = numpy.nanmax(y)
342 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
342 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
343 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
343 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
344
344
345 self.FTP_WEI = ftp_wei
345 self.FTP_WEI = ftp_wei
346 self.EXP_CODE = exp_code
346 self.EXP_CODE = exp_code
347 self.SUB_EXP_CODE = sub_exp_code
347 self.SUB_EXP_CODE = sub_exp_code
348 self.PLOT_POS = plot_pos
348 self.PLOT_POS = plot_pos
349
349
350 self.isConfig = True
350 self.isConfig = True
351
351
352 self.setWinTitle(title)
352 self.setWinTitle(title)
353
353
354 for i in range(self.nplots):
354 for i in range(self.nplots):
355 index = channelIndexList[i]
355 index = channelIndexList[i]
356 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
356 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
357 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
357 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
358 if len(dataOut.beam.codeList) != 0:
358 if len(dataOut.beam.codeList) != 0:
359 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
359 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
360
360
361 axes = self.axesList[i*self.__nsubplots]
361 axes = self.axesList[i*self.__nsubplots]
362 axes.pcolor(x, y, zdB[index,:,:],
362 axes.pcolor(x, y, zdB[index,:,:],
363 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
363 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
364 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
364 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
365 ticksize=9, cblabel='')
365 ticksize=9, cblabel='')
366
366
367 if self.__showprofile:
367 if self.__showprofile:
368 axes = self.axesList[i*self.__nsubplots +1]
368 axes = self.axesList[i*self.__nsubplots +1]
369 axes.pline(avgdB[index,:], y,
369 axes.pline(avgdB[index,:], y,
370 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
370 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
371 xlabel='dB', ylabel='', title='',
371 xlabel='dB', ylabel='', title='',
372 ytick_visible=False,
372 ytick_visible=False,
373 grid='x')
373 grid='x')
374
374
375 noiseline = numpy.repeat(noisedB[index], len(y))
375 noiseline = numpy.repeat(noisedB[index], len(y))
376 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
376 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
377
377
378 self.draw()
378 self.draw()
379
379
380 if figfile == None:
380 if figfile == None:
381 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
381 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
382 name = str_datetime
382 name = str_datetime
383 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
383 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
384 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
384 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
385 figfile = self.getFilename(name)
385 figfile = self.getFilename(name)
386
386
387 self.save(figpath=figpath,
387 self.save(figpath=figpath,
388 figfile=figfile,
388 figfile=figfile,
389 save=save,
389 save=save,
390 ftp=ftp,
390 ftp=ftp,
391 wr_period=wr_period,
391 wr_period=wr_period,
392 thisDatetime=thisDatetime)
392 thisDatetime=thisDatetime)
393
393
394
394
395
395
396 class MomentsPlot_(Figure):
396 class MomentsPlot_(Figure):
397
397
398 isConfig = None
398 isConfig = None
399 __nsubplots = None
399 __nsubplots = None
400
400
401 WIDTHPROF = None
401 WIDTHPROF = None
402 HEIGHTPROF = None
402 HEIGHTPROF = None
403 PREFIX = 'prm'
403 PREFIX = 'prm'
404 def __init__(self):
404 def __init__(self):
405 Figure.__init__(self)
405 Figure.__init__(self)
406 self.isConfig = False
406 self.isConfig = False
407 self.__nsubplots = 1
407 self.__nsubplots = 1
408
408
409 self.WIDTH = 280
409 self.WIDTH = 280
410 self.HEIGHT = 250
410 self.HEIGHT = 250
411 self.WIDTHPROF = 120
411 self.WIDTHPROF = 120
412 self.HEIGHTPROF = 0
412 self.HEIGHTPROF = 0
413 self.counter_imagwr = 0
413 self.counter_imagwr = 0
414
414
415 self.PLOT_CODE = MOMENTS_CODE
415 self.PLOT_CODE = MOMENTS_CODE
416
416
417 self.FTP_WEI = None
417 self.FTP_WEI = None
418 self.EXP_CODE = None
418 self.EXP_CODE = None
419 self.SUB_EXP_CODE = None
419 self.SUB_EXP_CODE = None
420 self.PLOT_POS = None
420 self.PLOT_POS = None
421
421
422 def getSubplots(self):
422 def getSubplots(self):
423
423
424 ncol = int(numpy.sqrt(self.nplots)+0.9)
424 ncol = int(numpy.sqrt(self.nplots)+0.9)
425 nrow = int(self.nplots*1./ncol + 0.9)
425 nrow = int(self.nplots*1./ncol + 0.9)
426
426
427 return nrow, ncol
427 return nrow, ncol
428
428
429 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
429 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
430
430
431 self.__showprofile = showprofile
431 self.__showprofile = showprofile
432 self.nplots = nplots
432 self.nplots = nplots
433
433
434 ncolspan = 1
434 ncolspan = 1
435 colspan = 1
435 colspan = 1
436 if showprofile:
436 if showprofile:
437 ncolspan = 3
437 ncolspan = 3
438 colspan = 2
438 colspan = 2
439 self.__nsubplots = 2
439 self.__nsubplots = 2
440
440
441 self.createFigure(id = id,
441 self.createFigure(id = id,
442 wintitle = wintitle,
442 wintitle = wintitle,
443 widthplot = self.WIDTH + self.WIDTHPROF,
443 widthplot = self.WIDTH + self.WIDTHPROF,
444 heightplot = self.HEIGHT + self.HEIGHTPROF,
444 heightplot = self.HEIGHT + self.HEIGHTPROF,
445 show=show)
445 show=show)
446
446
447 nrow, ncol = self.getSubplots()
447 nrow, ncol = self.getSubplots()
448
448
449 counter = 0
449 counter = 0
450 for y in range(nrow):
450 for y in range(nrow):
451 for x in range(ncol):
451 for x in range(ncol):
452
452
453 if counter >= self.nplots:
453 if counter >= self.nplots:
454 break
454 break
455
455
456 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
456 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
457
457
458 if showprofile:
458 if showprofile:
459 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
459 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
460
460
461 counter += 1
461 counter += 1
462
462
463 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
463 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
464 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
464 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
465 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
465 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
466 server=None, folder=None, username=None, password=None,
466 server=None, folder=None, username=None, password=None,
467 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
467 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
468
468
469 """
469 """
470
470
471 Input:
471 Input:
472 dataOut :
472 dataOut :
473 id :
473 id :
474 wintitle :
474 wintitle :
475 channelList :
475 channelList :
476 showProfile :
476 showProfile :
477 xmin : None,
477 xmin : None,
478 xmax : None,
478 xmax : None,
479 ymin : None,
479 ymin : None,
480 ymax : None,
480 ymax : None,
481 zmin : None,
481 zmin : None,
482 zmax : None
482 zmax : None
483 """
483 """
484
484
485 if dataOut.flagNoData:
485 if dataOut.flagNoData:
486 return None
486 return None
487
487
488 if realtime:
488 if realtime:
489 if not(isRealtime(utcdatatime = dataOut.utctime)):
489 if not(isRealtime(utcdatatime = dataOut.utctime)):
490 print('Skipping this plot function')
490 print('Skipping this plot function')
491 return
491 return
492
492
493 if channelList == None:
493 if channelList == None:
494 channelIndexList = dataOut.channelIndexList
494 channelIndexList = dataOut.channelIndexList
495 else:
495 else:
496 channelIndexList = []
496 channelIndexList = []
497 for channel in channelList:
497 for channel in channelList:
498 if channel not in dataOut.channelList:
498 if channel not in dataOut.channelList:
499 raise ValueError("Channel %d is not in dataOut.channelList")
499 raise ValueError("Channel %d is not in dataOut.channelList")
500 channelIndexList.append(dataOut.channelList.index(channel))
500 channelIndexList.append(dataOut.channelList.index(channel))
501
501
502 factor = dataOut.normFactor
502 factor = dataOut.normFactor
503 x = dataOut.abscissaList
503 x = dataOut.abscissaList
504 y = dataOut.heightList
504 y = dataOut.heightList
505
505
506 z = dataOut.data_pre[channelIndexList,:,:]/factor
506 z = dataOut.data_pre[channelIndexList,:,:]/factor
507 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
507 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
508 avg = numpy.average(z, axis=1)
508 avg = numpy.average(z, axis=1)
509 noise = dataOut.noise/factor
509 noise = dataOut.noise/factor
510
510
511 zdB = 10*numpy.log10(z)
511 zdB = 10*numpy.log10(z)
512 avgdB = 10*numpy.log10(avg)
512 avgdB = 10*numpy.log10(avg)
513 noisedB = 10*numpy.log10(noise)
513 noisedB = 10*numpy.log10(noise)
514
514
515 #thisDatetime = dataOut.datatime
515 #thisDatetime = dataOut.datatime
516 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
516 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
517 title = wintitle + " Parameters"
517 title = wintitle + " Parameters"
518 xlabel = "Velocity (m/s)"
518 xlabel = "Velocity (m/s)"
519 ylabel = "Range (Km)"
519 ylabel = "Range (Km)"
520
520
521 update_figfile = False
521 update_figfile = False
522
522
523 if not self.isConfig:
523 if not self.isConfig:
524
524
525 nplots = len(channelIndexList)
525 nplots = len(channelIndexList)
526
526
527 self.setup(id=id,
527 self.setup(id=id,
528 nplots=nplots,
528 nplots=nplots,
529 wintitle=wintitle,
529 wintitle=wintitle,
530 showprofile=showprofile,
530 showprofile=showprofile,
531 show=show)
531 show=show)
532
532
533 if xmin == None: xmin = numpy.nanmin(x)
533 if xmin == None: xmin = numpy.nanmin(x)
534 if xmax == None: xmax = numpy.nanmax(x)
534 if xmax == None: xmax = numpy.nanmax(x)
535 if ymin == None: ymin = numpy.nanmin(y)
535 if ymin == None: ymin = numpy.nanmin(y)
536 if ymax == None: ymax = numpy.nanmax(y)
536 if ymax == None: ymax = numpy.nanmax(y)
537 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
537 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
538 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
538 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
539
539
540 self.FTP_WEI = ftp_wei
540 self.FTP_WEI = ftp_wei
541 self.EXP_CODE = exp_code
541 self.EXP_CODE = exp_code
542 self.SUB_EXP_CODE = sub_exp_code
542 self.SUB_EXP_CODE = sub_exp_code
543 self.PLOT_POS = plot_pos
543 self.PLOT_POS = plot_pos
544
544
545 self.isConfig = True
545 self.isConfig = True
546 update_figfile = True
546 update_figfile = True
547
547
548 self.setWinTitle(title)
548 self.setWinTitle(title)
549
549
550 for i in range(self.nplots):
550 for i in range(self.nplots):
551 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
551 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
552 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
552 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
553 axes = self.axesList[i*self.__nsubplots]
553 axes = self.axesList[i*self.__nsubplots]
554 axes.pcolor(x, y, zdB[i,:,:],
554 axes.pcolor(x, y, zdB[i,:,:],
555 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
555 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
556 xlabel=xlabel, ylabel=ylabel, title=title,
556 xlabel=xlabel, ylabel=ylabel, title=title,
557 ticksize=9, cblabel='')
557 ticksize=9, cblabel='')
558 #Mean Line
558 #Mean Line
559 mean = dataOut.data_param[i, 1, :]
559 mean = dataOut.data_param[i, 1, :]
560 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
560 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
561
561
562 if self.__showprofile:
562 if self.__showprofile:
563 axes = self.axesList[i*self.__nsubplots +1]
563 axes = self.axesList[i*self.__nsubplots +1]
564 axes.pline(avgdB[i], y,
564 axes.pline(avgdB[i], y,
565 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
565 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
566 xlabel='dB', ylabel='', title='',
566 xlabel='dB', ylabel='', title='',
567 ytick_visible=False,
567 ytick_visible=False,
568 grid='x')
568 grid='x')
569
569
570 noiseline = numpy.repeat(noisedB[i], len(y))
570 noiseline = numpy.repeat(noisedB[i], len(y))
571 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
571 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
572
572
573 self.draw()
573 self.draw()
574
574
575 self.save(figpath=figpath,
575 self.save(figpath=figpath,
576 figfile=figfile,
576 figfile=figfile,
577 save=save,
577 save=save,
578 ftp=ftp,
578 ftp=ftp,
579 wr_period=wr_period,
579 wr_period=wr_period,
580 thisDatetime=thisDatetime)
580 thisDatetime=thisDatetime)
581
581
582
582
583 class SkyMapPlot_(Figure):
583 class SkyMapPlot_(Figure):
584
584
585 __isConfig = None
585 __isConfig = None
586 __nsubplots = None
586 __nsubplots = None
587
587
588 WIDTHPROF = None
588 WIDTHPROF = None
589 HEIGHTPROF = None
589 HEIGHTPROF = None
590 PREFIX = 'mmap'
590 PREFIX = 'mmap'
591
591
592 def __init__(self, **kwargs):
592 def __init__(self, **kwargs):
593 Figure.__init__(self, **kwargs)
593 Figure.__init__(self, **kwargs)
594 self.isConfig = False
594 self.isConfig = False
595 self.__nsubplots = 1
595 self.__nsubplots = 1
596
596
597 # self.WIDTH = 280
597 # self.WIDTH = 280
598 # self.HEIGHT = 250
598 # self.HEIGHT = 250
599 self.WIDTH = 600
599 self.WIDTH = 600
600 self.HEIGHT = 600
600 self.HEIGHT = 600
601 self.WIDTHPROF = 120
601 self.WIDTHPROF = 120
602 self.HEIGHTPROF = 0
602 self.HEIGHTPROF = 0
603 self.counter_imagwr = 0
603 self.counter_imagwr = 0
604
604
605 self.PLOT_CODE = MSKYMAP_CODE
605 self.PLOT_CODE = MSKYMAP_CODE
606
606
607 self.FTP_WEI = None
607 self.FTP_WEI = None
608 self.EXP_CODE = None
608 self.EXP_CODE = None
609 self.SUB_EXP_CODE = None
609 self.SUB_EXP_CODE = None
610 self.PLOT_POS = None
610 self.PLOT_POS = None
611
611
612 def getSubplots(self):
612 def getSubplots(self):
613
613
614 ncol = int(numpy.sqrt(self.nplots)+0.9)
614 ncol = int(numpy.sqrt(self.nplots)+0.9)
615 nrow = int(self.nplots*1./ncol + 0.9)
615 nrow = int(self.nplots*1./ncol + 0.9)
616
616
617 return nrow, ncol
617 return nrow, ncol
618
618
619 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
619 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
620
620
621 self.__showprofile = showprofile
621 self.__showprofile = showprofile
622 self.nplots = nplots
622 self.nplots = nplots
623
623
624 ncolspan = 1
624 ncolspan = 1
625 colspan = 1
625 colspan = 1
626
626
627 self.createFigure(id = id,
627 self.createFigure(id = id,
628 wintitle = wintitle,
628 wintitle = wintitle,
629 widthplot = self.WIDTH, #+ self.WIDTHPROF,
629 widthplot = self.WIDTH, #+ self.WIDTHPROF,
630 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
630 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
631 show=show)
631 show=show)
632
632
633 nrow, ncol = 1,1
633 nrow, ncol = 1,1
634 counter = 0
634 counter = 0
635 x = 0
635 x = 0
636 y = 0
636 y = 0
637 self.addAxes(1, 1, 0, 0, 1, 1, True)
637 self.addAxes(1, 1, 0, 0, 1, 1, True)
638
638
639 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
639 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
640 tmin=0, tmax=24, timerange=None,
640 tmin=0, tmax=24, timerange=None,
641 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
641 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
642 server=None, folder=None, username=None, password=None,
642 server=None, folder=None, username=None, password=None,
643 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
643 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
644
644
645 """
645 """
646
646
647 Input:
647 Input:
648 dataOut :
648 dataOut :
649 id :
649 id :
650 wintitle :
650 wintitle :
651 channelList :
651 channelList :
652 showProfile :
652 showProfile :
653 xmin : None,
653 xmin : None,
654 xmax : None,
654 xmax : None,
655 ymin : None,
655 ymin : None,
656 ymax : None,
656 ymax : None,
657 zmin : None,
657 zmin : None,
658 zmax : None
658 zmax : None
659 """
659 """
660
660
661 arrayParameters = dataOut.data_param
661 arrayParameters = dataOut.data_param
662 error = arrayParameters[:,-1]
662 error = arrayParameters[:,-1]
663 indValid = numpy.where(error == 0)[0]
663 indValid = numpy.where(error == 0)[0]
664 finalMeteor = arrayParameters[indValid,:]
664 finalMeteor = arrayParameters[indValid,:]
665 finalAzimuth = finalMeteor[:,3]
665 finalAzimuth = finalMeteor[:,3]
666 finalZenith = finalMeteor[:,4]
666 finalZenith = finalMeteor[:,4]
667
667
668 x = finalAzimuth*numpy.pi/180
668 x = finalAzimuth*numpy.pi/180
669 y = finalZenith
669 y = finalZenith
670 x1 = [dataOut.ltctime, dataOut.ltctime]
670 x1 = [dataOut.ltctime, dataOut.ltctime]
671
671
672 #thisDatetime = dataOut.datatime
672 #thisDatetime = dataOut.datatime
673 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
673 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
674 title = wintitle + " Parameters"
674 title = wintitle + " Parameters"
675 xlabel = "Zonal Zenith Angle (deg) "
675 xlabel = "Zonal Zenith Angle (deg) "
676 ylabel = "Meridional Zenith Angle (deg)"
676 ylabel = "Meridional Zenith Angle (deg)"
677 update_figfile = False
677 update_figfile = False
678
678
679 if not self.isConfig:
679 if not self.isConfig:
680
680
681 nplots = 1
681 nplots = 1
682
682
683 self.setup(id=id,
683 self.setup(id=id,
684 nplots=nplots,
684 nplots=nplots,
685 wintitle=wintitle,
685 wintitle=wintitle,
686 showprofile=showprofile,
686 showprofile=showprofile,
687 show=show)
687 show=show)
688
688
689 if self.xmin is None and self.xmax is None:
689 if self.xmin is None and self.xmax is None:
690 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
690 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
691
691
692 if timerange != None:
692 if timerange != None:
693 self.timerange = timerange
693 self.timerange = timerange
694 else:
694 else:
695 self.timerange = self.xmax - self.xmin
695 self.timerange = self.xmax - self.xmin
696
696
697 self.FTP_WEI = ftp_wei
697 self.FTP_WEI = ftp_wei
698 self.EXP_CODE = exp_code
698 self.EXP_CODE = exp_code
699 self.SUB_EXP_CODE = sub_exp_code
699 self.SUB_EXP_CODE = sub_exp_code
700 self.PLOT_POS = plot_pos
700 self.PLOT_POS = plot_pos
701 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
701 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
702 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
702 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
703 self.isConfig = True
703 self.isConfig = True
704 update_figfile = True
704 update_figfile = True
705
705
706 self.setWinTitle(title)
706 self.setWinTitle(title)
707
707
708 i = 0
708 i = 0
709 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
709 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
710
710
711 axes = self.axesList[i*self.__nsubplots]
711 axes = self.axesList[i*self.__nsubplots]
712 nevents = axes.x_buffer.shape[0] + x.shape[0]
712 nevents = axes.x_buffer.shape[0] + x.shape[0]
713 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
713 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
714 axes.polar(x, y,
714 axes.polar(x, y,
715 title=title, xlabel=xlabel, ylabel=ylabel,
715 title=title, xlabel=xlabel, ylabel=ylabel,
716 ticksize=9, cblabel='')
716 ticksize=9, cblabel='')
717
717
718 self.draw()
718 self.draw()
719
719
720 self.save(figpath=figpath,
720 self.save(figpath=figpath,
721 figfile=figfile,
721 figfile=figfile,
722 save=save,
722 save=save,
723 ftp=ftp,
723 ftp=ftp,
724 wr_period=wr_period,
724 wr_period=wr_period,
725 thisDatetime=thisDatetime,
725 thisDatetime=thisDatetime,
726 update_figfile=update_figfile)
726 update_figfile=update_figfile)
727
727
728 if dataOut.ltctime >= self.xmax:
728 if dataOut.ltctime >= self.xmax:
729 self.isConfigmagwr = wr_period
729 self.isConfigmagwr = wr_period
730 self.isConfig = False
730 self.isConfig = False
731 update_figfile = True
731 update_figfile = True
732 axes.__firsttime = True
732 axes.__firsttime = True
733 self.xmin += self.timerange
733 self.xmin += self.timerange
734 self.xmax += self.timerange
734 self.xmax += self.timerange
735
735
736
736
737
737
738
738 @MPDecorator
739 class WindProfilerPlot_(Figure):
739 class WindProfilerPlot_(Figure):
740
740
741 __isConfig = None
741 __isConfig = None
742 __nsubplots = None
742 __nsubplots = None
743
743
744 WIDTHPROF = None
744 WIDTHPROF = None
745 HEIGHTPROF = None
745 HEIGHTPROF = None
746 PREFIX = 'wind'
746 PREFIX = 'wind'
747
747
748 def __init__(self, **kwargs):
748 def __init__(self):
749 Figure.__init__(self, **kwargs)
749 Figure.__init__(self)
750 self.timerange = None
750 self.timerange = None
751 self.isConfig = False
751 self.isConfig = False
752 self.__nsubplots = 1
752 self.__nsubplots = 1
753
753
754 self.WIDTH = 800
754 self.WIDTH = 800
755 self.HEIGHT = 300
755 self.HEIGHT = 300
756 self.WIDTHPROF = 120
756 self.WIDTHPROF = 120
757 self.HEIGHTPROF = 0
757 self.HEIGHTPROF = 0
758 self.counter_imagwr = 0
758 self.counter_imagwr = 0
759
759
760 self.PLOT_CODE = WIND_CODE
760 self.PLOT_CODE = WIND_CODE
761
761
762 self.FTP_WEI = None
762 self.FTP_WEI = None
763 self.EXP_CODE = None
763 self.EXP_CODE = None
764 self.SUB_EXP_CODE = None
764 self.SUB_EXP_CODE = None
765 self.PLOT_POS = None
765 self.PLOT_POS = None
766 self.tmin = None
766 self.tmin = None
767 self.tmax = None
767 self.tmax = None
768
768
769 self.xmin = None
769 self.xmin = None
770 self.xmax = None
770 self.xmax = None
771
771
772 self.figfile = None
772 self.figfile = None
773
773
774 def getSubplots(self):
774 def getSubplots(self):
775
775
776 ncol = 1
776 ncol = 1
777 nrow = self.nplots
777 nrow = self.nplots
778
778
779 return nrow, ncol
779 return nrow, ncol
780
780
781 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
781 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
782
782
783 self.__showprofile = showprofile
783 self.__showprofile = showprofile
784 self.nplots = nplots
784 self.nplots = nplots
785
785
786 ncolspan = 1
786 ncolspan = 1
787 colspan = 1
787 colspan = 1
788
788
789 self.createFigure(id = id,
789 self.createFigure(id = id,
790 wintitle = wintitle,
790 wintitle = wintitle,
791 widthplot = self.WIDTH + self.WIDTHPROF,
791 widthplot = self.WIDTH + self.WIDTHPROF,
792 heightplot = self.HEIGHT + self.HEIGHTPROF,
792 heightplot = self.HEIGHT + self.HEIGHTPROF,
793 show=show)
793 show=show)
794
794
795 nrow, ncol = self.getSubplots()
795 nrow, ncol = self.getSubplots()
796
796
797 counter = 0
797 counter = 0
798 for y in range(nrow):
798 for y in range(nrow):
799 if counter >= self.nplots:
799 if counter >= self.nplots:
800 break
800 break
801
801
802 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
802 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
803 counter += 1
803 counter += 1
804
804
805 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
805 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
806 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
806 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
807 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
807 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
808 timerange=None, SNRthresh = None,
808 timerange=None, SNRthresh = None,
809 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
809 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
810 server=None, folder=None, username=None, password=None,
810 server=None, folder=None, username=None, password=None,
811 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
811 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
812 """
812 """
813
813
814 Input:
814 Input:
815 dataOut :
815 dataOut :
816 id :
816 id :
817 wintitle :
817 wintitle :
818 channelList :
818 channelList :
819 showProfile :
819 showProfile :
820 xmin : None,
820 xmin : None,
821 xmax : None,
821 xmax : None,
822 ymin : None,
822 ymin : None,
823 ymax : None,
823 ymax : None,
824 zmin : None,
824 zmin : None,
825 zmax : None
825 zmax : None
826 """
826 """
827
827
828 if dataOut.flagNoData:
829 return dataOut
830
828 # if timerange is not None:
831 # if timerange is not None:
829 # self.timerange = timerange
832 # self.timerange = timerange
830 #
833 #
831 # tmin = None
834 # tmin = None
832 # tmax = None
835 # tmax = None
833
836
834 x = dataOut.getTimeRange1(dataOut.paramInterval)
837 x = dataOut.getTimeRange1(dataOut.paramInterval)
835 y = dataOut.heightList
838 y = dataOut.heightList
836 z = dataOut.data_output.copy()
839 z = dataOut.data_output.copy()
837 nplots = z.shape[0] #Number of wind dimensions estimated
840 nplots = z.shape[0] #Number of wind dimensions estimated
838 nplotsw = nplots
841 nplotsw = nplots
839
842
840
843
841 #If there is a SNR function defined
844 #If there is a SNR function defined
842 if dataOut.data_SNR is not None:
845 if dataOut.data_SNR is not None:
843 nplots += 1
846 nplots += 1
844 SNR = dataOut.data_SNR[0]
847 SNR = dataOut.data_SNR[0]
845 SNRavg = SNR#numpy.average(SNR, axis=0)
848 SNRavg = SNR#numpy.average(SNR, axis=0)
846
849
847 SNRdB = 10*numpy.log10(SNR)
850 SNRdB = 10*numpy.log10(SNR)
848 SNRavgdB = 10*numpy.log10(SNRavg)
851 SNRavgdB = 10*numpy.log10(SNRavg)
849
852
850 if SNRthresh == None:
853 if SNRthresh == None:
851 SNRthresh = -5.0
854 SNRthresh = -5.0
852 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
855 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
853
856
854 for i in range(nplotsw):
857 for i in range(nplotsw):
855 z[i,ind] = numpy.nan
858 z[i,ind] = numpy.nan
856
859
857 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
860 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
858 #thisDatetime = datetime.datetime.now()
861 #thisDatetime = datetime.datetime.now()
859 title = wintitle + "Wind"
862 title = wintitle + "Wind"
860 xlabel = ""
863 xlabel = ""
861 ylabel = "Height (km)"
864 ylabel = "Height (km)"
862 update_figfile = False
865 update_figfile = False
863
866
864 if not self.isConfig:
867 if not self.isConfig:
865
868
866 self.setup(id=id,
869 self.setup(id=id,
867 nplots=nplots,
870 nplots=nplots,
868 wintitle=wintitle,
871 wintitle=wintitle,
869 showprofile=showprofile,
872 showprofile=showprofile,
870 show=show)
873 show=show)
871
874
872 if timerange is not None:
875 if timerange is not None:
873 self.timerange = timerange
876 self.timerange = timerange
874
877
875 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
878 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
876
879
877 if ymin == None: ymin = numpy.nanmin(y)
880 if ymin == None: ymin = numpy.nanmin(y)
878 if ymax == None: ymax = numpy.nanmax(y)
881 if ymax == None: ymax = numpy.nanmax(y)
879
882
880 if zmax == None: zmax = numpy.nanmax(abs(z[list(range(2)),:]))
883 if zmax == None: zmax = numpy.nanmax(abs(z[list(range(2)),:]))
881 #if numpy.isnan(zmax): zmax = 50
884 #if numpy.isnan(zmax): zmax = 50
882 if zmin == None: zmin = -zmax
885 if zmin == None: zmin = -zmax
883
886
884 if nplotsw == 3:
887 if nplotsw == 3:
885 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
888 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
886 if zmin_ver == None: zmin_ver = -zmax_ver
889 if zmin_ver == None: zmin_ver = -zmax_ver
887
890
888 if dataOut.data_SNR is not None:
891 if dataOut.data_SNR is not None:
889 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
892 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
890 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
893 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
891
894
892
895
893 self.FTP_WEI = ftp_wei
896 self.FTP_WEI = ftp_wei
894 self.EXP_CODE = exp_code
897 self.EXP_CODE = exp_code
895 self.SUB_EXP_CODE = sub_exp_code
898 self.SUB_EXP_CODE = sub_exp_code
896 self.PLOT_POS = plot_pos
899 self.PLOT_POS = plot_pos
897
900
898 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
901 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
899 self.isConfig = True
902 self.isConfig = True
900 self.figfile = figfile
903 self.figfile = figfile
901 update_figfile = True
904 update_figfile = True
902
905
903 self.setWinTitle(title)
906 self.setWinTitle(title)
904
907
905 if ((self.xmax - x[1]) < (x[1]-x[0])):
908 if ((self.xmax - x[1]) < (x[1]-x[0])):
906 x[1] = self.xmax
909 x[1] = self.xmax
907
910
908 strWind = ['Zonal', 'Meridional', 'Vertical']
911 strWind = ['Zonal', 'Meridional', 'Vertical']
909 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
912 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
910 zmaxVector = [zmax, zmax, zmax_ver]
913 zmaxVector = [zmax, zmax, zmax_ver]
911 zminVector = [zmin, zmin, zmin_ver]
914 zminVector = [zmin, zmin, zmin_ver]
912 windFactor = [1,1,100]
915 windFactor = [1,1,100]
913
916
914 for i in range(nplotsw):
917 for i in range(nplotsw):
915
918
916 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
919 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
917 axes = self.axesList[i*self.__nsubplots]
920 axes = self.axesList[i*self.__nsubplots]
918
921
919 z1 = z[i,:].reshape((1,-1))*windFactor[i]
922 z1 = z[i,:].reshape((1,-1))*windFactor[i]
920
923
921 axes.pcolorbuffer(x, y, z1,
924 axes.pcolorbuffer(x, y, z1,
922 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
925 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
923 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
926 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
924 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
927 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
925
928
926 if dataOut.data_SNR is not None:
929 if dataOut.data_SNR is not None:
927 i += 1
930 i += 1
928 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
931 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
929 axes = self.axesList[i*self.__nsubplots]
932 axes = self.axesList[i*self.__nsubplots]
930 SNRavgdB = SNRavgdB.reshape((1,-1))
933 SNRavgdB = SNRavgdB.reshape((1,-1))
931 axes.pcolorbuffer(x, y, SNRavgdB,
934 axes.pcolorbuffer(x, y, SNRavgdB,
932 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
935 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
933 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
936 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
934 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
937 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
935
938
936 self.draw()
939 self.draw()
937
940
938 self.save(figpath=figpath,
941 self.save(figpath=figpath,
939 figfile=figfile,
942 figfile=figfile,
940 save=save,
943 save=save,
941 ftp=ftp,
944 ftp=ftp,
942 wr_period=wr_period,
945 wr_period=wr_period,
943 thisDatetime=thisDatetime,
946 thisDatetime=thisDatetime,
944 update_figfile=update_figfile)
947 update_figfile=update_figfile)
945
948
946 if dataOut.ltctime + dataOut.paramInterval >= self.xmax:
949 if dataOut.ltctime + dataOut.paramInterval >= self.xmax:
947 self.counter_imagwr = wr_period
950 self.counter_imagwr = wr_period
948 self.isConfig = False
951 self.isConfig = False
949 update_figfile = True
952 update_figfile = True
950
953
954 return dataOut
955
951 @MPDecorator
956 @MPDecorator
952 class ParametersPlot_(Figure):
957 class ParametersPlot_(Figure):
953
958
954 __isConfig = None
959 __isConfig = None
955 __nsubplots = None
960 __nsubplots = None
956
961
957 WIDTHPROF = None
962 WIDTHPROF = None
958 HEIGHTPROF = None
963 HEIGHTPROF = None
959 PREFIX = 'param'
964 PREFIX = 'param'
960
965
961 nplots = None
966 nplots = None
962 nchan = None
967 nchan = None
963
968
964 def __init__(self):#, **kwargs):
969 def __init__(self):#, **kwargs):
965 Figure.__init__(self)#, **kwargs)
970 Figure.__init__(self)#, **kwargs)
966 self.timerange = None
971 self.timerange = None
967 self.isConfig = False
972 self.isConfig = False
968 self.__nsubplots = 1
973 self.__nsubplots = 1
969
974
970 self.WIDTH = 300
975 self.WIDTH = 300
971 self.HEIGHT = 550
976 self.HEIGHT = 550
972 self.WIDTHPROF = 120
977 self.WIDTHPROF = 120
973 self.HEIGHTPROF = 0
978 self.HEIGHTPROF = 0
974 self.counter_imagwr = 0
979 self.counter_imagwr = 0
975
980
976 self.PLOT_CODE = RTI_CODE
981 self.PLOT_CODE = RTI_CODE
977
982
978 self.FTP_WEI = None
983 self.FTP_WEI = None
979 self.EXP_CODE = None
984 self.EXP_CODE = None
980 self.SUB_EXP_CODE = None
985 self.SUB_EXP_CODE = None
981 self.PLOT_POS = None
986 self.PLOT_POS = None
982 self.tmin = None
987 self.tmin = None
983 self.tmax = None
988 self.tmax = None
984
989
985 self.xmin = None
990 self.xmin = None
986 self.xmax = None
991 self.xmax = None
987
992
988 self.figfile = None
993 self.figfile = None
989
994
990 def getSubplots(self):
995 def getSubplots(self):
991
996
992 ncol = 1
997 ncol = 1
993 nrow = self.nplots
998 nrow = self.nplots
994
999
995 return nrow, ncol
1000 return nrow, ncol
996
1001
997 def setup(self, id, nplots, wintitle, show=True):
1002 def setup(self, id, nplots, wintitle, show=True):
998
1003
999 self.nplots = nplots
1004 self.nplots = nplots
1000
1005
1001 ncolspan = 1
1006 ncolspan = 1
1002 colspan = 1
1007 colspan = 1
1003
1008
1004 self.createFigure(id = id,
1009 self.createFigure(id = id,
1005 wintitle = wintitle,
1010 wintitle = wintitle,
1006 widthplot = self.WIDTH + self.WIDTHPROF,
1011 widthplot = self.WIDTH + self.WIDTHPROF,
1007 heightplot = self.HEIGHT + self.HEIGHTPROF,
1012 heightplot = self.HEIGHT + self.HEIGHTPROF,
1008 show=show)
1013 show=show)
1009
1014
1010 nrow, ncol = self.getSubplots()
1015 nrow, ncol = self.getSubplots()
1011
1016
1012 counter = 0
1017 counter = 0
1013 for y in range(nrow):
1018 for y in range(nrow):
1014 for x in range(ncol):
1019 for x in range(ncol):
1015
1020
1016 if counter >= self.nplots:
1021 if counter >= self.nplots:
1017 break
1022 break
1018
1023
1019 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1024 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1020
1025
1021 counter += 1
1026 counter += 1
1022
1027
1023 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet",
1028 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet",
1024 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
1029 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
1025 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
1030 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
1026 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1031 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1027 server=None, folder=None, username=None, password=None,
1032 server=None, folder=None, username=None, password=None,
1028 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None):
1033 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None):
1029 """
1034 """
1030
1035
1031 Input:
1036 Input:
1032 dataOut :
1037 dataOut :
1033 id :
1038 id :
1034 wintitle :
1039 wintitle :
1035 channelList :
1040 channelList :
1036 showProfile :
1041 showProfile :
1037 xmin : None,
1042 xmin : None,
1038 xmax : None,
1043 xmax : None,
1039 ymin : None,
1044 ymin : None,
1040 ymax : None,
1045 ymax : None,
1041 zmin : None,
1046 zmin : None,
1042 zmax : None
1047 zmax : None
1043 """
1048 """
1044 if dataOut.flagNoData:
1049 if dataOut.flagNoData:
1045 return dataOut
1050 return dataOut
1046
1051
1047
1052
1048 if HEIGHT is not None:
1053 if HEIGHT is not None:
1049 self.HEIGHT = HEIGHT
1054 self.HEIGHT = HEIGHT
1050
1055
1051
1056
1052 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1057 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1053 return
1058 return
1054
1059
1055 if channelList == None:
1060 if channelList == None:
1056 channelIndexList = list(range(dataOut.data_param.shape[0]))
1061 channelIndexList = list(range(dataOut.data_param.shape[0]))
1057 else:
1062 else:
1058 channelIndexList = []
1063 channelIndexList = []
1059 for channel in channelList:
1064 for channel in channelList:
1060 if channel not in dataOut.channelList:
1065 if channel not in dataOut.channelList:
1061 raise ValueError("Channel %d is not in dataOut.channelList")
1066 raise ValueError("Channel %d is not in dataOut.channelList")
1062 channelIndexList.append(dataOut.channelList.index(channel))
1067 channelIndexList.append(dataOut.channelList.index(channel))
1063
1068
1064 x = dataOut.getTimeRange1(dataOut.paramInterval)
1069 x = dataOut.getTimeRange1(dataOut.paramInterval)
1065 y = dataOut.getHeiRange()
1070 y = dataOut.getHeiRange()
1066
1071
1067 if dataOut.data_param.ndim == 3:
1072 if dataOut.data_param.ndim == 3:
1068 z = dataOut.data_param[channelIndexList,paramIndex,:]
1073 z = dataOut.data_param[channelIndexList,paramIndex,:]
1069 else:
1074 else:
1070 z = dataOut.data_param[channelIndexList,:]
1075 z = dataOut.data_param[channelIndexList,:]
1071
1076
1072 if showSNR:
1077 if showSNR:
1073 #SNR data
1078 #SNR data
1074 SNRarray = dataOut.data_SNR[channelIndexList,:]
1079 SNRarray = dataOut.data_SNR[channelIndexList,:]
1075 SNRdB = 10*numpy.log10(SNRarray)
1080 SNRdB = 10*numpy.log10(SNRarray)
1076 ind = numpy.where(SNRdB < SNRthresh)
1081 ind = numpy.where(SNRdB < SNRthresh)
1077 z[ind] = numpy.nan
1082 z[ind] = numpy.nan
1078
1083
1079 thisDatetime = dataOut.datatime
1084 thisDatetime = dataOut.datatime
1080 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1085 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1081 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1086 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1082 xlabel = ""
1087 xlabel = ""
1083 ylabel = "Range (km)"
1088 ylabel = "Range (km)"
1084
1089
1085 update_figfile = False
1090 update_figfile = False
1086
1091
1087 if not self.isConfig:
1092 if not self.isConfig:
1088
1093
1089 nchan = len(channelIndexList)
1094 nchan = len(channelIndexList)
1090 self.nchan = nchan
1095 self.nchan = nchan
1091 self.plotFact = 1
1096 self.plotFact = 1
1092 nplots = nchan
1097 nplots = nchan
1093
1098
1094 if showSNR:
1099 if showSNR:
1095 nplots = nchan*2
1100 nplots = nchan*2
1096 self.plotFact = 2
1101 self.plotFact = 2
1097 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1102 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1098 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1103 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1099
1104
1100 self.setup(id=id,
1105 self.setup(id=id,
1101 nplots=nplots,
1106 nplots=nplots,
1102 wintitle=wintitle,
1107 wintitle=wintitle,
1103 show=show)
1108 show=show)
1104
1109
1105 if timerange != None:
1110 if timerange != None:
1106 self.timerange = timerange
1111 self.timerange = timerange
1107
1112
1108 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1113 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1109
1114
1110 if ymin == None: ymin = numpy.nanmin(y)
1115 if ymin == None: ymin = numpy.nanmin(y)
1111 if ymax == None: ymax = numpy.nanmax(y)
1116 if ymax == None: ymax = numpy.nanmax(y)
1112 if zmin == None: zmin = numpy.nanmin(z)
1117 if zmin == None: zmin = numpy.nanmin(z)
1113 if zmax == None: zmax = numpy.nanmax(z)
1118 if zmax == None: zmax = numpy.nanmax(z)
1114
1119
1115 self.FTP_WEI = ftp_wei
1120 self.FTP_WEI = ftp_wei
1116 self.EXP_CODE = exp_code
1121 self.EXP_CODE = exp_code
1117 self.SUB_EXP_CODE = sub_exp_code
1122 self.SUB_EXP_CODE = sub_exp_code
1118 self.PLOT_POS = plot_pos
1123 self.PLOT_POS = plot_pos
1119
1124
1120 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1125 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1121 self.isConfig = True
1126 self.isConfig = True
1122 self.figfile = figfile
1127 self.figfile = figfile
1123 update_figfile = True
1128 update_figfile = True
1124
1129
1125 self.setWinTitle(title)
1130 self.setWinTitle(title)
1126
1131
1127 # for i in range(self.nchan):
1132 # for i in range(self.nchan):
1128 # index = channelIndexList[i]
1133 # index = channelIndexList[i]
1129 # title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1134 # title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1130 # axes = self.axesList[i*self.plotFact]
1135 # axes = self.axesList[i*self.plotFact]
1131 # z1 = z[i,:].reshape((1,-1))
1136 # z1 = z[i,:].reshape((1,-1))
1132 # axes.pcolorbuffer(x, y, z1,
1137 # axes.pcolorbuffer(x, y, z1,
1133 # xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1138 # xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1134 # xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1139 # xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1135 # ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
1140 # ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
1136 #
1141 #
1137 # if showSNR:
1142 # if showSNR:
1138 # title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1143 # title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1139 # axes = self.axesList[i*self.plotFact + 1]
1144 # axes = self.axesList[i*self.plotFact + 1]
1140 # SNRdB1 = SNRdB[i,:].reshape((1,-1))
1145 # SNRdB1 = SNRdB[i,:].reshape((1,-1))
1141 # axes.pcolorbuffer(x, y, SNRdB1,
1146 # axes.pcolorbuffer(x, y, SNRdB1,
1142 # xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1147 # xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1143 # xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1148 # xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1144 # ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1149 # ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1145
1150
1146 i=0
1151 i=0
1147 index = channelIndexList[i]
1152 index = channelIndexList[i]
1148 title = "Factor de reflectividad Z [dBZ]"
1153 title = "Factor de reflectividad Z [dBZ]"
1149 axes = self.axesList[i*self.plotFact]
1154 axes = self.axesList[i*self.plotFact]
1150 z1 = z[i,:].reshape((1,-1))
1155 z1 = z[i,:].reshape((1,-1))
1151 axes.pcolorbuffer(x, y, z1,
1156 axes.pcolorbuffer(x, y, z1,
1152 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1157 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1153 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1158 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1154 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
1159 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
1155
1160
1156 if showSNR:
1161 if showSNR:
1157 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1162 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1158 axes = self.axesList[i*self.plotFact + 1]
1163 axes = self.axesList[i*self.plotFact + 1]
1159 SNRdB1 = SNRdB[i,:].reshape((1,-1))
1164 SNRdB1 = SNRdB[i,:].reshape((1,-1))
1160 axes.pcolorbuffer(x, y, SNRdB1,
1165 axes.pcolorbuffer(x, y, SNRdB1,
1161 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1166 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1162 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1167 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1163 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1168 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1164
1169
1165 i=1
1170 i=1
1166 index = channelIndexList[i]
1171 index = channelIndexList[i]
1167 title = "Velocidad vertical Doppler [m/s]"
1172 title = "Velocidad vertical Doppler [m/s]"
1168 axes = self.axesList[i*self.plotFact]
1173 axes = self.axesList[i*self.plotFact]
1169 z1 = z[i,:].reshape((1,-1))
1174 z1 = z[i,:].reshape((1,-1))
1170 axes.pcolorbuffer(x, y, z1,
1175 axes.pcolorbuffer(x, y, z1,
1171 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=-10, zmax=10,
1176 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=-10, zmax=10,
1172 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1177 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1173 ticksize=9, cblabel='', cbsize="1%",colormap='seismic_r')
1178 ticksize=9, cblabel='', cbsize="1%",colormap='seismic_r')
1174
1179
1175 if showSNR:
1180 if showSNR:
1176 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1181 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1177 axes = self.axesList[i*self.plotFact + 1]
1182 axes = self.axesList[i*self.plotFact + 1]
1178 SNRdB1 = SNRdB[i,:].reshape((1,-1))
1183 SNRdB1 = SNRdB[i,:].reshape((1,-1))
1179 axes.pcolorbuffer(x, y, SNRdB1,
1184 axes.pcolorbuffer(x, y, SNRdB1,
1180 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1185 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1181 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1186 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1182 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1187 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1183
1188
1184 i=2
1189 i=2
1185 index = channelIndexList[i]
1190 index = channelIndexList[i]
1186 title = "Intensidad de lluvia [mm/h]"
1191 title = "Intensidad de lluvia [mm/h]"
1187 axes = self.axesList[i*self.plotFact]
1192 axes = self.axesList[i*self.plotFact]
1188 z1 = z[i,:].reshape((1,-1))
1193 z1 = z[i,:].reshape((1,-1))
1189 axes.pcolorbuffer(x, y, z1,
1194 axes.pcolorbuffer(x, y, z1,
1190 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=40,
1195 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=40,
1191 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1196 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1192 ticksize=9, cblabel='', cbsize="1%",colormap='ocean_r')
1197 ticksize=9, cblabel='', cbsize="1%",colormap='ocean_r')
1193
1198
1194 if showSNR:
1199 if showSNR:
1195 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1200 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1196 axes = self.axesList[i*self.plotFact + 1]
1201 axes = self.axesList[i*self.plotFact + 1]
1197 SNRdB1 = SNRdB[i,:].reshape((1,-1))
1202 SNRdB1 = SNRdB[i,:].reshape((1,-1))
1198 axes.pcolorbuffer(x, y, SNRdB1,
1203 axes.pcolorbuffer(x, y, SNRdB1,
1199 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1204 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1200 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1205 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1201 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1206 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
1202
1207
1203
1208
1204 self.draw()
1209 self.draw()
1205
1210
1206 if dataOut.ltctime >= self.xmax:
1211 if dataOut.ltctime >= self.xmax:
1207 self.counter_imagwr = wr_period
1212 self.counter_imagwr = wr_period
1208 self.isConfig = False
1213 self.isConfig = False
1209 update_figfile = True
1214 update_figfile = True
1210
1215
1211 self.save(figpath=figpath,
1216 self.save(figpath=figpath,
1212 figfile=figfile,
1217 figfile=figfile,
1213 save=save,
1218 save=save,
1214 ftp=ftp,
1219 ftp=ftp,
1215 wr_period=wr_period,
1220 wr_period=wr_period,
1216 thisDatetime=thisDatetime,
1221 thisDatetime=thisDatetime,
1217 update_figfile=update_figfile)
1222 update_figfile=update_figfile)
1218
1223
1219 return dataOut
1224 return dataOut
1220 @MPDecorator
1225 @MPDecorator
1221 class Parameters1Plot_(Figure):
1226 class Parameters1Plot_(Figure):
1222
1227
1223 __isConfig = None
1228 __isConfig = None
1224 __nsubplots = None
1229 __nsubplots = None
1225
1230
1226 WIDTHPROF = None
1231 WIDTHPROF = None
1227 HEIGHTPROF = None
1232 HEIGHTPROF = None
1228 PREFIX = 'prm'
1233 PREFIX = 'prm'
1229
1234
1230 def __init__(self):
1235 def __init__(self):
1231 Figure.__init__(self)
1236 Figure.__init__(self)
1232 self.timerange = 2*60*60
1237 self.timerange = 2*60*60
1233 self.isConfig = False
1238 self.isConfig = False
1234 self.__nsubplots = 1
1239 self.__nsubplots = 1
1235
1240
1236 self.WIDTH = 800
1241 self.WIDTH = 800
1237 self.HEIGHT = 180
1242 self.HEIGHT = 180
1238 self.WIDTHPROF = 120
1243 self.WIDTHPROF = 120
1239 self.HEIGHTPROF = 0
1244 self.HEIGHTPROF = 0
1240 self.counter_imagwr = 0
1245 self.counter_imagwr = 0
1241
1246
1242 self.PLOT_CODE = PARMS_CODE
1247 self.PLOT_CODE = PARMS_CODE
1243
1248
1244 self.FTP_WEI = None
1249 self.FTP_WEI = None
1245 self.EXP_CODE = None
1250 self.EXP_CODE = None
1246 self.SUB_EXP_CODE = None
1251 self.SUB_EXP_CODE = None
1247 self.PLOT_POS = None
1252 self.PLOT_POS = None
1248 self.tmin = None
1253 self.tmin = None
1249 self.tmax = None
1254 self.tmax = None
1250
1255
1251 self.xmin = None
1256 self.xmin = None
1252 self.xmax = None
1257 self.xmax = None
1253
1258
1254 self.figfile = None
1259 self.figfile = None
1255
1260
1256 def getSubplots(self):
1261 def getSubplots(self):
1257
1262
1258 ncol = 1
1263 ncol = 1
1259 nrow = self.nplots
1264 nrow = self.nplots
1260
1265
1261 return nrow, ncol
1266 return nrow, ncol
1262
1267
1263 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1268 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1264
1269
1265 self.__showprofile = showprofile
1270 self.__showprofile = showprofile
1266 self.nplots = nplots
1271 self.nplots = nplots
1267
1272
1268 ncolspan = 1
1273 ncolspan = 1
1269 colspan = 1
1274 colspan = 1
1270
1275
1271 self.createFigure(id = id,
1276 self.createFigure(id = id,
1272 wintitle = wintitle,
1277 wintitle = wintitle,
1273 widthplot = self.WIDTH + self.WIDTHPROF,
1278 widthplot = self.WIDTH + self.WIDTHPROF,
1274 heightplot = self.HEIGHT + self.HEIGHTPROF,
1279 heightplot = self.HEIGHT + self.HEIGHTPROF,
1275 show=show)
1280 show=show)
1276
1281
1277 nrow, ncol = self.getSubplots()
1282 nrow, ncol = self.getSubplots()
1278
1283
1279 counter = 0
1284 counter = 0
1280 for y in range(nrow):
1285 for y in range(nrow):
1281 for x in range(ncol):
1286 for x in range(ncol):
1282
1287
1283 if counter >= self.nplots:
1288 if counter >= self.nplots:
1284 break
1289 break
1285
1290
1286 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1291 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1287
1292
1288 if showprofile:
1293 if showprofile:
1289 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1294 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1290
1295
1291 counter += 1
1296 counter += 1
1292
1297
1293 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
1298 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
1294 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
1299 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
1295 parameterIndex = None, onlyPositive = False,
1300 parameterIndex = None, onlyPositive = False,
1296 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
1301 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
1297 DOP = True,
1302 DOP = True,
1298 zlabel = "", parameterName = "", parameterObject = "data_param",
1303 zlabel = "", parameterName = "", parameterObject = "data_param",
1299 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1304 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1300 server=None, folder=None, username=None, password=None,
1305 server=None, folder=None, username=None, password=None,
1301 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1306 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1302
1307
1303 """
1308 """
1304 Input:
1309 Input:
1305 dataOut :
1310 dataOut :
1306 id :
1311 id :
1307 wintitle :
1312 wintitle :
1308 channelList :
1313 channelList :
1309 showProfile :
1314 showProfile :
1310 xmin : None,
1315 xmin : None,
1311 xmax : None,
1316 xmax : None,
1312 ymin : None,
1317 ymin : None,
1313 ymax : None,
1318 ymax : None,
1314 zmin : None,
1319 zmin : None,
1315 zmax : None
1320 zmax : None
1316 """
1321 """
1317 if dataOut.flagNoData:
1322 if dataOut.flagNoData:
1318 return dataOut
1323 return dataOut
1319
1324
1320 data_param = getattr(dataOut, parameterObject)
1325 data_param = getattr(dataOut, parameterObject)
1321
1326
1322 if channelList == None:
1327 if channelList == None:
1323 channelIndexList = numpy.arange(data_param.shape[0])
1328 channelIndexList = numpy.arange(data_param.shape[0])
1324 else:
1329 else:
1325 channelIndexList = numpy.array(channelList)
1330 channelIndexList = numpy.array(channelList)
1326
1331
1327 nchan = len(channelIndexList) #Number of channels being plotted
1332 nchan = len(channelIndexList) #Number of channels being plotted
1328
1333
1329 if nchan < 1:
1334 if nchan < 1:
1330 return
1335 return
1331
1336
1332 nGraphsByChannel = 0
1337 nGraphsByChannel = 0
1333
1338
1334 if SNR:
1339 if SNR:
1335 nGraphsByChannel += 1
1340 nGraphsByChannel += 1
1336 if DOP:
1341 if DOP:
1337 nGraphsByChannel += 1
1342 nGraphsByChannel += 1
1338
1343
1339 if nGraphsByChannel < 1:
1344 if nGraphsByChannel < 1:
1340 return
1345 return
1341
1346
1342 nplots = nGraphsByChannel*nchan
1347 nplots = nGraphsByChannel*nchan
1343
1348
1344 if timerange is not None:
1349 if timerange is not None:
1345 self.timerange = timerange
1350 self.timerange = timerange
1346
1351
1347 #tmin = None
1352 #tmin = None
1348 #tmax = None
1353 #tmax = None
1349 if parameterIndex == None:
1354 if parameterIndex == None:
1350 parameterIndex = 1
1355 parameterIndex = 1
1351
1356
1352 x = dataOut.getTimeRange1(dataOut.paramInterval)
1357 x = dataOut.getTimeRange1(dataOut.paramInterval)
1353 y = dataOut.heightList
1358 y = dataOut.heightList
1354
1359
1355 if dataOut.data_param.ndim == 3:
1360 if dataOut.data_param.ndim == 3:
1356 z = dataOut.data_param[channelIndexList,parameterIndex,:]
1361 z = dataOut.data_param[channelIndexList,parameterIndex,:]
1357 else:
1362 else:
1358 z = dataOut.data_param[channelIndexList,:]
1363 z = dataOut.data_param[channelIndexList,:]
1359
1364
1360 if dataOut.data_SNR is not None:
1365 if dataOut.data_SNR is not None:
1361 if dataOut.data_SNR.ndim == 2:
1366 if dataOut.data_SNR.ndim == 2:
1362 SNRavg = numpy.average(dataOut.data_SNR, axis=0)
1367 SNRavg = numpy.average(dataOut.data_SNR, axis=0)
1363 else:
1368 else:
1364 SNRavg = dataOut.data_SNR
1369 SNRavg = dataOut.data_SNR
1365 SNRdB = 10*numpy.log10(SNRavg)
1370 SNRdB = 10*numpy.log10(SNRavg)
1366
1371
1367 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1372 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1368 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1373 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1369 xlabel = ""
1374 xlabel = ""
1370 ylabel = "Range (Km)"
1375 ylabel = "Range (Km)"
1371
1376
1372 if onlyPositive:
1377 if onlyPositive:
1373 colormap = "jet"
1378 colormap = "jet"
1374 zmin = 0
1379 zmin = 0
1375 else: colormap = "RdBu_r"
1380 else: colormap = "RdBu_r"
1376
1381
1377 if not self.isConfig:
1382 if not self.isConfig:
1378
1383
1379 self.setup(id=id,
1384 self.setup(id=id,
1380 nplots=nplots,
1385 nplots=nplots,
1381 wintitle=wintitle,
1386 wintitle=wintitle,
1382 showprofile=showprofile,
1387 showprofile=showprofile,
1383 show=show)
1388 show=show)
1384
1389
1385 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1390 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1386
1391
1387 if ymin == None: ymin = numpy.nanmin(y)
1392 if ymin == None: ymin = numpy.nanmin(y)
1388 if ymax == None: ymax = numpy.nanmax(y)
1393 if ymax == None: ymax = numpy.nanmax(y)
1389 if zmin == None: zmin = numpy.nanmin(z)
1394 if zmin == None: zmin = numpy.nanmin(z)
1390 if zmax == None: zmax = numpy.nanmax(z)
1395 if zmax == None: zmax = numpy.nanmax(z)
1391
1396
1392 if SNR:
1397 if SNR:
1393 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1398 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
1394 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1399 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
1395
1400
1396 self.FTP_WEI = ftp_wei
1401 self.FTP_WEI = ftp_wei
1397 self.EXP_CODE = exp_code
1402 self.EXP_CODE = exp_code
1398 self.SUB_EXP_CODE = sub_exp_code
1403 self.SUB_EXP_CODE = sub_exp_code
1399 self.PLOT_POS = plot_pos
1404 self.PLOT_POS = plot_pos
1400
1405
1401 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1406 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1402 self.isConfig = True
1407 self.isConfig = True
1403 self.figfile = figfile
1408 self.figfile = figfile
1404
1409
1405 self.setWinTitle(title)
1410 self.setWinTitle(title)
1406
1411
1407 if ((self.xmax - x[1]) < (x[1]-x[0])):
1412 if ((self.xmax - x[1]) < (x[1]-x[0])):
1408 x[1] = self.xmax
1413 x[1] = self.xmax
1409
1414
1410 for i in range(nchan):
1415 for i in range(nchan):
1411
1416
1412 if (SNR and not onlySNR): j = 2*i
1417 if (SNR and not onlySNR): j = 2*i
1413 else: j = i
1418 else: j = i
1414
1419
1415 j = nGraphsByChannel*i
1420 j = nGraphsByChannel*i
1416
1421
1417 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1422 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1418 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1423 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1419
1424
1420 if not onlySNR:
1425 if not onlySNR:
1421 axes = self.axesList[j*self.__nsubplots]
1426 axes = self.axesList[j*self.__nsubplots]
1422 z1 = z[i,:].reshape((1,-1))
1427 z1 = z[i,:].reshape((1,-1))
1423 axes.pcolorbuffer(x, y, z1,
1428 axes.pcolorbuffer(x, y, z1,
1424 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1429 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1425 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1430 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1426 ticksize=9, cblabel=zlabel, cbsize="1%")
1431 ticksize=9, cblabel=zlabel, cbsize="1%")
1427
1432
1428 if DOP:
1433 if DOP:
1429 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1434 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1430
1435
1431 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1436 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1432 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1437 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
1433 axes = self.axesList[j]
1438 axes = self.axesList[j]
1434 z1 = z[i,:].reshape((1,-1))
1439 z1 = z[i,:].reshape((1,-1))
1435 axes.pcolorbuffer(x, y, z1,
1440 axes.pcolorbuffer(x, y, z1,
1436 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1441 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
1437 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1442 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
1438 ticksize=9, cblabel=zlabel, cbsize="1%")
1443 ticksize=9, cblabel=zlabel, cbsize="1%")
1439
1444
1440 if SNR:
1445 if SNR:
1441 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1446 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1442 axes = self.axesList[(j)*self.__nsubplots]
1447 axes = self.axesList[(j)*self.__nsubplots]
1443 if not onlySNR:
1448 if not onlySNR:
1444 axes = self.axesList[(j + 1)*self.__nsubplots]
1449 axes = self.axesList[(j + 1)*self.__nsubplots]
1445
1450
1446 axes = self.axesList[(j + nGraphsByChannel-1)]
1451 axes = self.axesList[(j + nGraphsByChannel-1)]
1447 z1 = SNRdB.reshape((1,-1))
1452 z1 = SNRdB.reshape((1,-1))
1448 axes.pcolorbuffer(x, y, z1,
1453 axes.pcolorbuffer(x, y, z1,
1449 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1454 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1450 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1455 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1451 ticksize=9, cblabel=zlabel, cbsize="1%")
1456 ticksize=9, cblabel=zlabel, cbsize="1%")
1452
1457
1453
1458
1454
1459
1455 self.draw()
1460 self.draw()
1456
1461
1457 if x[1] >= self.axesList[0].xmax:
1462 if x[1] >= self.axesList[0].xmax:
1458 self.counter_imagwr = wr_period
1463 self.counter_imagwr = wr_period
1459 self.isConfig = False
1464 self.isConfig = False
1460 self.figfile = None
1465 self.figfile = None
1461
1466
1462 self.save(figpath=figpath,
1467 self.save(figpath=figpath,
1463 figfile=figfile,
1468 figfile=figfile,
1464 save=save,
1469 save=save,
1465 ftp=ftp,
1470 ftp=ftp,
1466 wr_period=wr_period,
1471 wr_period=wr_period,
1467 thisDatetime=thisDatetime,
1472 thisDatetime=thisDatetime,
1468 update_figfile=False)
1473 update_figfile=False)
1469 return dataOut
1474 return dataOut
1470
1475
1471 class SpectralFittingPlot_(Figure):
1476 class SpectralFittingPlot_(Figure):
1472
1477
1473 __isConfig = None
1478 __isConfig = None
1474 __nsubplots = None
1479 __nsubplots = None
1475
1480
1476 WIDTHPROF = None
1481 WIDTHPROF = None
1477 HEIGHTPROF = None
1482 HEIGHTPROF = None
1478 PREFIX = 'prm'
1483 PREFIX = 'prm'
1479
1484
1480
1485
1481 N = None
1486 N = None
1482 ippSeconds = None
1487 ippSeconds = None
1483
1488
1484 def __init__(self, **kwargs):
1489 def __init__(self, **kwargs):
1485 Figure.__init__(self, **kwargs)
1490 Figure.__init__(self, **kwargs)
1486 self.isConfig = False
1491 self.isConfig = False
1487 self.__nsubplots = 1
1492 self.__nsubplots = 1
1488
1493
1489 self.PLOT_CODE = SPECFIT_CODE
1494 self.PLOT_CODE = SPECFIT_CODE
1490
1495
1491 self.WIDTH = 450
1496 self.WIDTH = 450
1492 self.HEIGHT = 250
1497 self.HEIGHT = 250
1493 self.WIDTHPROF = 0
1498 self.WIDTHPROF = 0
1494 self.HEIGHTPROF = 0
1499 self.HEIGHTPROF = 0
1495
1500
1496 def getSubplots(self):
1501 def getSubplots(self):
1497
1502
1498 ncol = int(numpy.sqrt(self.nplots)+0.9)
1503 ncol = int(numpy.sqrt(self.nplots)+0.9)
1499 nrow = int(self.nplots*1./ncol + 0.9)
1504 nrow = int(self.nplots*1./ncol + 0.9)
1500
1505
1501 return nrow, ncol
1506 return nrow, ncol
1502
1507
1503 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1508 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1504
1509
1505 showprofile = False
1510 showprofile = False
1506 self.__showprofile = showprofile
1511 self.__showprofile = showprofile
1507 self.nplots = nplots
1512 self.nplots = nplots
1508
1513
1509 ncolspan = 5
1514 ncolspan = 5
1510 colspan = 4
1515 colspan = 4
1511 if showprofile:
1516 if showprofile:
1512 ncolspan = 5
1517 ncolspan = 5
1513 colspan = 4
1518 colspan = 4
1514 self.__nsubplots = 2
1519 self.__nsubplots = 2
1515
1520
1516 self.createFigure(id = id,
1521 self.createFigure(id = id,
1517 wintitle = wintitle,
1522 wintitle = wintitle,
1518 widthplot = self.WIDTH + self.WIDTHPROF,
1523 widthplot = self.WIDTH + self.WIDTHPROF,
1519 heightplot = self.HEIGHT + self.HEIGHTPROF,
1524 heightplot = self.HEIGHT + self.HEIGHTPROF,
1520 show=show)
1525 show=show)
1521
1526
1522 nrow, ncol = self.getSubplots()
1527 nrow, ncol = self.getSubplots()
1523
1528
1524 counter = 0
1529 counter = 0
1525 for y in range(nrow):
1530 for y in range(nrow):
1526 for x in range(ncol):
1531 for x in range(ncol):
1527
1532
1528 if counter >= self.nplots:
1533 if counter >= self.nplots:
1529 break
1534 break
1530
1535
1531 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1536 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1532
1537
1533 if showprofile:
1538 if showprofile:
1534 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1539 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1535
1540
1536 counter += 1
1541 counter += 1
1537
1542
1538 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1543 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1539 xmin=None, xmax=None, ymin=None, ymax=None,
1544 xmin=None, xmax=None, ymin=None, ymax=None,
1540 save=False, figpath='./', figfile=None, show=True):
1545 save=False, figpath='./', figfile=None, show=True):
1541
1546
1542 """
1547 """
1543
1548
1544 Input:
1549 Input:
1545 dataOut :
1550 dataOut :
1546 id :
1551 id :
1547 wintitle :
1552 wintitle :
1548 channelList :
1553 channelList :
1549 showProfile :
1554 showProfile :
1550 xmin : None,
1555 xmin : None,
1551 xmax : None,
1556 xmax : None,
1552 zmin : None,
1557 zmin : None,
1553 zmax : None
1558 zmax : None
1554 """
1559 """
1555
1560
1556 if cutHeight==None:
1561 if cutHeight==None:
1557 h=270
1562 h=270
1558 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1563 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1559 cutHeight = dataOut.heightList[heightindex]
1564 cutHeight = dataOut.heightList[heightindex]
1560
1565
1561 factor = dataOut.normFactor
1566 factor = dataOut.normFactor
1562 x = dataOut.abscissaList[:-1]
1567 x = dataOut.abscissaList[:-1]
1563 #y = dataOut.getHeiRange()
1568 #y = dataOut.getHeiRange()
1564
1569
1565 z = dataOut.data_pre[:,:,heightindex]/factor
1570 z = dataOut.data_pre[:,:,heightindex]/factor
1566 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1571 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1567 avg = numpy.average(z, axis=1)
1572 avg = numpy.average(z, axis=1)
1568 listChannels = z.shape[0]
1573 listChannels = z.shape[0]
1569
1574
1570 #Reconstruct Function
1575 #Reconstruct Function
1571 if fit==True:
1576 if fit==True:
1572 groupArray = dataOut.groupList
1577 groupArray = dataOut.groupList
1573 listChannels = groupArray.reshape((groupArray.size))
1578 listChannels = groupArray.reshape((groupArray.size))
1574 listChannels.sort()
1579 listChannels.sort()
1575 spcFitLine = numpy.zeros(z.shape)
1580 spcFitLine = numpy.zeros(z.shape)
1576 constants = dataOut.constants
1581 constants = dataOut.constants
1577
1582
1578 nGroups = groupArray.shape[0]
1583 nGroups = groupArray.shape[0]
1579 nChannels = groupArray.shape[1]
1584 nChannels = groupArray.shape[1]
1580 nProfiles = z.shape[1]
1585 nProfiles = z.shape[1]
1581
1586
1582 for f in range(nGroups):
1587 for f in range(nGroups):
1583 groupChann = groupArray[f,:]
1588 groupChann = groupArray[f,:]
1584 p = dataOut.data_param[f,:,heightindex]
1589 p = dataOut.data_param[f,:,heightindex]
1585 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1590 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1586 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1591 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1587 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1592 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1588 spcFitLine[groupChann,:] = fitLineAux
1593 spcFitLine[groupChann,:] = fitLineAux
1589 # spcFitLine = spcFitLine/factor
1594 # spcFitLine = spcFitLine/factor
1590
1595
1591 z = z[listChannels,:]
1596 z = z[listChannels,:]
1592 spcFitLine = spcFitLine[listChannels,:]
1597 spcFitLine = spcFitLine[listChannels,:]
1593 spcFitLinedB = 10*numpy.log10(spcFitLine)
1598 spcFitLinedB = 10*numpy.log10(spcFitLine)
1594
1599
1595 zdB = 10*numpy.log10(z)
1600 zdB = 10*numpy.log10(z)
1596 #thisDatetime = dataOut.datatime
1601 #thisDatetime = dataOut.datatime
1597 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1602 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1598 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1603 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1599 xlabel = "Velocity (m/s)"
1604 xlabel = "Velocity (m/s)"
1600 ylabel = "Spectrum"
1605 ylabel = "Spectrum"
1601
1606
1602 if not self.isConfig:
1607 if not self.isConfig:
1603
1608
1604 nplots = listChannels.size
1609 nplots = listChannels.size
1605
1610
1606 self.setup(id=id,
1611 self.setup(id=id,
1607 nplots=nplots,
1612 nplots=nplots,
1608 wintitle=wintitle,
1613 wintitle=wintitle,
1609 showprofile=showprofile,
1614 showprofile=showprofile,
1610 show=show)
1615 show=show)
1611
1616
1612 if xmin == None: xmin = numpy.nanmin(x)
1617 if xmin == None: xmin = numpy.nanmin(x)
1613 if xmax == None: xmax = numpy.nanmax(x)
1618 if xmax == None: xmax = numpy.nanmax(x)
1614 if ymin == None: ymin = numpy.nanmin(zdB)
1619 if ymin == None: ymin = numpy.nanmin(zdB)
1615 if ymax == None: ymax = numpy.nanmax(zdB)+2
1620 if ymax == None: ymax = numpy.nanmax(zdB)+2
1616
1621
1617 self.isConfig = True
1622 self.isConfig = True
1618
1623
1619 self.setWinTitle(title)
1624 self.setWinTitle(title)
1620 for i in range(self.nplots):
1625 for i in range(self.nplots):
1621 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1626 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1622 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1627 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1623 axes = self.axesList[i*self.__nsubplots]
1628 axes = self.axesList[i*self.__nsubplots]
1624 if fit == False:
1629 if fit == False:
1625 axes.pline(x, zdB[i,:],
1630 axes.pline(x, zdB[i,:],
1626 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1631 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1627 xlabel=xlabel, ylabel=ylabel, title=title
1632 xlabel=xlabel, ylabel=ylabel, title=title
1628 )
1633 )
1629 if fit == True:
1634 if fit == True:
1630 fitline=spcFitLinedB[i,:]
1635 fitline=spcFitLinedB[i,:]
1631 y=numpy.vstack([zdB[i,:],fitline] )
1636 y=numpy.vstack([zdB[i,:],fitline] )
1632 legendlabels=['Data','Fitting']
1637 legendlabels=['Data','Fitting']
1633 axes.pmultilineyaxis(x, y,
1638 axes.pmultilineyaxis(x, y,
1634 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1639 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1635 xlabel=xlabel, ylabel=ylabel, title=title,
1640 xlabel=xlabel, ylabel=ylabel, title=title,
1636 legendlabels=legendlabels, marker=None,
1641 legendlabels=legendlabels, marker=None,
1637 linestyle='solid', grid='both')
1642 linestyle='solid', grid='both')
1638
1643
1639 self.draw()
1644 self.draw()
1640
1645
1641 self.save(figpath=figpath,
1646 self.save(figpath=figpath,
1642 figfile=figfile,
1647 figfile=figfile,
1643 save=save,
1648 save=save,
1644 ftp=ftp,
1649 ftp=ftp,
1645 wr_period=wr_period,
1650 wr_period=wr_period,
1646 thisDatetime=thisDatetime)
1651 thisDatetime=thisDatetime)
1647
1652
1648
1653
1649 class EWDriftsPlot_(Figure):
1654 class EWDriftsPlot_(Figure):
1650
1655
1651 __isConfig = None
1656 __isConfig = None
1652 __nsubplots = None
1657 __nsubplots = None
1653
1658
1654 WIDTHPROF = None
1659 WIDTHPROF = None
1655 HEIGHTPROF = None
1660 HEIGHTPROF = None
1656 PREFIX = 'drift'
1661 PREFIX = 'drift'
1657
1662
1658 def __init__(self, **kwargs):
1663 def __init__(self, **kwargs):
1659 Figure.__init__(self, **kwargs)
1664 Figure.__init__(self, **kwargs)
1660 self.timerange = 2*60*60
1665 self.timerange = 2*60*60
1661 self.isConfig = False
1666 self.isConfig = False
1662 self.__nsubplots = 1
1667 self.__nsubplots = 1
1663
1668
1664 self.WIDTH = 800
1669 self.WIDTH = 800
1665 self.HEIGHT = 150
1670 self.HEIGHT = 150
1666 self.WIDTHPROF = 120
1671 self.WIDTHPROF = 120
1667 self.HEIGHTPROF = 0
1672 self.HEIGHTPROF = 0
1668 self.counter_imagwr = 0
1673 self.counter_imagwr = 0
1669
1674
1670 self.PLOT_CODE = EWDRIFT_CODE
1675 self.PLOT_CODE = EWDRIFT_CODE
1671
1676
1672 self.FTP_WEI = None
1677 self.FTP_WEI = None
1673 self.EXP_CODE = None
1678 self.EXP_CODE = None
1674 self.SUB_EXP_CODE = None
1679 self.SUB_EXP_CODE = None
1675 self.PLOT_POS = None
1680 self.PLOT_POS = None
1676 self.tmin = None
1681 self.tmin = None
1677 self.tmax = None
1682 self.tmax = None
1678
1683
1679 self.xmin = None
1684 self.xmin = None
1680 self.xmax = None
1685 self.xmax = None
1681
1686
1682 self.figfile = None
1687 self.figfile = None
1683
1688
1684 def getSubplots(self):
1689 def getSubplots(self):
1685
1690
1686 ncol = 1
1691 ncol = 1
1687 nrow = self.nplots
1692 nrow = self.nplots
1688
1693
1689 return nrow, ncol
1694 return nrow, ncol
1690
1695
1691 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1696 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1692
1697
1693 self.__showprofile = showprofile
1698 self.__showprofile = showprofile
1694 self.nplots = nplots
1699 self.nplots = nplots
1695
1700
1696 ncolspan = 1
1701 ncolspan = 1
1697 colspan = 1
1702 colspan = 1
1698
1703
1699 self.createFigure(id = id,
1704 self.createFigure(id = id,
1700 wintitle = wintitle,
1705 wintitle = wintitle,
1701 widthplot = self.WIDTH + self.WIDTHPROF,
1706 widthplot = self.WIDTH + self.WIDTHPROF,
1702 heightplot = self.HEIGHT + self.HEIGHTPROF,
1707 heightplot = self.HEIGHT + self.HEIGHTPROF,
1703 show=show)
1708 show=show)
1704
1709
1705 nrow, ncol = self.getSubplots()
1710 nrow, ncol = self.getSubplots()
1706
1711
1707 counter = 0
1712 counter = 0
1708 for y in range(nrow):
1713 for y in range(nrow):
1709 if counter >= self.nplots:
1714 if counter >= self.nplots:
1710 break
1715 break
1711
1716
1712 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1717 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1713 counter += 1
1718 counter += 1
1714
1719
1715 def run(self, dataOut, id, wintitle="", channelList=None,
1720 def run(self, dataOut, id, wintitle="", channelList=None,
1716 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1721 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1717 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1722 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1718 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1723 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1719 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1724 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1720 server=None, folder=None, username=None, password=None,
1725 server=None, folder=None, username=None, password=None,
1721 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1726 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1722 """
1727 """
1723
1728
1724 Input:
1729 Input:
1725 dataOut :
1730 dataOut :
1726 id :
1731 id :
1727 wintitle :
1732 wintitle :
1728 channelList :
1733 channelList :
1729 showProfile :
1734 showProfile :
1730 xmin : None,
1735 xmin : None,
1731 xmax : None,
1736 xmax : None,
1732 ymin : None,
1737 ymin : None,
1733 ymax : None,
1738 ymax : None,
1734 zmin : None,
1739 zmin : None,
1735 zmax : None
1740 zmax : None
1736 """
1741 """
1737
1742
1738 if timerange is not None:
1743 if timerange is not None:
1739 self.timerange = timerange
1744 self.timerange = timerange
1740
1745
1741 tmin = None
1746 tmin = None
1742 tmax = None
1747 tmax = None
1743
1748
1744 x = dataOut.getTimeRange1(dataOut.outputInterval)
1749 x = dataOut.getTimeRange1(dataOut.outputInterval)
1745 # y = dataOut.heightList
1750 # y = dataOut.heightList
1746 y = dataOut.heightList
1751 y = dataOut.heightList
1747
1752
1748 z = dataOut.data_output
1753 z = dataOut.data_output
1749 nplots = z.shape[0] #Number of wind dimensions estimated
1754 nplots = z.shape[0] #Number of wind dimensions estimated
1750 nplotsw = nplots
1755 nplotsw = nplots
1751
1756
1752 #If there is a SNR function defined
1757 #If there is a SNR function defined
1753 if dataOut.data_SNR is not None:
1758 if dataOut.data_SNR is not None:
1754 nplots += 1
1759 nplots += 1
1755 SNR = dataOut.data_SNR
1760 SNR = dataOut.data_SNR
1756
1761
1757 if SNR_1:
1762 if SNR_1:
1758 SNR += 1
1763 SNR += 1
1759
1764
1760 SNRavg = numpy.average(SNR, axis=0)
1765 SNRavg = numpy.average(SNR, axis=0)
1761
1766
1762 SNRdB = 10*numpy.log10(SNR)
1767 SNRdB = 10*numpy.log10(SNR)
1763 SNRavgdB = 10*numpy.log10(SNRavg)
1768 SNRavgdB = 10*numpy.log10(SNRavg)
1764
1769
1765 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1770 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1766
1771
1767 for i in range(nplotsw):
1772 for i in range(nplotsw):
1768 z[i,ind] = numpy.nan
1773 z[i,ind] = numpy.nan
1769
1774
1770
1775
1771 showprofile = False
1776 showprofile = False
1772 # thisDatetime = dataOut.datatime
1777 # thisDatetime = dataOut.datatime
1773 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1778 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1774 title = wintitle + " EW Drifts"
1779 title = wintitle + " EW Drifts"
1775 xlabel = ""
1780 xlabel = ""
1776 ylabel = "Height (Km)"
1781 ylabel = "Height (Km)"
1777
1782
1778 if not self.isConfig:
1783 if not self.isConfig:
1779
1784
1780 self.setup(id=id,
1785 self.setup(id=id,
1781 nplots=nplots,
1786 nplots=nplots,
1782 wintitle=wintitle,
1787 wintitle=wintitle,
1783 showprofile=showprofile,
1788 showprofile=showprofile,
1784 show=show)
1789 show=show)
1785
1790
1786 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1791 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1787
1792
1788 if ymin == None: ymin = numpy.nanmin(y)
1793 if ymin == None: ymin = numpy.nanmin(y)
1789 if ymax == None: ymax = numpy.nanmax(y)
1794 if ymax == None: ymax = numpy.nanmax(y)
1790
1795
1791 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1796 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1792 if zminZonal == None: zminZonal = -zmaxZonal
1797 if zminZonal == None: zminZonal = -zmaxZonal
1793 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1798 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1794 if zminVertical == None: zminVertical = -zmaxVertical
1799 if zminVertical == None: zminVertical = -zmaxVertical
1795
1800
1796 if dataOut.data_SNR is not None:
1801 if dataOut.data_SNR is not None:
1797 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1802 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1798 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1803 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1799
1804
1800 self.FTP_WEI = ftp_wei
1805 self.FTP_WEI = ftp_wei
1801 self.EXP_CODE = exp_code
1806 self.EXP_CODE = exp_code
1802 self.SUB_EXP_CODE = sub_exp_code
1807 self.SUB_EXP_CODE = sub_exp_code
1803 self.PLOT_POS = plot_pos
1808 self.PLOT_POS = plot_pos
1804
1809
1805 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1810 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1806 self.isConfig = True
1811 self.isConfig = True
1807
1812
1808
1813
1809 self.setWinTitle(title)
1814 self.setWinTitle(title)
1810
1815
1811 if ((self.xmax - x[1]) < (x[1]-x[0])):
1816 if ((self.xmax - x[1]) < (x[1]-x[0])):
1812 x[1] = self.xmax
1817 x[1] = self.xmax
1813
1818
1814 strWind = ['Zonal','Vertical']
1819 strWind = ['Zonal','Vertical']
1815 strCb = 'Velocity (m/s)'
1820 strCb = 'Velocity (m/s)'
1816 zmaxVector = [zmaxZonal, zmaxVertical]
1821 zmaxVector = [zmaxZonal, zmaxVertical]
1817 zminVector = [zminZonal, zminVertical]
1822 zminVector = [zminZonal, zminVertical]
1818
1823
1819 for i in range(nplotsw):
1824 for i in range(nplotsw):
1820
1825
1821 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1826 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1822 axes = self.axesList[i*self.__nsubplots]
1827 axes = self.axesList[i*self.__nsubplots]
1823
1828
1824 z1 = z[i,:].reshape((1,-1))
1829 z1 = z[i,:].reshape((1,-1))
1825
1830
1826 axes.pcolorbuffer(x, y, z1,
1831 axes.pcolorbuffer(x, y, z1,
1827 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1832 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1828 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1833 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1829 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1834 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1830
1835
1831 if dataOut.data_SNR is not None:
1836 if dataOut.data_SNR is not None:
1832 i += 1
1837 i += 1
1833 if SNR_1:
1838 if SNR_1:
1834 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1839 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1835 else:
1840 else:
1836 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1841 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1837 axes = self.axesList[i*self.__nsubplots]
1842 axes = self.axesList[i*self.__nsubplots]
1838 SNRavgdB = SNRavgdB.reshape((1,-1))
1843 SNRavgdB = SNRavgdB.reshape((1,-1))
1839
1844
1840 axes.pcolorbuffer(x, y, SNRavgdB,
1845 axes.pcolorbuffer(x, y, SNRavgdB,
1841 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1846 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1842 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1847 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1843 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1848 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1844
1849
1845 self.draw()
1850 self.draw()
1846
1851
1847 if x[1] >= self.axesList[0].xmax:
1852 if x[1] >= self.axesList[0].xmax:
1848 self.counter_imagwr = wr_period
1853 self.counter_imagwr = wr_period
1849 self.isConfig = False
1854 self.isConfig = False
1850 self.figfile = None
1855 self.figfile = None
1851
1856
1852
1857
1853
1858
1854
1859
1855 class PhasePlot_(Figure):
1860 class PhasePlot_(Figure):
1856
1861
1857 __isConfig = None
1862 __isConfig = None
1858 __nsubplots = None
1863 __nsubplots = None
1859
1864
1860 PREFIX = 'mphase'
1865 PREFIX = 'mphase'
1861
1866
1862
1867
1863 def __init__(self, **kwargs):
1868 def __init__(self, **kwargs):
1864 Figure.__init__(self, **kwargs)
1869 Figure.__init__(self, **kwargs)
1865 self.timerange = 24*60*60
1870 self.timerange = 24*60*60
1866 self.isConfig = False
1871 self.isConfig = False
1867 self.__nsubplots = 1
1872 self.__nsubplots = 1
1868 self.counter_imagwr = 0
1873 self.counter_imagwr = 0
1869 self.WIDTH = 600
1874 self.WIDTH = 600
1870 self.HEIGHT = 300
1875 self.HEIGHT = 300
1871 self.WIDTHPROF = 120
1876 self.WIDTHPROF = 120
1872 self.HEIGHTPROF = 0
1877 self.HEIGHTPROF = 0
1873 self.xdata = None
1878 self.xdata = None
1874 self.ydata = None
1879 self.ydata = None
1875
1880
1876 self.PLOT_CODE = MPHASE_CODE
1881 self.PLOT_CODE = MPHASE_CODE
1877
1882
1878 self.FTP_WEI = None
1883 self.FTP_WEI = None
1879 self.EXP_CODE = None
1884 self.EXP_CODE = None
1880 self.SUB_EXP_CODE = None
1885 self.SUB_EXP_CODE = None
1881 self.PLOT_POS = None
1886 self.PLOT_POS = None
1882
1887
1883
1888
1884 self.filename_phase = None
1889 self.filename_phase = None
1885
1890
1886 self.figfile = None
1891 self.figfile = None
1887
1892
1888 def getSubplots(self):
1893 def getSubplots(self):
1889
1894
1890 ncol = 1
1895 ncol = 1
1891 nrow = 1
1896 nrow = 1
1892
1897
1893 return nrow, ncol
1898 return nrow, ncol
1894
1899
1895 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1900 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1896
1901
1897 self.__showprofile = showprofile
1902 self.__showprofile = showprofile
1898 self.nplots = nplots
1903 self.nplots = nplots
1899
1904
1900 ncolspan = 7
1905 ncolspan = 7
1901 colspan = 6
1906 colspan = 6
1902 self.__nsubplots = 2
1907 self.__nsubplots = 2
1903
1908
1904 self.createFigure(id = id,
1909 self.createFigure(id = id,
1905 wintitle = wintitle,
1910 wintitle = wintitle,
1906 widthplot = self.WIDTH+self.WIDTHPROF,
1911 widthplot = self.WIDTH+self.WIDTHPROF,
1907 heightplot = self.HEIGHT+self.HEIGHTPROF,
1912 heightplot = self.HEIGHT+self.HEIGHTPROF,
1908 show=show)
1913 show=show)
1909
1914
1910 nrow, ncol = self.getSubplots()
1915 nrow, ncol = self.getSubplots()
1911
1916
1912 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1917 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1913
1918
1914
1919
1915 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1920 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1916 xmin=None, xmax=None, ymin=None, ymax=None,
1921 xmin=None, xmax=None, ymin=None, ymax=None,
1917 timerange=None,
1922 timerange=None,
1918 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1923 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1919 server=None, folder=None, username=None, password=None,
1924 server=None, folder=None, username=None, password=None,
1920 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1925 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1921
1926
1922
1927
1923 tmin = None
1928 tmin = None
1924 tmax = None
1929 tmax = None
1925 x = dataOut.getTimeRange1(dataOut.outputInterval)
1930 x = dataOut.getTimeRange1(dataOut.outputInterval)
1926 y = dataOut.getHeiRange()
1931 y = dataOut.getHeiRange()
1927
1932
1928
1933
1929 #thisDatetime = dataOut.datatime
1934 #thisDatetime = dataOut.datatime
1930 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1935 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1931 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1936 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1932 xlabel = "Local Time"
1937 xlabel = "Local Time"
1933 ylabel = "Phase"
1938 ylabel = "Phase"
1934
1939
1935
1940
1936 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1941 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1937 phase_beacon = dataOut.data_output
1942 phase_beacon = dataOut.data_output
1938 update_figfile = False
1943 update_figfile = False
1939
1944
1940 if not self.isConfig:
1945 if not self.isConfig:
1941
1946
1942 self.nplots = phase_beacon.size
1947 self.nplots = phase_beacon.size
1943
1948
1944 self.setup(id=id,
1949 self.setup(id=id,
1945 nplots=self.nplots,
1950 nplots=self.nplots,
1946 wintitle=wintitle,
1951 wintitle=wintitle,
1947 showprofile=showprofile,
1952 showprofile=showprofile,
1948 show=show)
1953 show=show)
1949
1954
1950 if timerange is not None:
1955 if timerange is not None:
1951 self.timerange = timerange
1956 self.timerange = timerange
1952
1957
1953 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1958 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1954
1959
1955 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1960 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1956 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1961 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1957
1962
1958 self.FTP_WEI = ftp_wei
1963 self.FTP_WEI = ftp_wei
1959 self.EXP_CODE = exp_code
1964 self.EXP_CODE = exp_code
1960 self.SUB_EXP_CODE = sub_exp_code
1965 self.SUB_EXP_CODE = sub_exp_code
1961 self.PLOT_POS = plot_pos
1966 self.PLOT_POS = plot_pos
1962
1967
1963 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1968 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1964 self.isConfig = True
1969 self.isConfig = True
1965 self.figfile = figfile
1970 self.figfile = figfile
1966 self.xdata = numpy.array([])
1971 self.xdata = numpy.array([])
1967 self.ydata = numpy.array([])
1972 self.ydata = numpy.array([])
1968
1973
1969 #open file beacon phase
1974 #open file beacon phase
1970 path = '%s%03d' %(self.PREFIX, self.id)
1975 path = '%s%03d' %(self.PREFIX, self.id)
1971 beacon_file = os.path.join(path,'%s.txt'%self.name)
1976 beacon_file = os.path.join(path,'%s.txt'%self.name)
1972 self.filename_phase = os.path.join(figpath,beacon_file)
1977 self.filename_phase = os.path.join(figpath,beacon_file)
1973 update_figfile = True
1978 update_figfile = True
1974
1979
1975
1980
1976 #store data beacon phase
1981 #store data beacon phase
1977 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1982 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1978
1983
1979 self.setWinTitle(title)
1984 self.setWinTitle(title)
1980
1985
1981
1986
1982 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1987 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1983
1988
1984 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1989 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1985
1990
1986 axes = self.axesList[0]
1991 axes = self.axesList[0]
1987
1992
1988 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1993 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1989
1994
1990 if len(self.ydata)==0:
1995 if len(self.ydata)==0:
1991 self.ydata = phase_beacon.reshape(-1,1)
1996 self.ydata = phase_beacon.reshape(-1,1)
1992 else:
1997 else:
1993 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1998 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1994
1999
1995
2000
1996 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
2001 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1997 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
2002 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1998 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
2003 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1999 XAxisAsTime=True, grid='both'
2004 XAxisAsTime=True, grid='both'
2000 )
2005 )
2001
2006
2002 self.draw()
2007 self.draw()
2003
2008
2004 self.save(figpath=figpath,
2009 self.save(figpath=figpath,
2005 figfile=figfile,
2010 figfile=figfile,
2006 save=save,
2011 save=save,
2007 ftp=ftp,
2012 ftp=ftp,
2008 wr_period=wr_period,
2013 wr_period=wr_period,
2009 thisDatetime=thisDatetime,
2014 thisDatetime=thisDatetime,
2010 update_figfile=update_figfile)
2015 update_figfile=update_figfile)
2011
2016
2012 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
2017 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
2013 self.counter_imagwr = wr_period
2018 self.counter_imagwr = wr_period
2014 self.isConfig = False
2019 self.isConfig = False
2015 update_figfile = True
2020 update_figfile = True
2016
2021
2017
2022
2018
2023
2019 class NSMeteorDetection1Plot_(Figure):
2024 class NSMeteorDetection1Plot_(Figure):
2020
2025
2021 isConfig = None
2026 isConfig = None
2022 __nsubplots = None
2027 __nsubplots = None
2023
2028
2024 WIDTHPROF = None
2029 WIDTHPROF = None
2025 HEIGHTPROF = None
2030 HEIGHTPROF = None
2026 PREFIX = 'nsm'
2031 PREFIX = 'nsm'
2027
2032
2028 zminList = None
2033 zminList = None
2029 zmaxList = None
2034 zmaxList = None
2030 cmapList = None
2035 cmapList = None
2031 titleList = None
2036 titleList = None
2032 nPairs = None
2037 nPairs = None
2033 nChannels = None
2038 nChannels = None
2034 nParam = None
2039 nParam = None
2035
2040
2036 def __init__(self, **kwargs):
2041 def __init__(self, **kwargs):
2037 Figure.__init__(self, **kwargs)
2042 Figure.__init__(self, **kwargs)
2038 self.isConfig = False
2043 self.isConfig = False
2039 self.__nsubplots = 1
2044 self.__nsubplots = 1
2040
2045
2041 self.WIDTH = 750
2046 self.WIDTH = 750
2042 self.HEIGHT = 250
2047 self.HEIGHT = 250
2043 self.WIDTHPROF = 120
2048 self.WIDTHPROF = 120
2044 self.HEIGHTPROF = 0
2049 self.HEIGHTPROF = 0
2045 self.counter_imagwr = 0
2050 self.counter_imagwr = 0
2046
2051
2047 self.PLOT_CODE = SPEC_CODE
2052 self.PLOT_CODE = SPEC_CODE
2048
2053
2049 self.FTP_WEI = None
2054 self.FTP_WEI = None
2050 self.EXP_CODE = None
2055 self.EXP_CODE = None
2051 self.SUB_EXP_CODE = None
2056 self.SUB_EXP_CODE = None
2052 self.PLOT_POS = None
2057 self.PLOT_POS = None
2053
2058
2054 self.__xfilter_ena = False
2059 self.__xfilter_ena = False
2055 self.__yfilter_ena = False
2060 self.__yfilter_ena = False
2056
2061
2057 def getSubplots(self):
2062 def getSubplots(self):
2058
2063
2059 ncol = 3
2064 ncol = 3
2060 nrow = int(numpy.ceil(self.nplots/3.0))
2065 nrow = int(numpy.ceil(self.nplots/3.0))
2061
2066
2062 return nrow, ncol
2067 return nrow, ncol
2063
2068
2064 def setup(self, id, nplots, wintitle, show=True):
2069 def setup(self, id, nplots, wintitle, show=True):
2065
2070
2066 self.nplots = nplots
2071 self.nplots = nplots
2067
2072
2068 ncolspan = 1
2073 ncolspan = 1
2069 colspan = 1
2074 colspan = 1
2070
2075
2071 self.createFigure(id = id,
2076 self.createFigure(id = id,
2072 wintitle = wintitle,
2077 wintitle = wintitle,
2073 widthplot = self.WIDTH + self.WIDTHPROF,
2078 widthplot = self.WIDTH + self.WIDTHPROF,
2074 heightplot = self.HEIGHT + self.HEIGHTPROF,
2079 heightplot = self.HEIGHT + self.HEIGHTPROF,
2075 show=show)
2080 show=show)
2076
2081
2077 nrow, ncol = self.getSubplots()
2082 nrow, ncol = self.getSubplots()
2078
2083
2079 counter = 0
2084 counter = 0
2080 for y in range(nrow):
2085 for y in range(nrow):
2081 for x in range(ncol):
2086 for x in range(ncol):
2082
2087
2083 if counter >= self.nplots:
2088 if counter >= self.nplots:
2084 break
2089 break
2085
2090
2086 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2091 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2087
2092
2088 counter += 1
2093 counter += 1
2089
2094
2090 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2095 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2091 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2096 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2092 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2097 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2093 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2098 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2094 server=None, folder=None, username=None, password=None,
2099 server=None, folder=None, username=None, password=None,
2095 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2100 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2096 xaxis="frequency"):
2101 xaxis="frequency"):
2097
2102
2098 """
2103 """
2099
2104
2100 Input:
2105 Input:
2101 dataOut :
2106 dataOut :
2102 id :
2107 id :
2103 wintitle :
2108 wintitle :
2104 channelList :
2109 channelList :
2105 showProfile :
2110 showProfile :
2106 xmin : None,
2111 xmin : None,
2107 xmax : None,
2112 xmax : None,
2108 ymin : None,
2113 ymin : None,
2109 ymax : None,
2114 ymax : None,
2110 zmin : None,
2115 zmin : None,
2111 zmax : None
2116 zmax : None
2112 """
2117 """
2113 #SEPARAR EN DOS PLOTS
2118 #SEPARAR EN DOS PLOTS
2114 nParam = dataOut.data_param.shape[1] - 3
2119 nParam = dataOut.data_param.shape[1] - 3
2115
2120
2116 utctime = dataOut.data_param[0,0]
2121 utctime = dataOut.data_param[0,0]
2117 tmet = dataOut.data_param[:,1].astype(int)
2122 tmet = dataOut.data_param[:,1].astype(int)
2118 hmet = dataOut.data_param[:,2].astype(int)
2123 hmet = dataOut.data_param[:,2].astype(int)
2119
2124
2120 x = dataOut.abscissaList
2125 x = dataOut.abscissaList
2121 y = dataOut.heightList
2126 y = dataOut.heightList
2122
2127
2123 z = numpy.zeros((nParam, y.size, x.size - 1))
2128 z = numpy.zeros((nParam, y.size, x.size - 1))
2124 z[:,:] = numpy.nan
2129 z[:,:] = numpy.nan
2125 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
2130 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
2126 z[0,:,:] = 10*numpy.log10(z[0,:,:])
2131 z[0,:,:] = 10*numpy.log10(z[0,:,:])
2127
2132
2128 xlabel = "Time (s)"
2133 xlabel = "Time (s)"
2129 ylabel = "Range (km)"
2134 ylabel = "Range (km)"
2130
2135
2131 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2136 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2132
2137
2133 if not self.isConfig:
2138 if not self.isConfig:
2134
2139
2135 nplots = nParam
2140 nplots = nParam
2136
2141
2137 self.setup(id=id,
2142 self.setup(id=id,
2138 nplots=nplots,
2143 nplots=nplots,
2139 wintitle=wintitle,
2144 wintitle=wintitle,
2140 show=show)
2145 show=show)
2141
2146
2142 if xmin is None: xmin = numpy.nanmin(x)
2147 if xmin is None: xmin = numpy.nanmin(x)
2143 if xmax is None: xmax = numpy.nanmax(x)
2148 if xmax is None: xmax = numpy.nanmax(x)
2144 if ymin is None: ymin = numpy.nanmin(y)
2149 if ymin is None: ymin = numpy.nanmin(y)
2145 if ymax is None: ymax = numpy.nanmax(y)
2150 if ymax is None: ymax = numpy.nanmax(y)
2146 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2151 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2147 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2152 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2148 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2153 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2149 if vmin is None: vmin = -vmax
2154 if vmin is None: vmin = -vmax
2150 if wmin is None: wmin = 0
2155 if wmin is None: wmin = 0
2151 if wmax is None: wmax = 50
2156 if wmax is None: wmax = 50
2152
2157
2153 pairsList = dataOut.groupList
2158 pairsList = dataOut.groupList
2154 self.nPairs = len(dataOut.groupList)
2159 self.nPairs = len(dataOut.groupList)
2155
2160
2156 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
2161 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
2157 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
2162 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
2158 titleList = ["SNR","Radial Velocity","Coherence"]
2163 titleList = ["SNR","Radial Velocity","Coherence"]
2159 cmapList = ["jet","RdBu_r","jet"]
2164 cmapList = ["jet","RdBu_r","jet"]
2160
2165
2161 for i in range(self.nPairs):
2166 for i in range(self.nPairs):
2162 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
2167 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
2163 titleList = titleList + [strAux1]
2168 titleList = titleList + [strAux1]
2164 cmapList = cmapList + ["RdBu_r"]
2169 cmapList = cmapList + ["RdBu_r"]
2165
2170
2166 self.zminList = zminList
2171 self.zminList = zminList
2167 self.zmaxList = zmaxList
2172 self.zmaxList = zmaxList
2168 self.cmapList = cmapList
2173 self.cmapList = cmapList
2169 self.titleList = titleList
2174 self.titleList = titleList
2170
2175
2171 self.FTP_WEI = ftp_wei
2176 self.FTP_WEI = ftp_wei
2172 self.EXP_CODE = exp_code
2177 self.EXP_CODE = exp_code
2173 self.SUB_EXP_CODE = sub_exp_code
2178 self.SUB_EXP_CODE = sub_exp_code
2174 self.PLOT_POS = plot_pos
2179 self.PLOT_POS = plot_pos
2175
2180
2176 self.isConfig = True
2181 self.isConfig = True
2177
2182
2178 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2183 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2179
2184
2180 for i in range(nParam):
2185 for i in range(nParam):
2181 title = self.titleList[i] + ": " +str_datetime
2186 title = self.titleList[i] + ": " +str_datetime
2182 axes = self.axesList[i]
2187 axes = self.axesList[i]
2183 axes.pcolor(x, y, z[i,:].T,
2188 axes.pcolor(x, y, z[i,:].T,
2184 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2189 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2185 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2190 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2186 self.draw()
2191 self.draw()
2187
2192
2188 if figfile == None:
2193 if figfile == None:
2189 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2194 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2190 name = str_datetime
2195 name = str_datetime
2191 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2196 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2192 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2197 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2193 figfile = self.getFilename(name)
2198 figfile = self.getFilename(name)
2194
2199
2195 self.save(figpath=figpath,
2200 self.save(figpath=figpath,
2196 figfile=figfile,
2201 figfile=figfile,
2197 save=save,
2202 save=save,
2198 ftp=ftp,
2203 ftp=ftp,
2199 wr_period=wr_period,
2204 wr_period=wr_period,
2200 thisDatetime=thisDatetime)
2205 thisDatetime=thisDatetime)
2201
2206
2202
2207
2203 class NSMeteorDetection2Plot_(Figure):
2208 class NSMeteorDetection2Plot_(Figure):
2204
2209
2205 isConfig = None
2210 isConfig = None
2206 __nsubplots = None
2211 __nsubplots = None
2207
2212
2208 WIDTHPROF = None
2213 WIDTHPROF = None
2209 HEIGHTPROF = None
2214 HEIGHTPROF = None
2210 PREFIX = 'nsm'
2215 PREFIX = 'nsm'
2211
2216
2212 zminList = None
2217 zminList = None
2213 zmaxList = None
2218 zmaxList = None
2214 cmapList = None
2219 cmapList = None
2215 titleList = None
2220 titleList = None
2216 nPairs = None
2221 nPairs = None
2217 nChannels = None
2222 nChannels = None
2218 nParam = None
2223 nParam = None
2219
2224
2220 def __init__(self, **kwargs):
2225 def __init__(self, **kwargs):
2221 Figure.__init__(self, **kwargs)
2226 Figure.__init__(self, **kwargs)
2222 self.isConfig = False
2227 self.isConfig = False
2223 self.__nsubplots = 1
2228 self.__nsubplots = 1
2224
2229
2225 self.WIDTH = 750
2230 self.WIDTH = 750
2226 self.HEIGHT = 250
2231 self.HEIGHT = 250
2227 self.WIDTHPROF = 120
2232 self.WIDTHPROF = 120
2228 self.HEIGHTPROF = 0
2233 self.HEIGHTPROF = 0
2229 self.counter_imagwr = 0
2234 self.counter_imagwr = 0
2230
2235
2231 self.PLOT_CODE = SPEC_CODE
2236 self.PLOT_CODE = SPEC_CODE
2232
2237
2233 self.FTP_WEI = None
2238 self.FTP_WEI = None
2234 self.EXP_CODE = None
2239 self.EXP_CODE = None
2235 self.SUB_EXP_CODE = None
2240 self.SUB_EXP_CODE = None
2236 self.PLOT_POS = None
2241 self.PLOT_POS = None
2237
2242
2238 self.__xfilter_ena = False
2243 self.__xfilter_ena = False
2239 self.__yfilter_ena = False
2244 self.__yfilter_ena = False
2240
2245
2241 def getSubplots(self):
2246 def getSubplots(self):
2242
2247
2243 ncol = 3
2248 ncol = 3
2244 nrow = int(numpy.ceil(self.nplots/3.0))
2249 nrow = int(numpy.ceil(self.nplots/3.0))
2245
2250
2246 return nrow, ncol
2251 return nrow, ncol
2247
2252
2248 def setup(self, id, nplots, wintitle, show=True):
2253 def setup(self, id, nplots, wintitle, show=True):
2249
2254
2250 self.nplots = nplots
2255 self.nplots = nplots
2251
2256
2252 ncolspan = 1
2257 ncolspan = 1
2253 colspan = 1
2258 colspan = 1
2254
2259
2255 self.createFigure(id = id,
2260 self.createFigure(id = id,
2256 wintitle = wintitle,
2261 wintitle = wintitle,
2257 widthplot = self.WIDTH + self.WIDTHPROF,
2262 widthplot = self.WIDTH + self.WIDTHPROF,
2258 heightplot = self.HEIGHT + self.HEIGHTPROF,
2263 heightplot = self.HEIGHT + self.HEIGHTPROF,
2259 show=show)
2264 show=show)
2260
2265
2261 nrow, ncol = self.getSubplots()
2266 nrow, ncol = self.getSubplots()
2262
2267
2263 counter = 0
2268 counter = 0
2264 for y in range(nrow):
2269 for y in range(nrow):
2265 for x in range(ncol):
2270 for x in range(ncol):
2266
2271
2267 if counter >= self.nplots:
2272 if counter >= self.nplots:
2268 break
2273 break
2269
2274
2270 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2275 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
2271
2276
2272 counter += 1
2277 counter += 1
2273
2278
2274 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2279 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
2275 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2280 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
2276 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2281 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
2277 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2282 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
2278 server=None, folder=None, username=None, password=None,
2283 server=None, folder=None, username=None, password=None,
2279 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2284 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
2280 xaxis="frequency"):
2285 xaxis="frequency"):
2281
2286
2282 """
2287 """
2283
2288
2284 Input:
2289 Input:
2285 dataOut :
2290 dataOut :
2286 id :
2291 id :
2287 wintitle :
2292 wintitle :
2288 channelList :
2293 channelList :
2289 showProfile :
2294 showProfile :
2290 xmin : None,
2295 xmin : None,
2291 xmax : None,
2296 xmax : None,
2292 ymin : None,
2297 ymin : None,
2293 ymax : None,
2298 ymax : None,
2294 zmin : None,
2299 zmin : None,
2295 zmax : None
2300 zmax : None
2296 """
2301 """
2297 #Rebuild matrix
2302 #Rebuild matrix
2298 utctime = dataOut.data_param[0,0]
2303 utctime = dataOut.data_param[0,0]
2299 cmet = dataOut.data_param[:,1].astype(int)
2304 cmet = dataOut.data_param[:,1].astype(int)
2300 tmet = dataOut.data_param[:,2].astype(int)
2305 tmet = dataOut.data_param[:,2].astype(int)
2301 hmet = dataOut.data_param[:,3].astype(int)
2306 hmet = dataOut.data_param[:,3].astype(int)
2302
2307
2303 nParam = 3
2308 nParam = 3
2304 nChan = len(dataOut.groupList)
2309 nChan = len(dataOut.groupList)
2305 x = dataOut.abscissaList
2310 x = dataOut.abscissaList
2306 y = dataOut.heightList
2311 y = dataOut.heightList
2307
2312
2308 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
2313 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
2309 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
2314 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
2310 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
2315 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
2311 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
2316 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
2312
2317
2313 xlabel = "Time (s)"
2318 xlabel = "Time (s)"
2314 ylabel = "Range (km)"
2319 ylabel = "Range (km)"
2315
2320
2316 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2321 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
2317
2322
2318 if not self.isConfig:
2323 if not self.isConfig:
2319
2324
2320 nplots = nParam*nChan
2325 nplots = nParam*nChan
2321
2326
2322 self.setup(id=id,
2327 self.setup(id=id,
2323 nplots=nplots,
2328 nplots=nplots,
2324 wintitle=wintitle,
2329 wintitle=wintitle,
2325 show=show)
2330 show=show)
2326
2331
2327 if xmin is None: xmin = numpy.nanmin(x)
2332 if xmin is None: xmin = numpy.nanmin(x)
2328 if xmax is None: xmax = numpy.nanmax(x)
2333 if xmax is None: xmax = numpy.nanmax(x)
2329 if ymin is None: ymin = numpy.nanmin(y)
2334 if ymin is None: ymin = numpy.nanmin(y)
2330 if ymax is None: ymax = numpy.nanmax(y)
2335 if ymax is None: ymax = numpy.nanmax(y)
2331 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2336 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
2332 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2337 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
2333 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2338 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
2334 if vmin is None: vmin = -vmax
2339 if vmin is None: vmin = -vmax
2335 if wmin is None: wmin = 0
2340 if wmin is None: wmin = 0
2336 if wmax is None: wmax = 50
2341 if wmax is None: wmax = 50
2337
2342
2338 self.nChannels = nChan
2343 self.nChannels = nChan
2339
2344
2340 zminList = []
2345 zminList = []
2341 zmaxList = []
2346 zmaxList = []
2342 titleList = []
2347 titleList = []
2343 cmapList = []
2348 cmapList = []
2344 for i in range(self.nChannels):
2349 for i in range(self.nChannels):
2345 strAux1 = "SNR Channel "+ str(i)
2350 strAux1 = "SNR Channel "+ str(i)
2346 strAux2 = "Radial Velocity Channel "+ str(i)
2351 strAux2 = "Radial Velocity Channel "+ str(i)
2347 strAux3 = "Spectral Width Channel "+ str(i)
2352 strAux3 = "Spectral Width Channel "+ str(i)
2348
2353
2349 titleList = titleList + [strAux1,strAux2,strAux3]
2354 titleList = titleList + [strAux1,strAux2,strAux3]
2350 cmapList = cmapList + ["jet","RdBu_r","jet"]
2355 cmapList = cmapList + ["jet","RdBu_r","jet"]
2351 zminList = zminList + [SNRmin,vmin,wmin]
2356 zminList = zminList + [SNRmin,vmin,wmin]
2352 zmaxList = zmaxList + [SNRmax,vmax,wmax]
2357 zmaxList = zmaxList + [SNRmax,vmax,wmax]
2353
2358
2354 self.zminList = zminList
2359 self.zminList = zminList
2355 self.zmaxList = zmaxList
2360 self.zmaxList = zmaxList
2356 self.cmapList = cmapList
2361 self.cmapList = cmapList
2357 self.titleList = titleList
2362 self.titleList = titleList
2358
2363
2359 self.FTP_WEI = ftp_wei
2364 self.FTP_WEI = ftp_wei
2360 self.EXP_CODE = exp_code
2365 self.EXP_CODE = exp_code
2361 self.SUB_EXP_CODE = sub_exp_code
2366 self.SUB_EXP_CODE = sub_exp_code
2362 self.PLOT_POS = plot_pos
2367 self.PLOT_POS = plot_pos
2363
2368
2364 self.isConfig = True
2369 self.isConfig = True
2365
2370
2366 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2371 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
2367
2372
2368 for i in range(self.nplots):
2373 for i in range(self.nplots):
2369 title = self.titleList[i] + ": " +str_datetime
2374 title = self.titleList[i] + ": " +str_datetime
2370 axes = self.axesList[i]
2375 axes = self.axesList[i]
2371 axes.pcolor(x, y, z[i,:].T,
2376 axes.pcolor(x, y, z[i,:].T,
2372 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2377 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
2373 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2378 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
2374 self.draw()
2379 self.draw()
2375
2380
2376 if figfile == None:
2381 if figfile == None:
2377 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2382 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
2378 name = str_datetime
2383 name = str_datetime
2379 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2384 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
2380 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2385 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
2381 figfile = self.getFilename(name)
2386 figfile = self.getFilename(name)
2382
2387
2383 self.save(figpath=figpath,
2388 self.save(figpath=figpath,
2384 figfile=figfile,
2389 figfile=figfile,
2385 save=save,
2390 save=save,
2386 ftp=ftp,
2391 ftp=ftp,
2387 wr_period=wr_period,
2392 wr_period=wr_period,
2388 thisDatetime=thisDatetime)
2393 thisDatetime=thisDatetime)
2389 No newline at end of file
2394
@@ -1,500 +1,500
1 import os
1 import os
2 import sys
2 import sys
3 import datetime
3 import datetime
4 import numpy
4 import numpy
5 import matplotlib
5 import matplotlib
6
6
7 if 'BACKEND' in os.environ:
7 if 'BACKEND' in os.environ:
8 matplotlib.use(os.environ['BACKEND'])
8 matplotlib.use(os.environ['BACKEND'])
9 elif 'linux' in sys.platform:
9 elif 'linux' in sys.platform:
10 matplotlib.use("TkAgg")
10 matplotlib.use("TkAgg")
11 elif 'darwin' in sys.platform:
11 elif 'darwin' in sys.platform:
12 matplotlib.use('TkAgg')
12 matplotlib.use('TkAgg')
13 else:
13 else:
14 from schainpy.utils import log
14 from schainpy.utils import log
15 log.warning('Using default Backend="Agg"', 'INFO')
15 log.warning('Using default Backend="Agg"', 'INFO')
16 matplotlib.use('Agg')
16 matplotlib.use('Agg')
17 # Qt4Agg', 'GTK', 'GTKAgg', 'ps', 'agg', 'cairo', 'MacOSX', 'GTKCairo', 'WXAgg', 'template', 'TkAgg', 'GTK3Cairo', 'GTK3Agg', 'svg', 'WebAgg', 'CocoaAgg', 'emf', 'gdk', 'WX'
17 # Qt4Agg', 'GTK', 'GTKAgg', 'ps', 'agg', 'cairo', 'MacOSX', 'GTKCairo', 'WXAgg', 'template', 'TkAgg', 'GTK3Cairo', 'GTK3Agg', 'svg', 'WebAgg', 'CocoaAgg', 'emf', 'gdk', 'WX'
18 import matplotlib.pyplot
18 import matplotlib.pyplot
19
19
20 from mpl_toolkits.axes_grid1 import make_axes_locatable
20 from mpl_toolkits.axes_grid1 import make_axes_locatable
21 from matplotlib.ticker import FuncFormatter, LinearLocator
21 from matplotlib.ticker import FuncFormatter, LinearLocator
22
22
23 ###########################################
23 ###########################################
24 # Actualizacion de las funciones del driver
24 # Actualizacion de las funciones del driver
25 ###########################################
25 ###########################################
26
26
27 # create jro colormap
27 # create jro colormap
28
28
29 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
29 jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90]
30 blu_values = matplotlib.pyplot.get_cmap(
30 blu_values = matplotlib.pyplot.get_cmap(
31 "seismic_r", 20)(numpy.arange(20))[10:15]
31 "seismic_r", 20)(numpy.arange(20))[10:15]
32 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
32 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
33 "jro", numpy.vstack((blu_values, jet_values)))
33 "jro", numpy.vstack((blu_values, jet_values)))
34 matplotlib.pyplot.register_cmap(cmap=ncmap)
34 matplotlib.pyplot.register_cmap(cmap=ncmap)
35
35
36
36
37 def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi=80):
37 def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi=80):
38
38
39 matplotlib.pyplot.ioff()
39 matplotlib.pyplot.ioff()
40
40
41 fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor, figsize=(
41 fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor, figsize=(
42 1.0 * width / dpi, 1.0 * height / dpi))
42 1.0 * width / dpi, 1.0 * height / dpi))
43 fig.canvas.manager.set_window_title(wintitle)
43 fig.canvas.manager.set_window_title(wintitle)
44 # fig.canvas.manager.resize(width, height)
44 # fig.canvas.manager.resize(width, height)
45 matplotlib.pyplot.ion()
45 matplotlib.pyplot.ion()
46
46
47 if show:
47 if show:
48 matplotlib.pyplot.show()
48 matplotlib.pyplot.show()
49
49
50 return fig
50 return fig
51
51
52
52
53 def closeFigure(show=False, fig=None):
53 def closeFigure(show=False, fig=None):
54
54
55 # matplotlib.pyplot.ioff()
55 # matplotlib.pyplot.ioff()
56 # matplotlib.pyplot.pause(0)
56 # matplotlib.pyplot.pause(0)
57
57
58 if show:
58 if show:
59 matplotlib.pyplot.show()
59 matplotlib.pyplot.show()
60
60
61 if fig != None:
61 if fig != None:
62 matplotlib.pyplot.close(fig)
62 matplotlib.pyplot.close(fig)
63 # matplotlib.pyplot.pause(0)
63 # matplotlib.pyplot.pause(0)
64 # matplotlib.pyplot.ion()
64 # matplotlib.pyplot.ion()
65
65
66 return
66 return
67
67
68 matplotlib.pyplot.close("all")
68 matplotlib.pyplot.close("all")
69 # matplotlib.pyplot.pause(0)
69 # matplotlib.pyplot.pause(0)
70 # matplotlib.pyplot.ion()
70 # matplotlib.pyplot.ion()
71
71
72 return
72 return
73
73
74
74
75 def saveFigure(fig, filename):
75 def saveFigure(fig, filename):
76
76
77 # matplotlib.pyplot.ioff()
77 # matplotlib.pyplot.ioff()
78 fig.savefig(filename, dpi=matplotlib.pyplot.gcf().dpi)
78 fig.savefig(filename, dpi=matplotlib.pyplot.gcf().dpi)
79 # matplotlib.pyplot.ion()
79 # matplotlib.pyplot.ion()
80
80
81
81
82 def clearFigure(fig):
82 def clearFigure(fig):
83
83
84 fig.clf()
84 fig.clf()
85
85
86
86
87 def setWinTitle(fig, title):
87 def setWinTitle(fig, title):
88
88
89 fig.canvas.manager.set_window_title(title)
89 fig.canvas.manager.set_window_title(title)
90
90
91
91
92 def setTitle(fig, title):
92 def setTitle(fig, title):
93
93
94 fig.suptitle(title)
94 fig.suptitle(title)
95
95
96
96
97 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan, polar=False):
97 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan, polar=False):
98
98
99 matplotlib.pyplot.ioff()
99 matplotlib.pyplot.ioff()
100 matplotlib.pyplot.figure(fig.number)
100 matplotlib.pyplot.figure(fig.number)
101 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
101 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
102 (xpos, ypos),
102 (xpos, ypos),
103 colspan=colspan,
103 colspan=colspan,
104 rowspan=rowspan,
104 rowspan=rowspan,
105 polar=polar)
105 polar=polar)
106
106
107 matplotlib.pyplot.ion()
107 matplotlib.pyplot.ion()
108 return axes
108 return axes
109
109
110
110
111 def setAxesText(ax, text):
111 def setAxesText(ax, text):
112
112
113 ax.annotate(text,
113 ax.annotate(text,
114 xy=(.1, .99),
114 xy=(.1, .99),
115 xycoords='figure fraction',
115 xycoords='figure fraction',
116 horizontalalignment='left',
116 horizontalalignment='left',
117 verticalalignment='top',
117 verticalalignment='top',
118 fontsize=10)
118 fontsize=10)
119
119
120
120
121 def printLabels(ax, xlabel, ylabel, title):
121 def printLabels(ax, xlabel, ylabel, title):
122
122
123 ax.set_xlabel(xlabel, size=11)
123 ax.set_xlabel(xlabel, size=11)
124 ax.set_ylabel(ylabel, size=11)
124 ax.set_ylabel(ylabel, size=11)
125 ax.set_title(title, size=8)
125 ax.set_title(title, size=8)
126
126
127
127
128 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='',
128 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='',
129 ticksize=9, xtick_visible=True, ytick_visible=True,
129 ticksize=9, xtick_visible=True, ytick_visible=True,
130 nxticks=4, nyticks=10,
130 nxticks=4, nyticks=10,
131 grid=None, color='blue'):
131 grid=None, color='blue'):
132 """
132 """
133
133
134 Input:
134 Input:
135 grid : None, 'both', 'x', 'y'
135 grid : None, 'both', 'x', 'y'
136 """
136 """
137
137
138 matplotlib.pyplot.ioff()
138 matplotlib.pyplot.ioff()
139
139
140 ax.set_xlim([xmin, xmax])
140 ax.set_xlim([xmin, xmax])
141 ax.set_ylim([ymin, ymax])
141 ax.set_ylim([ymin, ymax])
142
142
143 printLabels(ax, xlabel, ylabel, title)
143 printLabels(ax, xlabel, ylabel, title)
144
144
145 ######################################################
145 ######################################################
146 if (xmax - xmin) <= 1:
146 if (xmax - xmin) <= 1:
147 xtickspos = numpy.linspace(xmin, xmax, nxticks)
147 xtickspos = numpy.linspace(xmin, xmax, nxticks)
148 xtickspos = numpy.array([float("%.1f" % i) for i in xtickspos])
148 xtickspos = numpy.array([float("%.1f" % i) for i in xtickspos])
149 ax.set_xticks(xtickspos)
149 ax.set_xticks(xtickspos)
150 else:
150 else:
151 xtickspos = numpy.arange(nxticks) * \
151 xtickspos = numpy.arange(nxticks) * \
152 int((xmax - xmin) / (nxticks)) + int(xmin)
152 int((xmax - xmin) / (nxticks)) + int(xmin)
153 # xtickspos = numpy.arange(nxticks)*float(xmax-xmin)/float(nxticks) + int(xmin)
153 # xtickspos = numpy.arange(nxticks)*float(xmax-xmin)/float(nxticks) + int(xmin)
154 ax.set_xticks(xtickspos)
154 ax.set_xticks(xtickspos)
155
155
156 for tick in ax.get_xticklabels():
156 for tick in ax.get_xticklabels():
157 tick.set_visible(xtick_visible)
157 tick.set_visible(xtick_visible)
158
158
159 for tick in ax.xaxis.get_major_ticks():
159 for tick in ax.xaxis.get_major_ticks():
160 tick.label.set_fontsize(ticksize)
160 tick.label.set_fontsize(ticksize)
161
161
162 ######################################################
162 ######################################################
163 for tick in ax.get_yticklabels():
163 for tick in ax.get_yticklabels():
164 tick.set_visible(ytick_visible)
164 tick.set_visible(ytick_visible)
165
165
166 for tick in ax.yaxis.get_major_ticks():
166 for tick in ax.yaxis.get_major_ticks():
167 tick.label.set_fontsize(ticksize)
167 tick.label.set_fontsize(ticksize)
168
168
169 ax.plot(x, y, color=color)
169 ax.plot(x, y, color=color)
170 iplot = ax.lines[-1]
170 iplot = ax.lines[-1]
171
171
172 ######################################################
172 ######################################################
173 if '0.' in matplotlib.__version__[0:2]:
173 if '0.' in matplotlib.__version__[0:2]:
174 print("The matplotlib version has to be updated to 1.1 or newer")
174 print("The matplotlib version has to be updated to 1.1 or newer")
175 return iplot
175 return iplot
176
176
177 if '1.0.' in matplotlib.__version__[0:4]:
177 if '1.0.' in matplotlib.__version__[0:4]:
178 print("The matplotlib version has to be updated to 1.1 or newer")
178 print("The matplotlib version has to be updated to 1.1 or newer")
179 return iplot
179 return iplot
180
180
181 if grid != None:
181 if grid != None:
182 ax.grid(b=True, which='major', axis=grid)
182 ax.grid(b=True, which='major', axis=grid)
183
183
184 matplotlib.pyplot.tight_layout()
184 matplotlib.pyplot.tight_layout()
185
185
186 matplotlib.pyplot.ion()
186 matplotlib.pyplot.ion()
187
187
188 return iplot
188 return iplot
189
189
190
190
191 def set_linedata(ax, x, y, idline):
191 def set_linedata(ax, x, y, idline):
192
192
193 ax.lines[idline].set_data(x, y)
193 ax.lines[idline].set_data(x, y)
194
194
195
195
196 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
196 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
197
197
198 ax = iplot.axes
198 ax = iplot.axes
199
199
200 printLabels(ax, xlabel, ylabel, title)
200 printLabels(ax, xlabel, ylabel, title)
201
201
202 set_linedata(ax, x, y, idline=0)
202 set_linedata(ax, x, y, idline=0)
203
203
204
204
205 def addpline(ax, x, y, color, linestyle, lw):
205 def addpline(ax, x, y, color, linestyle, lw):
206
206
207 ax.plot(x, y, color=color, linestyle=linestyle, lw=lw)
207 ax.plot(x, y, color=color, linestyle=linestyle, lw=lw)
208
208
209
209
210 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
210 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
211 xlabel='', ylabel='', title='', ticksize=9,
211 xlabel='', ylabel='', title='', ticksize=9,
212 colormap='jet', cblabel='', cbsize="5%",
212 colormap='jet', cblabel='', cbsize="5%",
213 XAxisAsTime=False):
213 XAxisAsTime=False):
214
214
215 matplotlib.pyplot.ioff()
215 matplotlib.pyplot.ioff()
216
216
217 divider = make_axes_locatable(ax)
217 divider = make_axes_locatable(ax)
218 ax_cb = divider.new_horizontal(size=cbsize, pad=0.05)
218 ax_cb = divider.new_horizontal(size=cbsize, pad=0.05)
219 fig = ax.get_figure()
219 fig = ax.get_figure()
220 fig.add_axes(ax_cb)
220 fig.add_axes(ax_cb)
221
221
222 ax.set_xlim([xmin, xmax])
222 ax.set_xlim([xmin, xmax])
223 ax.set_ylim([ymin, ymax])
223 ax.set_ylim([ymin, ymax])
224
224
225 printLabels(ax, xlabel, ylabel, title)
225 printLabels(ax, xlabel, ylabel, title)
226
226
227 z = numpy.ma.masked_invalid(z)
227 z = numpy.ma.masked_invalid(z)
228 cmap = matplotlib.pyplot.get_cmap(colormap)
228 cmap = matplotlib.pyplot.get_cmap(colormap)
229 cmap.set_bad('black', 1.)
229 cmap.set_bad('white', 1.)
230 imesh = ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, cmap=cmap)
230 imesh = ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, cmap=cmap)
231 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
231 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
232 cb.set_label(cblabel)
232 cb.set_label(cblabel)
233
233
234 # for tl in ax_cb.get_yticklabels():
234 # for tl in ax_cb.get_yticklabels():
235 # tl.set_visible(True)
235 # tl.set_visible(True)
236
236
237 for tick in ax.yaxis.get_major_ticks():
237 for tick in ax.yaxis.get_major_ticks():
238 tick.label.set_fontsize(ticksize)
238 tick.label.set_fontsize(ticksize)
239
239
240 for tick in ax.xaxis.get_major_ticks():
240 for tick in ax.xaxis.get_major_ticks():
241 tick.label.set_fontsize(ticksize)
241 tick.label.set_fontsize(ticksize)
242
242
243 for tick in cb.ax.get_yticklabels():
243 for tick in cb.ax.get_yticklabels():
244 tick.set_fontsize(ticksize)
244 tick.set_fontsize(ticksize)
245
245
246 ax_cb.yaxis.tick_right()
246 ax_cb.yaxis.tick_right()
247
247
248 if '0.' in matplotlib.__version__[0:2]:
248 if '0.' in matplotlib.__version__[0:2]:
249 print("The matplotlib version has to be updated to 1.1 or newer")
249 print("The matplotlib version has to be updated to 1.1 or newer")
250 return imesh
250 return imesh
251
251
252 if '1.0.' in matplotlib.__version__[0:4]:
252 if '1.0.' in matplotlib.__version__[0:4]:
253 print("The matplotlib version has to be updated to 1.1 or newer")
253 print("The matplotlib version has to be updated to 1.1 or newer")
254 return imesh
254 return imesh
255
255
256 matplotlib.pyplot.tight_layout()
256 matplotlib.pyplot.tight_layout()
257
257
258 if XAxisAsTime:
258 if XAxisAsTime:
259
259
260 def func(x, pos): return ('%s') % (
260 def func(x, pos): return ('%s') % (
261 datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
261 datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
262 ax.xaxis.set_major_formatter(FuncFormatter(func))
262 ax.xaxis.set_major_formatter(FuncFormatter(func))
263 ax.xaxis.set_major_locator(LinearLocator(7))
263 ax.xaxis.set_major_locator(LinearLocator(7))
264
264
265 matplotlib.pyplot.ion()
265 matplotlib.pyplot.ion()
266 return imesh
266 return imesh
267
267
268
268
269 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
269 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
270
270
271 z = z.T
271 z = z.T
272 ax = imesh.axes
272 ax = imesh.axes
273 printLabels(ax, xlabel, ylabel, title)
273 printLabels(ax, xlabel, ylabel, title)
274 imesh.set_array(z.ravel())
274 imesh.set_array(z.ravel())
275
275
276
276
277 def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
277 def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
278
278
279 printLabels(ax, xlabel, ylabel, title)
279 printLabels(ax, xlabel, ylabel, title)
280
280
281 ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax,
281 ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax,
282 cmap=matplotlib.pyplot.get_cmap(colormap))
282 cmap=matplotlib.pyplot.get_cmap(colormap))
283
283
284
284
285 def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
285 def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
286
286
287 printLabels(ax, xlabel, ylabel, title)
287 printLabels(ax, xlabel, ylabel, title)
288
288
289 ax.collections.remove(ax.collections[0])
289 ax.collections.remove(ax.collections[0])
290
290
291 z = numpy.ma.masked_invalid(z)
291 z = numpy.ma.masked_invalid(z)
292
292
293 cmap = matplotlib.pyplot.get_cmap(colormap)
293 cmap = matplotlib.pyplot.get_cmap(colormap)
294 cmap.set_bad('black', 1.)
294 cmap.set_bad('white', 1.)
295
295
296 ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, cmap=cmap)
296 ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, cmap=cmap)
297
297
298
298
299 def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
299 def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
300 ticksize=9, xtick_visible=True, ytick_visible=True,
300 ticksize=9, xtick_visible=True, ytick_visible=True,
301 nxticks=4, nyticks=10,
301 nxticks=4, nyticks=10,
302 grid=None):
302 grid=None):
303 """
303 """
304
304
305 Input:
305 Input:
306 grid : None, 'both', 'x', 'y'
306 grid : None, 'both', 'x', 'y'
307 """
307 """
308
308
309 matplotlib.pyplot.ioff()
309 matplotlib.pyplot.ioff()
310
310
311 lines = ax.plot(x.T, y)
311 lines = ax.plot(x.T, y)
312 leg = ax.legend(lines, legendlabels, loc='upper right')
312 leg = ax.legend(lines, legendlabels, loc='upper right')
313 leg.get_frame().set_alpha(0.5)
313 leg.get_frame().set_alpha(0.5)
314 ax.set_xlim([xmin, xmax])
314 ax.set_xlim([xmin, xmax])
315 ax.set_ylim([ymin, ymax])
315 ax.set_ylim([ymin, ymax])
316 printLabels(ax, xlabel, ylabel, title)
316 printLabels(ax, xlabel, ylabel, title)
317
317
318 xtickspos = numpy.arange(nxticks) * \
318 xtickspos = numpy.arange(nxticks) * \
319 int((xmax - xmin) / (nxticks)) + int(xmin)
319 int((xmax - xmin) / (nxticks)) + int(xmin)
320 ax.set_xticks(xtickspos)
320 ax.set_xticks(xtickspos)
321
321
322 for tick in ax.get_xticklabels():
322 for tick in ax.get_xticklabels():
323 tick.set_visible(xtick_visible)
323 tick.set_visible(xtick_visible)
324
324
325 for tick in ax.xaxis.get_major_ticks():
325 for tick in ax.xaxis.get_major_ticks():
326 tick.label.set_fontsize(ticksize)
326 tick.label.set_fontsize(ticksize)
327
327
328 for tick in ax.get_yticklabels():
328 for tick in ax.get_yticklabels():
329 tick.set_visible(ytick_visible)
329 tick.set_visible(ytick_visible)
330
330
331 for tick in ax.yaxis.get_major_ticks():
331 for tick in ax.yaxis.get_major_ticks():
332 tick.label.set_fontsize(ticksize)
332 tick.label.set_fontsize(ticksize)
333
333
334 iplot = ax.lines[-1]
334 iplot = ax.lines[-1]
335
335
336 if '0.' in matplotlib.__version__[0:2]:
336 if '0.' in matplotlib.__version__[0:2]:
337 print("The matplotlib version has to be updated to 1.1 or newer")
337 print("The matplotlib version has to be updated to 1.1 or newer")
338 return iplot
338 return iplot
339
339
340 if '1.0.' in matplotlib.__version__[0:4]:
340 if '1.0.' in matplotlib.__version__[0:4]:
341 print("The matplotlib version has to be updated to 1.1 or newer")
341 print("The matplotlib version has to be updated to 1.1 or newer")
342 return iplot
342 return iplot
343
343
344 if grid != None:
344 if grid != None:
345 ax.grid(b=True, which='major', axis=grid)
345 ax.grid(b=True, which='major', axis=grid)
346
346
347 matplotlib.pyplot.tight_layout()
347 matplotlib.pyplot.tight_layout()
348
348
349 matplotlib.pyplot.ion()
349 matplotlib.pyplot.ion()
350
350
351 return iplot
351 return iplot
352
352
353
353
354 def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''):
354 def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''):
355
355
356 ax = iplot.axes
356 ax = iplot.axes
357
357
358 printLabels(ax, xlabel, ylabel, title)
358 printLabels(ax, xlabel, ylabel, title)
359
359
360 for i in range(len(ax.lines)):
360 for i in range(len(ax.lines)):
361 line = ax.lines[i]
361 line = ax.lines[i]
362 line.set_data(x[i, :], y)
362 line.set_data(x[i, :], y)
363
363
364
364
365 def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
365 def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
366 ticksize=9, xtick_visible=True, ytick_visible=True,
366 ticksize=9, xtick_visible=True, ytick_visible=True,
367 nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None",
367 nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None",
368 grid=None, XAxisAsTime=False):
368 grid=None, XAxisAsTime=False):
369 """
369 """
370
370
371 Input:
371 Input:
372 grid : None, 'both', 'x', 'y'
372 grid : None, 'both', 'x', 'y'
373 """
373 """
374
374
375 matplotlib.pyplot.ioff()
375 matplotlib.pyplot.ioff()
376
376
377 # lines = ax.plot(x, y.T, marker=marker,markersize=markersize,linestyle=linestyle)
377 # lines = ax.plot(x, y.T, marker=marker,markersize=markersize,linestyle=linestyle)
378 lines = ax.plot(x, y.T)
378 lines = ax.plot(x, y.T)
379 # leg = ax.legend(lines, legendlabels, loc=2, bbox_to_anchor=(1.01, 1.00), numpoints=1, handlelength=1.5, \
379 # leg = ax.legend(lines, legendlabels, loc=2, bbox_to_anchor=(1.01, 1.00), numpoints=1, handlelength=1.5, \
380 # handletextpad=0.5, borderpad=0.5, labelspacing=0.5, borderaxespad=0.)
380 # handletextpad=0.5, borderpad=0.5, labelspacing=0.5, borderaxespad=0.)
381
381
382 leg = ax.legend(lines, legendlabels,
382 leg = ax.legend(lines, legendlabels,
383 loc='upper right', bbox_to_anchor=(1.16, 1), borderaxespad=0)
383 loc='upper right', bbox_to_anchor=(1.16, 1), borderaxespad=0)
384
384
385 for label in leg.get_texts():
385 for label in leg.get_texts():
386 label.set_fontsize(9)
386 label.set_fontsize(9)
387
387
388 ax.set_xlim([xmin, xmax])
388 ax.set_xlim([xmin, xmax])
389 ax.set_ylim([ymin, ymax])
389 ax.set_ylim([ymin, ymax])
390 printLabels(ax, xlabel, ylabel, title)
390 printLabels(ax, xlabel, ylabel, title)
391
391
392 # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
392 # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
393 # ax.set_xticks(xtickspos)
393 # ax.set_xticks(xtickspos)
394
394
395 for tick in ax.get_xticklabels():
395 for tick in ax.get_xticklabels():
396 tick.set_visible(xtick_visible)
396 tick.set_visible(xtick_visible)
397
397
398 for tick in ax.xaxis.get_major_ticks():
398 for tick in ax.xaxis.get_major_ticks():
399 tick.label.set_fontsize(ticksize)
399 tick.label.set_fontsize(ticksize)
400
400
401 for tick in ax.get_yticklabels():
401 for tick in ax.get_yticklabels():
402 tick.set_visible(ytick_visible)
402 tick.set_visible(ytick_visible)
403
403
404 for tick in ax.yaxis.get_major_ticks():
404 for tick in ax.yaxis.get_major_ticks():
405 tick.label.set_fontsize(ticksize)
405 tick.label.set_fontsize(ticksize)
406
406
407 iplot = ax.lines[-1]
407 iplot = ax.lines[-1]
408
408
409 if '0.' in matplotlib.__version__[0:2]:
409 if '0.' in matplotlib.__version__[0:2]:
410 print("The matplotlib version has to be updated to 1.1 or newer")
410 print("The matplotlib version has to be updated to 1.1 or newer")
411 return iplot
411 return iplot
412
412
413 if '1.0.' in matplotlib.__version__[0:4]:
413 if '1.0.' in matplotlib.__version__[0:4]:
414 print("The matplotlib version has to be updated to 1.1 or newer")
414 print("The matplotlib version has to be updated to 1.1 or newer")
415 return iplot
415 return iplot
416
416
417 if grid != None:
417 if grid != None:
418 ax.grid(b=True, which='major', axis=grid)
418 ax.grid(b=True, which='major', axis=grid)
419
419
420 matplotlib.pyplot.tight_layout()
420 matplotlib.pyplot.tight_layout()
421
421
422 if XAxisAsTime:
422 if XAxisAsTime:
423
423
424 def func(x, pos): return ('%s') % (
424 def func(x, pos): return ('%s') % (
425 datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
425 datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
426 ax.xaxis.set_major_formatter(FuncFormatter(func))
426 ax.xaxis.set_major_formatter(FuncFormatter(func))
427 ax.xaxis.set_major_locator(LinearLocator(7))
427 ax.xaxis.set_major_locator(LinearLocator(7))
428
428
429 matplotlib.pyplot.ion()
429 matplotlib.pyplot.ion()
430
430
431 return iplot
431 return iplot
432
432
433
433
434 def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''):
434 def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''):
435
435
436 ax = iplot.axes
436 ax = iplot.axes
437 printLabels(ax, xlabel, ylabel, title)
437 printLabels(ax, xlabel, ylabel, title)
438
438
439 for i in range(len(ax.lines)):
439 for i in range(len(ax.lines)):
440 line = ax.lines[i]
440 line = ax.lines[i]
441 line.set_data(x, y[i, :])
441 line.set_data(x, y[i, :])
442
442
443
443
444 def createPolar(ax, x, y,
444 def createPolar(ax, x, y,
445 xlabel='', ylabel='', title='', ticksize=9,
445 xlabel='', ylabel='', title='', ticksize=9,
446 colormap='jet', cblabel='', cbsize="5%",
446 colormap='jet', cblabel='', cbsize="5%",
447 XAxisAsTime=False):
447 XAxisAsTime=False):
448
448
449 matplotlib.pyplot.ioff()
449 matplotlib.pyplot.ioff()
450
450
451 ax.plot(x, y, 'bo', markersize=5)
451 ax.plot(x, y, 'bo', markersize=5)
452 # ax.set_rmax(90)
452 # ax.set_rmax(90)
453 ax.set_ylim(0, 90)
453 ax.set_ylim(0, 90)
454 ax.set_yticks(numpy.arange(0, 90, 20))
454 ax.set_yticks(numpy.arange(0, 90, 20))
455 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center' ,size='11')
455 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center' ,size='11')
456 # ax.text(0, 50, ylabel, rotation='vertical', va ='center', ha = 'left' ,size='11')
456 # ax.text(0, 50, ylabel, rotation='vertical', va ='center', ha = 'left' ,size='11')
457 # ax.text(100, 100, 'example', ha='left', va='center', rotation='vertical')
457 # ax.text(100, 100, 'example', ha='left', va='center', rotation='vertical')
458 ax.yaxis.labelpad = 40
458 ax.yaxis.labelpad = 40
459 printLabels(ax, xlabel, ylabel, title)
459 printLabels(ax, xlabel, ylabel, title)
460 iplot = ax.lines[-1]
460 iplot = ax.lines[-1]
461
461
462 if '0.' in matplotlib.__version__[0:2]:
462 if '0.' in matplotlib.__version__[0:2]:
463 print("The matplotlib version has to be updated to 1.1 or newer")
463 print("The matplotlib version has to be updated to 1.1 or newer")
464 return iplot
464 return iplot
465
465
466 if '1.0.' in matplotlib.__version__[0:4]:
466 if '1.0.' in matplotlib.__version__[0:4]:
467 print("The matplotlib version has to be updated to 1.1 or newer")
467 print("The matplotlib version has to be updated to 1.1 or newer")
468 return iplot
468 return iplot
469
469
470 # if grid != None:
470 # if grid != None:
471 # ax.grid(b=True, which='major', axis=grid)
471 # ax.grid(b=True, which='major', axis=grid)
472
472
473 matplotlib.pyplot.tight_layout()
473 matplotlib.pyplot.tight_layout()
474
474
475 matplotlib.pyplot.ion()
475 matplotlib.pyplot.ion()
476
476
477 return iplot
477 return iplot
478
478
479
479
480 def polar(iplot, x, y, xlabel='', ylabel='', title=''):
480 def polar(iplot, x, y, xlabel='', ylabel='', title=''):
481
481
482 ax = iplot.axes
482 ax = iplot.axes
483
483
484 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center',size='11')
484 # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center',size='11')
485 printLabels(ax, xlabel, ylabel, title)
485 printLabels(ax, xlabel, ylabel, title)
486
486
487 set_linedata(ax, x, y, idline=0)
487 set_linedata(ax, x, y, idline=0)
488
488
489
489
490 def draw(fig):
490 def draw(fig):
491
491
492 if type(fig) == 'int':
492 if type(fig) == 'int':
493 raise ValueError("Error drawing: Fig parameter should be a matplotlib figure object figure")
493 raise ValueError("Error drawing: Fig parameter should be a matplotlib figure object figure")
494
494
495 fig.canvas.draw()
495 fig.canvas.draw()
496
496
497
497
498 def pause(interval=0.000001):
498 def pause(interval=0.000001):
499
499
500 matplotlib.pyplot.pause(interval) No newline at end of file
500 matplotlib.pyplot.pause(interval)
@@ -1,642 +1,642
1 '''
1 '''
2 Created on Aug 1, 2017
2 Created on Aug 1, 2017
3
3
4 @author: Juan C. Espinoza
4 @author: Juan C. Espinoza
5 '''
5 '''
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import time
9 import time
10 import json
10 import json
11 import glob
11 import glob
12 import datetime
12 import datetime
13
13
14 import numpy
14 import numpy
15 import h5py
15 import h5py
16
16
17 from schainpy.model.io.jroIO_base import JRODataReader
17 from schainpy.model.io.jroIO_base import JRODataReader
18 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
18 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
19 from schainpy.model.data.jrodata import Parameters
19 from schainpy.model.data.jrodata import Parameters
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 try:
22 try:
23 import madrigal.cedar
23 import madrigal.cedar
24 except:
24 except:
25 log.warning(
25 log.warning(
26 'You should install "madrigal library" module if you want to read/write Madrigal data'
26 'You should install "madrigal library" module if you want to read/write Madrigal data'
27 )
27 )
28
28
29 DEF_CATALOG = {
29 DEF_CATALOG = {
30 'principleInvestigator': 'Marco Milla',
30 'principleInvestigator': 'Marco Milla',
31 'expPurpose': None,
31 'expPurpose': None,
32 'cycleTime': None,
32 'cycleTime': None,
33 'correlativeExp': None,
33 'correlativeExp': None,
34 'sciRemarks': None,
34 'sciRemarks': None,
35 'instRemarks': None
35 'instRemarks': None
36 }
36 }
37 DEF_HEADER = {
37 DEF_HEADER = {
38 'kindatDesc': None,
38 'kindatDesc': None,
39 'analyst': 'Jicamarca User',
39 'analyst': 'Jicamarca User',
40 'comments': None,
40 'comments': None,
41 'history': None
41 'history': None
42 }
42 }
43 MNEMONICS = {
43 MNEMONICS = {
44 10: 'jro',
44 10: 'jro',
45 11: 'jbr',
45 11: 'jbr',
46 840: 'jul',
46 840: 'jul',
47 13: 'jas',
47 13: 'jas',
48 1000: 'pbr',
48 1000: 'pbr',
49 1001: 'hbr',
49 1001: 'hbr',
50 1002: 'obr',
50 1002: 'obr',
51 }
51 }
52
52
53 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
53 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
54
54
55 def load_json(obj):
55 def load_json(obj):
56 '''
56 '''
57 Parse json as string instead of unicode
57 Parse json as string instead of unicode
58 '''
58 '''
59
59
60 if isinstance(obj, str):
60 if isinstance(obj, str):
61 iterable = json.loads(obj)
61 iterable = json.loads(obj)
62 else:
62 else:
63 iterable = obj
63 iterable = obj
64
64
65 if isinstance(iterable, dict):
65 if isinstance(iterable, dict):
66 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, str) else v
66 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, str) else v
67 for k, v in list(iterable.items())}
67 for k, v in list(iterable.items())}
68 elif isinstance(iterable, (list, tuple)):
68 elif isinstance(iterable, (list, tuple)):
69 return [str(v) if isinstance(v, str) else v for v in iterable]
69 return [str(v) if isinstance(v, str) else v for v in iterable]
70
70
71 return iterable
71 return iterable
72
72
73 @MPDecorator
73 @MPDecorator
74 class MADReader(JRODataReader, ProcessingUnit):
74 class MADReader(JRODataReader, ProcessingUnit):
75
75
76 def __init__(self):
76 def __init__(self):
77
77
78 ProcessingUnit.__init__(self)
78 ProcessingUnit.__init__(self)
79
79
80 self.dataOut = Parameters()
80 self.dataOut = Parameters()
81 self.counter_records = 0
81 self.counter_records = 0
82 self.nrecords = None
82 self.nrecords = None
83 self.flagNoMoreFiles = 0
83 self.flagNoMoreFiles = 0
84 self.isConfig = False
84 self.isConfig = False
85 self.filename = None
85 self.filename = None
86 self.intervals = set()
86 self.intervals = set()
87
87
88 def setup(self,
88 def setup(self,
89 path=None,
89 path=None,
90 startDate=None,
90 startDate=None,
91 endDate=None,
91 endDate=None,
92 format=None,
92 format=None,
93 startTime=datetime.time(0, 0, 0),
93 startTime=datetime.time(0, 0, 0),
94 endTime=datetime.time(23, 59, 59),
94 endTime=datetime.time(23, 59, 59),
95 **kwargs):
95 **kwargs):
96
96
97 self.path = path
97 self.path = path
98 self.startDate = startDate
98 self.startDate = startDate
99 self.endDate = endDate
99 self.endDate = endDate
100 self.startTime = startTime
100 self.startTime = startTime
101 self.endTime = endTime
101 self.endTime = endTime
102 self.datatime = datetime.datetime(1900,1,1)
102 self.datatime = datetime.datetime(1900,1,1)
103 self.oneDDict = load_json(kwargs.get('oneDDict',
103 self.oneDDict = load_json(kwargs.get('oneDDict',
104 "{\"GDLATR\":\"lat\", \"GDLONR\":\"lon\"}"))
104 "{\"GDLATR\":\"lat\", \"GDLONR\":\"lon\"}"))
105 self.twoDDict = load_json(kwargs.get('twoDDict',
105 self.twoDDict = load_json(kwargs.get('twoDDict',
106 "{\"GDALT\": \"heightList\"}"))
106 "{\"GDALT\": \"heightList\"}"))
107 self.ind2DList = load_json(kwargs.get('ind2DList',
107 self.ind2DList = load_json(kwargs.get('ind2DList',
108 "[\"GDALT\"]"))
108 "[\"GDALT\"]"))
109 if self.path is None:
109 if self.path is None:
110 raise ValueError('The path is not valid')
110 raise ValueError('The path is not valid')
111
111
112 if format is None:
112 if format is None:
113 raise ValueError('The format is not valid choose simple or hdf5')
113 raise ValueError('The format is not valid choose simple or hdf5')
114 elif format.lower() in ('simple', 'txt'):
114 elif format.lower() in ('simple', 'txt'):
115 self.ext = '.txt'
115 self.ext = '.txt'
116 elif format.lower() in ('cedar',):
116 elif format.lower() in ('cedar',):
117 self.ext = '.001'
117 self.ext = '.001'
118 else:
118 else:
119 self.ext = '.hdf5'
119 self.ext = '.hdf5'
120
120
121 self.search_files(self.path)
121 self.search_files(self.path)
122 self.fileId = 0
122 self.fileId = 0
123
123
124 if not self.fileList:
124 if not self.fileList:
125 raise Warning('There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path))
125 raise Warning('There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path))
126
126
127 self.setNextFile()
127 self.setNextFile()
128
128
129 def search_files(self, path):
129 def search_files(self, path):
130 '''
130 '''
131 Searching for madrigal files in path
131 Searching for madrigal files in path
132 Creating a list of files to procces included in [startDate,endDate]
132 Creating a list of files to procces included in [startDate,endDate]
133
133
134 Input:
134 Input:
135 path - Path to find files
135 path - Path to find files
136 '''
136 '''
137
137
138 log.log('Searching files {} in {} '.format(self.ext, path), 'MADReader')
138 log.log('Searching files {} in {} '.format(self.ext, path), 'MADReader')
139 foldercounter = 0
139 foldercounter = 0
140 fileList0 = glob.glob1(path, '*{}'.format(self.ext))
140 fileList0 = glob.glob1(path, '*{}'.format(self.ext))
141 fileList0.sort()
141 fileList0.sort()
142
142
143 self.fileList = []
143 self.fileList = []
144 self.dateFileList = []
144 self.dateFileList = []
145
145
146 startDate = self.startDate - datetime.timedelta(1)
146 startDate = self.startDate - datetime.timedelta(1)
147 endDate = self.endDate + datetime.timedelta(1)
147 endDate = self.endDate + datetime.timedelta(1)
148
148
149 for thisFile in fileList0:
149 for thisFile in fileList0:
150 year = thisFile[3:7]
150 year = thisFile[3:7]
151 if not year.isdigit():
151 if not year.isdigit():
152 continue
152 continue
153
153
154 month = thisFile[7:9]
154 month = thisFile[7:9]
155 if not month.isdigit():
155 if not month.isdigit():
156 continue
156 continue
157
157
158 day = thisFile[9:11]
158 day = thisFile[9:11]
159 if not day.isdigit():
159 if not day.isdigit():
160 continue
160 continue
161
161
162 year, month, day = int(year), int(month), int(day)
162 year, month, day = int(year), int(month), int(day)
163 dateFile = datetime.date(year, month, day)
163 dateFile = datetime.date(year, month, day)
164
164
165 if (startDate > dateFile) or (endDate < dateFile):
165 if (startDate > dateFile) or (endDate < dateFile):
166 continue
166 continue
167
167
168 self.fileList.append(thisFile)
168 self.fileList.append(thisFile)
169 self.dateFileList.append(dateFile)
169 self.dateFileList.append(dateFile)
170
170
171 return
171 return
172
172
173 def parseHeader(self):
173 def parseHeader(self):
174 '''
174 '''
175 '''
175 '''
176
176
177 self.output = {}
177 self.output = {}
178 self.version = '2'
178 self.version = '2'
179 s_parameters = None
179 s_parameters = None
180 if self.ext == '.txt':
180 if self.ext == '.txt':
181 self.parameters = [s.strip().lower() for s in self.fp.readline().strip().split(' ') if s]
181 self.parameters = [s.strip().lower() for s in self.fp.readline().strip().split(' ') if s]
182 elif self.ext == '.hdf5':
182 elif self.ext == '.hdf5':
183 metadata = self.fp['Metadata']
183 metadata = self.fp['Metadata']
184 data = self.fp['Data']['Array Layout']
184 data = self.fp['Data']['Array Layout']
185 if 'Independent Spatial Parameters' in metadata:
185 if 'Independent Spatial Parameters' in metadata:
186 s_parameters = [s[0].lower() for s in metadata['Independent Spatial Parameters']]
186 s_parameters = [s[0].lower() for s in metadata['Independent Spatial Parameters']]
187 self.version = '3'
187 self.version = '3'
188 one = [s[0].lower() for s in data['1D Parameters']['Data Parameters']]
188 one = [s[0].lower() for s in data['1D Parameters']['Data Parameters']]
189 one_d = [1 for s in one]
189 one_d = [1 for s in one]
190 two = [s[0].lower() for s in data['2D Parameters']['Data Parameters']]
190 two = [s[0].lower() for s in data['2D Parameters']['Data Parameters']]
191 two_d = [2 for s in two]
191 two_d = [2 for s in two]
192 self.parameters = one + two
192 self.parameters = one + two
193 self.parameters_d = one_d + two_d
193 self.parameters_d = one_d + two_d
194
194
195 log.success('Parameters found: {}'.format(','.join(self.parameters)),
195 log.success('Parameters found: {}'.format(','.join(str(self.parameters))),
196 'MADReader')
196 'MADReader')
197 if s_parameters:
197 if s_parameters:
198 log.success('Spatial parameters: {}'.format(','.join(s_parameters)),
198 log.success('Spatial parameters: {}'.format(','.join(str(s_parameters))),
199 'MADReader')
199 'MADReader')
200
200
201 for param in list(self.oneDDict.keys()):
201 for param in list(self.oneDDict.keys()):
202 if param.lower() not in self.parameters:
202 if param.lower() not in self.parameters:
203 log.warning(
203 log.warning(
204 'Parameter {} not found will be ignored'.format(
204 'Parameter {} not found will be ignored'.format(
205 param),
205 param),
206 'MADReader')
206 'MADReader')
207 self.oneDDict.pop(param, None)
207 self.oneDDict.pop(param, None)
208
208
209 for param, value in list(self.twoDDict.items()):
209 for param, value in list(self.twoDDict.items()):
210 if param.lower() not in self.parameters:
210 if param.lower() not in self.parameters:
211 log.warning(
211 log.warning(
212 'Parameter {} not found, it will be ignored'.format(
212 'Parameter {} not found, it will be ignored'.format(
213 param),
213 param),
214 'MADReader')
214 'MADReader')
215 self.twoDDict.pop(param, None)
215 self.twoDDict.pop(param, None)
216 continue
216 continue
217 if isinstance(value, list):
217 if isinstance(value, list):
218 if value[0] not in self.output:
218 if value[0] not in self.output:
219 self.output[value[0]] = []
219 self.output[value[0]] = []
220 self.output[value[0]].append(None)
220 self.output[value[0]].append(None)
221
221
222 def parseData(self):
222 def parseData(self):
223 '''
223 '''
224 '''
224 '''
225
225
226 if self.ext == '.txt':
226 if self.ext == '.txt':
227 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
227 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
228 self.nrecords = self.data.shape[0]
228 self.nrecords = self.data.shape[0]
229 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.ind2DList[0].lower())])
229 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.ind2DList[0].lower())])
230 elif self.ext == '.hdf5':
230 elif self.ext == '.hdf5':
231 self.data = self.fp['Data']['Array Layout']
231 self.data = self.fp['Data']['Array Layout']
232 self.nrecords = len(self.data['timestamps'].value)
232 self.nrecords = len(self.data['timestamps'].value)
233 self.ranges = self.data['range'].value
233 self.ranges = self.data['range'].value
234
234
235 def setNextFile(self):
235 def setNextFile(self):
236 '''
236 '''
237 '''
237 '''
238
238
239 file_id = self.fileId
239 file_id = self.fileId
240
240
241 if file_id == len(self.fileList):
241 if file_id == len(self.fileList):
242 log.success('No more files', 'MADReader')
242 log.success('No more files', 'MADReader')
243 self.flagNoMoreFiles = 1
243 self.flagNoMoreFiles = 1
244 return 0
244 return 0
245
245
246 log.success(
246 log.success(
247 'Opening: {}'.format(self.fileList[file_id]),
247 'Opening: {}'.format(self.fileList[file_id]),
248 'MADReader'
248 'MADReader'
249 )
249 )
250
250
251 filename = os.path.join(self.path, self.fileList[file_id])
251 filename = os.path.join(self.path, self.fileList[file_id])
252
252
253 if self.filename is not None:
253 if self.filename is not None:
254 self.fp.close()
254 self.fp.close()
255
255
256 self.filename = filename
256 self.filename = filename
257 self.filedate = self.dateFileList[file_id]
257 self.filedate = self.dateFileList[file_id]
258
258
259 if self.ext=='.hdf5':
259 if self.ext=='.hdf5':
260 self.fp = h5py.File(self.filename, 'r')
260 self.fp = h5py.File(self.filename, 'r')
261 else:
261 else:
262 self.fp = open(self.filename, 'rb')
262 self.fp = open(self.filename, 'rb')
263
263
264 self.parseHeader()
264 self.parseHeader()
265 self.parseData()
265 self.parseData()
266 self.sizeOfFile = os.path.getsize(self.filename)
266 self.sizeOfFile = os.path.getsize(self.filename)
267 self.counter_records = 0
267 self.counter_records = 0
268 self.flagIsNewFile = 0
268 self.flagIsNewFile = 0
269 self.fileId += 1
269 self.fileId += 1
270
270
271 return 1
271 return 1
272
272
273 def readNextBlock(self):
273 def readNextBlock(self):
274
274
275 while True:
275 while True:
276 self.flagDiscontinuousBlock = 0
276 self.flagDiscontinuousBlock = 0
277 if self.flagIsNewFile:
277 if self.flagIsNewFile:
278 if not self.setNextFile():
278 if not self.setNextFile():
279 return 0
279 return 0
280
280
281 self.readBlock()
281 self.readBlock()
282
282
283 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
283 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
284 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
284 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
285 log.warning(
285 log.warning(
286 'Reading Record No. {}/{} -> {} [Skipping]'.format(
286 'Reading Record No. {}/{} -> {} [Skipping]'.format(
287 self.counter_records,
287 self.counter_records,
288 self.nrecords,
288 self.nrecords,
289 self.datatime.ctime()),
289 self.datatime.ctime()),
290 'MADReader')
290 'MADReader')
291 continue
291 continue
292 break
292 break
293
293
294 log.log(
294 log.log(
295 'Reading Record No. {}/{} -> {}'.format(
295 'Reading Record No. {}/{} -> {}'.format(
296 self.counter_records,
296 self.counter_records,
297 self.nrecords,
297 self.nrecords,
298 self.datatime.ctime()),
298 self.datatime.ctime()),
299 'MADReader')
299 'MADReader')
300
300
301 return 1
301 return 1
302
302
303 def readBlock(self):
303 def readBlock(self):
304 '''
304 '''
305 '''
305 '''
306 dum = []
306 dum = []
307 if self.ext == '.txt':
307 if self.ext == '.txt':
308 dt = self.data[self.counter_records][:6].astype(int)
308 dt = self.data[self.counter_records][:6].astype(int)
309 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
309 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
310 self.flagDiscontinuousBlock = 1
310 self.flagDiscontinuousBlock = 1
311 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
311 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
312 while True:
312 while True:
313 dt = self.data[self.counter_records][:6].astype(int)
313 dt = self.data[self.counter_records][:6].astype(int)
314 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
314 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
315 if datatime == self.datatime:
315 if datatime == self.datatime:
316 dum.append(self.data[self.counter_records])
316 dum.append(self.data[self.counter_records])
317 self.counter_records += 1
317 self.counter_records += 1
318 if self.counter_records == self.nrecords:
318 if self.counter_records == self.nrecords:
319 self.flagIsNewFile = True
319 self.flagIsNewFile = True
320 break
320 break
321 continue
321 continue
322 self.intervals.add((datatime-self.datatime).seconds)
322 self.intervals.add((datatime-self.datatime).seconds)
323 break
323 break
324 elif self.ext == '.hdf5':
324 elif self.ext == '.hdf5':
325 datatime = datetime.datetime.utcfromtimestamp(
325 datatime = datetime.datetime.utcfromtimestamp(
326 self.data['timestamps'][self.counter_records])
326 self.data['timestamps'][self.counter_records])
327 nHeights = len(self.ranges)
327 nHeights = len(self.ranges)
328 for n, param in enumerate(self.parameters):
328 for n, param in enumerate(self.parameters):
329 if self.parameters_d[n] == 1:
329 if self.parameters_d[n] == 1:
330 dum.append(numpy.ones(nHeights)*self.data['1D Parameters'][param][self.counter_records])
330 dum.append(numpy.ones(nHeights)*self.data['1D Parameters'][param][self.counter_records])
331 else:
331 else:
332 if self.version == '2':
332 if self.version == '2':
333 dum.append(self.data['2D Parameters'][param][self.counter_records])
333 dum.append(self.data['2D Parameters'][param][self.counter_records])
334 else:
334 else:
335 tmp = self.data['2D Parameters'][param].value.T
335 tmp = self.data['2D Parameters'][param].value.T
336 dum.append(tmp[self.counter_records])
336 dum.append(tmp[self.counter_records])
337 self.intervals.add((datatime-self.datatime).seconds)
337 self.intervals.add((datatime-self.datatime).seconds)
338 if datatime.date()>self.datatime.date():
338 if datatime.date()>self.datatime.date():
339 self.flagDiscontinuousBlock = 1
339 self.flagDiscontinuousBlock = 1
340 self.datatime = datatime
340 self.datatime = datatime
341 self.counter_records += 1
341 self.counter_records += 1
342 if self.counter_records == self.nrecords:
342 if self.counter_records == self.nrecords:
343 self.flagIsNewFile = True
343 self.flagIsNewFile = True
344
344
345 self.buffer = numpy.array(dum)
345 self.buffer = numpy.array(dum)
346 return
346 return
347
347
348 def set_output(self):
348 def set_output(self):
349 '''
349 '''
350 Storing data from buffer to dataOut object
350 Storing data from buffer to dataOut object
351 '''
351 '''
352
352
353 parameters = [None for __ in self.parameters]
353 parameters = [None for __ in self.parameters]
354
354
355 for param, attr in list(self.oneDDict.items()):
355 for param, attr in list(self.oneDDict.items()):
356 x = self.parameters.index(param.lower())
356 x = self.parameters.index(param.lower())
357 setattr(self.dataOut, attr, self.buffer[0][x])
357 setattr(self.dataOut, attr, self.buffer[0][x])
358
358
359 for param, value in list(self.twoDDict.items()):
359 for param, value in list(self.twoDDict.items()):
360 x = self.parameters.index(param.lower())
360 x = self.parameters.index(param.lower())
361 if self.ext == '.txt':
361 if self.ext == '.txt':
362 y = self.parameters.index(self.ind2DList[0].lower())
362 y = self.parameters.index(self.ind2DList[0].lower())
363 ranges = self.buffer[:,y]
363 ranges = self.buffer[:,y]
364 if self.ranges.size == ranges.size:
364 if self.ranges.size == ranges.size:
365 continue
365 continue
366 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
366 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
367 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
367 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
368 dummy[index] = self.buffer[:,x]
368 dummy[index] = self.buffer[:,x]
369 else:
369 else:
370 dummy = self.buffer[x]
370 dummy = self.buffer[x]
371
371
372 if isinstance(value, str):
372 if isinstance(value, str):
373 if value not in self.ind2DList:
373 if value not in self.ind2DList:
374 setattr(self.dataOut, value, dummy.reshape(1,-1))
374 setattr(self.dataOut, value, dummy.reshape(1,-1))
375 elif isinstance(value, list):
375 elif isinstance(value, list):
376 self.output[value[0]][value[1]] = dummy
376 self.output[value[0]][value[1]] = dummy
377 parameters[value[1]] = param
377 parameters[value[1]] = param
378
378
379 for key, value in list(self.output.items()):
379 for key, value in list(self.output.items()):
380 setattr(self.dataOut, key, numpy.array(value))
380 setattr(self.dataOut, key, numpy.array(value))
381
381
382 self.dataOut.parameters = [s for s in parameters if s]
382 self.dataOut.parameters = [s for s in parameters if s]
383 self.dataOut.heightList = self.ranges
383 self.dataOut.heightList = self.ranges
384 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
384 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
385 self.dataOut.utctimeInit = self.dataOut.utctime
385 self.dataOut.utctimeInit = self.dataOut.utctime
386 self.dataOut.paramInterval = min(self.intervals)
386 self.dataOut.paramInterval = min(self.intervals)
387 self.dataOut.useLocalTime = False
387 self.dataOut.useLocalTime = False
388 self.dataOut.flagNoData = False
388 self.dataOut.flagNoData = False
389 self.dataOut.nrecords = self.nrecords
389 self.dataOut.nrecords = self.nrecords
390 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
390 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
391
391
392 def getData(self):
392 def getData(self):
393 '''
393 '''
394 Storing data from databuffer to dataOut object
394 Storing data from databuffer to dataOut object
395 '''
395 '''
396 if self.flagNoMoreFiles:
396 if self.flagNoMoreFiles:
397 self.dataOut.flagNoData = True
397 self.dataOut.flagNoData = True
398 self.dataOut.error = 'No file left to process'
398 self.dataOut.error = 'No file left to process'
399 return 0
399 return 0
400
400
401 if not self.readNextBlock():
401 if not self.readNextBlock():
402 self.dataOut.flagNoData = True
402 self.dataOut.flagNoData = True
403 return 0
403 return 0
404
404
405 self.set_output()
405 self.set_output()
406
406
407 return 1
407 return 1
408
408
409
409
410 class MADWriter(Operation):
410 class MADWriter(Operation):
411
411
412 missing = -32767
412 missing = -32767
413
413
414 def __init__(self, **kwargs):
414 def __init__(self, **kwargs):
415
415
416 Operation.__init__(self, **kwargs)
416 Operation.__init__(self, **kwargs)
417 self.dataOut = Parameters()
417 self.dataOut = Parameters()
418 self.counter = 0
418 self.counter = 0
419 self.path = None
419 self.path = None
420 self.fp = None
420 self.fp = None
421
421
422 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
422 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
423 metadata='{}', format='cedar', **kwargs):
423 metadata='{}', format='cedar', **kwargs):
424 '''
424 '''
425 Inputs:
425 Inputs:
426 path - path where files will be created
426 path - path where files will be created
427 oneDDict - json of one-dimensional parameters in record where keys
427 oneDDict - json of one-dimensional parameters in record where keys
428 are Madrigal codes (integers or mnemonics) and values the corresponding
428 are Madrigal codes (integers or mnemonics) and values the corresponding
429 dataOut attribute e.g: {
429 dataOut attribute e.g: {
430 'gdlatr': 'lat',
430 'gdlatr': 'lat',
431 'gdlonr': 'lon',
431 'gdlonr': 'lon',
432 'gdlat2':'lat',
432 'gdlat2':'lat',
433 'glon2':'lon'}
433 'glon2':'lon'}
434 ind2DList - list of independent spatial two-dimensional parameters e.g:
434 ind2DList - list of independent spatial two-dimensional parameters e.g:
435 ['heighList']
435 ['heighList']
436 twoDDict - json of two-dimensional parameters in record where keys
436 twoDDict - json of two-dimensional parameters in record where keys
437 are Madrigal codes (integers or mnemonics) and values the corresponding
437 are Madrigal codes (integers or mnemonics) and values the corresponding
438 dataOut attribute if multidimensional array specify as tupple
438 dataOut attribute if multidimensional array specify as tupple
439 ('attr', pos) e.g: {
439 ('attr', pos) e.g: {
440 'gdalt': 'heightList',
440 'gdalt': 'heightList',
441 'vn1p2': ('data_output', 0),
441 'vn1p2': ('data_output', 0),
442 'vn2p2': ('data_output', 1),
442 'vn2p2': ('data_output', 1),
443 'vn3': ('data_output', 2),
443 'vn3': ('data_output', 2),
444 'snl': ('data_SNR', 'db')
444 'snl': ('data_SNR', 'db')
445 }
445 }
446 metadata - json of madrigal metadata (kinst, kindat, catalog and header)
446 metadata - json of madrigal metadata (kinst, kindat, catalog and header)
447 '''
447 '''
448 if not self.isConfig:
448 if not self.isConfig:
449 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
449 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
450 self.isConfig = True
450 self.isConfig = True
451
451
452 self.dataOut = dataOut
452 self.dataOut = dataOut
453 self.putData()
453 self.putData()
454 return
454 return
455
455
456 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
456 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
457 '''
457 '''
458 Configure Operation
458 Configure Operation
459 '''
459 '''
460
460
461 self.path = path
461 self.path = path
462 self.blocks = kwargs.get('blocks', None)
462 self.blocks = kwargs.get('blocks', None)
463 self.counter = 0
463 self.counter = 0
464 self.oneDDict = load_json(oneDDict)
464 self.oneDDict = load_json(oneDDict)
465 self.twoDDict = load_json(twoDDict)
465 self.twoDDict = load_json(twoDDict)
466 self.ind2DList = load_json(ind2DList)
466 self.ind2DList = load_json(ind2DList)
467 meta = load_json(metadata)
467 meta = load_json(metadata)
468 self.kinst = meta.get('kinst')
468 self.kinst = meta.get('kinst')
469 self.kindat = meta.get('kindat')
469 self.kindat = meta.get('kindat')
470 self.catalog = meta.get('catalog', DEF_CATALOG)
470 self.catalog = meta.get('catalog', DEF_CATALOG)
471 self.header = meta.get('header', DEF_HEADER)
471 self.header = meta.get('header', DEF_HEADER)
472 if format == 'cedar':
472 if format == 'cedar':
473 self.ext = '.dat'
473 self.ext = '.dat'
474 self.extra_args = {}
474 self.extra_args = {}
475 elif format == 'hdf5':
475 elif format == 'hdf5':
476 self.ext = '.hdf5'
476 self.ext = '.hdf5'
477 self.extra_args = {'ind2DList': self.ind2DList}
477 self.extra_args = {'ind2DList': self.ind2DList}
478
478
479 self.keys = [k.lower() for k in self.twoDDict]
479 self.keys = [k.lower() for k in self.twoDDict]
480 if 'range' in self.keys:
480 if 'range' in self.keys:
481 self.keys.remove('range')
481 self.keys.remove('range')
482 if 'gdalt' in self.keys:
482 if 'gdalt' in self.keys:
483 self.keys.remove('gdalt')
483 self.keys.remove('gdalt')
484
484
485 def setFile(self):
485 def setFile(self):
486 '''
486 '''
487 Create new cedar file object
487 Create new cedar file object
488 '''
488 '''
489
489
490 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
490 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
491 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
491 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
492
492
493 filename = '{}{}{}'.format(self.mnemonic,
493 filename = '{}{}{}'.format(self.mnemonic,
494 date.strftime('%Y%m%d_%H%M%S'),
494 date.strftime('%Y%m%d_%H%M%S'),
495 self.ext)
495 self.ext)
496
496
497 self.fullname = os.path.join(self.path, filename)
497 self.fullname = os.path.join(self.path, filename)
498
498
499 if os.path.isfile(self.fullname) :
499 if os.path.isfile(self.fullname) :
500 log.warning(
500 log.warning(
501 'Destination file {} already exists, previous file deleted.'.format(
501 'Destination file {} already exists, previous file deleted.'.format(
502 self.fullname),
502 self.fullname),
503 'MADWriter')
503 'MADWriter')
504 os.remove(self.fullname)
504 os.remove(self.fullname)
505
505
506 try:
506 try:
507 log.success(
507 log.success(
508 'Creating file: {}'.format(self.fullname),
508 'Creating file: {}'.format(self.fullname),
509 'MADWriter')
509 'MADWriter')
510 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
510 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
511 except ValueError as e:
511 except ValueError as e:
512 log.error(
512 log.error(
513 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
513 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
514 'MADWriter')
514 'MADWriter')
515 return
515 return
516
516
517 return 1
517 return 1
518
518
519 def writeBlock(self):
519 def writeBlock(self):
520 '''
520 '''
521 Add data records to cedar file taking data from oneDDict and twoDDict
521 Add data records to cedar file taking data from oneDDict and twoDDict
522 attributes.
522 attributes.
523 Allowed parameters in: parcodes.tab
523 Allowed parameters in: parcodes.tab
524 '''
524 '''
525
525
526 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
526 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
527 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
527 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
528 heights = self.dataOut.heightList
528 heights = self.dataOut.heightList
529
529
530 if self.ext == '.dat':
530 if self.ext == '.dat':
531 for key, value in list(self.twoDDict.items()):
531 for key, value in list(self.twoDDict.items()):
532 if isinstance(value, str):
532 if isinstance(value, str):
533 data = getattr(self.dataOut, value)
533 data = getattr(self.dataOut, value)
534 invalid = numpy.isnan(data)
534 invalid = numpy.isnan(data)
535 data[invalid] = self.missing
535 data[invalid] = self.missing
536 elif isinstance(value, (tuple, list)):
536 elif isinstance(value, (tuple, list)):
537 attr, key = value
537 attr, key = value
538 data = getattr(self.dataOut, attr)
538 data = getattr(self.dataOut, attr)
539 invalid = numpy.isnan(data)
539 invalid = numpy.isnan(data)
540 data[invalid] = self.missing
540 data[invalid] = self.missing
541
541
542 out = {}
542 out = {}
543 for key, value in list(self.twoDDict.items()):
543 for key, value in list(self.twoDDict.items()):
544 key = key.lower()
544 key = key.lower()
545 if isinstance(value, str):
545 if isinstance(value, str):
546 if 'db' in value.lower():
546 if 'db' in value.lower():
547 tmp = getattr(self.dataOut, value.replace('_db', ''))
547 tmp = getattr(self.dataOut, value.replace('_db', ''))
548 SNRavg = numpy.average(tmp, axis=0)
548 SNRavg = numpy.average(tmp, axis=0)
549 tmp = 10*numpy.log10(SNRavg)
549 tmp = 10*numpy.log10(SNRavg)
550 else:
550 else:
551 tmp = getattr(self.dataOut, value)
551 tmp = getattr(self.dataOut, value)
552 out[key] = tmp.flatten()
552 out[key] = tmp.flatten()
553 elif isinstance(value, (tuple, list)):
553 elif isinstance(value, (tuple, list)):
554 attr, x = value
554 attr, x = value
555 data = getattr(self.dataOut, attr)
555 data = getattr(self.dataOut, attr)
556 out[key] = data[int(x)]
556 out[key] = data[int(x)]
557
557
558 a = numpy.array([out[k] for k in self.keys])
558 a = numpy.array([out[k] for k in self.keys])
559 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
559 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
560 index = numpy.where(nrows == False)[0]
560 index = numpy.where(nrows == False)[0]
561
561
562 rec = madrigal.cedar.MadrigalDataRecord(
562 rec = madrigal.cedar.MadrigalDataRecord(
563 self.kinst,
563 self.kinst,
564 self.kindat,
564 self.kindat,
565 startTime.year,
565 startTime.year,
566 startTime.month,
566 startTime.month,
567 startTime.day,
567 startTime.day,
568 startTime.hour,
568 startTime.hour,
569 startTime.minute,
569 startTime.minute,
570 startTime.second,
570 startTime.second,
571 startTime.microsecond/10000,
571 startTime.microsecond/10000,
572 endTime.year,
572 endTime.year,
573 endTime.month,
573 endTime.month,
574 endTime.day,
574 endTime.day,
575 endTime.hour,
575 endTime.hour,
576 endTime.minute,
576 endTime.minute,
577 endTime.second,
577 endTime.second,
578 endTime.microsecond/10000,
578 endTime.microsecond/10000,
579 list(self.oneDDict.keys()),
579 list(self.oneDDict.keys()),
580 list(self.twoDDict.keys()),
580 list(self.twoDDict.keys()),
581 len(index),
581 len(index),
582 **self.extra_args
582 **self.extra_args
583 )
583 )
584
584
585 # Setting 1d values
585 # Setting 1d values
586 for key in self.oneDDict:
586 for key in self.oneDDict:
587 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
587 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
588
588
589 # Setting 2d values
589 # Setting 2d values
590 nrec = 0
590 nrec = 0
591 for n in index:
591 for n in index:
592 for key in out:
592 for key in out:
593 rec.set2D(key, nrec, out[key][n])
593 rec.set2D(key, nrec, out[key][n])
594 nrec += 1
594 nrec += 1
595
595
596 self.fp.append(rec)
596 self.fp.append(rec)
597 if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0:
597 if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0:
598 self.fp.dump()
598 self.fp.dump()
599 if self.counter % 100 == 0 and self.counter > 0:
599 if self.counter % 100 == 0 and self.counter > 0:
600 log.log(
600 log.log(
601 'Writing {} records'.format(
601 'Writing {} records'.format(
602 self.counter),
602 self.counter),
603 'MADWriter')
603 'MADWriter')
604
604
605 def setHeader(self):
605 def setHeader(self):
606 '''
606 '''
607 Create an add catalog and header to cedar file
607 Create an add catalog and header to cedar file
608 '''
608 '''
609
609
610 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
610 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
611
611
612 if self.ext == '.dat':
612 if self.ext == '.dat':
613 self.fp.write()
613 self.fp.write()
614 else:
614 else:
615 self.fp.dump()
615 self.fp.dump()
616 self.fp.close()
616 self.fp.close()
617
617
618 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
618 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
619 header.createCatalog(**self.catalog)
619 header.createCatalog(**self.catalog)
620 header.createHeader(**self.header)
620 header.createHeader(**self.header)
621 header.write()
621 header.write()
622
622
623 def putData(self):
623 def putData(self):
624
624
625 if self.dataOut.flagNoData:
625 if self.dataOut.flagNoData:
626 return 0
626 return 0
627
627
628 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
628 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
629 if self.counter > 0:
629 if self.counter > 0:
630 self.setHeader()
630 self.setHeader()
631 self.counter = 0
631 self.counter = 0
632
632
633 if self.counter == 0:
633 if self.counter == 0:
634 self.setFile()
634 self.setFile()
635
635
636 self.writeBlock()
636 self.writeBlock()
637 self.counter += 1
637 self.counter += 1
638
638
639 def close(self):
639 def close(self):
640
640
641 if self.counter > 0:
641 if self.counter > 0:
642 self.setHeader() No newline at end of file
642 self.setHeader()
@@ -1,3856 +1,3857
1 import numpy
1 import numpy
2 import math
2 import math
3 from scipy import optimize, interpolate, signal, stats, ndimage
3 from scipy import optimize, interpolate, signal, stats, ndimage
4 import scipy
4 import scipy
5 import re
5 import re
6 import datetime
6 import datetime
7 import copy
7 import copy
8 import sys
8 import sys
9 import importlib
9 import importlib
10 import itertools
10 import itertools
11 from multiprocessing import Pool, TimeoutError
11 from multiprocessing import Pool, TimeoutError
12 from multiprocessing.pool import ThreadPool
12 from multiprocessing.pool import ThreadPool
13 import time
13 import time
14
14
15 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
15 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
16 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
16 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
17 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
17 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
18 from scipy import asarray as ar,exp
18 from scipy import asarray as ar,exp
19 from scipy.optimize import curve_fit
19 from scipy.optimize import curve_fit
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import warnings
21 import warnings
22 from numpy import NaN
22 from numpy import NaN
23 from scipy.optimize.optimize import OptimizeWarning
23 from scipy.optimize.optimize import OptimizeWarning
24 warnings.filterwarnings('ignore')
24 warnings.filterwarnings('ignore')
25
25
26
26
27 SPEED_OF_LIGHT = 299792458
27 SPEED_OF_LIGHT = 299792458
28
28
29
29
30 '''solving pickling issue'''
30 '''solving pickling issue'''
31
31
32 def _pickle_method(method):
32 def _pickle_method(method):
33 func_name = method.__func__.__name__
33 func_name = method.__func__.__name__
34 obj = method.__self__
34 obj = method.__self__
35 cls = method.__self__.__class__
35 cls = method.__self__.__class__
36 return _unpickle_method, (func_name, obj, cls)
36 return _unpickle_method, (func_name, obj, cls)
37
37
38 def _unpickle_method(func_name, obj, cls):
38 def _unpickle_method(func_name, obj, cls):
39 for cls in cls.mro():
39 for cls in cls.mro():
40 try:
40 try:
41 func = cls.__dict__[func_name]
41 func = cls.__dict__[func_name]
42 except KeyError:
42 except KeyError:
43 pass
43 pass
44 else:
44 else:
45 break
45 break
46 return func.__get__(obj, cls)
46 return func.__get__(obj, cls)
47
47
48 @MPDecorator
48 @MPDecorator
49 class ParametersProc(ProcessingUnit):
49 class ParametersProc(ProcessingUnit):
50
50
51 METHODS = {}
51 METHODS = {}
52 nSeconds = None
52 nSeconds = None
53
53
54 def __init__(self):
54 def __init__(self):
55 ProcessingUnit.__init__(self)
55 ProcessingUnit.__init__(self)
56
56
57 # self.objectDict = {}
57 # self.objectDict = {}
58 self.buffer = None
58 self.buffer = None
59 self.firstdatatime = None
59 self.firstdatatime = None
60 self.profIndex = 0
60 self.profIndex = 0
61 self.dataOut = Parameters()
61 self.dataOut = Parameters()
62 self.setupReq = False #Agregar a todas las unidades de proc
62 self.setupReq = False #Agregar a todas las unidades de proc
63
63
64 def __updateObjFromInput(self):
64 def __updateObjFromInput(self):
65
65
66 self.dataOut.inputUnit = self.dataIn.type
66 self.dataOut.inputUnit = self.dataIn.type
67
67
68 self.dataOut.timeZone = self.dataIn.timeZone
68 self.dataOut.timeZone = self.dataIn.timeZone
69 self.dataOut.dstFlag = self.dataIn.dstFlag
69 self.dataOut.dstFlag = self.dataIn.dstFlag
70 self.dataOut.errorCount = self.dataIn.errorCount
70 self.dataOut.errorCount = self.dataIn.errorCount
71 self.dataOut.useLocalTime = self.dataIn.useLocalTime
71 self.dataOut.useLocalTime = self.dataIn.useLocalTime
72
72
73 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
73 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
74 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
74 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
75 self.dataOut.channelList = self.dataIn.channelList
75 self.dataOut.channelList = self.dataIn.channelList
76 self.dataOut.heightList = self.dataIn.heightList
76 self.dataOut.heightList = self.dataIn.heightList
77 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
77 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
78 # self.dataOut.nHeights = self.dataIn.nHeights
78 # self.dataOut.nHeights = self.dataIn.nHeights
79 # self.dataOut.nChannels = self.dataIn.nChannels
79 # self.dataOut.nChannels = self.dataIn.nChannels
80 self.dataOut.nBaud = self.dataIn.nBaud
80 self.dataOut.nBaud = self.dataIn.nBaud
81 self.dataOut.nCode = self.dataIn.nCode
81 self.dataOut.nCode = self.dataIn.nCode
82 self.dataOut.code = self.dataIn.code
82 self.dataOut.code = self.dataIn.code
83 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
83 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
84 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
84 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
85 # self.dataOut.utctime = self.firstdatatime
85 # self.dataOut.utctime = self.firstdatatime
86 self.dataOut.utctime = self.dataIn.utctime
86 self.dataOut.utctime = self.dataIn.utctime
87 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
87 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
88 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
88 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
89 self.dataOut.nCohInt = self.dataIn.nCohInt
89 self.dataOut.nCohInt = self.dataIn.nCohInt
90 # self.dataOut.nIncohInt = 1
90 # self.dataOut.nIncohInt = 1
91 self.dataOut.ippSeconds = self.dataIn.ippSeconds
91 self.dataOut.ippSeconds = self.dataIn.ippSeconds
92 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
92 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
93 self.dataOut.timeInterval1 = self.dataIn.timeInterval
93 self.dataOut.timeInterval1 = self.dataIn.timeInterval
94 self.dataOut.heightList = self.dataIn.getHeiRange()
94 self.dataOut.heightList = self.dataIn.getHeiRange()
95 self.dataOut.frequency = self.dataIn.frequency
95 self.dataOut.frequency = self.dataIn.frequency
96 # self.dataOut.noise = self.dataIn.noise
96 # self.dataOut.noise = self.dataIn.noise
97
97
98 def run(self):
98 def run(self):
99
99
100
100
101
101
102 #---------------------- Voltage Data ---------------------------
102 #---------------------- Voltage Data ---------------------------
103
103
104 if self.dataIn.type == "Voltage":
104 if self.dataIn.type == "Voltage":
105
105
106 self.__updateObjFromInput()
106 self.__updateObjFromInput()
107 self.dataOut.data_pre = self.dataIn.data.copy()
107 self.dataOut.data_pre = self.dataIn.data.copy()
108 self.dataOut.flagNoData = False
108 self.dataOut.flagNoData = False
109 self.dataOut.utctimeInit = self.dataIn.utctime
109 self.dataOut.utctimeInit = self.dataIn.utctime
110 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
110 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
111 return
111 return
112
112
113 #---------------------- Spectra Data ---------------------------
113 #---------------------- Spectra Data ---------------------------
114
114
115 if self.dataIn.type == "Spectra":
115 if self.dataIn.type == "Spectra":
116
116
117 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
117 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
118 self.dataOut.data_spc = self.dataIn.data_spc
118 self.dataOut.data_spc = self.dataIn.data_spc
119 self.dataOut.data_cspc = self.dataIn.data_cspc
119 self.dataOut.data_cspc = self.dataIn.data_cspc
120 self.dataOut.nProfiles = self.dataIn.nProfiles
120 self.dataOut.nProfiles = self.dataIn.nProfiles
121 self.dataOut.nIncohInt = self.dataIn.nIncohInt
121 self.dataOut.nIncohInt = self.dataIn.nIncohInt
122 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
122 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
123 self.dataOut.ippFactor = self.dataIn.ippFactor
123 self.dataOut.ippFactor = self.dataIn.ippFactor
124 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
124 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
125 self.dataOut.spc_noise = self.dataIn.getNoise()
125 self.dataOut.spc_noise = self.dataIn.getNoise()
126 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
126 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
127 # self.dataOut.normFactor = self.dataIn.normFactor
127 # self.dataOut.normFactor = self.dataIn.normFactor
128 self.dataOut.pairsList = self.dataIn.pairsList
128 self.dataOut.pairsList = self.dataIn.pairsList
129 self.dataOut.groupList = self.dataIn.pairsList
129 self.dataOut.groupList = self.dataIn.pairsList
130 self.dataOut.flagNoData = False
130 self.dataOut.flagNoData = False
131
131
132 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
132 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
133 self.dataOut.ChanDist = self.dataIn.ChanDist
133 self.dataOut.ChanDist = self.dataIn.ChanDist
134 else: self.dataOut.ChanDist = None
134 else: self.dataOut.ChanDist = None
135
135
136 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
136 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
137 # self.dataOut.VelRange = self.dataIn.VelRange
137 # self.dataOut.VelRange = self.dataIn.VelRange
138 #else: self.dataOut.VelRange = None
138 #else: self.dataOut.VelRange = None
139
139
140 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
140 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
141 self.dataOut.RadarConst = self.dataIn.RadarConst
141 self.dataOut.RadarConst = self.dataIn.RadarConst
142
142
143 if hasattr(self.dataIn, 'NPW'): #NPW
143 if hasattr(self.dataIn, 'NPW'): #NPW
144 self.dataOut.NPW = self.dataIn.NPW
144 self.dataOut.NPW = self.dataIn.NPW
145
145
146 if hasattr(self.dataIn, 'COFA'): #COFA
146 if hasattr(self.dataIn, 'COFA'): #COFA
147 self.dataOut.COFA = self.dataIn.COFA
147 self.dataOut.COFA = self.dataIn.COFA
148
148
149
149
150
150
151 #---------------------- Correlation Data ---------------------------
151 #---------------------- Correlation Data ---------------------------
152
152
153 if self.dataIn.type == "Correlation":
153 if self.dataIn.type == "Correlation":
154 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
154 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
155
155
156 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
156 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
157 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
157 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
158 self.dataOut.groupList = (acf_pairs, ccf_pairs)
158 self.dataOut.groupList = (acf_pairs, ccf_pairs)
159
159
160 self.dataOut.abscissaList = self.dataIn.lagRange
160 self.dataOut.abscissaList = self.dataIn.lagRange
161 self.dataOut.noise = self.dataIn.noise
161 self.dataOut.noise = self.dataIn.noise
162 self.dataOut.data_SNR = self.dataIn.SNR
162 self.dataOut.data_SNR = self.dataIn.SNR
163 self.dataOut.flagNoData = False
163 self.dataOut.flagNoData = False
164 self.dataOut.nAvg = self.dataIn.nAvg
164 self.dataOut.nAvg = self.dataIn.nAvg
165
165
166 #---------------------- Parameters Data ---------------------------
166 #---------------------- Parameters Data ---------------------------
167
167
168 if self.dataIn.type == "Parameters":
168 if self.dataIn.type == "Parameters":
169 self.dataOut.copy(self.dataIn)
169 self.dataOut.copy(self.dataIn)
170 self.dataOut.flagNoData = False
170 self.dataOut.flagNoData = False
171
171
172 return True
172 return True
173
173
174 self.__updateObjFromInput()
174 self.__updateObjFromInput()
175 self.dataOut.utctimeInit = self.dataIn.utctime
175 self.dataOut.utctimeInit = self.dataIn.utctime
176 self.dataOut.paramInterval = self.dataIn.timeInterval
176 self.dataOut.paramInterval = self.dataIn.timeInterval
177
177
178 return
178 return
179
179
180
180
181 def target(tups):
181 def target(tups):
182
182
183 obj, args = tups
183 obj, args = tups
184
184
185 return obj.FitGau(args)
185 return obj.FitGau(args)
186
186
187
187
188 class SpectralFilters(Operation):
188 class SpectralFilters(Operation):
189
189
190 '''This class allows the Rainfall / Wind Selection for CLAIRE RADAR
190 '''This class allows the Rainfall / Wind Selection for CLAIRE RADAR
191
191
192 LimitR : It is the limit in m/s of Rainfall
192 LimitR : It is the limit in m/s of Rainfall
193 LimitW : It is the limit in m/s for Winds
193 LimitW : It is the limit in m/s for Winds
194
194
195 Input:
195 Input:
196
196
197 self.dataOut.data_pre : SPC and CSPC
197 self.dataOut.data_pre : SPC and CSPC
198 self.dataOut.spc_range : To select wind and rainfall velocities
198 self.dataOut.spc_range : To select wind and rainfall velocities
199
199
200 Affected:
200 Affected:
201
201
202 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
202 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
203 self.dataOut.spcparam_range : Used in SpcParamPlot
203 self.dataOut.spcparam_range : Used in SpcParamPlot
204 self.dataOut.SPCparam : Used in PrecipitationProc
204 self.dataOut.SPCparam : Used in PrecipitationProc
205
205
206
206
207 '''
207 '''
208
208
209 def __init__(self):
209 def __init__(self):
210 Operation.__init__(self)
210 Operation.__init__(self)
211 self.i=0
211 self.i=0
212
212
213 def run(self, dataOut, PositiveLimit=1.5, NegativeLimit=2.5):
213 def run(self, dataOut, PositiveLimit=1.5, NegativeLimit=2.5):
214
214
215
215
216 #Limite de vientos
216 #Limite de vientos
217 LimitR = PositiveLimit
217 LimitR = PositiveLimit
218 LimitN = NegativeLimit
218 LimitN = NegativeLimit
219
219
220 self.spc = dataOut.data_pre[0].copy()
220 self.spc = dataOut.data_pre[0].copy()
221 self.cspc = dataOut.data_pre[1].copy()
221 self.cspc = dataOut.data_pre[1].copy()
222
222
223 self.Num_Hei = self.spc.shape[2]
223 self.Num_Hei = self.spc.shape[2]
224 self.Num_Bin = self.spc.shape[1]
224 self.Num_Bin = self.spc.shape[1]
225 self.Num_Chn = self.spc.shape[0]
225 self.Num_Chn = self.spc.shape[0]
226
226
227 VelRange = dataOut.spc_range[2]
227 VelRange = dataOut.spc_range[2]
228 TimeRange = dataOut.spc_range[1]
228 TimeRange = dataOut.spc_range[1]
229 FrecRange = dataOut.spc_range[0]
229 FrecRange = dataOut.spc_range[0]
230
230
231 Vmax= 2*numpy.max(dataOut.spc_range[2])
231 Vmax= 2*numpy.max(dataOut.spc_range[2])
232 Tmax= 2*numpy.max(dataOut.spc_range[1])
232 Tmax= 2*numpy.max(dataOut.spc_range[1])
233 Fmax= 2*numpy.max(dataOut.spc_range[0])
233 Fmax= 2*numpy.max(dataOut.spc_range[0])
234
234
235 Breaker1R=VelRange[numpy.abs(VelRange-(-LimitN)).argmin()]
235 Breaker1R=VelRange[numpy.abs(VelRange-(-LimitN)).argmin()]
236 Breaker1R=numpy.where(VelRange == Breaker1R)
236 Breaker1R=numpy.where(VelRange == Breaker1R)
237
237
238 Delta = self.Num_Bin/2 - Breaker1R[0]
238 Delta = self.Num_Bin/2 - Breaker1R[0]
239
239
240
240
241 '''Reacomodando SPCrange'''
241 '''Reacomodando SPCrange'''
242
243 VelRange=numpy.roll(VelRange,-(int(self.Num_Bin/2)) ,axis=0)
242
244
243 VelRange=numpy.roll(VelRange,-(self.Num_Bin/2) ,axis=0)
245 VelRange[-(int(self.Num_Bin/2)):]+= Vmax
244
245 VelRange[-(self.Num_Bin/2):]+= Vmax
246
246
247 FrecRange=numpy.roll(FrecRange,-(self.Num_Bin/2),axis=0)
247 FrecRange=numpy.roll(FrecRange,-(int(self.Num_Bin/2)),axis=0)
248
248
249 FrecRange[-(self.Num_Bin/2):]+= Fmax
249 FrecRange[-(int(self.Num_Bin/2)):]+= Fmax
250
250
251 TimeRange=numpy.roll(TimeRange,-(self.Num_Bin/2),axis=0)
251 TimeRange=numpy.roll(TimeRange,-(int(self.Num_Bin/2)),axis=0)
252
252
253 TimeRange[-(self.Num_Bin/2):]+= Tmax
253 TimeRange[-(int(self.Num_Bin/2)):]+= Tmax
254
254
255 ''' ------------------ '''
255 ''' ------------------ '''
256
256
257 Breaker2R=VelRange[numpy.abs(VelRange-(LimitR)).argmin()]
257 Breaker2R=VelRange[numpy.abs(VelRange-(LimitR)).argmin()]
258 Breaker2R=numpy.where(VelRange == Breaker2R)
258 Breaker2R=numpy.where(VelRange == Breaker2R)
259
259
260
260
261 SPCroll = numpy.roll(self.spc,-(self.Num_Bin/2) ,axis=1)
261 SPCroll = numpy.roll(self.spc,-(int(self.Num_Bin/2)) ,axis=1)
262
262
263 SPCcut = SPCroll.copy()
263 SPCcut = SPCroll.copy()
264 for i in range(self.Num_Chn):
264 for i in range(self.Num_Chn):
265
265
266 SPCcut[i,0:int(Breaker2R[0]),:] = dataOut.noise[i]
266 SPCcut[i,0:int(Breaker2R[0]),:] = dataOut.noise[i]
267 SPCcut[i,-int(Delta):,:] = dataOut.noise[i]
267 SPCcut[i,-int(Delta):,:] = dataOut.noise[i]
268
268
269 SPCcut[i]=SPCcut[i]- dataOut.noise[i]
269 SPCcut[i]=SPCcut[i]- dataOut.noise[i]
270 SPCcut[ numpy.where( SPCcut<0 ) ] = 1e-20
270 SPCcut[ numpy.where( SPCcut<0 ) ] = 1e-20
271
271
272 SPCroll[i]=SPCroll[i]-dataOut.noise[i]
272 SPCroll[i]=SPCroll[i]-dataOut.noise[i]
273 SPCroll[ numpy.where( SPCroll<0 ) ] = 1e-20
273 SPCroll[ numpy.where( SPCroll<0 ) ] = 1e-20
274
274
275 SPC_ch1 = SPCroll
275 SPC_ch1 = SPCroll
276
276
277 SPC_ch2 = SPCcut
277 SPC_ch2 = SPCcut
278
278
279 SPCparam = (SPC_ch1, SPC_ch2, self.spc)
279 SPCparam = (SPC_ch1, SPC_ch2, self.spc)
280 dataOut.SPCparam = numpy.asarray(SPCparam)
280 dataOut.SPCparam = numpy.asarray(SPCparam)
281
281
282
282
283 dataOut.spcparam_range=numpy.zeros([self.Num_Chn,self.Num_Bin+1])
283 dataOut.spcparam_range=numpy.zeros([self.Num_Chn,self.Num_Bin+1])
284
284
285 dataOut.spcparam_range[2]=VelRange
285 dataOut.spcparam_range[2]=VelRange
286 dataOut.spcparam_range[1]=TimeRange
286 dataOut.spcparam_range[1]=TimeRange
287 dataOut.spcparam_range[0]=FrecRange
287 dataOut.spcparam_range[0]=FrecRange
288
288 return dataOut
289
289
290 class GaussianFit(Operation):
290 class GaussianFit(Operation):
291
291
292 '''
292 '''
293 Function that fit of one and two generalized gaussians (gg) based
293 Function that fit of one and two generalized gaussians (gg) based
294 on the PSD shape across an "power band" identified from a cumsum of
294 on the PSD shape across an "power band" identified from a cumsum of
295 the measured spectrum - noise.
295 the measured spectrum - noise.
296
296
297 Input:
297 Input:
298 self.dataOut.data_pre : SelfSpectra
298 self.dataOut.data_pre : SelfSpectra
299
299
300 Output:
300 Output:
301 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
301 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
302
302
303 '''
303 '''
304 def __init__(self):
304 def __init__(self):
305 Operation.__init__(self)
305 Operation.__init__(self)
306 self.i=0
306 self.i=0
307
307
308
308
309 def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
309 def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
310 """This routine will find a couple of generalized Gaussians to a power spectrum
310 """This routine will find a couple of generalized Gaussians to a power spectrum
311 input: spc
311 input: spc
312 output:
312 output:
313 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
313 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
314 """
314 """
315
315
316 self.spc = dataOut.data_pre[0].copy()
316 self.spc = dataOut.data_pre[0].copy()
317 self.Num_Hei = self.spc.shape[2]
317 self.Num_Hei = self.spc.shape[2]
318 self.Num_Bin = self.spc.shape[1]
318 self.Num_Bin = self.spc.shape[1]
319 self.Num_Chn = self.spc.shape[0]
319 self.Num_Chn = self.spc.shape[0]
320 Vrange = dataOut.abscissaList
320 Vrange = dataOut.abscissaList
321
321
322 GauSPC = numpy.empty([self.Num_Chn,self.Num_Bin,self.Num_Hei])
322 GauSPC = numpy.empty([self.Num_Chn,self.Num_Bin,self.Num_Hei])
323 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
323 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
324 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
324 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
325 SPC_ch1[:] = numpy.NaN
325 SPC_ch1[:] = numpy.NaN
326 SPC_ch2[:] = numpy.NaN
326 SPC_ch2[:] = numpy.NaN
327
327
328
328
329 start_time = time.time()
329 start_time = time.time()
330
330
331 noise_ = dataOut.spc_noise[0].copy()
331 noise_ = dataOut.spc_noise[0].copy()
332
332
333
333
334 pool = Pool(processes=self.Num_Chn)
334 pool = Pool(processes=self.Num_Chn)
335 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
335 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
336 objs = [self for __ in range(self.Num_Chn)]
336 objs = [self for __ in range(self.Num_Chn)]
337 attrs = list(zip(objs, args))
337 attrs = list(zip(objs, args))
338 gauSPC = pool.map(target, attrs)
338 gauSPC = pool.map(target, attrs)
339 dataOut.SPCparam = numpy.asarray(SPCparam)
339 dataOut.SPCparam = numpy.asarray(SPCparam)
340
340
341 ''' Parameters:
341 ''' Parameters:
342 1. Amplitude
342 1. Amplitude
343 2. Shift
343 2. Shift
344 3. Width
344 3. Width
345 4. Power
345 4. Power
346 '''
346 '''
347
347
348 def FitGau(self, X):
348 def FitGau(self, X):
349
349
350 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
350 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
351
351
352 SPCparam = []
352 SPCparam = []
353 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
353 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
354 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
354 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
355 SPC_ch1[:] = 0#numpy.NaN
355 SPC_ch1[:] = 0#numpy.NaN
356 SPC_ch2[:] = 0#numpy.NaN
356 SPC_ch2[:] = 0#numpy.NaN
357
357
358
358
359
359
360 for ht in range(self.Num_Hei):
360 for ht in range(self.Num_Hei):
361
361
362
362
363 spc = numpy.asarray(self.spc)[ch,:,ht]
363 spc = numpy.asarray(self.spc)[ch,:,ht]
364
364
365 #############################################
365 #############################################
366 # normalizing spc and noise
366 # normalizing spc and noise
367 # This part differs from gg1
367 # This part differs from gg1
368 spc_norm_max = max(spc)
368 spc_norm_max = max(spc)
369 #spc = spc / spc_norm_max
369 #spc = spc / spc_norm_max
370 pnoise = pnoise #/ spc_norm_max
370 pnoise = pnoise #/ spc_norm_max
371 #############################################
371 #############################################
372
372
373 fatspectra=1.0
373 fatspectra=1.0
374
374
375 wnoise = noise_ #/ spc_norm_max
375 wnoise = noise_ #/ spc_norm_max
376 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
376 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
377 #if wnoise>1.1*pnoise: # to be tested later
377 #if wnoise>1.1*pnoise: # to be tested later
378 # wnoise=pnoise
378 # wnoise=pnoise
379 noisebl=wnoise*0.9;
379 noisebl=wnoise*0.9;
380 noisebh=wnoise*1.1
380 noisebh=wnoise*1.1
381 spc=spc-wnoise
381 spc=spc-wnoise
382
382
383 minx=numpy.argmin(spc)
383 minx=numpy.argmin(spc)
384 #spcs=spc.copy()
384 #spcs=spc.copy()
385 spcs=numpy.roll(spc,-minx)
385 spcs=numpy.roll(spc,-minx)
386 cum=numpy.cumsum(spcs)
386 cum=numpy.cumsum(spcs)
387 tot_noise=wnoise * self.Num_Bin #64;
387 tot_noise=wnoise * self.Num_Bin #64;
388
388
389 snr = sum(spcs)/tot_noise
389 snr = sum(spcs)/tot_noise
390 snrdB=10.*numpy.log10(snr)
390 snrdB=10.*numpy.log10(snr)
391
391
392 if snrdB < SNRlimit :
392 if snrdB < SNRlimit :
393 snr = numpy.NaN
393 snr = numpy.NaN
394 SPC_ch1[:,ht] = 0#numpy.NaN
394 SPC_ch1[:,ht] = 0#numpy.NaN
395 SPC_ch1[:,ht] = 0#numpy.NaN
395 SPC_ch1[:,ht] = 0#numpy.NaN
396 SPCparam = (SPC_ch1,SPC_ch2)
396 SPCparam = (SPC_ch1,SPC_ch2)
397 continue
397 continue
398
398
399
399
400 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
400 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
401 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
401 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
402
402
403 cummax=max(cum);
403 cummax=max(cum);
404 epsi=0.08*fatspectra # cumsum to narrow down the energy region
404 epsi=0.08*fatspectra # cumsum to narrow down the energy region
405 cumlo=cummax*epsi;
405 cumlo=cummax*epsi;
406 cumhi=cummax*(1-epsi)
406 cumhi=cummax*(1-epsi)
407 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
407 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
408
408
409
409
410 if len(powerindex) < 1:# case for powerindex 0
410 if len(powerindex) < 1:# case for powerindex 0
411 continue
411 continue
412 powerlo=powerindex[0]
412 powerlo=powerindex[0]
413 powerhi=powerindex[-1]
413 powerhi=powerindex[-1]
414 powerwidth=powerhi-powerlo
414 powerwidth=powerhi-powerlo
415
415
416 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
416 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
417 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
417 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
418 midpeak=(firstpeak+secondpeak)/2.
418 midpeak=(firstpeak+secondpeak)/2.
419 firstamp=spcs[int(firstpeak)]
419 firstamp=spcs[int(firstpeak)]
420 secondamp=spcs[int(secondpeak)]
420 secondamp=spcs[int(secondpeak)]
421 midamp=spcs[int(midpeak)]
421 midamp=spcs[int(midpeak)]
422
422
423 x=numpy.arange( self.Num_Bin )
423 x=numpy.arange( self.Num_Bin )
424 y_data=spc+wnoise
424 y_data=spc+wnoise
425
425
426 ''' single Gaussian '''
426 ''' single Gaussian '''
427 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
427 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
428 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
428 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
429 power0=2.
429 power0=2.
430 amplitude0=midamp
430 amplitude0=midamp
431 state0=[shift0,width0,amplitude0,power0,wnoise]
431 state0=[shift0,width0,amplitude0,power0,wnoise]
432 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
432 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
433 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
433 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
434
434
435 chiSq1=lsq1[1];
435 chiSq1=lsq1[1];
436
436
437
437
438 if fatspectra<1.0 and powerwidth<4:
438 if fatspectra<1.0 and powerwidth<4:
439 choice=0
439 choice=0
440 Amplitude0=lsq1[0][2]
440 Amplitude0=lsq1[0][2]
441 shift0=lsq1[0][0]
441 shift0=lsq1[0][0]
442 width0=lsq1[0][1]
442 width0=lsq1[0][1]
443 p0=lsq1[0][3]
443 p0=lsq1[0][3]
444 Amplitude1=0.
444 Amplitude1=0.
445 shift1=0.
445 shift1=0.
446 width1=0.
446 width1=0.
447 p1=0.
447 p1=0.
448 noise=lsq1[0][4]
448 noise=lsq1[0][4]
449 #return (numpy.array([shift0,width0,Amplitude0,p0]),
449 #return (numpy.array([shift0,width0,Amplitude0,p0]),
450 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
450 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
451
451
452 ''' two gaussians '''
452 ''' two gaussians '''
453 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
453 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
454 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
454 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
455 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
455 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
456 width0=powerwidth/6.;
456 width0=powerwidth/6.;
457 width1=width0
457 width1=width0
458 power0=2.;
458 power0=2.;
459 power1=power0
459 power1=power0
460 amplitude0=firstamp;
460 amplitude0=firstamp;
461 amplitude1=secondamp
461 amplitude1=secondamp
462 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
462 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
463 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
463 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
464 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
464 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
465 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
465 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
466
466
467 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
467 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
468
468
469
469
470 chiSq2=lsq2[1];
470 chiSq2=lsq2[1];
471
471
472
472
473
473
474 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
474 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
475
475
476 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
476 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
477 if oneG:
477 if oneG:
478 choice=0
478 choice=0
479 else:
479 else:
480 w1=lsq2[0][1]; w2=lsq2[0][5]
480 w1=lsq2[0][1]; w2=lsq2[0][5]
481 a1=lsq2[0][2]; a2=lsq2[0][6]
481 a1=lsq2[0][2]; a2=lsq2[0][6]
482 p1=lsq2[0][3]; p2=lsq2[0][7]
482 p1=lsq2[0][3]; p2=lsq2[0][7]
483 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
483 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
484 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
484 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
485 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
485 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
486
486
487 if gp1>gp2:
487 if gp1>gp2:
488 if a1>0.7*a2:
488 if a1>0.7*a2:
489 choice=1
489 choice=1
490 else:
490 else:
491 choice=2
491 choice=2
492 elif gp2>gp1:
492 elif gp2>gp1:
493 if a2>0.7*a1:
493 if a2>0.7*a1:
494 choice=2
494 choice=2
495 else:
495 else:
496 choice=1
496 choice=1
497 else:
497 else:
498 choice=numpy.argmax([a1,a2])+1
498 choice=numpy.argmax([a1,a2])+1
499 #else:
499 #else:
500 #choice=argmin([std2a,std2b])+1
500 #choice=argmin([std2a,std2b])+1
501
501
502 else: # with low SNR go to the most energetic peak
502 else: # with low SNR go to the most energetic peak
503 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
503 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
504
504
505
505
506 shift0=lsq2[0][0];
506 shift0=lsq2[0][0];
507 vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
507 vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
508 shift1=lsq2[0][4];
508 shift1=lsq2[0][4];
509 vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
509 vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
510
510
511 max_vel = 1.0
511 max_vel = 1.0
512
512
513 #first peak will be 0, second peak will be 1
513 #first peak will be 0, second peak will be 1
514 if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range
514 if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range
515 shift0=lsq2[0][0]
515 shift0=lsq2[0][0]
516 width0=lsq2[0][1]
516 width0=lsq2[0][1]
517 Amplitude0=lsq2[0][2]
517 Amplitude0=lsq2[0][2]
518 p0=lsq2[0][3]
518 p0=lsq2[0][3]
519
519
520 shift1=lsq2[0][4]
520 shift1=lsq2[0][4]
521 width1=lsq2[0][5]
521 width1=lsq2[0][5]
522 Amplitude1=lsq2[0][6]
522 Amplitude1=lsq2[0][6]
523 p1=lsq2[0][7]
523 p1=lsq2[0][7]
524 noise=lsq2[0][8]
524 noise=lsq2[0][8]
525 else:
525 else:
526 shift1=lsq2[0][0]
526 shift1=lsq2[0][0]
527 width1=lsq2[0][1]
527 width1=lsq2[0][1]
528 Amplitude1=lsq2[0][2]
528 Amplitude1=lsq2[0][2]
529 p1=lsq2[0][3]
529 p1=lsq2[0][3]
530
530
531 shift0=lsq2[0][4]
531 shift0=lsq2[0][4]
532 width0=lsq2[0][5]
532 width0=lsq2[0][5]
533 Amplitude0=lsq2[0][6]
533 Amplitude0=lsq2[0][6]
534 p0=lsq2[0][7]
534 p0=lsq2[0][7]
535 noise=lsq2[0][8]
535 noise=lsq2[0][8]
536
536
537 if Amplitude0<0.05: # in case the peak is noise
537 if Amplitude0<0.05: # in case the peak is noise
538 shift0,width0,Amplitude0,p0 = [0,0,0,0]#4*[numpy.NaN]
538 shift0,width0,Amplitude0,p0 = [0,0,0,0]#4*[numpy.NaN]
539 if Amplitude1<0.05:
539 if Amplitude1<0.05:
540 shift1,width1,Amplitude1,p1 = [0,0,0,0]#4*[numpy.NaN]
540 shift1,width1,Amplitude1,p1 = [0,0,0,0]#4*[numpy.NaN]
541
541
542
542
543 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
543 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
544 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
544 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
545 SPCparam = (SPC_ch1,SPC_ch2)
545 SPCparam = (SPC_ch1,SPC_ch2)
546
546
547
547
548 return GauSPC
548 return GauSPC
549
549
550 def y_model1(self,x,state):
550 def y_model1(self,x,state):
551 shift0,width0,amplitude0,power0,noise=state
551 shift0,width0,amplitude0,power0,noise=state
552 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
552 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
553
553
554 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
554 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
555
555
556 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
556 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
557 return model0+model0u+model0d+noise
557 return model0+model0u+model0d+noise
558
558
559 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
559 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
560 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
560 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
561 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
561 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
562
562
563 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
563 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
564
564
565 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
565 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
566 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
566 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
567
567
568 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
568 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
569
569
570 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
570 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
571 return model0+model0u+model0d+model1+model1u+model1d+noise
571 return model0+model0u+model0d+model1+model1u+model1d+noise
572
572
573 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
573 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
574
574
575 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
575 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
576
576
577 def misfit2(self,state,y_data,x,num_intg):
577 def misfit2(self,state,y_data,x,num_intg):
578 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
578 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
579
579
580
580
581
581
582 class PrecipitationProc(Operation):
582 class PrecipitationProc(Operation):
583
583
584 '''
584 '''
585 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
585 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
586
586
587 Input:
587 Input:
588 self.dataOut.data_pre : SelfSpectra
588 self.dataOut.data_pre : SelfSpectra
589
589
590 Output:
590 Output:
591
591
592 self.dataOut.data_output : Reflectivity factor, rainfall Rate
592 self.dataOut.data_output : Reflectivity factor, rainfall Rate
593
593
594
594
595 Parameters affected:
595 Parameters affected:
596 '''
596 '''
597
597
598 def __init__(self):
598 def __init__(self):
599 Operation.__init__(self)
599 Operation.__init__(self)
600 self.i=0
600 self.i=0
601
601
602
602
603 def gaus(self,xSamples,Amp,Mu,Sigma):
603 def gaus(self,xSamples,Amp,Mu,Sigma):
604 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
604 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
605
605
606
606
607
607
608 def Moments(self, ySamples, xSamples):
608 def Moments(self, ySamples, xSamples):
609 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
609 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
610 yNorm = ySamples / Pot
610 yNorm = ySamples / Pot
611
611
612 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
612 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
613 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
613 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
614 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
614 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
615
615
616 return numpy.array([Pot, Vr, Desv])
616 return numpy.array([Pot, Vr, Desv])
617
617
618 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
618 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
619 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km = 0.93, Altitude=3350):
619 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km = 0.93, Altitude=3350):
620
620
621
621
622 Velrange = dataOut.spcparam_range[2]
622 Velrange = dataOut.spcparam_range[2]
623 FrecRange = dataOut.spcparam_range[0]
623 FrecRange = dataOut.spcparam_range[0]
624
624
625 dV= Velrange[1]-Velrange[0]
625 dV= Velrange[1]-Velrange[0]
626 dF= FrecRange[1]-FrecRange[0]
626 dF= FrecRange[1]-FrecRange[0]
627
627
628 if radar == "MIRA35C" :
628 if radar == "MIRA35C" :
629
629
630 self.spc = dataOut.data_pre[0].copy()
630 self.spc = dataOut.data_pre[0].copy()
631 self.Num_Hei = self.spc.shape[2]
631 self.Num_Hei = self.spc.shape[2]
632 self.Num_Bin = self.spc.shape[1]
632 self.Num_Bin = self.spc.shape[1]
633 self.Num_Chn = self.spc.shape[0]
633 self.Num_Chn = self.spc.shape[0]
634 Ze = self.dBZeMODE2(dataOut)
634 Ze = self.dBZeMODE2(dataOut)
635
635
636 else:
636 else:
637
637
638 self.spc = dataOut.SPCparam[1].copy() #dataOut.data_pre[0].copy() #
638 self.spc = dataOut.SPCparam[1].copy() #dataOut.data_pre[0].copy() #
639
639
640 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
640 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
641
641
642 self.spc[:,:,0:7]= numpy.NaN
642 self.spc[:,:,0:7]= numpy.NaN
643
643
644 """##########################################"""
644 """##########################################"""
645
645
646 self.Num_Hei = self.spc.shape[2]
646 self.Num_Hei = self.spc.shape[2]
647 self.Num_Bin = self.spc.shape[1]
647 self.Num_Bin = self.spc.shape[1]
648 self.Num_Chn = self.spc.shape[0]
648 self.Num_Chn = self.spc.shape[0]
649
649
650 ''' Se obtiene la constante del RADAR '''
650 ''' Se obtiene la constante del RADAR '''
651
651
652 self.Pt = Pt
652 self.Pt = Pt
653 self.Gt = Gt
653 self.Gt = Gt
654 self.Gr = Gr
654 self.Gr = Gr
655 self.Lambda = Lambda
655 self.Lambda = Lambda
656 self.aL = aL
656 self.aL = aL
657 self.tauW = tauW
657 self.tauW = tauW
658 self.ThetaT = ThetaT
658 self.ThetaT = ThetaT
659 self.ThetaR = ThetaR
659 self.ThetaR = ThetaR
660
660
661 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
661 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
662 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
662 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
663 RadarConstant = 5e-26 * Numerator / Denominator #
663 RadarConstant = 10e-26 * Numerator / Denominator #
664
664
665 ''' ============================= '''
665 ''' ============================= '''
666
666
667 self.spc[0] = (self.spc[0]-dataOut.noise[0])
667 self.spc[0] = (self.spc[0]-dataOut.noise[0])
668 self.spc[1] = (self.spc[1]-dataOut.noise[1])
668 self.spc[1] = (self.spc[1]-dataOut.noise[1])
669 self.spc[2] = (self.spc[2]-dataOut.noise[2])
669 self.spc[2] = (self.spc[2]-dataOut.noise[2])
670
670
671 self.spc[ numpy.where(self.spc < 0)] = 0
671 self.spc[ numpy.where(self.spc < 0)] = 0
672
672
673 SPCmean = (numpy.mean(self.spc,0) - numpy.mean(dataOut.noise))
673 SPCmean = (numpy.mean(self.spc,0) - numpy.mean(dataOut.noise))
674 SPCmean[ numpy.where(SPCmean < 0)] = 0
674 SPCmean[ numpy.where(SPCmean < 0)] = 0
675
675
676 ETAn = numpy.zeros([self.Num_Bin,self.Num_Hei])
676 ETAn = numpy.zeros([self.Num_Bin,self.Num_Hei])
677 ETAv = numpy.zeros([self.Num_Bin,self.Num_Hei])
677 ETAv = numpy.zeros([self.Num_Bin,self.Num_Hei])
678 ETAd = numpy.zeros([self.Num_Bin,self.Num_Hei])
678 ETAd = numpy.zeros([self.Num_Bin,self.Num_Hei])
679
679
680 Pr = SPCmean[:,:]
680 Pr = SPCmean[:,:]
681
681
682 VelMeteoro = numpy.mean(SPCmean,axis=0)
682 VelMeteoro = numpy.mean(SPCmean,axis=0)
683
683
684 D_range = numpy.zeros([self.Num_Bin,self.Num_Hei])
684 D_range = numpy.zeros([self.Num_Bin,self.Num_Hei])
685 SIGMA = numpy.zeros([self.Num_Bin,self.Num_Hei])
685 SIGMA = numpy.zeros([self.Num_Bin,self.Num_Hei])
686 N_dist = numpy.zeros([self.Num_Bin,self.Num_Hei])
686 N_dist = numpy.zeros([self.Num_Bin,self.Num_Hei])
687 V_mean = numpy.zeros(self.Num_Hei)
687 V_mean = numpy.zeros(self.Num_Hei)
688 del_V = numpy.zeros(self.Num_Hei)
688 del_V = numpy.zeros(self.Num_Hei)
689 Z = numpy.zeros(self.Num_Hei)
689 Z = numpy.zeros(self.Num_Hei)
690 Ze = numpy.zeros(self.Num_Hei)
690 Ze = numpy.zeros(self.Num_Hei)
691 RR = numpy.zeros(self.Num_Hei)
691 RR = numpy.zeros(self.Num_Hei)
692
692
693 Range = dataOut.heightList*1000.
693 Range = dataOut.heightList*1000.
694
694
695 for R in range(self.Num_Hei):
695 for R in range(self.Num_Hei):
696
696
697 h = Range[R] + Altitude #Range from ground to radar pulse altitude
697 h = Range[R] + Altitude #Range from ground to radar pulse altitude
698 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
698 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
699
699
700 D_range[:,R] = numpy.log( (9.65 - (Velrange[0:self.Num_Bin] / del_V[R])) / 10.3 ) / -0.6 #Diameter range [m]x10**-3
700 D_range[:,R] = numpy.log( (9.65 - (Velrange[0:self.Num_Bin] / del_V[R])) / 10.3 ) / -0.6 #Diameter range [m]x10**-3
701
701
702 '''NOTA: ETA(n) dn = ETA(f) df
702 '''NOTA: ETA(n) dn = ETA(f) df
703
703
704 dn = 1 Diferencial de muestreo
704 dn = 1 Diferencial de muestreo
705 df = ETA(n) / ETA(f)
705 df = ETA(n) / ETA(f)
706
706
707 '''
707 '''
708
708
709 ETAn[:,R] = RadarConstant * Pr[:,R] * (Range[R] )**2 #Reflectivity (ETA)
709 ETAn[:,R] = RadarConstant * Pr[:,R] * (Range[R] )**2 #Reflectivity (ETA)
710
710
711 ETAv[:,R]=ETAn[:,R]/dV
711 ETAv[:,R]=ETAn[:,R]/dV
712
712
713 ETAd[:,R]=ETAv[:,R]*6.18*exp(-0.6*D_range[:,R])
713 ETAd[:,R]=ETAv[:,R]*6.18*exp(-0.6*D_range[:,R])
714
714
715 SIGMA[:,R] = Km * (D_range[:,R] * 1e-3 )**6 * numpy.pi**5 / Lambda**4 #Equivalent Section of drops (sigma)
715 SIGMA[:,R] = Km * (D_range[:,R] * 1e-3 )**6 * numpy.pi**5 / Lambda**4 #Equivalent Section of drops (sigma)
716
716
717 N_dist[:,R] = ETAn[:,R] / SIGMA[:,R]
717 N_dist[:,R] = ETAn[:,R] / SIGMA[:,R]
718
718
719 DMoments = self.Moments(Pr[:,R], Velrange[0:self.Num_Bin])
719 DMoments = self.Moments(Pr[:,R], Velrange[0:self.Num_Bin])
720
720
721 try:
721 try:
722 popt01,pcov = curve_fit(self.gaus, Velrange[0:self.Num_Bin] , Pr[:,R] , p0=DMoments)
722 popt01,pcov = curve_fit(self.gaus, Velrange[0:self.Num_Bin] , Pr[:,R] , p0=DMoments)
723 except:
723 except:
724 popt01=numpy.zeros(3)
724 popt01=numpy.zeros(3)
725 popt01[1]= DMoments[1]
725 popt01[1]= DMoments[1]
726
726
727 if popt01[1]<0 or popt01[1]>20:
727 if popt01[1]<0 or popt01[1]>20:
728 popt01[1]=numpy.NaN
728 popt01[1]=numpy.NaN
729
729
730
730
731 V_mean[R]=popt01[1]
731 V_mean[R]=popt01[1]
732
732
733 Z[R] = numpy.nansum( N_dist[:,R] * (D_range[:,R])**6 )#*10**-18
733 Z[R] = numpy.nansum( N_dist[:,R] * (D_range[:,R])**6 )#*10**-18
734
734
735 RR[R] = 0.0006*numpy.pi * numpy.nansum( D_range[:,R]**3 * N_dist[:,R] * Velrange[0:self.Num_Bin] ) #Rainfall rate
735 RR[R] = 0.0006*numpy.pi * numpy.nansum( D_range[:,R]**3 * N_dist[:,R] * Velrange[0:self.Num_Bin] ) #Rainfall rate
736
736
737 Ze[R] = (numpy.nansum( ETAn[:,R]) * Lambda**4) / ( 10**-18*numpy.pi**5 * Km)
737 Ze[R] = (numpy.nansum( ETAn[:,R]) * Lambda**4) / ( 10**-18*numpy.pi**5 * Km)
738
738
739
739
740
740
741 RR2 = (Z/200)**(1/1.6)
741 RR2 = (Z/200)**(1/1.6)
742 dBRR = 10*numpy.log10(RR)
742 dBRR = 10*numpy.log10(RR)
743 dBRR2 = 10*numpy.log10(RR2)
743 dBRR2 = 10*numpy.log10(RR2)
744
744
745 dBZe = 10*numpy.log10(Ze)
745 dBZe = 10*numpy.log10(Ze)
746 dBZ = 10*numpy.log10(Z)
746 dBZ = 10*numpy.log10(Z)
747
747
748 dataOut.data_output = RR[8]
748 dataOut.data_output = RR[8]
749 dataOut.data_param = numpy.ones([3,self.Num_Hei])
749 dataOut.data_param = numpy.ones([3,self.Num_Hei])
750 dataOut.channelList = [0,1,2]
750 dataOut.channelList = [0,1,2]
751
751
752 dataOut.data_param[0]=dBZ
752 dataOut.data_param[0]=dBZ
753 dataOut.data_param[1]=V_mean
753 dataOut.data_param[1]=V_mean
754 dataOut.data_param[2]=RR
754 dataOut.data_param[2]=RR
755
755
756 return dataOut
756
757
757 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
758 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
758
759
759 NPW = dataOut.NPW
760 NPW = dataOut.NPW
760 COFA = dataOut.COFA
761 COFA = dataOut.COFA
761
762
762 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
763 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
763 RadarConst = dataOut.RadarConst
764 RadarConst = dataOut.RadarConst
764 #frequency = 34.85*10**9
765 #frequency = 34.85*10**9
765
766
766 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
767 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
767 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
768 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
768
769
769 ETA = numpy.sum(SNR,1)
770 ETA = numpy.sum(SNR,1)
770
771
771 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
772 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
772
773
773 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
774 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
774
775
775 for r in range(self.Num_Hei):
776 for r in range(self.Num_Hei):
776
777
777 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
778 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
778 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
779 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
779
780
780 return Ze
781 return Ze
781
782
782 # def GetRadarConstant(self):
783 # def GetRadarConstant(self):
783 #
784 #
784 # """
785 # """
785 # Constants:
786 # Constants:
786 #
787 #
787 # Pt: Transmission Power dB 5kW 5000
788 # Pt: Transmission Power dB 5kW 5000
788 # Gt: Transmission Gain dB 24.7 dB 295.1209
789 # Gt: Transmission Gain dB 24.7 dB 295.1209
789 # Gr: Reception Gain dB 18.5 dB 70.7945
790 # Gr: Reception Gain dB 18.5 dB 70.7945
790 # Lambda: Wavelenght m 0.6741 m 0.6741
791 # Lambda: Wavelenght m 0.6741 m 0.6741
791 # aL: Attenuation loses dB 4dB 2.5118
792 # aL: Attenuation loses dB 4dB 2.5118
792 # tauW: Width of transmission pulse s 4us 4e-6
793 # tauW: Width of transmission pulse s 4us 4e-6
793 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
794 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
794 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
795 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
795 #
796 #
796 # """
797 # """
797 #
798 #
798 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
799 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
799 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
800 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
800 # RadarConstant = Numerator / Denominator
801 # RadarConstant = Numerator / Denominator
801 #
802 #
802 # return RadarConstant
803 # return RadarConstant
803
804
804
805
805
806
806 class FullSpectralAnalysis(Operation):
807 class FullSpectralAnalysis(Operation):
807
808
808 """
809 """
809 Function that implements Full Spectral Analisys technique.
810 Function that implements Full Spectral Analisys technique.
810
811
811 Input:
812 Input:
812 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
813 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
813 self.dataOut.groupList : Pairlist of channels
814 self.dataOut.groupList : Pairlist of channels
814 self.dataOut.ChanDist : Physical distance between receivers
815 self.dataOut.ChanDist : Physical distance between receivers
815
816
816
817
817 Output:
818 Output:
818
819
819 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
820 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
820
821
821
822
822 Parameters affected: Winds, height range, SNR
823 Parameters affected: Winds, height range, SNR
823
824
824 """
825 """
825 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRlimit=7):
826 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRlimit=7):
826
827
827 self.indice=int(numpy.random.rand()*1000)
828 self.indice=int(numpy.random.rand()*1000)
828
829
829 spc = dataOut.data_pre[0].copy()
830 spc = dataOut.data_pre[0].copy()
830 cspc = dataOut.data_pre[1]
831 cspc = dataOut.data_pre[1]
831
832
832 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
833 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
833
834
834 SNRspc = spc.copy()
835 SNRspc = spc.copy()
835 SNRspc[:,:,0:7]= numpy.NaN
836 SNRspc[:,:,0:7]= numpy.NaN
836
837
837 """##########################################"""
838 """##########################################"""
838
839
839
840
840 nChannel = spc.shape[0]
841 nChannel = spc.shape[0]
841 nProfiles = spc.shape[1]
842 nProfiles = spc.shape[1]
842 nHeights = spc.shape[2]
843 nHeights = spc.shape[2]
843
844
844 pairsList = dataOut.groupList
845 pairsList = dataOut.groupList
845 if dataOut.ChanDist is not None :
846 if dataOut.ChanDist is not None :
846 ChanDist = dataOut.ChanDist
847 ChanDist = dataOut.ChanDist
847 else:
848 else:
848 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
849 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
849
850
850 FrecRange = dataOut.spc_range[0]
851 FrecRange = dataOut.spc_range[0]
851
852
852 ySamples=numpy.ones([nChannel,nProfiles])
853 ySamples=numpy.ones([nChannel,nProfiles])
853 phase=numpy.ones([nChannel,nProfiles])
854 phase=numpy.ones([nChannel,nProfiles])
854 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
855 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
855 coherence=numpy.ones([nChannel,nProfiles])
856 coherence=numpy.ones([nChannel,nProfiles])
856 PhaseSlope=numpy.ones(nChannel)
857 PhaseSlope=numpy.ones(nChannel)
857 PhaseInter=numpy.ones(nChannel)
858 PhaseInter=numpy.ones(nChannel)
858 data_SNR=numpy.zeros([nProfiles])
859 data_SNR=numpy.zeros([nProfiles])
859
860
860 data = dataOut.data_pre
861 data = dataOut.data_pre
861 noise = dataOut.noise
862 noise = dataOut.noise
862
863
863 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
864 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
864
865
865 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
866 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
866
867
867
868
868 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
869 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
869
870
870 velocityX=[]
871 velocityX=[]
871 velocityY=[]
872 velocityY=[]
872 velocityV=[]
873 velocityV=[]
873 PhaseLine=[]
874 PhaseLine=[]
874
875
875 dbSNR = 10*numpy.log10(dataOut.data_SNR)
876 dbSNR = 10*numpy.log10(dataOut.data_SNR)
876 dbSNR = numpy.average(dbSNR,0)
877 dbSNR = numpy.average(dbSNR,0)
877
878
878 for Height in range(nHeights):
879 for Height in range(nHeights):
879
880
880 [Vzon,Vmer,Vver, GaussCenter, PhaseSlope, FitGaussCSPC]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, dataOut.spc_range.copy(), dbSNR[Height], SNRlimit)
881 [Vzon,Vmer,Vver, GaussCenter, PhaseSlope, FitGaussCSPC]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit)
881 PhaseLine = numpy.append(PhaseLine, PhaseSlope)
882 PhaseLine = numpy.append(PhaseLine, PhaseSlope)
882
883
883 if abs(Vzon)<100. and abs(Vzon)> 0.:
884 if abs(Vzon)<100. and abs(Vzon)> 0.:
884 velocityX=numpy.append(velocityX, Vzon)#Vmag
885 velocityX=numpy.append(velocityX, Vzon)#Vmag
885
886
886 else:
887 else:
887 velocityX=numpy.append(velocityX, numpy.NaN)
888 velocityX=numpy.append(velocityX, numpy.NaN)
888
889
889 if abs(Vmer)<100. and abs(Vmer) > 0.:
890 if abs(Vmer)<100. and abs(Vmer) > 0.:
890 velocityY=numpy.append(velocityY, -Vmer)#Vang
891 velocityY=numpy.append(velocityY, -Vmer)#Vang
891
892
892 else:
893 else:
893 velocityY=numpy.append(velocityY, numpy.NaN)
894 velocityY=numpy.append(velocityY, numpy.NaN)
894
895
895 if dbSNR[Height] > SNRlimit:
896 if dbSNR[Height] > SNRlimit:
896 velocityV=numpy.append(velocityV, -Vver)#FirstMoment[Height])
897 velocityV=numpy.append(velocityV, -Vver)#FirstMoment[Height])
897 else:
898 else:
898 velocityV=numpy.append(velocityV, numpy.NaN)
899 velocityV=numpy.append(velocityV, numpy.NaN)
899
900
900
901
901
902
902 '''Nota: Cambiar el signo de numpy.array(velocityX) cuando se intente procesar datos de BLTR'''
903 '''Nota: Cambiar el signo de numpy.array(velocityX) cuando se intente procesar datos de BLTR'''
903 data_output[0] = numpy.array(velocityX) #self.moving_average(numpy.array(velocityX) , N=1)
904 data_output[0] = numpy.array(velocityX) #self.moving_average(numpy.array(velocityX) , N=1)
904 data_output[1] = numpy.array(velocityY) #self.moving_average(numpy.array(velocityY) , N=1)
905 data_output[1] = numpy.array(velocityY) #self.moving_average(numpy.array(velocityY) , N=1)
905 data_output[2] = velocityV#FirstMoment
906 data_output[2] = velocityV#FirstMoment
906
907
907 xFrec=FrecRange[0:spc.shape[1]]
908 xFrec=FrecRange[0:spc.shape[1]]
908
909
909 dataOut.data_output=data_output
910 dataOut.data_output=data_output
910
911
911 return
912 return dataOut
912
913
913
914
914 def moving_average(self,x, N=2):
915 def moving_average(self,x, N=2):
915 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
916 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
916
917
917 def gaus(self,xSamples,Amp,Mu,Sigma):
918 def gaus(self,xSamples,Amp,Mu,Sigma):
918 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
919 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
919
920
920
921
921
922
922 def Moments(self, ySamples, xSamples):
923 def Moments(self, ySamples, xSamples):
923 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
924 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
924 yNorm = ySamples / Pot
925 yNorm = ySamples / Pot
925 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
926 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
926 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
927 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
927 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
928 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
928
929
929 return numpy.array([Pot, Vr, Desv])
930 return numpy.array([Pot, Vr, Desv])
930
931
931 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit):
932 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit):
932
933
933
934
934
935
935 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
936 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
936 phase=numpy.ones([spc.shape[0],spc.shape[1]])
937 phase=numpy.ones([spc.shape[0],spc.shape[1]])
937 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
938 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
938 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
939 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
939 PhaseSlope=numpy.zeros(spc.shape[0])
940 PhaseSlope=numpy.zeros(spc.shape[0])
940 PhaseInter=numpy.ones(spc.shape[0])
941 PhaseInter=numpy.ones(spc.shape[0])
941 xFrec=AbbsisaRange[0][0:spc.shape[1]]
942 xFrec=AbbsisaRange[0][0:spc.shape[1]]
942 xVel =AbbsisaRange[2][0:spc.shape[1]]
943 xVel =AbbsisaRange[2][0:spc.shape[1]]
943 Vv=numpy.empty(spc.shape[2])*0
944 Vv=numpy.empty(spc.shape[2])*0
944 SPCav = numpy.average(spc, axis=0)-numpy.average(noise) #spc[0]-noise[0]#
945 SPCav = numpy.average(spc, axis=0)-numpy.average(noise) #spc[0]-noise[0]#
945
946
946 SPCmoments = self.Moments(SPCav[:,Height], xVel )
947 SPCmoments = self.Moments(SPCav[:,Height], xVel )
947 CSPCmoments = []
948 CSPCmoments = []
948 cspcNoise = numpy.empty(3)
949 cspcNoise = numpy.empty(3)
949
950
950 '''Getting Eij and Nij'''
951 '''Getting Eij and Nij'''
951
952
952 Xi01=ChanDist[0][0]
953 Xi01=ChanDist[0][0]
953 Eta01=ChanDist[0][1]
954 Eta01=ChanDist[0][1]
954
955
955 Xi02=ChanDist[1][0]
956 Xi02=ChanDist[1][0]
956 Eta02=ChanDist[1][1]
957 Eta02=ChanDist[1][1]
957
958
958 Xi12=ChanDist[2][0]
959 Xi12=ChanDist[2][0]
959 Eta12=ChanDist[2][1]
960 Eta12=ChanDist[2][1]
960
961
961 z = spc.copy()
962 z = spc.copy()
962 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
963 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
963
964
964 for i in range(spc.shape[0]):
965 for i in range(spc.shape[0]):
965
966
966 '''****** Line of Data SPC ******'''
967 '''****** Line of Data SPC ******'''
967 zline=z[i,:,Height].copy() - noise[i] # Se resta ruido
968 zline=z[i,:,Height].copy() - noise[i] # Se resta ruido
968
969
969 '''****** SPC is normalized ******'''
970 '''****** SPC is normalized ******'''
970 SmoothSPC =self.moving_average(zline.copy(),N=1) # Se suaviza el ruido
971 SmoothSPC =self.moving_average(zline.copy(),N=1) # Se suaviza el ruido
971 FactNorm = SmoothSPC/numpy.nansum(SmoothSPC) # SPC Normalizado y suavizado
972 FactNorm = SmoothSPC/numpy.nansum(SmoothSPC) # SPC Normalizado y suavizado
972
973
973 xSamples = xFrec # Se toma el rango de frecuncias
974 xSamples = xFrec # Se toma el rango de frecuncias
974 ySamples[i] = FactNorm # Se toman los valores de SPC normalizado
975 ySamples[i] = FactNorm # Se toman los valores de SPC normalizado
975
976
976 for i in range(spc.shape[0]):
977 for i in range(spc.shape[0]):
977
978
978 '''****** Line of Data CSPC ******'''
979 '''****** Line of Data CSPC ******'''
979 cspcLine = ( cspc[i,:,Height].copy())# - noise[i] ) # no! Se resta el ruido
980 cspcLine = ( cspc[i,:,Height].copy())# - noise[i] ) # no! Se resta el ruido
980 SmoothCSPC =self.moving_average(cspcLine,N=1) # Se suaviza el ruido
981 SmoothCSPC =self.moving_average(cspcLine,N=1) # Se suaviza el ruido
981 cspcNorm = SmoothCSPC/numpy.nansum(SmoothCSPC) # CSPC normalizado y suavizado
982 cspcNorm = SmoothCSPC/numpy.nansum(SmoothCSPC) # CSPC normalizado y suavizado
982
983
983 '''****** CSPC is normalized with respect to Briggs and Vincent ******'''
984 '''****** CSPC is normalized with respect to Briggs and Vincent ******'''
984 chan_index0 = pairsList[i][0]
985 chan_index0 = pairsList[i][0]
985 chan_index1 = pairsList[i][1]
986 chan_index1 = pairsList[i][1]
986
987
987 CSPCFactor= numpy.abs(numpy.nansum(ySamples[chan_index0]))**2 * numpy.abs(numpy.nansum(ySamples[chan_index1]))**2
988 CSPCFactor= numpy.abs(numpy.nansum(ySamples[chan_index0]))**2 * numpy.abs(numpy.nansum(ySamples[chan_index1]))**2
988 CSPCNorm = cspcNorm / numpy.sqrt(CSPCFactor)
989 CSPCNorm = cspcNorm / numpy.sqrt(CSPCFactor)
989
990
990 CSPCSamples[i] = CSPCNorm
991 CSPCSamples[i] = CSPCNorm
991
992
992 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
993 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
993
994
994 #coherence[i]= self.moving_average(coherence[i],N=1)
995 #coherence[i]= self.moving_average(coherence[i],N=1)
995
996
996 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
997 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
997
998
998 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPCSamples[0]), xSamples),
999 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPCSamples[0]), xSamples),
999 self.Moments(numpy.abs(CSPCSamples[1]), xSamples),
1000 self.Moments(numpy.abs(CSPCSamples[1]), xSamples),
1000 self.Moments(numpy.abs(CSPCSamples[2]), xSamples)])
1001 self.Moments(numpy.abs(CSPCSamples[2]), xSamples)])
1001
1002
1002
1003
1003 popt=[1e-10,0,1e-10]
1004 popt=[1e-10,0,1e-10]
1004 popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10]
1005 popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10]
1005 FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0
1006 FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0
1006
1007
1007 CSPCMask01 = numpy.abs(CSPCSamples[0])
1008 CSPCMask01 = numpy.abs(CSPCSamples[0])
1008 CSPCMask02 = numpy.abs(CSPCSamples[1])
1009 CSPCMask02 = numpy.abs(CSPCSamples[1])
1009 CSPCMask12 = numpy.abs(CSPCSamples[2])
1010 CSPCMask12 = numpy.abs(CSPCSamples[2])
1010
1011
1011 mask01 = ~numpy.isnan(CSPCMask01)
1012 mask01 = ~numpy.isnan(CSPCMask01)
1012 mask02 = ~numpy.isnan(CSPCMask02)
1013 mask02 = ~numpy.isnan(CSPCMask02)
1013 mask12 = ~numpy.isnan(CSPCMask12)
1014 mask12 = ~numpy.isnan(CSPCMask12)
1014
1015
1015 #mask = ~numpy.isnan(CSPCMask01)
1016 #mask = ~numpy.isnan(CSPCMask01)
1016 CSPCMask01 = CSPCMask01[mask01]
1017 CSPCMask01 = CSPCMask01[mask01]
1017 CSPCMask02 = CSPCMask02[mask02]
1018 CSPCMask02 = CSPCMask02[mask02]
1018 CSPCMask12 = CSPCMask12[mask12]
1019 CSPCMask12 = CSPCMask12[mask12]
1019 #CSPCMask01 = numpy.ma.masked_invalid(CSPCMask01)
1020 #CSPCMask01 = numpy.ma.masked_invalid(CSPCMask01)
1020
1021
1021
1022
1022
1023
1023 '''***Fit Gauss CSPC01***'''
1024 '''***Fit Gauss CSPC01***'''
1024 if dbSNR > SNRlimit and numpy.abs(SPCmoments[1])<3 :
1025 if dbSNR > SNRlimit and numpy.abs(SPCmoments[1])<3 :
1025 try:
1026 try:
1026 popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0])
1027 popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0])
1027 popt02,pcov = curve_fit(self.gaus,xSamples[mask02],numpy.abs(CSPCMask02),p0=CSPCmoments[1])
1028 popt02,pcov = curve_fit(self.gaus,xSamples[mask02],numpy.abs(CSPCMask02),p0=CSPCmoments[1])
1028 popt12,pcov = curve_fit(self.gaus,xSamples[mask12],numpy.abs(CSPCMask12),p0=CSPCmoments[2])
1029 popt12,pcov = curve_fit(self.gaus,xSamples[mask12],numpy.abs(CSPCMask12),p0=CSPCmoments[2])
1029 FitGauss01 = self.gaus(xSamples,*popt01)
1030 FitGauss01 = self.gaus(xSamples,*popt01)
1030 FitGauss02 = self.gaus(xSamples,*popt02)
1031 FitGauss02 = self.gaus(xSamples,*popt02)
1031 FitGauss12 = self.gaus(xSamples,*popt12)
1032 FitGauss12 = self.gaus(xSamples,*popt12)
1032 except:
1033 except:
1033 FitGauss01=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[0]))
1034 FitGauss01=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[0]))
1034 FitGauss02=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[1]))
1035 FitGauss02=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[1]))
1035 FitGauss12=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[2]))
1036 FitGauss12=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[2]))
1036
1037
1037
1038
1038 CSPCopt = numpy.vstack([popt01,popt02,popt12])
1039 CSPCopt = numpy.vstack([popt01,popt02,popt12])
1039
1040
1040 '''****** Getting fij width ******'''
1041 '''****** Getting fij width ******'''
1041
1042
1042 yMean = numpy.average(ySamples, axis=0) # ySamples[0]
1043 yMean = numpy.average(ySamples, axis=0) # ySamples[0]
1043
1044
1044 '''******* Getting fitting Gaussian *******'''
1045 '''******* Getting fitting Gaussian *******'''
1045 meanGauss = sum(xSamples*yMean) / len(xSamples) # Mu, velocidad radial (frecuencia)
1046 meanGauss = sum(xSamples*yMean) / len(xSamples) # Mu, velocidad radial (frecuencia)
1046 sigma2 = sum(yMean*(xSamples-meanGauss)**2) / len(xSamples) # Varianza, Ancho espectral (frecuencia)
1047 sigma2 = sum(yMean*(xSamples-meanGauss)**2) / len(xSamples) # Varianza, Ancho espectral (frecuencia)
1047
1048
1048 yMoments = self.Moments(yMean, xSamples)
1049 yMoments = self.Moments(yMean, xSamples)
1049
1050
1050 if dbSNR > SNRlimit and numpy.abs(SPCmoments[1])<3: # and abs(meanGauss/sigma2) > 0.00001:
1051 if dbSNR > SNRlimit and numpy.abs(SPCmoments[1])<3: # and abs(meanGauss/sigma2) > 0.00001:
1051 try:
1052 try:
1052 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=yMoments)
1053 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=yMoments)
1053 FitGauss=self.gaus(xSamples,*popt)
1054 FitGauss=self.gaus(xSamples,*popt)
1054
1055
1055 except :#RuntimeError:
1056 except :#RuntimeError:
1056 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1057 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1057
1058
1058
1059
1059 else:
1060 else:
1060 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1061 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1061
1062
1062
1063
1063
1064
1064 '''****** Getting Fij ******'''
1065 '''****** Getting Fij ******'''
1065 Fijcspc = CSPCopt[:,2]/2*3
1066 Fijcspc = CSPCopt[:,2]/2*3
1066
1067
1067
1068
1068 GaussCenter = popt[1] #xFrec[GCpos]
1069 GaussCenter = popt[1] #xFrec[GCpos]
1069 #Punto en Eje X de la Gaussiana donde se encuentra el centro
1070 #Punto en Eje X de la Gaussiana donde se encuentra el centro
1070 ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()]
1071 ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()]
1071 PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0]
1072 PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0]
1072
1073
1073 #Punto e^-1 hubicado en la Gaussiana
1074 #Punto e^-1 hubicado en la Gaussiana
1074 PeMinus1 = numpy.max(FitGauss)* numpy.exp(-1)
1075 PeMinus1 = numpy.max(FitGauss)* numpy.exp(-1)
1075 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss"
1076 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss"
1076 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1077 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1077
1078
1078 if xSamples[PointFij] > xSamples[PointGauCenter]:
1079 if xSamples[PointFij] > xSamples[PointGauCenter]:
1079 Fij = xSamples[PointFij] - xSamples[PointGauCenter]
1080 Fij = xSamples[PointFij] - xSamples[PointGauCenter]
1080
1081
1081 else:
1082 else:
1082 Fij = xSamples[PointGauCenter] - xSamples[PointFij]
1083 Fij = xSamples[PointGauCenter] - xSamples[PointFij]
1083
1084
1084
1085
1085 '''****** Taking frequency ranges from SPCs ******'''
1086 '''****** Taking frequency ranges from SPCs ******'''
1086
1087
1087
1088
1088 #GaussCenter = popt[1] #Primer momento 01
1089 #GaussCenter = popt[1] #Primer momento 01
1089 GauWidth = popt[2] *3/2 #Ancho de banda de Gau01
1090 GauWidth = popt[2] *3/2 #Ancho de banda de Gau01
1090 Range = numpy.empty(2)
1091 Range = numpy.empty(2)
1091 Range[0] = GaussCenter - GauWidth
1092 Range[0] = GaussCenter - GauWidth
1092 Range[1] = GaussCenter + GauWidth
1093 Range[1] = GaussCenter + GauWidth
1093 #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max)
1094 #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max)
1094 ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()]
1095 ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()]
1095 ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()]
1096 ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()]
1096
1097
1097 PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0]
1098 PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0]
1098 PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0]
1099 PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0]
1099
1100
1100 Range=numpy.array([ PointRangeMin, PointRangeMax ])
1101 Range=numpy.array([ PointRangeMin, PointRangeMax ])
1101
1102
1102 FrecRange = xFrec[ Range[0] : Range[1] ]
1103 FrecRange = xFrec[ Range[0] : Range[1] ]
1103 VelRange = xVel[ Range[0] : Range[1] ]
1104 VelRange = xVel[ Range[0] : Range[1] ]
1104
1105
1105
1106
1106 '''****** Getting SCPC Slope ******'''
1107 '''****** Getting SCPC Slope ******'''
1107
1108
1108 for i in range(spc.shape[0]):
1109 for i in range(spc.shape[0]):
1109
1110
1110 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.3:
1111 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.3:
1111 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1112 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1112
1113
1113 '''***********************VelRange******************'''
1114 '''***********************VelRange******************'''
1114
1115
1115 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1116 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1116
1117
1117 if len(FrecRange) == len(PhaseRange):
1118 if len(FrecRange) == len(PhaseRange):
1118 try:
1119 try:
1119 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange[mask], PhaseRange[mask])
1120 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange[mask], PhaseRange[mask])
1120 PhaseSlope[i]=slope
1121 PhaseSlope[i]=slope
1121 PhaseInter[i]=intercept
1122 PhaseInter[i]=intercept
1122 except:
1123 except:
1123 PhaseSlope[i]=0
1124 PhaseSlope[i]=0
1124 PhaseInter[i]=0
1125 PhaseInter[i]=0
1125 else:
1126 else:
1126 PhaseSlope[i]=0
1127 PhaseSlope[i]=0
1127 PhaseInter[i]=0
1128 PhaseInter[i]=0
1128 else:
1129 else:
1129 PhaseSlope[i]=0
1130 PhaseSlope[i]=0
1130 PhaseInter[i]=0
1131 PhaseInter[i]=0
1131
1132
1132
1133
1133 '''Getting constant C'''
1134 '''Getting constant C'''
1134 cC=(Fij*numpy.pi)**2
1135 cC=(Fij*numpy.pi)**2
1135
1136
1136 '''****** Getting constants F and G ******'''
1137 '''****** Getting constants F and G ******'''
1137 MijEijNij=numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1138 MijEijNij=numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1138 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1139 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1139 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1140 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1140 MijResults=numpy.array([MijResult0,MijResult1])
1141 MijResults=numpy.array([MijResult0,MijResult1])
1141 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1142 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1142
1143
1143 '''****** Getting constants A, B and H ******'''
1144 '''****** Getting constants A, B and H ******'''
1144 W01=numpy.nanmax( FitGauss01 ) #numpy.abs(CSPCSamples[0]))
1145 W01=numpy.nanmax( FitGauss01 ) #numpy.abs(CSPCSamples[0]))
1145 W02=numpy.nanmax( FitGauss02 ) #numpy.abs(CSPCSamples[1]))
1146 W02=numpy.nanmax( FitGauss02 ) #numpy.abs(CSPCSamples[1]))
1146 W12=numpy.nanmax( FitGauss12 ) #numpy.abs(CSPCSamples[2]))
1147 W12=numpy.nanmax( FitGauss12 ) #numpy.abs(CSPCSamples[2]))
1147
1148
1148 WijResult0=((cF*Xi01+cG*Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1149 WijResult0=((cF*Xi01+cG*Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1149 WijResult1=((cF*Xi02+cG*Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1150 WijResult1=((cF*Xi02+cG*Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1150 WijResult2=((cF*Xi12+cG*Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1151 WijResult2=((cF*Xi12+cG*Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1151
1152
1152 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1153 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1153
1154
1154 WijEijNij=numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1155 WijEijNij=numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1155 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1156 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1156
1157
1157 VxVy=numpy.array([[cA,cH],[cH,cB]])
1158 VxVy=numpy.array([[cA,cH],[cH,cB]])
1158 VxVyResults=numpy.array([-cF,-cG])
1159 VxVyResults=numpy.array([-cF,-cG])
1159 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1160 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1160
1161
1161 Vzon = Vy
1162 Vzon = Vy
1162 Vmer = Vx
1163 Vmer = Vx
1163 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1164 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1164 Vang=numpy.arctan2(Vmer,Vzon)
1165 Vang=numpy.arctan2(Vmer,Vzon)
1165 if numpy.abs( popt[1] ) < 3.5 and len(FrecRange)>4:
1166 if numpy.abs( popt[1] ) < 3.5 and len(FrecRange)>4:
1166 Vver=popt[1]
1167 Vver=popt[1]
1167 else:
1168 else:
1168 Vver=numpy.NaN
1169 Vver=numpy.NaN
1169 FitGaussCSPC = numpy.array([FitGauss01,FitGauss02,FitGauss12])
1170 FitGaussCSPC = numpy.array([FitGauss01,FitGauss02,FitGauss12])
1170
1171
1171
1172
1172 return Vzon, Vmer, Vver, GaussCenter, PhaseSlope, FitGaussCSPC
1173 return Vzon, Vmer, Vver, GaussCenter, PhaseSlope, FitGaussCSPC
1173
1174
1174 class SpectralMoments(Operation):
1175 class SpectralMoments(Operation):
1175
1176
1176 '''
1177 '''
1177 Function SpectralMoments()
1178 Function SpectralMoments()
1178
1179
1179 Calculates moments (power, mean, standard deviation) and SNR of the signal
1180 Calculates moments (power, mean, standard deviation) and SNR of the signal
1180
1181
1181 Type of dataIn: Spectra
1182 Type of dataIn: Spectra
1182
1183
1183 Configuration Parameters:
1184 Configuration Parameters:
1184
1185
1185 dirCosx : Cosine director in X axis
1186 dirCosx : Cosine director in X axis
1186 dirCosy : Cosine director in Y axis
1187 dirCosy : Cosine director in Y axis
1187
1188
1188 elevation :
1189 elevation :
1189 azimuth :
1190 azimuth :
1190
1191
1191 Input:
1192 Input:
1192 channelList : simple channel list to select e.g. [2,3,7]
1193 channelList : simple channel list to select e.g. [2,3,7]
1193 self.dataOut.data_pre : Spectral data
1194 self.dataOut.data_pre : Spectral data
1194 self.dataOut.abscissaList : List of frequencies
1195 self.dataOut.abscissaList : List of frequencies
1195 self.dataOut.noise : Noise level per channel
1196 self.dataOut.noise : Noise level per channel
1196
1197
1197 Affected:
1198 Affected:
1198 self.dataOut.moments : Parameters per channel
1199 self.dataOut.moments : Parameters per channel
1199 self.dataOut.data_SNR : SNR per channel
1200 self.dataOut.data_SNR : SNR per channel
1200
1201
1201 '''
1202 '''
1202
1203
1203 def run(self, dataOut):
1204 def run(self, dataOut):
1204
1205
1205 #dataOut.data_pre = dataOut.data_pre[0]
1206 #dataOut.data_pre = dataOut.data_pre[0]
1206 data = dataOut.data_pre[0]
1207 data = dataOut.data_pre[0]
1207 absc = dataOut.abscissaList[:-1]
1208 absc = dataOut.abscissaList[:-1]
1208 noise = dataOut.noise
1209 noise = dataOut.noise
1209 nChannel = data.shape[0]
1210 nChannel = data.shape[0]
1210 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1211 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1211
1212
1212 for ind in range(nChannel):
1213 for ind in range(nChannel):
1213 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1214 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1214
1215
1215 dataOut.moments = data_param[:,1:,:]
1216 dataOut.moments = data_param[:,1:,:]
1216 dataOut.data_SNR = data_param[:,0]
1217 dataOut.data_SNR = data_param[:,0]
1217 dataOut.data_DOP = data_param[:,1]
1218 dataOut.data_DOP = data_param[:,1]
1218 dataOut.data_MEAN = data_param[:,2]
1219 dataOut.data_MEAN = data_param[:,2]
1219 dataOut.data_STD = data_param[:,3]
1220 dataOut.data_STD = data_param[:,3]
1220 return dataOut
1221 return dataOut
1221
1222
1222 def __calculateMoments(self, oldspec, oldfreq, n0,
1223 def __calculateMoments(self, oldspec, oldfreq, n0,
1223 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1224 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1224
1225
1225 if (nicoh is None): nicoh = 1
1226 if (nicoh is None): nicoh = 1
1226 if (graph is None): graph = 0
1227 if (graph is None): graph = 0
1227 if (smooth is None): smooth = 0
1228 if (smooth is None): smooth = 0
1228 elif (self.smooth < 3): smooth = 0
1229 elif (self.smooth < 3): smooth = 0
1229
1230
1230 if (type1 is None): type1 = 0
1231 if (type1 is None): type1 = 0
1231 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1232 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1232 if (snrth is None): snrth = -3
1233 if (snrth is None): snrth = -3
1233 if (dc is None): dc = 0
1234 if (dc is None): dc = 0
1234 if (aliasing is None): aliasing = 0
1235 if (aliasing is None): aliasing = 0
1235 if (oldfd is None): oldfd = 0
1236 if (oldfd is None): oldfd = 0
1236 if (wwauto is None): wwauto = 0
1237 if (wwauto is None): wwauto = 0
1237
1238
1238 if (n0 < 1.e-20): n0 = 1.e-20
1239 if (n0 < 1.e-20): n0 = 1.e-20
1239
1240
1240 freq = oldfreq
1241 freq = oldfreq
1241 vec_power = numpy.zeros(oldspec.shape[1])
1242 vec_power = numpy.zeros(oldspec.shape[1])
1242 vec_fd = numpy.zeros(oldspec.shape[1])
1243 vec_fd = numpy.zeros(oldspec.shape[1])
1243 vec_w = numpy.zeros(oldspec.shape[1])
1244 vec_w = numpy.zeros(oldspec.shape[1])
1244 vec_snr = numpy.zeros(oldspec.shape[1])
1245 vec_snr = numpy.zeros(oldspec.shape[1])
1245
1246
1246 oldspec = numpy.ma.masked_invalid(oldspec)
1247 oldspec = numpy.ma.masked_invalid(oldspec)
1247
1248
1248 for ind in range(oldspec.shape[1]):
1249 for ind in range(oldspec.shape[1]):
1249
1250
1250 spec = oldspec[:,ind]
1251 spec = oldspec[:,ind]
1251 aux = spec*fwindow
1252 aux = spec*fwindow
1252 max_spec = aux.max()
1253 max_spec = aux.max()
1253 m = list(aux).index(max_spec)
1254 m = list(aux).index(max_spec)
1254
1255
1255 #Smooth
1256 #Smooth
1256 if (smooth == 0): spec2 = spec
1257 if (smooth == 0): spec2 = spec
1257 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1258 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1258
1259
1259 # Calculo de Momentos
1260 # Calculo de Momentos
1260 bb = spec2[list(range(m,spec2.size))]
1261 bb = spec2[list(range(m,spec2.size))]
1261 bb = (bb<n0).nonzero()
1262 bb = (bb<n0).nonzero()
1262 bb = bb[0]
1263 bb = bb[0]
1263
1264
1264 ss = spec2[list(range(0,m + 1))]
1265 ss = spec2[list(range(0,m + 1))]
1265 ss = (ss<n0).nonzero()
1266 ss = (ss<n0).nonzero()
1266 ss = ss[0]
1267 ss = ss[0]
1267
1268
1268 if (bb.size == 0):
1269 if (bb.size == 0):
1269 bb0 = spec.size - 1 - m
1270 bb0 = spec.size - 1 - m
1270 else:
1271 else:
1271 bb0 = bb[0] - 1
1272 bb0 = bb[0] - 1
1272 if (bb0 < 0):
1273 if (bb0 < 0):
1273 bb0 = 0
1274 bb0 = 0
1274
1275
1275 if (ss.size == 0): ss1 = 1
1276 if (ss.size == 0): ss1 = 1
1276 else: ss1 = max(ss) + 1
1277 else: ss1 = max(ss) + 1
1277
1278
1278 if (ss1 > m): ss1 = m
1279 if (ss1 > m): ss1 = m
1279
1280
1280 valid = numpy.asarray(list(range(int(m + bb0 - ss1 + 1)))) + ss1
1281 valid = numpy.asarray(list(range(int(m + bb0 - ss1 + 1)))) + ss1
1281 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1282 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1282 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1283 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1283 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1284 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1284 snr = (spec2.mean()-n0)/n0
1285 snr = (spec2.mean()-n0)/n0
1285
1286
1286 if (snr < 1.e-20) :
1287 if (snr < 1.e-20) :
1287 snr = 1.e-20
1288 snr = 1.e-20
1288
1289
1289 vec_power[ind] = power
1290 vec_power[ind] = power
1290 vec_fd[ind] = fd
1291 vec_fd[ind] = fd
1291 vec_w[ind] = w
1292 vec_w[ind] = w
1292 vec_snr[ind] = snr
1293 vec_snr[ind] = snr
1293
1294
1294 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1295 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1295 return moments
1296 return moments
1296
1297
1297 #------------------ Get SA Parameters --------------------------
1298 #------------------ Get SA Parameters --------------------------
1298
1299
1299 def GetSAParameters(self):
1300 def GetSAParameters(self):
1300 #SA en frecuencia
1301 #SA en frecuencia
1301 pairslist = self.dataOut.groupList
1302 pairslist = self.dataOut.groupList
1302 num_pairs = len(pairslist)
1303 num_pairs = len(pairslist)
1303
1304
1304 vel = self.dataOut.abscissaList
1305 vel = self.dataOut.abscissaList
1305 spectra = self.dataOut.data_pre
1306 spectra = self.dataOut.data_pre
1306 cspectra = self.dataIn.data_cspc
1307 cspectra = self.dataIn.data_cspc
1307 delta_v = vel[1] - vel[0]
1308 delta_v = vel[1] - vel[0]
1308
1309
1309 #Calculating the power spectrum
1310 #Calculating the power spectrum
1310 spc_pow = numpy.sum(spectra, 3)*delta_v
1311 spc_pow = numpy.sum(spectra, 3)*delta_v
1311 #Normalizing Spectra
1312 #Normalizing Spectra
1312 norm_spectra = spectra/spc_pow
1313 norm_spectra = spectra/spc_pow
1313 #Calculating the norm_spectra at peak
1314 #Calculating the norm_spectra at peak
1314 max_spectra = numpy.max(norm_spectra, 3)
1315 max_spectra = numpy.max(norm_spectra, 3)
1315
1316
1316 #Normalizing Cross Spectra
1317 #Normalizing Cross Spectra
1317 norm_cspectra = numpy.zeros(cspectra.shape)
1318 norm_cspectra = numpy.zeros(cspectra.shape)
1318
1319
1319 for i in range(num_chan):
1320 for i in range(num_chan):
1320 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1321 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1321
1322
1322 max_cspectra = numpy.max(norm_cspectra,2)
1323 max_cspectra = numpy.max(norm_cspectra,2)
1323 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1324 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1324
1325
1325 for i in range(num_pairs):
1326 for i in range(num_pairs):
1326 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1327 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1327 #------------------- Get Lags ----------------------------------
1328 #------------------- Get Lags ----------------------------------
1328
1329
1329 class SALags(Operation):
1330 class SALags(Operation):
1330 '''
1331 '''
1331 Function GetMoments()
1332 Function GetMoments()
1332
1333
1333 Input:
1334 Input:
1334 self.dataOut.data_pre
1335 self.dataOut.data_pre
1335 self.dataOut.abscissaList
1336 self.dataOut.abscissaList
1336 self.dataOut.noise
1337 self.dataOut.noise
1337 self.dataOut.normFactor
1338 self.dataOut.normFactor
1338 self.dataOut.data_SNR
1339 self.dataOut.data_SNR
1339 self.dataOut.groupList
1340 self.dataOut.groupList
1340 self.dataOut.nChannels
1341 self.dataOut.nChannels
1341
1342
1342 Affected:
1343 Affected:
1343 self.dataOut.data_param
1344 self.dataOut.data_param
1344
1345
1345 '''
1346 '''
1346 def run(self, dataOut):
1347 def run(self, dataOut):
1347 data_acf = dataOut.data_pre[0]
1348 data_acf = dataOut.data_pre[0]
1348 data_ccf = dataOut.data_pre[1]
1349 data_ccf = dataOut.data_pre[1]
1349 normFactor_acf = dataOut.normFactor[0]
1350 normFactor_acf = dataOut.normFactor[0]
1350 normFactor_ccf = dataOut.normFactor[1]
1351 normFactor_ccf = dataOut.normFactor[1]
1351 pairs_acf = dataOut.groupList[0]
1352 pairs_acf = dataOut.groupList[0]
1352 pairs_ccf = dataOut.groupList[1]
1353 pairs_ccf = dataOut.groupList[1]
1353
1354
1354 nHeights = dataOut.nHeights
1355 nHeights = dataOut.nHeights
1355 absc = dataOut.abscissaList
1356 absc = dataOut.abscissaList
1356 noise = dataOut.noise
1357 noise = dataOut.noise
1357 SNR = dataOut.data_SNR
1358 SNR = dataOut.data_SNR
1358 nChannels = dataOut.nChannels
1359 nChannels = dataOut.nChannels
1359 # pairsList = dataOut.groupList
1360 # pairsList = dataOut.groupList
1360 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1361 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1361
1362
1362 for l in range(len(pairs_acf)):
1363 for l in range(len(pairs_acf)):
1363 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1364 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1364
1365
1365 for l in range(len(pairs_ccf)):
1366 for l in range(len(pairs_ccf)):
1366 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1367 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1367
1368
1368 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1369 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1369 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1370 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1370 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1371 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1371 return
1372 return
1372
1373
1373 # def __getPairsAutoCorr(self, pairsList, nChannels):
1374 # def __getPairsAutoCorr(self, pairsList, nChannels):
1374 #
1375 #
1375 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1376 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1376 #
1377 #
1377 # for l in range(len(pairsList)):
1378 # for l in range(len(pairsList)):
1378 # firstChannel = pairsList[l][0]
1379 # firstChannel = pairsList[l][0]
1379 # secondChannel = pairsList[l][1]
1380 # secondChannel = pairsList[l][1]
1380 #
1381 #
1381 # #Obteniendo pares de Autocorrelacion
1382 # #Obteniendo pares de Autocorrelacion
1382 # if firstChannel == secondChannel:
1383 # if firstChannel == secondChannel:
1383 # pairsAutoCorr[firstChannel] = int(l)
1384 # pairsAutoCorr[firstChannel] = int(l)
1384 #
1385 #
1385 # pairsAutoCorr = pairsAutoCorr.astype(int)
1386 # pairsAutoCorr = pairsAutoCorr.astype(int)
1386 #
1387 #
1387 # pairsCrossCorr = range(len(pairsList))
1388 # pairsCrossCorr = range(len(pairsList))
1388 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1389 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1389 #
1390 #
1390 # return pairsAutoCorr, pairsCrossCorr
1391 # return pairsAutoCorr, pairsCrossCorr
1391
1392
1392 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1393 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1393
1394
1394 lag0 = data_acf.shape[1]/2
1395 lag0 = data_acf.shape[1]/2
1395 #Funcion de Autocorrelacion
1396 #Funcion de Autocorrelacion
1396 mean_acf = stats.nanmean(data_acf, axis = 0)
1397 mean_acf = stats.nanmean(data_acf, axis = 0)
1397
1398
1398 #Obtencion Indice de TauCross
1399 #Obtencion Indice de TauCross
1399 ind_ccf = data_ccf.argmax(axis = 1)
1400 ind_ccf = data_ccf.argmax(axis = 1)
1400 #Obtencion Indice de TauAuto
1401 #Obtencion Indice de TauAuto
1401 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1402 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1402 ccf_lag0 = data_ccf[:,lag0,:]
1403 ccf_lag0 = data_ccf[:,lag0,:]
1403
1404
1404 for i in range(ccf_lag0.shape[0]):
1405 for i in range(ccf_lag0.shape[0]):
1405 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1406 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1406
1407
1407 #Obtencion de TauCross y TauAuto
1408 #Obtencion de TauCross y TauAuto
1408 tau_ccf = lagRange[ind_ccf]
1409 tau_ccf = lagRange[ind_ccf]
1409 tau_acf = lagRange[ind_acf]
1410 tau_acf = lagRange[ind_acf]
1410
1411
1411 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1412 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1412
1413
1413 tau_ccf[Nan1,Nan2] = numpy.nan
1414 tau_ccf[Nan1,Nan2] = numpy.nan
1414 tau_acf[Nan1,Nan2] = numpy.nan
1415 tau_acf[Nan1,Nan2] = numpy.nan
1415 tau = numpy.vstack((tau_ccf,tau_acf))
1416 tau = numpy.vstack((tau_ccf,tau_acf))
1416
1417
1417 return tau
1418 return tau
1418
1419
1419 def __calculateLag1Phase(self, data, lagTRange):
1420 def __calculateLag1Phase(self, data, lagTRange):
1420 data1 = stats.nanmean(data, axis = 0)
1421 data1 = stats.nanmean(data, axis = 0)
1421 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1422 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1422
1423
1423 phase = numpy.angle(data1[lag1,:])
1424 phase = numpy.angle(data1[lag1,:])
1424
1425
1425 return phase
1426 return phase
1426
1427
1427 class SpectralFitting(Operation):
1428 class SpectralFitting(Operation):
1428 '''
1429 '''
1429 Function GetMoments()
1430 Function GetMoments()
1430
1431
1431 Input:
1432 Input:
1432 Output:
1433 Output:
1433 Variables modified:
1434 Variables modified:
1434 '''
1435 '''
1435
1436
1436 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1437 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1437
1438
1438
1439
1439 if path != None:
1440 if path != None:
1440 sys.path.append(path)
1441 sys.path.append(path)
1441 self.dataOut.library = importlib.import_module(file)
1442 self.dataOut.library = importlib.import_module(file)
1442
1443
1443 #To be inserted as a parameter
1444 #To be inserted as a parameter
1444 groupArray = numpy.array(groupList)
1445 groupArray = numpy.array(groupList)
1445 # groupArray = numpy.array([[0,1],[2,3]])
1446 # groupArray = numpy.array([[0,1],[2,3]])
1446 self.dataOut.groupList = groupArray
1447 self.dataOut.groupList = groupArray
1447
1448
1448 nGroups = groupArray.shape[0]
1449 nGroups = groupArray.shape[0]
1449 nChannels = self.dataIn.nChannels
1450 nChannels = self.dataIn.nChannels
1450 nHeights=self.dataIn.heightList.size
1451 nHeights=self.dataIn.heightList.size
1451
1452
1452 #Parameters Array
1453 #Parameters Array
1453 self.dataOut.data_param = None
1454 self.dataOut.data_param = None
1454
1455
1455 #Set constants
1456 #Set constants
1456 constants = self.dataOut.library.setConstants(self.dataIn)
1457 constants = self.dataOut.library.setConstants(self.dataIn)
1457 self.dataOut.constants = constants
1458 self.dataOut.constants = constants
1458 M = self.dataIn.normFactor
1459 M = self.dataIn.normFactor
1459 N = self.dataIn.nFFTPoints
1460 N = self.dataIn.nFFTPoints
1460 ippSeconds = self.dataIn.ippSeconds
1461 ippSeconds = self.dataIn.ippSeconds
1461 K = self.dataIn.nIncohInt
1462 K = self.dataIn.nIncohInt
1462 pairsArray = numpy.array(self.dataIn.pairsList)
1463 pairsArray = numpy.array(self.dataIn.pairsList)
1463
1464
1464 #List of possible combinations
1465 #List of possible combinations
1465 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1466 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1466 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1467 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1467
1468
1468 if getSNR:
1469 if getSNR:
1469 listChannels = groupArray.reshape((groupArray.size))
1470 listChannels = groupArray.reshape((groupArray.size))
1470 listChannels.sort()
1471 listChannels.sort()
1471 noise = self.dataIn.getNoise()
1472 noise = self.dataIn.getNoise()
1472 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1473 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1473
1474
1474 for i in range(nGroups):
1475 for i in range(nGroups):
1475 coord = groupArray[i,:]
1476 coord = groupArray[i,:]
1476
1477
1477 #Input data array
1478 #Input data array
1478 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1479 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1479 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1480 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1480
1481
1481 #Cross Spectra data array for Covariance Matrixes
1482 #Cross Spectra data array for Covariance Matrixes
1482 ind = 0
1483 ind = 0
1483 for pairs in listComb:
1484 for pairs in listComb:
1484 pairsSel = numpy.array([coord[x],coord[y]])
1485 pairsSel = numpy.array([coord[x],coord[y]])
1485 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1486 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1486 ind += 1
1487 ind += 1
1487 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1488 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1488 dataCross = dataCross**2/K
1489 dataCross = dataCross**2/K
1489
1490
1490 for h in range(nHeights):
1491 for h in range(nHeights):
1491
1492
1492 #Input
1493 #Input
1493 d = data[:,h]
1494 d = data[:,h]
1494
1495
1495 #Covariance Matrix
1496 #Covariance Matrix
1496 D = numpy.diag(d**2/K)
1497 D = numpy.diag(d**2/K)
1497 ind = 0
1498 ind = 0
1498 for pairs in listComb:
1499 for pairs in listComb:
1499 #Coordinates in Covariance Matrix
1500 #Coordinates in Covariance Matrix
1500 x = pairs[0]
1501 x = pairs[0]
1501 y = pairs[1]
1502 y = pairs[1]
1502 #Channel Index
1503 #Channel Index
1503 S12 = dataCross[ind,:,h]
1504 S12 = dataCross[ind,:,h]
1504 D12 = numpy.diag(S12)
1505 D12 = numpy.diag(S12)
1505 #Completing Covariance Matrix with Cross Spectras
1506 #Completing Covariance Matrix with Cross Spectras
1506 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1507 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1507 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1508 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1508 ind += 1
1509 ind += 1
1509 Dinv=numpy.linalg.inv(D)
1510 Dinv=numpy.linalg.inv(D)
1510 L=numpy.linalg.cholesky(Dinv)
1511 L=numpy.linalg.cholesky(Dinv)
1511 LT=L.T
1512 LT=L.T
1512
1513
1513 dp = numpy.dot(LT,d)
1514 dp = numpy.dot(LT,d)
1514
1515
1515 #Initial values
1516 #Initial values
1516 data_spc = self.dataIn.data_spc[coord,:,h]
1517 data_spc = self.dataIn.data_spc[coord,:,h]
1517
1518
1518 if (h>0)and(error1[3]<5):
1519 if (h>0)and(error1[3]<5):
1519 p0 = self.dataOut.data_param[i,:,h-1]
1520 p0 = self.dataOut.data_param[i,:,h-1]
1520 else:
1521 else:
1521 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1522 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1522
1523
1523 try:
1524 try:
1524 #Least Squares
1525 #Least Squares
1525 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1526 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1526 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1527 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1527 #Chi square error
1528 #Chi square error
1528 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1529 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1529 #Error with Jacobian
1530 #Error with Jacobian
1530 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1531 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1531 except:
1532 except:
1532 minp = p0*numpy.nan
1533 minp = p0*numpy.nan
1533 error0 = numpy.nan
1534 error0 = numpy.nan
1534 error1 = p0*numpy.nan
1535 error1 = p0*numpy.nan
1535
1536
1536 #Save
1537 #Save
1537 if self.dataOut.data_param is None:
1538 if self.dataOut.data_param is None:
1538 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1539 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1539 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1540 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1540
1541
1541 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1542 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1542 self.dataOut.data_param[i,:,h] = minp
1543 self.dataOut.data_param[i,:,h] = minp
1543 return
1544 return
1544
1545
1545 def __residFunction(self, p, dp, LT, constants):
1546 def __residFunction(self, p, dp, LT, constants):
1546
1547
1547 fm = self.dataOut.library.modelFunction(p, constants)
1548 fm = self.dataOut.library.modelFunction(p, constants)
1548 fmp=numpy.dot(LT,fm)
1549 fmp=numpy.dot(LT,fm)
1549
1550
1550 return dp-fmp
1551 return dp-fmp
1551
1552
1552 def __getSNR(self, z, noise):
1553 def __getSNR(self, z, noise):
1553
1554
1554 avg = numpy.average(z, axis=1)
1555 avg = numpy.average(z, axis=1)
1555 SNR = (avg.T-noise)/noise
1556 SNR = (avg.T-noise)/noise
1556 SNR = SNR.T
1557 SNR = SNR.T
1557 return SNR
1558 return SNR
1558
1559
1559 def __chisq(p,chindex,hindex):
1560 def __chisq(p,chindex,hindex):
1560 #similar to Resid but calculates CHI**2
1561 #similar to Resid but calculates CHI**2
1561 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1562 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1562 dp=numpy.dot(LT,d)
1563 dp=numpy.dot(LT,d)
1563 fmp=numpy.dot(LT,fm)
1564 fmp=numpy.dot(LT,fm)
1564 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1565 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1565 return chisq
1566 return chisq
1566
1567
1567 class WindProfiler(Operation):
1568 class WindProfiler(Operation):
1568
1569
1569 __isConfig = False
1570 __isConfig = False
1570
1571
1571 __initime = None
1572 __initime = None
1572 __lastdatatime = None
1573 __lastdatatime = None
1573 __integrationtime = None
1574 __integrationtime = None
1574
1575
1575 __buffer = None
1576 __buffer = None
1576
1577
1577 __dataReady = False
1578 __dataReady = False
1578
1579
1579 __firstdata = None
1580 __firstdata = None
1580
1581
1581 n = None
1582 n = None
1582
1583
1583 def __init__(self):
1584 def __init__(self):
1584 Operation.__init__(self)
1585 Operation.__init__(self)
1585
1586
1586 def __calculateCosDir(self, elev, azim):
1587 def __calculateCosDir(self, elev, azim):
1587 zen = (90 - elev)*numpy.pi/180
1588 zen = (90 - elev)*numpy.pi/180
1588 azim = azim*numpy.pi/180
1589 azim = azim*numpy.pi/180
1589 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1590 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1590 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1591 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1591
1592
1592 signX = numpy.sign(numpy.cos(azim))
1593 signX = numpy.sign(numpy.cos(azim))
1593 signY = numpy.sign(numpy.sin(azim))
1594 signY = numpy.sign(numpy.sin(azim))
1594
1595
1595 cosDirX = numpy.copysign(cosDirX, signX)
1596 cosDirX = numpy.copysign(cosDirX, signX)
1596 cosDirY = numpy.copysign(cosDirY, signY)
1597 cosDirY = numpy.copysign(cosDirY, signY)
1597 return cosDirX, cosDirY
1598 return cosDirX, cosDirY
1598
1599
1599 def __calculateAngles(self, theta_x, theta_y, azimuth):
1600 def __calculateAngles(self, theta_x, theta_y, azimuth):
1600
1601
1601 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1602 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1602 zenith_arr = numpy.arccos(dir_cosw)
1603 zenith_arr = numpy.arccos(dir_cosw)
1603 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1604 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1604
1605
1605 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1606 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1606 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1607 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1607
1608
1608 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1609 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1609
1610
1610 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1611 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1611
1612
1612 #
1613 #
1613 if horOnly:
1614 if horOnly:
1614 A = numpy.c_[dir_cosu,dir_cosv]
1615 A = numpy.c_[dir_cosu,dir_cosv]
1615 else:
1616 else:
1616 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1617 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1617 A = numpy.asmatrix(A)
1618 A = numpy.asmatrix(A)
1618 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1619 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1619
1620
1620 return A1
1621 return A1
1621
1622
1622 def __correctValues(self, heiRang, phi, velRadial, SNR):
1623 def __correctValues(self, heiRang, phi, velRadial, SNR):
1623 listPhi = phi.tolist()
1624 listPhi = phi.tolist()
1624 maxid = listPhi.index(max(listPhi))
1625 maxid = listPhi.index(max(listPhi))
1625 minid = listPhi.index(min(listPhi))
1626 minid = listPhi.index(min(listPhi))
1626
1627
1627 rango = list(range(len(phi)))
1628 rango = list(range(len(phi)))
1628 # rango = numpy.delete(rango,maxid)
1629 # rango = numpy.delete(rango,maxid)
1629
1630
1630 heiRang1 = heiRang*math.cos(phi[maxid])
1631 heiRang1 = heiRang*math.cos(phi[maxid])
1631 heiRangAux = heiRang*math.cos(phi[minid])
1632 heiRangAux = heiRang*math.cos(phi[minid])
1632 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1633 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1633 heiRang1 = numpy.delete(heiRang1,indOut)
1634 heiRang1 = numpy.delete(heiRang1,indOut)
1634
1635
1635 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1636 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1636 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1637 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1637
1638
1638 for i in rango:
1639 for i in rango:
1639 x = heiRang*math.cos(phi[i])
1640 x = heiRang*math.cos(phi[i])
1640 y1 = velRadial[i,:]
1641 y1 = velRadial[i,:]
1641 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1642 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1642
1643
1643 x1 = heiRang1
1644 x1 = heiRang1
1644 y11 = f1(x1)
1645 y11 = f1(x1)
1645
1646
1646 y2 = SNR[i,:]
1647 y2 = SNR[i,:]
1647 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1648 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1648 y21 = f2(x1)
1649 y21 = f2(x1)
1649
1650
1650 velRadial1[i,:] = y11
1651 velRadial1[i,:] = y11
1651 SNR1[i,:] = y21
1652 SNR1[i,:] = y21
1652
1653
1653 return heiRang1, velRadial1, SNR1
1654 return heiRang1, velRadial1, SNR1
1654
1655
1655 def __calculateVelUVW(self, A, velRadial):
1656 def __calculateVelUVW(self, A, velRadial):
1656
1657
1657 #Operacion Matricial
1658 #Operacion Matricial
1658 # velUVW = numpy.zeros((velRadial.shape[1],3))
1659 # velUVW = numpy.zeros((velRadial.shape[1],3))
1659 # for ind in range(velRadial.shape[1]):
1660 # for ind in range(velRadial.shape[1]):
1660 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1661 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1661 # velUVW = velUVW.transpose()
1662 # velUVW = velUVW.transpose()
1662 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1663 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1663 velUVW[:,:] = numpy.dot(A,velRadial)
1664 velUVW[:,:] = numpy.dot(A,velRadial)
1664
1665
1665
1666
1666 return velUVW
1667 return velUVW
1667
1668
1668 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1669 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1669
1670
1670 def techniqueDBS(self, kwargs):
1671 def techniqueDBS(self, kwargs):
1671 """
1672 """
1672 Function that implements Doppler Beam Swinging (DBS) technique.
1673 Function that implements Doppler Beam Swinging (DBS) technique.
1673
1674
1674 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1675 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1675 Direction correction (if necessary), Ranges and SNR
1676 Direction correction (if necessary), Ranges and SNR
1676
1677
1677 Output: Winds estimation (Zonal, Meridional and Vertical)
1678 Output: Winds estimation (Zonal, Meridional and Vertical)
1678
1679
1679 Parameters affected: Winds, height range, SNR
1680 Parameters affected: Winds, height range, SNR
1680 """
1681 """
1681 velRadial0 = kwargs['velRadial']
1682 velRadial0 = kwargs['velRadial']
1682 heiRang = kwargs['heightList']
1683 heiRang = kwargs['heightList']
1683 SNR0 = kwargs['SNR']
1684 SNR0 = kwargs['SNR']
1684
1685
1685 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1686 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1686 theta_x = numpy.array(kwargs['dirCosx'])
1687 theta_x = numpy.array(kwargs['dirCosx'])
1687 theta_y = numpy.array(kwargs['dirCosy'])
1688 theta_y = numpy.array(kwargs['dirCosy'])
1688 else:
1689 else:
1689 elev = numpy.array(kwargs['elevation'])
1690 elev = numpy.array(kwargs['elevation'])
1690 azim = numpy.array(kwargs['azimuth'])
1691 azim = numpy.array(kwargs['azimuth'])
1691 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1692 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1692 azimuth = kwargs['correctAzimuth']
1693 azimuth = kwargs['correctAzimuth']
1693 if 'horizontalOnly' in kwargs:
1694 if 'horizontalOnly' in kwargs:
1694 horizontalOnly = kwargs['horizontalOnly']
1695 horizontalOnly = kwargs['horizontalOnly']
1695 else: horizontalOnly = False
1696 else: horizontalOnly = False
1696 if 'correctFactor' in kwargs:
1697 if 'correctFactor' in kwargs:
1697 correctFactor = kwargs['correctFactor']
1698 correctFactor = kwargs['correctFactor']
1698 else: correctFactor = 1
1699 else: correctFactor = 1
1699 if 'channelList' in kwargs:
1700 if 'channelList' in kwargs:
1700 channelList = kwargs['channelList']
1701 channelList = kwargs['channelList']
1701 if len(channelList) == 2:
1702 if len(channelList) == 2:
1702 horizontalOnly = True
1703 horizontalOnly = True
1703 arrayChannel = numpy.array(channelList)
1704 arrayChannel = numpy.array(channelList)
1704 param = param[arrayChannel,:,:]
1705 param = param[arrayChannel,:,:]
1705 theta_x = theta_x[arrayChannel]
1706 theta_x = theta_x[arrayChannel]
1706 theta_y = theta_y[arrayChannel]
1707 theta_y = theta_y[arrayChannel]
1707
1708
1708 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1709 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1709 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1710 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1710 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1711 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1711
1712
1712 #Calculo de Componentes de la velocidad con DBS
1713 #Calculo de Componentes de la velocidad con DBS
1713 winds = self.__calculateVelUVW(A,velRadial1)
1714 winds = self.__calculateVelUVW(A,velRadial1)
1714
1715
1715 return winds, heiRang1, SNR1
1716 return winds, heiRang1, SNR1
1716
1717
1717 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1718 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1718
1719
1719 nPairs = len(pairs_ccf)
1720 nPairs = len(pairs_ccf)
1720 posx = numpy.asarray(posx)
1721 posx = numpy.asarray(posx)
1721 posy = numpy.asarray(posy)
1722 posy = numpy.asarray(posy)
1722
1723
1723 #Rotacion Inversa para alinear con el azimuth
1724 #Rotacion Inversa para alinear con el azimuth
1724 if azimuth!= None:
1725 if azimuth!= None:
1725 azimuth = azimuth*math.pi/180
1726 azimuth = azimuth*math.pi/180
1726 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1727 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1727 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1728 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1728 else:
1729 else:
1729 posx1 = posx
1730 posx1 = posx
1730 posy1 = posy
1731 posy1 = posy
1731
1732
1732 #Calculo de Distancias
1733 #Calculo de Distancias
1733 distx = numpy.zeros(nPairs)
1734 distx = numpy.zeros(nPairs)
1734 disty = numpy.zeros(nPairs)
1735 disty = numpy.zeros(nPairs)
1735 dist = numpy.zeros(nPairs)
1736 dist = numpy.zeros(nPairs)
1736 ang = numpy.zeros(nPairs)
1737 ang = numpy.zeros(nPairs)
1737
1738
1738 for i in range(nPairs):
1739 for i in range(nPairs):
1739 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1740 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1740 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1741 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1741 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1742 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1742 ang[i] = numpy.arctan2(disty[i],distx[i])
1743 ang[i] = numpy.arctan2(disty[i],distx[i])
1743
1744
1744 return distx, disty, dist, ang
1745 return distx, disty, dist, ang
1745 #Calculo de Matrices
1746 #Calculo de Matrices
1746 # nPairs = len(pairs)
1747 # nPairs = len(pairs)
1747 # ang1 = numpy.zeros((nPairs, 2, 1))
1748 # ang1 = numpy.zeros((nPairs, 2, 1))
1748 # dist1 = numpy.zeros((nPairs, 2, 1))
1749 # dist1 = numpy.zeros((nPairs, 2, 1))
1749 #
1750 #
1750 # for j in range(nPairs):
1751 # for j in range(nPairs):
1751 # dist1[j,0,0] = dist[pairs[j][0]]
1752 # dist1[j,0,0] = dist[pairs[j][0]]
1752 # dist1[j,1,0] = dist[pairs[j][1]]
1753 # dist1[j,1,0] = dist[pairs[j][1]]
1753 # ang1[j,0,0] = ang[pairs[j][0]]
1754 # ang1[j,0,0] = ang[pairs[j][0]]
1754 # ang1[j,1,0] = ang[pairs[j][1]]
1755 # ang1[j,1,0] = ang[pairs[j][1]]
1755 #
1756 #
1756 # return distx,disty, dist1,ang1
1757 # return distx,disty, dist1,ang1
1757
1758
1758
1759
1759 def __calculateVelVer(self, phase, lagTRange, _lambda):
1760 def __calculateVelVer(self, phase, lagTRange, _lambda):
1760
1761
1761 Ts = lagTRange[1] - lagTRange[0]
1762 Ts = lagTRange[1] - lagTRange[0]
1762 velW = -_lambda*phase/(4*math.pi*Ts)
1763 velW = -_lambda*phase/(4*math.pi*Ts)
1763
1764
1764 return velW
1765 return velW
1765
1766
1766 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1767 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1767 nPairs = tau1.shape[0]
1768 nPairs = tau1.shape[0]
1768 nHeights = tau1.shape[1]
1769 nHeights = tau1.shape[1]
1769 vel = numpy.zeros((nPairs,3,nHeights))
1770 vel = numpy.zeros((nPairs,3,nHeights))
1770 dist1 = numpy.reshape(dist, (dist.size,1))
1771 dist1 = numpy.reshape(dist, (dist.size,1))
1771
1772
1772 angCos = numpy.cos(ang)
1773 angCos = numpy.cos(ang)
1773 angSin = numpy.sin(ang)
1774 angSin = numpy.sin(ang)
1774
1775
1775 vel0 = dist1*tau1/(2*tau2**2)
1776 vel0 = dist1*tau1/(2*tau2**2)
1776 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1777 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1777 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1778 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1778
1779
1779 ind = numpy.where(numpy.isinf(vel))
1780 ind = numpy.where(numpy.isinf(vel))
1780 vel[ind] = numpy.nan
1781 vel[ind] = numpy.nan
1781
1782
1782 return vel
1783 return vel
1783
1784
1784 # def __getPairsAutoCorr(self, pairsList, nChannels):
1785 # def __getPairsAutoCorr(self, pairsList, nChannels):
1785 #
1786 #
1786 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1787 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1787 #
1788 #
1788 # for l in range(len(pairsList)):
1789 # for l in range(len(pairsList)):
1789 # firstChannel = pairsList[l][0]
1790 # firstChannel = pairsList[l][0]
1790 # secondChannel = pairsList[l][1]
1791 # secondChannel = pairsList[l][1]
1791 #
1792 #
1792 # #Obteniendo pares de Autocorrelacion
1793 # #Obteniendo pares de Autocorrelacion
1793 # if firstChannel == secondChannel:
1794 # if firstChannel == secondChannel:
1794 # pairsAutoCorr[firstChannel] = int(l)
1795 # pairsAutoCorr[firstChannel] = int(l)
1795 #
1796 #
1796 # pairsAutoCorr = pairsAutoCorr.astype(int)
1797 # pairsAutoCorr = pairsAutoCorr.astype(int)
1797 #
1798 #
1798 # pairsCrossCorr = range(len(pairsList))
1799 # pairsCrossCorr = range(len(pairsList))
1799 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1800 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1800 #
1801 #
1801 # return pairsAutoCorr, pairsCrossCorr
1802 # return pairsAutoCorr, pairsCrossCorr
1802
1803
1803 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1804 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1804 def techniqueSA(self, kwargs):
1805 def techniqueSA(self, kwargs):
1805
1806
1806 """
1807 """
1807 Function that implements Spaced Antenna (SA) technique.
1808 Function that implements Spaced Antenna (SA) technique.
1808
1809
1809 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1810 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1810 Direction correction (if necessary), Ranges and SNR
1811 Direction correction (if necessary), Ranges and SNR
1811
1812
1812 Output: Winds estimation (Zonal, Meridional and Vertical)
1813 Output: Winds estimation (Zonal, Meridional and Vertical)
1813
1814
1814 Parameters affected: Winds
1815 Parameters affected: Winds
1815 """
1816 """
1816 position_x = kwargs['positionX']
1817 position_x = kwargs['positionX']
1817 position_y = kwargs['positionY']
1818 position_y = kwargs['positionY']
1818 azimuth = kwargs['azimuth']
1819 azimuth = kwargs['azimuth']
1819
1820
1820 if 'correctFactor' in kwargs:
1821 if 'correctFactor' in kwargs:
1821 correctFactor = kwargs['correctFactor']
1822 correctFactor = kwargs['correctFactor']
1822 else:
1823 else:
1823 correctFactor = 1
1824 correctFactor = 1
1824
1825
1825 groupList = kwargs['groupList']
1826 groupList = kwargs['groupList']
1826 pairs_ccf = groupList[1]
1827 pairs_ccf = groupList[1]
1827 tau = kwargs['tau']
1828 tau = kwargs['tau']
1828 _lambda = kwargs['_lambda']
1829 _lambda = kwargs['_lambda']
1829
1830
1830 #Cross Correlation pairs obtained
1831 #Cross Correlation pairs obtained
1831 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1832 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1832 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1833 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1833 # pairsSelArray = numpy.array(pairsSelected)
1834 # pairsSelArray = numpy.array(pairsSelected)
1834 # pairs = []
1835 # pairs = []
1835 #
1836 #
1836 # #Wind estimation pairs obtained
1837 # #Wind estimation pairs obtained
1837 # for i in range(pairsSelArray.shape[0]/2):
1838 # for i in range(pairsSelArray.shape[0]/2):
1838 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1839 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1839 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1840 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1840 # pairs.append((ind1,ind2))
1841 # pairs.append((ind1,ind2))
1841
1842
1842 indtau = tau.shape[0]/2
1843 indtau = tau.shape[0]/2
1843 tau1 = tau[:indtau,:]
1844 tau1 = tau[:indtau,:]
1844 tau2 = tau[indtau:-1,:]
1845 tau2 = tau[indtau:-1,:]
1845 # tau1 = tau1[pairs,:]
1846 # tau1 = tau1[pairs,:]
1846 # tau2 = tau2[pairs,:]
1847 # tau2 = tau2[pairs,:]
1847 phase1 = tau[-1,:]
1848 phase1 = tau[-1,:]
1848
1849
1849 #---------------------------------------------------------------------
1850 #---------------------------------------------------------------------
1850 #Metodo Directo
1851 #Metodo Directo
1851 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1852 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1852 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1853 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1853 winds = stats.nanmean(winds, axis=0)
1854 winds = stats.nanmean(winds, axis=0)
1854 #---------------------------------------------------------------------
1855 #---------------------------------------------------------------------
1855 #Metodo General
1856 #Metodo General
1856 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1857 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1857 # #Calculo Coeficientes de Funcion de Correlacion
1858 # #Calculo Coeficientes de Funcion de Correlacion
1858 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1859 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1859 # #Calculo de Velocidades
1860 # #Calculo de Velocidades
1860 # winds = self.calculateVelUV(F,G,A,B,H)
1861 # winds = self.calculateVelUV(F,G,A,B,H)
1861
1862
1862 #---------------------------------------------------------------------
1863 #---------------------------------------------------------------------
1863 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1864 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1864 winds = correctFactor*winds
1865 winds = correctFactor*winds
1865 return winds
1866 return winds
1866
1867
1867 def __checkTime(self, currentTime, paramInterval, outputInterval):
1868 def __checkTime(self, currentTime, paramInterval, outputInterval):
1868
1869
1869 dataTime = currentTime + paramInterval
1870 dataTime = currentTime + paramInterval
1870 deltaTime = dataTime - self.__initime
1871 deltaTime = dataTime - self.__initime
1871
1872
1872 if deltaTime >= outputInterval or deltaTime < 0:
1873 if deltaTime >= outputInterval or deltaTime < 0:
1873 self.__dataReady = True
1874 self.__dataReady = True
1874 return
1875 return
1875
1876
1876 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1877 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1877 '''
1878 '''
1878 Function that implements winds estimation technique with detected meteors.
1879 Function that implements winds estimation technique with detected meteors.
1879
1880
1880 Input: Detected meteors, Minimum meteor quantity to wind estimation
1881 Input: Detected meteors, Minimum meteor quantity to wind estimation
1881
1882
1882 Output: Winds estimation (Zonal and Meridional)
1883 Output: Winds estimation (Zonal and Meridional)
1883
1884
1884 Parameters affected: Winds
1885 Parameters affected: Winds
1885 '''
1886 '''
1886 #Settings
1887 #Settings
1887 nInt = (heightMax - heightMin)/2
1888 nInt = (heightMax - heightMin)/2
1888 nInt = int(nInt)
1889 nInt = int(nInt)
1889 winds = numpy.zeros((2,nInt))*numpy.nan
1890 winds = numpy.zeros((2,nInt))*numpy.nan
1890
1891
1891 #Filter errors
1892 #Filter errors
1892 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1893 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1893 finalMeteor = arrayMeteor[error,:]
1894 finalMeteor = arrayMeteor[error,:]
1894
1895
1895 #Meteor Histogram
1896 #Meteor Histogram
1896 finalHeights = finalMeteor[:,2]
1897 finalHeights = finalMeteor[:,2]
1897 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1898 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1898 nMeteorsPerI = hist[0]
1899 nMeteorsPerI = hist[0]
1899 heightPerI = hist[1]
1900 heightPerI = hist[1]
1900
1901
1901 #Sort of meteors
1902 #Sort of meteors
1902 indSort = finalHeights.argsort()
1903 indSort = finalHeights.argsort()
1903 finalMeteor2 = finalMeteor[indSort,:]
1904 finalMeteor2 = finalMeteor[indSort,:]
1904
1905
1905 # Calculating winds
1906 # Calculating winds
1906 ind1 = 0
1907 ind1 = 0
1907 ind2 = 0
1908 ind2 = 0
1908
1909
1909 for i in range(nInt):
1910 for i in range(nInt):
1910 nMet = nMeteorsPerI[i]
1911 nMet = nMeteorsPerI[i]
1911 ind1 = ind2
1912 ind1 = ind2
1912 ind2 = ind1 + nMet
1913 ind2 = ind1 + nMet
1913
1914
1914 meteorAux = finalMeteor2[ind1:ind2,:]
1915 meteorAux = finalMeteor2[ind1:ind2,:]
1915
1916
1916 if meteorAux.shape[0] >= meteorThresh:
1917 if meteorAux.shape[0] >= meteorThresh:
1917 vel = meteorAux[:, 6]
1918 vel = meteorAux[:, 6]
1918 zen = meteorAux[:, 4]*numpy.pi/180
1919 zen = meteorAux[:, 4]*numpy.pi/180
1919 azim = meteorAux[:, 3]*numpy.pi/180
1920 azim = meteorAux[:, 3]*numpy.pi/180
1920
1921
1921 n = numpy.cos(zen)
1922 n = numpy.cos(zen)
1922 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1923 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1923 # l = m*numpy.tan(azim)
1924 # l = m*numpy.tan(azim)
1924 l = numpy.sin(zen)*numpy.sin(azim)
1925 l = numpy.sin(zen)*numpy.sin(azim)
1925 m = numpy.sin(zen)*numpy.cos(azim)
1926 m = numpy.sin(zen)*numpy.cos(azim)
1926
1927
1927 A = numpy.vstack((l, m)).transpose()
1928 A = numpy.vstack((l, m)).transpose()
1928 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1929 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1929 windsAux = numpy.dot(A1, vel)
1930 windsAux = numpy.dot(A1, vel)
1930
1931
1931 winds[0,i] = windsAux[0]
1932 winds[0,i] = windsAux[0]
1932 winds[1,i] = windsAux[1]
1933 winds[1,i] = windsAux[1]
1933
1934
1934 return winds, heightPerI[:-1]
1935 return winds, heightPerI[:-1]
1935
1936
1936 def techniqueNSM_SA(self, **kwargs):
1937 def techniqueNSM_SA(self, **kwargs):
1937 metArray = kwargs['metArray']
1938 metArray = kwargs['metArray']
1938 heightList = kwargs['heightList']
1939 heightList = kwargs['heightList']
1939 timeList = kwargs['timeList']
1940 timeList = kwargs['timeList']
1940
1941
1941 rx_location = kwargs['rx_location']
1942 rx_location = kwargs['rx_location']
1942 groupList = kwargs['groupList']
1943 groupList = kwargs['groupList']
1943 azimuth = kwargs['azimuth']
1944 azimuth = kwargs['azimuth']
1944 dfactor = kwargs['dfactor']
1945 dfactor = kwargs['dfactor']
1945 k = kwargs['k']
1946 k = kwargs['k']
1946
1947
1947 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
1948 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
1948 d = dist*dfactor
1949 d = dist*dfactor
1949 #Phase calculation
1950 #Phase calculation
1950 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
1951 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
1951
1952
1952 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
1953 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
1953
1954
1954 velEst = numpy.zeros((heightList.size,2))*numpy.nan
1955 velEst = numpy.zeros((heightList.size,2))*numpy.nan
1955 azimuth1 = azimuth1*numpy.pi/180
1956 azimuth1 = azimuth1*numpy.pi/180
1956
1957
1957 for i in range(heightList.size):
1958 for i in range(heightList.size):
1958 h = heightList[i]
1959 h = heightList[i]
1959 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
1960 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
1960 metHeight = metArray1[indH,:]
1961 metHeight = metArray1[indH,:]
1961 if metHeight.shape[0] >= 2:
1962 if metHeight.shape[0] >= 2:
1962 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
1963 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
1963 iazim = metHeight[:,1].astype(int)
1964 iazim = metHeight[:,1].astype(int)
1964 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
1965 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
1965 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
1966 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
1966 A = numpy.asmatrix(A)
1967 A = numpy.asmatrix(A)
1967 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
1968 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
1968 velHor = numpy.dot(A1,velAux)
1969 velHor = numpy.dot(A1,velAux)
1969
1970
1970 velEst[i,:] = numpy.squeeze(velHor)
1971 velEst[i,:] = numpy.squeeze(velHor)
1971 return velEst
1972 return velEst
1972
1973
1973 def __getPhaseSlope(self, metArray, heightList, timeList):
1974 def __getPhaseSlope(self, metArray, heightList, timeList):
1974 meteorList = []
1975 meteorList = []
1975 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
1976 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
1976 #Putting back together the meteor matrix
1977 #Putting back together the meteor matrix
1977 utctime = metArray[:,0]
1978 utctime = metArray[:,0]
1978 uniqueTime = numpy.unique(utctime)
1979 uniqueTime = numpy.unique(utctime)
1979
1980
1980 phaseDerThresh = 0.5
1981 phaseDerThresh = 0.5
1981 ippSeconds = timeList[1] - timeList[0]
1982 ippSeconds = timeList[1] - timeList[0]
1982 sec = numpy.where(timeList>1)[0][0]
1983 sec = numpy.where(timeList>1)[0][0]
1983 nPairs = metArray.shape[1] - 6
1984 nPairs = metArray.shape[1] - 6
1984 nHeights = len(heightList)
1985 nHeights = len(heightList)
1985
1986
1986 for t in uniqueTime:
1987 for t in uniqueTime:
1987 metArray1 = metArray[utctime==t,:]
1988 metArray1 = metArray[utctime==t,:]
1988 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
1989 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
1989 tmet = metArray1[:,1].astype(int)
1990 tmet = metArray1[:,1].astype(int)
1990 hmet = metArray1[:,2].astype(int)
1991 hmet = metArray1[:,2].astype(int)
1991
1992
1992 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
1993 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
1993 metPhase[:,:] = numpy.nan
1994 metPhase[:,:] = numpy.nan
1994 metPhase[:,hmet,tmet] = metArray1[:,6:].T
1995 metPhase[:,hmet,tmet] = metArray1[:,6:].T
1995
1996
1996 #Delete short trails
1997 #Delete short trails
1997 metBool = ~numpy.isnan(metPhase[0,:,:])
1998 metBool = ~numpy.isnan(metPhase[0,:,:])
1998 heightVect = numpy.sum(metBool, axis = 1)
1999 heightVect = numpy.sum(metBool, axis = 1)
1999 metBool[heightVect<sec,:] = False
2000 metBool[heightVect<sec,:] = False
2000 metPhase[:,heightVect<sec,:] = numpy.nan
2001 metPhase[:,heightVect<sec,:] = numpy.nan
2001
2002
2002 #Derivative
2003 #Derivative
2003 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2004 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2004 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2005 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2005 metPhase[phDerAux] = numpy.nan
2006 metPhase[phDerAux] = numpy.nan
2006
2007
2007 #--------------------------METEOR DETECTION -----------------------------------------
2008 #--------------------------METEOR DETECTION -----------------------------------------
2008 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2009 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2009
2010
2010 for p in numpy.arange(nPairs):
2011 for p in numpy.arange(nPairs):
2011 phase = metPhase[p,:,:]
2012 phase = metPhase[p,:,:]
2012 phDer = metDer[p,:,:]
2013 phDer = metDer[p,:,:]
2013
2014
2014 for h in indMet:
2015 for h in indMet:
2015 height = heightList[h]
2016 height = heightList[h]
2016 phase1 = phase[h,:] #82
2017 phase1 = phase[h,:] #82
2017 phDer1 = phDer[h,:]
2018 phDer1 = phDer[h,:]
2018
2019
2019 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2020 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2020
2021
2021 indValid = numpy.where(~numpy.isnan(phase1))[0]
2022 indValid = numpy.where(~numpy.isnan(phase1))[0]
2022 initMet = indValid[0]
2023 initMet = indValid[0]
2023 endMet = 0
2024 endMet = 0
2024
2025
2025 for i in range(len(indValid)-1):
2026 for i in range(len(indValid)-1):
2026
2027
2027 #Time difference
2028 #Time difference
2028 inow = indValid[i]
2029 inow = indValid[i]
2029 inext = indValid[i+1]
2030 inext = indValid[i+1]
2030 idiff = inext - inow
2031 idiff = inext - inow
2031 #Phase difference
2032 #Phase difference
2032 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2033 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2033
2034
2034 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2035 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2035 sizeTrail = inow - initMet + 1
2036 sizeTrail = inow - initMet + 1
2036 if sizeTrail>3*sec: #Too short meteors
2037 if sizeTrail>3*sec: #Too short meteors
2037 x = numpy.arange(initMet,inow+1)*ippSeconds
2038 x = numpy.arange(initMet,inow+1)*ippSeconds
2038 y = phase1[initMet:inow+1]
2039 y = phase1[initMet:inow+1]
2039 ynnan = ~numpy.isnan(y)
2040 ynnan = ~numpy.isnan(y)
2040 x = x[ynnan]
2041 x = x[ynnan]
2041 y = y[ynnan]
2042 y = y[ynnan]
2042 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2043 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2043 ylin = x*slope + intercept
2044 ylin = x*slope + intercept
2044 rsq = r_value**2
2045 rsq = r_value**2
2045 if rsq > 0.5:
2046 if rsq > 0.5:
2046 vel = slope#*height*1000/(k*d)
2047 vel = slope#*height*1000/(k*d)
2047 estAux = numpy.array([utctime,p,height, vel, rsq])
2048 estAux = numpy.array([utctime,p,height, vel, rsq])
2048 meteorList.append(estAux)
2049 meteorList.append(estAux)
2049 initMet = inext
2050 initMet = inext
2050 metArray2 = numpy.array(meteorList)
2051 metArray2 = numpy.array(meteorList)
2051
2052
2052 return metArray2
2053 return metArray2
2053
2054
2054 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2055 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2055
2056
2056 azimuth1 = numpy.zeros(len(pairslist))
2057 azimuth1 = numpy.zeros(len(pairslist))
2057 dist = numpy.zeros(len(pairslist))
2058 dist = numpy.zeros(len(pairslist))
2058
2059
2059 for i in range(len(rx_location)):
2060 for i in range(len(rx_location)):
2060 ch0 = pairslist[i][0]
2061 ch0 = pairslist[i][0]
2061 ch1 = pairslist[i][1]
2062 ch1 = pairslist[i][1]
2062
2063
2063 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2064 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2064 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2065 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2065 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2066 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2066 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2067 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2067
2068
2068 azimuth1 -= azimuth0
2069 azimuth1 -= azimuth0
2069 return azimuth1, dist
2070 return azimuth1, dist
2070
2071
2071 def techniqueNSM_DBS(self, **kwargs):
2072 def techniqueNSM_DBS(self, **kwargs):
2072 metArray = kwargs['metArray']
2073 metArray = kwargs['metArray']
2073 heightList = kwargs['heightList']
2074 heightList = kwargs['heightList']
2074 timeList = kwargs['timeList']
2075 timeList = kwargs['timeList']
2075 azimuth = kwargs['azimuth']
2076 azimuth = kwargs['azimuth']
2076 theta_x = numpy.array(kwargs['theta_x'])
2077 theta_x = numpy.array(kwargs['theta_x'])
2077 theta_y = numpy.array(kwargs['theta_y'])
2078 theta_y = numpy.array(kwargs['theta_y'])
2078
2079
2079 utctime = metArray[:,0]
2080 utctime = metArray[:,0]
2080 cmet = metArray[:,1].astype(int)
2081 cmet = metArray[:,1].astype(int)
2081 hmet = metArray[:,3].astype(int)
2082 hmet = metArray[:,3].astype(int)
2082 SNRmet = metArray[:,4]
2083 SNRmet = metArray[:,4]
2083 vmet = metArray[:,5]
2084 vmet = metArray[:,5]
2084 spcmet = metArray[:,6]
2085 spcmet = metArray[:,6]
2085
2086
2086 nChan = numpy.max(cmet) + 1
2087 nChan = numpy.max(cmet) + 1
2087 nHeights = len(heightList)
2088 nHeights = len(heightList)
2088
2089
2089 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2090 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2090 hmet = heightList[hmet]
2091 hmet = heightList[hmet]
2091 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2092 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2092
2093
2093 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2094 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2094
2095
2095 for i in range(nHeights - 1):
2096 for i in range(nHeights - 1):
2096 hmin = heightList[i]
2097 hmin = heightList[i]
2097 hmax = heightList[i + 1]
2098 hmax = heightList[i + 1]
2098
2099
2099 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2100 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2100 indthisH = numpy.where(thisH)
2101 indthisH = numpy.where(thisH)
2101
2102
2102 if numpy.size(indthisH) > 3:
2103 if numpy.size(indthisH) > 3:
2103
2104
2104 vel_aux = vmet[thisH]
2105 vel_aux = vmet[thisH]
2105 chan_aux = cmet[thisH]
2106 chan_aux = cmet[thisH]
2106 cosu_aux = dir_cosu[chan_aux]
2107 cosu_aux = dir_cosu[chan_aux]
2107 cosv_aux = dir_cosv[chan_aux]
2108 cosv_aux = dir_cosv[chan_aux]
2108 cosw_aux = dir_cosw[chan_aux]
2109 cosw_aux = dir_cosw[chan_aux]
2109
2110
2110 nch = numpy.size(numpy.unique(chan_aux))
2111 nch = numpy.size(numpy.unique(chan_aux))
2111 if nch > 1:
2112 if nch > 1:
2112 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2113 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2113 velEst[i,:] = numpy.dot(A,vel_aux)
2114 velEst[i,:] = numpy.dot(A,vel_aux)
2114
2115
2115 return velEst
2116 return velEst
2116
2117
2117 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2118 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2118
2119
2119 param = dataOut.data_param
2120 param = dataOut.data_param
2120 if dataOut.abscissaList != None:
2121 if dataOut.abscissaList != None:
2121 absc = dataOut.abscissaList[:-1]
2122 absc = dataOut.abscissaList[:-1]
2122 # noise = dataOut.noise
2123 # noise = dataOut.noise
2123 heightList = dataOut.heightList
2124 heightList = dataOut.heightList
2124 SNR = dataOut.data_SNR
2125 SNR = dataOut.data_SNR
2125
2126
2126 if technique == 'DBS':
2127 if technique == 'DBS':
2127
2128
2128 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2129 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2129 kwargs['heightList'] = heightList
2130 kwargs['heightList'] = heightList
2130 kwargs['SNR'] = SNR
2131 kwargs['SNR'] = SNR
2131
2132
2132 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2133 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2133 dataOut.utctimeInit = dataOut.utctime
2134 dataOut.utctimeInit = dataOut.utctime
2134 dataOut.outputInterval = dataOut.paramInterval
2135 dataOut.outputInterval = dataOut.paramInterval
2135
2136
2136 elif technique == 'SA':
2137 elif technique == 'SA':
2137
2138
2138 #Parameters
2139 #Parameters
2139 # position_x = kwargs['positionX']
2140 # position_x = kwargs['positionX']
2140 # position_y = kwargs['positionY']
2141 # position_y = kwargs['positionY']
2141 # azimuth = kwargs['azimuth']
2142 # azimuth = kwargs['azimuth']
2142 #
2143 #
2143 # if kwargs.has_key('crosspairsList'):
2144 # if kwargs.has_key('crosspairsList'):
2144 # pairs = kwargs['crosspairsList']
2145 # pairs = kwargs['crosspairsList']
2145 # else:
2146 # else:
2146 # pairs = None
2147 # pairs = None
2147 #
2148 #
2148 # if kwargs.has_key('correctFactor'):
2149 # if kwargs.has_key('correctFactor'):
2149 # correctFactor = kwargs['correctFactor']
2150 # correctFactor = kwargs['correctFactor']
2150 # else:
2151 # else:
2151 # correctFactor = 1
2152 # correctFactor = 1
2152
2153
2153 # tau = dataOut.data_param
2154 # tau = dataOut.data_param
2154 # _lambda = dataOut.C/dataOut.frequency
2155 # _lambda = dataOut.C/dataOut.frequency
2155 # pairsList = dataOut.groupList
2156 # pairsList = dataOut.groupList
2156 # nChannels = dataOut.nChannels
2157 # nChannels = dataOut.nChannels
2157
2158
2158 kwargs['groupList'] = dataOut.groupList
2159 kwargs['groupList'] = dataOut.groupList
2159 kwargs['tau'] = dataOut.data_param
2160 kwargs['tau'] = dataOut.data_param
2160 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2161 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2161 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2162 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2162 dataOut.data_output = self.techniqueSA(kwargs)
2163 dataOut.data_output = self.techniqueSA(kwargs)
2163 dataOut.utctimeInit = dataOut.utctime
2164 dataOut.utctimeInit = dataOut.utctime
2164 dataOut.outputInterval = dataOut.timeInterval
2165 dataOut.outputInterval = dataOut.timeInterval
2165
2166
2166 elif technique == 'Meteors':
2167 elif technique == 'Meteors':
2167 dataOut.flagNoData = True
2168 dataOut.flagNoData = True
2168 self.__dataReady = False
2169 self.__dataReady = False
2169
2170
2170 if 'nHours' in kwargs:
2171 if 'nHours' in kwargs:
2171 nHours = kwargs['nHours']
2172 nHours = kwargs['nHours']
2172 else:
2173 else:
2173 nHours = 1
2174 nHours = 1
2174
2175
2175 if 'meteorsPerBin' in kwargs:
2176 if 'meteorsPerBin' in kwargs:
2176 meteorThresh = kwargs['meteorsPerBin']
2177 meteorThresh = kwargs['meteorsPerBin']
2177 else:
2178 else:
2178 meteorThresh = 6
2179 meteorThresh = 6
2179
2180
2180 if 'hmin' in kwargs:
2181 if 'hmin' in kwargs:
2181 hmin = kwargs['hmin']
2182 hmin = kwargs['hmin']
2182 else: hmin = 70
2183 else: hmin = 70
2183 if 'hmax' in kwargs:
2184 if 'hmax' in kwargs:
2184 hmax = kwargs['hmax']
2185 hmax = kwargs['hmax']
2185 else: hmax = 110
2186 else: hmax = 110
2186
2187
2187 dataOut.outputInterval = nHours*3600
2188 dataOut.outputInterval = nHours*3600
2188
2189
2189 if self.__isConfig == False:
2190 if self.__isConfig == False:
2190 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2191 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2191 #Get Initial LTC time
2192 #Get Initial LTC time
2192 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2193 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2193 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2194 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2194
2195
2195 self.__isConfig = True
2196 self.__isConfig = True
2196
2197
2197 if self.__buffer is None:
2198 if self.__buffer is None:
2198 self.__buffer = dataOut.data_param
2199 self.__buffer = dataOut.data_param
2199 self.__firstdata = copy.copy(dataOut)
2200 self.__firstdata = copy.copy(dataOut)
2200
2201
2201 else:
2202 else:
2202 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2203 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2203
2204
2204 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2205 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2205
2206
2206 if self.__dataReady:
2207 if self.__dataReady:
2207 dataOut.utctimeInit = self.__initime
2208 dataOut.utctimeInit = self.__initime
2208
2209
2209 self.__initime += dataOut.outputInterval #to erase time offset
2210 self.__initime += dataOut.outputInterval #to erase time offset
2210
2211
2211 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2212 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2212 dataOut.flagNoData = False
2213 dataOut.flagNoData = False
2213 self.__buffer = None
2214 self.__buffer = None
2214
2215
2215 elif technique == 'Meteors1':
2216 elif technique == 'Meteors1':
2216 dataOut.flagNoData = True
2217 dataOut.flagNoData = True
2217 self.__dataReady = False
2218 self.__dataReady = False
2218
2219
2219 if 'nMins' in kwargs:
2220 if 'nMins' in kwargs:
2220 nMins = kwargs['nMins']
2221 nMins = kwargs['nMins']
2221 else: nMins = 20
2222 else: nMins = 20
2222 if 'rx_location' in kwargs:
2223 if 'rx_location' in kwargs:
2223 rx_location = kwargs['rx_location']
2224 rx_location = kwargs['rx_location']
2224 else: rx_location = [(0,1),(1,1),(1,0)]
2225 else: rx_location = [(0,1),(1,1),(1,0)]
2225 if 'azimuth' in kwargs:
2226 if 'azimuth' in kwargs:
2226 azimuth = kwargs['azimuth']
2227 azimuth = kwargs['azimuth']
2227 else: azimuth = 51.06
2228 else: azimuth = 51.06
2228 if 'dfactor' in kwargs:
2229 if 'dfactor' in kwargs:
2229 dfactor = kwargs['dfactor']
2230 dfactor = kwargs['dfactor']
2230 if 'mode' in kwargs:
2231 if 'mode' in kwargs:
2231 mode = kwargs['mode']
2232 mode = kwargs['mode']
2232 if 'theta_x' in kwargs:
2233 if 'theta_x' in kwargs:
2233 theta_x = kwargs['theta_x']
2234 theta_x = kwargs['theta_x']
2234 if 'theta_y' in kwargs:
2235 if 'theta_y' in kwargs:
2235 theta_y = kwargs['theta_y']
2236 theta_y = kwargs['theta_y']
2236 else: mode = 'SA'
2237 else: mode = 'SA'
2237
2238
2238 #Borrar luego esto
2239 #Borrar luego esto
2239 if dataOut.groupList is None:
2240 if dataOut.groupList is None:
2240 dataOut.groupList = [(0,1),(0,2),(1,2)]
2241 dataOut.groupList = [(0,1),(0,2),(1,2)]
2241 groupList = dataOut.groupList
2242 groupList = dataOut.groupList
2242 C = 3e8
2243 C = 3e8
2243 freq = 50e6
2244 freq = 50e6
2244 lamb = C/freq
2245 lamb = C/freq
2245 k = 2*numpy.pi/lamb
2246 k = 2*numpy.pi/lamb
2246
2247
2247 timeList = dataOut.abscissaList
2248 timeList = dataOut.abscissaList
2248 heightList = dataOut.heightList
2249 heightList = dataOut.heightList
2249
2250
2250 if self.__isConfig == False:
2251 if self.__isConfig == False:
2251 dataOut.outputInterval = nMins*60
2252 dataOut.outputInterval = nMins*60
2252 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2253 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2253 #Get Initial LTC time
2254 #Get Initial LTC time
2254 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2255 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2255 minuteAux = initime.minute
2256 minuteAux = initime.minute
2256 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2257 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2257 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2258 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2258
2259
2259 self.__isConfig = True
2260 self.__isConfig = True
2260
2261
2261 if self.__buffer is None:
2262 if self.__buffer is None:
2262 self.__buffer = dataOut.data_param
2263 self.__buffer = dataOut.data_param
2263 self.__firstdata = copy.copy(dataOut)
2264 self.__firstdata = copy.copy(dataOut)
2264
2265
2265 else:
2266 else:
2266 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2267 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2267
2268
2268 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2269 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2269
2270
2270 if self.__dataReady:
2271 if self.__dataReady:
2271 dataOut.utctimeInit = self.__initime
2272 dataOut.utctimeInit = self.__initime
2272 self.__initime += dataOut.outputInterval #to erase time offset
2273 self.__initime += dataOut.outputInterval #to erase time offset
2273
2274
2274 metArray = self.__buffer
2275 metArray = self.__buffer
2275 if mode == 'SA':
2276 if mode == 'SA':
2276 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2277 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2277 elif mode == 'DBS':
2278 elif mode == 'DBS':
2278 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2279 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2279 dataOut.data_output = dataOut.data_output.T
2280 dataOut.data_output = dataOut.data_output.T
2280 dataOut.flagNoData = False
2281 dataOut.flagNoData = False
2281 self.__buffer = None
2282 self.__buffer = None
2282
2283
2283 return
2284 return
2284
2285
2285 class EWDriftsEstimation(Operation):
2286 class EWDriftsEstimation(Operation):
2286
2287
2287 def __init__(self):
2288 def __init__(self):
2288 Operation.__init__(self)
2289 Operation.__init__(self)
2289
2290
2290 def __correctValues(self, heiRang, phi, velRadial, SNR):
2291 def __correctValues(self, heiRang, phi, velRadial, SNR):
2291 listPhi = phi.tolist()
2292 listPhi = phi.tolist()
2292 maxid = listPhi.index(max(listPhi))
2293 maxid = listPhi.index(max(listPhi))
2293 minid = listPhi.index(min(listPhi))
2294 minid = listPhi.index(min(listPhi))
2294
2295
2295 rango = list(range(len(phi)))
2296 rango = list(range(len(phi)))
2296 # rango = numpy.delete(rango,maxid)
2297 # rango = numpy.delete(rango,maxid)
2297
2298
2298 heiRang1 = heiRang*math.cos(phi[maxid])
2299 heiRang1 = heiRang*math.cos(phi[maxid])
2299 heiRangAux = heiRang*math.cos(phi[minid])
2300 heiRangAux = heiRang*math.cos(phi[minid])
2300 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2301 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2301 heiRang1 = numpy.delete(heiRang1,indOut)
2302 heiRang1 = numpy.delete(heiRang1,indOut)
2302
2303
2303 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2304 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2304 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2305 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2305
2306
2306 for i in rango:
2307 for i in rango:
2307 x = heiRang*math.cos(phi[i])
2308 x = heiRang*math.cos(phi[i])
2308 y1 = velRadial[i,:]
2309 y1 = velRadial[i,:]
2309 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2310 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2310
2311
2311 x1 = heiRang1
2312 x1 = heiRang1
2312 y11 = f1(x1)
2313 y11 = f1(x1)
2313
2314
2314 y2 = SNR[i,:]
2315 y2 = SNR[i,:]
2315 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2316 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2316 y21 = f2(x1)
2317 y21 = f2(x1)
2317
2318
2318 velRadial1[i,:] = y11
2319 velRadial1[i,:] = y11
2319 SNR1[i,:] = y21
2320 SNR1[i,:] = y21
2320
2321
2321 return heiRang1, velRadial1, SNR1
2322 return heiRang1, velRadial1, SNR1
2322
2323
2323 def run(self, dataOut, zenith, zenithCorrection):
2324 def run(self, dataOut, zenith, zenithCorrection):
2324 heiRang = dataOut.heightList
2325 heiRang = dataOut.heightList
2325 velRadial = dataOut.data_param[:,3,:]
2326 velRadial = dataOut.data_param[:,3,:]
2326 SNR = dataOut.data_SNR
2327 SNR = dataOut.data_SNR
2327
2328
2328 zenith = numpy.array(zenith)
2329 zenith = numpy.array(zenith)
2329 zenith -= zenithCorrection
2330 zenith -= zenithCorrection
2330 zenith *= numpy.pi/180
2331 zenith *= numpy.pi/180
2331
2332
2332 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2333 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2333
2334
2334 alp = zenith[0]
2335 alp = zenith[0]
2335 bet = zenith[1]
2336 bet = zenith[1]
2336
2337
2337 w_w = velRadial1[0,:]
2338 w_w = velRadial1[0,:]
2338 w_e = velRadial1[1,:]
2339 w_e = velRadial1[1,:]
2339
2340
2340 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2341 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2341 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2342 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2342
2343
2343 winds = numpy.vstack((u,w))
2344 winds = numpy.vstack((u,w))
2344
2345
2345 dataOut.heightList = heiRang1
2346 dataOut.heightList = heiRang1
2346 dataOut.data_output = winds
2347 dataOut.data_output = winds
2347 dataOut.data_SNR = SNR1
2348 dataOut.data_SNR = SNR1
2348
2349
2349 dataOut.utctimeInit = dataOut.utctime
2350 dataOut.utctimeInit = dataOut.utctime
2350 dataOut.outputInterval = dataOut.timeInterval
2351 dataOut.outputInterval = dataOut.timeInterval
2351 return
2352 return
2352
2353
2353 #--------------- Non Specular Meteor ----------------
2354 #--------------- Non Specular Meteor ----------------
2354
2355
2355 class NonSpecularMeteorDetection(Operation):
2356 class NonSpecularMeteorDetection(Operation):
2356
2357
2357 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2358 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2358 data_acf = dataOut.data_pre[0]
2359 data_acf = dataOut.data_pre[0]
2359 data_ccf = dataOut.data_pre[1]
2360 data_ccf = dataOut.data_pre[1]
2360 pairsList = dataOut.groupList[1]
2361 pairsList = dataOut.groupList[1]
2361
2362
2362 lamb = dataOut.C/dataOut.frequency
2363 lamb = dataOut.C/dataOut.frequency
2363 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2364 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2364 paramInterval = dataOut.paramInterval
2365 paramInterval = dataOut.paramInterval
2365
2366
2366 nChannels = data_acf.shape[0]
2367 nChannels = data_acf.shape[0]
2367 nLags = data_acf.shape[1]
2368 nLags = data_acf.shape[1]
2368 nProfiles = data_acf.shape[2]
2369 nProfiles = data_acf.shape[2]
2369 nHeights = dataOut.nHeights
2370 nHeights = dataOut.nHeights
2370 nCohInt = dataOut.nCohInt
2371 nCohInt = dataOut.nCohInt
2371 sec = numpy.round(nProfiles/dataOut.paramInterval)
2372 sec = numpy.round(nProfiles/dataOut.paramInterval)
2372 heightList = dataOut.heightList
2373 heightList = dataOut.heightList
2373 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2374 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2374 utctime = dataOut.utctime
2375 utctime = dataOut.utctime
2375
2376
2376 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2377 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2377
2378
2378 #------------------------ SNR --------------------------------------
2379 #------------------------ SNR --------------------------------------
2379 power = data_acf[:,0,:,:].real
2380 power = data_acf[:,0,:,:].real
2380 noise = numpy.zeros(nChannels)
2381 noise = numpy.zeros(nChannels)
2381 SNR = numpy.zeros(power.shape)
2382 SNR = numpy.zeros(power.shape)
2382 for i in range(nChannels):
2383 for i in range(nChannels):
2383 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2384 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2384 SNR[i] = (power[i]-noise[i])/noise[i]
2385 SNR[i] = (power[i]-noise[i])/noise[i]
2385 SNRm = numpy.nanmean(SNR, axis = 0)
2386 SNRm = numpy.nanmean(SNR, axis = 0)
2386 SNRdB = 10*numpy.log10(SNR)
2387 SNRdB = 10*numpy.log10(SNR)
2387
2388
2388 if mode == 'SA':
2389 if mode == 'SA':
2389 dataOut.groupList = dataOut.groupList[1]
2390 dataOut.groupList = dataOut.groupList[1]
2390 nPairs = data_ccf.shape[0]
2391 nPairs = data_ccf.shape[0]
2391 #---------------------- Coherence and Phase --------------------------
2392 #---------------------- Coherence and Phase --------------------------
2392 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2393 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2393 # phase1 = numpy.copy(phase)
2394 # phase1 = numpy.copy(phase)
2394 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2395 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2395
2396
2396 for p in range(nPairs):
2397 for p in range(nPairs):
2397 ch0 = pairsList[p][0]
2398 ch0 = pairsList[p][0]
2398 ch1 = pairsList[p][1]
2399 ch1 = pairsList[p][1]
2399 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2400 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2400 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2401 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2401 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2402 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2402 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2403 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2403 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2404 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2404 coh = numpy.nanmax(coh1, axis = 0)
2405 coh = numpy.nanmax(coh1, axis = 0)
2405 # struc = numpy.ones((5,1))
2406 # struc = numpy.ones((5,1))
2406 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2407 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2407 #---------------------- Radial Velocity ----------------------------
2408 #---------------------- Radial Velocity ----------------------------
2408 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2409 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2409 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2410 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2410
2411
2411 if allData:
2412 if allData:
2412 boolMetFin = ~numpy.isnan(SNRm)
2413 boolMetFin = ~numpy.isnan(SNRm)
2413 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2414 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2414 else:
2415 else:
2415 #------------------------ Meteor mask ---------------------------------
2416 #------------------------ Meteor mask ---------------------------------
2416 # #SNR mask
2417 # #SNR mask
2417 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2418 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2418 #
2419 #
2419 # #Erase small objects
2420 # #Erase small objects
2420 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2421 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2421 #
2422 #
2422 # auxEEJ = numpy.sum(boolMet1,axis=0)
2423 # auxEEJ = numpy.sum(boolMet1,axis=0)
2423 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2424 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2424 # indEEJ = numpy.where(indOver)[0]
2425 # indEEJ = numpy.where(indOver)[0]
2425 # indNEEJ = numpy.where(~indOver)[0]
2426 # indNEEJ = numpy.where(~indOver)[0]
2426 #
2427 #
2427 # boolMetFin = boolMet1
2428 # boolMetFin = boolMet1
2428 #
2429 #
2429 # if indEEJ.size > 0:
2430 # if indEEJ.size > 0:
2430 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2431 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2431 #
2432 #
2432 # boolMet2 = coh > cohThresh
2433 # boolMet2 = coh > cohThresh
2433 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2434 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2434 #
2435 #
2435 # #Final Meteor mask
2436 # #Final Meteor mask
2436 # boolMetFin = boolMet1|boolMet2
2437 # boolMetFin = boolMet1|boolMet2
2437
2438
2438 #Coherence mask
2439 #Coherence mask
2439 boolMet1 = coh > 0.75
2440 boolMet1 = coh > 0.75
2440 struc = numpy.ones((30,1))
2441 struc = numpy.ones((30,1))
2441 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2442 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2442
2443
2443 #Derivative mask
2444 #Derivative mask
2444 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2445 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2445 boolMet2 = derPhase < 0.2
2446 boolMet2 = derPhase < 0.2
2446 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2447 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2447 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2448 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2448 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2449 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2449 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2450 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2450 # #Final mask
2451 # #Final mask
2451 # boolMetFin = boolMet2
2452 # boolMetFin = boolMet2
2452 boolMetFin = boolMet1&boolMet2
2453 boolMetFin = boolMet1&boolMet2
2453 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2454 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2454 #Creating data_param
2455 #Creating data_param
2455 coordMet = numpy.where(boolMetFin)
2456 coordMet = numpy.where(boolMetFin)
2456
2457
2457 tmet = coordMet[0]
2458 tmet = coordMet[0]
2458 hmet = coordMet[1]
2459 hmet = coordMet[1]
2459
2460
2460 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2461 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2461 data_param[:,0] = utctime
2462 data_param[:,0] = utctime
2462 data_param[:,1] = tmet
2463 data_param[:,1] = tmet
2463 data_param[:,2] = hmet
2464 data_param[:,2] = hmet
2464 data_param[:,3] = SNRm[tmet,hmet]
2465 data_param[:,3] = SNRm[tmet,hmet]
2465 data_param[:,4] = velRad[tmet,hmet]
2466 data_param[:,4] = velRad[tmet,hmet]
2466 data_param[:,5] = coh[tmet,hmet]
2467 data_param[:,5] = coh[tmet,hmet]
2467 data_param[:,6:] = phase[:,tmet,hmet].T
2468 data_param[:,6:] = phase[:,tmet,hmet].T
2468
2469
2469 elif mode == 'DBS':
2470 elif mode == 'DBS':
2470 dataOut.groupList = numpy.arange(nChannels)
2471 dataOut.groupList = numpy.arange(nChannels)
2471
2472
2472 #Radial Velocities
2473 #Radial Velocities
2473 phase = numpy.angle(data_acf[:,1,:,:])
2474 phase = numpy.angle(data_acf[:,1,:,:])
2474 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2475 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2475 velRad = phase*lamb/(4*numpy.pi*tSamp)
2476 velRad = phase*lamb/(4*numpy.pi*tSamp)
2476
2477
2477 #Spectral width
2478 #Spectral width
2478 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2479 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2479 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2480 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2480 acf1 = data_acf[:,1,:,:]
2481 acf1 = data_acf[:,1,:,:]
2481 acf2 = data_acf[:,2,:,:]
2482 acf2 = data_acf[:,2,:,:]
2482
2483
2483 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2484 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2484 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2485 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2485 if allData:
2486 if allData:
2486 boolMetFin = ~numpy.isnan(SNRdB)
2487 boolMetFin = ~numpy.isnan(SNRdB)
2487 else:
2488 else:
2488 #SNR
2489 #SNR
2489 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2490 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2490 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2491 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2491
2492
2492 #Radial velocity
2493 #Radial velocity
2493 boolMet2 = numpy.abs(velRad) < 20
2494 boolMet2 = numpy.abs(velRad) < 20
2494 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2495 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2495
2496
2496 #Spectral Width
2497 #Spectral Width
2497 boolMet3 = spcWidth < 30
2498 boolMet3 = spcWidth < 30
2498 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2499 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2499 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2500 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2500 boolMetFin = boolMet1&boolMet2&boolMet3
2501 boolMetFin = boolMet1&boolMet2&boolMet3
2501
2502
2502 #Creating data_param
2503 #Creating data_param
2503 coordMet = numpy.where(boolMetFin)
2504 coordMet = numpy.where(boolMetFin)
2504
2505
2505 cmet = coordMet[0]
2506 cmet = coordMet[0]
2506 tmet = coordMet[1]
2507 tmet = coordMet[1]
2507 hmet = coordMet[2]
2508 hmet = coordMet[2]
2508
2509
2509 data_param = numpy.zeros((tmet.size, 7))
2510 data_param = numpy.zeros((tmet.size, 7))
2510 data_param[:,0] = utctime
2511 data_param[:,0] = utctime
2511 data_param[:,1] = cmet
2512 data_param[:,1] = cmet
2512 data_param[:,2] = tmet
2513 data_param[:,2] = tmet
2513 data_param[:,3] = hmet
2514 data_param[:,3] = hmet
2514 data_param[:,4] = SNR[cmet,tmet,hmet].T
2515 data_param[:,4] = SNR[cmet,tmet,hmet].T
2515 data_param[:,5] = velRad[cmet,tmet,hmet].T
2516 data_param[:,5] = velRad[cmet,tmet,hmet].T
2516 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2517 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2517
2518
2518 # self.dataOut.data_param = data_int
2519 # self.dataOut.data_param = data_int
2519 if len(data_param) == 0:
2520 if len(data_param) == 0:
2520 dataOut.flagNoData = True
2521 dataOut.flagNoData = True
2521 else:
2522 else:
2522 dataOut.data_param = data_param
2523 dataOut.data_param = data_param
2523
2524
2524 def __erase_small(self, binArray, threshX, threshY):
2525 def __erase_small(self, binArray, threshX, threshY):
2525 labarray, numfeat = ndimage.measurements.label(binArray)
2526 labarray, numfeat = ndimage.measurements.label(binArray)
2526 binArray1 = numpy.copy(binArray)
2527 binArray1 = numpy.copy(binArray)
2527
2528
2528 for i in range(1,numfeat + 1):
2529 for i in range(1,numfeat + 1):
2529 auxBin = (labarray==i)
2530 auxBin = (labarray==i)
2530 auxSize = auxBin.sum()
2531 auxSize = auxBin.sum()
2531
2532
2532 x,y = numpy.where(auxBin)
2533 x,y = numpy.where(auxBin)
2533 widthX = x.max() - x.min()
2534 widthX = x.max() - x.min()
2534 widthY = y.max() - y.min()
2535 widthY = y.max() - y.min()
2535
2536
2536 #width X: 3 seg -> 12.5*3
2537 #width X: 3 seg -> 12.5*3
2537 #width Y:
2538 #width Y:
2538
2539
2539 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2540 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2540 binArray1[auxBin] = False
2541 binArray1[auxBin] = False
2541
2542
2542 return binArray1
2543 return binArray1
2543
2544
2544 #--------------- Specular Meteor ----------------
2545 #--------------- Specular Meteor ----------------
2545
2546
2546 class SMDetection(Operation):
2547 class SMDetection(Operation):
2547 '''
2548 '''
2548 Function DetectMeteors()
2549 Function DetectMeteors()
2549 Project developed with paper:
2550 Project developed with paper:
2550 HOLDSWORTH ET AL. 2004
2551 HOLDSWORTH ET AL. 2004
2551
2552
2552 Input:
2553 Input:
2553 self.dataOut.data_pre
2554 self.dataOut.data_pre
2554
2555
2555 centerReceiverIndex: From the channels, which is the center receiver
2556 centerReceiverIndex: From the channels, which is the center receiver
2556
2557
2557 hei_ref: Height reference for the Beacon signal extraction
2558 hei_ref: Height reference for the Beacon signal extraction
2558 tauindex:
2559 tauindex:
2559 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2560 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2560
2561
2561 cohDetection: Whether to user Coherent detection or not
2562 cohDetection: Whether to user Coherent detection or not
2562 cohDet_timeStep: Coherent Detection calculation time step
2563 cohDet_timeStep: Coherent Detection calculation time step
2563 cohDet_thresh: Coherent Detection phase threshold to correct phases
2564 cohDet_thresh: Coherent Detection phase threshold to correct phases
2564
2565
2565 noise_timeStep: Noise calculation time step
2566 noise_timeStep: Noise calculation time step
2566 noise_multiple: Noise multiple to define signal threshold
2567 noise_multiple: Noise multiple to define signal threshold
2567
2568
2568 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2569 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2569 multDet_rangeLimit: Multiple Detection Removal range limit in km
2570 multDet_rangeLimit: Multiple Detection Removal range limit in km
2570
2571
2571 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2572 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2572 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2573 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2573
2574
2574 hmin: Minimum Height of the meteor to use it in the further wind estimations
2575 hmin: Minimum Height of the meteor to use it in the further wind estimations
2575 hmax: Maximum Height of the meteor to use it in the further wind estimations
2576 hmax: Maximum Height of the meteor to use it in the further wind estimations
2576 azimuth: Azimuth angle correction
2577 azimuth: Azimuth angle correction
2577
2578
2578 Affected:
2579 Affected:
2579 self.dataOut.data_param
2580 self.dataOut.data_param
2580
2581
2581 Rejection Criteria (Errors):
2582 Rejection Criteria (Errors):
2582 0: No error; analysis OK
2583 0: No error; analysis OK
2583 1: SNR < SNR threshold
2584 1: SNR < SNR threshold
2584 2: angle of arrival (AOA) ambiguously determined
2585 2: angle of arrival (AOA) ambiguously determined
2585 3: AOA estimate not feasible
2586 3: AOA estimate not feasible
2586 4: Large difference in AOAs obtained from different antenna baselines
2587 4: Large difference in AOAs obtained from different antenna baselines
2587 5: echo at start or end of time series
2588 5: echo at start or end of time series
2588 6: echo less than 5 examples long; too short for analysis
2589 6: echo less than 5 examples long; too short for analysis
2589 7: echo rise exceeds 0.3s
2590 7: echo rise exceeds 0.3s
2590 8: echo decay time less than twice rise time
2591 8: echo decay time less than twice rise time
2591 9: large power level before echo
2592 9: large power level before echo
2592 10: large power level after echo
2593 10: large power level after echo
2593 11: poor fit to amplitude for estimation of decay time
2594 11: poor fit to amplitude for estimation of decay time
2594 12: poor fit to CCF phase variation for estimation of radial drift velocity
2595 12: poor fit to CCF phase variation for estimation of radial drift velocity
2595 13: height unresolvable echo: not valid height within 70 to 110 km
2596 13: height unresolvable echo: not valid height within 70 to 110 km
2596 14: height ambiguous echo: more then one possible height within 70 to 110 km
2597 14: height ambiguous echo: more then one possible height within 70 to 110 km
2597 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2598 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2598 16: oscilatory echo, indicating event most likely not an underdense echo
2599 16: oscilatory echo, indicating event most likely not an underdense echo
2599
2600
2600 17: phase difference in meteor Reestimation
2601 17: phase difference in meteor Reestimation
2601
2602
2602 Data Storage:
2603 Data Storage:
2603 Meteors for Wind Estimation (8):
2604 Meteors for Wind Estimation (8):
2604 Utc Time | Range Height
2605 Utc Time | Range Height
2605 Azimuth Zenith errorCosDir
2606 Azimuth Zenith errorCosDir
2606 VelRad errorVelRad
2607 VelRad errorVelRad
2607 Phase0 Phase1 Phase2 Phase3
2608 Phase0 Phase1 Phase2 Phase3
2608 TypeError
2609 TypeError
2609
2610
2610 '''
2611 '''
2611
2612
2612 def run(self, dataOut, hei_ref = None, tauindex = 0,
2613 def run(self, dataOut, hei_ref = None, tauindex = 0,
2613 phaseOffsets = None,
2614 phaseOffsets = None,
2614 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2615 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2615 noise_timeStep = 4, noise_multiple = 4,
2616 noise_timeStep = 4, noise_multiple = 4,
2616 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2617 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2617 phaseThresh = 20, SNRThresh = 5,
2618 phaseThresh = 20, SNRThresh = 5,
2618 hmin = 50, hmax=150, azimuth = 0,
2619 hmin = 50, hmax=150, azimuth = 0,
2619 channelPositions = None) :
2620 channelPositions = None) :
2620
2621
2621
2622
2622 #Getting Pairslist
2623 #Getting Pairslist
2623 if channelPositions is None:
2624 if channelPositions is None:
2624 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2625 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2625 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2626 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2626 meteorOps = SMOperations()
2627 meteorOps = SMOperations()
2627 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2628 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2628 heiRang = dataOut.getHeiRange()
2629 heiRang = dataOut.getHeiRange()
2629 #Get Beacon signal - No Beacon signal anymore
2630 #Get Beacon signal - No Beacon signal anymore
2630 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2631 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2631 #
2632 #
2632 # if hei_ref != None:
2633 # if hei_ref != None:
2633 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2634 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2634 #
2635 #
2635
2636
2636
2637
2637 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2638 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2638 # see if the user put in pre defined phase shifts
2639 # see if the user put in pre defined phase shifts
2639 voltsPShift = dataOut.data_pre.copy()
2640 voltsPShift = dataOut.data_pre.copy()
2640
2641
2641 # if predefinedPhaseShifts != None:
2642 # if predefinedPhaseShifts != None:
2642 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2643 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2643 #
2644 #
2644 # # elif beaconPhaseShifts:
2645 # # elif beaconPhaseShifts:
2645 # # #get hardware phase shifts using beacon signal
2646 # # #get hardware phase shifts using beacon signal
2646 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2647 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2647 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2648 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2648 #
2649 #
2649 # else:
2650 # else:
2650 # hardwarePhaseShifts = numpy.zeros(5)
2651 # hardwarePhaseShifts = numpy.zeros(5)
2651 #
2652 #
2652 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2653 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2653 # for i in range(self.dataOut.data_pre.shape[0]):
2654 # for i in range(self.dataOut.data_pre.shape[0]):
2654 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2655 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2655
2656
2656 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2657 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2657
2658
2658 #Remove DC
2659 #Remove DC
2659 voltsDC = numpy.mean(voltsPShift,1)
2660 voltsDC = numpy.mean(voltsPShift,1)
2660 voltsDC = numpy.mean(voltsDC,1)
2661 voltsDC = numpy.mean(voltsDC,1)
2661 for i in range(voltsDC.shape[0]):
2662 for i in range(voltsDC.shape[0]):
2662 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2663 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2663
2664
2664 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2665 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2665 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2666 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2666
2667
2667 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2668 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2668 #Coherent Detection
2669 #Coherent Detection
2669 if cohDetection:
2670 if cohDetection:
2670 #use coherent detection to get the net power
2671 #use coherent detection to get the net power
2671 cohDet_thresh = cohDet_thresh*numpy.pi/180
2672 cohDet_thresh = cohDet_thresh*numpy.pi/180
2672 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2673 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2673
2674
2674 #Non-coherent detection!
2675 #Non-coherent detection!
2675 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2676 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2676 #********** END OF COH/NON-COH POWER CALCULATION**********************
2677 #********** END OF COH/NON-COH POWER CALCULATION**********************
2677
2678
2678 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2679 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2679 #Get noise
2680 #Get noise
2680 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2681 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2681 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2682 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2682 #Get signal threshold
2683 #Get signal threshold
2683 signalThresh = noise_multiple*noise
2684 signalThresh = noise_multiple*noise
2684 #Meteor echoes detection
2685 #Meteor echoes detection
2685 listMeteors = self.__findMeteors(powerNet, signalThresh)
2686 listMeteors = self.__findMeteors(powerNet, signalThresh)
2686 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2687 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2687
2688
2688 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2689 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2689 #Parameters
2690 #Parameters
2690 heiRange = dataOut.getHeiRange()
2691 heiRange = dataOut.getHeiRange()
2691 rangeInterval = heiRange[1] - heiRange[0]
2692 rangeInterval = heiRange[1] - heiRange[0]
2692 rangeLimit = multDet_rangeLimit/rangeInterval
2693 rangeLimit = multDet_rangeLimit/rangeInterval
2693 timeLimit = multDet_timeLimit/dataOut.timeInterval
2694 timeLimit = multDet_timeLimit/dataOut.timeInterval
2694 #Multiple detection removals
2695 #Multiple detection removals
2695 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2696 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2696 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2697 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2697
2698
2698 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2699 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2699 #Parameters
2700 #Parameters
2700 phaseThresh = phaseThresh*numpy.pi/180
2701 phaseThresh = phaseThresh*numpy.pi/180
2701 thresh = [phaseThresh, noise_multiple, SNRThresh]
2702 thresh = [phaseThresh, noise_multiple, SNRThresh]
2702 #Meteor reestimation (Errors N 1, 6, 12, 17)
2703 #Meteor reestimation (Errors N 1, 6, 12, 17)
2703 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2704 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2704 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2705 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2705 #Estimation of decay times (Errors N 7, 8, 11)
2706 #Estimation of decay times (Errors N 7, 8, 11)
2706 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2707 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2707 #******************* END OF METEOR REESTIMATION *******************
2708 #******************* END OF METEOR REESTIMATION *******************
2708
2709
2709 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2710 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2710 #Calculating Radial Velocity (Error N 15)
2711 #Calculating Radial Velocity (Error N 15)
2711 radialStdThresh = 10
2712 radialStdThresh = 10
2712 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2713 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2713
2714
2714 if len(listMeteors4) > 0:
2715 if len(listMeteors4) > 0:
2715 #Setting New Array
2716 #Setting New Array
2716 date = dataOut.utctime
2717 date = dataOut.utctime
2717 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2718 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2718
2719
2719 #Correcting phase offset
2720 #Correcting phase offset
2720 if phaseOffsets != None:
2721 if phaseOffsets != None:
2721 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2722 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2722 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2723 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2723
2724
2724 #Second Pairslist
2725 #Second Pairslist
2725 pairsList = []
2726 pairsList = []
2726 pairx = (0,1)
2727 pairx = (0,1)
2727 pairy = (2,3)
2728 pairy = (2,3)
2728 pairsList.append(pairx)
2729 pairsList.append(pairx)
2729 pairsList.append(pairy)
2730 pairsList.append(pairy)
2730
2731
2731 jph = numpy.array([0,0,0,0])
2732 jph = numpy.array([0,0,0,0])
2732 h = (hmin,hmax)
2733 h = (hmin,hmax)
2733 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2734 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2734
2735
2735 # #Calculate AOA (Error N 3, 4)
2736 # #Calculate AOA (Error N 3, 4)
2736 # #JONES ET AL. 1998
2737 # #JONES ET AL. 1998
2737 # error = arrayParameters[:,-1]
2738 # error = arrayParameters[:,-1]
2738 # AOAthresh = numpy.pi/8
2739 # AOAthresh = numpy.pi/8
2739 # phases = -arrayParameters[:,9:13]
2740 # phases = -arrayParameters[:,9:13]
2740 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2741 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2741 #
2742 #
2742 # #Calculate Heights (Error N 13 and 14)
2743 # #Calculate Heights (Error N 13 and 14)
2743 # error = arrayParameters[:,-1]
2744 # error = arrayParameters[:,-1]
2744 # Ranges = arrayParameters[:,2]
2745 # Ranges = arrayParameters[:,2]
2745 # zenith = arrayParameters[:,5]
2746 # zenith = arrayParameters[:,5]
2746 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2747 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2747 # error = arrayParameters[:,-1]
2748 # error = arrayParameters[:,-1]
2748 #********************* END OF PARAMETERS CALCULATION **************************
2749 #********************* END OF PARAMETERS CALCULATION **************************
2749
2750
2750 #***************************+ PASS DATA TO NEXT STEP **********************
2751 #***************************+ PASS DATA TO NEXT STEP **********************
2751 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2752 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2752 dataOut.data_param = arrayParameters
2753 dataOut.data_param = arrayParameters
2753
2754
2754 if arrayParameters is None:
2755 if arrayParameters is None:
2755 dataOut.flagNoData = True
2756 dataOut.flagNoData = True
2756 else:
2757 else:
2757 dataOut.flagNoData = True
2758 dataOut.flagNoData = True
2758
2759
2759 return
2760 return
2760
2761
2761 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2762 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2762
2763
2763 minIndex = min(newheis[0])
2764 minIndex = min(newheis[0])
2764 maxIndex = max(newheis[0])
2765 maxIndex = max(newheis[0])
2765
2766
2766 voltage = voltage0[:,:,minIndex:maxIndex+1]
2767 voltage = voltage0[:,:,minIndex:maxIndex+1]
2767 nLength = voltage.shape[1]/n
2768 nLength = voltage.shape[1]/n
2768 nMin = 0
2769 nMin = 0
2769 nMax = 0
2770 nMax = 0
2770 phaseOffset = numpy.zeros((len(pairslist),n))
2771 phaseOffset = numpy.zeros((len(pairslist),n))
2771
2772
2772 for i in range(n):
2773 for i in range(n):
2773 nMax += nLength
2774 nMax += nLength
2774 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2775 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2775 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2776 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2776 phaseOffset[:,i] = phaseCCF.transpose()
2777 phaseOffset[:,i] = phaseCCF.transpose()
2777 nMin = nMax
2778 nMin = nMax
2778 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2779 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2779
2780
2780 #Remove Outliers
2781 #Remove Outliers
2781 factor = 2
2782 factor = 2
2782 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2783 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2783 dw = numpy.std(wt,axis = 1)
2784 dw = numpy.std(wt,axis = 1)
2784 dw = dw.reshape((dw.size,1))
2785 dw = dw.reshape((dw.size,1))
2785 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2786 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2786 phaseOffset[ind] = numpy.nan
2787 phaseOffset[ind] = numpy.nan
2787 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2788 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2788
2789
2789 return phaseOffset
2790 return phaseOffset
2790
2791
2791 def __shiftPhase(self, data, phaseShift):
2792 def __shiftPhase(self, data, phaseShift):
2792 #this will shift the phase of a complex number
2793 #this will shift the phase of a complex number
2793 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2794 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2794 return dataShifted
2795 return dataShifted
2795
2796
2796 def __estimatePhaseDifference(self, array, pairslist):
2797 def __estimatePhaseDifference(self, array, pairslist):
2797 nChannel = array.shape[0]
2798 nChannel = array.shape[0]
2798 nHeights = array.shape[2]
2799 nHeights = array.shape[2]
2799 numPairs = len(pairslist)
2800 numPairs = len(pairslist)
2800 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2801 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2801 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2802 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2802
2803
2803 #Correct phases
2804 #Correct phases
2804 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2805 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2805 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2806 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2806
2807
2807 if indDer[0].shape[0] > 0:
2808 if indDer[0].shape[0] > 0:
2808 for i in range(indDer[0].shape[0]):
2809 for i in range(indDer[0].shape[0]):
2809 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2810 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2810 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2811 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2811
2812
2812 # for j in range(numSides):
2813 # for j in range(numSides):
2813 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2814 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2814 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2815 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2815 #
2816 #
2816 #Linear
2817 #Linear
2817 phaseInt = numpy.zeros((numPairs,1))
2818 phaseInt = numpy.zeros((numPairs,1))
2818 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2819 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2819 for j in range(numPairs):
2820 for j in range(numPairs):
2820 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2821 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2821 phaseInt[j] = fit[1]
2822 phaseInt[j] = fit[1]
2822 #Phase Differences
2823 #Phase Differences
2823 phaseDiff = phaseInt - phaseCCF[:,2,:]
2824 phaseDiff = phaseInt - phaseCCF[:,2,:]
2824 phaseArrival = phaseInt.reshape(phaseInt.size)
2825 phaseArrival = phaseInt.reshape(phaseInt.size)
2825
2826
2826 #Dealias
2827 #Dealias
2827 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2828 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2828 # indAlias = numpy.where(phaseArrival > numpy.pi)
2829 # indAlias = numpy.where(phaseArrival > numpy.pi)
2829 # phaseArrival[indAlias] -= 2*numpy.pi
2830 # phaseArrival[indAlias] -= 2*numpy.pi
2830 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2831 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2831 # phaseArrival[indAlias] += 2*numpy.pi
2832 # phaseArrival[indAlias] += 2*numpy.pi
2832
2833
2833 return phaseDiff, phaseArrival
2834 return phaseDiff, phaseArrival
2834
2835
2835 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2836 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2836 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2837 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2837 #find the phase shifts of each channel over 1 second intervals
2838 #find the phase shifts of each channel over 1 second intervals
2838 #only look at ranges below the beacon signal
2839 #only look at ranges below the beacon signal
2839 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2840 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2840 numBlocks = int(volts.shape[1]/numProfPerBlock)
2841 numBlocks = int(volts.shape[1]/numProfPerBlock)
2841 numHeights = volts.shape[2]
2842 numHeights = volts.shape[2]
2842 nChannel = volts.shape[0]
2843 nChannel = volts.shape[0]
2843 voltsCohDet = volts.copy()
2844 voltsCohDet = volts.copy()
2844
2845
2845 pairsarray = numpy.array(pairslist)
2846 pairsarray = numpy.array(pairslist)
2846 indSides = pairsarray[:,1]
2847 indSides = pairsarray[:,1]
2847 # indSides = numpy.array(range(nChannel))
2848 # indSides = numpy.array(range(nChannel))
2848 # indSides = numpy.delete(indSides, indCenter)
2849 # indSides = numpy.delete(indSides, indCenter)
2849 #
2850 #
2850 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2851 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2851 listBlocks = numpy.array_split(volts, numBlocks, 1)
2852 listBlocks = numpy.array_split(volts, numBlocks, 1)
2852
2853
2853 startInd = 0
2854 startInd = 0
2854 endInd = 0
2855 endInd = 0
2855
2856
2856 for i in range(numBlocks):
2857 for i in range(numBlocks):
2857 startInd = endInd
2858 startInd = endInd
2858 endInd = endInd + listBlocks[i].shape[1]
2859 endInd = endInd + listBlocks[i].shape[1]
2859
2860
2860 arrayBlock = listBlocks[i]
2861 arrayBlock = listBlocks[i]
2861 # arrayBlockCenter = listCenter[i]
2862 # arrayBlockCenter = listCenter[i]
2862
2863
2863 #Estimate the Phase Difference
2864 #Estimate the Phase Difference
2864 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2865 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2865 #Phase Difference RMS
2866 #Phase Difference RMS
2866 arrayPhaseRMS = numpy.abs(phaseDiff)
2867 arrayPhaseRMS = numpy.abs(phaseDiff)
2867 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2868 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2868 indPhase = numpy.where(phaseRMSaux==4)
2869 indPhase = numpy.where(phaseRMSaux==4)
2869 #Shifting
2870 #Shifting
2870 if indPhase[0].shape[0] > 0:
2871 if indPhase[0].shape[0] > 0:
2871 for j in range(indSides.size):
2872 for j in range(indSides.size):
2872 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2873 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2873 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2874 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2874
2875
2875 return voltsCohDet
2876 return voltsCohDet
2876
2877
2877 def __calculateCCF(self, volts, pairslist ,laglist):
2878 def __calculateCCF(self, volts, pairslist ,laglist):
2878
2879
2879 nHeights = volts.shape[2]
2880 nHeights = volts.shape[2]
2880 nPoints = volts.shape[1]
2881 nPoints = volts.shape[1]
2881 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2882 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2882
2883
2883 for i in range(len(pairslist)):
2884 for i in range(len(pairslist)):
2884 volts1 = volts[pairslist[i][0]]
2885 volts1 = volts[pairslist[i][0]]
2885 volts2 = volts[pairslist[i][1]]
2886 volts2 = volts[pairslist[i][1]]
2886
2887
2887 for t in range(len(laglist)):
2888 for t in range(len(laglist)):
2888 idxT = laglist[t]
2889 idxT = laglist[t]
2889 if idxT >= 0:
2890 if idxT >= 0:
2890 vStacked = numpy.vstack((volts2[idxT:,:],
2891 vStacked = numpy.vstack((volts2[idxT:,:],
2891 numpy.zeros((idxT, nHeights),dtype='complex')))
2892 numpy.zeros((idxT, nHeights),dtype='complex')))
2892 else:
2893 else:
2893 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2894 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2894 volts2[:(nPoints + idxT),:]))
2895 volts2[:(nPoints + idxT),:]))
2895 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2896 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2896
2897
2897 vStacked = None
2898 vStacked = None
2898 return voltsCCF
2899 return voltsCCF
2899
2900
2900 def __getNoise(self, power, timeSegment, timeInterval):
2901 def __getNoise(self, power, timeSegment, timeInterval):
2901 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2902 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2902 numBlocks = int(power.shape[0]/numProfPerBlock)
2903 numBlocks = int(power.shape[0]/numProfPerBlock)
2903 numHeights = power.shape[1]
2904 numHeights = power.shape[1]
2904
2905
2905 listPower = numpy.array_split(power, numBlocks, 0)
2906 listPower = numpy.array_split(power, numBlocks, 0)
2906 noise = numpy.zeros((power.shape[0], power.shape[1]))
2907 noise = numpy.zeros((power.shape[0], power.shape[1]))
2907 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2908 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2908
2909
2909 startInd = 0
2910 startInd = 0
2910 endInd = 0
2911 endInd = 0
2911
2912
2912 for i in range(numBlocks): #split por canal
2913 for i in range(numBlocks): #split por canal
2913 startInd = endInd
2914 startInd = endInd
2914 endInd = endInd + listPower[i].shape[0]
2915 endInd = endInd + listPower[i].shape[0]
2915
2916
2916 arrayBlock = listPower[i]
2917 arrayBlock = listPower[i]
2917 noiseAux = numpy.mean(arrayBlock, 0)
2918 noiseAux = numpy.mean(arrayBlock, 0)
2918 # noiseAux = numpy.median(noiseAux)
2919 # noiseAux = numpy.median(noiseAux)
2919 # noiseAux = numpy.mean(arrayBlock)
2920 # noiseAux = numpy.mean(arrayBlock)
2920 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2921 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2921
2922
2922 noiseAux1 = numpy.mean(arrayBlock)
2923 noiseAux1 = numpy.mean(arrayBlock)
2923 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2924 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2924
2925
2925 return noise, noise1
2926 return noise, noise1
2926
2927
2927 def __findMeteors(self, power, thresh):
2928 def __findMeteors(self, power, thresh):
2928 nProf = power.shape[0]
2929 nProf = power.shape[0]
2929 nHeights = power.shape[1]
2930 nHeights = power.shape[1]
2930 listMeteors = []
2931 listMeteors = []
2931
2932
2932 for i in range(nHeights):
2933 for i in range(nHeights):
2933 powerAux = power[:,i]
2934 powerAux = power[:,i]
2934 threshAux = thresh[:,i]
2935 threshAux = thresh[:,i]
2935
2936
2936 indUPthresh = numpy.where(powerAux > threshAux)[0]
2937 indUPthresh = numpy.where(powerAux > threshAux)[0]
2937 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2938 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2938
2939
2939 j = 0
2940 j = 0
2940
2941
2941 while (j < indUPthresh.size - 2):
2942 while (j < indUPthresh.size - 2):
2942 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
2943 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
2943 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
2944 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
2944 indDNthresh = indDNthresh[indDNAux]
2945 indDNthresh = indDNthresh[indDNAux]
2945
2946
2946 if (indDNthresh.size > 0):
2947 if (indDNthresh.size > 0):
2947 indEnd = indDNthresh[0] - 1
2948 indEnd = indDNthresh[0] - 1
2948 indInit = indUPthresh[j]
2949 indInit = indUPthresh[j]
2949
2950
2950 meteor = powerAux[indInit:indEnd + 1]
2951 meteor = powerAux[indInit:indEnd + 1]
2951 indPeak = meteor.argmax() + indInit
2952 indPeak = meteor.argmax() + indInit
2952 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
2953 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
2953
2954
2954 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
2955 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
2955 j = numpy.where(indUPthresh == indEnd)[0] + 1
2956 j = numpy.where(indUPthresh == indEnd)[0] + 1
2956 else: j+=1
2957 else: j+=1
2957 else: j+=1
2958 else: j+=1
2958
2959
2959 return listMeteors
2960 return listMeteors
2960
2961
2961 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
2962 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
2962
2963
2963 arrayMeteors = numpy.asarray(listMeteors)
2964 arrayMeteors = numpy.asarray(listMeteors)
2964 listMeteors1 = []
2965 listMeteors1 = []
2965
2966
2966 while arrayMeteors.shape[0] > 0:
2967 while arrayMeteors.shape[0] > 0:
2967 FLAs = arrayMeteors[:,4]
2968 FLAs = arrayMeteors[:,4]
2968 maxFLA = FLAs.argmax()
2969 maxFLA = FLAs.argmax()
2969 listMeteors1.append(arrayMeteors[maxFLA,:])
2970 listMeteors1.append(arrayMeteors[maxFLA,:])
2970
2971
2971 MeteorInitTime = arrayMeteors[maxFLA,1]
2972 MeteorInitTime = arrayMeteors[maxFLA,1]
2972 MeteorEndTime = arrayMeteors[maxFLA,3]
2973 MeteorEndTime = arrayMeteors[maxFLA,3]
2973 MeteorHeight = arrayMeteors[maxFLA,0]
2974 MeteorHeight = arrayMeteors[maxFLA,0]
2974
2975
2975 #Check neighborhood
2976 #Check neighborhood
2976 maxHeightIndex = MeteorHeight + rangeLimit
2977 maxHeightIndex = MeteorHeight + rangeLimit
2977 minHeightIndex = MeteorHeight - rangeLimit
2978 minHeightIndex = MeteorHeight - rangeLimit
2978 minTimeIndex = MeteorInitTime - timeLimit
2979 minTimeIndex = MeteorInitTime - timeLimit
2979 maxTimeIndex = MeteorEndTime + timeLimit
2980 maxTimeIndex = MeteorEndTime + timeLimit
2980
2981
2981 #Check Heights
2982 #Check Heights
2982 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
2983 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
2983 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
2984 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
2984 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
2985 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
2985
2986
2986 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
2987 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
2987
2988
2988 return listMeteors1
2989 return listMeteors1
2989
2990
2990 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
2991 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
2991 numHeights = volts.shape[2]
2992 numHeights = volts.shape[2]
2992 nChannel = volts.shape[0]
2993 nChannel = volts.shape[0]
2993
2994
2994 thresholdPhase = thresh[0]
2995 thresholdPhase = thresh[0]
2995 thresholdNoise = thresh[1]
2996 thresholdNoise = thresh[1]
2996 thresholdDB = float(thresh[2])
2997 thresholdDB = float(thresh[2])
2997
2998
2998 thresholdDB1 = 10**(thresholdDB/10)
2999 thresholdDB1 = 10**(thresholdDB/10)
2999 pairsarray = numpy.array(pairslist)
3000 pairsarray = numpy.array(pairslist)
3000 indSides = pairsarray[:,1]
3001 indSides = pairsarray[:,1]
3001
3002
3002 pairslist1 = list(pairslist)
3003 pairslist1 = list(pairslist)
3003 pairslist1.append((0,1))
3004 pairslist1.append((0,1))
3004 pairslist1.append((3,4))
3005 pairslist1.append((3,4))
3005
3006
3006 listMeteors1 = []
3007 listMeteors1 = []
3007 listPowerSeries = []
3008 listPowerSeries = []
3008 listVoltageSeries = []
3009 listVoltageSeries = []
3009 #volts has the war data
3010 #volts has the war data
3010
3011
3011 if frequency == 30e6:
3012 if frequency == 30e6:
3012 timeLag = 45*10**-3
3013 timeLag = 45*10**-3
3013 else:
3014 else:
3014 timeLag = 15*10**-3
3015 timeLag = 15*10**-3
3015 lag = numpy.ceil(timeLag/timeInterval)
3016 lag = numpy.ceil(timeLag/timeInterval)
3016
3017
3017 for i in range(len(listMeteors)):
3018 for i in range(len(listMeteors)):
3018
3019
3019 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3020 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3020 meteorAux = numpy.zeros(16)
3021 meteorAux = numpy.zeros(16)
3021
3022
3022 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3023 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3023 mHeight = listMeteors[i][0]
3024 mHeight = listMeteors[i][0]
3024 mStart = listMeteors[i][1]
3025 mStart = listMeteors[i][1]
3025 mPeak = listMeteors[i][2]
3026 mPeak = listMeteors[i][2]
3026 mEnd = listMeteors[i][3]
3027 mEnd = listMeteors[i][3]
3027
3028
3028 #get the volt data between the start and end times of the meteor
3029 #get the volt data between the start and end times of the meteor
3029 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3030 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3030 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3031 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3031
3032
3032 #3.6. Phase Difference estimation
3033 #3.6. Phase Difference estimation
3033 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3034 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3034
3035
3035 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3036 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3036 #meteorVolts0.- all Channels, all Profiles
3037 #meteorVolts0.- all Channels, all Profiles
3037 meteorVolts0 = volts[:,:,mHeight]
3038 meteorVolts0 = volts[:,:,mHeight]
3038 meteorThresh = noise[:,mHeight]*thresholdNoise
3039 meteorThresh = noise[:,mHeight]*thresholdNoise
3039 meteorNoise = noise[:,mHeight]
3040 meteorNoise = noise[:,mHeight]
3040 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3041 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3041 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3042 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3042
3043
3043 #Times reestimation
3044 #Times reestimation
3044 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3045 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3045 if mStart1.size > 0:
3046 if mStart1.size > 0:
3046 mStart1 = mStart1[-1] + 1
3047 mStart1 = mStart1[-1] + 1
3047
3048
3048 else:
3049 else:
3049 mStart1 = mPeak
3050 mStart1 = mPeak
3050
3051
3051 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3052 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3052 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3053 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3053 if mEndDecayTime1.size == 0:
3054 if mEndDecayTime1.size == 0:
3054 mEndDecayTime1 = powerNet0.size
3055 mEndDecayTime1 = powerNet0.size
3055 else:
3056 else:
3056 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3057 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3057 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3058 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3058
3059
3059 #meteorVolts1.- all Channels, from start to end
3060 #meteorVolts1.- all Channels, from start to end
3060 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3061 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3061 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3062 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3062 if meteorVolts2.shape[1] == 0:
3063 if meteorVolts2.shape[1] == 0:
3063 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3064 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3064 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3065 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3065 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3066 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3066 ##################### END PARAMETERS REESTIMATION #########################
3067 ##################### END PARAMETERS REESTIMATION #########################
3067
3068
3068 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3069 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3069 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3070 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3070 if meteorVolts2.shape[1] > 0:
3071 if meteorVolts2.shape[1] > 0:
3071 #Phase Difference re-estimation
3072 #Phase Difference re-estimation
3072 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3073 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3073 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3074 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3074 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3075 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3075 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3076 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3076 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3077 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3077
3078
3078 #Phase Difference RMS
3079 #Phase Difference RMS
3079 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3080 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3080 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3081 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3081 #Data from Meteor
3082 #Data from Meteor
3082 mPeak1 = powerNet1.argmax() + mStart1
3083 mPeak1 = powerNet1.argmax() + mStart1
3083 mPeakPower1 = powerNet1.max()
3084 mPeakPower1 = powerNet1.max()
3084 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3085 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3085 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3086 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3086 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3087 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3087 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3088 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3088 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3089 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3089 #Vectorize
3090 #Vectorize
3090 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3091 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3091 meteorAux[7:11] = phaseDiffint[0:4]
3092 meteorAux[7:11] = phaseDiffint[0:4]
3092
3093
3093 #Rejection Criterions
3094 #Rejection Criterions
3094 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3095 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3095 meteorAux[-1] = 17
3096 meteorAux[-1] = 17
3096 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3097 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3097 meteorAux[-1] = 1
3098 meteorAux[-1] = 1
3098
3099
3099
3100
3100 else:
3101 else:
3101 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3102 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3102 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3103 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3103 PowerSeries = 0
3104 PowerSeries = 0
3104
3105
3105 listMeteors1.append(meteorAux)
3106 listMeteors1.append(meteorAux)
3106 listPowerSeries.append(PowerSeries)
3107 listPowerSeries.append(PowerSeries)
3107 listVoltageSeries.append(meteorVolts1)
3108 listVoltageSeries.append(meteorVolts1)
3108
3109
3109 return listMeteors1, listPowerSeries, listVoltageSeries
3110 return listMeteors1, listPowerSeries, listVoltageSeries
3110
3111
3111 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3112 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3112
3113
3113 threshError = 10
3114 threshError = 10
3114 #Depending if it is 30 or 50 MHz
3115 #Depending if it is 30 or 50 MHz
3115 if frequency == 30e6:
3116 if frequency == 30e6:
3116 timeLag = 45*10**-3
3117 timeLag = 45*10**-3
3117 else:
3118 else:
3118 timeLag = 15*10**-3
3119 timeLag = 15*10**-3
3119 lag = numpy.ceil(timeLag/timeInterval)
3120 lag = numpy.ceil(timeLag/timeInterval)
3120
3121
3121 listMeteors1 = []
3122 listMeteors1 = []
3122
3123
3123 for i in range(len(listMeteors)):
3124 for i in range(len(listMeteors)):
3124 meteorPower = listPower[i]
3125 meteorPower = listPower[i]
3125 meteorAux = listMeteors[i]
3126 meteorAux = listMeteors[i]
3126
3127
3127 if meteorAux[-1] == 0:
3128 if meteorAux[-1] == 0:
3128
3129
3129 try:
3130 try:
3130 indmax = meteorPower.argmax()
3131 indmax = meteorPower.argmax()
3131 indlag = indmax + lag
3132 indlag = indmax + lag
3132
3133
3133 y = meteorPower[indlag:]
3134 y = meteorPower[indlag:]
3134 x = numpy.arange(0, y.size)*timeLag
3135 x = numpy.arange(0, y.size)*timeLag
3135
3136
3136 #first guess
3137 #first guess
3137 a = y[0]
3138 a = y[0]
3138 tau = timeLag
3139 tau = timeLag
3139 #exponential fit
3140 #exponential fit
3140 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3141 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3141 y1 = self.__exponential_function(x, *popt)
3142 y1 = self.__exponential_function(x, *popt)
3142 #error estimation
3143 #error estimation
3143 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3144 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3144
3145
3145 decayTime = popt[1]
3146 decayTime = popt[1]
3146 riseTime = indmax*timeInterval
3147 riseTime = indmax*timeInterval
3147 meteorAux[11:13] = [decayTime, error]
3148 meteorAux[11:13] = [decayTime, error]
3148
3149
3149 #Table items 7, 8 and 11
3150 #Table items 7, 8 and 11
3150 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3151 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3151 meteorAux[-1] = 7
3152 meteorAux[-1] = 7
3152 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3153 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3153 meteorAux[-1] = 8
3154 meteorAux[-1] = 8
3154 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3155 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3155 meteorAux[-1] = 11
3156 meteorAux[-1] = 11
3156
3157
3157
3158
3158 except:
3159 except:
3159 meteorAux[-1] = 11
3160 meteorAux[-1] = 11
3160
3161
3161
3162
3162 listMeteors1.append(meteorAux)
3163 listMeteors1.append(meteorAux)
3163
3164
3164 return listMeteors1
3165 return listMeteors1
3165
3166
3166 #Exponential Function
3167 #Exponential Function
3167
3168
3168 def __exponential_function(self, x, a, tau):
3169 def __exponential_function(self, x, a, tau):
3169 y = a*numpy.exp(-x/tau)
3170 y = a*numpy.exp(-x/tau)
3170 return y
3171 return y
3171
3172
3172 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3173 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3173
3174
3174 pairslist1 = list(pairslist)
3175 pairslist1 = list(pairslist)
3175 pairslist1.append((0,1))
3176 pairslist1.append((0,1))
3176 pairslist1.append((3,4))
3177 pairslist1.append((3,4))
3177 numPairs = len(pairslist1)
3178 numPairs = len(pairslist1)
3178 #Time Lag
3179 #Time Lag
3179 timeLag = 45*10**-3
3180 timeLag = 45*10**-3
3180 c = 3e8
3181 c = 3e8
3181 lag = numpy.ceil(timeLag/timeInterval)
3182 lag = numpy.ceil(timeLag/timeInterval)
3182 freq = 30e6
3183 freq = 30e6
3183
3184
3184 listMeteors1 = []
3185 listMeteors1 = []
3185
3186
3186 for i in range(len(listMeteors)):
3187 for i in range(len(listMeteors)):
3187 meteorAux = listMeteors[i]
3188 meteorAux = listMeteors[i]
3188 if meteorAux[-1] == 0:
3189 if meteorAux[-1] == 0:
3189 mStart = listMeteors[i][1]
3190 mStart = listMeteors[i][1]
3190 mPeak = listMeteors[i][2]
3191 mPeak = listMeteors[i][2]
3191 mLag = mPeak - mStart + lag
3192 mLag = mPeak - mStart + lag
3192
3193
3193 #get the volt data between the start and end times of the meteor
3194 #get the volt data between the start and end times of the meteor
3194 meteorVolts = listVolts[i]
3195 meteorVolts = listVolts[i]
3195 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3196 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3196
3197
3197 #Get CCF
3198 #Get CCF
3198 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3199 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3199
3200
3200 #Method 2
3201 #Method 2
3201 slopes = numpy.zeros(numPairs)
3202 slopes = numpy.zeros(numPairs)
3202 time = numpy.array([-2,-1,1,2])*timeInterval
3203 time = numpy.array([-2,-1,1,2])*timeInterval
3203 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3204 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3204
3205
3205 #Correct phases
3206 #Correct phases
3206 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3207 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3207 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3208 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3208
3209
3209 if indDer[0].shape[0] > 0:
3210 if indDer[0].shape[0] > 0:
3210 for i in range(indDer[0].shape[0]):
3211 for i in range(indDer[0].shape[0]):
3211 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3212 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3212 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3213 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3213
3214
3214 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3215 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3215 for j in range(numPairs):
3216 for j in range(numPairs):
3216 fit = stats.linregress(time, angAllCCF[j,:])
3217 fit = stats.linregress(time, angAllCCF[j,:])
3217 slopes[j] = fit[0]
3218 slopes[j] = fit[0]
3218
3219
3219 #Remove Outlier
3220 #Remove Outlier
3220 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3221 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3221 # slopes = numpy.delete(slopes,indOut)
3222 # slopes = numpy.delete(slopes,indOut)
3222 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3223 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3223 # slopes = numpy.delete(slopes,indOut)
3224 # slopes = numpy.delete(slopes,indOut)
3224
3225
3225 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3226 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3226 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3227 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3227 meteorAux[-2] = radialError
3228 meteorAux[-2] = radialError
3228 meteorAux[-3] = radialVelocity
3229 meteorAux[-3] = radialVelocity
3229
3230
3230 #Setting Error
3231 #Setting Error
3231 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3232 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3232 if numpy.abs(radialVelocity) > 200:
3233 if numpy.abs(radialVelocity) > 200:
3233 meteorAux[-1] = 15
3234 meteorAux[-1] = 15
3234 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3235 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3235 elif radialError > radialStdThresh:
3236 elif radialError > radialStdThresh:
3236 meteorAux[-1] = 12
3237 meteorAux[-1] = 12
3237
3238
3238 listMeteors1.append(meteorAux)
3239 listMeteors1.append(meteorAux)
3239 return listMeteors1
3240 return listMeteors1
3240
3241
3241 def __setNewArrays(self, listMeteors, date, heiRang):
3242 def __setNewArrays(self, listMeteors, date, heiRang):
3242
3243
3243 #New arrays
3244 #New arrays
3244 arrayMeteors = numpy.array(listMeteors)
3245 arrayMeteors = numpy.array(listMeteors)
3245 arrayParameters = numpy.zeros((len(listMeteors), 13))
3246 arrayParameters = numpy.zeros((len(listMeteors), 13))
3246
3247
3247 #Date inclusion
3248 #Date inclusion
3248 # date = re.findall(r'\((.*?)\)', date)
3249 # date = re.findall(r'\((.*?)\)', date)
3249 # date = date[0].split(',')
3250 # date = date[0].split(',')
3250 # date = map(int, date)
3251 # date = map(int, date)
3251 #
3252 #
3252 # if len(date)<6:
3253 # if len(date)<6:
3253 # date.append(0)
3254 # date.append(0)
3254 #
3255 #
3255 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3256 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3256 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3257 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3257 arrayDate = numpy.tile(date, (len(listMeteors)))
3258 arrayDate = numpy.tile(date, (len(listMeteors)))
3258
3259
3259 #Meteor array
3260 #Meteor array
3260 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3261 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3261 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3262 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3262
3263
3263 #Parameters Array
3264 #Parameters Array
3264 arrayParameters[:,0] = arrayDate #Date
3265 arrayParameters[:,0] = arrayDate #Date
3265 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3266 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3266 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3267 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3267 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3268 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3268 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3269 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3269
3270
3270
3271
3271 return arrayParameters
3272 return arrayParameters
3272
3273
3273 class CorrectSMPhases(Operation):
3274 class CorrectSMPhases(Operation):
3274
3275
3275 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3276 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3276
3277
3277 arrayParameters = dataOut.data_param
3278 arrayParameters = dataOut.data_param
3278 pairsList = []
3279 pairsList = []
3279 pairx = (0,1)
3280 pairx = (0,1)
3280 pairy = (2,3)
3281 pairy = (2,3)
3281 pairsList.append(pairx)
3282 pairsList.append(pairx)
3282 pairsList.append(pairy)
3283 pairsList.append(pairy)
3283 jph = numpy.zeros(4)
3284 jph = numpy.zeros(4)
3284
3285
3285 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3286 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3286 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3287 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3287 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3288 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3288
3289
3289 meteorOps = SMOperations()
3290 meteorOps = SMOperations()
3290 if channelPositions is None:
3291 if channelPositions is None:
3291 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3292 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3292 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3293 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3293
3294
3294 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3295 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3295 h = (hmin,hmax)
3296 h = (hmin,hmax)
3296
3297
3297 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3298 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3298
3299
3299 dataOut.data_param = arrayParameters
3300 dataOut.data_param = arrayParameters
3300 return
3301 return
3301
3302
3302 class SMPhaseCalibration(Operation):
3303 class SMPhaseCalibration(Operation):
3303
3304
3304 __buffer = None
3305 __buffer = None
3305
3306
3306 __initime = None
3307 __initime = None
3307
3308
3308 __dataReady = False
3309 __dataReady = False
3309
3310
3310 __isConfig = False
3311 __isConfig = False
3311
3312
3312 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3313 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3313
3314
3314 dataTime = currentTime + paramInterval
3315 dataTime = currentTime + paramInterval
3315 deltaTime = dataTime - initTime
3316 deltaTime = dataTime - initTime
3316
3317
3317 if deltaTime >= outputInterval or deltaTime < 0:
3318 if deltaTime >= outputInterval or deltaTime < 0:
3318 return True
3319 return True
3319
3320
3320 return False
3321 return False
3321
3322
3322 def __getGammas(self, pairs, d, phases):
3323 def __getGammas(self, pairs, d, phases):
3323 gammas = numpy.zeros(2)
3324 gammas = numpy.zeros(2)
3324
3325
3325 for i in range(len(pairs)):
3326 for i in range(len(pairs)):
3326
3327
3327 pairi = pairs[i]
3328 pairi = pairs[i]
3328
3329
3329 phip3 = phases[:,pairi[0]]
3330 phip3 = phases[:,pairi[0]]
3330 d3 = d[pairi[0]]
3331 d3 = d[pairi[0]]
3331 phip2 = phases[:,pairi[1]]
3332 phip2 = phases[:,pairi[1]]
3332 d2 = d[pairi[1]]
3333 d2 = d[pairi[1]]
3333 #Calculating gamma
3334 #Calculating gamma
3334 # jdcos = alp1/(k*d1)
3335 # jdcos = alp1/(k*d1)
3335 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3336 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3336 jgamma = -phip2*d3/d2 - phip3
3337 jgamma = -phip2*d3/d2 - phip3
3337 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3338 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3338 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3339 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3339 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3340 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3340
3341
3341 #Revised distribution
3342 #Revised distribution
3342 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3343 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3343
3344
3344 #Histogram
3345 #Histogram
3345 nBins = 64
3346 nBins = 64
3346 rmin = -0.5*numpy.pi
3347 rmin = -0.5*numpy.pi
3347 rmax = 0.5*numpy.pi
3348 rmax = 0.5*numpy.pi
3348 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3349 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3349
3350
3350 meteorsY = phaseHisto[0]
3351 meteorsY = phaseHisto[0]
3351 phasesX = phaseHisto[1][:-1]
3352 phasesX = phaseHisto[1][:-1]
3352 width = phasesX[1] - phasesX[0]
3353 width = phasesX[1] - phasesX[0]
3353 phasesX += width/2
3354 phasesX += width/2
3354
3355
3355 #Gaussian aproximation
3356 #Gaussian aproximation
3356 bpeak = meteorsY.argmax()
3357 bpeak = meteorsY.argmax()
3357 peak = meteorsY.max()
3358 peak = meteorsY.max()
3358 jmin = bpeak - 5
3359 jmin = bpeak - 5
3359 jmax = bpeak + 5 + 1
3360 jmax = bpeak + 5 + 1
3360
3361
3361 if jmin<0:
3362 if jmin<0:
3362 jmin = 0
3363 jmin = 0
3363 jmax = 6
3364 jmax = 6
3364 elif jmax > meteorsY.size:
3365 elif jmax > meteorsY.size:
3365 jmin = meteorsY.size - 6
3366 jmin = meteorsY.size - 6
3366 jmax = meteorsY.size
3367 jmax = meteorsY.size
3367
3368
3368 x0 = numpy.array([peak,bpeak,50])
3369 x0 = numpy.array([peak,bpeak,50])
3369 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3370 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3370
3371
3371 #Gammas
3372 #Gammas
3372 gammas[i] = coeff[0][1]
3373 gammas[i] = coeff[0][1]
3373
3374
3374 return gammas
3375 return gammas
3375
3376
3376 def __residualFunction(self, coeffs, y, t):
3377 def __residualFunction(self, coeffs, y, t):
3377
3378
3378 return y - self.__gauss_function(t, coeffs)
3379 return y - self.__gauss_function(t, coeffs)
3379
3380
3380 def __gauss_function(self, t, coeffs):
3381 def __gauss_function(self, t, coeffs):
3381
3382
3382 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3383 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3383
3384
3384 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3385 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3385 meteorOps = SMOperations()
3386 meteorOps = SMOperations()
3386 nchan = 4
3387 nchan = 4
3387 pairx = pairsList[0] #x es 0
3388 pairx = pairsList[0] #x es 0
3388 pairy = pairsList[1] #y es 1
3389 pairy = pairsList[1] #y es 1
3389 center_xangle = 0
3390 center_xangle = 0
3390 center_yangle = 0
3391 center_yangle = 0
3391 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3392 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3392 ntimes = len(range_angle)
3393 ntimes = len(range_angle)
3393
3394
3394 nstepsx = 20
3395 nstepsx = 20
3395 nstepsy = 20
3396 nstepsy = 20
3396
3397
3397 for iz in range(ntimes):
3398 for iz in range(ntimes):
3398 min_xangle = -range_angle[iz]/2 + center_xangle
3399 min_xangle = -range_angle[iz]/2 + center_xangle
3399 max_xangle = range_angle[iz]/2 + center_xangle
3400 max_xangle = range_angle[iz]/2 + center_xangle
3400 min_yangle = -range_angle[iz]/2 + center_yangle
3401 min_yangle = -range_angle[iz]/2 + center_yangle
3401 max_yangle = range_angle[iz]/2 + center_yangle
3402 max_yangle = range_angle[iz]/2 + center_yangle
3402
3403
3403 inc_x = (max_xangle-min_xangle)/nstepsx
3404 inc_x = (max_xangle-min_xangle)/nstepsx
3404 inc_y = (max_yangle-min_yangle)/nstepsy
3405 inc_y = (max_yangle-min_yangle)/nstepsy
3405
3406
3406 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3407 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3407 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3408 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3408 penalty = numpy.zeros((nstepsx,nstepsy))
3409 penalty = numpy.zeros((nstepsx,nstepsy))
3409 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3410 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3410 jph = numpy.zeros(nchan)
3411 jph = numpy.zeros(nchan)
3411
3412
3412 # Iterations looking for the offset
3413 # Iterations looking for the offset
3413 for iy in range(int(nstepsy)):
3414 for iy in range(int(nstepsy)):
3414 for ix in range(int(nstepsx)):
3415 for ix in range(int(nstepsx)):
3415 d3 = d[pairsList[1][0]]
3416 d3 = d[pairsList[1][0]]
3416 d2 = d[pairsList[1][1]]
3417 d2 = d[pairsList[1][1]]
3417 d5 = d[pairsList[0][0]]
3418 d5 = d[pairsList[0][0]]
3418 d4 = d[pairsList[0][1]]
3419 d4 = d[pairsList[0][1]]
3419
3420
3420 alp2 = alpha_y[iy] #gamma 1
3421 alp2 = alpha_y[iy] #gamma 1
3421 alp4 = alpha_x[ix] #gamma 0
3422 alp4 = alpha_x[ix] #gamma 0
3422
3423
3423 alp3 = -alp2*d3/d2 - gammas[1]
3424 alp3 = -alp2*d3/d2 - gammas[1]
3424 alp5 = -alp4*d5/d4 - gammas[0]
3425 alp5 = -alp4*d5/d4 - gammas[0]
3425 # jph[pairy[1]] = alpha_y[iy]
3426 # jph[pairy[1]] = alpha_y[iy]
3426 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3427 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3427
3428
3428 # jph[pairx[1]] = alpha_x[ix]
3429 # jph[pairx[1]] = alpha_x[ix]
3429 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3430 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3430 jph[pairsList[0][1]] = alp4
3431 jph[pairsList[0][1]] = alp4
3431 jph[pairsList[0][0]] = alp5
3432 jph[pairsList[0][0]] = alp5
3432 jph[pairsList[1][0]] = alp3
3433 jph[pairsList[1][0]] = alp3
3433 jph[pairsList[1][1]] = alp2
3434 jph[pairsList[1][1]] = alp2
3434 jph_array[:,ix,iy] = jph
3435 jph_array[:,ix,iy] = jph
3435 # d = [2.0,2.5,2.5,2.0]
3436 # d = [2.0,2.5,2.5,2.0]
3436 #falta chequear si va a leer bien los meteoros
3437 #falta chequear si va a leer bien los meteoros
3437 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3438 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3438 error = meteorsArray1[:,-1]
3439 error = meteorsArray1[:,-1]
3439 ind1 = numpy.where(error==0)[0]
3440 ind1 = numpy.where(error==0)[0]
3440 penalty[ix,iy] = ind1.size
3441 penalty[ix,iy] = ind1.size
3441
3442
3442 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3443 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3443 phOffset = jph_array[:,i,j]
3444 phOffset = jph_array[:,i,j]
3444
3445
3445 center_xangle = phOffset[pairx[1]]
3446 center_xangle = phOffset[pairx[1]]
3446 center_yangle = phOffset[pairy[1]]
3447 center_yangle = phOffset[pairy[1]]
3447
3448
3448 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3449 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3449 phOffset = phOffset*180/numpy.pi
3450 phOffset = phOffset*180/numpy.pi
3450 return phOffset
3451 return phOffset
3451
3452
3452
3453
3453 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3454 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3454
3455
3455 dataOut.flagNoData = True
3456 dataOut.flagNoData = True
3456 self.__dataReady = False
3457 self.__dataReady = False
3457 dataOut.outputInterval = nHours*3600
3458 dataOut.outputInterval = nHours*3600
3458
3459
3459 if self.__isConfig == False:
3460 if self.__isConfig == False:
3460 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3461 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3461 #Get Initial LTC time
3462 #Get Initial LTC time
3462 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3463 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3463 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3464 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3464
3465
3465 self.__isConfig = True
3466 self.__isConfig = True
3466
3467
3467 if self.__buffer is None:
3468 if self.__buffer is None:
3468 self.__buffer = dataOut.data_param.copy()
3469 self.__buffer = dataOut.data_param.copy()
3469
3470
3470 else:
3471 else:
3471 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3472 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3472
3473
3473 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3474 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3474
3475
3475 if self.__dataReady:
3476 if self.__dataReady:
3476 dataOut.utctimeInit = self.__initime
3477 dataOut.utctimeInit = self.__initime
3477 self.__initime += dataOut.outputInterval #to erase time offset
3478 self.__initime += dataOut.outputInterval #to erase time offset
3478
3479
3479 freq = dataOut.frequency
3480 freq = dataOut.frequency
3480 c = dataOut.C #m/s
3481 c = dataOut.C #m/s
3481 lamb = c/freq
3482 lamb = c/freq
3482 k = 2*numpy.pi/lamb
3483 k = 2*numpy.pi/lamb
3483 azimuth = 0
3484 azimuth = 0
3484 h = (hmin, hmax)
3485 h = (hmin, hmax)
3485 # pairs = ((0,1),(2,3)) #Estrella
3486 # pairs = ((0,1),(2,3)) #Estrella
3486 # pairs = ((1,0),(2,3)) #T
3487 # pairs = ((1,0),(2,3)) #T
3487
3488
3488 if channelPositions is None:
3489 if channelPositions is None:
3489 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3490 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3490 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3491 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3491 meteorOps = SMOperations()
3492 meteorOps = SMOperations()
3492 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3493 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3493
3494
3494 #Checking correct order of pairs
3495 #Checking correct order of pairs
3495 pairs = []
3496 pairs = []
3496 if distances[1] > distances[0]:
3497 if distances[1] > distances[0]:
3497 pairs.append((1,0))
3498 pairs.append((1,0))
3498 else:
3499 else:
3499 pairs.append((0,1))
3500 pairs.append((0,1))
3500
3501
3501 if distances[3] > distances[2]:
3502 if distances[3] > distances[2]:
3502 pairs.append((3,2))
3503 pairs.append((3,2))
3503 else:
3504 else:
3504 pairs.append((2,3))
3505 pairs.append((2,3))
3505 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3506 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3506
3507
3507 meteorsArray = self.__buffer
3508 meteorsArray = self.__buffer
3508 error = meteorsArray[:,-1]
3509 error = meteorsArray[:,-1]
3509 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3510 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3510 ind1 = numpy.where(boolError)[0]
3511 ind1 = numpy.where(boolError)[0]
3511 meteorsArray = meteorsArray[ind1,:]
3512 meteorsArray = meteorsArray[ind1,:]
3512 meteorsArray[:,-1] = 0
3513 meteorsArray[:,-1] = 0
3513 phases = meteorsArray[:,8:12]
3514 phases = meteorsArray[:,8:12]
3514
3515
3515 #Calculate Gammas
3516 #Calculate Gammas
3516 gammas = self.__getGammas(pairs, distances, phases)
3517 gammas = self.__getGammas(pairs, distances, phases)
3517 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3518 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3518 #Calculate Phases
3519 #Calculate Phases
3519 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3520 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3520 phasesOff = phasesOff.reshape((1,phasesOff.size))
3521 phasesOff = phasesOff.reshape((1,phasesOff.size))
3521 dataOut.data_output = -phasesOff
3522 dataOut.data_output = -phasesOff
3522 dataOut.flagNoData = False
3523 dataOut.flagNoData = False
3523 self.__buffer = None
3524 self.__buffer = None
3524
3525
3525
3526
3526 return
3527 return
3527
3528
3528 class SMOperations():
3529 class SMOperations():
3529
3530
3530 def __init__(self):
3531 def __init__(self):
3531
3532
3532 return
3533 return
3533
3534
3534 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3535 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3535
3536
3536 arrayParameters = arrayParameters0.copy()
3537 arrayParameters = arrayParameters0.copy()
3537 hmin = h[0]
3538 hmin = h[0]
3538 hmax = h[1]
3539 hmax = h[1]
3539
3540
3540 #Calculate AOA (Error N 3, 4)
3541 #Calculate AOA (Error N 3, 4)
3541 #JONES ET AL. 1998
3542 #JONES ET AL. 1998
3542 AOAthresh = numpy.pi/8
3543 AOAthresh = numpy.pi/8
3543 error = arrayParameters[:,-1]
3544 error = arrayParameters[:,-1]
3544 phases = -arrayParameters[:,8:12] + jph
3545 phases = -arrayParameters[:,8:12] + jph
3545 # phases = numpy.unwrap(phases)
3546 # phases = numpy.unwrap(phases)
3546 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3547 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3547
3548
3548 #Calculate Heights (Error N 13 and 14)
3549 #Calculate Heights (Error N 13 and 14)
3549 error = arrayParameters[:,-1]
3550 error = arrayParameters[:,-1]
3550 Ranges = arrayParameters[:,1]
3551 Ranges = arrayParameters[:,1]
3551 zenith = arrayParameters[:,4]
3552 zenith = arrayParameters[:,4]
3552 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3553 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3553
3554
3554 #----------------------- Get Final data ------------------------------------
3555 #----------------------- Get Final data ------------------------------------
3555 # error = arrayParameters[:,-1]
3556 # error = arrayParameters[:,-1]
3556 # ind1 = numpy.where(error==0)[0]
3557 # ind1 = numpy.where(error==0)[0]
3557 # arrayParameters = arrayParameters[ind1,:]
3558 # arrayParameters = arrayParameters[ind1,:]
3558
3559
3559 return arrayParameters
3560 return arrayParameters
3560
3561
3561 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3562 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3562
3563
3563 arrayAOA = numpy.zeros((phases.shape[0],3))
3564 arrayAOA = numpy.zeros((phases.shape[0],3))
3564 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3565 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3565
3566
3566 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3567 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3567 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3568 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3568 arrayAOA[:,2] = cosDirError
3569 arrayAOA[:,2] = cosDirError
3569
3570
3570 azimuthAngle = arrayAOA[:,0]
3571 azimuthAngle = arrayAOA[:,0]
3571 zenithAngle = arrayAOA[:,1]
3572 zenithAngle = arrayAOA[:,1]
3572
3573
3573 #Setting Error
3574 #Setting Error
3574 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3575 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3575 error[indError] = 0
3576 error[indError] = 0
3576 #Number 3: AOA not fesible
3577 #Number 3: AOA not fesible
3577 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3578 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3578 error[indInvalid] = 3
3579 error[indInvalid] = 3
3579 #Number 4: Large difference in AOAs obtained from different antenna baselines
3580 #Number 4: Large difference in AOAs obtained from different antenna baselines
3580 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3581 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3581 error[indInvalid] = 4
3582 error[indInvalid] = 4
3582 return arrayAOA, error
3583 return arrayAOA, error
3583
3584
3584 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3585 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3585
3586
3586 #Initializing some variables
3587 #Initializing some variables
3587 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3588 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3588 ang_aux = ang_aux.reshape(1,ang_aux.size)
3589 ang_aux = ang_aux.reshape(1,ang_aux.size)
3589
3590
3590 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3591 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3591 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3592 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3592
3593
3593
3594
3594 for i in range(2):
3595 for i in range(2):
3595 ph0 = arrayPhase[:,pairsList[i][0]]
3596 ph0 = arrayPhase[:,pairsList[i][0]]
3596 ph1 = arrayPhase[:,pairsList[i][1]]
3597 ph1 = arrayPhase[:,pairsList[i][1]]
3597 d0 = distances[pairsList[i][0]]
3598 d0 = distances[pairsList[i][0]]
3598 d1 = distances[pairsList[i][1]]
3599 d1 = distances[pairsList[i][1]]
3599
3600
3600 ph0_aux = ph0 + ph1
3601 ph0_aux = ph0 + ph1
3601 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3602 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3602 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3603 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3603 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3604 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3604 #First Estimation
3605 #First Estimation
3605 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3606 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3606
3607
3607 #Most-Accurate Second Estimation
3608 #Most-Accurate Second Estimation
3608 phi1_aux = ph0 - ph1
3609 phi1_aux = ph0 - ph1
3609 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3610 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3610 #Direction Cosine 1
3611 #Direction Cosine 1
3611 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3612 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3612
3613
3613 #Searching the correct Direction Cosine
3614 #Searching the correct Direction Cosine
3614 cosdir0_aux = cosdir0[:,i]
3615 cosdir0_aux = cosdir0[:,i]
3615 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3616 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3616 #Minimum Distance
3617 #Minimum Distance
3617 cosDiff = (cosdir1 - cosdir0_aux)**2
3618 cosDiff = (cosdir1 - cosdir0_aux)**2
3618 indcos = cosDiff.argmin(axis = 1)
3619 indcos = cosDiff.argmin(axis = 1)
3619 #Saving Value obtained
3620 #Saving Value obtained
3620 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3621 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3621
3622
3622 return cosdir0, cosdir
3623 return cosdir0, cosdir
3623
3624
3624 def __calculateAOA(self, cosdir, azimuth):
3625 def __calculateAOA(self, cosdir, azimuth):
3625 cosdirX = cosdir[:,0]
3626 cosdirX = cosdir[:,0]
3626 cosdirY = cosdir[:,1]
3627 cosdirY = cosdir[:,1]
3627
3628
3628 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3629 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3629 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3630 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3630 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3631 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3631
3632
3632 return angles
3633 return angles
3633
3634
3634 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3635 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3635
3636
3636 Ramb = 375 #Ramb = c/(2*PRF)
3637 Ramb = 375 #Ramb = c/(2*PRF)
3637 Re = 6371 #Earth Radius
3638 Re = 6371 #Earth Radius
3638 heights = numpy.zeros(Ranges.shape)
3639 heights = numpy.zeros(Ranges.shape)
3639
3640
3640 R_aux = numpy.array([0,1,2])*Ramb
3641 R_aux = numpy.array([0,1,2])*Ramb
3641 R_aux = R_aux.reshape(1,R_aux.size)
3642 R_aux = R_aux.reshape(1,R_aux.size)
3642
3643
3643 Ranges = Ranges.reshape(Ranges.size,1)
3644 Ranges = Ranges.reshape(Ranges.size,1)
3644
3645
3645 Ri = Ranges + R_aux
3646 Ri = Ranges + R_aux
3646 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3647 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3647
3648
3648 #Check if there is a height between 70 and 110 km
3649 #Check if there is a height between 70 and 110 km
3649 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3650 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3650 ind_h = numpy.where(h_bool == 1)[0]
3651 ind_h = numpy.where(h_bool == 1)[0]
3651
3652
3652 hCorr = hi[ind_h, :]
3653 hCorr = hi[ind_h, :]
3653 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3654 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3654
3655
3655 hCorr = hi[ind_hCorr][:len(ind_h)]
3656 hCorr = hi[ind_hCorr][:len(ind_h)]
3656 heights[ind_h] = hCorr
3657 heights[ind_h] = hCorr
3657
3658
3658 #Setting Error
3659 #Setting Error
3659 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3660 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3660 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3661 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3661 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3662 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3662 error[indError] = 0
3663 error[indError] = 0
3663 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3664 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3664 error[indInvalid2] = 14
3665 error[indInvalid2] = 14
3665 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3666 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3666 error[indInvalid1] = 13
3667 error[indInvalid1] = 13
3667
3668
3668 return heights, error
3669 return heights, error
3669
3670
3670 def getPhasePairs(self, channelPositions):
3671 def getPhasePairs(self, channelPositions):
3671 chanPos = numpy.array(channelPositions)
3672 chanPos = numpy.array(channelPositions)
3672 listOper = list(itertools.combinations(list(range(5)),2))
3673 listOper = list(itertools.combinations(list(range(5)),2))
3673
3674
3674 distances = numpy.zeros(4)
3675 distances = numpy.zeros(4)
3675 axisX = []
3676 axisX = []
3676 axisY = []
3677 axisY = []
3677 distX = numpy.zeros(3)
3678 distX = numpy.zeros(3)
3678 distY = numpy.zeros(3)
3679 distY = numpy.zeros(3)
3679 ix = 0
3680 ix = 0
3680 iy = 0
3681 iy = 0
3681
3682
3682 pairX = numpy.zeros((2,2))
3683 pairX = numpy.zeros((2,2))
3683 pairY = numpy.zeros((2,2))
3684 pairY = numpy.zeros((2,2))
3684
3685
3685 for i in range(len(listOper)):
3686 for i in range(len(listOper)):
3686 pairi = listOper[i]
3687 pairi = listOper[i]
3687
3688
3688 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3689 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3689
3690
3690 if posDif[0] == 0:
3691 if posDif[0] == 0:
3691 axisY.append(pairi)
3692 axisY.append(pairi)
3692 distY[iy] = posDif[1]
3693 distY[iy] = posDif[1]
3693 iy += 1
3694 iy += 1
3694 elif posDif[1] == 0:
3695 elif posDif[1] == 0:
3695 axisX.append(pairi)
3696 axisX.append(pairi)
3696 distX[ix] = posDif[0]
3697 distX[ix] = posDif[0]
3697 ix += 1
3698 ix += 1
3698
3699
3699 for i in range(2):
3700 for i in range(2):
3700 if i==0:
3701 if i==0:
3701 dist0 = distX
3702 dist0 = distX
3702 axis0 = axisX
3703 axis0 = axisX
3703 else:
3704 else:
3704 dist0 = distY
3705 dist0 = distY
3705 axis0 = axisY
3706 axis0 = axisY
3706
3707
3707 side = numpy.argsort(dist0)[:-1]
3708 side = numpy.argsort(dist0)[:-1]
3708 axis0 = numpy.array(axis0)[side,:]
3709 axis0 = numpy.array(axis0)[side,:]
3709 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3710 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3710 axis1 = numpy.unique(numpy.reshape(axis0,4))
3711 axis1 = numpy.unique(numpy.reshape(axis0,4))
3711 side = axis1[axis1 != chanC]
3712 side = axis1[axis1 != chanC]
3712 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3713 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3713 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3714 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3714 if diff1<0:
3715 if diff1<0:
3715 chan2 = side[0]
3716 chan2 = side[0]
3716 d2 = numpy.abs(diff1)
3717 d2 = numpy.abs(diff1)
3717 chan1 = side[1]
3718 chan1 = side[1]
3718 d1 = numpy.abs(diff2)
3719 d1 = numpy.abs(diff2)
3719 else:
3720 else:
3720 chan2 = side[1]
3721 chan2 = side[1]
3721 d2 = numpy.abs(diff2)
3722 d2 = numpy.abs(diff2)
3722 chan1 = side[0]
3723 chan1 = side[0]
3723 d1 = numpy.abs(diff1)
3724 d1 = numpy.abs(diff1)
3724
3725
3725 if i==0:
3726 if i==0:
3726 chanCX = chanC
3727 chanCX = chanC
3727 chan1X = chan1
3728 chan1X = chan1
3728 chan2X = chan2
3729 chan2X = chan2
3729 distances[0:2] = numpy.array([d1,d2])
3730 distances[0:2] = numpy.array([d1,d2])
3730 else:
3731 else:
3731 chanCY = chanC
3732 chanCY = chanC
3732 chan1Y = chan1
3733 chan1Y = chan1
3733 chan2Y = chan2
3734 chan2Y = chan2
3734 distances[2:4] = numpy.array([d1,d2])
3735 distances[2:4] = numpy.array([d1,d2])
3735 # axisXsides = numpy.reshape(axisX[ix,:],4)
3736 # axisXsides = numpy.reshape(axisX[ix,:],4)
3736 #
3737 #
3737 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3738 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3738 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3739 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3739 #
3740 #
3740 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3741 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3741 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3742 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3742 # channel25X = int(pairX[0,ind25X])
3743 # channel25X = int(pairX[0,ind25X])
3743 # channel20X = int(pairX[1,ind20X])
3744 # channel20X = int(pairX[1,ind20X])
3744 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3745 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3745 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3746 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3746 # channel25Y = int(pairY[0,ind25Y])
3747 # channel25Y = int(pairY[0,ind25Y])
3747 # channel20Y = int(pairY[1,ind20Y])
3748 # channel20Y = int(pairY[1,ind20Y])
3748
3749
3749 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3750 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3750 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3751 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3751
3752
3752 return pairslist, distances
3753 return pairslist, distances
3753 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3754 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3754 #
3755 #
3755 # arrayAOA = numpy.zeros((phases.shape[0],3))
3756 # arrayAOA = numpy.zeros((phases.shape[0],3))
3756 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3757 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3757 #
3758 #
3758 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3759 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3759 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3760 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3760 # arrayAOA[:,2] = cosDirError
3761 # arrayAOA[:,2] = cosDirError
3761 #
3762 #
3762 # azimuthAngle = arrayAOA[:,0]
3763 # azimuthAngle = arrayAOA[:,0]
3763 # zenithAngle = arrayAOA[:,1]
3764 # zenithAngle = arrayAOA[:,1]
3764 #
3765 #
3765 # #Setting Error
3766 # #Setting Error
3766 # #Number 3: AOA not fesible
3767 # #Number 3: AOA not fesible
3767 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3768 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3768 # error[indInvalid] = 3
3769 # error[indInvalid] = 3
3769 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3770 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3770 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3771 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3771 # error[indInvalid] = 4
3772 # error[indInvalid] = 4
3772 # return arrayAOA, error
3773 # return arrayAOA, error
3773 #
3774 #
3774 # def __getDirectionCosines(self, arrayPhase, pairsList):
3775 # def __getDirectionCosines(self, arrayPhase, pairsList):
3775 #
3776 #
3776 # #Initializing some variables
3777 # #Initializing some variables
3777 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3778 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3778 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3779 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3779 #
3780 #
3780 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3781 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3781 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3782 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3782 #
3783 #
3783 #
3784 #
3784 # for i in range(2):
3785 # for i in range(2):
3785 # #First Estimation
3786 # #First Estimation
3786 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3787 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3787 # #Dealias
3788 # #Dealias
3788 # indcsi = numpy.where(phi0_aux > numpy.pi)
3789 # indcsi = numpy.where(phi0_aux > numpy.pi)
3789 # phi0_aux[indcsi] -= 2*numpy.pi
3790 # phi0_aux[indcsi] -= 2*numpy.pi
3790 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3791 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3791 # phi0_aux[indcsi] += 2*numpy.pi
3792 # phi0_aux[indcsi] += 2*numpy.pi
3792 # #Direction Cosine 0
3793 # #Direction Cosine 0
3793 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3794 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3794 #
3795 #
3795 # #Most-Accurate Second Estimation
3796 # #Most-Accurate Second Estimation
3796 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3797 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3797 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3798 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3798 # #Direction Cosine 1
3799 # #Direction Cosine 1
3799 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3800 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3800 #
3801 #
3801 # #Searching the correct Direction Cosine
3802 # #Searching the correct Direction Cosine
3802 # cosdir0_aux = cosdir0[:,i]
3803 # cosdir0_aux = cosdir0[:,i]
3803 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3804 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3804 # #Minimum Distance
3805 # #Minimum Distance
3805 # cosDiff = (cosdir1 - cosdir0_aux)**2
3806 # cosDiff = (cosdir1 - cosdir0_aux)**2
3806 # indcos = cosDiff.argmin(axis = 1)
3807 # indcos = cosDiff.argmin(axis = 1)
3807 # #Saving Value obtained
3808 # #Saving Value obtained
3808 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3809 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3809 #
3810 #
3810 # return cosdir0, cosdir
3811 # return cosdir0, cosdir
3811 #
3812 #
3812 # def __calculateAOA(self, cosdir, azimuth):
3813 # def __calculateAOA(self, cosdir, azimuth):
3813 # cosdirX = cosdir[:,0]
3814 # cosdirX = cosdir[:,0]
3814 # cosdirY = cosdir[:,1]
3815 # cosdirY = cosdir[:,1]
3815 #
3816 #
3816 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3817 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3817 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3818 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3818 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3819 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3819 #
3820 #
3820 # return angles
3821 # return angles
3821 #
3822 #
3822 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3823 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3823 #
3824 #
3824 # Ramb = 375 #Ramb = c/(2*PRF)
3825 # Ramb = 375 #Ramb = c/(2*PRF)
3825 # Re = 6371 #Earth Radius
3826 # Re = 6371 #Earth Radius
3826 # heights = numpy.zeros(Ranges.shape)
3827 # heights = numpy.zeros(Ranges.shape)
3827 #
3828 #
3828 # R_aux = numpy.array([0,1,2])*Ramb
3829 # R_aux = numpy.array([0,1,2])*Ramb
3829 # R_aux = R_aux.reshape(1,R_aux.size)
3830 # R_aux = R_aux.reshape(1,R_aux.size)
3830 #
3831 #
3831 # Ranges = Ranges.reshape(Ranges.size,1)
3832 # Ranges = Ranges.reshape(Ranges.size,1)
3832 #
3833 #
3833 # Ri = Ranges + R_aux
3834 # Ri = Ranges + R_aux
3834 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3835 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3835 #
3836 #
3836 # #Check if there is a height between 70 and 110 km
3837 # #Check if there is a height between 70 and 110 km
3837 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3838 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3838 # ind_h = numpy.where(h_bool == 1)[0]
3839 # ind_h = numpy.where(h_bool == 1)[0]
3839 #
3840 #
3840 # hCorr = hi[ind_h, :]
3841 # hCorr = hi[ind_h, :]
3841 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3842 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3842 #
3843 #
3843 # hCorr = hi[ind_hCorr]
3844 # hCorr = hi[ind_hCorr]
3844 # heights[ind_h] = hCorr
3845 # heights[ind_h] = hCorr
3845 #
3846 #
3846 # #Setting Error
3847 # #Setting Error
3847 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3848 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3848 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3849 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3849 #
3850 #
3850 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3851 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3851 # error[indInvalid2] = 14
3852 # error[indInvalid2] = 14
3852 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3853 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3853 # error[indInvalid1] = 13
3854 # error[indInvalid1] = 13
3854 #
3855 #
3855 # return heights, error
3856 # return heights, error
3856 No newline at end of file
3857
General Comments 0
You need to be logged in to leave comments. Login now