##// END OF EJS Templates
-Functional HDF5 Format Writing and Reading Unit...
Julio Valdez -
r804:4c41460abf8c
parent child
Show More
@@ -1,1169 +1,1169
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
10
11 from jroheaderIO import SystemHeader, RadarControllerHeader
11 from jroheaderIO import SystemHeader, RadarControllerHeader
12
12
13 def getNumpyDtype(dataTypeCode):
13 def getNumpyDtype(dataTypeCode):
14
14
15 if dataTypeCode == 0:
15 if dataTypeCode == 0:
16 numpyDtype = numpy.dtype([('real','<i1'),('imag','<i1')])
16 numpyDtype = numpy.dtype([('real','<i1'),('imag','<i1')])
17 elif dataTypeCode == 1:
17 elif dataTypeCode == 1:
18 numpyDtype = numpy.dtype([('real','<i2'),('imag','<i2')])
18 numpyDtype = numpy.dtype([('real','<i2'),('imag','<i2')])
19 elif dataTypeCode == 2:
19 elif dataTypeCode == 2:
20 numpyDtype = numpy.dtype([('real','<i4'),('imag','<i4')])
20 numpyDtype = numpy.dtype([('real','<i4'),('imag','<i4')])
21 elif dataTypeCode == 3:
21 elif dataTypeCode == 3:
22 numpyDtype = numpy.dtype([('real','<i8'),('imag','<i8')])
22 numpyDtype = numpy.dtype([('real','<i8'),('imag','<i8')])
23 elif dataTypeCode == 4:
23 elif dataTypeCode == 4:
24 numpyDtype = numpy.dtype([('real','<f4'),('imag','<f4')])
24 numpyDtype = numpy.dtype([('real','<f4'),('imag','<f4')])
25 elif dataTypeCode == 5:
25 elif dataTypeCode == 5:
26 numpyDtype = numpy.dtype([('real','<f8'),('imag','<f8')])
26 numpyDtype = numpy.dtype([('real','<f8'),('imag','<f8')])
27 else:
27 else:
28 raise ValueError, 'dataTypeCode was not defined'
28 raise ValueError, 'dataTypeCode was not defined'
29
29
30 return numpyDtype
30 return numpyDtype
31
31
32 def getDataTypeCode(numpyDtype):
32 def getDataTypeCode(numpyDtype):
33
33
34 if numpyDtype == numpy.dtype([('real','<i1'),('imag','<i1')]):
34 if numpyDtype == numpy.dtype([('real','<i1'),('imag','<i1')]):
35 datatype = 0
35 datatype = 0
36 elif numpyDtype == numpy.dtype([('real','<i2'),('imag','<i2')]):
36 elif numpyDtype == numpy.dtype([('real','<i2'),('imag','<i2')]):
37 datatype = 1
37 datatype = 1
38 elif numpyDtype == numpy.dtype([('real','<i4'),('imag','<i4')]):
38 elif numpyDtype == numpy.dtype([('real','<i4'),('imag','<i4')]):
39 datatype = 2
39 datatype = 2
40 elif numpyDtype == numpy.dtype([('real','<i8'),('imag','<i8')]):
40 elif numpyDtype == numpy.dtype([('real','<i8'),('imag','<i8')]):
41 datatype = 3
41 datatype = 3
42 elif numpyDtype == numpy.dtype([('real','<f4'),('imag','<f4')]):
42 elif numpyDtype == numpy.dtype([('real','<f4'),('imag','<f4')]):
43 datatype = 4
43 datatype = 4
44 elif numpyDtype == numpy.dtype([('real','<f8'),('imag','<f8')]):
44 elif numpyDtype == numpy.dtype([('real','<f8'),('imag','<f8')]):
45 datatype = 5
45 datatype = 5
46 else:
46 else:
47 datatype = None
47 datatype = None
48
48
49 return datatype
49 return datatype
50
50
51 def hildebrand_sekhon(data, navg):
51 def hildebrand_sekhon(data, navg):
52 """
52 """
53 This method is for the objective determination of the noise level in Doppler spectra. This
53 This method is for the objective determination of the noise level in Doppler spectra. This
54 implementation technique is based on the fact that the standard deviation of the spectral
54 implementation technique is based on the fact that the standard deviation of the spectral
55 densities is equal to the mean spectral density for white Gaussian noise
55 densities is equal to the mean spectral density for white Gaussian noise
56
56
57 Inputs:
57 Inputs:
58 Data : heights
58 Data : heights
59 navg : numbers of averages
59 navg : numbers of averages
60
60
61 Return:
61 Return:
62 -1 : any error
62 -1 : any error
63 anoise : noise's level
63 anoise : noise's level
64 """
64 """
65
65
66 sortdata = numpy.sort(data,axis=None)
66 sortdata = numpy.sort(data,axis=None)
67 lenOfData = len(sortdata)
67 lenOfData = len(sortdata)
68 nums_min = lenOfData*0.2
68 nums_min = lenOfData*0.2
69
69
70 if nums_min <= 5:
70 if nums_min <= 5:
71 nums_min = 5
71 nums_min = 5
72
72
73 sump = 0.
73 sump = 0.
74
74
75 sumq = 0.
75 sumq = 0.
76
76
77 j = 0
77 j = 0
78
78
79 cont = 1
79 cont = 1
80
80
81 while((cont==1)and(j<lenOfData)):
81 while((cont==1)and(j<lenOfData)):
82
82
83 sump += sortdata[j]
83 sump += sortdata[j]
84
84
85 sumq += sortdata[j]**2
85 sumq += sortdata[j]**2
86
86
87 if j > nums_min:
87 if j > nums_min:
88 rtest = float(j)/(j-1) + 1.0/navg
88 rtest = float(j)/(j-1) + 1.0/navg
89 if ((sumq*j) > (rtest*sump**2)):
89 if ((sumq*j) > (rtest*sump**2)):
90 j = j - 1
90 j = j - 1
91 sump = sump - sortdata[j]
91 sump = sump - sortdata[j]
92 sumq = sumq - sortdata[j]**2
92 sumq = sumq - sortdata[j]**2
93 cont = 0
93 cont = 0
94
94
95 j += 1
95 j += 1
96
96
97 lnoise = sump /j
97 lnoise = sump /j
98 # stdv = numpy.sqrt((sumq - lnoise**2)/(j - 1))
98 # stdv = numpy.sqrt((sumq - lnoise**2)/(j - 1))
99 return lnoise
99 return lnoise
100
100
101 class Beam:
101 class Beam:
102 def __init__(self):
102 def __init__(self):
103 self.codeList = []
103 self.codeList = []
104 self.azimuthList = []
104 self.azimuthList = []
105 self.zenithList = []
105 self.zenithList = []
106
106
107 class GenericData(object):
107 class GenericData(object):
108
108
109 flagNoData = True
109 flagNoData = True
110
110
111 def __init__(self):
111 def __init__(self):
112
112
113 raise NotImplementedError
113 raise NotImplementedError
114
114
115 def copy(self, inputObj=None):
115 def copy(self, inputObj=None):
116
116
117 if inputObj == None:
117 if inputObj == None:
118 return copy.deepcopy(self)
118 return copy.deepcopy(self)
119
119
120 for key in inputObj.__dict__.keys():
120 for key in inputObj.__dict__.keys():
121
121
122 attribute = inputObj.__dict__[key]
122 attribute = inputObj.__dict__[key]
123
123
124 #If this attribute is a tuple or list
124 #If this attribute is a tuple or list
125 if type(inputObj.__dict__[key]) in (tuple, list):
125 if type(inputObj.__dict__[key]) in (tuple, list):
126 self.__dict__[key] = attribute[:]
126 self.__dict__[key] = attribute[:]
127 continue
127 continue
128
128
129 #If this attribute is another object or instance
129 #If this attribute is another object or instance
130 if hasattr(attribute, '__dict__'):
130 if hasattr(attribute, '__dict__'):
131 self.__dict__[key] = attribute.copy()
131 self.__dict__[key] = attribute.copy()
132 continue
132 continue
133
133
134 self.__dict__[key] = inputObj.__dict__[key]
134 self.__dict__[key] = inputObj.__dict__[key]
135
135
136 def deepcopy(self):
136 def deepcopy(self):
137
137
138 return copy.deepcopy(self)
138 return copy.deepcopy(self)
139
139
140 def isEmpty(self):
140 def isEmpty(self):
141
141
142 return self.flagNoData
142 return self.flagNoData
143
143
144 class JROData(GenericData):
144 class JROData(GenericData):
145
145
146 # m_BasicHeader = BasicHeader()
146 # m_BasicHeader = BasicHeader()
147 # m_ProcessingHeader = ProcessingHeader()
147 # m_ProcessingHeader = ProcessingHeader()
148
148
149 systemHeaderObj = SystemHeader()
149 systemHeaderObj = SystemHeader()
150
150
151 radarControllerHeaderObj = RadarControllerHeader()
151 radarControllerHeaderObj = RadarControllerHeader()
152
152
153 # data = None
153 # data = None
154
154
155 type = None
155 type = None
156
156
157 datatype = None #dtype but in string
157 datatype = None #dtype but in string
158
158
159 # dtype = None
159 # dtype = None
160
160
161 # nChannels = None
161 # nChannels = None
162
162
163 # nHeights = None
163 # nHeights = None
164
164
165 nProfiles = None
165 nProfiles = None
166
166
167 heightList = None
167 heightList = None
168
168
169 channelList = None
169 channelList = None
170
170
171 flagDiscontinuousBlock = False
171 flagDiscontinuousBlock = False
172
172
173 useLocalTime = False
173 useLocalTime = False
174
174
175 utctime = None
175 utctime = None
176
176
177 timeZone = None
177 timeZone = None
178
178
179 dstFlag = None
179 dstFlag = None
180
180
181 errorCount = None
181 errorCount = None
182
182
183 blocksize = None
183 blocksize = None
184
184
185 # nCode = None
185 # nCode = None
186 #
186 #
187 # nBaud = None
187 # nBaud = None
188 #
188 #
189 # code = None
189 # code = None
190
190
191 flagDecodeData = False #asumo q la data no esta decodificada
191 flagDecodeData = False #asumo q la data no esta decodificada
192
192
193 flagDeflipData = False #asumo q la data no esta sin flip
193 flagDeflipData = False #asumo q la data no esta sin flip
194
194
195 flagShiftFFT = False
195 flagShiftFFT = False
196
196
197 # ippSeconds = None
197 # ippSeconds = None
198
198
199 # timeInterval = None
199 # timeInterval = None
200
200
201 nCohInt = None
201 nCohInt = None
202
202
203 # noise = None
203 # noise = None
204
204
205 windowOfFilter = 1
205 windowOfFilter = 1
206
206
207 #Speed of ligth
207 #Speed of ligth
208 C = 3e8
208 C = 3e8
209
209
210 frequency = 49.92e6
210 frequency = 49.92e6
211
211
212 realtime = False
212 realtime = False
213
213
214 beacon_heiIndexList = None
214 beacon_heiIndexList = None
215
215
216 last_block = None
216 last_block = None
217
217
218 blocknow = None
218 blocknow = None
219
219
220 azimuth = None
220 azimuth = None
221
221
222 zenith = None
222 zenith = None
223
223
224 beam = Beam()
224 beam = Beam()
225
225
226 profileIndex = None
226 profileIndex = None
227
227
228 def __init__(self):
228 def __init__(self):
229
229
230 raise NotImplementedError
230 raise NotImplementedError
231
231
232 def getNoise(self):
232 def getNoise(self):
233
233
234 raise NotImplementedError
234 raise NotImplementedError
235
235
236 def getNChannels(self):
236 def getNChannels(self):
237
237
238 return len(self.channelList)
238 return len(self.channelList)
239
239
240 def getChannelIndexList(self):
240 def getChannelIndexList(self):
241
241
242 return range(self.nChannels)
242 return range(self.nChannels)
243
243
244 def getNHeights(self):
244 def getNHeights(self):
245
245
246 return len(self.heightList)
246 return len(self.heightList)
247
247
248 def getHeiRange(self, extrapoints=0):
248 def getHeiRange(self, extrapoints=0):
249
249
250 heis = self.heightList
250 heis = self.heightList
251 # deltah = self.heightList[1] - self.heightList[0]
251 # deltah = self.heightList[1] - self.heightList[0]
252 #
252 #
253 # heis.append(self.heightList[-1])
253 # heis.append(self.heightList[-1])
254
254
255 return heis
255 return heis
256
256
257 def getDeltaH(self):
257 def getDeltaH(self):
258
258
259 delta = self.heightList[1] - self.heightList[0]
259 delta = self.heightList[1] - self.heightList[0]
260
260
261 return delta
261 return delta
262
262
263 def getltctime(self):
263 def getltctime(self):
264
264
265 if self.useLocalTime:
265 if self.useLocalTime:
266 return self.utctime - self.timeZone*60
266 return self.utctime - self.timeZone*60
267
267
268 return self.utctime
268 return self.utctime
269
269
270 def getDatatime(self):
270 def getDatatime(self):
271
271
272 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
272 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
273 return datatimeValue
273 return datatimeValue
274
274
275 def getTimeRange(self):
275 def getTimeRange(self):
276
276
277 datatime = []
277 datatime = []
278
278
279 datatime.append(self.ltctime)
279 datatime.append(self.ltctime)
280 datatime.append(self.ltctime + self.timeInterval+60)
280 datatime.append(self.ltctime + self.timeInterval+60)
281
281
282 datatime = numpy.array(datatime)
282 datatime = numpy.array(datatime)
283
283
284 return datatime
284 return datatime
285
285
286 def getFmaxTimeResponse(self):
286 def getFmaxTimeResponse(self):
287
287
288 period = (10**-6)*self.getDeltaH()/(0.15)
288 period = (10**-6)*self.getDeltaH()/(0.15)
289
289
290 PRF = 1./(period * self.nCohInt)
290 PRF = 1./(period * self.nCohInt)
291
291
292 fmax = PRF
292 fmax = PRF
293
293
294 return fmax
294 return fmax
295
295
296 def getFmax(self):
296 def getFmax(self):
297
297
298 PRF = 1./(self.ippSeconds * self.nCohInt)
298 PRF = 1./(self.ippSeconds * self.nCohInt)
299
299
300 fmax = PRF
300 fmax = PRF
301
301
302 return fmax
302 return fmax
303
303
304 def getVmax(self):
304 def getVmax(self):
305
305
306 _lambda = self.C/self.frequency
306 _lambda = self.C/self.frequency
307
307
308 vmax = self.getFmax() * _lambda
308 vmax = self.getFmax() * _lambda
309
309
310 return vmax
310 return vmax
311
311
312 def get_ippSeconds(self):
312 def get_ippSeconds(self):
313 '''
313 '''
314 '''
314 '''
315 return self.radarControllerHeaderObj.ippSeconds
315 return self.radarControllerHeaderObj.ippSeconds
316
316
317 def set_ippSeconds(self, ippSeconds):
317 def set_ippSeconds(self, ippSeconds):
318 '''
318 '''
319 '''
319 '''
320
320
321 self.radarControllerHeaderObj.ippSeconds = ippSeconds
321 self.radarControllerHeaderObj.ippSeconds = ippSeconds
322
322
323 return
323 return
324
324
325 def get_dtype(self):
325 def get_dtype(self):
326 '''
326 '''
327 '''
327 '''
328 return getNumpyDtype(self.datatype)
328 return getNumpyDtype(self.datatype)
329
329
330 def set_dtype(self, numpyDtype):
330 def set_dtype(self, numpyDtype):
331 '''
331 '''
332 '''
332 '''
333
333
334 self.datatype = getDataTypeCode(numpyDtype)
334 self.datatype = getDataTypeCode(numpyDtype)
335
335
336 def get_code(self):
336 def get_code(self):
337 '''
337 '''
338 '''
338 '''
339 return self.radarControllerHeaderObj.code
339 return self.radarControllerHeaderObj.code
340
340
341 def set_code(self, code):
341 def set_code(self, code):
342 '''
342 '''
343 '''
343 '''
344 self.radarControllerHeaderObj.code = code
344 self.radarControllerHeaderObj.code = code
345
345
346 return
346 return
347
347
348 def get_ncode(self):
348 def get_ncode(self):
349 '''
349 '''
350 '''
350 '''
351 return self.radarControllerHeaderObj.nCode
351 return self.radarControllerHeaderObj.nCode
352
352
353 def set_ncode(self, nCode):
353 def set_ncode(self, nCode):
354 '''
354 '''
355 '''
355 '''
356 self.radarControllerHeaderObj.nCode = nCode
356 self.radarControllerHeaderObj.nCode = nCode
357
357
358 return
358 return
359
359
360 def get_nbaud(self):
360 def get_nbaud(self):
361 '''
361 '''
362 '''
362 '''
363 return self.radarControllerHeaderObj.nBaud
363 return self.radarControllerHeaderObj.nBaud
364
364
365 def set_nbaud(self, nBaud):
365 def set_nbaud(self, nBaud):
366 '''
366 '''
367 '''
367 '''
368 self.radarControllerHeaderObj.nBaud = nBaud
368 self.radarControllerHeaderObj.nBaud = nBaud
369
369
370 return
370 return
371
371
372 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
372 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
373 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
373 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
374 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
374 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
375 #noise = property(getNoise, "I'm the 'nHeights' property.")
375 #noise = property(getNoise, "I'm the 'nHeights' property.")
376 datatime = property(getDatatime, "I'm the 'datatime' property")
376 datatime = property(getDatatime, "I'm the 'datatime' property")
377 ltctime = property(getltctime, "I'm the 'ltctime' property")
377 ltctime = property(getltctime, "I'm the 'ltctime' property")
378 ippSeconds = property(get_ippSeconds, set_ippSeconds)
378 ippSeconds = property(get_ippSeconds, set_ippSeconds)
379 dtype = property(get_dtype, set_dtype)
379 dtype = property(get_dtype, set_dtype)
380 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
380 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
381 code = property(get_code, set_code)
381 code = property(get_code, set_code)
382 nCode = property(get_ncode, set_ncode)
382 nCode = property(get_ncode, set_ncode)
383 nBaud = property(get_nbaud, set_nbaud)
383 nBaud = property(get_nbaud, set_nbaud)
384
384
385 class Voltage(JROData):
385 class Voltage(JROData):
386
386
387 #data es un numpy array de 2 dmensiones (canales, alturas)
387 #data es un numpy array de 2 dmensiones (canales, alturas)
388 data = None
388 data = None
389
389
390 def __init__(self):
390 def __init__(self):
391 '''
391 '''
392 Constructor
392 Constructor
393 '''
393 '''
394
394
395 self.useLocalTime = True
395 self.useLocalTime = True
396
396
397 self.radarControllerHeaderObj = RadarControllerHeader()
397 self.radarControllerHeaderObj = RadarControllerHeader()
398
398
399 self.systemHeaderObj = SystemHeader()
399 self.systemHeaderObj = SystemHeader()
400
400
401 self.type = "Voltage"
401 self.type = "Voltage"
402
402
403 self.data = None
403 self.data = None
404
404
405 # self.dtype = None
405 # self.dtype = None
406
406
407 # self.nChannels = 0
407 # self.nChannels = 0
408
408
409 # self.nHeights = 0
409 # self.nHeights = 0
410
410
411 self.nProfiles = None
411 self.nProfiles = None
412
412
413 self.heightList = None
413 self.heightList = None
414
414
415 self.channelList = None
415 self.channelList = None
416
416
417 # self.channelIndexList = None
417 # self.channelIndexList = None
418
418
419 self.flagNoData = True
419 self.flagNoData = True
420
420
421 self.flagDiscontinuousBlock = False
421 self.flagDiscontinuousBlock = False
422
422
423 self.utctime = None
423 self.utctime = None
424
424
425 self.timeZone = None
425 self.timeZone = None
426
426
427 self.dstFlag = None
427 self.dstFlag = None
428
428
429 self.errorCount = None
429 self.errorCount = None
430
430
431 self.nCohInt = None
431 self.nCohInt = None
432
432
433 self.blocksize = None
433 self.blocksize = None
434
434
435 self.flagDecodeData = False #asumo q la data no esta decodificada
435 self.flagDecodeData = False #asumo q la data no esta decodificada
436
436
437 self.flagDeflipData = False #asumo q la data no esta sin flip
437 self.flagDeflipData = False #asumo q la data no esta sin flip
438
438
439 self.flagShiftFFT = False
439 self.flagShiftFFT = False
440
440
441 self.flagDataAsBlock = False #Asumo que la data es leida perfil a perfil
441 self.flagDataAsBlock = False #Asumo que la data es leida perfil a perfil
442
442
443 self.profileIndex = 0
443 self.profileIndex = 0
444
444
445 def getNoisebyHildebrand(self, channel = None):
445 def getNoisebyHildebrand(self, channel = None):
446 """
446 """
447 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
447 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
448
448
449 Return:
449 Return:
450 noiselevel
450 noiselevel
451 """
451 """
452
452
453 if channel != None:
453 if channel != None:
454 data = self.data[channel]
454 data = self.data[channel]
455 nChannels = 1
455 nChannels = 1
456 else:
456 else:
457 data = self.data
457 data = self.data
458 nChannels = self.nChannels
458 nChannels = self.nChannels
459
459
460 noise = numpy.zeros(nChannels)
460 noise = numpy.zeros(nChannels)
461 power = data * numpy.conjugate(data)
461 power = data * numpy.conjugate(data)
462
462
463 for thisChannel in range(nChannels):
463 for thisChannel in range(nChannels):
464 if nChannels == 1:
464 if nChannels == 1:
465 daux = power[:].real
465 daux = power[:].real
466 else:
466 else:
467 daux = power[thisChannel,:].real
467 daux = power[thisChannel,:].real
468 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
468 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
469
469
470 return noise
470 return noise
471
471
472 def getNoise(self, type = 1, channel = None):
472 def getNoise(self, type = 1, channel = None):
473
473
474 if type == 1:
474 if type == 1:
475 noise = self.getNoisebyHildebrand(channel)
475 noise = self.getNoisebyHildebrand(channel)
476
476
477 return noise
477 return noise
478
478
479 def getPower(self, channel = None):
479 def getPower(self, channel = None):
480
480
481 if channel != None:
481 if channel != None:
482 data = self.data[channel]
482 data = self.data[channel]
483 else:
483 else:
484 data = self.data
484 data = self.data
485
485
486 power = data * numpy.conjugate(data)
486 power = data * numpy.conjugate(data)
487
487
488 return 10*numpy.log10(power.real)
488 return 10*numpy.log10(power.real)
489
489
490 def getTimeInterval(self):
490 def getTimeInterval(self):
491
491
492 timeInterval = self.ippSeconds * self.nCohInt
492 timeInterval = self.ippSeconds * self.nCohInt
493
493
494 return timeInterval
494 return timeInterval
495
495
496 noise = property(getNoise, "I'm the 'nHeights' property.")
496 noise = property(getNoise, "I'm the 'nHeights' property.")
497 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
497 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
498
498
499 class Spectra(JROData):
499 class Spectra(JROData):
500
500
501 #data es un numpy array de 2 dmensiones (canales, perfiles, alturas)
501 #data es un numpy array de 2 dmensiones (canales, perfiles, alturas)
502 data_spc = None
502 data_spc = None
503
503
504 #data es un numpy array de 2 dmensiones (canales, pares, alturas)
504 #data es un numpy array de 2 dmensiones (canales, pares, alturas)
505 data_cspc = None
505 data_cspc = None
506
506
507 #data es un numpy array de 2 dmensiones (canales, alturas)
507 #data es un numpy array de 2 dmensiones (canales, alturas)
508 data_dc = None
508 data_dc = None
509
509
510 nFFTPoints = None
510 nFFTPoints = None
511
511
512 # nPairs = None
512 # nPairs = None
513
513
514 pairsList = None
514 pairsList = None
515
515
516 nIncohInt = None
516 nIncohInt = None
517
517
518 wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia
518 wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia
519
519
520 nCohInt = None #se requiere para determinar el valor de timeInterval
520 nCohInt = None #se requiere para determinar el valor de timeInterval
521
521
522 ippFactor = None
522 ippFactor = None
523
523
524 profileIndex = 0
524 profileIndex = 0
525
525
526 plotting = "spectra"
526 plotting = "spectra"
527
527
528 def __init__(self):
528 def __init__(self):
529 '''
529 '''
530 Constructor
530 Constructor
531 '''
531 '''
532
532
533 self.useLocalTime = True
533 self.useLocalTime = True
534
534
535 self.radarControllerHeaderObj = RadarControllerHeader()
535 self.radarControllerHeaderObj = RadarControllerHeader()
536
536
537 self.systemHeaderObj = SystemHeader()
537 self.systemHeaderObj = SystemHeader()
538
538
539 self.type = "Spectra"
539 self.type = "Spectra"
540
540
541 # self.data = None
541 # self.data = None
542
542
543 # self.dtype = None
543 # self.dtype = None
544
544
545 # self.nChannels = 0
545 # self.nChannels = 0
546
546
547 # self.nHeights = 0
547 # self.nHeights = 0
548
548
549 self.nProfiles = None
549 self.nProfiles = None
550
550
551 self.heightList = None
551 self.heightList = None
552
552
553 self.channelList = None
553 self.channelList = None
554
554
555 # self.channelIndexList = None
555 # self.channelIndexList = None
556
556
557 self.pairsList = None
557 self.pairsList = None
558
558
559 self.flagNoData = True
559 self.flagNoData = True
560
560
561 self.flagDiscontinuousBlock = False
561 self.flagDiscontinuousBlock = False
562
562
563 self.utctime = None
563 self.utctime = None
564
564
565 self.nCohInt = None
565 self.nCohInt = None
566
566
567 self.nIncohInt = None
567 self.nIncohInt = None
568
568
569 self.blocksize = None
569 self.blocksize = None
570
570
571 self.nFFTPoints = None
571 self.nFFTPoints = None
572
572
573 self.wavelength = None
573 self.wavelength = None
574
574
575 self.flagDecodeData = False #asumo q la data no esta decodificada
575 self.flagDecodeData = False #asumo q la data no esta decodificada
576
576
577 self.flagDeflipData = False #asumo q la data no esta sin flip
577 self.flagDeflipData = False #asumo q la data no esta sin flip
578
578
579 self.flagShiftFFT = False
579 self.flagShiftFFT = False
580
580
581 self.ippFactor = 1
581 self.ippFactor = 1
582
582
583 #self.noise = None
583 #self.noise = None
584
584
585 self.beacon_heiIndexList = []
585 self.beacon_heiIndexList = []
586
586
587 self.noise_estimation = None
587 self.noise_estimation = None
588
588
589
589
590 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
590 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
591 """
591 """
592 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
592 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
593
593
594 Return:
594 Return:
595 noiselevel
595 noiselevel
596 """
596 """
597
597
598 noise = numpy.zeros(self.nChannels)
598 noise = numpy.zeros(self.nChannels)
599
599
600 for channel in range(self.nChannels):
600 for channel in range(self.nChannels):
601 daux = self.data_spc[channel,xmin_index:xmax_index,ymin_index:ymax_index]
601 daux = self.data_spc[channel,xmin_index:xmax_index,ymin_index:ymax_index]
602 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
602 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
603
603
604 return noise
604 return noise
605
605
606 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
606 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
607
607
608 if self.noise_estimation is not None:
608 if self.noise_estimation is not None:
609 return self.noise_estimation #this was estimated by getNoise Operation defined in jroproc_spectra.py
609 return self.noise_estimation #this was estimated by getNoise Operation defined in jroproc_spectra.py
610 else:
610 else:
611 noise = self.getNoisebyHildebrand(xmin_index, xmax_index, ymin_index, ymax_index)
611 noise = self.getNoisebyHildebrand(xmin_index, xmax_index, ymin_index, ymax_index)
612 return noise
612 return noise
613
613
614 def getFreqRangeTimeResponse(self, extrapoints=0):
614 def getFreqRangeTimeResponse(self, extrapoints=0):
615
615
616 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints*self.ippFactor)
616 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints*self.ippFactor)
617 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
617 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
618
618
619 return freqrange
619 return freqrange
620
620
621 def getAcfRange(self, extrapoints=0):
621 def getAcfRange(self, extrapoints=0):
622
622
623 deltafreq = 10./(self.getFmax() / (self.nFFTPoints*self.ippFactor))
623 deltafreq = 10./(self.getFmax() / (self.nFFTPoints*self.ippFactor))
624 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
624 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
625
625
626 return freqrange
626 return freqrange
627
627
628 def getFreqRange(self, extrapoints=0):
628 def getFreqRange(self, extrapoints=0):
629
629
630 deltafreq = self.getFmax() / (self.nFFTPoints*self.ippFactor)
630 deltafreq = self.getFmax() / (self.nFFTPoints*self.ippFactor)
631 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
631 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
632
632
633 return freqrange
633 return freqrange
634
634
635 def getVelRange(self, extrapoints=0):
635 def getVelRange(self, extrapoints=0):
636
636
637 deltav = self.getVmax() / (self.nFFTPoints*self.ippFactor)
637 deltav = self.getVmax() / (self.nFFTPoints*self.ippFactor)
638 velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltav/2
638 velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltav/2
639
639
640 return velrange
640 return velrange
641
641
642 def getNPairs(self):
642 def getNPairs(self):
643
643
644 return len(self.pairsList)
644 return len(self.pairsList)
645
645
646 def getPairsIndexList(self):
646 def getPairsIndexList(self):
647
647
648 return range(self.nPairs)
648 return range(self.nPairs)
649
649
650 def getNormFactor(self):
650 def getNormFactor(self):
651
651
652 pwcode = 1
652 pwcode = 1
653
653
654 if self.flagDecodeData:
654 if self.flagDecodeData:
655 pwcode = numpy.sum(self.code[0]**2)
655 pwcode = numpy.sum(self.code[0]**2)
656 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
656 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
657 normFactor = self.nProfiles*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
657 normFactor = self.nProfiles*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
658
658
659 return normFactor
659 return normFactor
660
660
661 def getFlagCspc(self):
661 def getFlagCspc(self):
662
662
663 if self.data_cspc is None:
663 if self.data_cspc is None:
664 return True
664 return True
665
665
666 return False
666 return False
667
667
668 def getFlagDc(self):
668 def getFlagDc(self):
669
669
670 if self.data_dc is None:
670 if self.data_dc is None:
671 return True
671 return True
672
672
673 return False
673 return False
674
674
675 def getTimeInterval(self):
675 def getTimeInterval(self):
676
676
677 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles
677 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles
678
678
679 return timeInterval
679 return timeInterval
680
680
681 def setValue(self, value):
681 def setValue(self, value):
682
682
683 print "This property should not be initialized"
683 print "This property should not be initialized"
684
684
685 return
685 return
686
686
687 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
687 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
688 pairsIndexList = property(getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
688 pairsIndexList = property(getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
689 normFactor = property(getNormFactor, setValue, "I'm the 'getNormFactor' property.")
689 normFactor = property(getNormFactor, setValue, "I'm the 'getNormFactor' property.")
690 flag_cspc = property(getFlagCspc, setValue)
690 flag_cspc = property(getFlagCspc, setValue)
691 flag_dc = property(getFlagDc, setValue)
691 flag_dc = property(getFlagDc, setValue)
692 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
692 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
693 timeInterval = property(getTimeInterval, setValue, "I'm the 'timeInterval' property")
693 timeInterval = property(getTimeInterval, setValue, "I'm the 'timeInterval' property")
694
694
695 class SpectraHeis(Spectra):
695 class SpectraHeis(Spectra):
696
696
697 data_spc = None
697 data_spc = None
698
698
699 data_cspc = None
699 data_cspc = None
700
700
701 data_dc = None
701 data_dc = None
702
702
703 nFFTPoints = None
703 nFFTPoints = None
704
704
705 # nPairs = None
705 # nPairs = None
706
706
707 pairsList = None
707 pairsList = None
708
708
709 nCohInt = None
709 nCohInt = None
710
710
711 nIncohInt = None
711 nIncohInt = None
712
712
713 def __init__(self):
713 def __init__(self):
714
714
715 self.radarControllerHeaderObj = RadarControllerHeader()
715 self.radarControllerHeaderObj = RadarControllerHeader()
716
716
717 self.systemHeaderObj = SystemHeader()
717 self.systemHeaderObj = SystemHeader()
718
718
719 self.type = "SpectraHeis"
719 self.type = "SpectraHeis"
720
720
721 # self.dtype = None
721 # self.dtype = None
722
722
723 # self.nChannels = 0
723 # self.nChannels = 0
724
724
725 # self.nHeights = 0
725 # self.nHeights = 0
726
726
727 self.nProfiles = None
727 self.nProfiles = None
728
728
729 self.heightList = None
729 self.heightList = None
730
730
731 self.channelList = None
731 self.channelList = None
732
732
733 # self.channelIndexList = None
733 # self.channelIndexList = None
734
734
735 self.flagNoData = True
735 self.flagNoData = True
736
736
737 self.flagDiscontinuousBlock = False
737 self.flagDiscontinuousBlock = False
738
738
739 # self.nPairs = 0
739 # self.nPairs = 0
740
740
741 self.utctime = None
741 self.utctime = None
742
742
743 self.blocksize = None
743 self.blocksize = None
744
744
745 self.profileIndex = 0
745 self.profileIndex = 0
746
746
747 self.nCohInt = 1
747 self.nCohInt = 1
748
748
749 self.nIncohInt = 1
749 self.nIncohInt = 1
750
750
751 def getNormFactor(self):
751 def getNormFactor(self):
752 pwcode = 1
752 pwcode = 1
753 if self.flagDecodeData:
753 if self.flagDecodeData:
754 pwcode = numpy.sum(self.code[0]**2)
754 pwcode = numpy.sum(self.code[0]**2)
755
755
756 normFactor = self.nIncohInt*self.nCohInt*pwcode
756 normFactor = self.nIncohInt*self.nCohInt*pwcode
757
757
758 return normFactor
758 return normFactor
759
759
760 def getTimeInterval(self):
760 def getTimeInterval(self):
761
761
762 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
762 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
763
763
764 return timeInterval
764 return timeInterval
765
765
766 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
766 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
767 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
767 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
768
768
769 class Fits(JROData):
769 class Fits(JROData):
770
770
771 heightList = None
771 heightList = None
772
772
773 channelList = None
773 channelList = None
774
774
775 flagNoData = True
775 flagNoData = True
776
776
777 flagDiscontinuousBlock = False
777 flagDiscontinuousBlock = False
778
778
779 useLocalTime = False
779 useLocalTime = False
780
780
781 utctime = None
781 utctime = None
782
782
783 timeZone = None
783 timeZone = None
784
784
785 # ippSeconds = None
785 # ippSeconds = None
786
786
787 # timeInterval = None
787 # timeInterval = None
788
788
789 nCohInt = None
789 nCohInt = None
790
790
791 nIncohInt = None
791 nIncohInt = None
792
792
793 noise = None
793 noise = None
794
794
795 windowOfFilter = 1
795 windowOfFilter = 1
796
796
797 #Speed of ligth
797 #Speed of ligth
798 C = 3e8
798 C = 3e8
799
799
800 frequency = 49.92e6
800 frequency = 49.92e6
801
801
802 realtime = False
802 realtime = False
803
803
804
804
805 def __init__(self):
805 def __init__(self):
806
806
807 self.type = "Fits"
807 self.type = "Fits"
808
808
809 self.nProfiles = None
809 self.nProfiles = None
810
810
811 self.heightList = None
811 self.heightList = None
812
812
813 self.channelList = None
813 self.channelList = None
814
814
815 # self.channelIndexList = None
815 # self.channelIndexList = None
816
816
817 self.flagNoData = True
817 self.flagNoData = True
818
818
819 self.utctime = None
819 self.utctime = None
820
820
821 self.nCohInt = 1
821 self.nCohInt = 1
822
822
823 self.nIncohInt = 1
823 self.nIncohInt = 1
824
824
825 self.useLocalTime = True
825 self.useLocalTime = True
826
826
827 self.profileIndex = 0
827 self.profileIndex = 0
828
828
829 # self.utctime = None
829 # self.utctime = None
830 # self.timeZone = None
830 # self.timeZone = None
831 # self.ltctime = None
831 # self.ltctime = None
832 # self.timeInterval = None
832 # self.timeInterval = None
833 # self.header = None
833 # self.header = None
834 # self.data_header = None
834 # self.data_header = None
835 # self.data = None
835 # self.data = None
836 # self.datatime = None
836 # self.datatime = None
837 # self.flagNoData = False
837 # self.flagNoData = False
838 # self.expName = ''
838 # self.expName = ''
839 # self.nChannels = None
839 # self.nChannels = None
840 # self.nSamples = None
840 # self.nSamples = None
841 # self.dataBlocksPerFile = None
841 # self.dataBlocksPerFile = None
842 # self.comments = ''
842 # self.comments = ''
843 #
843 #
844
844
845
845
846 def getltctime(self):
846 def getltctime(self):
847
847
848 if self.useLocalTime:
848 if self.useLocalTime:
849 return self.utctime - self.timeZone*60
849 return self.utctime - self.timeZone*60
850
850
851 return self.utctime
851 return self.utctime
852
852
853 def getDatatime(self):
853 def getDatatime(self):
854
854
855 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
855 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
856 return datatime
856 return datatime
857
857
858 def getTimeRange(self):
858 def getTimeRange(self):
859
859
860 datatime = []
860 datatime = []
861
861
862 datatime.append(self.ltctime)
862 datatime.append(self.ltctime)
863 datatime.append(self.ltctime + self.timeInterval)
863 datatime.append(self.ltctime + self.timeInterval)
864
864
865 datatime = numpy.array(datatime)
865 datatime = numpy.array(datatime)
866
866
867 return datatime
867 return datatime
868
868
869 def getHeiRange(self):
869 def getHeiRange(self):
870
870
871 heis = self.heightList
871 heis = self.heightList
872
872
873 return heis
873 return heis
874
874
875 def getNHeights(self):
875 def getNHeights(self):
876
876
877 return len(self.heightList)
877 return len(self.heightList)
878
878
879 def getNChannels(self):
879 def getNChannels(self):
880
880
881 return len(self.channelList)
881 return len(self.channelList)
882
882
883 def getChannelIndexList(self):
883 def getChannelIndexList(self):
884
884
885 return range(self.nChannels)
885 return range(self.nChannels)
886
886
887 def getNoise(self, type = 1):
887 def getNoise(self, type = 1):
888
888
889 #noise = numpy.zeros(self.nChannels)
889 #noise = numpy.zeros(self.nChannels)
890
890
891 if type == 1:
891 if type == 1:
892 noise = self.getNoisebyHildebrand()
892 noise = self.getNoisebyHildebrand()
893
893
894 if type == 2:
894 if type == 2:
895 noise = self.getNoisebySort()
895 noise = self.getNoisebySort()
896
896
897 if type == 3:
897 if type == 3:
898 noise = self.getNoisebyWindow()
898 noise = self.getNoisebyWindow()
899
899
900 return noise
900 return noise
901
901
902 def getTimeInterval(self):
902 def getTimeInterval(self):
903
903
904 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
904 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
905
905
906 return timeInterval
906 return timeInterval
907
907
908 datatime = property(getDatatime, "I'm the 'datatime' property")
908 datatime = property(getDatatime, "I'm the 'datatime' property")
909 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
909 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
910 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
910 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
911 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
911 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
912 noise = property(getNoise, "I'm the 'nHeights' property.")
912 noise = property(getNoise, "I'm the 'nHeights' property.")
913
913
914 ltctime = property(getltctime, "I'm the 'ltctime' property")
914 ltctime = property(getltctime, "I'm the 'ltctime' property")
915 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
915 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
916
916
917 class Correlation(JROData):
917 class Correlation(JROData):
918
918
919 noise = None
919 noise = None
920
920
921 SNR = None
921 SNR = None
922
922
923 pairsAutoCorr = None #Pairs of Autocorrelation
923 pairsAutoCorr = None #Pairs of Autocorrelation
924
924
925 #--------------------------------------------------
925 #--------------------------------------------------
926
926
927 data_corr = None
927 data_corr = None
928
928
929 data_volt = None
929 data_volt = None
930
930
931 lagT = None # each element value is a profileIndex
931 lagT = None # each element value is a profileIndex
932
932
933 lagR = None # each element value is in km
933 lagR = None # each element value is in km
934
934
935 pairsList = None
935 pairsList = None
936
936
937 calculateVelocity = None
937 calculateVelocity = None
938
938
939 nPoints = None
939 nPoints = None
940
940
941 nAvg = None
941 nAvg = None
942
942
943 bufferSize = None
943 bufferSize = None
944
944
945 def __init__(self):
945 def __init__(self):
946 '''
946 '''
947 Constructor
947 Constructor
948 '''
948 '''
949 self.radarControllerHeaderObj = RadarControllerHeader()
949 self.radarControllerHeaderObj = RadarControllerHeader()
950
950
951 self.systemHeaderObj = SystemHeader()
951 self.systemHeaderObj = SystemHeader()
952
952
953 self.type = "Correlation"
953 self.type = "Correlation"
954
954
955 self.data = None
955 self.data = None
956
956
957 self.dtype = None
957 self.dtype = None
958
958
959 self.nProfiles = None
959 self.nProfiles = None
960
960
961 self.heightList = None
961 self.heightList = None
962
962
963 self.channelList = None
963 self.channelList = None
964
964
965 self.flagNoData = True
965 self.flagNoData = True
966
966
967 self.flagDiscontinuousBlock = False
967 self.flagDiscontinuousBlock = False
968
968
969 self.utctime = None
969 self.utctime = None
970
970
971 self.timeZone = None
971 self.timeZone = None
972
972
973 self.dstFlag = None
973 self.dstFlag = None
974
974
975 self.errorCount = None
975 self.errorCount = None
976
976
977 self.blocksize = None
977 self.blocksize = None
978
978
979 self.flagDecodeData = False #asumo q la data no esta decodificada
979 self.flagDecodeData = False #asumo q la data no esta decodificada
980
980
981 self.flagDeflipData = False #asumo q la data no esta sin flip
981 self.flagDeflipData = False #asumo q la data no esta sin flip
982
982
983 self.pairsList = None
983 self.pairsList = None
984
984
985 self.nPoints = None
985 self.nPoints = None
986
986
987 def getLagTRange(self, extrapoints=0):
987 def getLagTRange(self, extrapoints=0):
988
988
989 lagTRange = self.lagT
989 lagTRange = self.lagT
990 diff = lagTRange[1] - lagTRange[0]
990 diff = lagTRange[1] - lagTRange[0]
991 extra = numpy.arange(1,extrapoints + 1)*diff + lagTRange[-1]
991 extra = numpy.arange(1,extrapoints + 1)*diff + lagTRange[-1]
992 lagTRange = numpy.hstack((lagTRange, extra))
992 lagTRange = numpy.hstack((lagTRange, extra))
993
993
994 return lagTRange
994 return lagTRange
995
995
996 def getLagRRange(self, extrapoints=0):
996 def getLagRRange(self, extrapoints=0):
997
997
998 return self.lagR
998 return self.lagR
999
999
1000 def getPairsList(self):
1000 def getPairsList(self):
1001
1001
1002 return self.pairsList
1002 return self.pairsList
1003
1003
1004 def getCalculateVelocity(self):
1004 def getCalculateVelocity(self):
1005
1005
1006 return self.calculateVelocity
1006 return self.calculateVelocity
1007
1007
1008 def getNPoints(self):
1008 def getNPoints(self):
1009
1009
1010 return self.nPoints
1010 return self.nPoints
1011
1011
1012 def getNAvg(self):
1012 def getNAvg(self):
1013
1013
1014 return self.nAvg
1014 return self.nAvg
1015
1015
1016 def getBufferSize(self):
1016 def getBufferSize(self):
1017
1017
1018 return self.bufferSize
1018 return self.bufferSize
1019
1019
1020 def getPairsAutoCorr(self):
1020 def getPairsAutoCorr(self):
1021 pairsList = self.pairsList
1021 pairsList = self.pairsList
1022 pairsAutoCorr = numpy.zeros(self.nChannels, dtype = 'int')*numpy.nan
1022 pairsAutoCorr = numpy.zeros(self.nChannels, dtype = 'int')*numpy.nan
1023
1023
1024 for l in range(len(pairsList)):
1024 for l in range(len(pairsList)):
1025 firstChannel = pairsList[l][0]
1025 firstChannel = pairsList[l][0]
1026 secondChannel = pairsList[l][1]
1026 secondChannel = pairsList[l][1]
1027
1027
1028 #Obteniendo pares de Autocorrelacion
1028 #Obteniendo pares de Autocorrelacion
1029 if firstChannel == secondChannel:
1029 if firstChannel == secondChannel:
1030 pairsAutoCorr[firstChannel] = int(l)
1030 pairsAutoCorr[firstChannel] = int(l)
1031
1031
1032 pairsAutoCorr = pairsAutoCorr.astype(int)
1032 pairsAutoCorr = pairsAutoCorr.astype(int)
1033
1033
1034 return pairsAutoCorr
1034 return pairsAutoCorr
1035
1035
1036 def getNoise(self, mode = 2):
1036 def getNoise(self, mode = 2):
1037
1037
1038 indR = numpy.where(self.lagR == 0)[0][0]
1038 indR = numpy.where(self.lagR == 0)[0][0]
1039 indT = numpy.where(self.lagT == 0)[0][0]
1039 indT = numpy.where(self.lagT == 0)[0][0]
1040
1040
1041 jspectra0 = self.data_corr[:,:,indR,:]
1041 jspectra0 = self.data_corr[:,:,indR,:]
1042 jspectra = copy.copy(jspectra0)
1042 jspectra = copy.copy(jspectra0)
1043
1043
1044 num_chan = jspectra.shape[0]
1044 num_chan = jspectra.shape[0]
1045 num_hei = jspectra.shape[2]
1045 num_hei = jspectra.shape[2]
1046
1046
1047 freq_dc = jspectra.shape[1]/2
1047 freq_dc = jspectra.shape[1]/2
1048 ind_vel = numpy.array([-2,-1,1,2]) + freq_dc
1048 ind_vel = numpy.array([-2,-1,1,2]) + freq_dc
1049
1049
1050 if ind_vel[0]<0:
1050 if ind_vel[0]<0:
1051 ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof
1051 ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof
1052
1052
1053 if mode == 1:
1053 if mode == 1:
1054 jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION
1054 jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION
1055
1055
1056 if mode == 2:
1056 if mode == 2:
1057
1057
1058 vel = numpy.array([-2,-1,1,2])
1058 vel = numpy.array([-2,-1,1,2])
1059 xx = numpy.zeros([4,4])
1059 xx = numpy.zeros([4,4])
1060
1060
1061 for fil in range(4):
1061 for fil in range(4):
1062 xx[fil,:] = vel[fil]**numpy.asarray(range(4))
1062 xx[fil,:] = vel[fil]**numpy.asarray(range(4))
1063
1063
1064 xx_inv = numpy.linalg.inv(xx)
1064 xx_inv = numpy.linalg.inv(xx)
1065 xx_aux = xx_inv[0,:]
1065 xx_aux = xx_inv[0,:]
1066
1066
1067 for ich in range(num_chan):
1067 for ich in range(num_chan):
1068 yy = jspectra[ich,ind_vel,:]
1068 yy = jspectra[ich,ind_vel,:]
1069 jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy)
1069 jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy)
1070
1070
1071 junkid = jspectra[ich,freq_dc,:]<=0
1071 junkid = jspectra[ich,freq_dc,:]<=0
1072 cjunkid = sum(junkid)
1072 cjunkid = sum(junkid)
1073
1073
1074 if cjunkid.any():
1074 if cjunkid.any():
1075 jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2
1075 jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2
1076
1076
1077 noise = jspectra0[:,freq_dc,:] - jspectra[:,freq_dc,:]
1077 noise = jspectra0[:,freq_dc,:] - jspectra[:,freq_dc,:]
1078
1078
1079 return noise
1079 return noise
1080
1080
1081 def getTimeInterval(self):
1081 def getTimeInterval(self):
1082
1082
1083 timeInterval = self.ippSeconds * self.nCohInt * self.nPoints
1083 timeInterval = self.ippSeconds * self.nCohInt * self.nPoints
1084
1084
1085 return timeInterval
1085 return timeInterval
1086
1086
1087 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1087 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1088 # pairsList = property(getPairsList, "I'm the 'pairsList' property.")
1088 # pairsList = property(getPairsList, "I'm the 'pairsList' property.")
1089 # nPoints = property(getNPoints, "I'm the 'nPoints' property.")
1089 # nPoints = property(getNPoints, "I'm the 'nPoints' property.")
1090 calculateVelocity = property(getCalculateVelocity, "I'm the 'calculateVelocity' property.")
1090 calculateVelocity = property(getCalculateVelocity, "I'm the 'calculateVelocity' property.")
1091 nAvg = property(getNAvg, "I'm the 'nAvg' property.")
1091 nAvg = property(getNAvg, "I'm the 'nAvg' property.")
1092 bufferSize = property(getBufferSize, "I'm the 'bufferSize' property.")
1092 bufferSize = property(getBufferSize, "I'm the 'bufferSize' property.")
1093
1093
1094
1094
1095 class Parameters(JROData):
1095 class Parameters(JROData):
1096
1096
1097 #Information from previous data
1097 #Information from previous data
1098
1098
1099 inputUnit = None #Type of data to be processed
1099 inputUnit = None #Type of data to be processed
1100
1100
1101 operation = None #Type of operation to parametrize
1101 operation = None #Type of operation to parametrize
1102
1102
1103 normFactor = None #Normalization Factor
1103 normFactor = None #Normalization Factor
1104
1104
1105 groupList = None #List of Pairs, Groups, etc
1105 groupList = None #List of Pairs, Groups, etc
1106
1106
1107 #Parameters
1107 #Parameters
1108
1108
1109 data_param = None #Parameters obtained
1109 data_param = None #Parameters obtained
1110
1110
1111 data_pre = None #Data Pre Parametrization
1111 data_pre = None #Data Pre Parametrization
1112
1112
1113 data_SNR = None #Signal to Noise Ratio
1113 data_SNR = None #Signal to Noise Ratio
1114
1114
1115 # heightRange = None #Heights
1115 # heightRange = None #Heights
1116
1116
1117 abscissaList = None #Abscissa, can be velocities, lags or time
1117 abscissaList = None #Abscissa, can be velocities, lags or time
1118
1118
1119 noise = None #Noise Potency
1119 noise = None #Noise Potency
1120
1120
1121 utctimeInit = None #Initial UTC time
1121 utctimeInit = None #Initial UTC time
1122
1122
1123 paramInterval = None #Time interval to calculate Parameters in seconds
1123 paramInterval = None #Time interval to calculate Parameters in seconds
1124
1124
1125 useLocalTime = True
1125 useLocalTime = True
1126
1126
1127 #Fitting
1127 #Fitting
1128
1128
1129 data_error = None #Error of the estimation
1129 data_error = None #Error of the estimation
1130
1130
1131 constants = None
1131 constants = None
1132
1132
1133 library = None
1133 library = None
1134
1134
1135 #Output signal
1135 #Output signal
1136
1136
1137 outputInterval = None #Time interval to calculate output signal in seconds
1137 outputInterval = None #Time interval to calculate output signal in seconds
1138
1138
1139 data_output = None #Out signal
1139 data_output = None #Out signal
1140
1140
1141
1141
1142
1142
1143 def __init__(self):
1143 def __init__(self):
1144 '''
1144 '''
1145 Constructor
1145 Constructor
1146 '''
1146 '''
1147 self.radarControllerHeaderObj = RadarControllerHeader()
1147 self.radarControllerHeaderObj = RadarControllerHeader()
1148
1148
1149 self.systemHeaderObj = SystemHeader()
1149 self.systemHeaderObj = SystemHeader()
1150
1150
1151 self.type = "Parameters"
1151 self.type = "Parameters"
1152
1152
1153 def getTimeRange1(self):
1153 def getTimeRange1(self, interval):
1154
1154
1155 datatime = []
1155 datatime = []
1156
1156
1157 if self.useLocalTime:
1157 if self.useLocalTime:
1158 time1 = self.utctimeInit - self.timeZone*60
1158 time1 = self.utctimeInit - self.timeZone*60
1159 else:
1159 else:
1160 time1 = self.utctimeInit
1160 time1 = self.utctimeInit
1161
1161
1162 # datatime.append(self.utctimeInit)
1162 # datatime.append(self.utctimeInit)
1163 # datatime.append(self.utctimeInit + self.outputInterval)
1163 # datatime.append(self.utctimeInit + self.outputInterval)
1164 datatime.append(time1)
1164 datatime.append(time1)
1165 datatime.append(time1 + self.outputInterval)
1165 datatime.append(time1 + interval)
1166
1166
1167 datatime = numpy.array(datatime)
1167 datatime = numpy.array(datatime)
1168
1168
1169 return datatime
1169 return datatime
@@ -1,1373 +1,1364
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4
4
5 from figure import Figure, isRealtime
5 from figure import Figure, isRealtime
6 from plotting_codes import *
6 from plotting_codes import *
7
7
8 class MomentsPlot(Figure):
8 class MomentsPlot(Figure):
9
9
10 isConfig = None
10 isConfig = None
11 __nsubplots = None
11 __nsubplots = None
12
12
13 WIDTHPROF = None
13 WIDTHPROF = None
14 HEIGHTPROF = None
14 HEIGHTPROF = None
15 PREFIX = 'prm'
15 PREFIX = 'prm'
16
16
17 def __init__(self):
17 def __init__(self):
18
18
19 self.isConfig = False
19 self.isConfig = False
20 self.__nsubplots = 1
20 self.__nsubplots = 1
21
21
22 self.WIDTH = 280
22 self.WIDTH = 280
23 self.HEIGHT = 250
23 self.HEIGHT = 250
24 self.WIDTHPROF = 120
24 self.WIDTHPROF = 120
25 self.HEIGHTPROF = 0
25 self.HEIGHTPROF = 0
26 self.counter_imagwr = 0
26 self.counter_imagwr = 0
27
27
28 self.PLOT_CODE = MOMENTS_CODE
28 self.PLOT_CODE = MOMENTS_CODE
29
29
30 self.FTP_WEI = None
30 self.FTP_WEI = None
31 self.EXP_CODE = None
31 self.EXP_CODE = None
32 self.SUB_EXP_CODE = None
32 self.SUB_EXP_CODE = None
33 self.PLOT_POS = None
33 self.PLOT_POS = None
34
34
35 def getSubplots(self):
35 def getSubplots(self):
36
36
37 ncol = int(numpy.sqrt(self.nplots)+0.9)
37 ncol = int(numpy.sqrt(self.nplots)+0.9)
38 nrow = int(self.nplots*1./ncol + 0.9)
38 nrow = int(self.nplots*1./ncol + 0.9)
39
39
40 return nrow, ncol
40 return nrow, ncol
41
41
42 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
42 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
43
43
44 self.__showprofile = showprofile
44 self.__showprofile = showprofile
45 self.nplots = nplots
45 self.nplots = nplots
46
46
47 ncolspan = 1
47 ncolspan = 1
48 colspan = 1
48 colspan = 1
49 if showprofile:
49 if showprofile:
50 ncolspan = 3
50 ncolspan = 3
51 colspan = 2
51 colspan = 2
52 self.__nsubplots = 2
52 self.__nsubplots = 2
53
53
54 self.createFigure(id = id,
54 self.createFigure(id = id,
55 wintitle = wintitle,
55 wintitle = wintitle,
56 widthplot = self.WIDTH + self.WIDTHPROF,
56 widthplot = self.WIDTH + self.WIDTHPROF,
57 heightplot = self.HEIGHT + self.HEIGHTPROF,
57 heightplot = self.HEIGHT + self.HEIGHTPROF,
58 show=show)
58 show=show)
59
59
60 nrow, ncol = self.getSubplots()
60 nrow, ncol = self.getSubplots()
61
61
62 counter = 0
62 counter = 0
63 for y in range(nrow):
63 for y in range(nrow):
64 for x in range(ncol):
64 for x in range(ncol):
65
65
66 if counter >= self.nplots:
66 if counter >= self.nplots:
67 break
67 break
68
68
69 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
69 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
70
70
71 if showprofile:
71 if showprofile:
72 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
72 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
73
73
74 counter += 1
74 counter += 1
75
75
76 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
76 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
77 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
77 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
78 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
78 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
79 server=None, folder=None, username=None, password=None,
79 server=None, folder=None, username=None, password=None,
80 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
80 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
81
81
82 """
82 """
83
83
84 Input:
84 Input:
85 dataOut :
85 dataOut :
86 id :
86 id :
87 wintitle :
87 wintitle :
88 channelList :
88 channelList :
89 showProfile :
89 showProfile :
90 xmin : None,
90 xmin : None,
91 xmax : None,
91 xmax : None,
92 ymin : None,
92 ymin : None,
93 ymax : None,
93 ymax : None,
94 zmin : None,
94 zmin : None,
95 zmax : None
95 zmax : None
96 """
96 """
97
97
98 if dataOut.flagNoData:
98 if dataOut.flagNoData:
99 return None
99 return None
100
100
101 if realtime:
101 if realtime:
102 if not(isRealtime(utcdatatime = dataOut.utctime)):
102 if not(isRealtime(utcdatatime = dataOut.utctime)):
103 print 'Skipping this plot function'
103 print 'Skipping this plot function'
104 return
104 return
105
105
106 if channelList == None:
106 if channelList == None:
107 channelIndexList = dataOut.channelIndexList
107 channelIndexList = dataOut.channelIndexList
108 else:
108 else:
109 channelIndexList = []
109 channelIndexList = []
110 for channel in channelList:
110 for channel in channelList:
111 if channel not in dataOut.channelList:
111 if channel not in dataOut.channelList:
112 raise ValueError, "Channel %d is not in dataOut.channelList"
112 raise ValueError, "Channel %d is not in dataOut.channelList"
113 channelIndexList.append(dataOut.channelList.index(channel))
113 channelIndexList.append(dataOut.channelList.index(channel))
114
114
115 factor = dataOut.normFactor
115 factor = dataOut.normFactor
116 x = dataOut.abscissaList
116 x = dataOut.abscissaList
117 y = dataOut.heightList
117 y = dataOut.heightList
118
118
119 z = dataOut.data_pre[channelIndexList,:,:]/factor
119 z = dataOut.data_pre[channelIndexList,:,:]/factor
120 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
120 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
121 avg = numpy.average(z, axis=1)
121 avg = numpy.average(z, axis=1)
122 noise = dataOut.noise/factor
122 noise = dataOut.noise/factor
123
123
124 zdB = 10*numpy.log10(z)
124 zdB = 10*numpy.log10(z)
125 avgdB = 10*numpy.log10(avg)
125 avgdB = 10*numpy.log10(avg)
126 noisedB = 10*numpy.log10(noise)
126 noisedB = 10*numpy.log10(noise)
127
127
128 #thisDatetime = dataOut.datatime
128 #thisDatetime = dataOut.datatime
129 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
129 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
130 title = wintitle + " Parameters"
130 title = wintitle + " Parameters"
131 xlabel = "Velocity (m/s)"
131 xlabel = "Velocity (m/s)"
132 ylabel = "Range (Km)"
132 ylabel = "Range (Km)"
133
133
134 update_figfile = False
134 update_figfile = False
135
135
136 if not self.isConfig:
136 if not self.isConfig:
137
137
138 nplots = len(channelIndexList)
138 nplots = len(channelIndexList)
139
139
140 self.setup(id=id,
140 self.setup(id=id,
141 nplots=nplots,
141 nplots=nplots,
142 wintitle=wintitle,
142 wintitle=wintitle,
143 showprofile=showprofile,
143 showprofile=showprofile,
144 show=show)
144 show=show)
145
145
146 if xmin == None: xmin = numpy.nanmin(x)
146 if xmin == None: xmin = numpy.nanmin(x)
147 if xmax == None: xmax = numpy.nanmax(x)
147 if xmax == None: xmax = numpy.nanmax(x)
148 if ymin == None: ymin = numpy.nanmin(y)
148 if ymin == None: ymin = numpy.nanmin(y)
149 if ymax == None: ymax = numpy.nanmax(y)
149 if ymax == None: ymax = numpy.nanmax(y)
150 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
150 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
151 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
151 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
152
152
153 self.FTP_WEI = ftp_wei
153 self.FTP_WEI = ftp_wei
154 self.EXP_CODE = exp_code
154 self.EXP_CODE = exp_code
155 self.SUB_EXP_CODE = sub_exp_code
155 self.SUB_EXP_CODE = sub_exp_code
156 self.PLOT_POS = plot_pos
156 self.PLOT_POS = plot_pos
157
157
158 self.isConfig = True
158 self.isConfig = True
159 update_figfile = True
159 update_figfile = True
160
160
161 self.setWinTitle(title)
161 self.setWinTitle(title)
162
162
163 for i in range(self.nplots):
163 for i in range(self.nplots):
164 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
164 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
165 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
165 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
166 axes = self.axesList[i*self.__nsubplots]
166 axes = self.axesList[i*self.__nsubplots]
167 axes.pcolor(x, y, zdB[i,:,:],
167 axes.pcolor(x, y, zdB[i,:,:],
168 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
168 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
169 xlabel=xlabel, ylabel=ylabel, title=title,
169 xlabel=xlabel, ylabel=ylabel, title=title,
170 ticksize=9, cblabel='')
170 ticksize=9, cblabel='')
171 #Mean Line
171 #Mean Line
172 mean = dataOut.data_param[i, 1, :]
172 mean = dataOut.data_param[i, 1, :]
173 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
173 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
174
174
175 if self.__showprofile:
175 if self.__showprofile:
176 axes = self.axesList[i*self.__nsubplots +1]
176 axes = self.axesList[i*self.__nsubplots +1]
177 axes.pline(avgdB[i], y,
177 axes.pline(avgdB[i], y,
178 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
178 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
179 xlabel='dB', ylabel='', title='',
179 xlabel='dB', ylabel='', title='',
180 ytick_visible=False,
180 ytick_visible=False,
181 grid='x')
181 grid='x')
182
182
183 noiseline = numpy.repeat(noisedB[i], len(y))
183 noiseline = numpy.repeat(noisedB[i], len(y))
184 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
184 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
185
185
186 self.draw()
186 self.draw()
187
187
188 self.save(figpath=figpath,
188 self.save(figpath=figpath,
189 figfile=figfile,
189 figfile=figfile,
190 save=save,
190 save=save,
191 ftp=ftp,
191 ftp=ftp,
192 wr_period=wr_period,
192 wr_period=wr_period,
193 thisDatetime=thisDatetime)
193 thisDatetime=thisDatetime)
194
194
195
195
196
196
197 class SkyMapPlot(Figure):
197 class SkyMapPlot(Figure):
198
198
199 __isConfig = None
199 __isConfig = None
200 __nsubplots = None
200 __nsubplots = None
201
201
202 WIDTHPROF = None
202 WIDTHPROF = None
203 HEIGHTPROF = None
203 HEIGHTPROF = None
204 PREFIX = 'mmap'
204 PREFIX = 'mmap'
205
205
206 def __init__(self):
206 def __init__(self):
207
207
208 self.isConfig = False
208 self.isConfig = False
209 self.__nsubplots = 1
209 self.__nsubplots = 1
210
210
211 # self.WIDTH = 280
211 # self.WIDTH = 280
212 # self.HEIGHT = 250
212 # self.HEIGHT = 250
213 self.WIDTH = 600
213 self.WIDTH = 600
214 self.HEIGHT = 600
214 self.HEIGHT = 600
215 self.WIDTHPROF = 120
215 self.WIDTHPROF = 120
216 self.HEIGHTPROF = 0
216 self.HEIGHTPROF = 0
217 self.counter_imagwr = 0
217 self.counter_imagwr = 0
218
218
219 self.PLOT_CODE = MSKYMAP_CODE
219 self.PLOT_CODE = MSKYMAP_CODE
220
220
221 self.FTP_WEI = None
221 self.FTP_WEI = None
222 self.EXP_CODE = None
222 self.EXP_CODE = None
223 self.SUB_EXP_CODE = None
223 self.SUB_EXP_CODE = None
224 self.PLOT_POS = None
224 self.PLOT_POS = None
225
225
226 def getSubplots(self):
226 def getSubplots(self):
227
227
228 ncol = int(numpy.sqrt(self.nplots)+0.9)
228 ncol = int(numpy.sqrt(self.nplots)+0.9)
229 nrow = int(self.nplots*1./ncol + 0.9)
229 nrow = int(self.nplots*1./ncol + 0.9)
230
230
231 return nrow, ncol
231 return nrow, ncol
232
232
233 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
233 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
234
234
235 self.__showprofile = showprofile
235 self.__showprofile = showprofile
236 self.nplots = nplots
236 self.nplots = nplots
237
237
238 ncolspan = 1
238 ncolspan = 1
239 colspan = 1
239 colspan = 1
240
240
241 self.createFigure(id = id,
241 self.createFigure(id = id,
242 wintitle = wintitle,
242 wintitle = wintitle,
243 widthplot = self.WIDTH, #+ self.WIDTHPROF,
243 widthplot = self.WIDTH, #+ self.WIDTHPROF,
244 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
244 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
245 show=show)
245 show=show)
246
246
247 nrow, ncol = 1,1
247 nrow, ncol = 1,1
248 counter = 0
248 counter = 0
249 x = 0
249 x = 0
250 y = 0
250 y = 0
251 self.addAxes(1, 1, 0, 0, 1, 1, True)
251 self.addAxes(1, 1, 0, 0, 1, 1, True)
252
252
253 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
253 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
254 tmin=None, tmax=None, timerange=None,
254 tmin=0, tmax=24, timerange=None,
255 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
255 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
256 server=None, folder=None, username=None, password=None,
256 server=None, folder=None, username=None, password=None,
257 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
257 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
258
258
259 """
259 """
260
260
261 Input:
261 Input:
262 dataOut :
262 dataOut :
263 id :
263 id :
264 wintitle :
264 wintitle :
265 channelList :
265 channelList :
266 showProfile :
266 showProfile :
267 xmin : None,
267 xmin : None,
268 xmax : None,
268 xmax : None,
269 ymin : None,
269 ymin : None,
270 ymax : None,
270 ymax : None,
271 zmin : None,
271 zmin : None,
272 zmax : None
272 zmax : None
273 """
273 """
274
274
275 arrayParameters = dataOut.data_param[0,:]
275 arrayParameters = dataOut.data_param
276 error = arrayParameters[:,-1]
276 error = arrayParameters[:,-1]
277 indValid = numpy.where(error == 0)[0]
277 indValid = numpy.where(error == 0)[0]
278 finalMeteor = arrayParameters[indValid,:]
278 finalMeteor = arrayParameters[indValid,:]
279 finalAzimuth = finalMeteor[:,4]
279 finalAzimuth = finalMeteor[:,3]
280 finalZenith = finalMeteor[:,5]
280 finalZenith = finalMeteor[:,4]
281
281
282 x = finalAzimuth*numpy.pi/180
282 x = finalAzimuth*numpy.pi/180
283 y = finalZenith
283 y = finalZenith
284 x1 = dataOut.getTimeRange()
284 x1 = [dataOut.ltctime, dataOut.ltctime]
285
285
286 #thisDatetime = dataOut.datatime
286 #thisDatetime = dataOut.datatime
287 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
287 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
288 title = wintitle + " Parameters"
288 title = wintitle + " Parameters"
289 xlabel = "Zonal Zenith Angle (deg) "
289 xlabel = "Zonal Zenith Angle (deg) "
290 ylabel = "Meridional Zenith Angle (deg)"
290 ylabel = "Meridional Zenith Angle (deg)"
291 update_figfile = False
291 update_figfile = False
292
292
293 if not self.isConfig:
293 if not self.isConfig:
294
294
295 nplots = 1
295 nplots = 1
296
296
297 self.setup(id=id,
297 self.setup(id=id,
298 nplots=nplots,
298 nplots=nplots,
299 wintitle=wintitle,
299 wintitle=wintitle,
300 showprofile=showprofile,
300 showprofile=showprofile,
301 show=show)
301 show=show)
302
302
303 if self.xmin is None and self.xmax is None:
303 if self.xmin is None and self.xmax is None:
304 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
304 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
305
305
306 if timerange != None:
306 if timerange != None:
307 self.timerange = timerange
307 self.timerange = timerange
308 else:
308 else:
309 self.timerange = self.xmax - self.xmin
309 self.timerange = self.xmax - self.xmin
310
310
311 self.FTP_WEI = ftp_wei
311 self.FTP_WEI = ftp_wei
312 self.EXP_CODE = exp_code
312 self.EXP_CODE = exp_code
313 self.SUB_EXP_CODE = sub_exp_code
313 self.SUB_EXP_CODE = sub_exp_code
314 self.PLOT_POS = plot_pos
314 self.PLOT_POS = plot_pos
315 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
315 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
316 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
316 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
317 self.isConfig = True
317 self.isConfig = True
318 update_figfile = True
318 update_figfile = True
319
319
320 self.setWinTitle(title)
320 self.setWinTitle(title)
321
321
322 i = 0
322 i = 0
323 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
323 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
324
324
325 axes = self.axesList[i*self.__nsubplots]
325 axes = self.axesList[i*self.__nsubplots]
326 nevents = axes.x_buffer.shape[0] + x.shape[0]
326 nevents = axes.x_buffer.shape[0] + x.shape[0]
327 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
327 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
328 axes.polar(x, y,
328 axes.polar(x, y,
329 title=title, xlabel=xlabel, ylabel=ylabel,
329 title=title, xlabel=xlabel, ylabel=ylabel,
330 ticksize=9, cblabel='')
330 ticksize=9, cblabel='')
331
331
332 self.draw()
332 self.draw()
333
333
334 self.save(figpath=figpath,
334 self.save(figpath=figpath,
335 figfile=figfile,
335 figfile=figfile,
336 save=save,
336 save=save,
337 ftp=ftp,
337 ftp=ftp,
338 wr_period=wr_period,
338 wr_period=wr_period,
339 thisDatetime=thisDatetime,
339 thisDatetime=thisDatetime,
340 update_figfile=update_figfile)
340 update_figfile=update_figfile)
341
341
342 if dataOut.ltctime >= self.xmax:
342 if dataOut.ltctime >= self.xmax:
343 self.isConfigmagwr = wr_period
343 self.isConfigmagwr = wr_period
344 self.isConfig = False
344 self.isConfig = False
345 update_figfile = True
345 update_figfile = True
346 axes.__firsttime = True
346 axes.__firsttime = True
347 self.xmin += self.timerange
347 self.xmin += self.timerange
348 self.xmax += self.timerange
348 self.xmax += self.timerange
349
349
350
350
351
351
352
352
353 class WindProfilerPlot(Figure):
353 class WindProfilerPlot(Figure):
354
354
355 __isConfig = None
355 __isConfig = None
356 __nsubplots = None
356 __nsubplots = None
357
357
358 WIDTHPROF = None
358 WIDTHPROF = None
359 HEIGHTPROF = None
359 HEIGHTPROF = None
360 PREFIX = 'wind'
360 PREFIX = 'wind'
361
361
362 def __init__(self):
362 def __init__(self):
363
363
364 self.timerange = None
364 self.timerange = None
365 self.isConfig = False
365 self.isConfig = False
366 self.__nsubplots = 1
366 self.__nsubplots = 1
367
367
368 self.WIDTH = 800
368 self.WIDTH = 800
369 self.HEIGHT = 150
369 self.HEIGHT = 150
370 self.WIDTHPROF = 120
370 self.WIDTHPROF = 120
371 self.HEIGHTPROF = 0
371 self.HEIGHTPROF = 0
372 self.counter_imagwr = 0
372 self.counter_imagwr = 0
373
373
374 self.PLOT_CODE = WIND_CODE
374 self.PLOT_CODE = WIND_CODE
375
375
376 self.FTP_WEI = None
376 self.FTP_WEI = None
377 self.EXP_CODE = None
377 self.EXP_CODE = None
378 self.SUB_EXP_CODE = None
378 self.SUB_EXP_CODE = None
379 self.PLOT_POS = None
379 self.PLOT_POS = None
380 self.tmin = None
380 self.tmin = None
381 self.tmax = None
381 self.tmax = None
382
382
383 self.xmin = None
383 self.xmin = None
384 self.xmax = None
384 self.xmax = None
385
385
386 self.figfile = None
386 self.figfile = None
387
387
388 def getSubplots(self):
388 def getSubplots(self):
389
389
390 ncol = 1
390 ncol = 1
391 nrow = self.nplots
391 nrow = self.nplots
392
392
393 return nrow, ncol
393 return nrow, ncol
394
394
395 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
395 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
396
396
397 self.__showprofile = showprofile
397 self.__showprofile = showprofile
398 self.nplots = nplots
398 self.nplots = nplots
399
399
400 ncolspan = 1
400 ncolspan = 1
401 colspan = 1
401 colspan = 1
402
402
403 self.createFigure(id = id,
403 self.createFigure(id = id,
404 wintitle = wintitle,
404 wintitle = wintitle,
405 widthplot = self.WIDTH + self.WIDTHPROF,
405 widthplot = self.WIDTH + self.WIDTHPROF,
406 heightplot = self.HEIGHT + self.HEIGHTPROF,
406 heightplot = self.HEIGHT + self.HEIGHTPROF,
407 show=show)
407 show=show)
408
408
409 nrow, ncol = self.getSubplots()
409 nrow, ncol = self.getSubplots()
410
410
411 counter = 0
411 counter = 0
412 for y in range(nrow):
412 for y in range(nrow):
413 if counter >= self.nplots:
413 if counter >= self.nplots:
414 break
414 break
415
415
416 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
416 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
417 counter += 1
417 counter += 1
418
418
419 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
419 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
420 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
420 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
421 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
421 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
422 timerange=None, SNRthresh = None,
422 timerange=None, SNRthresh = None,
423 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
423 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
424 server=None, folder=None, username=None, password=None,
424 server=None, folder=None, username=None, password=None,
425 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
425 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
426 """
426 """
427
427
428 Input:
428 Input:
429 dataOut :
429 dataOut :
430 id :
430 id :
431 wintitle :
431 wintitle :
432 channelList :
432 channelList :
433 showProfile :
433 showProfile :
434 xmin : None,
434 xmin : None,
435 xmax : None,
435 xmax : None,
436 ymin : None,
436 ymin : None,
437 ymax : None,
437 ymax : None,
438 zmin : None,
438 zmin : None,
439 zmax : None
439 zmax : None
440 """
440 """
441
441
442 if channelList == None:
443 channelIndexList = dataOut.channelIndexList
444 else:
445 channelIndexList = []
446 for channel in channelList:
447 if channel not in dataOut.channelList:
448 raise ValueError, "Channel %d is not in dataOut.channelList"
449 channelIndexList.append(dataOut.channelList.index(channel))
450
451 # if timerange is not None:
442 # if timerange is not None:
452 # self.timerange = timerange
443 # self.timerange = timerange
453 #
444 #
454 # tmin = None
445 # tmin = None
455 # tmax = None
446 # tmax = None
456
447
457 x = dataOut.getTimeRange1()
448 x = dataOut.getTimeRange1(dataOut.outputInterval)
458 # y = dataOut.heightList
449 # y = dataOut.heightList
459 y = dataOut.heightList
450 y = dataOut.heightList
460
451
461 z = dataOut.data_output.copy()
452 z = dataOut.data_output.copy()
462 nplots = z.shape[0] #Number of wind dimensions estimated
453 nplots = z.shape[0] #Number of wind dimensions estimated
463 nplotsw = nplots
454 nplotsw = nplots
464
455
465 #If there is a SNR function defined
456 #If there is a SNR function defined
466 if dataOut.data_SNR is not None:
457 if dataOut.data_SNR is not None:
467 nplots += 1
458 nplots += 1
468 SNR = dataOut.data_SNR
459 SNR = dataOut.data_SNR
469 SNRavg = numpy.average(SNR, axis=0)
460 SNRavg = numpy.average(SNR, axis=0)
470
461
471 SNRdB = 10*numpy.log10(SNR)
462 SNRdB = 10*numpy.log10(SNR)
472 SNRavgdB = 10*numpy.log10(SNRavg)
463 SNRavgdB = 10*numpy.log10(SNRavg)
473
464
474 if SNRthresh == None: SNRthresh = -5.0
465 if SNRthresh == None: SNRthresh = -5.0
475 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
466 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
476
467
477 for i in range(nplotsw):
468 for i in range(nplotsw):
478 z[i,ind] = numpy.nan
469 z[i,ind] = numpy.nan
479
470
480
471
481 # showprofile = False
472 # showprofile = False
482 # thisDatetime = dataOut.datatime
473 # thisDatetime = dataOut.datatime
483 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
474 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
484 title = wintitle + "Wind"
475 title = wintitle + "Wind"
485 xlabel = ""
476 xlabel = ""
486 ylabel = "Range (Km)"
477 ylabel = "Range (Km)"
487 update_figfile = False
478 update_figfile = False
488
479
489 if not self.isConfig:
480 if not self.isConfig:
490
481
491 self.setup(id=id,
482 self.setup(id=id,
492 nplots=nplots,
483 nplots=nplots,
493 wintitle=wintitle,
484 wintitle=wintitle,
494 showprofile=showprofile,
485 showprofile=showprofile,
495 show=show)
486 show=show)
496
487
497 if timerange is not None:
488 if timerange is not None:
498 self.timerange = timerange
489 self.timerange = timerange
499
490
500 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
491 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
501
492
502 if ymin == None: ymin = numpy.nanmin(y)
493 if ymin == None: ymin = numpy.nanmin(y)
503 if ymax == None: ymax = numpy.nanmax(y)
494 if ymax == None: ymax = numpy.nanmax(y)
504
495
505 if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:]))
496 if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:]))
506 #if numpy.isnan(zmax): zmax = 50
497 #if numpy.isnan(zmax): zmax = 50
507 if zmin == None: zmin = -zmax
498 if zmin == None: zmin = -zmax
508
499
509 if nplotsw == 3:
500 if nplotsw == 3:
510 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
501 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
511 if zmin_ver == None: zmin_ver = -zmax_ver
502 if zmin_ver == None: zmin_ver = -zmax_ver
512
503
513 if dataOut.data_SNR is not None:
504 if dataOut.data_SNR is not None:
514 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
505 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
515 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
506 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
516
507
517
508
518 self.FTP_WEI = ftp_wei
509 self.FTP_WEI = ftp_wei
519 self.EXP_CODE = exp_code
510 self.EXP_CODE = exp_code
520 self.SUB_EXP_CODE = sub_exp_code
511 self.SUB_EXP_CODE = sub_exp_code
521 self.PLOT_POS = plot_pos
512 self.PLOT_POS = plot_pos
522
513
523 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
514 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
524 self.isConfig = True
515 self.isConfig = True
525 self.figfile = figfile
516 self.figfile = figfile
526 update_figfile = True
517 update_figfile = True
527
518
528 self.setWinTitle(title)
519 self.setWinTitle(title)
529
520
530 if ((self.xmax - x[1]) < (x[1]-x[0])):
521 if ((self.xmax - x[1]) < (x[1]-x[0])):
531 x[1] = self.xmax
522 x[1] = self.xmax
532
523
533 strWind = ['Zonal', 'Meridional', 'Vertical']
524 strWind = ['Zonal', 'Meridional', 'Vertical']
534 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
525 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
535 zmaxVector = [zmax, zmax, zmax_ver]
526 zmaxVector = [zmax, zmax, zmax_ver]
536 zminVector = [zmin, zmin, zmin_ver]
527 zminVector = [zmin, zmin, zmin_ver]
537 windFactor = [1,1,100]
528 windFactor = [1,1,100]
538
529
539 for i in range(nplotsw):
530 for i in range(nplotsw):
540
531
541 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
532 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
542 axes = self.axesList[i*self.__nsubplots]
533 axes = self.axesList[i*self.__nsubplots]
543
534
544 z1 = z[i,:].reshape((1,-1))*windFactor[i]
535 z1 = z[i,:].reshape((1,-1))*windFactor[i]
545
536
546 axes.pcolorbuffer(x, y, z1,
537 axes.pcolorbuffer(x, y, z1,
547 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
538 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
548 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
539 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
549 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="RdBu_r" )
540 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="RdBu_r" )
550
541
551 if dataOut.data_SNR is not None:
542 if dataOut.data_SNR is not None:
552 i += 1
543 i += 1
553 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
544 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
554 axes = self.axesList[i*self.__nsubplots]
545 axes = self.axesList[i*self.__nsubplots]
555
546
556 SNRavgdB = SNRavgdB.reshape((1,-1))
547 SNRavgdB = SNRavgdB.reshape((1,-1))
557
548
558 axes.pcolorbuffer(x, y, SNRavgdB,
549 axes.pcolorbuffer(x, y, SNRavgdB,
559 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
550 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
560 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
551 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
561 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
552 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
562
553
563 self.draw()
554 self.draw()
564
555
565 if dataOut.ltctime >= self.xmax:
556 if dataOut.ltctime >= self.xmax:
566 self.counter_imagwr = wr_period
557 self.counter_imagwr = wr_period
567 self.isConfig = False
558 self.isConfig = False
568 update_figfile = True
559 update_figfile = True
569
560
570 self.save(figpath=figpath,
561 self.save(figpath=figpath,
571 figfile=figfile,
562 figfile=figfile,
572 save=save,
563 save=save,
573 ftp=ftp,
564 ftp=ftp,
574 wr_period=wr_period,
565 wr_period=wr_period,
575 thisDatetime=thisDatetime,
566 thisDatetime=thisDatetime,
576 update_figfile=update_figfile)
567 update_figfile=update_figfile)
577
568
578
569
579
570
580 class ParametersPlot(Figure):
571 class ParametersPlot(Figure):
581
572
582 __isConfig = None
573 __isConfig = None
583 __nsubplots = None
574 __nsubplots = None
584
575
585 WIDTHPROF = None
576 WIDTHPROF = None
586 HEIGHTPROF = None
577 HEIGHTPROF = None
587 PREFIX = 'prm'
578 PREFIX = 'prm'
588
579
589 def __init__(self):
580 def __init__(self):
590
581
591 self.timerange = 2*60*60
582 self.timerange = 2*60*60
592 self.isConfig = False
583 self.isConfig = False
593 self.__nsubplots = 1
584 self.__nsubplots = 1
594
585
595 self.WIDTH = 800
586 self.WIDTH = 800
596 self.HEIGHT = 150
587 self.HEIGHT = 150
597 self.WIDTHPROF = 120
588 self.WIDTHPROF = 120
598 self.HEIGHTPROF = 0
589 self.HEIGHTPROF = 0
599 self.counter_imagwr = 0
590 self.counter_imagwr = 0
600
591
601 self.PLOT_CODE = PARMS_CODE
592 self.PLOT_CODE = PARMS_CODE
602
593
603 self.FTP_WEI = None
594 self.FTP_WEI = None
604 self.EXP_CODE = None
595 self.EXP_CODE = None
605 self.SUB_EXP_CODE = None
596 self.SUB_EXP_CODE = None
606 self.PLOT_POS = None
597 self.PLOT_POS = None
607 self.tmin = None
598 self.tmin = None
608 self.tmax = None
599 self.tmax = None
609
600
610 self.xmin = None
601 self.xmin = None
611 self.xmax = None
602 self.xmax = None
612
603
613 self.figfile = None
604 self.figfile = None
614
605
615 def getSubplots(self):
606 def getSubplots(self):
616
607
617 ncol = 1
608 ncol = 1
618 nrow = self.nplots
609 nrow = self.nplots
619
610
620 return nrow, ncol
611 return nrow, ncol
621
612
622 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
613 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
623
614
624 self.__showprofile = showprofile
615 self.__showprofile = showprofile
625 self.nplots = nplots
616 self.nplots = nplots
626
617
627 ncolspan = 1
618 ncolspan = 1
628 colspan = 1
619 colspan = 1
629
620
630 self.createFigure(id = id,
621 self.createFigure(id = id,
631 wintitle = wintitle,
622 wintitle = wintitle,
632 widthplot = self.WIDTH + self.WIDTHPROF,
623 widthplot = self.WIDTH + self.WIDTHPROF,
633 heightplot = self.HEIGHT + self.HEIGHTPROF,
624 heightplot = self.HEIGHT + self.HEIGHTPROF,
634 show=show)
625 show=show)
635
626
636 nrow, ncol = self.getSubplots()
627 nrow, ncol = self.getSubplots()
637
628
638 counter = 0
629 counter = 0
639 for y in range(nrow):
630 for y in range(nrow):
640 for x in range(ncol):
631 for x in range(ncol):
641
632
642 if counter >= self.nplots:
633 if counter >= self.nplots:
643 break
634 break
644
635
645 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
636 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
646
637
647 if showprofile:
638 if showprofile:
648 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
639 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
649
640
650 counter += 1
641 counter += 1
651
642
652 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
643 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
653 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
644 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
654 parameterIndex = None, onlyPositive = False,
645 parameterIndex = None, onlyPositive = False,
655 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
646 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
656 DOP = True,
647 DOP = True,
657 zlabel = "", parameterName = "", parameterObject = "data_param",
648 zlabel = "", parameterName = "", parameterObject = "data_param",
658 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
649 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
659 server=None, folder=None, username=None, password=None,
650 server=None, folder=None, username=None, password=None,
660 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
651 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
661
652
662 """
653 """
663
654
664 Input:
655 Input:
665 dataOut :
656 dataOut :
666 id :
657 id :
667 wintitle :
658 wintitle :
668 channelList :
659 channelList :
669 showProfile :
660 showProfile :
670 xmin : None,
661 xmin : None,
671 xmax : None,
662 xmax : None,
672 ymin : None,
663 ymin : None,
673 ymax : None,
664 ymax : None,
674 zmin : None,
665 zmin : None,
675 zmax : None
666 zmax : None
676 """
667 """
677
668
678 data_param = getattr(dataOut, parameterObject)
669 data_param = getattr(dataOut, parameterObject)
679
670
680 if channelList == None:
671 if channelList == None:
681 channelIndexList = numpy.arange(data_param.shape[0])
672 channelIndexList = numpy.arange(data_param.shape[0])
682 else:
673 else:
683 channelIndexList = numpy.array(channelList)
674 channelIndexList = numpy.array(channelList)
684
675
685 nchan = len(channelIndexList) #Number of channels being plotted
676 nchan = len(channelIndexList) #Number of channels being plotted
686
677
687 if nchan < 1:
678 if nchan < 1:
688 return
679 return
689
680
690 nGraphsByChannel = 0
681 nGraphsByChannel = 0
691
682
692 if SNR:
683 if SNR:
693 nGraphsByChannel += 1
684 nGraphsByChannel += 1
694 if DOP:
685 if DOP:
695 nGraphsByChannel += 1
686 nGraphsByChannel += 1
696
687
697 if nGraphsByChannel < 1:
688 if nGraphsByChannel < 1:
698 return
689 return
699
690
700 nplots = nGraphsByChannel*nchan
691 nplots = nGraphsByChannel*nchan
701
692
702 if timerange is not None:
693 if timerange is not None:
703 self.timerange = timerange
694 self.timerange = timerange
704
695
705 #tmin = None
696 #tmin = None
706 #tmax = None
697 #tmax = None
707 if parameterIndex == None:
698 if parameterIndex == None:
708 parameterIndex = 1
699 parameterIndex = 1
709
700
710 x = dataOut.getTimeRange1()
701 x = dataOut.getTimeRange1(dataOut.paramInterval)
711 y = dataOut.heightList
702 y = dataOut.heightList
712 z = data_param[channelIndexList,parameterIndex,:].copy()
703 z = data_param[channelIndexList,parameterIndex,:].copy()
713
704
714 zRange = dataOut.abscissaList
705 zRange = dataOut.abscissaList
715 # nChannels = z.shape[0] #Number of wind dimensions estimated
706 # nChannels = z.shape[0] #Number of wind dimensions estimated
716 # thisDatetime = dataOut.datatime
707 # thisDatetime = dataOut.datatime
717
708
718 if dataOut.data_SNR is not None:
709 if dataOut.data_SNR is not None:
719 SNRarray = dataOut.data_SNR[channelIndexList,:]
710 SNRarray = dataOut.data_SNR[channelIndexList,:]
720 SNRdB = 10*numpy.log10(SNRarray)
711 SNRdB = 10*numpy.log10(SNRarray)
721 # SNRavgdB = 10*numpy.log10(SNRavg)
712 # SNRavgdB = 10*numpy.log10(SNRavg)
722 ind = numpy.where(SNRdB < 10**(SNRthresh/10))
713 ind = numpy.where(SNRdB < 10**(SNRthresh/10))
723 z[ind] = numpy.nan
714 z[ind] = numpy.nan
724
715
725 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
716 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
726 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
717 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
727 xlabel = ""
718 xlabel = ""
728 ylabel = "Range (Km)"
719 ylabel = "Range (Km)"
729
720
730 if (SNR and not onlySNR): nplots = 2*nplots
721 if (SNR and not onlySNR): nplots = 2*nplots
731
722
732 if onlyPositive:
723 if onlyPositive:
733 colormap = "jet"
724 colormap = "jet"
734 zmin = 0
725 zmin = 0
735 else: colormap = "RdBu_r"
726 else: colormap = "RdBu_r"
736
727
737 if not self.isConfig:
728 if not self.isConfig:
738
729
739 self.setup(id=id,
730 self.setup(id=id,
740 nplots=nplots,
731 nplots=nplots,
741 wintitle=wintitle,
732 wintitle=wintitle,
742 showprofile=showprofile,
733 showprofile=showprofile,
743 show=show)
734 show=show)
744
735
745 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
736 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
746
737
747 if ymin == None: ymin = numpy.nanmin(y)
738 if ymin == None: ymin = numpy.nanmin(y)
748 if ymax == None: ymax = numpy.nanmax(y)
739 if ymax == None: ymax = numpy.nanmax(y)
749 if zmin == None: zmin = numpy.nanmin(zRange)
740 if zmin == None: zmin = numpy.nanmin(zRange)
750 if zmax == None: zmax = numpy.nanmax(zRange)
741 if zmax == None: zmax = numpy.nanmax(zRange)
751
742
752 if SNR:
743 if SNR:
753 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
744 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
754 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
745 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
755
746
756 self.FTP_WEI = ftp_wei
747 self.FTP_WEI = ftp_wei
757 self.EXP_CODE = exp_code
748 self.EXP_CODE = exp_code
758 self.SUB_EXP_CODE = sub_exp_code
749 self.SUB_EXP_CODE = sub_exp_code
759 self.PLOT_POS = plot_pos
750 self.PLOT_POS = plot_pos
760
751
761 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
752 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
762 self.isConfig = True
753 self.isConfig = True
763 self.figfile = figfile
754 self.figfile = figfile
764
755
765 self.setWinTitle(title)
756 self.setWinTitle(title)
766
757
767 if ((self.xmax - x[1]) < (x[1]-x[0])):
758 if ((self.xmax - x[1]) < (x[1]-x[0])):
768 x[1] = self.xmax
759 x[1] = self.xmax
769
760
770 for i in range(nchan):
761 for i in range(nchan):
771
762
772 if (SNR and not onlySNR): j = 2*i
763 if (SNR and not onlySNR): j = 2*i
773 else: j = i
764 else: j = i
774
765
775 j = nGraphsByChannel*i
766 j = nGraphsByChannel*i
776
767
777 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
768 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
778 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
769 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
779
770
780 if not onlySNR:
771 if not onlySNR:
781 axes = self.axesList[j*self.__nsubplots]
772 axes = self.axesList[j*self.__nsubplots]
782 z1 = z[i,:].reshape((1,-1))
773 z1 = z[i,:].reshape((1,-1))
783 axes.pcolorbuffer(x, y, z1,
774 axes.pcolorbuffer(x, y, z1,
784 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
775 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
785 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
776 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
786 ticksize=9, cblabel=zlabel, cbsize="1%")
777 ticksize=9, cblabel=zlabel, cbsize="1%")
787
778
788 if DOP:
779 if DOP:
789 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
780 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
790
781
791 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
782 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
792 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
783 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
793 axes = self.axesList[j]
784 axes = self.axesList[j]
794 z1 = z[i,:].reshape((1,-1))
785 z1 = z[i,:].reshape((1,-1))
795 axes.pcolorbuffer(x, y, z1,
786 axes.pcolorbuffer(x, y, z1,
796 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
787 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
797 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
788 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
798 ticksize=9, cblabel=zlabel, cbsize="1%")
789 ticksize=9, cblabel=zlabel, cbsize="1%")
799
790
800 if SNR:
791 if SNR:
801 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
792 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
802 axes = self.axesList[(j)*self.__nsubplots]
793 axes = self.axesList[(j)*self.__nsubplots]
803 if not onlySNR:
794 if not onlySNR:
804 axes = self.axesList[(j + 1)*self.__nsubplots]
795 axes = self.axesList[(j + 1)*self.__nsubplots]
805
796
806 axes = self.axesList[(j + nGraphsByChannel-1)]
797 axes = self.axesList[(j + nGraphsByChannel-1)]
807
798
808 z1 = SNRdB[i,:].reshape((1,-1))
799 z1 = SNRdB[i,:].reshape((1,-1))
809 axes.pcolorbuffer(x, y, z1,
800 axes.pcolorbuffer(x, y, z1,
810 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
801 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
811 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
802 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
812 ticksize=9, cblabel=zlabel, cbsize="1%")
803 ticksize=9, cblabel=zlabel, cbsize="1%")
813
804
814
805
815
806
816 self.draw()
807 self.draw()
817
808
818 if x[1] >= self.axesList[0].xmax:
809 if x[1] >= self.axesList[0].xmax:
819 self.counter_imagwr = wr_period
810 self.counter_imagwr = wr_period
820 self.isConfig = False
811 self.isConfig = False
821 self.figfile = None
812 self.figfile = None
822
813
823 self.save(figpath=figpath,
814 self.save(figpath=figpath,
824 figfile=figfile,
815 figfile=figfile,
825 save=save,
816 save=save,
826 ftp=ftp,
817 ftp=ftp,
827 wr_period=wr_period,
818 wr_period=wr_period,
828 thisDatetime=thisDatetime,
819 thisDatetime=thisDatetime,
829 update_figfile=False)
820 update_figfile=False)
830
821
831 class SpectralFittingPlot(Figure):
822 class SpectralFittingPlot(Figure):
832
823
833 __isConfig = None
824 __isConfig = None
834 __nsubplots = None
825 __nsubplots = None
835
826
836 WIDTHPROF = None
827 WIDTHPROF = None
837 HEIGHTPROF = None
828 HEIGHTPROF = None
838 PREFIX = 'prm'
829 PREFIX = 'prm'
839
830
840
831
841 N = None
832 N = None
842 ippSeconds = None
833 ippSeconds = None
843
834
844 def __init__(self):
835 def __init__(self):
845 self.isConfig = False
836 self.isConfig = False
846 self.__nsubplots = 1
837 self.__nsubplots = 1
847
838
848 self.PLOT_CODE = SPECFIT_CODE
839 self.PLOT_CODE = SPECFIT_CODE
849
840
850 self.WIDTH = 450
841 self.WIDTH = 450
851 self.HEIGHT = 250
842 self.HEIGHT = 250
852 self.WIDTHPROF = 0
843 self.WIDTHPROF = 0
853 self.HEIGHTPROF = 0
844 self.HEIGHTPROF = 0
854
845
855 def getSubplots(self):
846 def getSubplots(self):
856
847
857 ncol = int(numpy.sqrt(self.nplots)+0.9)
848 ncol = int(numpy.sqrt(self.nplots)+0.9)
858 nrow = int(self.nplots*1./ncol + 0.9)
849 nrow = int(self.nplots*1./ncol + 0.9)
859
850
860 return nrow, ncol
851 return nrow, ncol
861
852
862 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
853 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
863
854
864 showprofile = False
855 showprofile = False
865 self.__showprofile = showprofile
856 self.__showprofile = showprofile
866 self.nplots = nplots
857 self.nplots = nplots
867
858
868 ncolspan = 5
859 ncolspan = 5
869 colspan = 4
860 colspan = 4
870 if showprofile:
861 if showprofile:
871 ncolspan = 5
862 ncolspan = 5
872 colspan = 4
863 colspan = 4
873 self.__nsubplots = 2
864 self.__nsubplots = 2
874
865
875 self.createFigure(id = id,
866 self.createFigure(id = id,
876 wintitle = wintitle,
867 wintitle = wintitle,
877 widthplot = self.WIDTH + self.WIDTHPROF,
868 widthplot = self.WIDTH + self.WIDTHPROF,
878 heightplot = self.HEIGHT + self.HEIGHTPROF,
869 heightplot = self.HEIGHT + self.HEIGHTPROF,
879 show=show)
870 show=show)
880
871
881 nrow, ncol = self.getSubplots()
872 nrow, ncol = self.getSubplots()
882
873
883 counter = 0
874 counter = 0
884 for y in range(nrow):
875 for y in range(nrow):
885 for x in range(ncol):
876 for x in range(ncol):
886
877
887 if counter >= self.nplots:
878 if counter >= self.nplots:
888 break
879 break
889
880
890 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
881 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
891
882
892 if showprofile:
883 if showprofile:
893 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
884 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
894
885
895 counter += 1
886 counter += 1
896
887
897 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
888 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
898 xmin=None, xmax=None, ymin=None, ymax=None,
889 xmin=None, xmax=None, ymin=None, ymax=None,
899 save=False, figpath='./', figfile=None, show=True):
890 save=False, figpath='./', figfile=None, show=True):
900
891
901 """
892 """
902
893
903 Input:
894 Input:
904 dataOut :
895 dataOut :
905 id :
896 id :
906 wintitle :
897 wintitle :
907 channelList :
898 channelList :
908 showProfile :
899 showProfile :
909 xmin : None,
900 xmin : None,
910 xmax : None,
901 xmax : None,
911 zmin : None,
902 zmin : None,
912 zmax : None
903 zmax : None
913 """
904 """
914
905
915 if cutHeight==None:
906 if cutHeight==None:
916 h=270
907 h=270
917 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
908 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
918 cutHeight = dataOut.heightList[heightindex]
909 cutHeight = dataOut.heightList[heightindex]
919
910
920 factor = dataOut.normFactor
911 factor = dataOut.normFactor
921 x = dataOut.abscissaList[:-1]
912 x = dataOut.abscissaList[:-1]
922 #y = dataOut.getHeiRange()
913 #y = dataOut.getHeiRange()
923
914
924 z = dataOut.data_pre[:,:,heightindex]/factor
915 z = dataOut.data_pre[:,:,heightindex]/factor
925 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
916 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
926 avg = numpy.average(z, axis=1)
917 avg = numpy.average(z, axis=1)
927 listChannels = z.shape[0]
918 listChannels = z.shape[0]
928
919
929 #Reconstruct Function
920 #Reconstruct Function
930 if fit==True:
921 if fit==True:
931 groupArray = dataOut.groupList
922 groupArray = dataOut.groupList
932 listChannels = groupArray.reshape((groupArray.size))
923 listChannels = groupArray.reshape((groupArray.size))
933 listChannels.sort()
924 listChannels.sort()
934 spcFitLine = numpy.zeros(z.shape)
925 spcFitLine = numpy.zeros(z.shape)
935 constants = dataOut.constants
926 constants = dataOut.constants
936
927
937 nGroups = groupArray.shape[0]
928 nGroups = groupArray.shape[0]
938 nChannels = groupArray.shape[1]
929 nChannels = groupArray.shape[1]
939 nProfiles = z.shape[1]
930 nProfiles = z.shape[1]
940
931
941 for f in range(nGroups):
932 for f in range(nGroups):
942 groupChann = groupArray[f,:]
933 groupChann = groupArray[f,:]
943 p = dataOut.data_param[f,:,heightindex]
934 p = dataOut.data_param[f,:,heightindex]
944 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
935 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
945 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
936 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
946 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
937 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
947 spcFitLine[groupChann,:] = fitLineAux
938 spcFitLine[groupChann,:] = fitLineAux
948 # spcFitLine = spcFitLine/factor
939 # spcFitLine = spcFitLine/factor
949
940
950 z = z[listChannels,:]
941 z = z[listChannels,:]
951 spcFitLine = spcFitLine[listChannels,:]
942 spcFitLine = spcFitLine[listChannels,:]
952 spcFitLinedB = 10*numpy.log10(spcFitLine)
943 spcFitLinedB = 10*numpy.log10(spcFitLine)
953
944
954 zdB = 10*numpy.log10(z)
945 zdB = 10*numpy.log10(z)
955 #thisDatetime = dataOut.datatime
946 #thisDatetime = dataOut.datatime
956 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
947 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
957 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
948 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
958 xlabel = "Velocity (m/s)"
949 xlabel = "Velocity (m/s)"
959 ylabel = "Spectrum"
950 ylabel = "Spectrum"
960
951
961 if not self.isConfig:
952 if not self.isConfig:
962
953
963 nplots = listChannels.size
954 nplots = listChannels.size
964
955
965 self.setup(id=id,
956 self.setup(id=id,
966 nplots=nplots,
957 nplots=nplots,
967 wintitle=wintitle,
958 wintitle=wintitle,
968 showprofile=showprofile,
959 showprofile=showprofile,
969 show=show)
960 show=show)
970
961
971 if xmin == None: xmin = numpy.nanmin(x)
962 if xmin == None: xmin = numpy.nanmin(x)
972 if xmax == None: xmax = numpy.nanmax(x)
963 if xmax == None: xmax = numpy.nanmax(x)
973 if ymin == None: ymin = numpy.nanmin(zdB)
964 if ymin == None: ymin = numpy.nanmin(zdB)
974 if ymax == None: ymax = numpy.nanmax(zdB)+2
965 if ymax == None: ymax = numpy.nanmax(zdB)+2
975
966
976 self.isConfig = True
967 self.isConfig = True
977
968
978 self.setWinTitle(title)
969 self.setWinTitle(title)
979 for i in range(self.nplots):
970 for i in range(self.nplots):
980 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
971 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
981 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
972 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
982 axes = self.axesList[i*self.__nsubplots]
973 axes = self.axesList[i*self.__nsubplots]
983 if fit == False:
974 if fit == False:
984 axes.pline(x, zdB[i,:],
975 axes.pline(x, zdB[i,:],
985 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
976 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
986 xlabel=xlabel, ylabel=ylabel, title=title
977 xlabel=xlabel, ylabel=ylabel, title=title
987 )
978 )
988 if fit == True:
979 if fit == True:
989 fitline=spcFitLinedB[i,:]
980 fitline=spcFitLinedB[i,:]
990 y=numpy.vstack([zdB[i,:],fitline] )
981 y=numpy.vstack([zdB[i,:],fitline] )
991 legendlabels=['Data','Fitting']
982 legendlabels=['Data','Fitting']
992 axes.pmultilineyaxis(x, y,
983 axes.pmultilineyaxis(x, y,
993 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
984 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
994 xlabel=xlabel, ylabel=ylabel, title=title,
985 xlabel=xlabel, ylabel=ylabel, title=title,
995 legendlabels=legendlabels, marker=None,
986 legendlabels=legendlabels, marker=None,
996 linestyle='solid', grid='both')
987 linestyle='solid', grid='both')
997
988
998 self.draw()
989 self.draw()
999
990
1000 self.save(figpath=figpath,
991 self.save(figpath=figpath,
1001 figfile=figfile,
992 figfile=figfile,
1002 save=save,
993 save=save,
1003 ftp=ftp,
994 ftp=ftp,
1004 wr_period=wr_period,
995 wr_period=wr_period,
1005 thisDatetime=thisDatetime)
996 thisDatetime=thisDatetime)
1006
997
1007
998
1008 class EWDriftsPlot(Figure):
999 class EWDriftsPlot(Figure):
1009
1000
1010 __isConfig = None
1001 __isConfig = None
1011 __nsubplots = None
1002 __nsubplots = None
1012
1003
1013 WIDTHPROF = None
1004 WIDTHPROF = None
1014 HEIGHTPROF = None
1005 HEIGHTPROF = None
1015 PREFIX = 'drift'
1006 PREFIX = 'drift'
1016
1007
1017 def __init__(self):
1008 def __init__(self):
1018
1009
1019 self.timerange = 2*60*60
1010 self.timerange = 2*60*60
1020 self.isConfig = False
1011 self.isConfig = False
1021 self.__nsubplots = 1
1012 self.__nsubplots = 1
1022
1013
1023 self.WIDTH = 800
1014 self.WIDTH = 800
1024 self.HEIGHT = 150
1015 self.HEIGHT = 150
1025 self.WIDTHPROF = 120
1016 self.WIDTHPROF = 120
1026 self.HEIGHTPROF = 0
1017 self.HEIGHTPROF = 0
1027 self.counter_imagwr = 0
1018 self.counter_imagwr = 0
1028
1019
1029 self.PLOT_CODE = EWDRIFT_CODE
1020 self.PLOT_CODE = EWDRIFT_CODE
1030
1021
1031 self.FTP_WEI = None
1022 self.FTP_WEI = None
1032 self.EXP_CODE = None
1023 self.EXP_CODE = None
1033 self.SUB_EXP_CODE = None
1024 self.SUB_EXP_CODE = None
1034 self.PLOT_POS = None
1025 self.PLOT_POS = None
1035 self.tmin = None
1026 self.tmin = None
1036 self.tmax = None
1027 self.tmax = None
1037
1028
1038 self.xmin = None
1029 self.xmin = None
1039 self.xmax = None
1030 self.xmax = None
1040
1031
1041 self.figfile = None
1032 self.figfile = None
1042
1033
1043 def getSubplots(self):
1034 def getSubplots(self):
1044
1035
1045 ncol = 1
1036 ncol = 1
1046 nrow = self.nplots
1037 nrow = self.nplots
1047
1038
1048 return nrow, ncol
1039 return nrow, ncol
1049
1040
1050 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1041 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1051
1042
1052 self.__showprofile = showprofile
1043 self.__showprofile = showprofile
1053 self.nplots = nplots
1044 self.nplots = nplots
1054
1045
1055 ncolspan = 1
1046 ncolspan = 1
1056 colspan = 1
1047 colspan = 1
1057
1048
1058 self.createFigure(id = id,
1049 self.createFigure(id = id,
1059 wintitle = wintitle,
1050 wintitle = wintitle,
1060 widthplot = self.WIDTH + self.WIDTHPROF,
1051 widthplot = self.WIDTH + self.WIDTHPROF,
1061 heightplot = self.HEIGHT + self.HEIGHTPROF,
1052 heightplot = self.HEIGHT + self.HEIGHTPROF,
1062 show=show)
1053 show=show)
1063
1054
1064 nrow, ncol = self.getSubplots()
1055 nrow, ncol = self.getSubplots()
1065
1056
1066 counter = 0
1057 counter = 0
1067 for y in range(nrow):
1058 for y in range(nrow):
1068 if counter >= self.nplots:
1059 if counter >= self.nplots:
1069 break
1060 break
1070
1061
1071 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1062 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1072 counter += 1
1063 counter += 1
1073
1064
1074 def run(self, dataOut, id, wintitle="", channelList=None,
1065 def run(self, dataOut, id, wintitle="", channelList=None,
1075 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1066 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1076 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1067 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1077 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1068 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1078 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1069 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1079 server=None, folder=None, username=None, password=None,
1070 server=None, folder=None, username=None, password=None,
1080 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1071 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1081 """
1072 """
1082
1073
1083 Input:
1074 Input:
1084 dataOut :
1075 dataOut :
1085 id :
1076 id :
1086 wintitle :
1077 wintitle :
1087 channelList :
1078 channelList :
1088 showProfile :
1079 showProfile :
1089 xmin : None,
1080 xmin : None,
1090 xmax : None,
1081 xmax : None,
1091 ymin : None,
1082 ymin : None,
1092 ymax : None,
1083 ymax : None,
1093 zmin : None,
1084 zmin : None,
1094 zmax : None
1085 zmax : None
1095 """
1086 """
1096
1087
1097 if timerange is not None:
1088 if timerange is not None:
1098 self.timerange = timerange
1089 self.timerange = timerange
1099
1090
1100 tmin = None
1091 tmin = None
1101 tmax = None
1092 tmax = None
1102
1093
1103 x = dataOut.getTimeRange1()
1094 x = dataOut.getTimeRange1(dataOut.outputInterval)
1104 # y = dataOut.heightList
1095 # y = dataOut.heightList
1105 y = dataOut.heightList
1096 y = dataOut.heightList
1106
1097
1107 z = dataOut.data_output
1098 z = dataOut.data_output
1108 nplots = z.shape[0] #Number of wind dimensions estimated
1099 nplots = z.shape[0] #Number of wind dimensions estimated
1109 nplotsw = nplots
1100 nplotsw = nplots
1110
1101
1111 #If there is a SNR function defined
1102 #If there is a SNR function defined
1112 if dataOut.data_SNR is not None:
1103 if dataOut.data_SNR is not None:
1113 nplots += 1
1104 nplots += 1
1114 SNR = dataOut.data_SNR
1105 SNR = dataOut.data_SNR
1115
1106
1116 if SNR_1:
1107 if SNR_1:
1117 SNR += 1
1108 SNR += 1
1118
1109
1119 SNRavg = numpy.average(SNR, axis=0)
1110 SNRavg = numpy.average(SNR, axis=0)
1120
1111
1121 SNRdB = 10*numpy.log10(SNR)
1112 SNRdB = 10*numpy.log10(SNR)
1122 SNRavgdB = 10*numpy.log10(SNRavg)
1113 SNRavgdB = 10*numpy.log10(SNRavg)
1123
1114
1124 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1115 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1125
1116
1126 for i in range(nplotsw):
1117 for i in range(nplotsw):
1127 z[i,ind] = numpy.nan
1118 z[i,ind] = numpy.nan
1128
1119
1129
1120
1130 showprofile = False
1121 showprofile = False
1131 # thisDatetime = dataOut.datatime
1122 # thisDatetime = dataOut.datatime
1132 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1123 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1133 title = wintitle + " EW Drifts"
1124 title = wintitle + " EW Drifts"
1134 xlabel = ""
1125 xlabel = ""
1135 ylabel = "Height (Km)"
1126 ylabel = "Height (Km)"
1136
1127
1137 if not self.isConfig:
1128 if not self.isConfig:
1138
1129
1139 self.setup(id=id,
1130 self.setup(id=id,
1140 nplots=nplots,
1131 nplots=nplots,
1141 wintitle=wintitle,
1132 wintitle=wintitle,
1142 showprofile=showprofile,
1133 showprofile=showprofile,
1143 show=show)
1134 show=show)
1144
1135
1145 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1136 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1146
1137
1147 if ymin == None: ymin = numpy.nanmin(y)
1138 if ymin == None: ymin = numpy.nanmin(y)
1148 if ymax == None: ymax = numpy.nanmax(y)
1139 if ymax == None: ymax = numpy.nanmax(y)
1149
1140
1150 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1141 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1151 if zminZonal == None: zminZonal = -zmaxZonal
1142 if zminZonal == None: zminZonal = -zmaxZonal
1152 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1143 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1153 if zminVertical == None: zminVertical = -zmaxVertical
1144 if zminVertical == None: zminVertical = -zmaxVertical
1154
1145
1155 if dataOut.data_SNR is not None:
1146 if dataOut.data_SNR is not None:
1156 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1147 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1157 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1148 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1158
1149
1159 self.FTP_WEI = ftp_wei
1150 self.FTP_WEI = ftp_wei
1160 self.EXP_CODE = exp_code
1151 self.EXP_CODE = exp_code
1161 self.SUB_EXP_CODE = sub_exp_code
1152 self.SUB_EXP_CODE = sub_exp_code
1162 self.PLOT_POS = plot_pos
1153 self.PLOT_POS = plot_pos
1163
1154
1164 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1155 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1165 self.isConfig = True
1156 self.isConfig = True
1166
1157
1167
1158
1168 self.setWinTitle(title)
1159 self.setWinTitle(title)
1169
1160
1170 if ((self.xmax - x[1]) < (x[1]-x[0])):
1161 if ((self.xmax - x[1]) < (x[1]-x[0])):
1171 x[1] = self.xmax
1162 x[1] = self.xmax
1172
1163
1173 strWind = ['Zonal','Vertical']
1164 strWind = ['Zonal','Vertical']
1174 strCb = 'Velocity (m/s)'
1165 strCb = 'Velocity (m/s)'
1175 zmaxVector = [zmaxZonal, zmaxVertical]
1166 zmaxVector = [zmaxZonal, zmaxVertical]
1176 zminVector = [zminZonal, zminVertical]
1167 zminVector = [zminZonal, zminVertical]
1177
1168
1178 for i in range(nplotsw):
1169 for i in range(nplotsw):
1179
1170
1180 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1171 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1181 axes = self.axesList[i*self.__nsubplots]
1172 axes = self.axesList[i*self.__nsubplots]
1182
1173
1183 z1 = z[i,:].reshape((1,-1))
1174 z1 = z[i,:].reshape((1,-1))
1184
1175
1185 axes.pcolorbuffer(x, y, z1,
1176 axes.pcolorbuffer(x, y, z1,
1186 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1177 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1187 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1178 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1188 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1179 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1189
1180
1190 if dataOut.data_SNR is not None:
1181 if dataOut.data_SNR is not None:
1191 i += 1
1182 i += 1
1192 if SNR_1:
1183 if SNR_1:
1193 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1184 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1194 else:
1185 else:
1195 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1186 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1196 axes = self.axesList[i*self.__nsubplots]
1187 axes = self.axesList[i*self.__nsubplots]
1197 SNRavgdB = SNRavgdB.reshape((1,-1))
1188 SNRavgdB = SNRavgdB.reshape((1,-1))
1198
1189
1199 axes.pcolorbuffer(x, y, SNRavgdB,
1190 axes.pcolorbuffer(x, y, SNRavgdB,
1200 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1191 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1201 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1192 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1202 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1193 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1203
1194
1204 self.draw()
1195 self.draw()
1205
1196
1206 if x[1] >= self.axesList[0].xmax:
1197 if x[1] >= self.axesList[0].xmax:
1207 self.counter_imagwr = wr_period
1198 self.counter_imagwr = wr_period
1208 self.isConfig = False
1199 self.isConfig = False
1209 self.figfile = None
1200 self.figfile = None
1210
1201
1211
1202
1212
1203
1213
1204
1214 class PhasePlot(Figure):
1205 class PhasePlot(Figure):
1215
1206
1216 __isConfig = None
1207 __isConfig = None
1217 __nsubplots = None
1208 __nsubplots = None
1218
1209
1219 PREFIX = 'mphase'
1210 PREFIX = 'mphase'
1220
1211
1221 def __init__(self):
1212 def __init__(self):
1222
1213
1223 self.timerange = 24*60*60
1214 self.timerange = 24*60*60
1224 self.isConfig = False
1215 self.isConfig = False
1225 self.__nsubplots = 1
1216 self.__nsubplots = 1
1226 self.counter_imagwr = 0
1217 self.counter_imagwr = 0
1227 self.WIDTH = 600
1218 self.WIDTH = 600
1228 self.HEIGHT = 300
1219 self.HEIGHT = 300
1229 self.WIDTHPROF = 120
1220 self.WIDTHPROF = 120
1230 self.HEIGHTPROF = 0
1221 self.HEIGHTPROF = 0
1231 self.xdata = None
1222 self.xdata = None
1232 self.ydata = None
1223 self.ydata = None
1233
1224
1234 self.PLOT_CODE = MPHASE_CODE
1225 self.PLOT_CODE = MPHASE_CODE
1235
1226
1236 self.FTP_WEI = None
1227 self.FTP_WEI = None
1237 self.EXP_CODE = None
1228 self.EXP_CODE = None
1238 self.SUB_EXP_CODE = None
1229 self.SUB_EXP_CODE = None
1239 self.PLOT_POS = None
1230 self.PLOT_POS = None
1240
1231
1241
1232
1242 self.filename_phase = None
1233 self.filename_phase = None
1243
1234
1244 self.figfile = None
1235 self.figfile = None
1245
1236
1246 def getSubplots(self):
1237 def getSubplots(self):
1247
1238
1248 ncol = 1
1239 ncol = 1
1249 nrow = 1
1240 nrow = 1
1250
1241
1251 return nrow, ncol
1242 return nrow, ncol
1252
1243
1253 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1244 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1254
1245
1255 self.__showprofile = showprofile
1246 self.__showprofile = showprofile
1256 self.nplots = nplots
1247 self.nplots = nplots
1257
1248
1258 ncolspan = 7
1249 ncolspan = 7
1259 colspan = 6
1250 colspan = 6
1260 self.__nsubplots = 2
1251 self.__nsubplots = 2
1261
1252
1262 self.createFigure(id = id,
1253 self.createFigure(id = id,
1263 wintitle = wintitle,
1254 wintitle = wintitle,
1264 widthplot = self.WIDTH+self.WIDTHPROF,
1255 widthplot = self.WIDTH+self.WIDTHPROF,
1265 heightplot = self.HEIGHT+self.HEIGHTPROF,
1256 heightplot = self.HEIGHT+self.HEIGHTPROF,
1266 show=show)
1257 show=show)
1267
1258
1268 nrow, ncol = self.getSubplots()
1259 nrow, ncol = self.getSubplots()
1269
1260
1270 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1261 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1271
1262
1272
1263
1273 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1264 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1274 xmin=None, xmax=None, ymin=None, ymax=None,
1265 xmin=None, xmax=None, ymin=None, ymax=None,
1275 timerange=None,
1266 timerange=None,
1276 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1267 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1277 server=None, folder=None, username=None, password=None,
1268 server=None, folder=None, username=None, password=None,
1278 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1269 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1279
1270
1280
1271
1281 tmin = None
1272 tmin = None
1282 tmax = None
1273 tmax = None
1283 x = dataOut.getTimeRange1()
1274 x = dataOut.getTimeRange1(dataOut.outputInterval)
1284 y = dataOut.getHeiRange()
1275 y = dataOut.getHeiRange()
1285
1276
1286
1277
1287 #thisDatetime = dataOut.datatime
1278 #thisDatetime = dataOut.datatime
1288 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
1279 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
1289 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1280 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1290 xlabel = "Local Time"
1281 xlabel = "Local Time"
1291 ylabel = "Phase"
1282 ylabel = "Phase"
1292
1283
1293
1284
1294 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1285 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1295 phase_beacon = dataOut.data_output
1286 phase_beacon = dataOut.data_output
1296 update_figfile = False
1287 update_figfile = False
1297
1288
1298 if not self.isConfig:
1289 if not self.isConfig:
1299
1290
1300 self.nplots = phase_beacon.size
1291 self.nplots = phase_beacon.size
1301
1292
1302 self.setup(id=id,
1293 self.setup(id=id,
1303 nplots=self.nplots,
1294 nplots=self.nplots,
1304 wintitle=wintitle,
1295 wintitle=wintitle,
1305 showprofile=showprofile,
1296 showprofile=showprofile,
1306 show=show)
1297 show=show)
1307
1298
1308 if timerange is not None:
1299 if timerange is not None:
1309 self.timerange = timerange
1300 self.timerange = timerange
1310
1301
1311 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1302 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1312
1303
1313 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1304 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1314 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1305 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1315
1306
1316 self.FTP_WEI = ftp_wei
1307 self.FTP_WEI = ftp_wei
1317 self.EXP_CODE = exp_code
1308 self.EXP_CODE = exp_code
1318 self.SUB_EXP_CODE = sub_exp_code
1309 self.SUB_EXP_CODE = sub_exp_code
1319 self.PLOT_POS = plot_pos
1310 self.PLOT_POS = plot_pos
1320
1311
1321 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1312 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1322 self.isConfig = True
1313 self.isConfig = True
1323 self.figfile = figfile
1314 self.figfile = figfile
1324 self.xdata = numpy.array([])
1315 self.xdata = numpy.array([])
1325 self.ydata = numpy.array([])
1316 self.ydata = numpy.array([])
1326
1317
1327 #open file beacon phase
1318 #open file beacon phase
1328 path = '%s%03d' %(self.PREFIX, self.id)
1319 path = '%s%03d' %(self.PREFIX, self.id)
1329 beacon_file = os.path.join(path,'%s.txt'%self.name)
1320 beacon_file = os.path.join(path,'%s.txt'%self.name)
1330 self.filename_phase = os.path.join(figpath,beacon_file)
1321 self.filename_phase = os.path.join(figpath,beacon_file)
1331 update_figfile = True
1322 update_figfile = True
1332
1323
1333
1324
1334 #store data beacon phase
1325 #store data beacon phase
1335 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1326 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1336
1327
1337 self.setWinTitle(title)
1328 self.setWinTitle(title)
1338
1329
1339
1330
1340 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1331 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1341
1332
1342 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1333 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1343
1334
1344 axes = self.axesList[0]
1335 axes = self.axesList[0]
1345
1336
1346 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1337 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1347
1338
1348 if len(self.ydata)==0:
1339 if len(self.ydata)==0:
1349 self.ydata = phase_beacon.reshape(-1,1)
1340 self.ydata = phase_beacon.reshape(-1,1)
1350 else:
1341 else:
1351 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1342 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1352
1343
1353
1344
1354 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1345 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1355 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1346 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1356 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1347 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1357 XAxisAsTime=True, grid='both'
1348 XAxisAsTime=True, grid='both'
1358 )
1349 )
1359
1350
1360 self.draw()
1351 self.draw()
1361
1352
1362 if dataOut.ltctime >= self.xmax:
1353 if dataOut.ltctime >= self.xmax:
1363 self.counter_imagwr = wr_period
1354 self.counter_imagwr = wr_period
1364 self.isConfig = False
1355 self.isConfig = False
1365 update_figfile = True
1356 update_figfile = True
1366
1357
1367 self.save(figpath=figpath,
1358 self.save(figpath=figpath,
1368 figfile=figfile,
1359 figfile=figfile,
1369 save=save,
1360 save=save,
1370 ftp=ftp,
1361 ftp=ftp,
1371 wr_period=wr_period,
1362 wr_period=wr_period,
1372 thisDatetime=thisDatetime,
1363 thisDatetime=thisDatetime,
1373 update_figfile=update_figfile)
1364 update_figfile=update_figfile)
This diff has been collapsed as it changes many lines, (650 lines changed) Show them Hide them
@@ -1,1026 +1,1054
1 import numpy
1 import numpy
2 import time
2 import time
3 import os
3 import os
4 import h5py
4 import h5py
5 import re
5 import re
6 import datetime
6
7
7 from schainpy.model.data.jrodata import *
8 from schainpy.model.data.jrodata import *
8 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
10 # from jroIO_base import *
9 from schainpy.model.io.jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
12 import schainpy
10
13
11
14
12 class HDF5Reader(ProcessingUnit):
15 class HDF5Reader(ProcessingUnit):
16 '''
17 Reads HDF5 format files
18
19 path
20
21 startDate
22
23 endDate
24
25 startTime
26
27 endTime
28 '''
13
29
14 ext = ".hdf5"
30 ext = ".hdf5"
15
31
16 optchar = "D"
32 optchar = "D"
17
33
18 timezone = None
34 timezone = None
19
35
20 secStart = None
36 startTime = None
21
37
22 secEnd = None
38 endTime = None
23
39
24 fileIndex = None
40 fileIndex = None
25
41
26 blockIndex = None
42 utcList = None #To select data in the utctime list
27
43
28 blocksPerFile = None
44 blockList = None #List to blocks to be read from the file
45
46 blocksPerFile = None #Number of blocks to be read
47
48 blockIndex = None
29
49
30 path = None
50 path = None
31
51
32 #List of Files
52 #List of Files
33
53
34 filenameList = None
54 filenameList = None
35
55
36 datetimeList = None
56 datetimeList = None
37
57
38 #Hdf5 File
58 #Hdf5 File
39
59
40 fpMetadata = None
41
42 pathMeta = None
43
44 listMetaname = None
60 listMetaname = None
45
61
46 listMeta = None
62 listMeta = None
47
63
48 listDataname = None
64 listDataname = None
49
65
50 listData = None
66 listData = None
51
67
52 listShapes = None
68 listShapes = None
53
69
54 fp = None
70 fp = None
55
71
56 #dataOut reconstruction
72 #dataOut reconstruction
57
73
58 dataOut = None
74 dataOut = None
59
75
60 nRecords = None
61
62
76
63 def __init__(self):
77 def __init__(self):
64 self.dataOut = self.__createObjByDefault()
78 self.dataOut = Parameters()
65 return
79 return
66
80
67 def __createObjByDefault(self):
81 def setup(self, **kwargs):
68
69 dataObj = Parameters()
70
71 return dataObj
72
73 def setup(self,path=None,
74 startDate=None,
75 endDate=None,
76 startTime=datetime.time(0,0,0),
77 endTime=datetime.time(23,59,59),
78 walk=True,
79 timezone='ut',
80 all=0,
81 online=False,
82 ext=None):
83
82
84 if ext==None:
83 path = kwargs['path']
85 ext = self.ext
84 startDate = kwargs['startDate']
86 self.timezone = timezone
85 endDate = kwargs['endDate']
87 # self.all = all
86 startTime = kwargs['startTime']
88 # self.online = online
87 endTime = kwargs['endTime']
89 self.path = path
88 walk = kwargs['walk']
90
89 if kwargs.has_key('ext'):
91 startDateTime = datetime.datetime.combine(startDate,startTime)
90 ext = kwargs['ext']
92 endDateTime = datetime.datetime.combine(endDate,endTime)
93 secStart = (startDateTime-datetime.datetime(1970,1,1)).total_seconds()
94 secEnd = (endDateTime-datetime.datetime(1970,1,1)).total_seconds()
95
96 self.secStart = secStart
97 self.secEnd = secEnd
98
99 if not(online):
100 #Busqueda de archivos offline
101 self.__searchFilesOffline(path, startDate, endDate, ext, startTime, endTime, secStart, secEnd, walk)
102 else:
91 else:
103 self.__searchFilesOnline(path, walk)
92 ext = '.hdf5'
93
94 print "[Reading] Searching files in offline mode ..."
95 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
96 startTime=startTime, endTime=endTime,
97 ext=ext, walk=walk)
104
98
105 if not(self.filenameList):
99 if not(filenameList):
106 print "There is no files into the folder: %s"%(path)
100 print "There is no files into the folder: %s"%(path)
107 sys.exit(-1)
101 sys.exit(-1)
108
102
109 # self.__getExpParameters()
110
111 self.fileIndex = -1
103 self.fileIndex = -1
112
104 self.startTime = startTime
113 self.__setNextFileOffline()
105 self.endTime = endTime
114
106
115 self.__readMetadata()
107 self.__readMetadata()
116
108
117 self.blockIndex = 0
109 self.__setNextFileOffline()
118
110
119 return
111 return
120
112
121 def __searchFilesOffline(self,
113 def __searchFilesOffLine(self,
122 path,
114 path,
123 startDate,
115 startDate=None,
124 endDate,
116 endDate=None,
125 ext,
126 startTime=datetime.time(0,0,0),
117 startTime=datetime.time(0,0,0),
127 endTime=datetime.time(23,59,59),
118 endTime=datetime.time(23,59,59),
128 secStart = 0,
119 ext='.hdf5',
129 secEnd = numpy.inf,
130 walk=True):
120 walk=True):
131
121
132 # self.__setParameters(path, startDate, endDate, startTime, endTime, walk)
122 expLabel = ''
133 #
123 self.filenameList = []
134 # self.__checkPath()
124 self.datetimeList = []
135 #
136 # self.__findDataForDates()
137 #
138 # self.__selectDataForTimes()
139 #
140 # for i in range(len(self.filenameList)):
141 # print "%s" %(self.filenameList[i])
142
125
143 pathList = []
126 pathList = []
144
127
145 if not walk:
128 JRODataObj = JRODataReader()
146 #pathList.append(path)
129 dateList, pathList = JRODataObj.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True)
147 multi_path = path.split(',')
148 for single_path in multi_path:
149 pathList.append(single_path)
150
130
151 else:
131 if dateList == []:
152 #dirList = []
132 print "[Reading] No *%s files in %s from %s to %s)"%(ext, path,
153 multi_path = path.split(',')
133 datetime.datetime.combine(startDate,startTime).ctime(),
154 for single_path in multi_path:
134 datetime.datetime.combine(endDate,endTime).ctime())
155 dirList = []
156 for thisPath in os.listdir(single_path):
157 if not os.path.isdir(os.path.join(single_path,thisPath)):
158 continue
159 if not isDoyFolder(thisPath):
160 continue
161
162 dirList.append(thisPath)
163
164 if not(dirList):
165 return None, None
166
167 thisDate = startDate
168
135
169 while(thisDate <= endDate):
170 year = thisDate.timetuple().tm_year
171 doy = thisDate.timetuple().tm_yday
172
173 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
174 if len(matchlist) == 0:
175 thisDate += datetime.timedelta(1)
176 continue
177 for match in matchlist:
178 pathList.append(os.path.join(single_path,match))
179
180 thisDate += datetime.timedelta(1)
181
182 if pathList == []:
183 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
184 return None, None
136 return None, None
185
137
186 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
138 if len(dateList) > 1:
139 print "[Reading] %d days were found in date range: %s - %s" %(len(dateList), startDate, endDate)
140 else:
141 print "[Reading] data was found for the date %s" %(dateList[0])
187
142
188 filenameList = []
143 filenameList = []
189 datetimeList = []
144 datetimeList = []
190 pathDict = {}
191 filenameList_to_sort = []
192
193 for i in range(len(pathList)):
194
145
195 thisPath = pathList[i]
146 #----------------------------------------------------------------------------------
196
147
197 fileList = glob.glob1(thisPath, "*%s" %ext)
148 for thisPath in pathList:
198 fileList.sort()
149 # thisPath = pathList[pathDict[file]]
199 pathDict.setdefault(fileList[0])
200 pathDict[fileList[0]] = i
201 filenameList_to_sort.append(fileList[0])
202
203 filenameList_to_sort.sort()
204
205 for file in filenameList_to_sort:
206 thisPath = pathList[pathDict[file]]
207
150
208 fileList = glob.glob1(thisPath, "*%s" %ext)
151 fileList = glob.glob1(thisPath, "*%s" %ext)
209 fileList.sort()
152 fileList.sort()
210
153
211 for file in fileList:
154 for file in fileList:
212
155
213 filename = os.path.join(thisPath,file)
156 filename = os.path.join(thisPath,file)
214 thisDatetime = self.__isFileinThisTime(filename, secStart, secEnd)
157
158 if not isFileInDateRange(filename, startDate, endDate):
159 continue
160
161 thisDatetime = self.__isFileInTimeRange(filename, startDate, endDate, startTime, endTime)
215
162
216 if not(thisDatetime):
163 if not(thisDatetime):
217 continue
164 continue
218
165
219 filenameList.append(filename)
166 filenameList.append(filename)
220 datetimeList.append(thisDatetime)
167 datetimeList.append(thisDatetime)
221
168
222 if not(filenameList):
169 if not(filenameList):
223 print "Any file was found for the time range %s - %s" %(startTime, endTime)
170 print "[Reading] Any file was found int time range %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
224 return None, None
171 return None, None
225
172
226 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
173 print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime)
227 print
174 print
228
175
229 for i in range(len(filenameList)):
176 for i in range(len(filenameList)):
230 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
177 print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
231
178
232 self.filenameList = filenameList
179 self.filenameList = filenameList
233 self.datetimeList = datetimeList
180 self.datetimeList = datetimeList
234
181
235 return pathList, filenameList
182 return pathList, filenameList
236
183
237 def __isFileinThisTime(self, filename, startSeconds, endSeconds):
184 def __isFileInTimeRange(self,filename, startDate, endDate, startTime, endTime):
185
238 """
186 """
239 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
187 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
240
188
241 Inputs:
189 Inputs:
242 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
190 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
243
191
192 startDate : fecha inicial del rango seleccionado en formato datetime.date
193
194 endDate : fecha final del rango seleccionado en formato datetime.date
195
244 startTime : tiempo inicial del rango seleccionado en formato datetime.time
196 startTime : tiempo inicial del rango seleccionado en formato datetime.time
245
197
246 endTime : tiempo final del rango seleccionado en formato datetime.time
198 endTime : tiempo final del rango seleccionado en formato datetime.time
247
199
248 Return:
200 Return:
249 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
201 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
250 fecha especificado, de lo contrario retorna False.
202 fecha especificado, de lo contrario retorna False.
251
203
252 Excepciones:
204 Excepciones:
253 Si el archivo no existe o no puede ser abierto
205 Si el archivo no existe o no puede ser abierto
254 Si la cabecera no puede ser leida.
206 Si la cabecera no puede ser leida.
255
207
256 """
208 """
257
209
258 try:
210 try:
259 fp = fp = h5py.File(filename,'r')
211 fp = h5py.File(filename,'r')
212 grp1 = fp['Data']
213
260 except IOError:
214 except IOError:
261 traceback.print_exc()
215 traceback.print_exc()
262 raise IOError, "The file %s can't be opened" %(filename)
216 raise IOError, "The file %s can't be opened" %(filename)
263
217 #chino rata
264 grp = fp['Data']
218 #In case has utctime attribute
265 timeAux = grp['time']
219 grp2 = grp1['utctime']
266 time0 = timeAux[:][0].astype(numpy.float) #Time Vector
220 # thisUtcTime = grp2.value[0] - 5*3600 #To convert to local time
221 thisUtcTime = grp2.value[0]
267
222
268 fp.close()
223 fp.close()
269
224
270 if self.timezone == 'lt':
225 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0])
271 time0 -= 5*3600
226 thisDate = thisDatetime.date()
227 thisTime = thisDatetime.time()
272
228
273 boolTimer = numpy.logical_and(time0 >= startSeconds,time0 < endSeconds)
229 startUtcTime = (datetime.datetime.combine(thisDate,startTime)- datetime.datetime(1970, 1, 1)).total_seconds()
230 endUtcTime = (datetime.datetime.combine(thisDate,endTime)- datetime.datetime(1970, 1, 1)).total_seconds()
274
231
275 if not (numpy.any(boolTimer)):
232 #General case
276 return None
233 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
234 #-----------o----------------------------o-----------
235 # startTime endTime
277
236
278 thisDatetime = datetime.datetime.utcfromtimestamp(time0[0])
237 if endTime >= startTime:
238 thisUtcLog = numpy.logical_and(thisUtcTime > startUtcTime, thisUtcTime < endUtcTime)
239 if numpy.any(thisUtcLog): #If there is one block between the hours mentioned
279 return thisDatetime
240 return thisDatetime
241 return None
280
242
281 def __checkPath(self):
243 #If endTime < startTime then endTime belongs to the next day
282 if os.path.exists(self.path):
244 #<<<<<<<<<<<o o>>>>>>>>>>>
283 self.status = 1
245 #-----------o----------------------------o-----------
284 else:
246 # endTime startTime
285 self.status = 0
286 print 'Path:%s does not exists'%self.path
287
247
288 return
248 if (thisDate == startDate) and numpy.all(thisUtcTime < startUtcTime):
249 return None
250
251 if (thisDate == endDate) and numpy.all(thisUtcTime > endUtcTime):
252 return None
253
254 if numpy.all(thisUtcTime < startUtcTime) and numpy.all(thisUtcTime > endUtcTime):
255 return None
256
257 return thisDatetime
289
258
290 def __setNextFileOffline(self):
259 def __setNextFileOffline(self):
260
261 self.fileIndex += 1
291 idFile = self.fileIndex
262 idFile = self.fileIndex
292 idFile += 1
293
263
294 if not(idFile < len(self.filenameList)):
264 if not(idFile < len(self.filenameList)):
295 print "No more Files"
265 print "No more Files"
296 return 0
266 return 0
297
267
298 filename = self.filenameList[idFile]
268 filename = self.filenameList[idFile]
299
269
300 filePointer = h5py.File(filename,'r')
270 filePointer = h5py.File(filename,'r')
301
271
302 self.flagIsNewFile = 1
303 self.fileIndex = idFile
304 self.filename = filename
272 self.filename = filename
305
273
306 self.fp = filePointer
274 self.fp = filePointer
307
275
308 print "Setting the file: %s"%self.filename
276 print "Setting the file: %s"%self.filename
309
277
310 self.__readMetadata()
278 # self.__readMetadata()
311 self.__setBlockList()
279 self.__setBlockList()
280 self.__readData()
312 # self.nRecords = self.fp['Data'].attrs['blocksPerFile']
281 # self.nRecords = self.fp['Data'].attrs['blocksPerFile']
313 self.nRecords = self.fp['Data'].attrs['nRecords']
282 # self.nRecords = self.fp['Data'].attrs['nRecords']
314 self.blockIndex = 0
283 self.blockIndex = 0
315 return 1
284 return 1
316
285
317 def __setBlockList(self):
286 def __setBlockList(self):
318 '''
287 '''
288 Selects the data within the times defined
289
319 self.fp
290 self.fp
320 self.startDateTime
291 self.startTime
321 self.endDateTime
292 self.endTime
322
293
323 self.blockList
294 self.blockList
324 self.blocksPerFile
295 self.blocksPerFile
325
296
326 '''
297 '''
327 filePointer = self.fp
298 fp = self.fp
328 secStart = self.secStart
299 startTime = self.startTime
329 secEnd = self.secEnd
300 endTime = self.endTime
330
301
331 grp = filePointer['Data']
302 grp = fp['Data']
332 timeVector = grp['time'].value.astype(numpy.float)[0]
303 thisUtcTime = grp['utctime'].value.astype(numpy.float)[0]
333
304
334 if self.timezone == 'lt':
305 if self.timezone == 'lt':
335 timeVector -= 5*3600
306 thisUtcTime -= 5*3600
307
308 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0])
309 thisDate = thisDatetime.date()
310 thisTime = thisDatetime.time()
311
312 startUtcTime = (datetime.datetime.combine(thisDate,startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
313 endUtcTime = (datetime.datetime.combine(thisDate,endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
336
314
337 ind = numpy.where(numpy.logical_and(timeVector >= secStart , timeVector < secEnd))[0]
315 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
338
316
339 self.blockList = ind
317 self.blockList = ind
340 self.blocksPerFile = len(ind)
318 self.blocksPerFile = len(ind)
341
319
342 return
320 return
343
321
344 def __readMetadata(self):
322 def __readMetadata(self):
345 '''
323 '''
324 Reads Metadata
325
346 self.pathMeta
326 self.pathMeta
347
327
348 self.listShapes
328 self.listShapes
349 self.listMetaname
329 self.listMetaname
350 self.listMeta
330 self.listMeta
351
331
352 '''
332 '''
353
333
354 grp = self.fp['Data']
334 # grp = self.fp['Data']
355 pathMeta = os.path.join(self.path, grp.attrs['metadata'])
335 # pathMeta = os.path.join(self.path, grp.attrs['metadata'])
336 #
337 # if pathMeta == self.pathMeta:
338 # return
339 # else:
340 # self.pathMeta = pathMeta
341 #
342 # filePointer = h5py.File(self.pathMeta,'r')
343 # groupPointer = filePointer['Metadata']
356
344
357 if pathMeta == self.pathMeta:
345 filename = self.filenameList[0]
358 return
346
359 else:
347 fp = h5py.File(filename,'r')
360 self.pathMeta = pathMeta
361
348
362 filePointer = h5py.File(self.pathMeta,'r')
349 gp = fp['Metadata']
363 groupPointer = filePointer['Metadata']
364
350
365 listMetaname = []
351 listMetaname = []
366 listMetadata = []
352 listMetadata = []
367 for item in groupPointer.items():
353 for item in gp.items():
368 name = item[0]
354 name = item[0]
369
355
370 if name=='array dimensions':
356 if name=='array dimensions':
371 table = groupPointer[name][:]
357 table = gp[name][:]
372 listShapes = {}
358 listShapes = {}
373 for shapes in table:
359 for shapes in table:
374 listShapes[shapes[0]] = numpy.array([shapes[1],shapes[2],shapes[3],shapes[4]])
360 listShapes[shapes[0]] = numpy.array([shapes[1],shapes[2],shapes[3],shapes[4],shapes[5]])
375 else:
361 else:
376 data = groupPointer[name].value
362 data = gp[name].value
377 listMetaname.append(name)
363 listMetaname.append(name)
378 listMetadata.append(data)
364 listMetadata.append(data)
379
365
380 if name=='type':
366 # if name=='type':
381 self.__initDataOut(data)
367 # self.__initDataOut(data)
382
383 filePointer.close()
384
368
385 self.listShapes = listShapes
369 self.listShapes = listShapes
386 self.listMetaname = listMetaname
370 self.listMetaname = listMetaname
387 self.listMeta = listMetadata
371 self.listMeta = listMetadata
388
372
373 fp.close()
389 return
374 return
390
375
391 def __readData(self):
376 def __readData(self):
392 grp = self.fp['Data']
377 grp = self.fp['Data']
393 listdataname = []
378 listdataname = []
394 listdata = []
379 listdata = []
395
380
396 for item in grp.items():
381 for item in grp.items():
397 name = item[0]
382 name = item[0]
398
399 if name == 'time':
400 listdataname.append('utctime')
401 timeAux = grp[name].value.astype(numpy.float)[0]
402 listdata.append(timeAux)
403 continue
404
405 listdataname.append(name)
383 listdataname.append(name)
406 array = self.__setDataArray(self.nRecords, grp[name],self.listShapes[name])
384
385 array = self.__setDataArray(grp[name],self.listShapes[name])
407 listdata.append(array)
386 listdata.append(array)
408
387
409 self.listDataname = listdataname
388 self.listDataname = listdataname
410 self.listData = listdata
389 self.listData = listdata
411 return
390 return
412
391
413 def __setDataArray(self, nRecords, dataset, shapes):
392 def __setDataArray(self, dataset, shapes):
414
393
415 nChannels = shapes[0] #Dimension 0
394 nDims = shapes[0]
416
395
417 nPoints = shapes[1] #Dimension 1, number of Points or Parameters
396 nDim2 = shapes[1] #Dimension 0
418
397
419 nSamples = shapes[2] #Dimension 2, number of samples or ranges
398 nDim1 = shapes[2] #Dimension 1, number of Points or Parameters
420
399
421 mode = shapes[3]
400 nDim0 = shapes[3] #Dimension 2, number of samples or ranges
422
401
423 # if nPoints>1:
402 mode = shapes[4] #Mode of storing
424 # arrayData = numpy.zeros((nRecords,nChannels,nPoints,nSamples))
403
425 # else:
404 blockList = self.blockList
426 # arrayData = numpy.zeros((nRecords,nChannels,nSamples))
405
427 #
406 blocksPerFile = self.blocksPerFile
428 # chn = 'channel'
407
429 #
408 #Depending on what mode the data was stored
430 # for i in range(nChannels):
409 # if mode == 0: #Divided in channels
431 #
410 # strds = 'channel'
432 # data = dataset[chn + str(i)].value
411 # nDatas = nDim2
433 #
412 # newShapes = (blocksPerFile,nDim1,nDim0)
434 # if nPoints>1:
413 if mode == 1: #Divided in parameter
435 # data = numpy.rollaxis(data,2)
436 #
437 # arrayData[:,i,:] = data
438
439 arrayData = numpy.zeros((nRecords,nChannels,nPoints,nSamples))
440 doSqueeze = False
441 if mode == 0:
442 strds = 'channel'
443 nDatas = nChannels
444 newShapes = (nRecords,nPoints,nSamples)
445 if nPoints == 1:
446 doSqueeze = True
447 axisSqueeze = 2
448 else:
449 strds = 'param'
414 strds = 'param'
450 nDatas = nPoints
415 nDatas = nDim1
451 newShapes = (nRecords,nChannels,nSamples)
416 newShapes = (blocksPerFile,nDim2,nDim0)
452 if nChannels == 1:
417 elif mode==2: #Concatenated in a table
453 doSqueeze = True
418 strds = 'table0'
454 axisSqueeze = 1
419 arrayData = dataset[strds].value
420 #Selecting part of the dataset
421 utctime = arrayData[:,0]
422 u, indices = numpy.unique(utctime, return_index=True)
423
424 if blockList.size != indices.size:
425 indMin = indices[blockList[0]]
426 indMax = indices[blockList[-1] + 1]
427 arrayData = arrayData[indMin:indMax,:]
428 return arrayData
455
429
456 for i in range(nDatas):
430 #------- One dimension ---------------
431 if nDims == 1:
432 arrayData = dataset.value.astype(numpy.float)[0][blockList]
433
434 #------- Two dimensions -----------
435 elif nDims == 2:
436 arrayData = numpy.zeros((blocksPerFile,nDim1,nDim0))
437 newShapes = (blocksPerFile,nDim0)
438 nDatas = nDim1
457
439
440 for i in range(nDatas):
458 data = dataset[strds + str(i)].value
441 data = dataset[strds + str(i)].value
459 data = data.reshape(newShapes)
442 arrayData[:,i,:] = data[blockList,:]
460
443
461 if mode == 0:
444 #------- Three dimensions ---------
462 arrayData[:,i,:,:] = data
463 else:
445 else:
464 arrayData[:,:,i,:] = data
446 arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0))
447 for i in range(nDatas):
465
448
466 if doSqueeze:
449 data = dataset[strds + str(i)].value
467 arrayData = numpy.squeeze(arrayData, axis=axisSqueeze)
450 data = data[blockList,:,:]
451 data = data.reshape(newShapes)
452 # if mode == 0:
453 # arrayData[:,i,:,:] = data
454 # else:
455 arrayData[:,:,i,:] = data
468
456
469 return arrayData
457 return arrayData
470
458
471 def __initDataOut(self, type):
472
473 # if type =='Parameters':
474 # self.dataOut = Parameters()
475 # elif type =='Spectra':
476 # self.dataOut = Spectra()
477 # elif type =='Voltage':
478 # self.dataOut = Voltage()
479 # elif type =='Correlation':
480 # self.dataOut = Correlation()
481
482 return
483
484 def __setDataOut(self):
459 def __setDataOut(self):
485 listMeta = self.listMeta
460 listMeta = self.listMeta
486 listMetaname = self.listMetaname
461 listMetaname = self.listMetaname
487 listDataname = self.listDataname
462 listDataname = self.listDataname
488 listData = self.listData
463 listData = self.listData
464 listShapes = self.listShapes
489
465
490 blockIndex = self.blockIndex
466 blockIndex = self.blockIndex
491 blockList = self.blockList
467 # blockList = self.blockList
492
468
493 for i in range(len(listMeta)):
469 for i in range(len(listMeta)):
494 setattr(self.dataOut,listMetaname[i],listMeta[i])
470 setattr(self.dataOut,listMetaname[i],listMeta[i])
495
471
496 for j in range(len(listData)):
472 for j in range(len(listData)):
497 if listDataname[j]=='utctime':
473 nShapes = listShapes[listDataname[j]][0]
498 # setattr(self.dataOut,listDataname[j],listData[j][blockList[blockIndex]])
474 mode = listShapes[listDataname[j]][4]
499 setattr(self.dataOut,'utctimeInit',listData[j][blockList[blockIndex]])
475 if nShapes == 1:
500 continue
476 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
477 elif nShapes > 1:
478 setattr(self.dataOut,listDataname[j],listData[j][blockIndex,:])
479 #Mode Meteors
480 elif mode ==2:
481 selectedData = self.__selectDataMode2(listData[j], blockIndex)
482 setattr(self.dataOut, listDataname[j], selectedData)
483 return
501
484
502 setattr(self.dataOut,listDataname[j],listData[j][blockList[blockIndex],:])
485 def __selectDataMode2(self, data, blockIndex):
486 utctime = data[:,0]
487 aux, indices = numpy.unique(utctime, return_inverse=True)
488 selInd = numpy.where(indices == blockIndex)[0]
489 selData = data[selInd,:]
503
490
504 return self.dataOut.data_param
491 return selData
505
492
506 def getData(self):
493 def getData(self):
507
494
508 # if self.flagNoMoreFiles:
495 # if self.flagNoMoreFiles:
509 # self.dataOut.flagNoData = True
496 # self.dataOut.flagNoData = True
510 # print 'Process finished'
497 # print 'Process finished'
511 # return 0
498 # return 0
512 #
499 #
513 if self.blockIndex==self.blocksPerFile:
500 if self.blockIndex==self.blocksPerFile:
514 if not( self.__setNextFileOffline() ):
501 if not( self.__setNextFileOffline() ):
515 self.dataOut.flagNoData = True
502 self.dataOut.flagNoData = True
516 return 0
503 return 0
517
504
518 #
519 # if self.datablock == None: # setear esta condicion cuando no hayan datos por leers
505 # if self.datablock == None: # setear esta condicion cuando no hayan datos por leers
520 # self.dataOut.flagNoData = True
506 # self.dataOut.flagNoData = True
521 # return 0
507 # return 0
522
508 # self.__readData()
523 self.__readData()
524 self.__setDataOut()
509 self.__setDataOut()
525 self.dataOut.flagNoData = False
510 self.dataOut.flagNoData = False
526
511
527 self.blockIndex += 1
512 self.blockIndex += 1
528
513
529 return
514 return
530
515
531 def run(self, **kwargs):
516 def run(self, **kwargs):
532
517
533 if not(self.isConfig):
518 if not(self.isConfig):
534 self.setup(**kwargs)
519 self.setup(**kwargs)
535 # self.setObjProperties()
520 # self.setObjProperties()
536 self.isConfig = True
521 self.isConfig = True
537
522
538 self.getData()
523 self.getData()
539
524
540 return
525 return
541
526
542 class HDF5Writer(Operation):
527 class HDF5Writer(Operation):
528 '''
529 HDF5 Writer, stores parameters data in HDF5 format files
530
531 path: path where the files will be stored
532
533 blocksPerFile: number of blocks that will be saved in per HDF5 format file
534
535 mode: selects the data stacking mode: '0' channels, '1' parameters, '3' table (for meteors)
536
537 metadataList: list of attributes that will be stored as metadata
538
539 dataList: list of attributes that will be stores as data
540
541 '''
542
543
543
544 ext = ".hdf5"
544 ext = ".hdf5"
545
545
546 optchar = "D"
546 optchar = "D"
547
547
548 metaoptchar = "M"
548 metaoptchar = "M"
549
549
550 metaFile = None
550 metaFile = None
551
551
552 filename = None
552 filename = None
553
553
554 path = None
554 path = None
555
555
556 setFile = None
556 setFile = None
557
557
558 fp = None
558 fp = None
559
559
560 grp = None
560 grp = None
561
561
562 ds = None
562 ds = None
563
563
564 firsttime = True
564 firsttime = True
565
565
566 #Configurations
566 #Configurations
567
567
568 blocksPerFile = None
568 blocksPerFile = None
569
569
570 blockIndex = None
570 blockIndex = None
571
571
572 dataOut = None
572 dataOut = None
573
573
574 #Data Arrays
574 #Data Arrays
575
575
576 dataList = None
576 dataList = None
577
577
578 metadataList = None
578 metadataList = None
579
579
580 arrayDim = None
580 arrayDim = None
581
581
582 tableDim = None
582 tableDim = None
583
583
584 # dtype = [('arrayName', 'S20'),('nChannels', 'i'), ('nPoints', 'i'), ('nSamples', 'i'),('mode', 'b')]
584 # dtype = [('arrayName', 'S20'),('nChannels', 'i'), ('nPoints', 'i'), ('nSamples', 'i'),('mode', 'b')]
585
585
586 dtype = [('arrayName', 'S20'),('nDimensions', 'i'), ('dim2', 'i'), ('dim1', 'i'),('dim0', 'i'),('mode', 'b')]
586 dtype = [('arrayName', 'S20'),('nDimensions', 'i'), ('dim2', 'i'), ('dim1', 'i'),('dim0', 'i'),('mode', 'b')]
587
587
588 mode = None
588 mode = None
589
589
590 nDatas = None #Number of datasets to be stored per array
590 nDatas = None #Number of datasets to be stored per array
591
591
592 nDims = None #Number Dimensions in each dataset
592 nDims = None #Number Dimensions in each dataset
593
593
594 nDimsForDs = None
594 nDimsForDs = None
595
595
596 currentDay = None
596 currentDay = None
597
597
598 def __init__(self):
598 def __init__(self):
599
599
600 Operation.__init__(self)
600 Operation.__init__(self)
601 self.isConfig = False
601 self.isConfig = False
602 return
602 return
603
603
604 def setup(self, dataOut, **kwargs):
604 def setup(self, dataOut, **kwargs):
605
605
606 self.path = kwargs['path']
606 self.path = kwargs['path']
607
607
608 if kwargs.has_key('ext'):
609 self.ext = kwargs['ext']
610
611 if kwargs.has_key('blocksPerFile'):
608 if kwargs.has_key('blocksPerFile'):
612 self.blocksPerFile = kwargs['blocksPerFile']
609 self.blocksPerFile = kwargs['blocksPerFile']
613 else:
610 else:
614 self.blocksPerFile = 10
611 self.blocksPerFile = 10
615
612
616 self.metadataList = kwargs['metadataList']
613 self.metadataList = kwargs['metadataList']
617
614
618 self.dataList = kwargs['dataList']
615 self.dataList = kwargs['dataList']
619
616
620 self.dataOut = dataOut
617 self.dataOut = dataOut
621
618
622 if kwargs.has_key('mode'):
619 if kwargs.has_key('mode'):
623 mode = kwargs['mode']
620 mode = kwargs['mode']
624
621
625 if type(mode) == int:
622 if type(mode) == int:
626 mode = numpy.zeros(len(self.dataList)) + mode
623 mode = numpy.zeros(len(self.dataList)) + mode
627 else:
624 else:
628 mode = numpy.zeros(len(self.dataList))
625 mode = numpy.ones(len(self.dataList))
629
626
630 self.mode = mode
627 self.mode = mode
631
628
632 arrayDim = numpy.zeros((len(self.dataList),5))
629 arrayDim = numpy.zeros((len(self.dataList),5))
633
630
634 #Table dimensions
631 #Table dimensions
635
632
636 dtype0 = self.dtype
633 dtype0 = self.dtype
637
634
638 tableList = []
635 tableList = []
639
636
640 for i in range(len(self.dataList)):
637 for i in range(len(self.dataList)):
641
638
642 dataAux = getattr(self.dataOut, self.dataList[i])
639 dataAux = getattr(self.dataOut, self.dataList[i])
643
640
641 #--------------------- Conditionals ------------------------
642 #There is no data
643 if dataAux == None:
644 return 0
645
646 #Not array, just a number
644 if type(dataAux)==float or type(dataAux)==int:
647 if type(dataAux)==float or type(dataAux)==int:
645 arrayDim[i,0] = 1
648 arrayDim[i,0] = 1
646 else:
649 mode[i] = 0
647
650
648 if dataAux == None:
651 #Mode meteors
649 return 0
652 elif mode[i] == 2:
653 arrayDim[i,3] = dataAux.shape[-1]
654 arrayDim[i,4] = mode[i] #Mode the data was stored
650
655
651 arrayDim0 = dataAux.shape
656 #All the rest
652 arrayDim[i,0] = len(arrayDim0)
657 else:
653 arrayDim[i,4] = mode[i]
658 arrayDim0 = dataAux.shape #Data dimensions
659 arrayDim[i,0] = len(arrayDim0) #Number of array dimensions
660 arrayDim[i,4] = mode[i] #Mode the data was stored
654
661
662 # Three-dimension arrays
655 if len(arrayDim0) == 3:
663 if len(arrayDim0) == 3:
656 arrayDim[i,1:-1] = numpy.array(arrayDim0)
664 arrayDim[i,1:-1] = numpy.array(arrayDim0)
665
666 # Two-dimension arrays
657 elif len(arrayDim0) == 2:
667 elif len(arrayDim0) == 2:
658 arrayDim[i,2:-1] = numpy.array(arrayDim0) #nHeights
668 arrayDim[i,2:-1] = numpy.array(arrayDim0)
669
670 # One-dimension arrays
659 elif len(arrayDim0) == 1:
671 elif len(arrayDim0) == 1:
660 arrayDim[i,3] = arrayDim0
672 arrayDim[i,3] = arrayDim0
673
674 # No array, just a number
661 elif len(arrayDim0) == 0:
675 elif len(arrayDim0) == 0:
662 arrayDim[i,0] = 1
676 arrayDim[i,0] = 1
663 arrayDim[i,3] = 1
677 arrayDim[i,3] = 1
664
678
665 table = numpy.array((self.dataList[i],) + tuple(arrayDim[i,:]),dtype = dtype0)
679 table = numpy.array((self.dataList[i],) + tuple(arrayDim[i,:]),dtype = dtype0)
666 tableList.append(table)
680 tableList.append(table)
667
681
668 self.arrayDim = arrayDim
682 self.arrayDim = arrayDim
669 self.tableDim = numpy.array(tableList, dtype = dtype0)
683 self.tableDim = numpy.array(tableList, dtype = dtype0)
670 self.blockIndex = 0
684 self.blockIndex = 0
671
685
672 timeTuple = time.localtime(dataOut.utctime)
686 timeTuple = time.localtime(dataOut.utctime)
673 self.currentDay = timeTuple.tm_yday
687 self.currentDay = timeTuple.tm_yday
674 return 1
688 return 1
675
689
676 def putMetadata(self):
690 def putMetadata(self):
677
691
678 fp = self.createMetadataFile()
692 fp = self.createMetadataFile()
679 self.writeMetadata(fp)
693 self.writeMetadata(fp)
680 fp.close()
694 fp.close()
681 return
695 return
682
696
683 def createMetadataFile(self):
697 def createMetadataFile(self):
684 ext = self.ext
698 ext = self.ext
685 path = self.path
699 path = self.path
686 setFile = self.setFile
700 setFile = self.setFile
687
701
688 timeTuple = time.localtime(self.dataOut.utctime)
702 timeTuple = time.localtime(self.dataOut.utctime)
689
703
690 subfolder = ''
704 subfolder = ''
691 fullpath = os.path.join( path, subfolder )
705 fullpath = os.path.join( path, subfolder )
692
706
693 if not( os.path.exists(fullpath) ):
707 if not( os.path.exists(fullpath) ):
694 os.mkdir(fullpath)
708 os.mkdir(fullpath)
695 setFile = -1 #inicializo mi contador de seteo
709 setFile = -1 #inicializo mi contador de seteo
696
710
697 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
711 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
698 fullpath = os.path.join( path, subfolder )
712 fullpath = os.path.join( path, subfolder )
699
713
700 if not( os.path.exists(fullpath) ):
714 if not( os.path.exists(fullpath) ):
701 os.mkdir(fullpath)
715 os.mkdir(fullpath)
702 setFile = -1 #inicializo mi contador de seteo
716 setFile = -1 #inicializo mi contador de seteo
703
717
704 else:
718 else:
705 filesList = os.listdir( fullpath )
719 filesList = os.listdir( fullpath )
706 filesList = sorted( filesList, key=str.lower )
720 filesList = sorted( filesList, key=str.lower )
707 if len( filesList ) > 0:
721 if len( filesList ) > 0:
708 filesList = [k for k in filesList if 'M' in k]
722 filesList = [k for k in filesList if 'M' in k]
709 filen = filesList[-1]
723 filen = filesList[-1]
710 # el filename debera tener el siguiente formato
724 # el filename debera tener el siguiente formato
711 # 0 1234 567 89A BCDE (hex)
725 # 0 1234 567 89A BCDE (hex)
712 # x YYYY DDD SSS .ext
726 # x YYYY DDD SSS .ext
713 if isNumber( filen[8:11] ):
727 if isNumber( filen[8:11] ):
714 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
728 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
715 else:
729 else:
716 setFile = -1
730 setFile = -1
717 else:
731 else:
718 setFile = -1 #inicializo mi contador de seteo
732 setFile = -1 #inicializo mi contador de seteo
719
733
720 setFile += 1
734 setFile += 1
721
735
722 file = '%s%4.4d%3.3d%3.3d%s' % (self.metaoptchar,
736 file = '%s%4.4d%3.3d%3.3d%s' % (self.metaoptchar,
723 timeTuple.tm_year,
737 timeTuple.tm_year,
724 timeTuple.tm_yday,
738 timeTuple.tm_yday,
725 setFile,
739 setFile,
726 ext )
740 ext )
727
741
728 filename = os.path.join( path, subfolder, file )
742 filename = os.path.join( path, subfolder, file )
729 self.metaFile = file
743 self.metaFile = file
730 #Setting HDF5 File
744 #Setting HDF5 File
731 fp = h5py.File(filename,'w')
745 fp = h5py.File(filename,'w')
732
746
733 return fp
747 return fp
734
748
735 def writeMetadata(self, fp):
749 def writeMetadata(self, fp):
736
750
737 grp = fp.create_group("Metadata")
751 grp = fp.create_group("Metadata")
738 grp.create_dataset('array dimensions', data = self.tableDim, dtype = self.dtype)
752 grp.create_dataset('array dimensions', data = self.tableDim, dtype = self.dtype)
739
753
740 for i in range(len(self.metadataList)):
754 for i in range(len(self.metadataList)):
741 grp.create_dataset(self.metadataList[i], data=getattr(self.dataOut, self.metadataList[i]))
755 grp.create_dataset(self.metadataList[i], data=getattr(self.dataOut, self.metadataList[i]))
742 return
756 return
743
757
744 def dateFlag(self):
758 def dateFlag(self):
745
759
746 timeTuple = time.localtime(self.dataOut.utctime)
760 timeTuple = time.localtime(self.dataOut.utctime)
747 dataDay = timeTuple.tm_yday
761 dataDay = timeTuple.tm_yday
748
762
749 if dataDay == self.currentDay:
763 if dataDay == self.currentDay:
750 return False
764 return False
751
765
752 self.currentDay = dataDay
766 self.currentDay = dataDay
753 return True
767 return True
754
768
755 def setNextFile(self):
769 def setNextFile(self):
756
770
757 ext = self.ext
771 ext = self.ext
758 path = self.path
772 path = self.path
759 setFile = self.setFile
773 setFile = self.setFile
760 mode = self.mode
774 mode = self.mode
761
775
762 timeTuple = time.localtime(self.dataOut.utctime)
776 timeTuple = time.localtime(self.dataOut.utctime)
763 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
777 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
764
778
765 fullpath = os.path.join( path, subfolder )
779 fullpath = os.path.join( path, subfolder )
766
780
767 if os.path.exists(fullpath):
781 if os.path.exists(fullpath):
768 filesList = os.listdir( fullpath )
782 filesList = os.listdir( fullpath )
769 filesList = [k for k in filesList if 'D' in k]
783 filesList = [k for k in filesList if 'D' in k]
770 if len( filesList ) > 0:
784 if len( filesList ) > 0:
771 filesList = sorted( filesList, key=str.lower )
785 filesList = sorted( filesList, key=str.lower )
772 filen = filesList[-1]
786 filen = filesList[-1]
773 # el filename debera tener el siguiente formato
787 # el filename debera tener el siguiente formato
774 # 0 1234 567 89A BCDE (hex)
788 # 0 1234 567 89A BCDE (hex)
775 # x YYYY DDD SSS .ext
789 # x YYYY DDD SSS .ext
776 if isNumber( filen[8:11] ):
790 if isNumber( filen[8:11] ):
777 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
791 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
778 else:
792 else:
779 setFile = -1
793 setFile = -1
780 else:
794 else:
781 setFile = -1 #inicializo mi contador de seteo
795 setFile = -1 #inicializo mi contador de seteo
782 else:
796 else:
783 os.mkdir(fullpath)
797 os.mkdir(fullpath)
784 setFile = -1 #inicializo mi contador de seteo
798 setFile = -1 #inicializo mi contador de seteo
785
799
786 setFile += 1
800 setFile += 1
787
801
788 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
802 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
789 timeTuple.tm_year,
803 timeTuple.tm_year,
790 timeTuple.tm_yday,
804 timeTuple.tm_yday,
791 setFile,
805 setFile,
792 ext )
806 ext )
793
807
794 filename = os.path.join( path, subfolder, file )
808 filename = os.path.join( path, subfolder, file )
795
809
796 #Setting HDF5 File
810 #Setting HDF5 File
797 fp = h5py.File(filename,'w')
811 fp = h5py.File(filename,'w')
798
812
799 #writemetadata
813 #writemetadata
800 self.writeMetadata(fp)
814 self.writeMetadata(fp)
801
815
802 grp = fp.create_group("Data")
816 grp = fp.create_group("Data")
803 # grp.attrs['metadata'] = self.metaFile
817 # grp.attrs['metadata'] = self.metaFile
804
818
805 # grp.attrs['blocksPerFile'] = 0
819 # grp.attrs['blocksPerFile'] = 0
806
820
807 ds = []
821 ds = []
808 data = []
822 data = []
809 nDimsForDs = []
823 nDimsForDs = []
810
824
811 nDatas = numpy.zeros(len(self.dataList))
825 nDatas = numpy.zeros(len(self.dataList))
812 nDims = self.arrayDim[:,0]
826 nDims = self.arrayDim[:,0]
813
827
814 nDim1 = self.arrayDim[:,2]
828 nDim1 = self.arrayDim[:,2]
815 nDim0 = self.arrayDim[:,3]
829 nDim0 = self.arrayDim[:,3]
816
830
817 for i in range(len(self.dataList)):
831 for i in range(len(self.dataList)):
818
832
833 #One-dimension data
819 if nDims[i]==1:
834 if nDims[i]==1:
820 # ds0 = grp.create_dataset(self.dataList[i], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype='S20')
835 # ds0 = grp.create_dataset(self.dataList[i], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype='S20')
821 ds0 = grp.create_dataset(self.dataList[i], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype=numpy.float64)
836 ds0 = grp.create_dataset(self.dataList[i], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype=numpy.float64)
822 ds.append(ds0)
837 ds.append(ds0)
823 data.append([])
838 data.append([])
824 nDimsForDs.append(nDims[i])
839 nDimsForDs.append(nDims[i])
825 else:
840 else:
826
841
827 if mode[i]==0:
842 #Channel mode
828 strMode = "channel"
843 # if mode[i] == 0:
829 nDatas[i] = self.arrayDim[i,1]
844 # strMode = "channel"
830 else:
845 #
846 # #nDatas is the number of arrays per variable
847 # if nDims[i] == 1:
848 # nDatas[i] = self.arrayDim[i,1]
849 # elif nDims[i] == 2:
850 # nDatas[i] = self.arrayDim[i,2]
851
852 #Parameters mode
853 if mode[i] == 1:
831 strMode = "param"
854 strMode = "param"
832 nDatas[i] = self.arrayDim[i,2]
855 nDatas[i] = self.arrayDim[i,2]
833
856
834 if nDims[i]==2:
857 #Meteors mode
835 nDatas[i] = self.arrayDim[i,2]
858 elif mode[i] == 2:
859 strMode = "table"
860 nDatas[i] = 1
836
861
837 grp0 = grp.create_group(self.dataList[i])
862 grp0 = grp.create_group(self.dataList[i])
838
863
839 for j in range(int(nDatas[i])):
864 for j in range(int(nDatas[i])):
840 tableName = strMode + str(j)
865 tableName = strMode + str(j)
841
866
842 if nDims[i] == 3:
867 if nDims[i] == 3:
843 ds0 = grp0.create_dataset(tableName, (nDim1[i],nDim0[i],1) , data = numpy.zeros((nDim1[i],nDim0[i],1)) ,maxshape=(None,nDim0[i],None), chunks=True)
868 ds0 = grp0.create_dataset(tableName, (nDim1[i],nDim0[i],1) , data = numpy.zeros((nDim1[i],nDim0[i],1)) ,maxshape=(None,nDim0[i],None), chunks=True)
869
844 else:
870 else:
845 ds0 = grp0.create_dataset(tableName, (1,nDim0[i]), data = numpy.zeros((1,nDim0[i])) , maxshape=(None,nDim0[i]), chunks=True)
871 ds0 = grp0.create_dataset(tableName, (1,nDim0[i]), data = numpy.zeros((1,nDim0[i])) , maxshape=(None,nDim0[i]), chunks=True)
846
872
847 ds.append(ds0)
873 ds.append(ds0)
848 data.append([])
874 data.append([])
849 nDimsForDs.append(nDims[i])
875 nDimsForDs.append(nDims[i])
876
877 fp.flush()
878 fp.close()
879
850 self.nDatas = nDatas
880 self.nDatas = nDatas
851 self.nDims = nDims
881 self.nDims = nDims
852 self.nDimsForDs = nDimsForDs
882 self.nDimsForDs = nDimsForDs
853 #Saving variables
883 #Saving variables
854 print 'Writing the file: %s'%filename
884 print 'Writing the file: %s'%filename
855 self.filename = filename
885 self.filename = filename
856 self.fp = fp
886 # self.fp = fp
857 self.grp = grp
887 # self.grp = grp
858 self.grp.attrs.modify('nRecords', 1)
888 # self.grp.attrs.modify('nRecords', 1)
859 self.ds = ds
889 self.ds = ds
860 self.data = data
890 self.data = data
861
891 #
862 self.setFile = setFile
892 # self.setFile = setFile
863 self.firsttime = True
893 self.firsttime = True
864 self.blockIndex = 0
894 self.blockIndex = 0
865 return
895 return
866
896
867 def putData(self):
897 def putData(self):
868
898
869 if not self.firsttime:
870 self.readBlock()
871
872 if self.blockIndex == self.blocksPerFile or self.dateFlag():
899 if self.blockIndex == self.blocksPerFile or self.dateFlag():
873
874 self.setNextFile()
900 self.setNextFile()
875
901
876 self.setBlock()
902 # if not self.firsttime:
877 self.writeBlock()
903 self.readBlock()
878
904 self.setBlock() #Prepare data to be written
879 self.fp.flush()
905 self.writeBlock() #Write data
880 self.fp.close()
881
906
882 return
907 return
883
908
884 def readBlock(self):
909 def readBlock(self):
885
910
886 '''
911 '''
887 data Array configured
912 data Array configured
888
913
889
914
890 self.data
915 self.data
891 '''
916 '''
892 ds = self.ds
917 ds = self.ds
893 #Setting HDF5 File
918 #Setting HDF5 File
894 fp = h5py.File(self.filename,'r+')
919 fp = h5py.File(self.filename,'r+')
895 grp = fp["Data"]
920 grp = fp["Data"]
896 ind = 0
921 ind = 0
897
922
898 # grp.attrs['blocksPerFile'] = 0
923 # grp.attrs['blocksPerFile'] = 0
899 for i in range(len(self.dataList)):
924 for i in range(len(self.dataList)):
900
925
901 if self.nDims[i]==1:
926 if self.nDims[i]==1:
902 ds0 = grp[self.dataList[i]]
927 ds0 = grp[self.dataList[i]]
903 ds[ind] = ds0
928 ds[ind] = ds0
904 ind += 1
929 ind += 1
905 else:
930 else:
906 if self.mode[i]==0:
931 # if self.mode[i] == 0:
907 strMode = "channel"
932 # strMode = "channel"
908 else:
933 if self.mode[i] == 1:
909 strMode = "param"
934 strMode = "param"
935 elif self.mode[i] == 2:
936 strMode = "table"
910
937
911 grp0 = grp[self.dataList[i]]
938 grp0 = grp[self.dataList[i]]
912
939
913 for j in range(int(self.nDatas[i])):
940 for j in range(int(self.nDatas[i])):
914 tableName = strMode + str(j)
941 tableName = strMode + str(j)
915 ds0 = grp0[tableName]
942 ds0 = grp0[tableName]
916 ds[ind] = ds0
943 ds[ind] = ds0
917 ind += 1
944 ind += 1
918
945
919
920 self.fp = fp
946 self.fp = fp
921 self.grp = grp
947 self.grp = grp
922 self.ds = ds
948 self.ds = ds
923
949
924 return
950 return
925
951
926 def setBlock(self):
952 def setBlock(self):
927 '''
953 '''
928 data Array configured
954 data Array configured
929
955
930
956
931 self.data
957 self.data
932 '''
958 '''
933 #Creating Arrays
959 #Creating Arrays
934 data = self.data
960 data = self.data
935 nDatas = self.nDatas
961 nDatas = self.nDatas
936 nDims = self.nDims
962 nDims = self.nDims
937 mode = self.mode
963 mode = self.mode
938 ind = 0
964 ind = 0
939
965
940 for i in range(len(self.dataList)):
966 for i in range(len(self.dataList)):
941 dataAux = getattr(self.dataOut,self.dataList[i])
967 dataAux = getattr(self.dataOut,self.dataList[i])
942
968
943 if nDims[i] == 1:
969 if nDims[i] == 1 or mode[i] == 2:
944 # data[ind] = numpy.array([str(dataAux)]).reshape((1,1))
945 data[ind] = dataAux
970 data[ind] = dataAux
946 # if not self.firsttime:
947 # data[ind] = numpy.hstack((self.ds[ind][:], self.data[ind]))
948 ind += 1
971 ind += 1
949 else:
972
973 elif nDims[i] == 2:
950 for j in range(int(nDatas[i])):
974 for j in range(int(nDatas[i])):
951 if (mode[i] == 0) or (nDims[i] == 2): #In case division per channel or Dimensions is only 1
952 data[ind] = dataAux[j,:]
975 data[ind] = dataAux[j,:]
953 else:
976 ind += 1
954 data[ind] = dataAux[:,j,:]
955
956 # if nDims[i] == 3:
957 # data[ind] = data[ind].reshape((data[ind].shape[0],data[ind].shape[1],1))
958
959 # if not self.firsttime:
960 # data[ind] = numpy.dstack((self.ds[ind][:], data[ind]))
961
977
978 elif nDims[i] == 3:
979 for j in range(int(nDatas[i])):
980 # Extinct mode 0
981 # if (mode[i] == 0):
982 # data[ind] = dataAux[j,:,:]
962 # else:
983 # else:
963 # data[ind] = data[ind].reshape((1,data[ind].shape[0]))
984 data[ind] = dataAux[:,j,:]
964
965 # if not self.firsttime:
966 # data[ind] = numpy.vstack((self.ds[ind][:], data[ind]))
967 ind += 1
985 ind += 1
968
986
969 self.data = data
987 self.data = data
970 return
988 return
971
989
972 def writeBlock(self):
990 def writeBlock(self):
973 '''
991 '''
974 Saves the block in the HDF5 file
992 Saves the block in the HDF5 file
975 '''
993 '''
976 for i in range(len(self.ds)):
994 for i in range(len(self.ds)):
995
996 # First time
977 if self.firsttime:
997 if self.firsttime:
978 # self.ds[i].resize(self.data[i].shape)
998 # self.ds[i].resize(self.data[i].shape)
979 # self.ds[i][self.blockIndex,:] = self.data[i]
999 # self.ds[i][self.blockIndex,:] = self.data[i]
980 if type(self.data[i]) == numpy.ndarray:
1000 if type(self.data[i]) == numpy.ndarray:
981 nDims1 = len(self.ds[i].shape)
1001 nDims1 = len(self.ds[i].shape)
982
1002
983 if nDims1 == 3:
1003 if nDims1 == 3:
984 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
1004 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
985
1005
986 self.ds[i].resize(self.data[i].shape)
1006 self.ds[i].resize(self.data[i].shape)
1007
987 self.ds[i][:] = self.data[i]
1008 self.ds[i][:] = self.data[i]
988 else:
1009 else:
989 if self.nDimsForDs[i] == 1:
1010
1011 # From second time
1012 # Meteors!
1013 if self.mode[i] == 2:
1014 dataShape = self.data[i].shape
1015 dsShape = self.ds[i].shape
1016 self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1]))
1017 self.ds[i][dsShape[0]:,:] = self.data[i]
1018 # One dimension
1019 elif self.nDimsForDs[i] == 1:
990 self.ds[i].resize((self.ds[i].shape[0], self.ds[i].shape[1] + 1))
1020 self.ds[i].resize((self.ds[i].shape[0], self.ds[i].shape[1] + 1))
991 self.ds[i][0,-1] = self.data[i]
1021 self.ds[i][0,-1] = self.data[i]
1022 # Two dimension
992 elif self.nDimsForDs[i] == 2:
1023 elif self.nDimsForDs[i] == 2:
993 self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1]))
1024 self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1]))
994 self.ds[i][self.blockIndex,:] = self.data[i]
1025 self.ds[i][self.blockIndex,:] = self.data[i]
1026 # Three dimensions
995 elif self.nDimsForDs[i] == 3:
1027 elif self.nDimsForDs[i] == 3:
996
997 dataShape = self.data[i].shape
998 dsShape = self.ds[i].shape
999
1000 if dataShape[0]==dsShape[0]:
1001 self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1))
1028 self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1))
1002 self.ds[i][:,:,-1] = self.data[i]
1029 self.ds[i][:,:,-1] = self.data[i]
1003 else:
1004 self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1],self.ds[i].shape[2]))
1005 self.ds[i][dsShape[0]:,:,0] = self.data[i]
1006
1030
1007 self.blockIndex += 1
1008 self.firsttime = False
1031 self.firsttime = False
1032 self.blockIndex += 1
1033
1034 #Close to save changes
1035 self.fp.flush()
1036 self.fp.close()
1009 return
1037 return
1010
1038
1011 def run(self, dataOut, **kwargs):
1039 def run(self, dataOut, **kwargs):
1012
1040
1013 if not(self.isConfig):
1041 if not(self.isConfig):
1014 flagdata = self.setup(dataOut, **kwargs)
1042 flagdata = self.setup(dataOut, **kwargs)
1015
1043
1016 if not(flagdata):
1044 if not(flagdata):
1017 return
1045 return
1018
1046
1019 self.isConfig = True
1047 self.isConfig = True
1020 # self.putMetadata()
1048 # self.putMetadata()
1021 self.setNextFile()
1049 self.setNextFile()
1022
1050
1023 self.putData()
1051 self.putData()
1024 return
1052 return
1025
1053
1026
1054
@@ -1,2154 +1,2169
1 import numpy
1 import numpy
2 import math
2 import math
3 from scipy import optimize
3 from scipy import optimize
4 from scipy import interpolate
4 from scipy import interpolate
5 from scipy import signal
5 from scipy import signal
6 from scipy import stats
6 from scipy import stats
7 import re
7 import re
8 import datetime
8 import datetime
9 import copy
9 import copy
10 import sys
10 import sys
11 import importlib
11 import importlib
12 import itertools
12 import itertools
13
13
14 from jroproc_base import ProcessingUnit, Operation
14 from jroproc_base import ProcessingUnit, Operation
15 from schainpy.model.data.jrodata import Parameters
15 from schainpy.model.data.jrodata import Parameters
16
16
17
17
18 class ParametersProc(ProcessingUnit):
18 class ParametersProc(ProcessingUnit):
19
19
20 nSeconds = None
20 nSeconds = None
21
21
22 def __init__(self):
22 def __init__(self):
23 ProcessingUnit.__init__(self)
23 ProcessingUnit.__init__(self)
24
24
25 # self.objectDict = {}
25 # self.objectDict = {}
26 self.buffer = None
26 self.buffer = None
27 self.firstdatatime = None
27 self.firstdatatime = None
28 self.profIndex = 0
28 self.profIndex = 0
29 self.dataOut = Parameters()
29 self.dataOut = Parameters()
30
30
31 def __updateObjFromInput(self):
31 def __updateObjFromInput(self):
32
32
33 self.dataOut.inputUnit = self.dataIn.type
33 self.dataOut.inputUnit = self.dataIn.type
34
34
35 self.dataOut.timeZone = self.dataIn.timeZone
35 self.dataOut.timeZone = self.dataIn.timeZone
36 self.dataOut.dstFlag = self.dataIn.dstFlag
36 self.dataOut.dstFlag = self.dataIn.dstFlag
37 self.dataOut.errorCount = self.dataIn.errorCount
37 self.dataOut.errorCount = self.dataIn.errorCount
38 self.dataOut.useLocalTime = self.dataIn.useLocalTime
38 self.dataOut.useLocalTime = self.dataIn.useLocalTime
39
39
40 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
40 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
41 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
41 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
42 self.dataOut.channelList = self.dataIn.channelList
42 self.dataOut.channelList = self.dataIn.channelList
43 self.dataOut.heightList = self.dataIn.heightList
43 self.dataOut.heightList = self.dataIn.heightList
44 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
44 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
45 # self.dataOut.nHeights = self.dataIn.nHeights
45 # self.dataOut.nHeights = self.dataIn.nHeights
46 # self.dataOut.nChannels = self.dataIn.nChannels
46 # self.dataOut.nChannels = self.dataIn.nChannels
47 self.dataOut.nBaud = self.dataIn.nBaud
47 self.dataOut.nBaud = self.dataIn.nBaud
48 self.dataOut.nCode = self.dataIn.nCode
48 self.dataOut.nCode = self.dataIn.nCode
49 self.dataOut.code = self.dataIn.code
49 self.dataOut.code = self.dataIn.code
50 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
50 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
51 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
51 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
52 self.dataOut.utctime = self.firstdatatime
52 self.dataOut.utctime = self.firstdatatime
53 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
53 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
54 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
54 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
55 # self.dataOut.nCohInt = self.dataIn.nCohInt
55 # self.dataOut.nCohInt = self.dataIn.nCohInt
56 # self.dataOut.nIncohInt = 1
56 # self.dataOut.nIncohInt = 1
57 self.dataOut.ippSeconds = self.dataIn.ippSeconds
57 self.dataOut.ippSeconds = self.dataIn.ippSeconds
58 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
58 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
59 self.dataOut.timeInterval = self.dataIn.timeInterval
59 self.dataOut.timeInterval = self.dataIn.timeInterval
60 self.dataOut.heightList = self.dataIn.getHeiRange()
60 self.dataOut.heightList = self.dataIn.getHeiRange()
61 self.dataOut.frequency = self.dataIn.frequency
61 self.dataOut.frequency = self.dataIn.frequency
62
62
63 def run(self, nSeconds = 100, nProfiles = None):
63 def run(self, nSeconds = 100, nProfiles = None):
64
64
65
65
66
66
67 if self.firstdatatime == None:
67 if self.firstdatatime == None:
68 self.firstdatatime = self.dataIn.utctime
68 self.firstdatatime = self.dataIn.utctime
69
69
70 #---------------------- Voltage Data ---------------------------
70 #---------------------- Voltage Data ---------------------------
71
71
72 if self.dataIn.type == "Voltage":
72 if self.dataIn.type == "Voltage":
73 self.dataOut.flagNoData = True
73 self.dataOut.flagNoData = True
74
74
75
75
76 if self.buffer == None:
76 if self.buffer == None:
77 self.nSeconds = nSeconds
77 self.nSeconds = nSeconds
78 self.nProfiles= int(numpy.floor(nSeconds/(self.dataIn.ippSeconds*self.dataIn.nCohInt)))
78 self.nProfiles= int(numpy.floor(nSeconds/(self.dataIn.ippSeconds*self.dataIn.nCohInt)))
79
79
80 self.buffer = numpy.zeros((self.dataIn.nChannels,
80 self.buffer = numpy.zeros((self.dataIn.nChannels,
81 self.nProfiles,
81 self.nProfiles,
82 self.dataIn.nHeights),
82 self.dataIn.nHeights),
83 dtype='complex')
83 dtype='complex')
84
84
85 if self.profIndex == 7990:
85 if self.profIndex == 7990:
86 a = 1
86 a = 1
87
87
88 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
88 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
89 self.profIndex += 1
89 self.profIndex += 1
90
90
91 if self.profIndex == self.nProfiles:
91 if self.profIndex == self.nProfiles:
92
92
93 self.__updateObjFromInput()
93 self.__updateObjFromInput()
94 self.dataOut.data_pre = self.buffer.copy()
94 self.dataOut.data_pre = self.buffer.copy()
95 self.dataOut.paramInterval = nSeconds
95 self.dataOut.paramInterval = nSeconds
96 self.dataOut.flagNoData = False
96 self.dataOut.flagNoData = False
97
97
98 self.buffer = None
98 self.buffer = None
99 self.firstdatatime = None
99 self.firstdatatime = None
100 self.profIndex = 0
100 self.profIndex = 0
101 return
101 return
102
102
103 #---------------------- Spectra Data ---------------------------
103 #---------------------- Spectra Data ---------------------------
104
104
105 if self.dataIn.type == "Spectra":
105 if self.dataIn.type == "Spectra":
106 self.dataOut.data_pre = self.dataIn.data_spc.copy()
106 self.dataOut.data_pre = self.dataIn.data_spc.copy()
107 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
107 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
108 self.dataOut.noise = self.dataIn.getNoise()
108 self.dataOut.noise = self.dataIn.getNoise()
109 self.dataOut.normFactor = self.dataIn.normFactor
109 self.dataOut.normFactor = self.dataIn.normFactor
110 self.dataOut.groupList = self.dataIn.pairsList
110 self.dataOut.groupList = self.dataIn.pairsList
111 self.dataOut.flagNoData = False
111 self.dataOut.flagNoData = False
112
112
113 #---------------------- Correlation Data ---------------------------
113 #---------------------- Correlation Data ---------------------------
114
114
115 if self.dataIn.type == "Correlation":
115 if self.dataIn.type == "Correlation":
116 lagRRange = self.dataIn.lagR
116 lagRRange = self.dataIn.lagR
117 indR = numpy.where(lagRRange == 0)[0][0]
117 indR = numpy.where(lagRRange == 0)[0][0]
118
118
119 self.dataOut.data_pre = self.dataIn.data_corr.copy()[:,:,indR,:]
119 self.dataOut.data_pre = self.dataIn.data_corr.copy()[:,:,indR,:]
120 self.dataOut.abscissaList = self.dataIn.getLagTRange(1)
120 self.dataOut.abscissaList = self.dataIn.getLagTRange(1)
121 self.dataOut.noise = self.dataIn.noise
121 self.dataOut.noise = self.dataIn.noise
122 self.dataOut.normFactor = self.dataIn.normFactor
122 self.dataOut.normFactor = self.dataIn.normFactor
123 self.dataOut.data_SNR = self.dataIn.SNR
123 self.dataOut.data_SNR = self.dataIn.SNR
124 self.dataOut.groupList = self.dataIn.pairsList
124 self.dataOut.groupList = self.dataIn.pairsList
125 self.dataOut.flagNoData = False
125 self.dataOut.flagNoData = False
126
126
127 #---------------------- Correlation Data ---------------------------
127 #---------------------- Correlation Data ---------------------------
128
128
129 if self.dataIn.type == "Parameters":
129 if self.dataIn.type == "Parameters":
130 self.dataOut.copy(self.dataIn)
130 self.dataOut.copy(self.dataIn)
131 self.dataOut.flagNoData = False
131 self.dataOut.flagNoData = False
132
132
133 return True
133 return True
134
134
135 self.__updateObjFromInput()
135 self.__updateObjFromInput()
136 self.firstdatatime = None
136 self.firstdatatime = None
137 self.dataOut.utctimeInit = self.dataIn.utctime
137 self.dataOut.utctimeInit = self.dataIn.utctime
138 self.dataOut.paramInterval = self.dataIn.timeInterval
138 self.dataOut.paramInterval = self.dataIn.timeInterval
139
139
140 #------------------- Get Moments ----------------------------------
140 #------------------- Get Moments ----------------------------------
141 def GetMoments(self, channelList = None):
141 def GetMoments(self, channelList = None):
142 '''
142 '''
143 Function GetMoments()
143 Function GetMoments()
144
144
145 Input:
145 Input:
146 channelList : simple channel list to select e.g. [2,3,7]
146 channelList : simple channel list to select e.g. [2,3,7]
147 self.dataOut.data_pre
147 self.dataOut.data_pre
148 self.dataOut.abscissaList
148 self.dataOut.abscissaList
149 self.dataOut.noise
149 self.dataOut.noise
150
150
151 Affected:
151 Affected:
152 self.dataOut.data_param
152 self.dataOut.data_param
153 self.dataOut.data_SNR
153 self.dataOut.data_SNR
154
154
155 '''
155 '''
156 data = self.dataOut.data_pre
156 data = self.dataOut.data_pre
157 absc = self.dataOut.abscissaList[:-1]
157 absc = self.dataOut.abscissaList[:-1]
158 noise = self.dataOut.noise
158 noise = self.dataOut.noise
159
159
160 data_param = numpy.zeros((data.shape[0], 4, data.shape[2]))
160 data_param = numpy.zeros((data.shape[0], 4, data.shape[2]))
161
161
162 if channelList== None:
162 if channelList== None:
163 channelList = self.dataIn.channelList
163 channelList = self.dataIn.channelList
164 self.dataOut.channelList = channelList
164 self.dataOut.channelList = channelList
165
165
166 for ind in channelList:
166 for ind in channelList:
167 data_param[ind,:,:] = self.__calculateMoments(data[ind,:,:], absc, noise[ind])
167 data_param[ind,:,:] = self.__calculateMoments(data[ind,:,:], absc, noise[ind])
168
168
169 self.dataOut.data_param = data_param[:,1:,:]
169 self.dataOut.data_param = data_param[:,1:,:]
170 self.dataOut.data_SNR = data_param[:,0]
170 self.dataOut.data_SNR = data_param[:,0]
171 return
171 return
172
172
173 def __calculateMoments(self, oldspec, oldfreq, n0, nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
173 def __calculateMoments(self, oldspec, oldfreq, n0, nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
174
174
175 if (nicoh == None): nicoh = 1
175 if (nicoh == None): nicoh = 1
176 if (graph == None): graph = 0
176 if (graph == None): graph = 0
177 if (smooth == None): smooth = 0
177 if (smooth == None): smooth = 0
178 elif (self.smooth < 3): smooth = 0
178 elif (self.smooth < 3): smooth = 0
179
179
180 if (type1 == None): type1 = 0
180 if (type1 == None): type1 = 0
181 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
181 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
182 if (snrth == None): snrth = -3
182 if (snrth == None): snrth = -3
183 if (dc == None): dc = 0
183 if (dc == None): dc = 0
184 if (aliasing == None): aliasing = 0
184 if (aliasing == None): aliasing = 0
185 if (oldfd == None): oldfd = 0
185 if (oldfd == None): oldfd = 0
186 if (wwauto == None): wwauto = 0
186 if (wwauto == None): wwauto = 0
187
187
188 if (n0 < 1.e-20): n0 = 1.e-20
188 if (n0 < 1.e-20): n0 = 1.e-20
189
189
190 freq = oldfreq
190 freq = oldfreq
191 vec_power = numpy.zeros(oldspec.shape[1])
191 vec_power = numpy.zeros(oldspec.shape[1])
192 vec_fd = numpy.zeros(oldspec.shape[1])
192 vec_fd = numpy.zeros(oldspec.shape[1])
193 vec_w = numpy.zeros(oldspec.shape[1])
193 vec_w = numpy.zeros(oldspec.shape[1])
194 vec_snr = numpy.zeros(oldspec.shape[1])
194 vec_snr = numpy.zeros(oldspec.shape[1])
195
195
196 for ind in range(oldspec.shape[1]):
196 for ind in range(oldspec.shape[1]):
197
197
198 spec = oldspec[:,ind]
198 spec = oldspec[:,ind]
199 aux = spec*fwindow
199 aux = spec*fwindow
200 max_spec = aux.max()
200 max_spec = aux.max()
201 m = list(aux).index(max_spec)
201 m = list(aux).index(max_spec)
202
202
203 #Smooth
203 #Smooth
204 if (smooth == 0): spec2 = spec
204 if (smooth == 0): spec2 = spec
205 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
205 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
206
206
207 # Calculo de Momentos
207 # Calculo de Momentos
208 bb = spec2[range(m,spec2.size)]
208 bb = spec2[range(m,spec2.size)]
209 bb = (bb<n0).nonzero()
209 bb = (bb<n0).nonzero()
210 bb = bb[0]
210 bb = bb[0]
211
211
212 ss = spec2[range(0,m + 1)]
212 ss = spec2[range(0,m + 1)]
213 ss = (ss<n0).nonzero()
213 ss = (ss<n0).nonzero()
214 ss = ss[0]
214 ss = ss[0]
215
215
216 if (bb.size == 0):
216 if (bb.size == 0):
217 bb0 = spec.size - 1 - m
217 bb0 = spec.size - 1 - m
218 else:
218 else:
219 bb0 = bb[0] - 1
219 bb0 = bb[0] - 1
220 if (bb0 < 0):
220 if (bb0 < 0):
221 bb0 = 0
221 bb0 = 0
222
222
223 if (ss.size == 0): ss1 = 1
223 if (ss.size == 0): ss1 = 1
224 else: ss1 = max(ss) + 1
224 else: ss1 = max(ss) + 1
225
225
226 if (ss1 > m): ss1 = m
226 if (ss1 > m): ss1 = m
227
227
228 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
228 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
229 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
229 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
230 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
230 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
231 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
231 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
232 snr = (spec2.mean()-n0)/n0
232 snr = (spec2.mean()-n0)/n0
233
233
234 if (snr < 1.e-20) :
234 if (snr < 1.e-20) :
235 snr = 1.e-20
235 snr = 1.e-20
236
236
237 vec_power[ind] = power
237 vec_power[ind] = power
238 vec_fd[ind] = fd
238 vec_fd[ind] = fd
239 vec_w[ind] = w
239 vec_w[ind] = w
240 vec_snr[ind] = snr
240 vec_snr[ind] = snr
241
241
242 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
242 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
243 return moments
243 return moments
244
244
245 #------------------ Get SA Parameters --------------------------
245 #------------------ Get SA Parameters --------------------------
246
246
247 def GetSAParameters(self):
247 def GetSAParameters(self):
248 pairslist = self.dataOut.groupList
248 pairslist = self.dataOut.groupList
249 num_pairs = len(pairslist)
249 num_pairs = len(pairslist)
250
250
251 vel = self.dataOut.abscissaList
251 vel = self.dataOut.abscissaList
252 spectra = self.dataOut.data_pre
252 spectra = self.dataOut.data_pre
253 cspectra = self.dataIn.data_cspc
253 cspectra = self.dataIn.data_cspc
254 delta_v = vel[1] - vel[0]
254 delta_v = vel[1] - vel[0]
255
255
256 #Calculating the power spectrum
256 #Calculating the power spectrum
257 spc_pow = numpy.sum(spectra, 3)*delta_v
257 spc_pow = numpy.sum(spectra, 3)*delta_v
258 #Normalizing Spectra
258 #Normalizing Spectra
259 norm_spectra = spectra/spc_pow
259 norm_spectra = spectra/spc_pow
260 #Calculating the norm_spectra at peak
260 #Calculating the norm_spectra at peak
261 max_spectra = numpy.max(norm_spectra, 3)
261 max_spectra = numpy.max(norm_spectra, 3)
262
262
263 #Normalizing Cross Spectra
263 #Normalizing Cross Spectra
264 norm_cspectra = numpy.zeros(cspectra.shape)
264 norm_cspectra = numpy.zeros(cspectra.shape)
265
265
266 for i in range(num_chan):
266 for i in range(num_chan):
267 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
267 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
268
268
269 max_cspectra = numpy.max(norm_cspectra,2)
269 max_cspectra = numpy.max(norm_cspectra,2)
270 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
270 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
271
271
272 for i in range(num_pairs):
272 for i in range(num_pairs):
273 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
273 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
274 #------------------- Get Lags ----------------------------------
274 #------------------- Get Lags ----------------------------------
275
275
276 def GetLags(self):
276 def GetLags(self):
277 '''
277 '''
278 Function GetMoments()
278 Function GetMoments()
279
279
280 Input:
280 Input:
281 self.dataOut.data_pre
281 self.dataOut.data_pre
282 self.dataOut.abscissaList
282 self.dataOut.abscissaList
283 self.dataOut.noise
283 self.dataOut.noise
284 self.dataOut.normFactor
284 self.dataOut.normFactor
285 self.dataOut.data_SNR
285 self.dataOut.data_SNR
286 self.dataOut.groupList
286 self.dataOut.groupList
287 self.dataOut.nChannels
287 self.dataOut.nChannels
288
288
289 Affected:
289 Affected:
290 self.dataOut.data_param
290 self.dataOut.data_param
291
291
292 '''
292 '''
293
293
294 data = self.dataOut.data_pre
294 data = self.dataOut.data_pre
295 normFactor = self.dataOut.normFactor
295 normFactor = self.dataOut.normFactor
296 nHeights = self.dataOut.nHeights
296 nHeights = self.dataOut.nHeights
297 absc = self.dataOut.abscissaList[:-1]
297 absc = self.dataOut.abscissaList[:-1]
298 noise = self.dataOut.noise
298 noise = self.dataOut.noise
299 SNR = self.dataOut.data_SNR
299 SNR = self.dataOut.data_SNR
300 pairsList = self.dataOut.groupList
300 pairsList = self.dataOut.groupList
301 nChannels = self.dataOut.nChannels
301 nChannels = self.dataOut.nChannels
302 pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
302 pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
303 self.dataOut.data_param = numpy.zeros((len(pairsCrossCorr)*2 + 1, nHeights))
303 self.dataOut.data_param = numpy.zeros((len(pairsCrossCorr)*2 + 1, nHeights))
304
304
305 dataNorm = numpy.abs(data)
305 dataNorm = numpy.abs(data)
306 for l in range(len(pairsList)):
306 for l in range(len(pairsList)):
307 dataNorm[l,:,:] = dataNorm[l,:,:]/normFactor[l,:]
307 dataNorm[l,:,:] = dataNorm[l,:,:]/normFactor[l,:]
308
308
309 self.dataOut.data_param[:-1,:] = self.__calculateTaus(dataNorm, pairsCrossCorr, pairsAutoCorr, absc)
309 self.dataOut.data_param[:-1,:] = self.__calculateTaus(dataNorm, pairsCrossCorr, pairsAutoCorr, absc)
310 self.dataOut.data_param[-1,:] = self.__calculateLag1Phase(data, pairsAutoCorr, absc)
310 self.dataOut.data_param[-1,:] = self.__calculateLag1Phase(data, pairsAutoCorr, absc)
311 return
311 return
312
312
313 def __getPairsAutoCorr(self, pairsList, nChannels):
313 def __getPairsAutoCorr(self, pairsList, nChannels):
314
314
315 pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
315 pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
316
316
317 for l in range(len(pairsList)):
317 for l in range(len(pairsList)):
318 firstChannel = pairsList[l][0]
318 firstChannel = pairsList[l][0]
319 secondChannel = pairsList[l][1]
319 secondChannel = pairsList[l][1]
320
320
321 #Obteniendo pares de Autocorrelacion
321 #Obteniendo pares de Autocorrelacion
322 if firstChannel == secondChannel:
322 if firstChannel == secondChannel:
323 pairsAutoCorr[firstChannel] = int(l)
323 pairsAutoCorr[firstChannel] = int(l)
324
324
325 pairsAutoCorr = pairsAutoCorr.astype(int)
325 pairsAutoCorr = pairsAutoCorr.astype(int)
326
326
327 pairsCrossCorr = range(len(pairsList))
327 pairsCrossCorr = range(len(pairsList))
328 pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
328 pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
329
329
330 return pairsAutoCorr, pairsCrossCorr
330 return pairsAutoCorr, pairsCrossCorr
331
331
332 def __calculateTaus(self, data, pairsCrossCorr, pairsAutoCorr, lagTRange):
332 def __calculateTaus(self, data, pairsCrossCorr, pairsAutoCorr, lagTRange):
333
333
334 Pt0 = data.shape[1]/2
334 Pt0 = data.shape[1]/2
335 #Funcion de Autocorrelacion
335 #Funcion de Autocorrelacion
336 dataAutoCorr = stats.nanmean(data[pairsAutoCorr,:,:], axis = 0)
336 dataAutoCorr = stats.nanmean(data[pairsAutoCorr,:,:], axis = 0)
337
337
338 #Obtencion Indice de TauCross
338 #Obtencion Indice de TauCross
339 indCross = data[pairsCrossCorr,:,:].argmax(axis = 1)
339 indCross = data[pairsCrossCorr,:,:].argmax(axis = 1)
340 #Obtencion Indice de TauAuto
340 #Obtencion Indice de TauAuto
341 indAuto = numpy.zeros(indCross.shape,dtype = 'int')
341 indAuto = numpy.zeros(indCross.shape,dtype = 'int')
342 CCValue = data[pairsCrossCorr,Pt0,:]
342 CCValue = data[pairsCrossCorr,Pt0,:]
343 for i in range(pairsCrossCorr.size):
343 for i in range(pairsCrossCorr.size):
344 indAuto[i,:] = numpy.abs(dataAutoCorr - CCValue[i,:]).argmin(axis = 0)
344 indAuto[i,:] = numpy.abs(dataAutoCorr - CCValue[i,:]).argmin(axis = 0)
345
345
346 #Obtencion de TauCross y TauAuto
346 #Obtencion de TauCross y TauAuto
347 tauCross = lagTRange[indCross]
347 tauCross = lagTRange[indCross]
348 tauAuto = lagTRange[indAuto]
348 tauAuto = lagTRange[indAuto]
349
349
350 Nan1, Nan2 = numpy.where(tauCross == lagTRange[0])
350 Nan1, Nan2 = numpy.where(tauCross == lagTRange[0])
351
351
352 tauCross[Nan1,Nan2] = numpy.nan
352 tauCross[Nan1,Nan2] = numpy.nan
353 tauAuto[Nan1,Nan2] = numpy.nan
353 tauAuto[Nan1,Nan2] = numpy.nan
354 tau = numpy.vstack((tauCross,tauAuto))
354 tau = numpy.vstack((tauCross,tauAuto))
355
355
356 return tau
356 return tau
357
357
358 def __calculateLag1Phase(self, data, pairs, lagTRange):
358 def __calculateLag1Phase(self, data, pairs, lagTRange):
359 data1 = stats.nanmean(data[pairs,:,:], axis = 0)
359 data1 = stats.nanmean(data[pairs,:,:], axis = 0)
360 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
360 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
361
361
362 phase = numpy.angle(data1[lag1,:])
362 phase = numpy.angle(data1[lag1,:])
363
363
364 return phase
364 return phase
365 #------------------- Detect Meteors ------------------------------
365 #------------------- Detect Meteors ------------------------------
366
366
367 def MeteorDetection(self, hei_ref = None, tauindex = 0,
367 def MeteorDetection(self, hei_ref = None, tauindex = 0,
368 predefinedPhaseShifts = None, centerReceiverIndex = 2, saveAll = False,
368 predefinedPhaseShifts = None, centerReceiverIndex = 2,
369 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
369 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
370 noise_timeStep = 4, noise_multiple = 4,
370 noise_timeStep = 4, noise_multiple = 4,
371 multDet_timeLimit = 1, multDet_rangeLimit = 3,
371 multDet_timeLimit = 1, multDet_rangeLimit = 3,
372 phaseThresh = 20, SNRThresh = 8,
372 phaseThresh = 20, SNRThresh = 8,
373 hmin = 70, hmax=110, azimuth = 0) :
373 hmin = 70, hmax=110, azimuth = 0) :
374
374
375 '''
375 '''
376 Function DetectMeteors()
376 Function DetectMeteors()
377 Project developed with paper:
377 Project developed with paper:
378 HOLDSWORTH ET AL. 2004
378 HOLDSWORTH ET AL. 2004
379
379
380 Input:
380 Input:
381 self.dataOut.data_pre
381 self.dataOut.data_pre
382
382
383 centerReceiverIndex: From the channels, which is the center receiver
383 centerReceiverIndex: From the channels, which is the center receiver
384
384
385 hei_ref: Height reference for the Beacon signal extraction
385 hei_ref: Height reference for the Beacon signal extraction
386 tauindex:
386 tauindex:
387 predefinedPhaseShifts: Predefined phase offset for the voltge signals
387 predefinedPhaseShifts: Predefined phase offset for the voltge signals
388
388
389 cohDetection: Whether to user Coherent detection or not
389 cohDetection: Whether to user Coherent detection or not
390 cohDet_timeStep: Coherent Detection calculation time step
390 cohDet_timeStep: Coherent Detection calculation time step
391 cohDet_thresh: Coherent Detection phase threshold to correct phases
391 cohDet_thresh: Coherent Detection phase threshold to correct phases
392
392
393 noise_timeStep: Noise calculation time step
393 noise_timeStep: Noise calculation time step
394 noise_multiple: Noise multiple to define signal threshold
394 noise_multiple: Noise multiple to define signal threshold
395
395
396 multDet_timeLimit: Multiple Detection Removal time limit in seconds
396 multDet_timeLimit: Multiple Detection Removal time limit in seconds
397 multDet_rangeLimit: Multiple Detection Removal range limit in km
397 multDet_rangeLimit: Multiple Detection Removal range limit in km
398
398
399 phaseThresh: Maximum phase difference between receiver to be consider a meteor
399 phaseThresh: Maximum phase difference between receiver to be consider a meteor
400 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
400 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
401
401
402 hmin: Minimum Height of the meteor to use it in the further wind estimations
402 hmin: Minimum Height of the meteor to use it in the further wind estimations
403 hmax: Maximum Height of the meteor to use it in the further wind estimations
403 hmax: Maximum Height of the meteor to use it in the further wind estimations
404 azimuth: Azimuth angle correction
404 azimuth: Azimuth angle correction
405
405
406 Affected:
406 Affected:
407 self.dataOut.data_param
407 self.dataOut.data_param
408
408
409 Rejection Criteria (Errors):
409 Rejection Criteria (Errors):
410 0: No error; analysis OK
410 0: No error; analysis OK
411 1: SNR < SNR threshold
411 1: SNR < SNR threshold
412 2: angle of arrival (AOA) ambiguously determined
412 2: angle of arrival (AOA) ambiguously determined
413 3: AOA estimate not feasible
413 3: AOA estimate not feasible
414 4: Large difference in AOAs obtained from different antenna baselines
414 4: Large difference in AOAs obtained from different antenna baselines
415 5: echo at start or end of time series
415 5: echo at start or end of time series
416 6: echo less than 5 examples long; too short for analysis
416 6: echo less than 5 examples long; too short for analysis
417 7: echo rise exceeds 0.3s
417 7: echo rise exceeds 0.3s
418 8: echo decay time less than twice rise time
418 8: echo decay time less than twice rise time
419 9: large power level before echo
419 9: large power level before echo
420 10: large power level after echo
420 10: large power level after echo
421 11: poor fit to amplitude for estimation of decay time
421 11: poor fit to amplitude for estimation of decay time
422 12: poor fit to CCF phase variation for estimation of radial drift velocity
422 12: poor fit to CCF phase variation for estimation of radial drift velocity
423 13: height unresolvable echo: not valid height within 70 to 110 km
423 13: height unresolvable echo: not valid height within 70 to 110 km
424 14: height ambiguous echo: more then one possible height within 70 to 110 km
424 14: height ambiguous echo: more then one possible height within 70 to 110 km
425 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
425 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
426 16: oscilatory echo, indicating event most likely not an underdense echo
426 16: oscilatory echo, indicating event most likely not an underdense echo
427
427
428 17: phase difference in meteor Reestimation
428 17: phase difference in meteor Reestimation
429
429
430 Data Storage:
430 Data Storage:
431 Meteors for Wind Estimation (8):
431 Meteors for Wind Estimation (8):
432 Day Hour | Range Height
432 Day Hour | Range Height
433 Azimuth Zenith errorCosDir
433 Azimuth Zenith errorCosDir
434 VelRad errorVelRad
434 VelRad errorVelRad
435 TypeError
435 TypeError
436
436
437 '''
437 '''
438 #Get Beacon signal
438 #Get Beacon signal
439 newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
439 newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
440
440
441 if hei_ref != None:
441 if hei_ref != None:
442 newheis = numpy.where(self.dataOut.heightList>hei_ref)
442 newheis = numpy.where(self.dataOut.heightList>hei_ref)
443
443
444 heiRang = self.dataOut.getHeiRange()
444 heiRang = self.dataOut.getHeiRange()
445 #Pairs List
445 #Pairs List
446 pairslist = []
446 pairslist = []
447 nChannel = self.dataOut.nChannels
447 nChannel = self.dataOut.nChannels
448 for i in range(nChannel):
448 for i in range(nChannel):
449 if i != centerReceiverIndex:
449 if i != centerReceiverIndex:
450 pairslist.append((centerReceiverIndex,i))
450 pairslist.append((centerReceiverIndex,i))
451
451
452 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
452 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
453 # see if the user put in pre defined phase shifts
453 # see if the user put in pre defined phase shifts
454 voltsPShift = self.dataOut.data_pre.copy()
454 voltsPShift = self.dataOut.data_pre.copy()
455
455
456 if predefinedPhaseShifts != None:
456 if predefinedPhaseShifts != None:
457 hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
457 hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
458
458
459 elif beaconPhaseShifts:
459 # elif beaconPhaseShifts:
460 #get hardware phase shifts using beacon signal
460 # #get hardware phase shifts using beacon signal
461 hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
461 # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
462 hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
462 # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
463
463
464 else:
464 else:
465 hardwarePhaseShifts = numpy.zeros(5)
465 hardwarePhaseShifts = numpy.zeros(5)
466
466
467
467
468 voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
468 voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
469 for i in range(self.dataOut.data_pre.shape[0]):
469 for i in range(self.dataOut.data_pre.shape[0]):
470 voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
470 voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
471
471
472
472
473 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
473 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
474
474
475 #Remove DC
475 #Remove DC
476 voltsDC = numpy.mean(voltsPShift,1)
476 voltsDC = numpy.mean(voltsPShift,1)
477 voltsDC = numpy.mean(voltsDC,1)
477 voltsDC = numpy.mean(voltsDC,1)
478 for i in range(voltsDC.shape[0]):
478 for i in range(voltsDC.shape[0]):
479 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
479 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
480
480
481 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
481 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
482 voltsPShift = voltsPShift[:,:,:newheis[0][0]]
482 voltsPShift = voltsPShift[:,:,:newheis[0][0]]
483
483
484 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
484 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
485 #Coherent Detection
485 #Coherent Detection
486 if cohDetection:
486 if cohDetection:
487 #use coherent detection to get the net power
487 #use coherent detection to get the net power
488 cohDet_thresh = cohDet_thresh*numpy.pi/180
488 cohDet_thresh = cohDet_thresh*numpy.pi/180
489 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, self.dataOut.timeInterval, pairslist, cohDet_thresh)
489 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, self.dataOut.timeInterval, pairslist, cohDet_thresh)
490
490
491 #Non-coherent detection!
491 #Non-coherent detection!
492 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
492 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
493 #********** END OF COH/NON-COH POWER CALCULATION**********************
493 #********** END OF COH/NON-COH POWER CALCULATION**********************
494
494
495 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
495 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
496 #Get noise
496 #Get noise
497 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, self.dataOut.timeInterval)
497 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, self.dataOut.timeInterval)
498 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
498 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
499 #Get signal threshold
499 #Get signal threshold
500 signalThresh = noise_multiple*noise
500 signalThresh = noise_multiple*noise
501 #Meteor echoes detection
501 #Meteor echoes detection
502 listMeteors = self.__findMeteors(powerNet, signalThresh)
502 listMeteors = self.__findMeteors(powerNet, signalThresh)
503 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
503 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
504
504
505 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
505 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
506 #Parameters
506 #Parameters
507 heiRange = self.dataOut.getHeiRange()
507 heiRange = self.dataOut.getHeiRange()
508 rangeInterval = heiRange[1] - heiRange[0]
508 rangeInterval = heiRange[1] - heiRange[0]
509 rangeLimit = multDet_rangeLimit/rangeInterval
509 rangeLimit = multDet_rangeLimit/rangeInterval
510 timeLimit = multDet_timeLimit/self.dataOut.timeInterval
510 timeLimit = multDet_timeLimit/self.dataOut.timeInterval
511 #Multiple detection removals
511 #Multiple detection removals
512 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
512 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
513 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
513 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
514
514
515 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
515 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
516 #Parameters
516 #Parameters
517 phaseThresh = phaseThresh*numpy.pi/180
517 phaseThresh = phaseThresh*numpy.pi/180
518 thresh = [phaseThresh, noise_multiple, SNRThresh]
518 thresh = [phaseThresh, noise_multiple, SNRThresh]
519 #Meteor reestimation (Errors N 1, 6, 12, 17)
519 #Meteor reestimation (Errors N 1, 6, 12, 17)
520 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist, thresh, noise, self.dataOut.timeInterval, self.dataOut.frequency)
520 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist, thresh, noise, self.dataOut.timeInterval, self.dataOut.frequency)
521 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
521 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
522 #Estimation of decay times (Errors N 7, 8, 11)
522 #Estimation of decay times (Errors N 7, 8, 11)
523 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, self.dataOut.timeInterval, self.dataOut.frequency)
523 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, self.dataOut.timeInterval, self.dataOut.frequency)
524 #******************* END OF METEOR REESTIMATION *******************
524 #******************* END OF METEOR REESTIMATION *******************
525
525
526 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
526 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
527 #Calculating Radial Velocity (Error N 15)
527 #Calculating Radial Velocity (Error N 15)
528 radialStdThresh = 10
528 radialStdThresh = 10
529 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist, self.dataOut.timeInterval)
529 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist, self.dataOut.timeInterval)
530
530
531 if len(listMeteors4) > 0:
531 if len(listMeteors4) > 0:
532 #Setting New Array
533 date = self.dataOut.utctime
534 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
532
535
533 pairsList = []
536 pairsList = []
534 pairx = (0,3)
537 pairx = (0,3)
535 pairy = (1,2)
538 pairy = (1,2)
536 pairsList.append(pairx)
539 pairsList.append(pairx)
537 pairsList.append(pairy)
540 pairsList.append(pairy)
538
541
539 #Setting New Array
540 date = repr(self.dataOut.datatime)
541 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
542
543 meteorOps = MeteorOperations()
542 meteorOps = MeteorOperations()
544 jph = numpy.array([0,0,0,0])
543 jph = numpy.array([0,0,0,0])
545 h = (hmin,hmax)
544 h = (hmin,hmax)
546 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, jph)
545 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, jph)
547
546
548 # #Calculate AOA (Error N 3, 4)
547 # #Calculate AOA (Error N 3, 4)
549 # #JONES ET AL. 1998
548 # #JONES ET AL. 1998
550 # error = arrayParameters[:,-1]
549 # error = arrayParameters[:,-1]
551 # AOAthresh = numpy.pi/8
550 # AOAthresh = numpy.pi/8
552 # phases = -arrayParameters[:,9:13]
551 # phases = -arrayParameters[:,9:13]
553 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
552 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
554 #
553 #
555 # #Calculate Heights (Error N 13 and 14)
554 # #Calculate Heights (Error N 13 and 14)
556 # error = arrayParameters[:,-1]
555 # error = arrayParameters[:,-1]
557 # Ranges = arrayParameters[:,2]
556 # Ranges = arrayParameters[:,2]
558 # zenith = arrayParameters[:,5]
557 # zenith = arrayParameters[:,5]
559 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
558 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
560 # error = arrayParameters[:,-1]
559 # error = arrayParameters[:,-1]
561 #********************* END OF PARAMETERS CALCULATION **************************
560 #********************* END OF PARAMETERS CALCULATION **************************
562
561
563 #***************************+ PASS DATA TO NEXT STEP **********************
562 #***************************+ PASS DATA TO NEXT STEP **********************
564 arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
563 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
565 self.dataOut.data_param = arrayFinal
564 self.dataOut.data_param = arrayParameters
566
565
567 if arrayFinal == None:
566 if arrayParameters == None:
568 self.dataOut.flagNoData = True
567 self.dataOut.flagNoData = True
569
568
570 return
569 return
571
570
571 def correctMeteorPhases(self):
572
573 arrayParameters = self.dataOut.data_param
574 pairsList = []
575 pairx = (0,3)
576 pairy = (1,2)
577 pairsList.append(pairx)
578 pairsList.append(pairy)
579
580 meteorOps = MeteorOperations()
581 jph = numpy.array([0,0,0,0])
582 h = (hmin,hmax)
583 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, jph)
584 self.dataOut.data_param = arrayParameters
585 return
586
572 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
587 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
573
588
574 minIndex = min(newheis[0])
589 minIndex = min(newheis[0])
575 maxIndex = max(newheis[0])
590 maxIndex = max(newheis[0])
576
591
577 voltage = voltage0[:,:,minIndex:maxIndex+1]
592 voltage = voltage0[:,:,minIndex:maxIndex+1]
578 nLength = voltage.shape[1]/n
593 nLength = voltage.shape[1]/n
579 nMin = 0
594 nMin = 0
580 nMax = 0
595 nMax = 0
581 phaseOffset = numpy.zeros((len(pairslist),n))
596 phaseOffset = numpy.zeros((len(pairslist),n))
582
597
583 for i in range(n):
598 for i in range(n):
584 nMax += nLength
599 nMax += nLength
585 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
600 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
586 phaseCCF = numpy.mean(phaseCCF, axis = 2)
601 phaseCCF = numpy.mean(phaseCCF, axis = 2)
587 phaseOffset[:,i] = phaseCCF.transpose()
602 phaseOffset[:,i] = phaseCCF.transpose()
588 nMin = nMax
603 nMin = nMax
589 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
604 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
590
605
591 #Remove Outliers
606 #Remove Outliers
592 factor = 2
607 factor = 2
593 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
608 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
594 dw = numpy.std(wt,axis = 1)
609 dw = numpy.std(wt,axis = 1)
595 dw = dw.reshape((dw.size,1))
610 dw = dw.reshape((dw.size,1))
596 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
611 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
597 phaseOffset[ind] = numpy.nan
612 phaseOffset[ind] = numpy.nan
598 phaseOffset = stats.nanmean(phaseOffset, axis=1)
613 phaseOffset = stats.nanmean(phaseOffset, axis=1)
599
614
600 return phaseOffset
615 return phaseOffset
601
616
602 def __shiftPhase(self, data, phaseShift):
617 def __shiftPhase(self, data, phaseShift):
603 #this will shift the phase of a complex number
618 #this will shift the phase of a complex number
604 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
619 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
605 return dataShifted
620 return dataShifted
606
621
607 def __estimatePhaseDifference(self, array, pairslist):
622 def __estimatePhaseDifference(self, array, pairslist):
608 nChannel = array.shape[0]
623 nChannel = array.shape[0]
609 nHeights = array.shape[2]
624 nHeights = array.shape[2]
610 numPairs = len(pairslist)
625 numPairs = len(pairslist)
611 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
626 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
612 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
627 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
613
628
614 #Correct phases
629 #Correct phases
615 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
630 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
616 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
631 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
617
632
618 if indDer[0].shape[0] > 0:
633 if indDer[0].shape[0] > 0:
619 for i in range(indDer[0].shape[0]):
634 for i in range(indDer[0].shape[0]):
620 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
635 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
621 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
636 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
622
637
623 # for j in range(numSides):
638 # for j in range(numSides):
624 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
639 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
625 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
640 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
626 #
641 #
627 #Linear
642 #Linear
628 phaseInt = numpy.zeros((numPairs,1))
643 phaseInt = numpy.zeros((numPairs,1))
629 angAllCCF = phaseCCF[:,[0,1,3,4],0]
644 angAllCCF = phaseCCF[:,[0,1,3,4],0]
630 for j in range(numPairs):
645 for j in range(numPairs):
631 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
646 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
632 phaseInt[j] = fit[1]
647 phaseInt[j] = fit[1]
633 #Phase Differences
648 #Phase Differences
634 phaseDiff = phaseInt - phaseCCF[:,2,:]
649 phaseDiff = phaseInt - phaseCCF[:,2,:]
635 phaseArrival = phaseInt.reshape(phaseInt.size)
650 phaseArrival = phaseInt.reshape(phaseInt.size)
636
651
637 #Dealias
652 #Dealias
638 indAlias = numpy.where(phaseArrival > numpy.pi)
653 indAlias = numpy.where(phaseArrival > numpy.pi)
639 phaseArrival[indAlias] -= 2*numpy.pi
654 phaseArrival[indAlias] -= 2*numpy.pi
640 indAlias = numpy.where(phaseArrival < -numpy.pi)
655 indAlias = numpy.where(phaseArrival < -numpy.pi)
641 phaseArrival[indAlias] += 2*numpy.pi
656 phaseArrival[indAlias] += 2*numpy.pi
642
657
643 return phaseDiff, phaseArrival
658 return phaseDiff, phaseArrival
644
659
645 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
660 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
646 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
661 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
647 #find the phase shifts of each channel over 1 second intervals
662 #find the phase shifts of each channel over 1 second intervals
648 #only look at ranges below the beacon signal
663 #only look at ranges below the beacon signal
649 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
664 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
650 numBlocks = int(volts.shape[1]/numProfPerBlock)
665 numBlocks = int(volts.shape[1]/numProfPerBlock)
651 numHeights = volts.shape[2]
666 numHeights = volts.shape[2]
652 nChannel = volts.shape[0]
667 nChannel = volts.shape[0]
653 voltsCohDet = volts.copy()
668 voltsCohDet = volts.copy()
654
669
655 pairsarray = numpy.array(pairslist)
670 pairsarray = numpy.array(pairslist)
656 indSides = pairsarray[:,1]
671 indSides = pairsarray[:,1]
657 # indSides = numpy.array(range(nChannel))
672 # indSides = numpy.array(range(nChannel))
658 # indSides = numpy.delete(indSides, indCenter)
673 # indSides = numpy.delete(indSides, indCenter)
659 #
674 #
660 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
675 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
661 listBlocks = numpy.array_split(volts, numBlocks, 1)
676 listBlocks = numpy.array_split(volts, numBlocks, 1)
662
677
663 startInd = 0
678 startInd = 0
664 endInd = 0
679 endInd = 0
665
680
666 for i in range(numBlocks):
681 for i in range(numBlocks):
667 startInd = endInd
682 startInd = endInd
668 endInd = endInd + listBlocks[i].shape[1]
683 endInd = endInd + listBlocks[i].shape[1]
669
684
670 arrayBlock = listBlocks[i]
685 arrayBlock = listBlocks[i]
671 # arrayBlockCenter = listCenter[i]
686 # arrayBlockCenter = listCenter[i]
672
687
673 #Estimate the Phase Difference
688 #Estimate the Phase Difference
674 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
689 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
675 #Phase Difference RMS
690 #Phase Difference RMS
676 arrayPhaseRMS = numpy.abs(phaseDiff)
691 arrayPhaseRMS = numpy.abs(phaseDiff)
677 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
692 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
678 indPhase = numpy.where(phaseRMSaux==4)
693 indPhase = numpy.where(phaseRMSaux==4)
679 #Shifting
694 #Shifting
680 if indPhase[0].shape[0] > 0:
695 if indPhase[0].shape[0] > 0:
681 for j in range(indSides.size):
696 for j in range(indSides.size):
682 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
697 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
683 voltsCohDet[:,startInd:endInd,:] = arrayBlock
698 voltsCohDet[:,startInd:endInd,:] = arrayBlock
684
699
685 return voltsCohDet
700 return voltsCohDet
686
701
687 def __calculateCCF(self, volts, pairslist ,laglist):
702 def __calculateCCF(self, volts, pairslist ,laglist):
688
703
689 nHeights = volts.shape[2]
704 nHeights = volts.shape[2]
690 nPoints = volts.shape[1]
705 nPoints = volts.shape[1]
691 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
706 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
692
707
693 for i in range(len(pairslist)):
708 for i in range(len(pairslist)):
694 volts1 = volts[pairslist[i][0]]
709 volts1 = volts[pairslist[i][0]]
695 volts2 = volts[pairslist[i][1]]
710 volts2 = volts[pairslist[i][1]]
696
711
697 for t in range(len(laglist)):
712 for t in range(len(laglist)):
698 idxT = laglist[t]
713 idxT = laglist[t]
699 if idxT >= 0:
714 if idxT >= 0:
700 vStacked = numpy.vstack((volts2[idxT:,:],
715 vStacked = numpy.vstack((volts2[idxT:,:],
701 numpy.zeros((idxT, nHeights),dtype='complex')))
716 numpy.zeros((idxT, nHeights),dtype='complex')))
702 else:
717 else:
703 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
718 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
704 volts2[:(nPoints + idxT),:]))
719 volts2[:(nPoints + idxT),:]))
705 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
720 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
706
721
707 vStacked = None
722 vStacked = None
708 return voltsCCF
723 return voltsCCF
709
724
710 def __getNoise(self, power, timeSegment, timeInterval):
725 def __getNoise(self, power, timeSegment, timeInterval):
711 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
726 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
712 numBlocks = int(power.shape[0]/numProfPerBlock)
727 numBlocks = int(power.shape[0]/numProfPerBlock)
713 numHeights = power.shape[1]
728 numHeights = power.shape[1]
714
729
715 listPower = numpy.array_split(power, numBlocks, 0)
730 listPower = numpy.array_split(power, numBlocks, 0)
716 noise = numpy.zeros((power.shape[0], power.shape[1]))
731 noise = numpy.zeros((power.shape[0], power.shape[1]))
717 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
732 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
718
733
719 startInd = 0
734 startInd = 0
720 endInd = 0
735 endInd = 0
721
736
722 for i in range(numBlocks): #split por canal
737 for i in range(numBlocks): #split por canal
723 startInd = endInd
738 startInd = endInd
724 endInd = endInd + listPower[i].shape[0]
739 endInd = endInd + listPower[i].shape[0]
725
740
726 arrayBlock = listPower[i]
741 arrayBlock = listPower[i]
727 noiseAux = numpy.mean(arrayBlock, 0)
742 noiseAux = numpy.mean(arrayBlock, 0)
728 # noiseAux = numpy.median(noiseAux)
743 # noiseAux = numpy.median(noiseAux)
729 # noiseAux = numpy.mean(arrayBlock)
744 # noiseAux = numpy.mean(arrayBlock)
730 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
745 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
731
746
732 noiseAux1 = numpy.mean(arrayBlock)
747 noiseAux1 = numpy.mean(arrayBlock)
733 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
748 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
734
749
735 return noise, noise1
750 return noise, noise1
736
751
737 def __findMeteors(self, power, thresh):
752 def __findMeteors(self, power, thresh):
738 nProf = power.shape[0]
753 nProf = power.shape[0]
739 nHeights = power.shape[1]
754 nHeights = power.shape[1]
740 listMeteors = []
755 listMeteors = []
741
756
742 for i in range(nHeights):
757 for i in range(nHeights):
743 powerAux = power[:,i]
758 powerAux = power[:,i]
744 threshAux = thresh[:,i]
759 threshAux = thresh[:,i]
745
760
746 indUPthresh = numpy.where(powerAux > threshAux)[0]
761 indUPthresh = numpy.where(powerAux > threshAux)[0]
747 indDNthresh = numpy.where(powerAux <= threshAux)[0]
762 indDNthresh = numpy.where(powerAux <= threshAux)[0]
748
763
749 j = 0
764 j = 0
750
765
751 while (j < indUPthresh.size - 2):
766 while (j < indUPthresh.size - 2):
752 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
767 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
753 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
768 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
754 indDNthresh = indDNthresh[indDNAux]
769 indDNthresh = indDNthresh[indDNAux]
755
770
756 if (indDNthresh.size > 0):
771 if (indDNthresh.size > 0):
757 indEnd = indDNthresh[0] - 1
772 indEnd = indDNthresh[0] - 1
758 indInit = indUPthresh[j]
773 indInit = indUPthresh[j]
759
774
760 meteor = powerAux[indInit:indEnd + 1]
775 meteor = powerAux[indInit:indEnd + 1]
761 indPeak = meteor.argmax() + indInit
776 indPeak = meteor.argmax() + indInit
762 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
777 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
763
778
764 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
779 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
765 j = numpy.where(indUPthresh == indEnd)[0] + 1
780 j = numpy.where(indUPthresh == indEnd)[0] + 1
766 else: j+=1
781 else: j+=1
767 else: j+=1
782 else: j+=1
768
783
769 return listMeteors
784 return listMeteors
770
785
771 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
786 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
772
787
773 arrayMeteors = numpy.asarray(listMeteors)
788 arrayMeteors = numpy.asarray(listMeteors)
774 listMeteors1 = []
789 listMeteors1 = []
775
790
776 while arrayMeteors.shape[0] > 0:
791 while arrayMeteors.shape[0] > 0:
777 FLAs = arrayMeteors[:,4]
792 FLAs = arrayMeteors[:,4]
778 maxFLA = FLAs.argmax()
793 maxFLA = FLAs.argmax()
779 listMeteors1.append(arrayMeteors[maxFLA,:])
794 listMeteors1.append(arrayMeteors[maxFLA,:])
780
795
781 MeteorInitTime = arrayMeteors[maxFLA,1]
796 MeteorInitTime = arrayMeteors[maxFLA,1]
782 MeteorEndTime = arrayMeteors[maxFLA,3]
797 MeteorEndTime = arrayMeteors[maxFLA,3]
783 MeteorHeight = arrayMeteors[maxFLA,0]
798 MeteorHeight = arrayMeteors[maxFLA,0]
784
799
785 #Check neighborhood
800 #Check neighborhood
786 maxHeightIndex = MeteorHeight + rangeLimit
801 maxHeightIndex = MeteorHeight + rangeLimit
787 minHeightIndex = MeteorHeight - rangeLimit
802 minHeightIndex = MeteorHeight - rangeLimit
788 minTimeIndex = MeteorInitTime - timeLimit
803 minTimeIndex = MeteorInitTime - timeLimit
789 maxTimeIndex = MeteorEndTime + timeLimit
804 maxTimeIndex = MeteorEndTime + timeLimit
790
805
791 #Check Heights
806 #Check Heights
792 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
807 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
793 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
808 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
794 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
809 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
795
810
796 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
811 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
797
812
798 return listMeteors1
813 return listMeteors1
799
814
800 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
815 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
801 numHeights = volts.shape[2]
816 numHeights = volts.shape[2]
802 nChannel = volts.shape[0]
817 nChannel = volts.shape[0]
803
818
804 thresholdPhase = thresh[0]
819 thresholdPhase = thresh[0]
805 thresholdNoise = thresh[1]
820 thresholdNoise = thresh[1]
806 thresholdDB = float(thresh[2])
821 thresholdDB = float(thresh[2])
807
822
808 thresholdDB1 = 10**(thresholdDB/10)
823 thresholdDB1 = 10**(thresholdDB/10)
809 pairsarray = numpy.array(pairslist)
824 pairsarray = numpy.array(pairslist)
810 indSides = pairsarray[:,1]
825 indSides = pairsarray[:,1]
811
826
812 pairslist1 = list(pairslist)
827 pairslist1 = list(pairslist)
813 pairslist1.append((0,1))
828 pairslist1.append((0,1))
814 pairslist1.append((3,4))
829 pairslist1.append((3,4))
815
830
816 listMeteors1 = []
831 listMeteors1 = []
817 listPowerSeries = []
832 listPowerSeries = []
818 listVoltageSeries = []
833 listVoltageSeries = []
819 #volts has the war data
834 #volts has the war data
820
835
821 if frequency == 30e6:
836 if frequency == 30e6:
822 timeLag = 45*10**-3
837 timeLag = 45*10**-3
823 else:
838 else:
824 timeLag = 15*10**-3
839 timeLag = 15*10**-3
825 lag = numpy.ceil(timeLag/timeInterval)
840 lag = numpy.ceil(timeLag/timeInterval)
826
841
827 for i in range(len(listMeteors)):
842 for i in range(len(listMeteors)):
828
843
829 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
844 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
830 meteorAux = numpy.zeros(16)
845 meteorAux = numpy.zeros(16)
831
846
832 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
847 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
833 mHeight = listMeteors[i][0]
848 mHeight = listMeteors[i][0]
834 mStart = listMeteors[i][1]
849 mStart = listMeteors[i][1]
835 mPeak = listMeteors[i][2]
850 mPeak = listMeteors[i][2]
836 mEnd = listMeteors[i][3]
851 mEnd = listMeteors[i][3]
837
852
838 #get the volt data between the start and end times of the meteor
853 #get the volt data between the start and end times of the meteor
839 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
854 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
840 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
855 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
841
856
842 #3.6. Phase Difference estimation
857 #3.6. Phase Difference estimation
843 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
858 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
844
859
845 #3.7. Phase difference removal & meteor start, peak and end times reestimated
860 #3.7. Phase difference removal & meteor start, peak and end times reestimated
846 #meteorVolts0.- all Channels, all Profiles
861 #meteorVolts0.- all Channels, all Profiles
847 meteorVolts0 = volts[:,:,mHeight]
862 meteorVolts0 = volts[:,:,mHeight]
848 meteorThresh = noise[:,mHeight]*thresholdNoise
863 meteorThresh = noise[:,mHeight]*thresholdNoise
849 meteorNoise = noise[:,mHeight]
864 meteorNoise = noise[:,mHeight]
850 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
865 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
851 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
866 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
852
867
853 #Times reestimation
868 #Times reestimation
854 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
869 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
855 if mStart1.size > 0:
870 if mStart1.size > 0:
856 mStart1 = mStart1[-1] + 1
871 mStart1 = mStart1[-1] + 1
857
872
858 else:
873 else:
859 mStart1 = mPeak
874 mStart1 = mPeak
860
875
861 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
876 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
862 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
877 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
863 if mEndDecayTime1.size == 0:
878 if mEndDecayTime1.size == 0:
864 mEndDecayTime1 = powerNet0.size
879 mEndDecayTime1 = powerNet0.size
865 else:
880 else:
866 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
881 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
867 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
882 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
868
883
869 #meteorVolts1.- all Channels, from start to end
884 #meteorVolts1.- all Channels, from start to end
870 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
885 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
871 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
886 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
872 if meteorVolts2.shape[1] == 0:
887 if meteorVolts2.shape[1] == 0:
873 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
888 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
874 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
889 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
875 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
890 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
876 ##################### END PARAMETERS REESTIMATION #########################
891 ##################### END PARAMETERS REESTIMATION #########################
877
892
878 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
893 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
879 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
894 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
880 if meteorVolts2.shape[1] > 0:
895 if meteorVolts2.shape[1] > 0:
881 #Phase Difference re-estimation
896 #Phase Difference re-estimation
882 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
897 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
883 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
898 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
884 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
899 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
885 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
900 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
886 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
901 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
887
902
888 #Phase Difference RMS
903 #Phase Difference RMS
889 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
904 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
890 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
905 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
891 #Data from Meteor
906 #Data from Meteor
892 mPeak1 = powerNet1.argmax() + mStart1
907 mPeak1 = powerNet1.argmax() + mStart1
893 mPeakPower1 = powerNet1.max()
908 mPeakPower1 = powerNet1.max()
894 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
909 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
895 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
910 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
896 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
911 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
897 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
912 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
898 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
913 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
899 #Vectorize
914 #Vectorize
900 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
915 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
901 meteorAux[7:11] = phaseDiffint[0:4]
916 meteorAux[7:11] = phaseDiffint[0:4]
902
917
903 #Rejection Criterions
918 #Rejection Criterions
904 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
919 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
905 meteorAux[-1] = 17
920 meteorAux[-1] = 17
906 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
921 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
907 meteorAux[-1] = 1
922 meteorAux[-1] = 1
908
923
909
924
910 else:
925 else:
911 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
926 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
912 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
927 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
913 PowerSeries = 0
928 PowerSeries = 0
914
929
915 listMeteors1.append(meteorAux)
930 listMeteors1.append(meteorAux)
916 listPowerSeries.append(PowerSeries)
931 listPowerSeries.append(PowerSeries)
917 listVoltageSeries.append(meteorVolts1)
932 listVoltageSeries.append(meteorVolts1)
918
933
919 return listMeteors1, listPowerSeries, listVoltageSeries
934 return listMeteors1, listPowerSeries, listVoltageSeries
920
935
921 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
936 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
922
937
923 threshError = 10
938 threshError = 10
924 #Depending if it is 30 or 50 MHz
939 #Depending if it is 30 or 50 MHz
925 if frequency == 30e6:
940 if frequency == 30e6:
926 timeLag = 45*10**-3
941 timeLag = 45*10**-3
927 else:
942 else:
928 timeLag = 15*10**-3
943 timeLag = 15*10**-3
929 lag = numpy.ceil(timeLag/timeInterval)
944 lag = numpy.ceil(timeLag/timeInterval)
930
945
931 listMeteors1 = []
946 listMeteors1 = []
932
947
933 for i in range(len(listMeteors)):
948 for i in range(len(listMeteors)):
934 meteorPower = listPower[i]
949 meteorPower = listPower[i]
935 meteorAux = listMeteors[i]
950 meteorAux = listMeteors[i]
936
951
937 if meteorAux[-1] == 0:
952 if meteorAux[-1] == 0:
938
953
939 try:
954 try:
940 indmax = meteorPower.argmax()
955 indmax = meteorPower.argmax()
941 indlag = indmax + lag
956 indlag = indmax + lag
942
957
943 y = meteorPower[indlag:]
958 y = meteorPower[indlag:]
944 x = numpy.arange(0, y.size)*timeLag
959 x = numpy.arange(0, y.size)*timeLag
945
960
946 #first guess
961 #first guess
947 a = y[0]
962 a = y[0]
948 tau = timeLag
963 tau = timeLag
949 #exponential fit
964 #exponential fit
950 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
965 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
951 y1 = self.__exponential_function(x, *popt)
966 y1 = self.__exponential_function(x, *popt)
952 #error estimation
967 #error estimation
953 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
968 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
954
969
955 decayTime = popt[1]
970 decayTime = popt[1]
956 riseTime = indmax*timeInterval
971 riseTime = indmax*timeInterval
957 meteorAux[11:13] = [decayTime, error]
972 meteorAux[11:13] = [decayTime, error]
958
973
959 #Table items 7, 8 and 11
974 #Table items 7, 8 and 11
960 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
975 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
961 meteorAux[-1] = 7
976 meteorAux[-1] = 7
962 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
977 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
963 meteorAux[-1] = 8
978 meteorAux[-1] = 8
964 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
979 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
965 meteorAux[-1] = 11
980 meteorAux[-1] = 11
966
981
967
982
968 except:
983 except:
969 meteorAux[-1] = 11
984 meteorAux[-1] = 11
970
985
971
986
972 listMeteors1.append(meteorAux)
987 listMeteors1.append(meteorAux)
973
988
974 return listMeteors1
989 return listMeteors1
975
990
976 #Exponential Function
991 #Exponential Function
977
992
978 def __exponential_function(self, x, a, tau):
993 def __exponential_function(self, x, a, tau):
979 y = a*numpy.exp(-x/tau)
994 y = a*numpy.exp(-x/tau)
980 return y
995 return y
981
996
982 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
997 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
983
998
984 pairslist1 = list(pairslist)
999 pairslist1 = list(pairslist)
985 pairslist1.append((0,1))
1000 pairslist1.append((0,1))
986 pairslist1.append((3,4))
1001 pairslist1.append((3,4))
987 numPairs = len(pairslist1)
1002 numPairs = len(pairslist1)
988 #Time Lag
1003 #Time Lag
989 timeLag = 45*10**-3
1004 timeLag = 45*10**-3
990 c = 3e8
1005 c = 3e8
991 lag = numpy.ceil(timeLag/timeInterval)
1006 lag = numpy.ceil(timeLag/timeInterval)
992 freq = 30e6
1007 freq = 30e6
993
1008
994 listMeteors1 = []
1009 listMeteors1 = []
995
1010
996 for i in range(len(listMeteors)):
1011 for i in range(len(listMeteors)):
997 meteorAux = listMeteors[i]
1012 meteorAux = listMeteors[i]
998 if meteorAux[-1] == 0:
1013 if meteorAux[-1] == 0:
999 mStart = listMeteors[i][1]
1014 mStart = listMeteors[i][1]
1000 mPeak = listMeteors[i][2]
1015 mPeak = listMeteors[i][2]
1001 mLag = mPeak - mStart + lag
1016 mLag = mPeak - mStart + lag
1002
1017
1003 #get the volt data between the start and end times of the meteor
1018 #get the volt data between the start and end times of the meteor
1004 meteorVolts = listVolts[i]
1019 meteorVolts = listVolts[i]
1005 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
1020 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
1006
1021
1007 #Get CCF
1022 #Get CCF
1008 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
1023 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
1009
1024
1010 #Method 2
1025 #Method 2
1011 slopes = numpy.zeros(numPairs)
1026 slopes = numpy.zeros(numPairs)
1012 time = numpy.array([-2,-1,1,2])*timeInterval
1027 time = numpy.array([-2,-1,1,2])*timeInterval
1013 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
1028 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
1014
1029
1015 #Correct phases
1030 #Correct phases
1016 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
1031 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
1017 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
1032 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
1018
1033
1019 if indDer[0].shape[0] > 0:
1034 if indDer[0].shape[0] > 0:
1020 for i in range(indDer[0].shape[0]):
1035 for i in range(indDer[0].shape[0]):
1021 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
1036 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
1022 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
1037 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
1023
1038
1024 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
1039 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
1025 for j in range(numPairs):
1040 for j in range(numPairs):
1026 fit = stats.linregress(time, angAllCCF[j,:])
1041 fit = stats.linregress(time, angAllCCF[j,:])
1027 slopes[j] = fit[0]
1042 slopes[j] = fit[0]
1028
1043
1029 #Remove Outlier
1044 #Remove Outlier
1030 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
1045 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
1031 # slopes = numpy.delete(slopes,indOut)
1046 # slopes = numpy.delete(slopes,indOut)
1032 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
1047 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
1033 # slopes = numpy.delete(slopes,indOut)
1048 # slopes = numpy.delete(slopes,indOut)
1034
1049
1035 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
1050 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
1036 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
1051 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
1037 meteorAux[-2] = radialError
1052 meteorAux[-2] = radialError
1038 meteorAux[-3] = radialVelocity
1053 meteorAux[-3] = radialVelocity
1039
1054
1040 #Setting Error
1055 #Setting Error
1041 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
1056 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
1042 if numpy.abs(radialVelocity) > 200:
1057 if numpy.abs(radialVelocity) > 200:
1043 meteorAux[-1] = 15
1058 meteorAux[-1] = 15
1044 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
1059 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
1045 elif radialError > radialStdThresh:
1060 elif radialError > radialStdThresh:
1046 meteorAux[-1] = 12
1061 meteorAux[-1] = 12
1047
1062
1048 listMeteors1.append(meteorAux)
1063 listMeteors1.append(meteorAux)
1049 return listMeteors1
1064 return listMeteors1
1050
1065
1051 def __setNewArrays(self, listMeteors, date, heiRang):
1066 def __setNewArrays(self, listMeteors, date, heiRang):
1052
1067
1053 #New arrays
1068 #New arrays
1054 arrayMeteors = numpy.array(listMeteors)
1069 arrayMeteors = numpy.array(listMeteors)
1055 arrayParameters = numpy.zeros((len(listMeteors), 14))
1070 arrayParameters = numpy.zeros((len(listMeteors), 14))
1056
1071
1057 #Date inclusion
1072 #Date inclusion
1058 date = re.findall(r'\((.*?)\)', date)
1073 # date = re.findall(r'\((.*?)\)', date)
1059 date = date[0].split(',')
1074 # date = date[0].split(',')
1060 date = map(int, date)
1075 # date = map(int, date)
1061
1076 #
1062 if len(date)<6:
1077 # if len(date)<6:
1063 date.append(0)
1078 # date.append(0)
1064
1079 #
1065 date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
1080 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
1066 arrayDate = numpy.tile(date, (len(listMeteors), 1))
1081 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
1082 arrayDate = numpy.tile(date, (len(listMeteors)))
1067
1083
1068 #Meteor array
1084 #Meteor array
1069 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
1085 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
1070 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
1086 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
1071
1087
1072 #Parameters Array
1088 #Parameters Array
1073 arrayParameters[:,:2] = arrayDate #Date
1089 arrayParameters[:,0] = arrayDate #Date
1074 arrayParameters[:,2] = heiRang[arrayMeteors[:,0].astype(int)] #Range
1090 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
1075 arrayParameters[:,7:9] = arrayMeteors[:,-3:-1] #Radial velocity and its error
1091 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
1076 arrayParameters[:,9:13] = arrayMeteors[:,7:11] #Phases
1092 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
1077 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
1093 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
1078
1094
1079
1095
1080 return arrayParameters
1096 return arrayParameters
1081
1097
1082 def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
1098 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
1083
1099 #
1084 arrayAOA = numpy.zeros((phases.shape[0],3))
1100 # arrayAOA = numpy.zeros((phases.shape[0],3))
1085 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
1101 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
1086
1102 #
1087 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
1103 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
1088 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
1104 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
1089 arrayAOA[:,2] = cosDirError
1105 # arrayAOA[:,2] = cosDirError
1090
1106 #
1091 azimuthAngle = arrayAOA[:,0]
1107 # azimuthAngle = arrayAOA[:,0]
1092 zenithAngle = arrayAOA[:,1]
1108 # zenithAngle = arrayAOA[:,1]
1093
1109 #
1094 #Setting Error
1110 # #Setting Error
1095 #Number 3: AOA not fesible
1111 # #Number 3: AOA not fesible
1096 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
1112 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
1097 error[indInvalid] = 3
1113 # error[indInvalid] = 3
1098 #Number 4: Large difference in AOAs obtained from different antenna baselines
1114 # #Number 4: Large difference in AOAs obtained from different antenna baselines
1099 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
1115 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
1100 error[indInvalid] = 4
1116 # error[indInvalid] = 4
1101 return arrayAOA, error
1117 # return arrayAOA, error
1102
1118 #
1103 def __getDirectionCosines(self, arrayPhase, pairsList):
1119 # def __getDirectionCosines(self, arrayPhase, pairsList):
1104
1120 #
1105 #Initializing some variables
1121 # #Initializing some variables
1106 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
1122 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
1107 ang_aux = ang_aux.reshape(1,ang_aux.size)
1123 # ang_aux = ang_aux.reshape(1,ang_aux.size)
1108
1124 #
1109 cosdir = numpy.zeros((arrayPhase.shape[0],2))
1125 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
1110 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
1126 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
1111
1127 #
1112
1128 #
1113 for i in range(2):
1129 # for i in range(2):
1114 #First Estimation
1130 # #First Estimation
1115 phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
1131 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
1116 #Dealias
1132 # #Dealias
1117 indcsi = numpy.where(phi0_aux > numpy.pi)
1133 # indcsi = numpy.where(phi0_aux > numpy.pi)
1118 phi0_aux[indcsi] -= 2*numpy.pi
1134 # phi0_aux[indcsi] -= 2*numpy.pi
1119 indcsi = numpy.where(phi0_aux < -numpy.pi)
1135 # indcsi = numpy.where(phi0_aux < -numpy.pi)
1120 phi0_aux[indcsi] += 2*numpy.pi
1136 # phi0_aux[indcsi] += 2*numpy.pi
1121 #Direction Cosine 0
1137 # #Direction Cosine 0
1122 cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
1138 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
1123
1139 #
1124 #Most-Accurate Second Estimation
1140 # #Most-Accurate Second Estimation
1125 phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
1141 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
1126 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
1142 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
1127 #Direction Cosine 1
1143 # #Direction Cosine 1
1128 cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
1144 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
1129
1145 #
1130 #Searching the correct Direction Cosine
1146 # #Searching the correct Direction Cosine
1131 cosdir0_aux = cosdir0[:,i]
1147 # cosdir0_aux = cosdir0[:,i]
1132 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
1148 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
1133 #Minimum Distance
1149 # #Minimum Distance
1134 cosDiff = (cosdir1 - cosdir0_aux)**2
1150 # cosDiff = (cosdir1 - cosdir0_aux)**2
1135 indcos = cosDiff.argmin(axis = 1)
1151 # indcos = cosDiff.argmin(axis = 1)
1136 #Saving Value obtained
1152 # #Saving Value obtained
1137 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
1153 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
1138
1154 #
1139 return cosdir0, cosdir
1155 # return cosdir0, cosdir
1140
1156 #
1141 def __calculateAOA(self, cosdir, azimuth):
1157 # def __calculateAOA(self, cosdir, azimuth):
1142 cosdirX = cosdir[:,0]
1158 # cosdirX = cosdir[:,0]
1143 cosdirY = cosdir[:,1]
1159 # cosdirY = cosdir[:,1]
1144
1160 #
1145 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
1161 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
1146 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
1162 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
1147 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
1163 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
1148
1164 #
1149 return angles
1165 # return angles
1150
1166 #
1151 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
1167 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
1152
1168 #
1153 Ramb = 375 #Ramb = c/(2*PRF)
1169 # Ramb = 375 #Ramb = c/(2*PRF)
1154 Re = 6371 #Earth Radius
1170 # Re = 6371 #Earth Radius
1155 heights = numpy.zeros(Ranges.shape)
1171 # heights = numpy.zeros(Ranges.shape)
1156
1172 #
1157 R_aux = numpy.array([0,1,2])*Ramb
1173 # R_aux = numpy.array([0,1,2])*Ramb
1158 R_aux = R_aux.reshape(1,R_aux.size)
1174 # R_aux = R_aux.reshape(1,R_aux.size)
1159
1175 #
1160 Ranges = Ranges.reshape(Ranges.size,1)
1176 # Ranges = Ranges.reshape(Ranges.size,1)
1161
1177 #
1162 Ri = Ranges + R_aux
1178 # Ri = Ranges + R_aux
1163 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
1179 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
1164
1180 #
1165 #Check if there is a height between 70 and 110 km
1181 # #Check if there is a height between 70 and 110 km
1166 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
1182 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
1167 ind_h = numpy.where(h_bool == 1)[0]
1183 # ind_h = numpy.where(h_bool == 1)[0]
1168
1184 #
1169 hCorr = hi[ind_h, :]
1185 # hCorr = hi[ind_h, :]
1170 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
1186 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
1171
1187 #
1172 hCorr = hi[ind_hCorr]
1188 # hCorr = hi[ind_hCorr]
1173 heights[ind_h] = hCorr
1189 # heights[ind_h] = hCorr
1174
1190 #
1175 #Setting Error
1191 # #Setting Error
1176 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
1192 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
1177 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
1193 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
1178
1194 #
1179 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
1195 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
1180 error[indInvalid2] = 14
1196 # error[indInvalid2] = 14
1181 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
1197 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
1182 error[indInvalid1] = 13
1198 # error[indInvalid1] = 13
1183
1199 #
1184 return heights, error
1200 # return heights, error
1185
1201
1186 def SpectralFitting(self, getSNR = True, path=None, file=None, groupList=None):
1202 def SpectralFitting(self, getSNR = True, path=None, file=None, groupList=None):
1187
1203
1188 '''
1204 '''
1189 Function GetMoments()
1205 Function GetMoments()
1190
1206
1191 Input:
1207 Input:
1192 Output:
1208 Output:
1193 Variables modified:
1209 Variables modified:
1194 '''
1210 '''
1195 if path != None:
1211 if path != None:
1196 sys.path.append(path)
1212 sys.path.append(path)
1197 self.dataOut.library = importlib.import_module(file)
1213 self.dataOut.library = importlib.import_module(file)
1198
1214
1199 #To be inserted as a parameter
1215 #To be inserted as a parameter
1200 groupArray = numpy.array(groupList)
1216 groupArray = numpy.array(groupList)
1201 # groupArray = numpy.array([[0,1],[2,3]])
1217 # groupArray = numpy.array([[0,1],[2,3]])
1202 self.dataOut.groupList = groupArray
1218 self.dataOut.groupList = groupArray
1203
1219
1204 nGroups = groupArray.shape[0]
1220 nGroups = groupArray.shape[0]
1205 nChannels = self.dataIn.nChannels
1221 nChannels = self.dataIn.nChannels
1206 nHeights=self.dataIn.heightList.size
1222 nHeights=self.dataIn.heightList.size
1207
1223
1208 #Parameters Array
1224 #Parameters Array
1209 self.dataOut.data_param = None
1225 self.dataOut.data_param = None
1210
1226
1211 #Set constants
1227 #Set constants
1212 constants = self.dataOut.library.setConstants(self.dataIn)
1228 constants = self.dataOut.library.setConstants(self.dataIn)
1213 self.dataOut.constants = constants
1229 self.dataOut.constants = constants
1214 M = self.dataIn.normFactor
1230 M = self.dataIn.normFactor
1215 N = self.dataIn.nFFTPoints
1231 N = self.dataIn.nFFTPoints
1216 ippSeconds = self.dataIn.ippSeconds
1232 ippSeconds = self.dataIn.ippSeconds
1217 K = self.dataIn.nIncohInt
1233 K = self.dataIn.nIncohInt
1218 pairsArray = numpy.array(self.dataIn.pairsList)
1234 pairsArray = numpy.array(self.dataIn.pairsList)
1219
1235
1220 #List of possible combinations
1236 #List of possible combinations
1221 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1237 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1222 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1238 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1223
1239
1224 if getSNR:
1240 if getSNR:
1225 listChannels = groupArray.reshape((groupArray.size))
1241 listChannels = groupArray.reshape((groupArray.size))
1226 listChannels.sort()
1242 listChannels.sort()
1227 noise = self.dataIn.getNoise()
1243 noise = self.dataIn.getNoise()
1228 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1244 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1229
1245
1230 for i in range(nGroups):
1246 for i in range(nGroups):
1231 coord = groupArray[i,:]
1247 coord = groupArray[i,:]
1232
1248
1233 #Input data array
1249 #Input data array
1234 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1250 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1235 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1251 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1236
1252
1237 #Cross Spectra data array for Covariance Matrixes
1253 #Cross Spectra data array for Covariance Matrixes
1238 ind = 0
1254 ind = 0
1239 for pairs in listComb:
1255 for pairs in listComb:
1240 pairsSel = numpy.array([coord[x],coord[y]])
1256 pairsSel = numpy.array([coord[x],coord[y]])
1241 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1257 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1242 ind += 1
1258 ind += 1
1243 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1259 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1244 dataCross = dataCross**2/K
1260 dataCross = dataCross**2/K
1245
1261
1246 for h in range(nHeights):
1262 for h in range(nHeights):
1247 # print self.dataOut.heightList[h]
1263 # print self.dataOut.heightList[h]
1248
1264
1249 #Input
1265 #Input
1250 d = data[:,h]
1266 d = data[:,h]
1251
1267
1252 #Covariance Matrix
1268 #Covariance Matrix
1253 D = numpy.diag(d**2/K)
1269 D = numpy.diag(d**2/K)
1254 ind = 0
1270 ind = 0
1255 for pairs in listComb:
1271 for pairs in listComb:
1256 #Coordinates in Covariance Matrix
1272 #Coordinates in Covariance Matrix
1257 x = pairs[0]
1273 x = pairs[0]
1258 y = pairs[1]
1274 y = pairs[1]
1259 #Channel Index
1275 #Channel Index
1260 S12 = dataCross[ind,:,h]
1276 S12 = dataCross[ind,:,h]
1261 D12 = numpy.diag(S12)
1277 D12 = numpy.diag(S12)
1262 #Completing Covariance Matrix with Cross Spectras
1278 #Completing Covariance Matrix with Cross Spectras
1263 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1279 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1264 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1280 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1265 ind += 1
1281 ind += 1
1266 Dinv=numpy.linalg.inv(D)
1282 Dinv=numpy.linalg.inv(D)
1267 L=numpy.linalg.cholesky(Dinv)
1283 L=numpy.linalg.cholesky(Dinv)
1268 LT=L.T
1284 LT=L.T
1269
1285
1270 dp = numpy.dot(LT,d)
1286 dp = numpy.dot(LT,d)
1271
1287
1272 #Initial values
1288 #Initial values
1273 data_spc = self.dataIn.data_spc[coord,:,h]
1289 data_spc = self.dataIn.data_spc[coord,:,h]
1274
1290
1275 if (h>0)and(error1[3]<5):
1291 if (h>0)and(error1[3]<5):
1276 p0 = self.dataOut.data_param[i,:,h-1]
1292 p0 = self.dataOut.data_param[i,:,h-1]
1277 else:
1293 else:
1278 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1294 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1279
1295
1280 try:
1296 try:
1281 #Least Squares
1297 #Least Squares
1282 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1298 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1283 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1299 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1284 #Chi square error
1300 #Chi square error
1285 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1301 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1286 #Error with Jacobian
1302 #Error with Jacobian
1287 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1303 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1288 except:
1304 except:
1289 minp = p0*numpy.nan
1305 minp = p0*numpy.nan
1290 error0 = numpy.nan
1306 error0 = numpy.nan
1291 error1 = p0*numpy.nan
1307 error1 = p0*numpy.nan
1292
1308
1293 #Save
1309 #Save
1294 if self.dataOut.data_param == None:
1310 if self.dataOut.data_param == None:
1295 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1311 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1296 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1312 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1297
1313
1298 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1314 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1299 self.dataOut.data_param[i,:,h] = minp
1315 self.dataOut.data_param[i,:,h] = minp
1300 return
1316 return
1301
1317
1302 def __residFunction(self, p, dp, LT, constants):
1318 def __residFunction(self, p, dp, LT, constants):
1303
1319
1304 fm = self.dataOut.library.modelFunction(p, constants)
1320 fm = self.dataOut.library.modelFunction(p, constants)
1305 fmp=numpy.dot(LT,fm)
1321 fmp=numpy.dot(LT,fm)
1306
1322
1307 return dp-fmp
1323 return dp-fmp
1308
1324
1309 def __getSNR(self, z, noise):
1325 def __getSNR(self, z, noise):
1310
1326
1311 avg = numpy.average(z, axis=1)
1327 avg = numpy.average(z, axis=1)
1312 SNR = (avg.T-noise)/noise
1328 SNR = (avg.T-noise)/noise
1313 SNR = SNR.T
1329 SNR = SNR.T
1314 return SNR
1330 return SNR
1315
1331
1316 def __chisq(p,chindex,hindex):
1332 def __chisq(p,chindex,hindex):
1317 #similar to Resid but calculates CHI**2
1333 #similar to Resid but calculates CHI**2
1318 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1334 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1319 dp=numpy.dot(LT,d)
1335 dp=numpy.dot(LT,d)
1320 fmp=numpy.dot(LT,fm)
1336 fmp=numpy.dot(LT,fm)
1321 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1337 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1322 return chisq
1338 return chisq
1323
1339
1324
1340
1325
1326 class WindProfiler(Operation):
1341 class WindProfiler(Operation):
1327
1342
1328 __isConfig = False
1343 __isConfig = False
1329
1344
1330 __initime = None
1345 __initime = None
1331 __lastdatatime = None
1346 __lastdatatime = None
1332 __integrationtime = None
1347 __integrationtime = None
1333
1348
1334 __buffer = None
1349 __buffer = None
1335
1350
1336 __dataReady = False
1351 __dataReady = False
1337
1352
1338 __firstdata = None
1353 __firstdata = None
1339
1354
1340 n = None
1355 n = None
1341
1356
1342 def __init__(self):
1357 def __init__(self):
1343 Operation.__init__(self)
1358 Operation.__init__(self)
1344
1359
1345 def __calculateCosDir(self, elev, azim):
1360 def __calculateCosDir(self, elev, azim):
1346 zen = (90 - elev)*numpy.pi/180
1361 zen = (90 - elev)*numpy.pi/180
1347 azim = azim*numpy.pi/180
1362 azim = azim*numpy.pi/180
1348 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1363 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1349 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1364 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1350
1365
1351 signX = numpy.sign(numpy.cos(azim))
1366 signX = numpy.sign(numpy.cos(azim))
1352 signY = numpy.sign(numpy.sin(azim))
1367 signY = numpy.sign(numpy.sin(azim))
1353
1368
1354 cosDirX = numpy.copysign(cosDirX, signX)
1369 cosDirX = numpy.copysign(cosDirX, signX)
1355 cosDirY = numpy.copysign(cosDirY, signY)
1370 cosDirY = numpy.copysign(cosDirY, signY)
1356 return cosDirX, cosDirY
1371 return cosDirX, cosDirY
1357
1372
1358 def __calculateAngles(self, theta_x, theta_y, azimuth):
1373 def __calculateAngles(self, theta_x, theta_y, azimuth):
1359
1374
1360 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1375 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1361 zenith_arr = numpy.arccos(dir_cosw)
1376 zenith_arr = numpy.arccos(dir_cosw)
1362 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1377 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1363
1378
1364 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1379 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1365 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1380 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1366
1381
1367 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1382 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1368
1383
1369 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1384 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1370
1385
1371 #
1386 #
1372 if horOnly:
1387 if horOnly:
1373 A = numpy.c_[dir_cosu,dir_cosv]
1388 A = numpy.c_[dir_cosu,dir_cosv]
1374 else:
1389 else:
1375 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1390 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1376 A = numpy.asmatrix(A)
1391 A = numpy.asmatrix(A)
1377 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1392 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1378
1393
1379 return A1
1394 return A1
1380
1395
1381 def __correctValues(self, heiRang, phi, velRadial, SNR):
1396 def __correctValues(self, heiRang, phi, velRadial, SNR):
1382 listPhi = phi.tolist()
1397 listPhi = phi.tolist()
1383 maxid = listPhi.index(max(listPhi))
1398 maxid = listPhi.index(max(listPhi))
1384 minid = listPhi.index(min(listPhi))
1399 minid = listPhi.index(min(listPhi))
1385
1400
1386 rango = range(len(phi))
1401 rango = range(len(phi))
1387 # rango = numpy.delete(rango,maxid)
1402 # rango = numpy.delete(rango,maxid)
1388
1403
1389 heiRang1 = heiRang*math.cos(phi[maxid])
1404 heiRang1 = heiRang*math.cos(phi[maxid])
1390 heiRangAux = heiRang*math.cos(phi[minid])
1405 heiRangAux = heiRang*math.cos(phi[minid])
1391 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1406 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1392 heiRang1 = numpy.delete(heiRang1,indOut)
1407 heiRang1 = numpy.delete(heiRang1,indOut)
1393
1408
1394 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1409 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1395 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1410 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1396
1411
1397 for i in rango:
1412 for i in rango:
1398 x = heiRang*math.cos(phi[i])
1413 x = heiRang*math.cos(phi[i])
1399 y1 = velRadial[i,:]
1414 y1 = velRadial[i,:]
1400 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1415 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1401
1416
1402 x1 = heiRang1
1417 x1 = heiRang1
1403 y11 = f1(x1)
1418 y11 = f1(x1)
1404
1419
1405 y2 = SNR[i,:]
1420 y2 = SNR[i,:]
1406 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1421 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1407 y21 = f2(x1)
1422 y21 = f2(x1)
1408
1423
1409 velRadial1[i,:] = y11
1424 velRadial1[i,:] = y11
1410 SNR1[i,:] = y21
1425 SNR1[i,:] = y21
1411
1426
1412 return heiRang1, velRadial1, SNR1
1427 return heiRang1, velRadial1, SNR1
1413
1428
1414 def __calculateVelUVW(self, A, velRadial):
1429 def __calculateVelUVW(self, A, velRadial):
1415
1430
1416 #Operacion Matricial
1431 #Operacion Matricial
1417 # velUVW = numpy.zeros((velRadial.shape[1],3))
1432 # velUVW = numpy.zeros((velRadial.shape[1],3))
1418 # for ind in range(velRadial.shape[1]):
1433 # for ind in range(velRadial.shape[1]):
1419 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1434 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1420 # velUVW = velUVW.transpose()
1435 # velUVW = velUVW.transpose()
1421 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1436 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1422 velUVW[:,:] = numpy.dot(A,velRadial)
1437 velUVW[:,:] = numpy.dot(A,velRadial)
1423
1438
1424
1439
1425 return velUVW
1440 return velUVW
1426
1441
1427 def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1442 def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1428 """
1443 """
1429 Function that implements Doppler Beam Swinging (DBS) technique.
1444 Function that implements Doppler Beam Swinging (DBS) technique.
1430
1445
1431 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1446 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1432 Direction correction (if necessary), Ranges and SNR
1447 Direction correction (if necessary), Ranges and SNR
1433
1448
1434 Output: Winds estimation (Zonal, Meridional and Vertical)
1449 Output: Winds estimation (Zonal, Meridional and Vertical)
1435
1450
1436 Parameters affected: Winds, height range, SNR
1451 Parameters affected: Winds, height range, SNR
1437 """
1452 """
1438 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(dirCosx, disrCosy, azimuth)
1453 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(dirCosx, disrCosy, azimuth)
1439 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correct*velRadial0, SNR0)
1454 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correct*velRadial0, SNR0)
1440 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1455 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1441
1456
1442 #Calculo de Componentes de la velocidad con DBS
1457 #Calculo de Componentes de la velocidad con DBS
1443 winds = self.__calculateVelUVW(A,velRadial1)
1458 winds = self.__calculateVelUVW(A,velRadial1)
1444
1459
1445 return winds, heiRang1, SNR1
1460 return winds, heiRang1, SNR1
1446
1461
1447 def __calculateDistance(self, posx, posy, pairsCrossCorr, pairsList, pairs, azimuth = None):
1462 def __calculateDistance(self, posx, posy, pairsCrossCorr, pairsList, pairs, azimuth = None):
1448
1463
1449 posx = numpy.asarray(posx)
1464 posx = numpy.asarray(posx)
1450 posy = numpy.asarray(posy)
1465 posy = numpy.asarray(posy)
1451
1466
1452 #Rotacion Inversa para alinear con el azimuth
1467 #Rotacion Inversa para alinear con el azimuth
1453 if azimuth!= None:
1468 if azimuth!= None:
1454 azimuth = azimuth*math.pi/180
1469 azimuth = azimuth*math.pi/180
1455 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1470 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1456 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1471 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1457 else:
1472 else:
1458 posx1 = posx
1473 posx1 = posx
1459 posy1 = posy
1474 posy1 = posy
1460
1475
1461 #Calculo de Distancias
1476 #Calculo de Distancias
1462 distx = numpy.zeros(pairsCrossCorr.size)
1477 distx = numpy.zeros(pairsCrossCorr.size)
1463 disty = numpy.zeros(pairsCrossCorr.size)
1478 disty = numpy.zeros(pairsCrossCorr.size)
1464 dist = numpy.zeros(pairsCrossCorr.size)
1479 dist = numpy.zeros(pairsCrossCorr.size)
1465 ang = numpy.zeros(pairsCrossCorr.size)
1480 ang = numpy.zeros(pairsCrossCorr.size)
1466
1481
1467 for i in range(pairsCrossCorr.size):
1482 for i in range(pairsCrossCorr.size):
1468 distx[i] = posx1[pairsList[pairsCrossCorr[i]][1]] - posx1[pairsList[pairsCrossCorr[i]][0]]
1483 distx[i] = posx1[pairsList[pairsCrossCorr[i]][1]] - posx1[pairsList[pairsCrossCorr[i]][0]]
1469 disty[i] = posy1[pairsList[pairsCrossCorr[i]][1]] - posy1[pairsList[pairsCrossCorr[i]][0]]
1484 disty[i] = posy1[pairsList[pairsCrossCorr[i]][1]] - posy1[pairsList[pairsCrossCorr[i]][0]]
1470 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1485 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1471 ang[i] = numpy.arctan2(disty[i],distx[i])
1486 ang[i] = numpy.arctan2(disty[i],distx[i])
1472 #Calculo de Matrices
1487 #Calculo de Matrices
1473 nPairs = len(pairs)
1488 nPairs = len(pairs)
1474 ang1 = numpy.zeros((nPairs, 2, 1))
1489 ang1 = numpy.zeros((nPairs, 2, 1))
1475 dist1 = numpy.zeros((nPairs, 2, 1))
1490 dist1 = numpy.zeros((nPairs, 2, 1))
1476
1491
1477 for j in range(nPairs):
1492 for j in range(nPairs):
1478 dist1[j,0,0] = dist[pairs[j][0]]
1493 dist1[j,0,0] = dist[pairs[j][0]]
1479 dist1[j,1,0] = dist[pairs[j][1]]
1494 dist1[j,1,0] = dist[pairs[j][1]]
1480 ang1[j,0,0] = ang[pairs[j][0]]
1495 ang1[j,0,0] = ang[pairs[j][0]]
1481 ang1[j,1,0] = ang[pairs[j][1]]
1496 ang1[j,1,0] = ang[pairs[j][1]]
1482
1497
1483 return distx,disty, dist1,ang1
1498 return distx,disty, dist1,ang1
1484
1499
1485 def __calculateVelVer(self, phase, lagTRange, _lambda):
1500 def __calculateVelVer(self, phase, lagTRange, _lambda):
1486
1501
1487 Ts = lagTRange[1] - lagTRange[0]
1502 Ts = lagTRange[1] - lagTRange[0]
1488 velW = -_lambda*phase/(4*math.pi*Ts)
1503 velW = -_lambda*phase/(4*math.pi*Ts)
1489
1504
1490 return velW
1505 return velW
1491
1506
1492 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1507 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1493 nPairs = tau1.shape[0]
1508 nPairs = tau1.shape[0]
1494 vel = numpy.zeros((nPairs,3,tau1.shape[2]))
1509 vel = numpy.zeros((nPairs,3,tau1.shape[2]))
1495
1510
1496 angCos = numpy.cos(ang)
1511 angCos = numpy.cos(ang)
1497 angSin = numpy.sin(ang)
1512 angSin = numpy.sin(ang)
1498
1513
1499 vel0 = dist*tau1/(2*tau2**2)
1514 vel0 = dist*tau1/(2*tau2**2)
1500 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1515 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1501 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1516 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1502
1517
1503 ind = numpy.where(numpy.isinf(vel))
1518 ind = numpy.where(numpy.isinf(vel))
1504 vel[ind] = numpy.nan
1519 vel[ind] = numpy.nan
1505
1520
1506 return vel
1521 return vel
1507
1522
1508 def __getPairsAutoCorr(self, pairsList, nChannels):
1523 def __getPairsAutoCorr(self, pairsList, nChannels):
1509
1524
1510 pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1525 pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1511
1526
1512 for l in range(len(pairsList)):
1527 for l in range(len(pairsList)):
1513 firstChannel = pairsList[l][0]
1528 firstChannel = pairsList[l][0]
1514 secondChannel = pairsList[l][1]
1529 secondChannel = pairsList[l][1]
1515
1530
1516 #Obteniendo pares de Autocorrelacion
1531 #Obteniendo pares de Autocorrelacion
1517 if firstChannel == secondChannel:
1532 if firstChannel == secondChannel:
1518 pairsAutoCorr[firstChannel] = int(l)
1533 pairsAutoCorr[firstChannel] = int(l)
1519
1534
1520 pairsAutoCorr = pairsAutoCorr.astype(int)
1535 pairsAutoCorr = pairsAutoCorr.astype(int)
1521
1536
1522 pairsCrossCorr = range(len(pairsList))
1537 pairsCrossCorr = range(len(pairsList))
1523 pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1538 pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1524
1539
1525 return pairsAutoCorr, pairsCrossCorr
1540 return pairsAutoCorr, pairsCrossCorr
1526
1541
1527 def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1542 def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1528 """
1543 """
1529 Function that implements Spaced Antenna (SA) technique.
1544 Function that implements Spaced Antenna (SA) technique.
1530
1545
1531 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1546 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1532 Direction correction (if necessary), Ranges and SNR
1547 Direction correction (if necessary), Ranges and SNR
1533
1548
1534 Output: Winds estimation (Zonal, Meridional and Vertical)
1549 Output: Winds estimation (Zonal, Meridional and Vertical)
1535
1550
1536 Parameters affected: Winds
1551 Parameters affected: Winds
1537 """
1552 """
1538 #Cross Correlation pairs obtained
1553 #Cross Correlation pairs obtained
1539 pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1554 pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1540 pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1555 pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1541 pairsSelArray = numpy.array(pairsSelected)
1556 pairsSelArray = numpy.array(pairsSelected)
1542 pairs = []
1557 pairs = []
1543
1558
1544 #Wind estimation pairs obtained
1559 #Wind estimation pairs obtained
1545 for i in range(pairsSelArray.shape[0]/2):
1560 for i in range(pairsSelArray.shape[0]/2):
1546 ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1561 ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1547 ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1562 ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1548 pairs.append((ind1,ind2))
1563 pairs.append((ind1,ind2))
1549
1564
1550 indtau = tau.shape[0]/2
1565 indtau = tau.shape[0]/2
1551 tau1 = tau[:indtau,:]
1566 tau1 = tau[:indtau,:]
1552 tau2 = tau[indtau:-1,:]
1567 tau2 = tau[indtau:-1,:]
1553 tau1 = tau1[pairs,:]
1568 tau1 = tau1[pairs,:]
1554 tau2 = tau2[pairs,:]
1569 tau2 = tau2[pairs,:]
1555 phase1 = tau[-1,:]
1570 phase1 = tau[-1,:]
1556
1571
1557 #---------------------------------------------------------------------
1572 #---------------------------------------------------------------------
1558 #Metodo Directo
1573 #Metodo Directo
1559 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairsCrossCorr, pairsList, pairs,azimuth)
1574 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairsCrossCorr, pairsList, pairs,azimuth)
1560 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1575 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1561 winds = stats.nanmean(winds, axis=0)
1576 winds = stats.nanmean(winds, axis=0)
1562 #---------------------------------------------------------------------
1577 #---------------------------------------------------------------------
1563 #Metodo General
1578 #Metodo General
1564 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1579 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1565 # #Calculo Coeficientes de Funcion de Correlacion
1580 # #Calculo Coeficientes de Funcion de Correlacion
1566 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1581 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1567 # #Calculo de Velocidades
1582 # #Calculo de Velocidades
1568 # winds = self.calculateVelUV(F,G,A,B,H)
1583 # winds = self.calculateVelUV(F,G,A,B,H)
1569
1584
1570 #---------------------------------------------------------------------
1585 #---------------------------------------------------------------------
1571 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1586 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1572 winds = correctFactor*winds
1587 winds = correctFactor*winds
1573 return winds
1588 return winds
1574
1589
1575 def __checkTime(self, currentTime, paramInterval, outputInterval):
1590 def __checkTime(self, currentTime, paramInterval, outputInterval):
1576
1591
1577 dataTime = currentTime + paramInterval
1592 dataTime = currentTime + paramInterval
1578 deltaTime = dataTime - self.__initime
1593 deltaTime = dataTime - self.__initime
1579
1594
1580 if deltaTime >= outputInterval or deltaTime < 0:
1595 if deltaTime >= outputInterval or deltaTime < 0:
1581 self.__dataReady = True
1596 self.__dataReady = True
1582 return
1597 return
1583
1598
1584 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1599 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1585 '''
1600 '''
1586 Function that implements winds estimation technique with detected meteors.
1601 Function that implements winds estimation technique with detected meteors.
1587
1602
1588 Input: Detected meteors, Minimum meteor quantity to wind estimation
1603 Input: Detected meteors, Minimum meteor quantity to wind estimation
1589
1604
1590 Output: Winds estimation (Zonal and Meridional)
1605 Output: Winds estimation (Zonal and Meridional)
1591
1606
1592 Parameters affected: Winds
1607 Parameters affected: Winds
1593 '''
1608 '''
1594 # print arrayMeteor.shape
1609 # print arrayMeteor.shape
1595 #Settings
1610 #Settings
1596 nInt = (heightMax - heightMin)/2
1611 nInt = (heightMax - heightMin)/2
1597 # print nInt
1612 # print nInt
1598 nInt = int(nInt)
1613 nInt = int(nInt)
1599 # print nInt
1614 # print nInt
1600 winds = numpy.zeros((2,nInt))*numpy.nan
1615 winds = numpy.zeros((2,nInt))*numpy.nan
1601
1616
1602 #Filter errors
1617 #Filter errors
1603 error = numpy.where(arrayMeteor[0,:,-1] == 0)[0]
1618 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1604 finalMeteor = arrayMeteor[0,error,:]
1619 finalMeteor = arrayMeteor[error,:]
1605
1620
1606 #Meteor Histogram
1621 #Meteor Histogram
1607 finalHeights = finalMeteor[:,3]
1622 finalHeights = finalMeteor[:,2]
1608 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1623 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1609 nMeteorsPerI = hist[0]
1624 nMeteorsPerI = hist[0]
1610 heightPerI = hist[1]
1625 heightPerI = hist[1]
1611
1626
1612 #Sort of meteors
1627 #Sort of meteors
1613 indSort = finalHeights.argsort()
1628 indSort = finalHeights.argsort()
1614 finalMeteor2 = finalMeteor[indSort,:]
1629 finalMeteor2 = finalMeteor[indSort,:]
1615
1630
1616 # Calculating winds
1631 # Calculating winds
1617 ind1 = 0
1632 ind1 = 0
1618 ind2 = 0
1633 ind2 = 0
1619
1634
1620 for i in range(nInt):
1635 for i in range(nInt):
1621 nMet = nMeteorsPerI[i]
1636 nMet = nMeteorsPerI[i]
1622 ind1 = ind2
1637 ind1 = ind2
1623 ind2 = ind1 + nMet
1638 ind2 = ind1 + nMet
1624
1639
1625 meteorAux = finalMeteor2[ind1:ind2,:]
1640 meteorAux = finalMeteor2[ind1:ind2,:]
1626
1641
1627 if meteorAux.shape[0] >= meteorThresh:
1642 if meteorAux.shape[0] >= meteorThresh:
1628 vel = meteorAux[:, 7]
1643 vel = meteorAux[:, 6]
1629 zen = meteorAux[:, 5]*numpy.pi/180
1644 zen = meteorAux[:, 4]*numpy.pi/180
1630 azim = meteorAux[:, 4]*numpy.pi/180
1645 azim = meteorAux[:, 3]*numpy.pi/180
1631
1646
1632 n = numpy.cos(zen)
1647 n = numpy.cos(zen)
1633 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1648 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1634 # l = m*numpy.tan(azim)
1649 # l = m*numpy.tan(azim)
1635 l = numpy.sin(zen)*numpy.sin(azim)
1650 l = numpy.sin(zen)*numpy.sin(azim)
1636 m = numpy.sin(zen)*numpy.cos(azim)
1651 m = numpy.sin(zen)*numpy.cos(azim)
1637
1652
1638 A = numpy.vstack((l, m)).transpose()
1653 A = numpy.vstack((l, m)).transpose()
1639 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1654 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1640 windsAux = numpy.dot(A1, vel)
1655 windsAux = numpy.dot(A1, vel)
1641
1656
1642 winds[0,i] = windsAux[0]
1657 winds[0,i] = windsAux[0]
1643 winds[1,i] = windsAux[1]
1658 winds[1,i] = windsAux[1]
1644
1659
1645 return winds, heightPerI[:-1]
1660 return winds, heightPerI[:-1]
1646
1661
1647 def run(self, dataOut, technique, **kwargs):
1662 def run(self, dataOut, technique, **kwargs):
1648
1663
1649 param = dataOut.data_param
1664 param = dataOut.data_param
1650 if dataOut.abscissaList != None:
1665 if dataOut.abscissaList != None:
1651 absc = dataOut.abscissaList[:-1]
1666 absc = dataOut.abscissaList[:-1]
1652 noise = dataOut.noise
1667 noise = dataOut.noise
1653 heightList = dataOut.heightList
1668 heightList = dataOut.heightList
1654 SNR = dataOut.data_SNR
1669 SNR = dataOut.data_SNR
1655
1670
1656 if technique == 'DBS':
1671 if technique == 'DBS':
1657
1672
1658 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1673 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1659 theta_x = numpy.array(kwargs['dirCosx'])
1674 theta_x = numpy.array(kwargs['dirCosx'])
1660 theta_y = numpy.array(kwargs['dirCosy'])
1675 theta_y = numpy.array(kwargs['dirCosy'])
1661 else:
1676 else:
1662 elev = numpy.array(kwargs['elevation'])
1677 elev = numpy.array(kwargs['elevation'])
1663 azim = numpy.array(kwargs['azimuth'])
1678 azim = numpy.array(kwargs['azimuth'])
1664 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1679 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1665 azimuth = kwargs['correctAzimuth']
1680 azimuth = kwargs['correctAzimuth']
1666 if kwargs.has_key('horizontalOnly'):
1681 if kwargs.has_key('horizontalOnly'):
1667 horizontalOnly = kwargs['horizontalOnly']
1682 horizontalOnly = kwargs['horizontalOnly']
1668 else: horizontalOnly = False
1683 else: horizontalOnly = False
1669 if kwargs.has_key('correctFactor'):
1684 if kwargs.has_key('correctFactor'):
1670 correctFactor = kwargs['correctFactor']
1685 correctFactor = kwargs['correctFactor']
1671 else: correctFactor = 1
1686 else: correctFactor = 1
1672 if kwargs.has_key('channelList'):
1687 if kwargs.has_key('channelList'):
1673 channelList = kwargs['channelList']
1688 channelList = kwargs['channelList']
1674 if len(channelList) == 2:
1689 if len(channelList) == 2:
1675 horizontalOnly = True
1690 horizontalOnly = True
1676 arrayChannel = numpy.array(channelList)
1691 arrayChannel = numpy.array(channelList)
1677 param = param[arrayChannel,:,:]
1692 param = param[arrayChannel,:,:]
1678 theta_x = theta_x[arrayChannel]
1693 theta_x = theta_x[arrayChannel]
1679 theta_y = theta_y[arrayChannel]
1694 theta_y = theta_y[arrayChannel]
1680
1695
1681 velRadial0 = param[:,1,:] #Radial velocity
1696 velRadial0 = param[:,1,:] #Radial velocity
1682 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(velRadial0, theta_x, theta_y, azimuth, correctFactor, horizontalOnly, heightList, SNR) #DBS Function
1697 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(velRadial0, theta_x, theta_y, azimuth, correctFactor, horizontalOnly, heightList, SNR) #DBS Function
1683 dataOut.utctimeInit = dataOut.utctime
1698 dataOut.utctimeInit = dataOut.utctime
1684 dataOut.outputInterval = dataOut.timeInterval
1699 dataOut.outputInterval = dataOut.timeInterval
1685
1700
1686 elif technique == 'SA':
1701 elif technique == 'SA':
1687
1702
1688 #Parameters
1703 #Parameters
1689 position_x = kwargs['positionX']
1704 position_x = kwargs['positionX']
1690 position_y = kwargs['positionY']
1705 position_y = kwargs['positionY']
1691 azimuth = kwargs['azimuth']
1706 azimuth = kwargs['azimuth']
1692
1707
1693 if kwargs.has_key('crosspairsList'):
1708 if kwargs.has_key('crosspairsList'):
1694 pairs = kwargs['crosspairsList']
1709 pairs = kwargs['crosspairsList']
1695 else:
1710 else:
1696 pairs = None
1711 pairs = None
1697
1712
1698 if kwargs.has_key('correctFactor'):
1713 if kwargs.has_key('correctFactor'):
1699 correctFactor = kwargs['correctFactor']
1714 correctFactor = kwargs['correctFactor']
1700 else:
1715 else:
1701 correctFactor = 1
1716 correctFactor = 1
1702
1717
1703 tau = dataOut.data_param
1718 tau = dataOut.data_param
1704 _lambda = dataOut.C/dataOut.frequency
1719 _lambda = dataOut.C/dataOut.frequency
1705 pairsList = dataOut.groupList
1720 pairsList = dataOut.groupList
1706 nChannels = dataOut.nChannels
1721 nChannels = dataOut.nChannels
1707
1722
1708 dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
1723 dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
1709 dataOut.utctimeInit = dataOut.utctime
1724 dataOut.utctimeInit = dataOut.utctime
1710 dataOut.outputInterval = dataOut.timeInterval
1725 dataOut.outputInterval = dataOut.timeInterval
1711
1726
1712 elif technique == 'Meteors':
1727 elif technique == 'Meteors':
1713 dataOut.flagNoData = True
1728 dataOut.flagNoData = True
1714 self.__dataReady = False
1729 self.__dataReady = False
1715
1730
1716 if kwargs.has_key('nHours'):
1731 if kwargs.has_key('nHours'):
1717 nHours = kwargs['nHours']
1732 nHours = kwargs['nHours']
1718 else:
1733 else:
1719 nHours = 1
1734 nHours = 1
1720
1735
1721 if kwargs.has_key('meteorsPerBin'):
1736 if kwargs.has_key('meteorsPerBin'):
1722 meteorThresh = kwargs['meteorsPerBin']
1737 meteorThresh = kwargs['meteorsPerBin']
1723 else:
1738 else:
1724 meteorThresh = 6
1739 meteorThresh = 6
1725
1740
1726 if kwargs.has_key('hmin'):
1741 if kwargs.has_key('hmin'):
1727 hmin = kwargs['hmin']
1742 hmin = kwargs['hmin']
1728 else: hmin = 70
1743 else: hmin = 70
1729 if kwargs.has_key('hmax'):
1744 if kwargs.has_key('hmax'):
1730 hmax = kwargs['hmax']
1745 hmax = kwargs['hmax']
1731 else: hmax = 110
1746 else: hmax = 110
1732
1747
1733 dataOut.outputInterval = nHours*3600
1748 dataOut.outputInterval = nHours*3600
1734
1749
1735 if self.__isConfig == False:
1750 if self.__isConfig == False:
1736 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1751 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1737 #Get Initial LTC time
1752 #Get Initial LTC time
1738 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1753 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1739 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1754 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1740
1755
1741 self.__isConfig = True
1756 self.__isConfig = True
1742
1757
1743 if self.__buffer == None:
1758 if self.__buffer == None:
1744 self.__buffer = dataOut.data_param
1759 self.__buffer = dataOut.data_param
1745 self.__firstdata = copy.copy(dataOut)
1760 self.__firstdata = copy.copy(dataOut)
1746
1761
1747 else:
1762 else:
1748 self.__buffer = numpy.hstack((self.__buffer, dataOut.data_param))
1763 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
1749
1764
1750 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1765 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1751
1766
1752 if self.__dataReady:
1767 if self.__dataReady:
1753 dataOut.utctimeInit = self.__initime
1768 dataOut.utctimeInit = self.__initime
1754
1769
1755 self.__initime += dataOut.outputInterval #to erase time offset
1770 self.__initime += dataOut.outputInterval #to erase time offset
1756
1771
1757 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
1772 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
1758 dataOut.flagNoData = False
1773 dataOut.flagNoData = False
1759 self.__buffer = None
1774 self.__buffer = None
1760
1775
1761 return
1776 return
1762
1777
1763 class EWDriftsEstimation(Operation):
1778 class EWDriftsEstimation(Operation):
1764
1779
1765
1780
1766 def __init__(self):
1781 def __init__(self):
1767 Operation.__init__(self)
1782 Operation.__init__(self)
1768
1783
1769 def __correctValues(self, heiRang, phi, velRadial, SNR):
1784 def __correctValues(self, heiRang, phi, velRadial, SNR):
1770 listPhi = phi.tolist()
1785 listPhi = phi.tolist()
1771 maxid = listPhi.index(max(listPhi))
1786 maxid = listPhi.index(max(listPhi))
1772 minid = listPhi.index(min(listPhi))
1787 minid = listPhi.index(min(listPhi))
1773
1788
1774 rango = range(len(phi))
1789 rango = range(len(phi))
1775 # rango = numpy.delete(rango,maxid)
1790 # rango = numpy.delete(rango,maxid)
1776
1791
1777 heiRang1 = heiRang*math.cos(phi[maxid])
1792 heiRang1 = heiRang*math.cos(phi[maxid])
1778 heiRangAux = heiRang*math.cos(phi[minid])
1793 heiRangAux = heiRang*math.cos(phi[minid])
1779 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1794 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1780 heiRang1 = numpy.delete(heiRang1,indOut)
1795 heiRang1 = numpy.delete(heiRang1,indOut)
1781
1796
1782 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1797 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1783 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1798 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1784
1799
1785 for i in rango:
1800 for i in rango:
1786 x = heiRang*math.cos(phi[i])
1801 x = heiRang*math.cos(phi[i])
1787 y1 = velRadial[i,:]
1802 y1 = velRadial[i,:]
1788 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1803 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1789
1804
1790 x1 = heiRang1
1805 x1 = heiRang1
1791 y11 = f1(x1)
1806 y11 = f1(x1)
1792
1807
1793 y2 = SNR[i,:]
1808 y2 = SNR[i,:]
1794 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1809 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1795 y21 = f2(x1)
1810 y21 = f2(x1)
1796
1811
1797 velRadial1[i,:] = y11
1812 velRadial1[i,:] = y11
1798 SNR1[i,:] = y21
1813 SNR1[i,:] = y21
1799
1814
1800 return heiRang1, velRadial1, SNR1
1815 return heiRang1, velRadial1, SNR1
1801
1816
1802 def run(self, dataOut, zenith, zenithCorrection):
1817 def run(self, dataOut, zenith, zenithCorrection):
1803 heiRang = dataOut.heightList
1818 heiRang = dataOut.heightList
1804 velRadial = dataOut.data_param[:,3,:]
1819 velRadial = dataOut.data_param[:,3,:]
1805 SNR = dataOut.data_SNR
1820 SNR = dataOut.data_SNR
1806
1821
1807 zenith = numpy.array(zenith)
1822 zenith = numpy.array(zenith)
1808 zenith -= zenithCorrection
1823 zenith -= zenithCorrection
1809 zenith *= numpy.pi/180
1824 zenith *= numpy.pi/180
1810
1825
1811 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
1826 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
1812
1827
1813 alp = zenith[0]
1828 alp = zenith[0]
1814 bet = zenith[1]
1829 bet = zenith[1]
1815
1830
1816 w_w = velRadial1[0,:]
1831 w_w = velRadial1[0,:]
1817 w_e = velRadial1[1,:]
1832 w_e = velRadial1[1,:]
1818
1833
1819 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
1834 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
1820 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
1835 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
1821
1836
1822 winds = numpy.vstack((u,w))
1837 winds = numpy.vstack((u,w))
1823
1838
1824 dataOut.heightList = heiRang1
1839 dataOut.heightList = heiRang1
1825 dataOut.data_output = winds
1840 dataOut.data_output = winds
1826 dataOut.data_SNR = SNR1
1841 dataOut.data_SNR = SNR1
1827
1842
1828 dataOut.utctimeInit = dataOut.utctime
1843 dataOut.utctimeInit = dataOut.utctime
1829 dataOut.outputInterval = dataOut.timeInterval
1844 dataOut.outputInterval = dataOut.timeInterval
1830 return
1845 return
1831
1846
1832 class PhaseCalibration(Operation):
1847 class PhaseCalibration(Operation):
1833
1848
1834 __buffer = None
1849 __buffer = None
1835
1850
1836 __initime = None
1851 __initime = None
1837
1852
1838 __dataReady = False
1853 __dataReady = False
1839
1854
1840 __isConfig = False
1855 __isConfig = False
1841
1856
1842 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
1857 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
1843
1858
1844 dataTime = currentTime + paramInterval
1859 dataTime = currentTime + paramInterval
1845 deltaTime = dataTime - initTime
1860 deltaTime = dataTime - initTime
1846
1861
1847 if deltaTime >= outputInterval or deltaTime < 0:
1862 if deltaTime >= outputInterval or deltaTime < 0:
1848 return True
1863 return True
1849
1864
1850 return False
1865 return False
1851
1866
1852 def __getGammas(self, pairs, k, d, phases):
1867 def __getGammas(self, pairs, k, d, phases):
1853 gammas = numpy.zeros(2)
1868 gammas = numpy.zeros(2)
1854
1869
1855 for i in range(len(pairs)):
1870 for i in range(len(pairs)):
1856
1871
1857 pairi = pairs[i]
1872 pairi = pairs[i]
1858
1873
1859 #Calculating gamma
1874 #Calculating gamma
1860 jdcos = phases[:,pairi[1]]/(k*d[pairi[1]])
1875 jdcos = phases[:,pairi[1]]/(k*d[pairi[1]])
1861 jgamma = numpy.angle(numpy.exp(1j*(k*d[pairi[0]]*jdcos - phases[:,pairi[0]])))
1876 jgamma = numpy.angle(numpy.exp(1j*(k*d[pairi[0]]*jdcos - phases[:,pairi[0]])))
1862
1877
1863 #Revised distribution
1878 #Revised distribution
1864 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
1879 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
1865
1880
1866 #Histogram
1881 #Histogram
1867 nBins = 64.0
1882 nBins = 64.0
1868 rmin = -0.5*numpy.pi
1883 rmin = -0.5*numpy.pi
1869 rmax = 0.5*numpy.pi
1884 rmax = 0.5*numpy.pi
1870 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
1885 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
1871
1886
1872 meteorsY = phaseHisto[0]
1887 meteorsY = phaseHisto[0]
1873 phasesX = phaseHisto[1][:-1]
1888 phasesX = phaseHisto[1][:-1]
1874 width = phasesX[1] - phasesX[0]
1889 width = phasesX[1] - phasesX[0]
1875 phasesX += width/2
1890 phasesX += width/2
1876
1891
1877 #Gaussian aproximation
1892 #Gaussian aproximation
1878 bpeak = meteorsY.argmax()
1893 bpeak = meteorsY.argmax()
1879 peak = meteorsY.max()
1894 peak = meteorsY.max()
1880 jmin = bpeak - 5
1895 jmin = bpeak - 5
1881 jmax = bpeak + 5 + 1
1896 jmax = bpeak + 5 + 1
1882
1897
1883 if jmin<0:
1898 if jmin<0:
1884 jmin = 0
1899 jmin = 0
1885 jmax = 6
1900 jmax = 6
1886 elif jmax > meteorsY.size:
1901 elif jmax > meteorsY.size:
1887 jmin = meteorsY.size - 6
1902 jmin = meteorsY.size - 6
1888 jmax = meteorsY.size
1903 jmax = meteorsY.size
1889
1904
1890 x0 = numpy.array([peak,bpeak,50])
1905 x0 = numpy.array([peak,bpeak,50])
1891 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
1906 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
1892
1907
1893 #Gammas
1908 #Gammas
1894 gammas[i] = coeff[0][1]
1909 gammas[i] = coeff[0][1]
1895
1910
1896 return gammas
1911 return gammas
1897
1912
1898 def __residualFunction(self, coeffs, y, t):
1913 def __residualFunction(self, coeffs, y, t):
1899
1914
1900 return y - self.__gauss_function(t, coeffs)
1915 return y - self.__gauss_function(t, coeffs)
1901
1916
1902 def __gauss_function(self, t, coeffs):
1917 def __gauss_function(self, t, coeffs):
1903
1918
1904 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
1919 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
1905
1920
1906 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
1921 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
1907 meteorOps = MeteorOperations()
1922 meteorOps = MeteorOperations()
1908 nchan = 4
1923 nchan = 4
1909 pairx = pairsList[0]
1924 pairx = pairsList[0]
1910 pairy = pairsList[1]
1925 pairy = pairsList[1]
1911 center_xangle = 0
1926 center_xangle = 0
1912 center_yangle = 0
1927 center_yangle = 0
1913 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
1928 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
1914 ntimes = len(range_angle)
1929 ntimes = len(range_angle)
1915
1930
1916 nstepsx = 20.0
1931 nstepsx = 20.0
1917 nstepsy = 20.0
1932 nstepsy = 20.0
1918
1933
1919 for iz in range(ntimes):
1934 for iz in range(ntimes):
1920 min_xangle = -range_angle[iz]/2 + center_xangle
1935 min_xangle = -range_angle[iz]/2 + center_xangle
1921 max_xangle = range_angle[iz]/2 + center_xangle
1936 max_xangle = range_angle[iz]/2 + center_xangle
1922 min_yangle = -range_angle[iz]/2 + center_yangle
1937 min_yangle = -range_angle[iz]/2 + center_yangle
1923 max_yangle = range_angle[iz]/2 + center_yangle
1938 max_yangle = range_angle[iz]/2 + center_yangle
1924
1939
1925 inc_x = (max_xangle-min_xangle)/nstepsx
1940 inc_x = (max_xangle-min_xangle)/nstepsx
1926 inc_y = (max_yangle-min_yangle)/nstepsy
1941 inc_y = (max_yangle-min_yangle)/nstepsy
1927
1942
1928 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
1943 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
1929 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
1944 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
1930 penalty = numpy.zeros((nstepsx,nstepsy))
1945 penalty = numpy.zeros((nstepsx,nstepsy))
1931 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
1946 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
1932 jph = numpy.zeros(nchan)
1947 jph = numpy.zeros(nchan)
1933
1948
1934 # Iterations looking for the offset
1949 # Iterations looking for the offset
1935 for iy in range(int(nstepsy)):
1950 for iy in range(int(nstepsy)):
1936 for ix in range(int(nstepsx)):
1951 for ix in range(int(nstepsx)):
1937 jph[pairy[1]] = alpha_y[iy]
1952 jph[pairy[1]] = alpha_y[iy]
1938 jph[pairy[0]] = -gammas[1] + alpha_y[iy]*d[pairy[0]]/d[pairy[1]]
1953 jph[pairy[0]] = -gammas[1] + alpha_y[iy]*d[pairy[0]]/d[pairy[1]]
1939
1954
1940 jph[pairx[1]] = alpha_x[ix]
1955 jph[pairx[1]] = alpha_x[ix]
1941 jph[pairx[0]] = -gammas[0] + alpha_x[ix]*d[pairx[0]]/d[pairx[1]]
1956 jph[pairx[0]] = -gammas[0] + alpha_x[ix]*d[pairx[0]]/d[pairx[1]]
1942
1957
1943 jph_array[:,ix,iy] = jph
1958 jph_array[:,ix,iy] = jph
1944
1959
1945 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, jph)
1960 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, jph)
1946 error = meteorsArray1[:,-1]
1961 error = meteorsArray1[:,-1]
1947 ind1 = numpy.where(error==0)[0]
1962 ind1 = numpy.where(error==0)[0]
1948 penalty[ix,iy] = ind1.size
1963 penalty[ix,iy] = ind1.size
1949
1964
1950 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
1965 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
1951 phOffset = jph_array[:,i,j]
1966 phOffset = jph_array[:,i,j]
1952
1967
1953 center_xangle = phOffset[pairx[1]]
1968 center_xangle = phOffset[pairx[1]]
1954 center_yangle = phOffset[pairy[1]]
1969 center_yangle = phOffset[pairy[1]]
1955
1970
1956 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
1971 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
1957 phOffset = phOffset*180/numpy.pi
1972 phOffset = phOffset*180/numpy.pi
1958 return phOffset
1973 return phOffset
1959
1974
1960
1975
1961 def run(self, dataOut, pairs, distances, hmin, hmax, nHours = None):
1976 def run(self, dataOut, pairs, distances, hmin, hmax, nHours = None):
1962
1977
1963 dataOut.flagNoData = True
1978 dataOut.flagNoData = True
1964 self.__dataReady = False
1979 self.__dataReady = False
1965
1980
1966 if nHours == None:
1981 if nHours == None:
1967 nHours = 1
1982 nHours = 1
1968
1983
1969 dataOut.outputInterval = nHours*3600
1984 dataOut.outputInterval = nHours*3600
1970
1985
1971 if self.__isConfig == False:
1986 if self.__isConfig == False:
1972 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1987 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1973 #Get Initial LTC time
1988 #Get Initial LTC time
1974 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1989 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1975 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1990 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1976
1991
1977 self.__isConfig = True
1992 self.__isConfig = True
1978
1993
1979 if self.__buffer == None:
1994 if self.__buffer == None:
1980 self.__buffer = dataOut.data_param.copy()
1995 self.__buffer = dataOut.data_param.copy()
1981
1996
1982 else:
1997 else:
1983 self.__buffer = numpy.hstack((self.__buffer, dataOut.data_param))
1998 self.__buffer = numpy.hstack((self.__buffer, dataOut.data_param))
1984
1999
1985 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2000 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1986
2001
1987 if self.__dataReady:
2002 if self.__dataReady:
1988 dataOut.utctimeInit = self.__initime
2003 dataOut.utctimeInit = self.__initime
1989 self.__initime += dataOut.outputInterval #to erase time offset
2004 self.__initime += dataOut.outputInterval #to erase time offset
1990
2005
1991 freq = dataOut.frequency
2006 freq = dataOut.frequency
1992 c = dataOut.C #m/s
2007 c = dataOut.C #m/s
1993 lamb = c/freq
2008 lamb = c/freq
1994 k = 2*numpy.pi/lamb
2009 k = 2*numpy.pi/lamb
1995 azimuth = 0
2010 azimuth = 0
1996 h = (hmin, hmax)
2011 h = (hmin, hmax)
1997 pairsList = ((0,3),(1,2))
2012 pairsList = ((0,3),(1,2))
1998
2013
1999 meteorsArray = self.__buffer[0,:,:]
2014 meteorsArray = self.__buffer
2000 error = meteorsArray[:,-1]
2015 error = meteorsArray[:,-1]
2001 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
2016 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
2002 ind1 = numpy.where(boolError)[0]
2017 ind1 = numpy.where(boolError)[0]
2003 meteorsArray = meteorsArray[ind1,:]
2018 meteorsArray = meteorsArray[ind1,:]
2004 meteorsArray[:,-1] = 0
2019 meteorsArray[:,-1] = 0
2005 phases = meteorsArray[:,9:13]
2020 phases = meteorsArray[:,8:12]
2006
2021
2007 #Calculate Gammas
2022 #Calculate Gammas
2008 gammas = self.__getGammas(pairs, k, distances, phases)
2023 gammas = self.__getGammas(pairs, k, distances, phases)
2009 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
2024 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
2010 #Calculate Phases
2025 #Calculate Phases
2011 phasesOff = self.__getPhases(azimuth, h, pairsList, distances, gammas, meteorsArray)
2026 phasesOff = self.__getPhases(azimuth, h, pairsList, distances, gammas, meteorsArray)
2012 phasesOff = phasesOff.reshape((1,phasesOff.size))
2027 phasesOff = phasesOff.reshape((1,phasesOff.size))
2013 dataOut.data_output = -phasesOff
2028 dataOut.data_output = -phasesOff
2014 dataOut.flagNoData = False
2029 dataOut.flagNoData = False
2015 self.__buffer = None
2030 self.__buffer = None
2016
2031
2017
2032
2018 return
2033 return
2019
2034
2020 class MeteorOperations():
2035 class MeteorOperations():
2021
2036
2022 def __init__(self):
2037 def __init__(self):
2023
2038
2024 return
2039 return
2025
2040
2026 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, jph):
2041 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, jph):
2027
2042
2028 arrayParameters = arrayParameters0.copy()
2043 arrayParameters = arrayParameters0.copy()
2029 hmin = h[0]
2044 hmin = h[0]
2030 hmax = h[1]
2045 hmax = h[1]
2031
2046
2032 #Calculate AOA (Error N 3, 4)
2047 #Calculate AOA (Error N 3, 4)
2033 #JONES ET AL. 1998
2048 #JONES ET AL. 1998
2034 AOAthresh = numpy.pi/8
2049 AOAthresh = numpy.pi/8
2035 error = arrayParameters[:,-1]
2050 error = arrayParameters[:,-1]
2036 phases = -arrayParameters[:,9:13] + jph
2051 phases = -arrayParameters[:,8:12] + jph
2037 arrayParameters[:,4:7], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, error, AOAthresh, azimuth)
2052 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, error, AOAthresh, azimuth)
2038
2053
2039 #Calculate Heights (Error N 13 and 14)
2054 #Calculate Heights (Error N 13 and 14)
2040 error = arrayParameters[:,-1]
2055 error = arrayParameters[:,-1]
2041 Ranges = arrayParameters[:,2]
2056 Ranges = arrayParameters[:,1]
2042 zenith = arrayParameters[:,5]
2057 zenith = arrayParameters[:,4]
2043 arrayParameters[:,3], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
2058 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
2044
2059
2045 #----------------------- Get Final data ------------------------------------
2060 #----------------------- Get Final data ------------------------------------
2046 # error = arrayParameters[:,-1]
2061 # error = arrayParameters[:,-1]
2047 # ind1 = numpy.where(error==0)[0]
2062 # ind1 = numpy.where(error==0)[0]
2048 # arrayParameters = arrayParameters[ind1,:]
2063 # arrayParameters = arrayParameters[ind1,:]
2049
2064
2050 return arrayParameters
2065 return arrayParameters
2051
2066
2052 def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
2067 def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
2053
2068
2054 arrayAOA = numpy.zeros((phases.shape[0],3))
2069 arrayAOA = numpy.zeros((phases.shape[0],3))
2055 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
2070 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
2056
2071
2057 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
2072 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
2058 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
2073 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
2059 arrayAOA[:,2] = cosDirError
2074 arrayAOA[:,2] = cosDirError
2060
2075
2061 azimuthAngle = arrayAOA[:,0]
2076 azimuthAngle = arrayAOA[:,0]
2062 zenithAngle = arrayAOA[:,1]
2077 zenithAngle = arrayAOA[:,1]
2063
2078
2064 #Setting Error
2079 #Setting Error
2065 #Number 3: AOA not fesible
2080 #Number 3: AOA not fesible
2066 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
2081 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
2067 error[indInvalid] = 3
2082 error[indInvalid] = 3
2068 #Number 4: Large difference in AOAs obtained from different antenna baselines
2083 #Number 4: Large difference in AOAs obtained from different antenna baselines
2069 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
2084 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
2070 error[indInvalid] = 4
2085 error[indInvalid] = 4
2071 return arrayAOA, error
2086 return arrayAOA, error
2072
2087
2073 def __getDirectionCosines(self, arrayPhase, pairsList):
2088 def __getDirectionCosines(self, arrayPhase, pairsList):
2074
2089
2075 #Initializing some variables
2090 #Initializing some variables
2076 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
2091 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
2077 ang_aux = ang_aux.reshape(1,ang_aux.size)
2092 ang_aux = ang_aux.reshape(1,ang_aux.size)
2078
2093
2079 cosdir = numpy.zeros((arrayPhase.shape[0],2))
2094 cosdir = numpy.zeros((arrayPhase.shape[0],2))
2080 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
2095 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
2081
2096
2082
2097
2083 for i in range(2):
2098 for i in range(2):
2084 #First Estimation
2099 #First Estimation
2085 phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
2100 phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
2086 #Dealias
2101 #Dealias
2087 indcsi = numpy.where(phi0_aux > numpy.pi)
2102 indcsi = numpy.where(phi0_aux > numpy.pi)
2088 phi0_aux[indcsi] -= 2*numpy.pi
2103 phi0_aux[indcsi] -= 2*numpy.pi
2089 indcsi = numpy.where(phi0_aux < -numpy.pi)
2104 indcsi = numpy.where(phi0_aux < -numpy.pi)
2090 phi0_aux[indcsi] += 2*numpy.pi
2105 phi0_aux[indcsi] += 2*numpy.pi
2091 #Direction Cosine 0
2106 #Direction Cosine 0
2092 cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
2107 cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
2093
2108
2094 #Most-Accurate Second Estimation
2109 #Most-Accurate Second Estimation
2095 phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
2110 phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
2096 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
2111 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
2097 #Direction Cosine 1
2112 #Direction Cosine 1
2098 cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
2113 cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
2099
2114
2100 #Searching the correct Direction Cosine
2115 #Searching the correct Direction Cosine
2101 cosdir0_aux = cosdir0[:,i]
2116 cosdir0_aux = cosdir0[:,i]
2102 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
2117 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
2103 #Minimum Distance
2118 #Minimum Distance
2104 cosDiff = (cosdir1 - cosdir0_aux)**2
2119 cosDiff = (cosdir1 - cosdir0_aux)**2
2105 indcos = cosDiff.argmin(axis = 1)
2120 indcos = cosDiff.argmin(axis = 1)
2106 #Saving Value obtained
2121 #Saving Value obtained
2107 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
2122 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
2108
2123
2109 return cosdir0, cosdir
2124 return cosdir0, cosdir
2110
2125
2111 def __calculateAOA(self, cosdir, azimuth):
2126 def __calculateAOA(self, cosdir, azimuth):
2112 cosdirX = cosdir[:,0]
2127 cosdirX = cosdir[:,0]
2113 cosdirY = cosdir[:,1]
2128 cosdirY = cosdir[:,1]
2114
2129
2115 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
2130 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
2116 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
2131 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
2117 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
2132 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
2118
2133
2119 return angles
2134 return angles
2120
2135
2121 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
2136 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
2122
2137
2123 Ramb = 375 #Ramb = c/(2*PRF)
2138 Ramb = 375 #Ramb = c/(2*PRF)
2124 Re = 6371 #Earth Radius
2139 Re = 6371 #Earth Radius
2125 heights = numpy.zeros(Ranges.shape)
2140 heights = numpy.zeros(Ranges.shape)
2126
2141
2127 R_aux = numpy.array([0,1,2])*Ramb
2142 R_aux = numpy.array([0,1,2])*Ramb
2128 R_aux = R_aux.reshape(1,R_aux.size)
2143 R_aux = R_aux.reshape(1,R_aux.size)
2129
2144
2130 Ranges = Ranges.reshape(Ranges.size,1)
2145 Ranges = Ranges.reshape(Ranges.size,1)
2131
2146
2132 Ri = Ranges + R_aux
2147 Ri = Ranges + R_aux
2133 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
2148 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
2134
2149
2135 #Check if there is a height between 70 and 110 km
2150 #Check if there is a height between 70 and 110 km
2136 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
2151 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
2137 ind_h = numpy.where(h_bool == 1)[0]
2152 ind_h = numpy.where(h_bool == 1)[0]
2138
2153
2139 hCorr = hi[ind_h, :]
2154 hCorr = hi[ind_h, :]
2140 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
2155 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
2141
2156
2142 hCorr = hi[ind_hCorr]
2157 hCorr = hi[ind_hCorr]
2143 heights[ind_h] = hCorr
2158 heights[ind_h] = hCorr
2144
2159
2145 #Setting Error
2160 #Setting Error
2146 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
2161 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
2147 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
2162 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
2148
2163
2149 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
2164 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
2150 error[indInvalid2] = 14
2165 error[indInvalid2] = 14
2151 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
2166 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
2152 error[indInvalid1] = 13
2167 error[indInvalid1] = 13
2153
2168
2154 return heights, error No newline at end of file
2169 return heights, error
General Comments 0
You need to be logged in to leave comments. Login now