##// END OF EJS Templates
Fix BLTR spectra reader
Juan C. Espinoza -
r1211:2e26717528e3
parent child
Show More
@@ -1,1358 +1,1363
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
5 '''
5 '''
6
6
7 import copy
7 import copy
8 import numpy
8 import numpy
9 import datetime
9 import datetime
10 import json
10 import json
11
11
12 from schainpy.utils import log
12 from schainpy.utils import log
13 from .jroheaderIO import SystemHeader, RadarControllerHeader
13 from .jroheaderIO import SystemHeader, RadarControllerHeader
14
14
15
15
16 def getNumpyDtype(dataTypeCode):
16 def getNumpyDtype(dataTypeCode):
17
17
18 if dataTypeCode == 0:
18 if dataTypeCode == 0:
19 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
19 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
20 elif dataTypeCode == 1:
20 elif dataTypeCode == 1:
21 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
21 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
22 elif dataTypeCode == 2:
22 elif dataTypeCode == 2:
23 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
23 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
24 elif dataTypeCode == 3:
24 elif dataTypeCode == 3:
25 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
25 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
26 elif dataTypeCode == 4:
26 elif dataTypeCode == 4:
27 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
27 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
28 elif dataTypeCode == 5:
28 elif dataTypeCode == 5:
29 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
29 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
30 else:
30 else:
31 raise ValueError('dataTypeCode was not defined')
31 raise ValueError('dataTypeCode was not defined')
32
32
33 return numpyDtype
33 return numpyDtype
34
34
35
35
36 def getDataTypeCode(numpyDtype):
36 def getDataTypeCode(numpyDtype):
37
37
38 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
38 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
39 datatype = 0
39 datatype = 0
40 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
40 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
41 datatype = 1
41 datatype = 1
42 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
42 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
43 datatype = 2
43 datatype = 2
44 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
44 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
45 datatype = 3
45 datatype = 3
46 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
46 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
47 datatype = 4
47 datatype = 4
48 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
48 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
49 datatype = 5
49 datatype = 5
50 else:
50 else:
51 datatype = None
51 datatype = None
52
52
53 return datatype
53 return datatype
54
54
55
55
56 def hildebrand_sekhon(data, navg):
56 def hildebrand_sekhon(data, navg):
57 """
57 """
58 This method is for the objective determination of the noise level in Doppler spectra. This
58 This method is for the objective determination of the noise level in Doppler spectra. This
59 implementation technique is based on the fact that the standard deviation of the spectral
59 implementation technique is based on the fact that the standard deviation of the spectral
60 densities is equal to the mean spectral density for white Gaussian noise
60 densities is equal to the mean spectral density for white Gaussian noise
61
61
62 Inputs:
62 Inputs:
63 Data : heights
63 Data : heights
64 navg : numbers of averages
64 navg : numbers of averages
65
65
66 Return:
66 Return:
67 mean : noise's level
67 mean : noise's level
68 """
68 """
69
69
70 sortdata = numpy.sort(data, axis=None)
70 sortdata = numpy.sort(data, axis=None)
71 lenOfData = len(sortdata)
71 lenOfData = len(sortdata)
72 nums_min = lenOfData*0.2
72 nums_min = lenOfData*0.2
73
73
74 if nums_min <= 5:
74 if nums_min <= 5:
75
75
76 nums_min = 5
76 nums_min = 5
77
77
78 sump = 0.
78 sump = 0.
79 sumq = 0.
79 sumq = 0.
80
80
81 j = 0
81 j = 0
82 cont = 1
82 cont = 1
83
83
84 while((cont == 1)and(j < lenOfData)):
84 while((cont == 1)and(j < lenOfData)):
85
85
86 sump += sortdata[j]
86 sump += sortdata[j]
87 sumq += sortdata[j]**2
87 sumq += sortdata[j]**2
88
88
89 if j > nums_min:
89 if j > nums_min:
90 rtest = float(j)/(j-1) + 1.0/navg
90 rtest = float(j)/(j-1) + 1.0/navg
91 if ((sumq*j) > (rtest*sump**2)):
91 if ((sumq*j) > (rtest*sump**2)):
92 j = j - 1
92 j = j - 1
93 sump = sump - sortdata[j]
93 sump = sump - sortdata[j]
94 sumq = sumq - sortdata[j]**2
94 sumq = sumq - sortdata[j]**2
95 cont = 0
95 cont = 0
96
96
97 j += 1
97 j += 1
98
98
99 lnoise = sump / j
99 lnoise = sump / j
100
100
101 return lnoise
101 return lnoise
102
102
103
103
104 class Beam:
104 class Beam:
105
105
106 def __init__(self):
106 def __init__(self):
107 self.codeList = []
107 self.codeList = []
108 self.azimuthList = []
108 self.azimuthList = []
109 self.zenithList = []
109 self.zenithList = []
110
110
111
111
112 class GenericData(object):
112 class GenericData(object):
113
113
114 flagNoData = True
114 flagNoData = True
115
115
116 def copy(self, inputObj=None):
116 def copy(self, inputObj=None):
117
117
118 if inputObj == None:
118 if inputObj == None:
119 return copy.deepcopy(self)
119 return copy.deepcopy(self)
120
120
121 for key in list(inputObj.__dict__.keys()):
121 for key in list(inputObj.__dict__.keys()):
122
122
123 attribute = inputObj.__dict__[key]
123 attribute = inputObj.__dict__[key]
124
124
125 # If this attribute is a tuple or list
125 # If this attribute is a tuple or list
126 if type(inputObj.__dict__[key]) in (tuple, list):
126 if type(inputObj.__dict__[key]) in (tuple, list):
127 self.__dict__[key] = attribute[:]
127 self.__dict__[key] = attribute[:]
128 continue
128 continue
129
129
130 # If this attribute is another object or instance
130 # If this attribute is another object or instance
131 if hasattr(attribute, '__dict__'):
131 if hasattr(attribute, '__dict__'):
132 self.__dict__[key] = attribute.copy()
132 self.__dict__[key] = attribute.copy()
133 continue
133 continue
134
134
135 self.__dict__[key] = inputObj.__dict__[key]
135 self.__dict__[key] = inputObj.__dict__[key]
136
136
137 def deepcopy(self):
137 def deepcopy(self):
138
138
139 return copy.deepcopy(self)
139 return copy.deepcopy(self)
140
140
141 def isEmpty(self):
141 def isEmpty(self):
142
142
143 return self.flagNoData
143 return self.flagNoData
144
144
145
145
146 class JROData(GenericData):
146 class JROData(GenericData):
147
147
148 # m_BasicHeader = BasicHeader()
148 # m_BasicHeader = BasicHeader()
149 # m_ProcessingHeader = ProcessingHeader()
149 # m_ProcessingHeader = ProcessingHeader()
150
150
151 systemHeaderObj = SystemHeader()
151 systemHeaderObj = SystemHeader()
152 radarControllerHeaderObj = RadarControllerHeader()
152 radarControllerHeaderObj = RadarControllerHeader()
153 # data = None
153 # data = None
154 type = None
154 type = None
155 datatype = None # dtype but in string
155 datatype = None # dtype but in string
156 # dtype = None
156 # dtype = None
157 # nChannels = None
157 # nChannels = None
158 # nHeights = None
158 # nHeights = None
159 nProfiles = None
159 nProfiles = None
160 heightList = None
160 heightList = None
161 channelList = None
161 channelList = None
162 flagDiscontinuousBlock = False
162 flagDiscontinuousBlock = False
163 useLocalTime = False
163 useLocalTime = False
164 utctime = None
164 utctime = None
165 timeZone = None
165 timeZone = None
166 dstFlag = None
166 dstFlag = None
167 errorCount = None
167 errorCount = None
168 blocksize = None
168 blocksize = None
169 # nCode = None
169 # nCode = None
170 # nBaud = None
170 # nBaud = None
171 # code = None
171 # code = None
172 flagDecodeData = False # asumo q la data no esta decodificada
172 flagDecodeData = False # asumo q la data no esta decodificada
173 flagDeflipData = False # asumo q la data no esta sin flip
173 flagDeflipData = False # asumo q la data no esta sin flip
174 flagShiftFFT = False
174 flagShiftFFT = False
175 # ippSeconds = None
175 # ippSeconds = None
176 # timeInterval = None
176 # timeInterval = None
177 nCohInt = None
177 nCohInt = None
178 # noise = None
178 # noise = None
179 windowOfFilter = 1
179 windowOfFilter = 1
180 # Speed of ligth
180 # Speed of ligth
181 C = 3e8
181 C = 3e8
182 frequency = 49.92e6
182 frequency = 49.92e6
183 realtime = False
183 realtime = False
184 beacon_heiIndexList = None
184 beacon_heiIndexList = None
185 last_block = None
185 last_block = None
186 blocknow = None
186 blocknow = None
187 azimuth = None
187 azimuth = None
188 zenith = None
188 zenith = None
189 beam = Beam()
189 beam = Beam()
190 profileIndex = None
190 profileIndex = None
191 error = None
191 error = None
192 data = None
192 data = None
193 nmodes = None
193 nmodes = None
194
194
195 def __str__(self):
195 def __str__(self):
196
196
197 return '{} - {}'.format(self.type, self.getDatatime())
197 return '{} - {}'.format(self.type, self.getDatatime())
198
198
199 def getNoise(self):
199 def getNoise(self):
200
200
201 raise NotImplementedError
201 raise NotImplementedError
202
202
203 def getNChannels(self):
203 def getNChannels(self):
204
204
205 return len(self.channelList)
205 return len(self.channelList)
206
206
207 def getChannelIndexList(self):
207 def getChannelIndexList(self):
208
208
209 return list(range(self.nChannels))
209 return list(range(self.nChannels))
210
210
211 def getNHeights(self):
211 def getNHeights(self):
212
212
213 return len(self.heightList)
213 return len(self.heightList)
214
214
215 def getHeiRange(self, extrapoints=0):
215 def getHeiRange(self, extrapoints=0):
216
216
217 heis = self.heightList
217 heis = self.heightList
218 # deltah = self.heightList[1] - self.heightList[0]
218 # deltah = self.heightList[1] - self.heightList[0]
219 #
219 #
220 # heis.append(self.heightList[-1])
220 # heis.append(self.heightList[-1])
221
221
222 return heis
222 return heis
223
223
224 def getDeltaH(self):
224 def getDeltaH(self):
225
225
226 delta = self.heightList[1] - self.heightList[0]
226 delta = self.heightList[1] - self.heightList[0]
227
227
228 return delta
228 return delta
229
229
230 def getltctime(self):
230 def getltctime(self):
231
231
232 if self.useLocalTime:
232 if self.useLocalTime:
233 return self.utctime - self.timeZone * 60
233 return self.utctime - self.timeZone * 60
234
234
235 return self.utctime
235 return self.utctime
236
236
237 def getDatatime(self):
237 def getDatatime(self):
238
238
239 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
239 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
240 return datatimeValue
240 return datatimeValue
241
241
242 def getTimeRange(self):
242 def getTimeRange(self):
243
243
244 datatime = []
244 datatime = []
245
245
246 datatime.append(self.ltctime)
246 datatime.append(self.ltctime)
247 datatime.append(self.ltctime + self.timeInterval + 1)
247 datatime.append(self.ltctime + self.timeInterval + 1)
248
248
249 datatime = numpy.array(datatime)
249 datatime = numpy.array(datatime)
250
250
251 return datatime
251 return datatime
252
252
253 def getFmaxTimeResponse(self):
253 def getFmaxTimeResponse(self):
254
254
255 period = (10**-6) * self.getDeltaH() / (0.15)
255 period = (10**-6) * self.getDeltaH() / (0.15)
256
256
257 PRF = 1. / (period * self.nCohInt)
257 PRF = 1. / (period * self.nCohInt)
258
258
259 fmax = PRF
259 fmax = PRF
260
260
261 return fmax
261 return fmax
262
262
263 def getFmax(self):
263 def getFmax(self):
264 PRF = 1. / (self.ippSeconds * self.nCohInt)
264 PRF = 1. / (self.ippSeconds * self.nCohInt)
265
265
266 fmax = PRF
266 fmax = PRF
267 return fmax
267 return fmax
268
268
269 def getVmax(self):
269 def getVmax(self):
270
270
271 _lambda = self.C / self.frequency
271 _lambda = self.C / self.frequency
272
272
273 vmax = self.getFmax() * _lambda / 2
273 vmax = self.getFmax() * _lambda / 2
274
274
275 return vmax
275 return vmax
276
276
277 def get_ippSeconds(self):
277 def get_ippSeconds(self):
278 '''
278 '''
279 '''
279 '''
280 return self.radarControllerHeaderObj.ippSeconds
280 return self.radarControllerHeaderObj.ippSeconds
281
281
282 def set_ippSeconds(self, ippSeconds):
282 def set_ippSeconds(self, ippSeconds):
283 '''
283 '''
284 '''
284 '''
285
285
286 self.radarControllerHeaderObj.ippSeconds = ippSeconds
286 self.radarControllerHeaderObj.ippSeconds = ippSeconds
287
287
288 return
288 return
289
289
290 def get_dtype(self):
290 def get_dtype(self):
291 '''
291 '''
292 '''
292 '''
293 return getNumpyDtype(self.datatype)
293 return getNumpyDtype(self.datatype)
294
294
295 def set_dtype(self, numpyDtype):
295 def set_dtype(self, numpyDtype):
296 '''
296 '''
297 '''
297 '''
298
298
299 self.datatype = getDataTypeCode(numpyDtype)
299 self.datatype = getDataTypeCode(numpyDtype)
300
300
301 def get_code(self):
301 def get_code(self):
302 '''
302 '''
303 '''
303 '''
304 return self.radarControllerHeaderObj.code
304 return self.radarControllerHeaderObj.code
305
305
306 def set_code(self, code):
306 def set_code(self, code):
307 '''
307 '''
308 '''
308 '''
309 self.radarControllerHeaderObj.code = code
309 self.radarControllerHeaderObj.code = code
310
310
311 return
311 return
312
312
313 def get_ncode(self):
313 def get_ncode(self):
314 '''
314 '''
315 '''
315 '''
316 return self.radarControllerHeaderObj.nCode
316 return self.radarControllerHeaderObj.nCode
317
317
318 def set_ncode(self, nCode):
318 def set_ncode(self, nCode):
319 '''
319 '''
320 '''
320 '''
321 self.radarControllerHeaderObj.nCode = nCode
321 self.radarControllerHeaderObj.nCode = nCode
322
322
323 return
323 return
324
324
325 def get_nbaud(self):
325 def get_nbaud(self):
326 '''
326 '''
327 '''
327 '''
328 return self.radarControllerHeaderObj.nBaud
328 return self.radarControllerHeaderObj.nBaud
329
329
330 def set_nbaud(self, nBaud):
330 def set_nbaud(self, nBaud):
331 '''
331 '''
332 '''
332 '''
333 self.radarControllerHeaderObj.nBaud = nBaud
333 self.radarControllerHeaderObj.nBaud = nBaud
334
334
335 return
335 return
336
336
337 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
337 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
338 channelIndexList = property(
338 channelIndexList = property(
339 getChannelIndexList, "I'm the 'channelIndexList' property.")
339 getChannelIndexList, "I'm the 'channelIndexList' property.")
340 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
340 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
341 #noise = property(getNoise, "I'm the 'nHeights' property.")
341 #noise = property(getNoise, "I'm the 'nHeights' property.")
342 datatime = property(getDatatime, "I'm the 'datatime' property")
342 datatime = property(getDatatime, "I'm the 'datatime' property")
343 ltctime = property(getltctime, "I'm the 'ltctime' property")
343 ltctime = property(getltctime, "I'm the 'ltctime' property")
344 ippSeconds = property(get_ippSeconds, set_ippSeconds)
344 ippSeconds = property(get_ippSeconds, set_ippSeconds)
345 dtype = property(get_dtype, set_dtype)
345 dtype = property(get_dtype, set_dtype)
346 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
346 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
347 code = property(get_code, set_code)
347 code = property(get_code, set_code)
348 nCode = property(get_ncode, set_ncode)
348 nCode = property(get_ncode, set_ncode)
349 nBaud = property(get_nbaud, set_nbaud)
349 nBaud = property(get_nbaud, set_nbaud)
350
350
351
351
352 class Voltage(JROData):
352 class Voltage(JROData):
353
353
354 # data es un numpy array de 2 dmensiones (canales, alturas)
354 # data es un numpy array de 2 dmensiones (canales, alturas)
355 data = None
355 data = None
356
356
357 def __init__(self):
357 def __init__(self):
358 '''
358 '''
359 Constructor
359 Constructor
360 '''
360 '''
361
361
362 self.useLocalTime = True
362 self.useLocalTime = True
363 self.radarControllerHeaderObj = RadarControllerHeader()
363 self.radarControllerHeaderObj = RadarControllerHeader()
364 self.systemHeaderObj = SystemHeader()
364 self.systemHeaderObj = SystemHeader()
365 self.type = "Voltage"
365 self.type = "Voltage"
366 self.data = None
366 self.data = None
367 # self.dtype = None
367 # self.dtype = None
368 # self.nChannels = 0
368 # self.nChannels = 0
369 # self.nHeights = 0
369 # self.nHeights = 0
370 self.nProfiles = None
370 self.nProfiles = None
371 self.heightList = None
371 self.heightList = None
372 self.channelList = None
372 self.channelList = None
373 # self.channelIndexList = None
373 # self.channelIndexList = None
374 self.flagNoData = True
374 self.flagNoData = True
375 self.flagDiscontinuousBlock = False
375 self.flagDiscontinuousBlock = False
376 self.utctime = None
376 self.utctime = None
377 self.timeZone = None
377 self.timeZone = None
378 self.dstFlag = None
378 self.dstFlag = None
379 self.errorCount = None
379 self.errorCount = None
380 self.nCohInt = None
380 self.nCohInt = None
381 self.blocksize = None
381 self.blocksize = None
382 self.flagDecodeData = False # asumo q la data no esta decodificada
382 self.flagDecodeData = False # asumo q la data no esta decodificada
383 self.flagDeflipData = False # asumo q la data no esta sin flip
383 self.flagDeflipData = False # asumo q la data no esta sin flip
384 self.flagShiftFFT = False
384 self.flagShiftFFT = False
385 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
385 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
386 self.profileIndex = 0
386 self.profileIndex = 0
387
387
388 def getNoisebyHildebrand(self, channel=None):
388 def getNoisebyHildebrand(self, channel=None):
389 """
389 """
390 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
390 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
391
391
392 Return:
392 Return:
393 noiselevel
393 noiselevel
394 """
394 """
395
395
396 if channel != None:
396 if channel != None:
397 data = self.data[channel]
397 data = self.data[channel]
398 nChannels = 1
398 nChannels = 1
399 else:
399 else:
400 data = self.data
400 data = self.data
401 nChannels = self.nChannels
401 nChannels = self.nChannels
402
402
403 noise = numpy.zeros(nChannels)
403 noise = numpy.zeros(nChannels)
404 power = data * numpy.conjugate(data)
404 power = data * numpy.conjugate(data)
405
405
406 for thisChannel in range(nChannels):
406 for thisChannel in range(nChannels):
407 if nChannels == 1:
407 if nChannels == 1:
408 daux = power[:].real
408 daux = power[:].real
409 else:
409 else:
410 daux = power[thisChannel, :].real
410 daux = power[thisChannel, :].real
411 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
411 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
412
412
413 return noise
413 return noise
414
414
415 def getNoise(self, type=1, channel=None):
415 def getNoise(self, type=1, channel=None):
416
416
417 if type == 1:
417 if type == 1:
418 noise = self.getNoisebyHildebrand(channel)
418 noise = self.getNoisebyHildebrand(channel)
419
419
420 return noise
420 return noise
421
421
422 def getPower(self, channel=None):
422 def getPower(self, channel=None):
423
423
424 if channel != None:
424 if channel != None:
425 data = self.data[channel]
425 data = self.data[channel]
426 else:
426 else:
427 data = self.data
427 data = self.data
428
428
429 power = data * numpy.conjugate(data)
429 power = data * numpy.conjugate(data)
430 powerdB = 10 * numpy.log10(power.real)
430 powerdB = 10 * numpy.log10(power.real)
431 powerdB = numpy.squeeze(powerdB)
431 powerdB = numpy.squeeze(powerdB)
432
432
433 return powerdB
433 return powerdB
434
434
435 def getTimeInterval(self):
435 def getTimeInterval(self):
436
436
437 timeInterval = self.ippSeconds * self.nCohInt
437 timeInterval = self.ippSeconds * self.nCohInt
438
438
439 return timeInterval
439 return timeInterval
440
440
441 noise = property(getNoise, "I'm the 'nHeights' property.")
441 noise = property(getNoise, "I'm the 'nHeights' property.")
442 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
442 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
443
443
444
444
445 class Spectra(JROData):
445 class Spectra(JROData):
446
446
447 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
447 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
448 data_spc = None
448 data_spc = None
449 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
449 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
450 data_cspc = None
450 data_cspc = None
451 # data dc es un numpy array de 2 dmensiones (canales, alturas)
451 # data dc es un numpy array de 2 dmensiones (canales, alturas)
452 data_dc = None
452 data_dc = None
453 # data power
453 # data power
454 data_pwr = None
454 data_pwr = None
455 nFFTPoints = None
455 nFFTPoints = None
456 # nPairs = None
456 # nPairs = None
457 pairsList = None
457 pairsList = None
458 nIncohInt = None
458 nIncohInt = None
459 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
459 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
460 nCohInt = None # se requiere para determinar el valor de timeInterval
460 nCohInt = None # se requiere para determinar el valor de timeInterval
461 ippFactor = None
461 ippFactor = None
462 profileIndex = 0
462 profileIndex = 0
463 plotting = "spectra"
463 plotting = "spectra"
464
464
465 def __init__(self):
465 def __init__(self):
466 '''
466 '''
467 Constructor
467 Constructor
468 '''
468 '''
469
469
470 self.useLocalTime = True
470 self.useLocalTime = True
471 self.radarControllerHeaderObj = RadarControllerHeader()
471 self.radarControllerHeaderObj = RadarControllerHeader()
472 self.systemHeaderObj = SystemHeader()
472 self.systemHeaderObj = SystemHeader()
473 self.type = "Spectra"
473 self.type = "Spectra"
474 # self.data = None
474 # self.data = None
475 # self.dtype = None
475 # self.dtype = None
476 # self.nChannels = 0
476 # self.nChannels = 0
477 # self.nHeights = 0
477 # self.nHeights = 0
478 self.nProfiles = None
478 self.nProfiles = None
479 self.heightList = None
479 self.heightList = None
480 self.channelList = None
480 self.channelList = None
481 # self.channelIndexList = None
481 # self.channelIndexList = None
482 self.pairsList = None
482 self.pairsList = None
483 self.flagNoData = True
483 self.flagNoData = True
484 self.flagDiscontinuousBlock = False
484 self.flagDiscontinuousBlock = False
485 self.utctime = None
485 self.utctime = None
486 self.nCohInt = None
486 self.nCohInt = None
487 self.nIncohInt = None
487 self.nIncohInt = None
488 self.blocksize = None
488 self.blocksize = None
489 self.nFFTPoints = None
489 self.nFFTPoints = None
490 self.wavelength = None
490 self.wavelength = None
491 self.flagDecodeData = False # asumo q la data no esta decodificada
491 self.flagDecodeData = False # asumo q la data no esta decodificada
492 self.flagDeflipData = False # asumo q la data no esta sin flip
492 self.flagDeflipData = False # asumo q la data no esta sin flip
493 self.flagShiftFFT = False
493 self.flagShiftFFT = False
494 self.ippFactor = 1
494 self.ippFactor = 1
495 #self.noise = None
495 #self.noise = None
496 self.beacon_heiIndexList = []
496 self.beacon_heiIndexList = []
497 self.noise_estimation = None
497 self.noise_estimation = None
498
498
499 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
499 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
500 """
500 """
501 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
501 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
502
502
503 Return:
503 Return:
504 noiselevel
504 noiselevel
505 """
505 """
506
506
507 noise = numpy.zeros(self.nChannels)
507 noise = numpy.zeros(self.nChannels)
508
508
509 for channel in range(self.nChannels):
509 for channel in range(self.nChannels):
510 daux = self.data_spc[channel,
510 daux = self.data_spc[channel,
511 xmin_index:xmax_index, ymin_index:ymax_index]
511 xmin_index:xmax_index, ymin_index:ymax_index]
512 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
512 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
513
513
514 return noise
514 return noise
515
515
516 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
516 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
517
517
518 if self.noise_estimation is not None:
518 if self.noise_estimation is not None:
519 # this was estimated by getNoise Operation defined in jroproc_spectra.py
519 # this was estimated by getNoise Operation defined in jroproc_spectra.py
520 return self.noise_estimation
520 return self.noise_estimation
521 else:
521 else:
522 noise = self.getNoisebyHildebrand(
522 noise = self.getNoisebyHildebrand(
523 xmin_index, xmax_index, ymin_index, ymax_index)
523 xmin_index, xmax_index, ymin_index, ymax_index)
524 return noise
524 return noise
525
525
526 def getFreqRangeTimeResponse(self, extrapoints=0):
526 def getFreqRangeTimeResponse(self, extrapoints=0):
527
527
528 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
528 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
529 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
529 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
530
530
531 return freqrange
531 return freqrange
532
532
533 def getAcfRange(self, extrapoints=0):
533 def getAcfRange(self, extrapoints=0):
534
534
535 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
535 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
536 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
536 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
537
537
538 return freqrange
538 return freqrange
539
539
540 def getFreqRange(self, extrapoints=0):
540 def getFreqRange(self, extrapoints=0):
541
541
542 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
542 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
543 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
543 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
544
544
545 return freqrange
545 return freqrange
546
546
547 def getVelRange(self, extrapoints=0):
547 def getVelRange(self, extrapoints=0):
548
548
549 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
549 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
550 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
550 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
551
551
552 if self.nmodes:
552 if self.nmodes:
553 return velrange/self.nmodes
553 return velrange/self.nmodes
554 else:
554 else:
555 return velrange
555 return velrange
556
556
557 def getNPairs(self):
557 def getNPairs(self):
558
558
559 return len(self.pairsList)
559 return len(self.pairsList)
560
560
561 def getPairsIndexList(self):
561 def getPairsIndexList(self):
562
562
563 return list(range(self.nPairs))
563 return list(range(self.nPairs))
564
564
565 def getNormFactor(self):
565 def getNormFactor(self):
566
566
567 pwcode = 1
567 pwcode = 1
568
568
569 if self.flagDecodeData:
569 if self.flagDecodeData:
570 pwcode = numpy.sum(self.code[0]**2)
570 pwcode = numpy.sum(self.code[0]**2)
571 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
571 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
572 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
572 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
573
573
574 return normFactor
574 return normFactor
575
575
576 def getFlagCspc(self):
576 def getFlagCspc(self):
577
577
578 if self.data_cspc is None:
578 if self.data_cspc is None:
579 return True
579 return True
580
580
581 return False
581 return False
582
582
583 def getFlagDc(self):
583 def getFlagDc(self):
584
584
585 if self.data_dc is None:
585 if self.data_dc is None:
586 return True
586 return True
587
587
588 return False
588 return False
589
589
590 def getTimeInterval(self):
590 def getTimeInterval(self):
591
591
592 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
592 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
593
593 if self.nmodes:
594 return timeInterval
594 return self.nmodes*timeInterval
595 else:
596 return timeInterval
595
597
596 def getPower(self):
598 def getPower(self):
597
599
598 factor = self.normFactor
600 factor = self.normFactor
599 z = self.data_spc / factor
601 z = self.data_spc / factor
600 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
602 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
601 avg = numpy.average(z, axis=1)
603 avg = numpy.average(z, axis=1)
602
604
603 return 10 * numpy.log10(avg)
605 return 10 * numpy.log10(avg)
604
606
605 def getCoherence(self, pairsList=None, phase=False):
607 def getCoherence(self, pairsList=None, phase=False):
606
608
607 z = []
609 z = []
608 if pairsList is None:
610 if pairsList is None:
609 pairsIndexList = self.pairsIndexList
611 pairsIndexList = self.pairsIndexList
610 else:
612 else:
611 pairsIndexList = []
613 pairsIndexList = []
612 for pair in pairsList:
614 for pair in pairsList:
613 if pair not in self.pairsList:
615 if pair not in self.pairsList:
614 raise ValueError("Pair %s is not in dataOut.pairsList" % (
616 raise ValueError("Pair %s is not in dataOut.pairsList" % (
615 pair))
617 pair))
616 pairsIndexList.append(self.pairsList.index(pair))
618 pairsIndexList.append(self.pairsList.index(pair))
617 for i in range(len(pairsIndexList)):
619 for i in range(len(pairsIndexList)):
618 pair = self.pairsList[pairsIndexList[i]]
620 pair = self.pairsList[pairsIndexList[i]]
619 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
621 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
620 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
622 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
621 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
623 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
622 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
624 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
623 if phase:
625 if phase:
624 data = numpy.arctan2(avgcoherenceComplex.imag,
626 data = numpy.arctan2(avgcoherenceComplex.imag,
625 avgcoherenceComplex.real) * 180 / numpy.pi
627 avgcoherenceComplex.real) * 180 / numpy.pi
626 else:
628 else:
627 data = numpy.abs(avgcoherenceComplex)
629 data = numpy.abs(avgcoherenceComplex)
628
630
629 z.append(data)
631 z.append(data)
630
632
631 return numpy.array(z)
633 return numpy.array(z)
632
634
633 def setValue(self, value):
635 def setValue(self, value):
634
636
635 print("This property should not be initialized")
637 print("This property should not be initialized")
636
638
637 return
639 return
638
640
639 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
641 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
640 pairsIndexList = property(
642 pairsIndexList = property(
641 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
643 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
642 normFactor = property(getNormFactor, setValue,
644 normFactor = property(getNormFactor, setValue,
643 "I'm the 'getNormFactor' property.")
645 "I'm the 'getNormFactor' property.")
644 flag_cspc = property(getFlagCspc, setValue)
646 flag_cspc = property(getFlagCspc, setValue)
645 flag_dc = property(getFlagDc, setValue)
647 flag_dc = property(getFlagDc, setValue)
646 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
648 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
647 timeInterval = property(getTimeInterval, setValue,
649 timeInterval = property(getTimeInterval, setValue,
648 "I'm the 'timeInterval' property")
650 "I'm the 'timeInterval' property")
649
651
650
652
651 class SpectraHeis(Spectra):
653 class SpectraHeis(Spectra):
652
654
653 data_spc = None
655 data_spc = None
654 data_cspc = None
656 data_cspc = None
655 data_dc = None
657 data_dc = None
656 nFFTPoints = None
658 nFFTPoints = None
657 # nPairs = None
659 # nPairs = None
658 pairsList = None
660 pairsList = None
659 nCohInt = None
661 nCohInt = None
660 nIncohInt = None
662 nIncohInt = None
661
663
662 def __init__(self):
664 def __init__(self):
663
665
664 self.radarControllerHeaderObj = RadarControllerHeader()
666 self.radarControllerHeaderObj = RadarControllerHeader()
665
667
666 self.systemHeaderObj = SystemHeader()
668 self.systemHeaderObj = SystemHeader()
667
669
668 self.type = "SpectraHeis"
670 self.type = "SpectraHeis"
669
671
670 # self.dtype = None
672 # self.dtype = None
671
673
672 # self.nChannels = 0
674 # self.nChannels = 0
673
675
674 # self.nHeights = 0
676 # self.nHeights = 0
675
677
676 self.nProfiles = None
678 self.nProfiles = None
677
679
678 self.heightList = None
680 self.heightList = None
679
681
680 self.channelList = None
682 self.channelList = None
681
683
682 # self.channelIndexList = None
684 # self.channelIndexList = None
683
685
684 self.flagNoData = True
686 self.flagNoData = True
685
687
686 self.flagDiscontinuousBlock = False
688 self.flagDiscontinuousBlock = False
687
689
688 # self.nPairs = 0
690 # self.nPairs = 0
689
691
690 self.utctime = None
692 self.utctime = None
691
693
692 self.blocksize = None
694 self.blocksize = None
693
695
694 self.profileIndex = 0
696 self.profileIndex = 0
695
697
696 self.nCohInt = 1
698 self.nCohInt = 1
697
699
698 self.nIncohInt = 1
700 self.nIncohInt = 1
699
701
700 def getNormFactor(self):
702 def getNormFactor(self):
701 pwcode = 1
703 pwcode = 1
702 if self.flagDecodeData:
704 if self.flagDecodeData:
703 pwcode = numpy.sum(self.code[0]**2)
705 pwcode = numpy.sum(self.code[0]**2)
704
706
705 normFactor = self.nIncohInt * self.nCohInt * pwcode
707 normFactor = self.nIncohInt * self.nCohInt * pwcode
706
708
707 return normFactor
709 return normFactor
708
710
709 def getTimeInterval(self):
711 def getTimeInterval(self):
710
712
711 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
713 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
712
714
713 return timeInterval
715 return timeInterval
714
716
715 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
717 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
716 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
718 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
717
719
718
720
719 class Fits(JROData):
721 class Fits(JROData):
720
722
721 heightList = None
723 heightList = None
722 channelList = None
724 channelList = None
723 flagNoData = True
725 flagNoData = True
724 flagDiscontinuousBlock = False
726 flagDiscontinuousBlock = False
725 useLocalTime = False
727 useLocalTime = False
726 utctime = None
728 utctime = None
727 timeZone = None
729 timeZone = None
728 # ippSeconds = None
730 # ippSeconds = None
729 # timeInterval = None
731 # timeInterval = None
730 nCohInt = None
732 nCohInt = None
731 nIncohInt = None
733 nIncohInt = None
732 noise = None
734 noise = None
733 windowOfFilter = 1
735 windowOfFilter = 1
734 # Speed of ligth
736 # Speed of ligth
735 C = 3e8
737 C = 3e8
736 frequency = 49.92e6
738 frequency = 49.92e6
737 realtime = False
739 realtime = False
738
740
739 def __init__(self):
741 def __init__(self):
740
742
741 self.type = "Fits"
743 self.type = "Fits"
742
744
743 self.nProfiles = None
745 self.nProfiles = None
744
746
745 self.heightList = None
747 self.heightList = None
746
748
747 self.channelList = None
749 self.channelList = None
748
750
749 # self.channelIndexList = None
751 # self.channelIndexList = None
750
752
751 self.flagNoData = True
753 self.flagNoData = True
752
754
753 self.utctime = None
755 self.utctime = None
754
756
755 self.nCohInt = 1
757 self.nCohInt = 1
756
758
757 self.nIncohInt = 1
759 self.nIncohInt = 1
758
760
759 self.useLocalTime = True
761 self.useLocalTime = True
760
762
761 self.profileIndex = 0
763 self.profileIndex = 0
762
764
763 # self.utctime = None
765 # self.utctime = None
764 # self.timeZone = None
766 # self.timeZone = None
765 # self.ltctime = None
767 # self.ltctime = None
766 # self.timeInterval = None
768 # self.timeInterval = None
767 # self.header = None
769 # self.header = None
768 # self.data_header = None
770 # self.data_header = None
769 # self.data = None
771 # self.data = None
770 # self.datatime = None
772 # self.datatime = None
771 # self.flagNoData = False
773 # self.flagNoData = False
772 # self.expName = ''
774 # self.expName = ''
773 # self.nChannels = None
775 # self.nChannels = None
774 # self.nSamples = None
776 # self.nSamples = None
775 # self.dataBlocksPerFile = None
777 # self.dataBlocksPerFile = None
776 # self.comments = ''
778 # self.comments = ''
777 #
779 #
778
780
779 def getltctime(self):
781 def getltctime(self):
780
782
781 if self.useLocalTime:
783 if self.useLocalTime:
782 return self.utctime - self.timeZone * 60
784 return self.utctime - self.timeZone * 60
783
785
784 return self.utctime
786 return self.utctime
785
787
786 def getDatatime(self):
788 def getDatatime(self):
787
789
788 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
790 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
789 return datatime
791 return datatime
790
792
791 def getTimeRange(self):
793 def getTimeRange(self):
792
794
793 datatime = []
795 datatime = []
794
796
795 datatime.append(self.ltctime)
797 datatime.append(self.ltctime)
796 datatime.append(self.ltctime + self.timeInterval)
798 datatime.append(self.ltctime + self.timeInterval)
797
799
798 datatime = numpy.array(datatime)
800 datatime = numpy.array(datatime)
799
801
800 return datatime
802 return datatime
801
803
802 def getHeiRange(self):
804 def getHeiRange(self):
803
805
804 heis = self.heightList
806 heis = self.heightList
805
807
806 return heis
808 return heis
807
809
808 def getNHeights(self):
810 def getNHeights(self):
809
811
810 return len(self.heightList)
812 return len(self.heightList)
811
813
812 def getNChannels(self):
814 def getNChannels(self):
813
815
814 return len(self.channelList)
816 return len(self.channelList)
815
817
816 def getChannelIndexList(self):
818 def getChannelIndexList(self):
817
819
818 return list(range(self.nChannels))
820 return list(range(self.nChannels))
819
821
820 def getNoise(self, type=1):
822 def getNoise(self, type=1):
821
823
822 #noise = numpy.zeros(self.nChannels)
824 #noise = numpy.zeros(self.nChannels)
823
825
824 if type == 1:
826 if type == 1:
825 noise = self.getNoisebyHildebrand()
827 noise = self.getNoisebyHildebrand()
826
828
827 if type == 2:
829 if type == 2:
828 noise = self.getNoisebySort()
830 noise = self.getNoisebySort()
829
831
830 if type == 3:
832 if type == 3:
831 noise = self.getNoisebyWindow()
833 noise = self.getNoisebyWindow()
832
834
833 return noise
835 return noise
834
836
835 def getTimeInterval(self):
837 def getTimeInterval(self):
836
838
837 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
839 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
838
840
839 return timeInterval
841 return timeInterval
840
842
841 def get_ippSeconds(self):
843 def get_ippSeconds(self):
842 '''
844 '''
843 '''
845 '''
844 return self.ipp_sec
846 return self.ipp_sec
845
847
846
848
847 datatime = property(getDatatime, "I'm the 'datatime' property")
849 datatime = property(getDatatime, "I'm the 'datatime' property")
848 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
850 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
849 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
851 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
850 channelIndexList = property(
852 channelIndexList = property(
851 getChannelIndexList, "I'm the 'channelIndexList' property.")
853 getChannelIndexList, "I'm the 'channelIndexList' property.")
852 noise = property(getNoise, "I'm the 'nHeights' property.")
854 noise = property(getNoise, "I'm the 'nHeights' property.")
853
855
854 ltctime = property(getltctime, "I'm the 'ltctime' property")
856 ltctime = property(getltctime, "I'm the 'ltctime' property")
855 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
857 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
856 ippSeconds = property(get_ippSeconds, '')
858 ippSeconds = property(get_ippSeconds, '')
857
859
858 class Correlation(JROData):
860 class Correlation(JROData):
859
861
860 noise = None
862 noise = None
861 SNR = None
863 SNR = None
862 #--------------------------------------------------
864 #--------------------------------------------------
863 mode = None
865 mode = None
864 split = False
866 split = False
865 data_cf = None
867 data_cf = None
866 lags = None
868 lags = None
867 lagRange = None
869 lagRange = None
868 pairsList = None
870 pairsList = None
869 normFactor = None
871 normFactor = None
870 #--------------------------------------------------
872 #--------------------------------------------------
871 # calculateVelocity = None
873 # calculateVelocity = None
872 nLags = None
874 nLags = None
873 nPairs = None
875 nPairs = None
874 nAvg = None
876 nAvg = None
875
877
876 def __init__(self):
878 def __init__(self):
877 '''
879 '''
878 Constructor
880 Constructor
879 '''
881 '''
880 self.radarControllerHeaderObj = RadarControllerHeader()
882 self.radarControllerHeaderObj = RadarControllerHeader()
881
883
882 self.systemHeaderObj = SystemHeader()
884 self.systemHeaderObj = SystemHeader()
883
885
884 self.type = "Correlation"
886 self.type = "Correlation"
885
887
886 self.data = None
888 self.data = None
887
889
888 self.dtype = None
890 self.dtype = None
889
891
890 self.nProfiles = None
892 self.nProfiles = None
891
893
892 self.heightList = None
894 self.heightList = None
893
895
894 self.channelList = None
896 self.channelList = None
895
897
896 self.flagNoData = True
898 self.flagNoData = True
897
899
898 self.flagDiscontinuousBlock = False
900 self.flagDiscontinuousBlock = False
899
901
900 self.utctime = None
902 self.utctime = None
901
903
902 self.timeZone = None
904 self.timeZone = None
903
905
904 self.dstFlag = None
906 self.dstFlag = None
905
907
906 self.errorCount = None
908 self.errorCount = None
907
909
908 self.blocksize = None
910 self.blocksize = None
909
911
910 self.flagDecodeData = False # asumo q la data no esta decodificada
912 self.flagDecodeData = False # asumo q la data no esta decodificada
911
913
912 self.flagDeflipData = False # asumo q la data no esta sin flip
914 self.flagDeflipData = False # asumo q la data no esta sin flip
913
915
914 self.pairsList = None
916 self.pairsList = None
915
917
916 self.nPoints = None
918 self.nPoints = None
917
919
918 def getPairsList(self):
920 def getPairsList(self):
919
921
920 return self.pairsList
922 return self.pairsList
921
923
922 def getNoise(self, mode=2):
924 def getNoise(self, mode=2):
923
925
924 indR = numpy.where(self.lagR == 0)[0][0]
926 indR = numpy.where(self.lagR == 0)[0][0]
925 indT = numpy.where(self.lagT == 0)[0][0]
927 indT = numpy.where(self.lagT == 0)[0][0]
926
928
927 jspectra0 = self.data_corr[:, :, indR, :]
929 jspectra0 = self.data_corr[:, :, indR, :]
928 jspectra = copy.copy(jspectra0)
930 jspectra = copy.copy(jspectra0)
929
931
930 num_chan = jspectra.shape[0]
932 num_chan = jspectra.shape[0]
931 num_hei = jspectra.shape[2]
933 num_hei = jspectra.shape[2]
932
934
933 freq_dc = jspectra.shape[1] / 2
935 freq_dc = jspectra.shape[1] / 2
934 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
936 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
935
937
936 if ind_vel[0] < 0:
938 if ind_vel[0] < 0:
937 ind_vel[list(range(0, 1))] = ind_vel[list(
939 ind_vel[list(range(0, 1))] = ind_vel[list(
938 range(0, 1))] + self.num_prof
940 range(0, 1))] + self.num_prof
939
941
940 if mode == 1:
942 if mode == 1:
941 jspectra[:, freq_dc, :] = (
943 jspectra[:, freq_dc, :] = (
942 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
944 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
943
945
944 if mode == 2:
946 if mode == 2:
945
947
946 vel = numpy.array([-2, -1, 1, 2])
948 vel = numpy.array([-2, -1, 1, 2])
947 xx = numpy.zeros([4, 4])
949 xx = numpy.zeros([4, 4])
948
950
949 for fil in range(4):
951 for fil in range(4):
950 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
952 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
951
953
952 xx_inv = numpy.linalg.inv(xx)
954 xx_inv = numpy.linalg.inv(xx)
953 xx_aux = xx_inv[0, :]
955 xx_aux = xx_inv[0, :]
954
956
955 for ich in range(num_chan):
957 for ich in range(num_chan):
956 yy = jspectra[ich, ind_vel, :]
958 yy = jspectra[ich, ind_vel, :]
957 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
959 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
958
960
959 junkid = jspectra[ich, freq_dc, :] <= 0
961 junkid = jspectra[ich, freq_dc, :] <= 0
960 cjunkid = sum(junkid)
962 cjunkid = sum(junkid)
961
963
962 if cjunkid.any():
964 if cjunkid.any():
963 jspectra[ich, freq_dc, junkid.nonzero()] = (
965 jspectra[ich, freq_dc, junkid.nonzero()] = (
964 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
966 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
965
967
966 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
968 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
967
969
968 return noise
970 return noise
969
971
970 def getTimeInterval(self):
972 def getTimeInterval(self):
971
973
972 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
974 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
973
975
974 return timeInterval
976 return timeInterval
975
977
976 def splitFunctions(self):
978 def splitFunctions(self):
977
979
978 pairsList = self.pairsList
980 pairsList = self.pairsList
979 ccf_pairs = []
981 ccf_pairs = []
980 acf_pairs = []
982 acf_pairs = []
981 ccf_ind = []
983 ccf_ind = []
982 acf_ind = []
984 acf_ind = []
983 for l in range(len(pairsList)):
985 for l in range(len(pairsList)):
984 chan0 = pairsList[l][0]
986 chan0 = pairsList[l][0]
985 chan1 = pairsList[l][1]
987 chan1 = pairsList[l][1]
986
988
987 # Obteniendo pares de Autocorrelacion
989 # Obteniendo pares de Autocorrelacion
988 if chan0 == chan1:
990 if chan0 == chan1:
989 acf_pairs.append(chan0)
991 acf_pairs.append(chan0)
990 acf_ind.append(l)
992 acf_ind.append(l)
991 else:
993 else:
992 ccf_pairs.append(pairsList[l])
994 ccf_pairs.append(pairsList[l])
993 ccf_ind.append(l)
995 ccf_ind.append(l)
994
996
995 data_acf = self.data_cf[acf_ind]
997 data_acf = self.data_cf[acf_ind]
996 data_ccf = self.data_cf[ccf_ind]
998 data_ccf = self.data_cf[ccf_ind]
997
999
998 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1000 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
999
1001
1000 def getNormFactor(self):
1002 def getNormFactor(self):
1001 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1003 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1002 acf_pairs = numpy.array(acf_pairs)
1004 acf_pairs = numpy.array(acf_pairs)
1003 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1005 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1004
1006
1005 for p in range(self.nPairs):
1007 for p in range(self.nPairs):
1006 pair = self.pairsList[p]
1008 pair = self.pairsList[p]
1007
1009
1008 ch0 = pair[0]
1010 ch0 = pair[0]
1009 ch1 = pair[1]
1011 ch1 = pair[1]
1010
1012
1011 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1013 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1012 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1014 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1013 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1015 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1014
1016
1015 return normFactor
1017 return normFactor
1016
1018
1017 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1019 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1018 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1020 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1019
1021
1020
1022
1021 class Parameters(Spectra):
1023 class Parameters(Spectra):
1022
1024
1023 experimentInfo = None # Information about the experiment
1025 experimentInfo = None # Information about the experiment
1024 # Information from previous data
1026 # Information from previous data
1025 inputUnit = None # Type of data to be processed
1027 inputUnit = None # Type of data to be processed
1026 operation = None # Type of operation to parametrize
1028 operation = None # Type of operation to parametrize
1027 # normFactor = None #Normalization Factor
1029 # normFactor = None #Normalization Factor
1028 groupList = None # List of Pairs, Groups, etc
1030 groupList = None # List of Pairs, Groups, etc
1029 # Parameters
1031 # Parameters
1030 data_param = None # Parameters obtained
1032 data_param = None # Parameters obtained
1031 data_pre = None # Data Pre Parametrization
1033 data_pre = None # Data Pre Parametrization
1032 data_SNR = None # Signal to Noise Ratio
1034 data_SNR = None # Signal to Noise Ratio
1033 # heightRange = None #Heights
1035 # heightRange = None #Heights
1034 abscissaList = None # Abscissa, can be velocities, lags or time
1036 abscissaList = None # Abscissa, can be velocities, lags or time
1035 # noise = None #Noise Potency
1037 # noise = None #Noise Potency
1036 utctimeInit = None # Initial UTC time
1038 utctimeInit = None # Initial UTC time
1037 paramInterval = None # Time interval to calculate Parameters in seconds
1039 paramInterval = None # Time interval to calculate Parameters in seconds
1038 useLocalTime = True
1040 useLocalTime = True
1039 # Fitting
1041 # Fitting
1040 data_error = None # Error of the estimation
1042 data_error = None # Error of the estimation
1041 constants = None
1043 constants = None
1042 library = None
1044 library = None
1043 # Output signal
1045 # Output signal
1044 outputInterval = None # Time interval to calculate output signal in seconds
1046 outputInterval = None # Time interval to calculate output signal in seconds
1045 data_output = None # Out signal
1047 data_output = None # Out signal
1046 nAvg = None
1048 nAvg = None
1047 noise_estimation = None
1049 noise_estimation = None
1048 GauSPC = None # Fit gaussian SPC
1050 GauSPC = None # Fit gaussian SPC
1049
1051
1050 def __init__(self):
1052 def __init__(self):
1051 '''
1053 '''
1052 Constructor
1054 Constructor
1053 '''
1055 '''
1054 self.radarControllerHeaderObj = RadarControllerHeader()
1056 self.radarControllerHeaderObj = RadarControllerHeader()
1055
1057
1056 self.systemHeaderObj = SystemHeader()
1058 self.systemHeaderObj = SystemHeader()
1057
1059
1058 self.type = "Parameters"
1060 self.type = "Parameters"
1059
1061
1060 def getTimeRange1(self, interval):
1062 def getTimeRange1(self, interval):
1061
1063
1062 datatime = []
1064 datatime = []
1063
1065
1064 if self.useLocalTime:
1066 if self.useLocalTime:
1065 time1 = self.utctimeInit - self.timeZone * 60
1067 time1 = self.utctimeInit - self.timeZone * 60
1066 else:
1068 else:
1067 time1 = self.utctimeInit
1069 time1 = self.utctimeInit
1068
1070
1069 datatime.append(time1)
1071 datatime.append(time1)
1070 datatime.append(time1 + interval)
1072 datatime.append(time1 + interval)
1071 datatime = numpy.array(datatime)
1073 datatime = numpy.array(datatime)
1072
1074
1073 return datatime
1075 return datatime
1074
1076
1075 def getTimeInterval(self):
1077 def getTimeInterval(self):
1076
1078
1077 if hasattr(self, 'timeInterval1'):
1079 if hasattr(self, 'timeInterval1'):
1078 return self.timeInterval1
1080 return self.timeInterval1
1079 else:
1081 else:
1080 return self.paramInterval
1082 return self.paramInterval
1081
1083
1082 def setValue(self, value):
1084 def setValue(self, value):
1083
1085
1084 print("This property should not be initialized")
1086 print("This property should not be initialized")
1085
1087
1086 return
1088 return
1087
1089
1088 def getNoise(self):
1090 def getNoise(self):
1089
1091
1090 return self.spc_noise
1092 return self.spc_noise
1091
1093
1092 timeInterval = property(getTimeInterval)
1094 timeInterval = property(getTimeInterval)
1093 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1095 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1094
1096
1095
1097
1096 class PlotterData(object):
1098 class PlotterData(object):
1097 '''
1099 '''
1098 Object to hold data to be plotted
1100 Object to hold data to be plotted
1099 '''
1101 '''
1100
1102
1101 MAXNUMX = 100
1103 MAXNUMX = 100
1102 MAXNUMY = 100
1104 MAXNUMY = 100
1103
1105
1104 def __init__(self, code, throttle_value, exp_code, buffering=True):
1106 def __init__(self, code, throttle_value, exp_code, buffering=True):
1105
1107
1106 self.throttle = throttle_value
1108 self.throttle = throttle_value
1107 self.exp_code = exp_code
1109 self.exp_code = exp_code
1108 self.buffering = buffering
1110 self.buffering = buffering
1109 self.ready = False
1111 self.ready = False
1110 self.localtime = False
1112 self.localtime = False
1111 self.data = {}
1113 self.data = {}
1112 self.meta = {}
1114 self.meta = {}
1113 self.__times = []
1115 self.__times = []
1114 self.__heights = []
1116 self.__heights = []
1115
1117
1116 if 'snr' in code:
1118 if 'snr' in code:
1117 self.plottypes = ['snr']
1119 self.plottypes = ['snr']
1118 elif code == 'spc':
1120 elif code == 'spc':
1119 self.plottypes = ['spc', 'noise', 'rti']
1121 self.plottypes = ['spc', 'noise', 'rti']
1120 elif code == 'rti':
1122 elif code == 'rti':
1121 self.plottypes = ['noise', 'rti']
1123 self.plottypes = ['noise', 'rti']
1122 else:
1124 else:
1123 self.plottypes = [code]
1125 self.plottypes = [code]
1124
1126
1125 for plot in self.plottypes:
1127 for plot in self.plottypes:
1126 self.data[plot] = {}
1128 self.data[plot] = {}
1127
1129
1128 def __str__(self):
1130 def __str__(self):
1129 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1131 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1130 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
1132 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
1131
1133
1132 def __len__(self):
1134 def __len__(self):
1133 return len(self.__times)
1135 return len(self.__times)
1134
1136
1135 def __getitem__(self, key):
1137 def __getitem__(self, key):
1136
1138
1137 if key not in self.data:
1139 if key not in self.data:
1138 raise KeyError(log.error('Missing key: {}'.format(key)))
1140 raise KeyError(log.error('Missing key: {}'.format(key)))
1139 if 'spc' in key or not self.buffering:
1141 if 'spc' in key or not self.buffering:
1140 ret = self.data[key]
1142 ret = self.data[key]
1141 elif 'scope' in key:
1143 elif 'scope' in key:
1142 ret = numpy.array(self.data[key][float(self.tm)])
1144 ret = numpy.array(self.data[key][float(self.tm)])
1143 else:
1145 else:
1144 ret = numpy.array([self.data[key][x] for x in self.times])
1146 ret = numpy.array([self.data[key][x] for x in self.times])
1145 if ret.ndim > 1:
1147 if ret.ndim > 1:
1146 ret = numpy.swapaxes(ret, 0, 1)
1148 ret = numpy.swapaxes(ret, 0, 1)
1147 return ret
1149 return ret
1148
1150
1149 def __contains__(self, key):
1151 def __contains__(self, key):
1150 return key in self.data
1152 return key in self.data
1151
1153
1152 def setup(self):
1154 def setup(self):
1153 '''
1155 '''
1154 Configure object
1156 Configure object
1155 '''
1157 '''
1156
1158
1157 self.type = ''
1159 self.type = ''
1158 self.ready = False
1160 self.ready = False
1159 self.data = {}
1161 self.data = {}
1160 self.__times = []
1162 self.__times = []
1161 self.__heights = []
1163 self.__heights = []
1162 self.__all_heights = set()
1164 self.__all_heights = set()
1163 for plot in self.plottypes:
1165 for plot in self.plottypes:
1164 if 'snr' in plot:
1166 if 'snr' in plot:
1165 plot = 'snr'
1167 plot = 'snr'
1166 elif 'spc_moments' == plot:
1168 elif 'spc_moments' == plot:
1167 plot = 'moments'
1169 plot = 'moments'
1168 self.data[plot] = {}
1170 self.data[plot] = {}
1169
1171
1170 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1172 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1171 self.data['noise'] = {}
1173 self.data['noise'] = {}
1174 self.data['rti'] = {}
1172 if 'noise' not in self.plottypes:
1175 if 'noise' not in self.plottypes:
1173 self.plottypes.append('noise')
1176 self.plottypes.append('noise')
1177 if 'rti' not in self.plottypes:
1178 self.plottypes.append('rti')
1174
1179
1175 def shape(self, key):
1180 def shape(self, key):
1176 '''
1181 '''
1177 Get the shape of the one-element data for the given key
1182 Get the shape of the one-element data for the given key
1178 '''
1183 '''
1179
1184
1180 if len(self.data[key]):
1185 if len(self.data[key]):
1181 if 'spc' in key or not self.buffering:
1186 if 'spc' in key or not self.buffering:
1182 return self.data[key].shape
1187 return self.data[key].shape
1183 return self.data[key][self.__times[0]].shape
1188 return self.data[key][self.__times[0]].shape
1184 return (0,)
1189 return (0,)
1185
1190
1186 def update(self, dataOut, tm):
1191 def update(self, dataOut, tm):
1187 '''
1192 '''
1188 Update data object with new dataOut
1193 Update data object with new dataOut
1189 '''
1194 '''
1190
1195
1191 if tm in self.__times:
1196 if tm in self.__times:
1192 return
1197 return
1193 self.profileIndex = dataOut.profileIndex
1198 self.profileIndex = dataOut.profileIndex
1194 self.tm = tm
1199 self.tm = tm
1195 self.type = dataOut.type
1200 self.type = dataOut.type
1196 self.parameters = getattr(dataOut, 'parameters', [])
1201 self.parameters = getattr(dataOut, 'parameters', [])
1197 if hasattr(dataOut, 'pairsList'):
1202 if hasattr(dataOut, 'pairsList'):
1198 self.pairs = dataOut.pairsList
1203 self.pairs = dataOut.pairsList
1199 if hasattr(dataOut, 'meta'):
1204 if hasattr(dataOut, 'meta'):
1200 self.meta = dataOut.meta
1205 self.meta = dataOut.meta
1201 self.channels = dataOut.channelList
1206 self.channels = dataOut.channelList
1202 self.interval = dataOut.getTimeInterval()
1207 self.interval = dataOut.getTimeInterval()
1203 self.localtime = dataOut.useLocalTime
1208 self.localtime = dataOut.useLocalTime
1204 if 'spc' in self.plottypes or 'cspc' in self.plottypes or 'spc_moments' in self.plottypes:
1209 if 'spc' in self.plottypes or 'cspc' in self.plottypes or 'spc_moments' in self.plottypes:
1205 self.xrange = (dataOut.getFreqRange(1)/1000.,
1210 self.xrange = (dataOut.getFreqRange(1)/1000.,
1206 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1211 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1207 self.factor = dataOut.normFactor
1212 self.factor = dataOut.normFactor
1208 self.__heights.append(dataOut.heightList)
1213 self.__heights.append(dataOut.heightList)
1209 self.__all_heights.update(dataOut.heightList)
1214 self.__all_heights.update(dataOut.heightList)
1210 self.__times.append(tm)
1215 self.__times.append(tm)
1211
1216
1212 for plot in self.plottypes:
1217 for plot in self.plottypes:
1213 if plot in ('spc', 'spc_moments'):
1218 if plot in ('spc', 'spc_moments'):
1214 z = dataOut.data_spc/dataOut.normFactor
1219 z = dataOut.data_spc/dataOut.normFactor
1215 buffer = 10*numpy.log10(z)
1220 buffer = 10*numpy.log10(z)
1216 if plot == 'cspc':
1221 if plot == 'cspc':
1217 z = dataOut.data_spc/dataOut.normFactor
1222 z = dataOut.data_spc/dataOut.normFactor
1218 buffer = (dataOut.data_spc, dataOut.data_cspc)
1223 buffer = (dataOut.data_spc, dataOut.data_cspc)
1219 if plot == 'noise':
1224 if plot == 'noise':
1220 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1225 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1221 if plot == 'rti':
1226 if plot == 'rti':
1222 buffer = dataOut.getPower()
1227 buffer = dataOut.getPower()
1223 if plot == 'snr_db':
1228 if plot == 'snr_db':
1224 buffer = dataOut.data_SNR
1229 buffer = dataOut.data_SNR
1225 if plot == 'snr':
1230 if plot == 'snr':
1226 buffer = 10*numpy.log10(dataOut.data_SNR)
1231 buffer = 10*numpy.log10(dataOut.data_SNR)
1227 if plot == 'dop':
1232 if plot == 'dop':
1228 buffer = 10*numpy.log10(dataOut.data_DOP)
1233 buffer = 10*numpy.log10(dataOut.data_DOP)
1229 if plot == 'mean':
1234 if plot == 'mean':
1230 buffer = dataOut.data_MEAN
1235 buffer = dataOut.data_MEAN
1231 if plot == 'std':
1236 if plot == 'std':
1232 buffer = dataOut.data_STD
1237 buffer = dataOut.data_STD
1233 if plot == 'coh':
1238 if plot == 'coh':
1234 buffer = dataOut.getCoherence()
1239 buffer = dataOut.getCoherence()
1235 if plot == 'phase':
1240 if plot == 'phase':
1236 buffer = dataOut.getCoherence(phase=True)
1241 buffer = dataOut.getCoherence(phase=True)
1237 if plot == 'output':
1242 if plot == 'output':
1238 buffer = dataOut.data_output
1243 buffer = dataOut.data_output
1239 if plot == 'param':
1244 if plot == 'param':
1240 buffer = dataOut.data_param
1245 buffer = dataOut.data_param
1241 if plot == 'scope':
1246 if plot == 'scope':
1242 buffer = dataOut.data
1247 buffer = dataOut.data
1243 self.flagDataAsBlock = dataOut.flagDataAsBlock
1248 self.flagDataAsBlock = dataOut.flagDataAsBlock
1244 self.nProfiles = dataOut.nProfiles
1249 self.nProfiles = dataOut.nProfiles
1245
1250
1246 if plot == 'spc':
1251 if plot == 'spc':
1247 self.data[plot] = buffer
1252 self.data['spc'] = buffer
1248 elif plot == 'cspc':
1253 elif plot == 'cspc':
1249 self.data['spc'] = buffer[0]
1254 self.data['spc'] = buffer[0]
1250 self.data['cspc'] = buffer[1]
1255 self.data['cspc'] = buffer[1]
1251 elif plot == 'spc_moments':
1256 elif plot == 'spc_moments':
1252 self.data['spc'] = buffer
1257 self.data['spc'] = buffer
1253 self.data['moments'][tm] = dataOut.moments
1258 self.data['moments'][tm] = dataOut.moments
1254 else:
1259 else:
1255 if self.buffering:
1260 if self.buffering:
1256 self.data[plot][tm] = buffer
1261 self.data[plot][tm] = buffer
1257 else:
1262 else:
1258 self.data[plot] = buffer
1263 self.data[plot] = buffer
1259
1264
1260 def normalize_heights(self):
1265 def normalize_heights(self):
1261 '''
1266 '''
1262 Ensure same-dimension of the data for different heighList
1267 Ensure same-dimension of the data for different heighList
1263 '''
1268 '''
1264
1269
1265 H = numpy.array(list(self.__all_heights))
1270 H = numpy.array(list(self.__all_heights))
1266 H.sort()
1271 H.sort()
1267 for key in self.data:
1272 for key in self.data:
1268 shape = self.shape(key)[:-1] + H.shape
1273 shape = self.shape(key)[:-1] + H.shape
1269 for tm, obj in list(self.data[key].items()):
1274 for tm, obj in list(self.data[key].items()):
1270 h = self.__heights[self.__times.index(tm)]
1275 h = self.__heights[self.__times.index(tm)]
1271 if H.size == h.size:
1276 if H.size == h.size:
1272 continue
1277 continue
1273 index = numpy.where(numpy.in1d(H, h))[0]
1278 index = numpy.where(numpy.in1d(H, h))[0]
1274 dummy = numpy.zeros(shape) + numpy.nan
1279 dummy = numpy.zeros(shape) + numpy.nan
1275 if len(shape) == 2:
1280 if len(shape) == 2:
1276 dummy[:, index] = obj
1281 dummy[:, index] = obj
1277 else:
1282 else:
1278 dummy[index] = obj
1283 dummy[index] = obj
1279 self.data[key][tm] = dummy
1284 self.data[key][tm] = dummy
1280
1285
1281 self.__heights = [H for tm in self.__times]
1286 self.__heights = [H for tm in self.__times]
1282
1287
1283 def jsonify(self, decimate=False):
1288 def jsonify(self, decimate=False):
1284 '''
1289 '''
1285 Convert data to json
1290 Convert data to json
1286 '''
1291 '''
1287
1292
1288 data = {}
1293 data = {}
1289 tm = self.times[-1]
1294 tm = self.times[-1]
1290 dy = int(self.heights.size/self.MAXNUMY) + 1
1295 dy = int(self.heights.size/self.MAXNUMY) + 1
1291 for key in self.data:
1296 for key in self.data:
1292 if key in ('spc', 'cspc') or not self.buffering:
1297 if key in ('spc', 'cspc') or not self.buffering:
1293 dx = int(self.data[key].shape[1]/self.MAXNUMX) + 1
1298 dx = int(self.data[key].shape[1]/self.MAXNUMX) + 1
1294 data[key] = self.roundFloats(
1299 data[key] = self.roundFloats(
1295 self.data[key][::, ::dx, ::dy].tolist())
1300 self.data[key][::, ::dx, ::dy].tolist())
1296 else:
1301 else:
1297 data[key] = self.roundFloats(self.data[key][tm].tolist())
1302 data[key] = self.roundFloats(self.data[key][tm].tolist())
1298
1303
1299 ret = {'data': data}
1304 ret = {'data': data}
1300 ret['exp_code'] = self.exp_code
1305 ret['exp_code'] = self.exp_code
1301 ret['time'] = float(tm)
1306 ret['time'] = float(tm)
1302 ret['interval'] = float(self.interval)
1307 ret['interval'] = float(self.interval)
1303 ret['localtime'] = self.localtime
1308 ret['localtime'] = self.localtime
1304 ret['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1309 ret['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1305 if 'spc' in self.data or 'cspc' in self.data:
1310 if 'spc' in self.data or 'cspc' in self.data:
1306 ret['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1311 ret['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1307 else:
1312 else:
1308 ret['xrange'] = []
1313 ret['xrange'] = []
1309 if hasattr(self, 'pairs'):
1314 if hasattr(self, 'pairs'):
1310 ret['pairs'] = [(int(p[0]), int(p[1])) for p in self.pairs]
1315 ret['pairs'] = [(int(p[0]), int(p[1])) for p in self.pairs]
1311 else:
1316 else:
1312 ret['pairs'] = []
1317 ret['pairs'] = []
1313
1318
1314 for key, value in list(self.meta.items()):
1319 for key, value in list(self.meta.items()):
1315 ret[key] = value
1320 ret[key] = value
1316
1321
1317 return json.dumps(ret)
1322 return json.dumps(ret)
1318
1323
1319 @property
1324 @property
1320 def times(self):
1325 def times(self):
1321 '''
1326 '''
1322 Return the list of times of the current data
1327 Return the list of times of the current data
1323 '''
1328 '''
1324
1329
1325 ret = numpy.array(self.__times)
1330 ret = numpy.array(self.__times)
1326 ret.sort()
1331 ret.sort()
1327 return ret
1332 return ret
1328
1333
1329 @property
1334 @property
1330 def min_time(self):
1335 def min_time(self):
1331 '''
1336 '''
1332 Return the minimun time value
1337 Return the minimun time value
1333 '''
1338 '''
1334
1339
1335 return self.times[0]
1340 return self.times[0]
1336
1341
1337 @property
1342 @property
1338 def max_time(self):
1343 def max_time(self):
1339 '''
1344 '''
1340 Return the maximun time value
1345 Return the maximun time value
1341 '''
1346 '''
1342
1347
1343 return self.times[-1]
1348 return self.times[-1]
1344
1349
1345 @property
1350 @property
1346 def heights(self):
1351 def heights(self):
1347 '''
1352 '''
1348 Return the list of heights of the current data
1353 Return the list of heights of the current data
1349 '''
1354 '''
1350
1355
1351 return numpy.array(self.__heights[-1])
1356 return numpy.array(self.__heights[-1])
1352
1357
1353 @staticmethod
1358 @staticmethod
1354 def roundFloats(obj):
1359 def roundFloats(obj):
1355 if isinstance(obj, list):
1360 if isinstance(obj, list):
1356 return list(map(PlotterData.roundFloats, obj))
1361 return list(map(PlotterData.roundFloats, obj))
1357 elif isinstance(obj, float):
1362 elif isinstance(obj, float):
1358 return round(obj, 2)
1363 return round(obj, 2)
@@ -1,466 +1,466
1 import os
1 import os
2 import sys
2 import sys
3 import glob
3 import glob
4 import fnmatch
4 import fnmatch
5 import datetime
5 import datetime
6 import time
6 import time
7 import re
7 import re
8 import h5py
8 import h5py
9 import numpy
9 import numpy
10
10
11 import pylab as plb
11 import pylab as plb
12 from scipy.optimize import curve_fit
12 from scipy.optimize import curve_fit
13 from scipy import asarray as ar, exp
13 from scipy import asarray as ar, exp
14
14
15 SPEED_OF_LIGHT = 299792458
15 SPEED_OF_LIGHT = 299792458
16 SPEED_OF_LIGHT = 3e8
16 SPEED_OF_LIGHT = 3e8
17
17
18 try:
18 try:
19 from gevent import sleep
19 from gevent import sleep
20 except:
20 except:
21 from time import sleep
21 from time import sleep
22
22
23 from .utils import folder_in_range
23 from .utils import folder_in_range
24
24
25 from schainpy.model.data.jrodata import Spectra
25 from schainpy.model.data.jrodata import Spectra
26 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
26 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
27 from schainpy.utils import log
27 from schainpy.utils import log
28 from schainpy.model.io.jroIO_base import JRODataReader
28 from schainpy.model.io.jroIO_base import JRODataReader
29
29
30 def pol2cart(rho, phi):
30 def pol2cart(rho, phi):
31 x = rho * numpy.cos(phi)
31 x = rho * numpy.cos(phi)
32 y = rho * numpy.sin(phi)
32 y = rho * numpy.sin(phi)
33 return(x, y)
33 return(x, y)
34
34
35 FILE_STRUCTURE = numpy.dtype([ # HEADER 48bytes
35 FILE_STRUCTURE = numpy.dtype([ # HEADER 48bytes
36 ('FileMgcNumber', '<u4'), # 0x23020100
36 ('FileMgcNumber', '<u4'), # 0x23020100
37 ('nFDTdataRecors', '<u4'),
37 ('nFDTdataRecors', '<u4'),
38 ('OffsetStartHeader', '<u4'),
38 ('OffsetStartHeader', '<u4'),
39 ('RadarUnitId', '<u4'),
39 ('RadarUnitId', '<u4'),
40 ('SiteName', 'S32'), # Null terminated
40 ('SiteName', 'S32'), # Null terminated
41 ])
41 ])
42
42
43
43
44 class FileHeaderBLTR():
44 class FileHeaderBLTR():
45
45
46 def __init__(self, fo):
46 def __init__(self, fo):
47
47
48 self.fo = fo
48 self.fo = fo
49 self.size = 48
49 self.size = 48
50 self.read()
50 self.read()
51
51
52 def read(self):
52 def read(self):
53
53
54 header = numpy.fromfile(self.fo, FILE_STRUCTURE, 1)
54 header = numpy.fromfile(self.fo, FILE_STRUCTURE, 1)
55 self.FileMgcNumber = hex(header['FileMgcNumber'][0])
55 self.FileMgcNumber = hex(header['FileMgcNumber'][0])
56 self.nFDTdataRecors = int(header['nFDTdataRecors'][0])
56 self.nFDTdataRecors = int(header['nFDTdataRecors'][0])
57 self.RadarUnitId = int(header['RadarUnitId'][0])
57 self.RadarUnitId = int(header['RadarUnitId'][0])
58 self.OffsetStartHeader = int(header['OffsetStartHeader'][0])
58 self.OffsetStartHeader = int(header['OffsetStartHeader'][0])
59 self.SiteName = header['SiteName'][0]
59 self.SiteName = header['SiteName'][0]
60
60
61 def write(self, fp):
61 def write(self, fp):
62
62
63 headerTuple = (self.FileMgcNumber,
63 headerTuple = (self.FileMgcNumber,
64 self.nFDTdataRecors,
64 self.nFDTdataRecors,
65 self.RadarUnitId,
65 self.RadarUnitId,
66 self.SiteName,
66 self.SiteName,
67 self.size)
67 self.size)
68
68
69 header = numpy.array(headerTuple, FILE_STRUCTURE)
69 header = numpy.array(headerTuple, FILE_STRUCTURE)
70 header.tofile(fp)
70 header.tofile(fp)
71 ''' ndarray.tofile(fid, sep, format) Write array to a file as text or binary (default).
71 ''' ndarray.tofile(fid, sep, format) Write array to a file as text or binary (default).
72
72
73 fid : file or str
73 fid : file or str
74 An open file object, or a string containing a filename.
74 An open file object, or a string containing a filename.
75
75
76 sep : str
76 sep : str
77 Separator between array items for text output. If "" (empty), a binary file is written,
77 Separator between array items for text output. If "" (empty), a binary file is written,
78 equivalent to file.write(a.tobytes()).
78 equivalent to file.write(a.tobytes()).
79
79
80 format : str
80 format : str
81 Format string for text file output. Each entry in the array is formatted to text by
81 Format string for text file output. Each entry in the array is formatted to text by
82 first converting it to the closest Python type, and then using "format" % item.
82 first converting it to the closest Python type, and then using "format" % item.
83
83
84 '''
84 '''
85
85
86 return 1
86 return 1
87
87
88
88
89 RECORD_STRUCTURE = numpy.dtype([ # RECORD HEADER 180+20N bytes
89 RECORD_STRUCTURE = numpy.dtype([ # RECORD HEADER 180+20N bytes
90 ('RecMgcNumber', '<u4'), # 0x23030001
90 ('RecMgcNumber', '<u4'), # 0x23030001
91 ('RecCounter', '<u4'), # Record counter(0,1, ...)
91 ('RecCounter', '<u4'), # Record counter(0,1, ...)
92 # Offset to start of next record form start of this record
92 # Offset to start of next record form start of this record
93 ('Off2StartNxtRec', '<u4'),
93 ('Off2StartNxtRec', '<u4'),
94 # Offset to start of data from start of this record
94 # Offset to start of data from start of this record
95 ('Off2StartData', '<u4'),
95 ('Off2StartData', '<u4'),
96 # Epoch time stamp of start of acquisition (seconds)
96 # Epoch time stamp of start of acquisition (seconds)
97 ('nUtime', '<i4'),
97 ('nUtime', '<i4'),
98 # Millisecond component of time stamp (0,...,999)
98 # Millisecond component of time stamp (0,...,999)
99 ('nMilisec', '<u4'),
99 ('nMilisec', '<u4'),
100 # Experiment tag name (null terminated)
100 # Experiment tag name (null terminated)
101 ('ExpTagName', 'S32'),
101 ('ExpTagName', 'S32'),
102 # Experiment comment (null terminated)
102 # Experiment comment (null terminated)
103 ('ExpComment', 'S32'),
103 ('ExpComment', 'S32'),
104 # Site latitude (from GPS) in degrees (positive implies North)
104 # Site latitude (from GPS) in degrees (positive implies North)
105 ('SiteLatDegrees', '<f4'),
105 ('SiteLatDegrees', '<f4'),
106 # Site longitude (from GPS) in degrees (positive implies East)
106 # Site longitude (from GPS) in degrees (positive implies East)
107 ('SiteLongDegrees', '<f4'),
107 ('SiteLongDegrees', '<f4'),
108 # RTC GPS engine status (0=SEEK, 1=LOCK, 2=NOT FITTED, 3=UNAVAILABLE)
108 # RTC GPS engine status (0=SEEK, 1=LOCK, 2=NOT FITTED, 3=UNAVAILABLE)
109 ('RTCgpsStatus', '<u4'),
109 ('RTCgpsStatus', '<u4'),
110 ('TransmitFrec', '<u4'), # Transmit frequency (Hz)
110 ('TransmitFrec', '<u4'), # Transmit frequency (Hz)
111 ('ReceiveFrec', '<u4'), # Receive frequency
111 ('ReceiveFrec', '<u4'), # Receive frequency
112 # First local oscillator frequency (Hz)
112 # First local oscillator frequency (Hz)
113 ('FirstOsciFrec', '<u4'),
113 ('FirstOsciFrec', '<u4'),
114 # (0="O", 1="E", 2="linear 1", 3="linear2")
114 # (0="O", 1="E", 2="linear 1", 3="linear2")
115 ('Polarisation', '<u4'),
115 ('Polarisation', '<u4'),
116 # Receiver filter settings (0,1,2,3)
116 # Receiver filter settings (0,1,2,3)
117 ('ReceiverFiltSett', '<u4'),
117 ('ReceiverFiltSett', '<u4'),
118 # Number of modes in use (1 or 2)
118 # Number of modes in use (1 or 2)
119 ('nModesInUse', '<u4'),
119 ('nModesInUse', '<u4'),
120 # Dual Mode index number for these data (0 or 1)
120 # Dual Mode index number for these data (0 or 1)
121 ('DualModeIndex', '<u4'),
121 ('DualModeIndex', '<u4'),
122 # Dual Mode range correction for these data (m)
122 # Dual Mode range correction for these data (m)
123 ('DualModeRange', '<u4'),
123 ('DualModeRange', '<u4'),
124 # Number of digital channels acquired (2*N)
124 # Number of digital channels acquired (2*N)
125 ('nDigChannels', '<u4'),
125 ('nDigChannels', '<u4'),
126 # Sampling resolution (meters)
126 # Sampling resolution (meters)
127 ('SampResolution', '<u4'),
127 ('SampResolution', '<u4'),
128 # Number of range gates sampled
128 # Number of range gates sampled
129 ('nHeights', '<u4'),
129 ('nHeights', '<u4'),
130 # Start range of sampling (meters)
130 # Start range of sampling (meters)
131 ('StartRangeSamp', '<u4'),
131 ('StartRangeSamp', '<u4'),
132 ('PRFhz', '<u4'), # PRF (Hz)
132 ('PRFhz', '<u4'), # PRF (Hz)
133 ('nCohInt', '<u4'), # Integrations
133 ('nCohInt', '<u4'), # Integrations
134 # Number of data points transformed
134 # Number of data points transformed
135 ('nProfiles', '<u4'),
135 ('nProfiles', '<u4'),
136 # Number of receive beams stored in file (1 or N)
136 # Number of receive beams stored in file (1 or N)
137 ('nChannels', '<u4'),
137 ('nChannels', '<u4'),
138 ('nIncohInt', '<u4'), # Number of spectral averages
138 ('nIncohInt', '<u4'), # Number of spectral averages
139 # FFT windowing index (0 = no window)
139 # FFT windowing index (0 = no window)
140 ('FFTwindowingInd', '<u4'),
140 ('FFTwindowingInd', '<u4'),
141 # Beam steer angle (azimuth) in degrees (clockwise from true North)
141 # Beam steer angle (azimuth) in degrees (clockwise from true North)
142 ('BeamAngleAzim', '<f4'),
142 ('BeamAngleAzim', '<f4'),
143 # Beam steer angle (zenith) in degrees (0=> vertical)
143 # Beam steer angle (zenith) in degrees (0=> vertical)
144 ('BeamAngleZen', '<f4'),
144 ('BeamAngleZen', '<f4'),
145 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
145 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
146 ('AntennaCoord0', '<f4'),
146 ('AntennaCoord0', '<f4'),
147 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
147 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
148 ('AntennaAngl0', '<f4'),
148 ('AntennaAngl0', '<f4'),
149 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
149 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
150 ('AntennaCoord1', '<f4'),
150 ('AntennaCoord1', '<f4'),
151 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
151 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
152 ('AntennaAngl1', '<f4'),
152 ('AntennaAngl1', '<f4'),
153 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
153 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
154 ('AntennaCoord2', '<f4'),
154 ('AntennaCoord2', '<f4'),
155 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
155 # Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
156 ('AntennaAngl2', '<f4'),
156 ('AntennaAngl2', '<f4'),
157 # Receiver phase calibration (degrees) - N values
157 # Receiver phase calibration (degrees) - N values
158 ('RecPhaseCalibr0', '<f4'),
158 ('RecPhaseCalibr0', '<f4'),
159 # Receiver phase calibration (degrees) - N values
159 # Receiver phase calibration (degrees) - N values
160 ('RecPhaseCalibr1', '<f4'),
160 ('RecPhaseCalibr1', '<f4'),
161 # Receiver phase calibration (degrees) - N values
161 # Receiver phase calibration (degrees) - N values
162 ('RecPhaseCalibr2', '<f4'),
162 ('RecPhaseCalibr2', '<f4'),
163 # Receiver amplitude calibration (ratio relative to receiver one) - N values
163 # Receiver amplitude calibration (ratio relative to receiver one) - N values
164 ('RecAmpCalibr0', '<f4'),
164 ('RecAmpCalibr0', '<f4'),
165 # Receiver amplitude calibration (ratio relative to receiver one) - N values
165 # Receiver amplitude calibration (ratio relative to receiver one) - N values
166 ('RecAmpCalibr1', '<f4'),
166 ('RecAmpCalibr1', '<f4'),
167 # Receiver amplitude calibration (ratio relative to receiver one) - N values
167 # Receiver amplitude calibration (ratio relative to receiver one) - N values
168 ('RecAmpCalibr2', '<f4'),
168 ('RecAmpCalibr2', '<f4'),
169 # Receiver gains in dB - N values
169 # Receiver gains in dB - N values
170 ('ReceiverGaindB0', '<i4'),
170 ('ReceiverGaindB0', '<i4'),
171 # Receiver gains in dB - N values
171 # Receiver gains in dB - N values
172 ('ReceiverGaindB1', '<i4'),
172 ('ReceiverGaindB1', '<i4'),
173 # Receiver gains in dB - N values
173 # Receiver gains in dB - N values
174 ('ReceiverGaindB2', '<i4'),
174 ('ReceiverGaindB2', '<i4'),
175 ])
175 ])
176
176
177
177
178 class RecordHeaderBLTR():
178 class RecordHeaderBLTR():
179
179
180 def __init__(self, fo):
180 def __init__(self, fo):
181
181
182 self.fo = fo
182 self.fo = fo
183 self.OffsetStartHeader = 48
183 self.OffsetStartHeader = 48
184 self.Off2StartNxtRec = 811248
184 self.Off2StartNxtRec = 811248
185
185
186 def read(self, block):
186 def read(self, block):
187 OffRHeader = self.OffsetStartHeader + block * self.Off2StartNxtRec
187 OffRHeader = self.OffsetStartHeader + block * self.Off2StartNxtRec
188 self.fo.seek(OffRHeader, os.SEEK_SET)
188 self.fo.seek(OffRHeader, os.SEEK_SET)
189 header = numpy.fromfile(self.fo, RECORD_STRUCTURE, 1)
189 header = numpy.fromfile(self.fo, RECORD_STRUCTURE, 1)
190 self.RecMgcNumber = hex(header['RecMgcNumber'][0]) # 0x23030001
190 self.RecMgcNumber = hex(header['RecMgcNumber'][0]) # 0x23030001
191 self.RecCounter = int(header['RecCounter'][0])
191 self.RecCounter = int(header['RecCounter'][0])
192 self.Off2StartNxtRec = int(header['Off2StartNxtRec'][0])
192 self.Off2StartNxtRec = int(header['Off2StartNxtRec'][0])
193 self.Off2StartData = int(header['Off2StartData'][0])
193 self.Off2StartData = int(header['Off2StartData'][0])
194 self.nUtime = header['nUtime'][0]
194 self.nUtime = header['nUtime'][0]
195 self.nMilisec = header['nMilisec'][0]
195 self.nMilisec = header['nMilisec'][0]
196 self.ExpTagName = '' # str(header['ExpTagName'][0])
196 self.ExpTagName = '' # str(header['ExpTagName'][0])
197 self.ExpComment = '' # str(header['ExpComment'][0])
197 self.ExpComment = '' # str(header['ExpComment'][0])
198 self.SiteLatDegrees = header['SiteLatDegrees'][0]
198 self.SiteLatDegrees = header['SiteLatDegrees'][0]
199 self.SiteLongDegrees = header['SiteLongDegrees'][0]
199 self.SiteLongDegrees = header['SiteLongDegrees'][0]
200 self.RTCgpsStatus = header['RTCgpsStatus'][0]
200 self.RTCgpsStatus = header['RTCgpsStatus'][0]
201 self.TransmitFrec = header['TransmitFrec'][0]
201 self.TransmitFrec = header['TransmitFrec'][0]
202 self.ReceiveFrec = header['ReceiveFrec'][0]
202 self.ReceiveFrec = header['ReceiveFrec'][0]
203 self.FirstOsciFrec = header['FirstOsciFrec'][0]
203 self.FirstOsciFrec = header['FirstOsciFrec'][0]
204 self.Polarisation = header['Polarisation'][0]
204 self.Polarisation = header['Polarisation'][0]
205 self.ReceiverFiltSett = header['ReceiverFiltSett'][0]
205 self.ReceiverFiltSett = header['ReceiverFiltSett'][0]
206 self.nModesInUse = header['nModesInUse'][0]
206 self.nModesInUse = header['nModesInUse'][0]
207 self.DualModeIndex = header['DualModeIndex'][0]
207 self.DualModeIndex = header['DualModeIndex'][0]
208 self.DualModeRange = header['DualModeRange'][0]
208 self.DualModeRange = header['DualModeRange'][0]
209 self.nDigChannels = header['nDigChannels'][0]
209 self.nDigChannels = header['nDigChannels'][0]
210 self.SampResolution = header['SampResolution'][0]
210 self.SampResolution = header['SampResolution'][0]
211 self.nHeights = header['nHeights'][0]
211 self.nHeights = header['nHeights'][0]
212 self.StartRangeSamp = header['StartRangeSamp'][0]
212 self.StartRangeSamp = header['StartRangeSamp'][0]
213 self.PRFhz = header['PRFhz'][0]
213 self.PRFhz = header['PRFhz'][0]
214 self.nCohInt = header['nCohInt'][0]
214 self.nCohInt = header['nCohInt'][0]
215 self.nProfiles = header['nProfiles'][0]
215 self.nProfiles = header['nProfiles'][0]
216 self.nChannels = header['nChannels'][0]
216 self.nChannels = header['nChannels'][0]
217 self.nIncohInt = header['nIncohInt'][0]
217 self.nIncohInt = header['nIncohInt'][0]
218 self.FFTwindowingInd = header['FFTwindowingInd'][0]
218 self.FFTwindowingInd = header['FFTwindowingInd'][0]
219 self.BeamAngleAzim = header['BeamAngleAzim'][0]
219 self.BeamAngleAzim = header['BeamAngleAzim'][0]
220 self.BeamAngleZen = header['BeamAngleZen'][0]
220 self.BeamAngleZen = header['BeamAngleZen'][0]
221 self.AntennaCoord0 = header['AntennaCoord0'][0]
221 self.AntennaCoord0 = header['AntennaCoord0'][0]
222 self.AntennaAngl0 = header['AntennaAngl0'][0]
222 self.AntennaAngl0 = header['AntennaAngl0'][0]
223 self.AntennaCoord1 = header['AntennaCoord1'][0]
223 self.AntennaCoord1 = header['AntennaCoord1'][0]
224 self.AntennaAngl1 = header['AntennaAngl1'][0]
224 self.AntennaAngl1 = header['AntennaAngl1'][0]
225 self.AntennaCoord2 = header['AntennaCoord2'][0]
225 self.AntennaCoord2 = header['AntennaCoord2'][0]
226 self.AntennaAngl2 = header['AntennaAngl2'][0]
226 self.AntennaAngl2 = header['AntennaAngl2'][0]
227 self.RecPhaseCalibr0 = header['RecPhaseCalibr0'][0]
227 self.RecPhaseCalibr0 = header['RecPhaseCalibr0'][0]
228 self.RecPhaseCalibr1 = header['RecPhaseCalibr1'][0]
228 self.RecPhaseCalibr1 = header['RecPhaseCalibr1'][0]
229 self.RecPhaseCalibr2 = header['RecPhaseCalibr2'][0]
229 self.RecPhaseCalibr2 = header['RecPhaseCalibr2'][0]
230 self.RecAmpCalibr0 = header['RecAmpCalibr0'][0]
230 self.RecAmpCalibr0 = header['RecAmpCalibr0'][0]
231 self.RecAmpCalibr1 = header['RecAmpCalibr1'][0]
231 self.RecAmpCalibr1 = header['RecAmpCalibr1'][0]
232 self.RecAmpCalibr2 = header['RecAmpCalibr2'][0]
232 self.RecAmpCalibr2 = header['RecAmpCalibr2'][0]
233 self.ReceiverGaindB0 = header['ReceiverGaindB0'][0]
233 self.ReceiverGaindB0 = header['ReceiverGaindB0'][0]
234 self.ReceiverGaindB1 = header['ReceiverGaindB1'][0]
234 self.ReceiverGaindB1 = header['ReceiverGaindB1'][0]
235 self.ReceiverGaindB2 = header['ReceiverGaindB2'][0]
235 self.ReceiverGaindB2 = header['ReceiverGaindB2'][0]
236 self.ipp = 0.5 * (SPEED_OF_LIGHT / self.PRFhz)
236 self.ipp = 0.5 * (SPEED_OF_LIGHT / self.PRFhz)
237 self.RHsize = 180 + 20 * self.nChannels
237 self.RHsize = 180 + 20 * self.nChannels
238 self.Datasize = self.nProfiles * self.nChannels * self.nHeights * 2 * 4
238 self.Datasize = self.nProfiles * self.nChannels * self.nHeights * 2 * 4
239 endFp = self.OffsetStartHeader + self.RecCounter * self.Off2StartNxtRec
239 endFp = self.OffsetStartHeader + self.RecCounter * self.Off2StartNxtRec
240
240
241
241
242 if OffRHeader > endFp:
242 if OffRHeader > endFp:
243 sys.stderr.write(
243 sys.stderr.write(
244 "Warning %s: Size value read from System Header is lower than it has to be\n" % fp)
244 "Warning %s: Size value read from System Header is lower than it has to be\n" % fp)
245 return 0
245 return 0
246
246
247 if OffRHeader < endFp:
247 if OffRHeader < endFp:
248 sys.stderr.write(
248 sys.stderr.write(
249 "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp)
249 "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp)
250 return 0
250 return 0
251
251
252 return 1
252 return 1
253
253
254 @MPDecorator
254 @MPDecorator
255 class BLTRSpectraReader (ProcessingUnit):
255 class BLTRSpectraReader (ProcessingUnit):
256
256
257 def __init__(self):
257 def __init__(self):
258
258
259 ProcessingUnit.__init__(self)
259 ProcessingUnit.__init__(self)
260
260
261 self.ext = ".fdt"
261 self.ext = ".fdt"
262 self.optchar = "P"
262 self.optchar = "P"
263 self.fpFile = None
263 self.fpFile = None
264 self.fp = None
264 self.fp = None
265 self.BlockCounter = 0
265 self.BlockCounter = 0
266 self.fileSizeByHeader = None
266 self.fileSizeByHeader = None
267 self.filenameList = []
267 self.filenameList = []
268 self.fileSelector = 0
268 self.fileSelector = 0
269 self.Off2StartNxtRec = 0
269 self.Off2StartNxtRec = 0
270 self.RecCounter = 0
270 self.RecCounter = 0
271 self.flagNoMoreFiles = 0
271 self.flagNoMoreFiles = 0
272 self.data_spc = None
272 self.data_spc = None
273 self.data_cspc = None
273 self.data_cspc = None
274 self.path = None
274 self.path = None
275 self.OffsetStartHeader = 0
275 self.OffsetStartHeader = 0
276 self.Off2StartData = 0
276 self.Off2StartData = 0
277 self.ipp = 0
277 self.ipp = 0
278 self.nFDTdataRecors = 0
278 self.nFDTdataRecors = 0
279 self.blocksize = 0
279 self.blocksize = 0
280 self.dataOut = Spectra()
280 self.dataOut = Spectra()
281 self.dataOut.flagNoData = False
281 self.dataOut.flagNoData = False
282
282
283 def search_files(self):
283 def search_files(self):
284 '''
284 '''
285 Function that indicates the number of .fdt files that exist in the folder to be read.
285 Function that indicates the number of .fdt files that exist in the folder to be read.
286 It also creates an organized list with the names of the files to read.
286 It also creates an organized list with the names of the files to read.
287 '''
287 '''
288
288
289 files = glob.glob(os.path.join(self.path, '*{}'.format(self.ext)))
289 files = glob.glob(os.path.join(self.path, '*{}'.format(self.ext)))
290 files = sorted(files)
290 files = sorted(files)
291 for f in files:
291 for f in files:
292 filename = f.split('/')[-1]
292 filename = f.split('/')[-1]
293 if folder_in_range(filename.split('.')[1], self.startDate, self.endDate, '%Y%m%d'):
293 if folder_in_range(filename.split('.')[1], self.startDate, self.endDate, '%Y%m%d'):
294 self.filenameList.append(f)
294 self.filenameList.append(f)
295
295
296 def run(self, **kwargs):
296 def run(self, **kwargs):
297 '''
297 '''
298 This method will be the one that will initiate the data entry, will be called constantly.
298 This method will be the one that will initiate the data entry, will be called constantly.
299 You should first verify that your Setup () is set up and then continue to acquire
299 You should first verify that your Setup () is set up and then continue to acquire
300 the data to be processed with getData ().
300 the data to be processed with getData ().
301 '''
301 '''
302 if not self.isConfig:
302 if not self.isConfig:
303 self.setup(**kwargs)
303 self.setup(**kwargs)
304 self.isConfig = True
304 self.isConfig = True
305
305
306 self.getData()
306 self.getData()
307
307
308 def setup(self,
308 def setup(self,
309 path=None,
309 path=None,
310 startDate=None,
310 startDate=None,
311 endDate=None,
311 endDate=None,
312 startTime=None,
312 startTime=None,
313 endTime=None,
313 endTime=None,
314 walk=True,
314 walk=True,
315 code=None,
315 code=None,
316 online=False,
316 online=False,
317 mode=None,
317 mode=None,
318 **kwargs):
318 **kwargs):
319
319
320 self.isConfig = True
320 self.isConfig = True
321
321
322 self.path = path
322 self.path = path
323 self.startDate = startDate
323 self.startDate = startDate
324 self.endDate = endDate
324 self.endDate = endDate
325 self.startTime = startTime
325 self.startTime = startTime
326 self.endTime = endTime
326 self.endTime = endTime
327 self.walk = walk
327 self.walk = walk
328 self.mode = int(mode)
328 self.mode = int(mode)
329 self.search_files()
329 self.search_files()
330 if self.filenameList:
330 if self.filenameList:
331 self.readFile()
331 self.readFile()
332
332
333 def getData(self):
333 def getData(self):
334 '''
334 '''
335 Before starting this function, you should check that there is still an unread file,
335 Before starting this function, you should check that there is still an unread file,
336 If there are still blocks to read or if the data block is empty.
336 If there are still blocks to read or if the data block is empty.
337
337
338 You should call the file "read".
338 You should call the file "read".
339
339
340 '''
340 '''
341
341
342 if self.flagNoMoreFiles:
342 if self.flagNoMoreFiles:
343 self.dataOut.flagNoData = True
343 self.dataOut.flagNoData = True
344 self.dataOut.error = 'No more files'
344 self.dataOut.error = 'No more files'
345
345
346 self.readBlock()
346 self.readBlock()
347
347
348 def readFile(self):
348 def readFile(self):
349 '''
349 '''
350 You must indicate if you are reading in Online or Offline mode and load the
350 You must indicate if you are reading in Online or Offline mode and load the
351 The parameters for this file reading mode.
351 The parameters for this file reading mode.
352
352
353 Then you must do 2 actions:
353 Then you must do 2 actions:
354
354
355 1. Get the BLTR FileHeader.
355 1. Get the BLTR FileHeader.
356 2. Start reading the first block.
356 2. Start reading the first block.
357 '''
357 '''
358
358
359 if self.fileSelector < len(self.filenameList):
359 if self.fileSelector < len(self.filenameList):
360 log.success('Opening file: {}'.format(self.filenameList[self.fileSelector]), self.name)
360 log.success('Opening file: {}'.format(self.filenameList[self.fileSelector]), self.name)
361 self.fp = open(self.filenameList[self.fileSelector])
361 self.fp = open(self.filenameList[self.fileSelector])
362 self.fheader = FileHeaderBLTR(self.fp)
362 self.fheader = FileHeaderBLTR(self.fp)
363 self.rheader = RecordHeaderBLTR(self.fp)
363 self.rheader = RecordHeaderBLTR(self.fp)
364 self.nFDTdataRecors = self.fheader.nFDTdataRecors
364 self.nFDTdataRecors = self.fheader.nFDTdataRecors
365 self.fileSelector += 1
365 self.fileSelector += 1
366 self.BlockCounter = 0
366 self.BlockCounter = 0
367 return 1
367 return 1
368 else:
368 else:
369 self.flagNoMoreFiles = True
369 self.flagNoMoreFiles = True
370 self.dataOut.flagNoData = True
370 self.dataOut.flagNoData = True
371 return 0
371 return 0
372
372
373 def readBlock(self):
373 def readBlock(self):
374 '''
374 '''
375 It should be checked if the block has data, if it is not passed to the next file.
375 It should be checked if the block has data, if it is not passed to the next file.
376
376
377 Then the following is done:
377 Then the following is done:
378
378
379 1. Read the RecordHeader
379 1. Read the RecordHeader
380 2. Fill the buffer with the current block number.
380 2. Fill the buffer with the current block number.
381
381
382 '''
382 '''
383
383
384 if self.BlockCounter == self.nFDTdataRecors:
384 if self.BlockCounter == self.nFDTdataRecors:
385 if not self.readFile():
385 if not self.readFile():
386 return
386 return
387
387
388 if self.mode == 1:
388 if self.mode == 1:
389 self.rheader.read(self.BlockCounter+1)
389 self.rheader.read(self.BlockCounter+1)
390 elif self.mode == 0:
390 elif self.mode == 0:
391 self.rheader.read(self.BlockCounter)
391 self.rheader.read(self.BlockCounter)
392
392
393 self.RecCounter = self.rheader.RecCounter
393 self.RecCounter = self.rheader.RecCounter
394 self.OffsetStartHeader = self.rheader.OffsetStartHeader
394 self.OffsetStartHeader = self.rheader.OffsetStartHeader
395 self.Off2StartNxtRec = self.rheader.Off2StartNxtRec
395 self.Off2StartNxtRec = self.rheader.Off2StartNxtRec
396 self.Off2StartData = self.rheader.Off2StartData
396 self.Off2StartData = self.rheader.Off2StartData
397 self.nProfiles = self.rheader.nProfiles
397 self.nProfiles = self.rheader.nProfiles
398 self.nChannels = self.rheader.nChannels
398 self.nChannels = self.rheader.nChannels
399 self.nHeights = self.rheader.nHeights
399 self.nHeights = self.rheader.nHeights
400 self.frequency = self.rheader.TransmitFrec
400 self.frequency = self.rheader.TransmitFrec
401 self.DualModeIndex = self.rheader.DualModeIndex
401 self.DualModeIndex = self.rheader.DualModeIndex
402 self.pairsList = [(0, 1), (0, 2), (1, 2)]
402 self.pairsList = [(0, 1), (0, 2), (1, 2)]
403 self.dataOut.pairsList = self.pairsList
403 self.dataOut.pairsList = self.pairsList
404 self.nRdPairs = len(self.dataOut.pairsList)
404 self.nRdPairs = len(self.dataOut.pairsList)
405 self.dataOut.nRdPairs = self.nRdPairs
405 self.dataOut.nRdPairs = self.nRdPairs
406 self.dataOut.heightList = (self.rheader.StartRangeSamp + numpy.arange(self.nHeights) * self.rheader.SampResolution) / 1000.
406 self.dataOut.heightList = (self.rheader.StartRangeSamp + numpy.arange(self.nHeights) * self.rheader.SampResolution) / 1000.
407 self.dataOut.channelList = range(self.nChannels)
407 self.dataOut.channelList = range(self.nChannels)
408 self.dataOut.nProfiles=self.rheader.nProfiles
408 self.dataOut.nProfiles=self.rheader.nProfiles
409 self.dataOut.nIncohInt=self.rheader.nIncohInt
409 self.dataOut.nIncohInt=self.rheader.nIncohInt
410 self.dataOut.nCohInt=self.rheader.nCohInt
410 self.dataOut.nCohInt=self.rheader.nCohInt
411 self.dataOut.ippSeconds= 1/float(self.rheader.PRFhz)
411 self.dataOut.ippSeconds= 1/float(self.rheader.PRFhz)
412 self.dataOut.PRF=self.rheader.PRFhz
412 self.dataOut.PRF=self.rheader.PRFhz
413 self.dataOut.nFFTPoints=self.rheader.nProfiles
413 self.dataOut.nFFTPoints=self.rheader.nProfiles
414 self.dataOut.utctime=self.rheader.nUtime
414 self.dataOut.utctime = self.rheader.nUtime + self.rheader.nMilisec/1000.
415 self.dataOut.timeZone = 0
415 self.dataOut.timeZone = 0
416 self.dataOut.useLocalTime = False
416 self.dataOut.useLocalTime = False
417 self.dataOut.nmodes = 2
417 self.dataOut.nmodes = 2
418 log.log('Reading block {} - {}'.format(self.BlockCounter, self.dataOut.datatime), self.name)
418 log.log('Reading block {} - {}'.format(self.BlockCounter, self.dataOut.datatime), self.name)
419 OffDATA = self.OffsetStartHeader + self.RecCounter * \
419 OffDATA = self.OffsetStartHeader + self.RecCounter * \
420 self.Off2StartNxtRec + self.Off2StartData
420 self.Off2StartNxtRec + self.Off2StartData
421 self.fp.seek(OffDATA, os.SEEK_SET)
421 self.fp.seek(OffDATA, os.SEEK_SET)
422
422
423 self.data_fft = numpy.fromfile(self.fp, [('complex','<c8')], self.nProfiles*self.nChannels*self.nHeights )
423 self.data_fft = numpy.fromfile(self.fp, [('complex','<c8')], self.nProfiles*self.nChannels*self.nHeights )
424 self.data_fft = self.data_fft.astype(numpy.dtype('complex'))
424 self.data_fft = self.data_fft.astype(numpy.dtype('complex'))
425 self.data_block = numpy.reshape(self.data_fft,(self.nHeights, self.nChannels, self.nProfiles))
425 self.data_block = numpy.reshape(self.data_fft,(self.nHeights, self.nChannels, self.nProfiles))
426 self.data_block = numpy.transpose(self.data_block, (1,2,0))
426 self.data_block = numpy.transpose(self.data_block, (1,2,0))
427 copy = self.data_block.copy()
427 copy = self.data_block.copy()
428 spc = copy * numpy.conjugate(copy)
428 spc = copy * numpy.conjugate(copy)
429 self.data_spc = numpy.absolute(spc) # valor absoluto o magnitud
429 self.data_spc = numpy.absolute(spc) # valor absoluto o magnitud
430 self.dataOut.data_spc = self.data_spc
430 self.dataOut.data_spc = self.data_spc
431
431
432 cspc = self.data_block.copy()
432 cspc = self.data_block.copy()
433 self.data_cspc = self.data_block.copy()
433 self.data_cspc = self.data_block.copy()
434
434
435 for i in range(self.nRdPairs):
435 for i in range(self.nRdPairs):
436
436
437 chan_index0 = self.dataOut.pairsList[i][0]
437 chan_index0 = self.dataOut.pairsList[i][0]
438 chan_index1 = self.dataOut.pairsList[i][1]
438 chan_index1 = self.dataOut.pairsList[i][1]
439
439
440 self.data_cspc[i, :, :] = cspc[chan_index0, :, :] * numpy.conjugate(cspc[chan_index1, :, :])
440 self.data_cspc[i, :, :] = cspc[chan_index0, :, :] * numpy.conjugate(cspc[chan_index1, :, :])
441
441
442 '''Getting Eij and Nij'''
442 '''Getting Eij and Nij'''
443 (AntennaX0, AntennaY0) = pol2cart(
443 (AntennaX0, AntennaY0) = pol2cart(
444 self.rheader.AntennaCoord0, self.rheader.AntennaAngl0 * numpy.pi / 180)
444 self.rheader.AntennaCoord0, self.rheader.AntennaAngl0 * numpy.pi / 180)
445 (AntennaX1, AntennaY1) = pol2cart(
445 (AntennaX1, AntennaY1) = pol2cart(
446 self.rheader.AntennaCoord1, self.rheader.AntennaAngl1 * numpy.pi / 180)
446 self.rheader.AntennaCoord1, self.rheader.AntennaAngl1 * numpy.pi / 180)
447 (AntennaX2, AntennaY2) = pol2cart(
447 (AntennaX2, AntennaY2) = pol2cart(
448 self.rheader.AntennaCoord2, self.rheader.AntennaAngl2 * numpy.pi / 180)
448 self.rheader.AntennaCoord2, self.rheader.AntennaAngl2 * numpy.pi / 180)
449
449
450 E01 = AntennaX0 - AntennaX1
450 E01 = AntennaX0 - AntennaX1
451 N01 = AntennaY0 - AntennaY1
451 N01 = AntennaY0 - AntennaY1
452
452
453 E02 = AntennaX0 - AntennaX2
453 E02 = AntennaX0 - AntennaX2
454 N02 = AntennaY0 - AntennaY2
454 N02 = AntennaY0 - AntennaY2
455
455
456 E12 = AntennaX1 - AntennaX2
456 E12 = AntennaX1 - AntennaX2
457 N12 = AntennaY1 - AntennaY2
457 N12 = AntennaY1 - AntennaY2
458
458
459 self.ChanDist = numpy.array(
459 self.ChanDist = numpy.array(
460 [[E01, N01], [E02, N02], [E12, N12]])
460 [[E01, N01], [E02, N02], [E12, N12]])
461
461
462 self.dataOut.ChanDist = self.ChanDist
462 self.dataOut.ChanDist = self.ChanDist
463
463
464 self.BlockCounter += 2
464 self.BlockCounter += 2
465 self.dataOut.data_spc = self.data_spc
465 self.dataOut.data_spc = self.data_spc
466 self.dataOut.data_cspc =self.data_cspc
466 self.dataOut.data_cspc =self.data_cspc
General Comments 0
You need to be logged in to leave comments. Login now