##// END OF EJS Templates
no change
avaldezp -
r1510:c95a8abdd72f
parent child
Show More
@@ -1,1074 +1,1073
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 '''
79 '''
80 lenOfData = len(sortdata)
80 lenOfData = len(sortdata)
81 nums_min = lenOfData*0.2
81 nums_min = lenOfData*0.2
82
82
83 if nums_min <= 5:
83 if nums_min <= 5:
84
84
85 nums_min = 5
85 nums_min = 5
86
86
87 sump = 0.
87 sump = 0.
88 sumq = 0.
88 sumq = 0.
89
89
90 j = 0
90 j = 0
91 cont = 1
91 cont = 1
92
92
93 while((cont == 1)and(j < lenOfData)):
93 while((cont == 1)and(j < lenOfData)):
94
94
95 sump += sortdata[j]
95 sump += sortdata[j]
96 sumq += sortdata[j]**2
96 sumq += sortdata[j]**2
97
97
98 if j > nums_min:
98 if j > nums_min:
99 rtest = float(j)/(j-1) + 1.0/navg
99 rtest = float(j)/(j-1) + 1.0/navg
100 if ((sumq*j) > (rtest*sump**2)):
100 if ((sumq*j) > (rtest*sump**2)):
101 j = j - 1
101 j = j - 1
102 sump = sump - sortdata[j]
102 sump = sump - sortdata[j]
103 sumq = sumq - sortdata[j]**2
103 sumq = sumq - sortdata[j]**2
104 cont = 0
104 cont = 0
105
105
106 j += 1
106 j += 1
107
107
108 lnoise = sump / j
108 lnoise = sump / j
109 '''
109 '''
110 return _noise.hildebrand_sekhon(sortdata, navg)
110 return _noise.hildebrand_sekhon(sortdata, navg)
111
111
112
112
113 class Beam:
113 class Beam:
114
114
115 def __init__(self):
115 def __init__(self):
116 self.codeList = []
116 self.codeList = []
117 self.azimuthList = []
117 self.azimuthList = []
118 self.zenithList = []
118 self.zenithList = []
119
119
120
120
121 class GenericData(object):
121 class GenericData(object):
122
122
123 flagNoData = True
123 flagNoData = True
124
124
125 def copy(self, inputObj=None):
125 def copy(self, inputObj=None):
126
126
127 if inputObj == None:
127 if inputObj == None:
128 return copy.deepcopy(self)
128 return copy.deepcopy(self)
129
129
130 for key in list(inputObj.__dict__.keys()):
130 for key in list(inputObj.__dict__.keys()):
131
131
132 attribute = inputObj.__dict__[key]
132 attribute = inputObj.__dict__[key]
133
133
134 # If this attribute is a tuple or list
134 # If this attribute is a tuple or list
135 if type(inputObj.__dict__[key]) in (tuple, list):
135 if type(inputObj.__dict__[key]) in (tuple, list):
136 self.__dict__[key] = attribute[:]
136 self.__dict__[key] = attribute[:]
137 continue
137 continue
138
138
139 # If this attribute is another object or instance
139 # If this attribute is another object or instance
140 if hasattr(attribute, '__dict__'):
140 if hasattr(attribute, '__dict__'):
141 self.__dict__[key] = attribute.copy()
141 self.__dict__[key] = attribute.copy()
142 continue
142 continue
143
143
144 self.__dict__[key] = inputObj.__dict__[key]
144 self.__dict__[key] = inputObj.__dict__[key]
145
145
146 def deepcopy(self):
146 def deepcopy(self):
147
147
148 return copy.deepcopy(self)
148 return copy.deepcopy(self)
149
149
150 def isEmpty(self):
150 def isEmpty(self):
151
151
152 return self.flagNoData
152 return self.flagNoData
153
153
154 def isReady(self):
154 def isReady(self):
155
155
156 return not self.flagNoData
156 return not self.flagNoData
157
157
158
158
159 class JROData(GenericData):
159 class JROData(GenericData):
160
160
161 systemHeaderObj = SystemHeader()
161 systemHeaderObj = SystemHeader()
162 radarControllerHeaderObj = RadarControllerHeader()
162 radarControllerHeaderObj = RadarControllerHeader()
163 type = None
163 type = None
164 datatype = None # dtype but in string
164 datatype = None # dtype but in string
165 nProfiles = None
165 nProfiles = None
166 heightList = None
166 heightList = None
167 channelList = None
167 channelList = None
168 flagDiscontinuousBlock = False
168 flagDiscontinuousBlock = False
169 useLocalTime = False
169 useLocalTime = False
170 utctime = None
170 utctime = None
171 timeZone = None
171 timeZone = None
172 dstFlag = None
172 dstFlag = None
173 errorCount = None
173 errorCount = None
174 blocksize = None
174 blocksize = None
175 flagDecodeData = False # asumo q la data no esta decodificada
175 flagDecodeData = False # asumo q la data no esta decodificada
176 flagDeflipData = False # asumo q la data no esta sin flip
176 flagDeflipData = False # asumo q la data no esta sin flip
177 flagShiftFFT = False
177 flagShiftFFT = False
178 nCohInt = None
178 nCohInt = None
179 windowOfFilter = 1
179 windowOfFilter = 1
180 C = 3e8
180 C = 3e8
181 frequency = 49.92e6
181 frequency = 49.92e6
182 realtime = False
182 realtime = False
183 beacon_heiIndexList = None
183 beacon_heiIndexList = None
184 last_block = None
184 last_block = None
185 blocknow = None
185 blocknow = None
186 azimuth = None
186 azimuth = None
187 zenith = None
187 zenith = None
188 beam = Beam()
188 beam = Beam()
189 profileIndex = None
189 profileIndex = None
190 error = None
190 error = None
191 data = None
191 data = None
192 nmodes = None
192 nmodes = None
193 h0 = 0
193 h0 = 0
194 metadata_list = ['heightList', 'timeZone', 'type']
194 metadata_list = ['heightList', 'timeZone', 'type']
195
195
196 def __str__(self):
196 def __str__(self):
197
197
198 return '{} - {}'.format(self.type, self.datatime())
198 return '{} - {}'.format(self.type, self.datatime())
199
199
200 def getNoise(self):
200 def getNoise(self):
201
201
202 raise NotImplementedError
202 raise NotImplementedError
203
203
204 @property
204 @property
205 def nChannels(self):
205 def nChannels(self):
206
206
207 return len(self.channelList)
207 return len(self.channelList)
208
208
209 @property
209 @property
210 def channelIndexList(self):
210 def channelIndexList(self):
211
211
212 return list(range(self.nChannels))
212 return list(range(self.nChannels))
213
213
214 @property
214 @property
215 def nHeights(self):
215 def nHeights(self):
216
216
217 return len(self.heightList)
217 return len(self.heightList)
218
218
219 def getDeltaH(self):
219 def getDeltaH(self):
220
220
221 return self.heightList[1] - self.heightList[0]
221 return self.heightList[1] - self.heightList[0]
222
222
223 @property
223 @property
224 def ltctime(self):
224 def ltctime(self):
225
225
226 if self.useLocalTime:
226 if self.useLocalTime:
227 return self.utctime - self.timeZone * 60
227 return self.utctime - self.timeZone * 60
228
228
229 return self.utctime
229 return self.utctime
230
230
231 @property
231 @property
232 def datatime(self):
232 def datatime(self):
233
233
234 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
234 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
235 return datatimeValue
235 return datatimeValue
236
236
237 def getTimeRange(self):
237 def getTimeRange(self):
238
238
239 datatime = []
239 datatime = []
240
240
241 datatime.append(self.ltctime)
241 datatime.append(self.ltctime)
242 datatime.append(self.ltctime + self.timeInterval + 1)
242 datatime.append(self.ltctime + self.timeInterval + 1)
243
243
244 datatime = numpy.array(datatime)
244 datatime = numpy.array(datatime)
245
245
246 return datatime
246 return datatime
247
247
248 def getFmaxTimeResponse(self):
248 def getFmaxTimeResponse(self):
249
249
250 period = (10**-6) * self.getDeltaH() / (0.15)
250 period = (10**-6) * self.getDeltaH() / (0.15)
251
251
252 PRF = 1. / (period * self.nCohInt)
252 PRF = 1. / (period * self.nCohInt)
253
253
254 fmax = PRF
254 fmax = PRF
255
255
256 return fmax
256 return fmax
257
257
258 def getFmax(self):
258 def getFmax(self):
259 PRF = 1. / (self.ippSeconds * self.nCohInt)
259 PRF = 1. / (self.ippSeconds * self.nCohInt)
260
260
261 fmax = PRF
261 fmax = PRF
262 return fmax
262 return fmax
263
263
264 def getVmax(self):
264 def getVmax(self):
265
265
266 _lambda = self.C / self.frequency
266 _lambda = self.C / self.frequency
267
268 vmax = self.getFmax() * _lambda / 2
267 vmax = self.getFmax() * _lambda / 2
269
268
270 return vmax
269 return vmax
271
270
272 @property
271 @property
273 def ippSeconds(self):
272 def ippSeconds(self):
274 '''
273 '''
275 '''
274 '''
276 return self.radarControllerHeaderObj.ippSeconds
275 return self.radarControllerHeaderObj.ippSeconds
277
276
278 @ippSeconds.setter
277 @ippSeconds.setter
279 def ippSeconds(self, ippSeconds):
278 def ippSeconds(self, ippSeconds):
280 '''
279 '''
281 '''
280 '''
282 self.radarControllerHeaderObj.ippSeconds = ippSeconds
281 self.radarControllerHeaderObj.ippSeconds = ippSeconds
283
282
284 @property
283 @property
285 def code(self):
284 def code(self):
286 '''
285 '''
287 '''
286 '''
288 return self.radarControllerHeaderObj.code
287 return self.radarControllerHeaderObj.code
289
288
290 @code.setter
289 @code.setter
291 def code(self, code):
290 def code(self, code):
292 '''
291 '''
293 '''
292 '''
294 self.radarControllerHeaderObj.code = code
293 self.radarControllerHeaderObj.code = code
295
294
296 @property
295 @property
297 def nCode(self):
296 def nCode(self):
298 '''
297 '''
299 '''
298 '''
300 return self.radarControllerHeaderObj.nCode
299 return self.radarControllerHeaderObj.nCode
301
300
302 @nCode.setter
301 @nCode.setter
303 def nCode(self, ncode):
302 def nCode(self, ncode):
304 '''
303 '''
305 '''
304 '''
306 self.radarControllerHeaderObj.nCode = ncode
305 self.radarControllerHeaderObj.nCode = ncode
307
306
308 @property
307 @property
309 def nBaud(self):
308 def nBaud(self):
310 '''
309 '''
311 '''
310 '''
312 return self.radarControllerHeaderObj.nBaud
311 return self.radarControllerHeaderObj.nBaud
313
312
314 @nBaud.setter
313 @nBaud.setter
315 def nBaud(self, nbaud):
314 def nBaud(self, nbaud):
316 '''
315 '''
317 '''
316 '''
318 self.radarControllerHeaderObj.nBaud = nbaud
317 self.radarControllerHeaderObj.nBaud = nbaud
319
318
320 @property
319 @property
321 def ipp(self):
320 def ipp(self):
322 '''
321 '''
323 '''
322 '''
324 return self.radarControllerHeaderObj.ipp
323 return self.radarControllerHeaderObj.ipp
325
324
326 @ipp.setter
325 @ipp.setter
327 def ipp(self, ipp):
326 def ipp(self, ipp):
328 '''
327 '''
329 '''
328 '''
330 self.radarControllerHeaderObj.ipp = ipp
329 self.radarControllerHeaderObj.ipp = ipp
331
330
332 @property
331 @property
333 def metadata(self):
332 def metadata(self):
334 '''
333 '''
335 '''
334 '''
336
335
337 return {attr: getattr(self, attr) for attr in self.metadata_list}
336 return {attr: getattr(self, attr) for attr in self.metadata_list}
338
337
339
338
340 class Voltage(JROData):
339 class Voltage(JROData):
341
340
342 dataPP_POW = None
341 dataPP_POW = None
343 dataPP_DOP = None
342 dataPP_DOP = None
344 dataPP_WIDTH = None
343 dataPP_WIDTH = None
345 dataPP_SNR = None
344 dataPP_SNR = None
346
345
347 def __init__(self):
346 def __init__(self):
348 '''
347 '''
349 Constructor
348 Constructor
350 '''
349 '''
351
350
352 self.useLocalTime = True
351 self.useLocalTime = True
353 self.radarControllerHeaderObj = RadarControllerHeader()
352 self.radarControllerHeaderObj = RadarControllerHeader()
354 self.systemHeaderObj = SystemHeader()
353 self.systemHeaderObj = SystemHeader()
355 self.type = "Voltage"
354 self.type = "Voltage"
356 self.data = None
355 self.data = None
357 self.nProfiles = None
356 self.nProfiles = None
358 self.heightList = None
357 self.heightList = None
359 self.channelList = None
358 self.channelList = None
360 self.flagNoData = True
359 self.flagNoData = True
361 self.flagDiscontinuousBlock = False
360 self.flagDiscontinuousBlock = False
362 self.utctime = None
361 self.utctime = None
363 self.timeZone = 0
362 self.timeZone = 0
364 self.dstFlag = None
363 self.dstFlag = None
365 self.errorCount = None
364 self.errorCount = None
366 self.nCohInt = None
365 self.nCohInt = None
367 self.blocksize = None
366 self.blocksize = None
368 self.flagCohInt = False
367 self.flagCohInt = False
369 self.flagDecodeData = False # asumo q la data no esta decodificada
368 self.flagDecodeData = False # asumo q la data no esta decodificada
370 self.flagDeflipData = False # asumo q la data no esta sin flip
369 self.flagDeflipData = False # asumo q la data no esta sin flip
371 self.flagShiftFFT = False
370 self.flagShiftFFT = False
372 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
371 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
373 self.profileIndex = 0
372 self.profileIndex = 0
374 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
373 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
375 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
374 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
376
375
377 def getNoisebyHildebrand(self, channel=None):
376 def getNoisebyHildebrand(self, channel=None):
378 """
377 """
379 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
378 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
380
379
381 Return:
380 Return:
382 noiselevel
381 noiselevel
383 """
382 """
384
383
385 if channel != None:
384 if channel != None:
386 data = self.data[channel]
385 data = self.data[channel]
387 nChannels = 1
386 nChannels = 1
388 else:
387 else:
389 data = self.data
388 data = self.data
390 nChannels = self.nChannels
389 nChannels = self.nChannels
391
390
392 noise = numpy.zeros(nChannels)
391 noise = numpy.zeros(nChannels)
393 power = data * numpy.conjugate(data)
392 power = data * numpy.conjugate(data)
394
393
395 for thisChannel in range(nChannels):
394 for thisChannel in range(nChannels):
396 if nChannels == 1:
395 if nChannels == 1:
397 daux = power[:].real
396 daux = power[:].real
398 else:
397 else:
399 daux = power[thisChannel, :].real
398 daux = power[thisChannel, :].real
400 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
399 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
401
400
402 return noise
401 return noise
403
402
404 def getNoise(self, type=1, channel=None):
403 def getNoise(self, type=1, channel=None):
405
404
406 if type == 1:
405 if type == 1:
407 noise = self.getNoisebyHildebrand(channel)
406 noise = self.getNoisebyHildebrand(channel)
408
407
409 return noise
408 return noise
410
409
411 def getPower(self, channel=None):
410 def getPower(self, channel=None):
412
411
413 if channel != None:
412 if channel != None:
414 data = self.data[channel]
413 data = self.data[channel]
415 else:
414 else:
416 data = self.data
415 data = self.data
417
416
418 power = data * numpy.conjugate(data)
417 power = data * numpy.conjugate(data)
419 powerdB = 10 * numpy.log10(power.real)
418 powerdB = 10 * numpy.log10(power.real)
420 powerdB = numpy.squeeze(powerdB)
419 powerdB = numpy.squeeze(powerdB)
421
420
422 return powerdB
421 return powerdB
423
422
424 @property
423 @property
425 def timeInterval(self):
424 def timeInterval(self):
426
425
427 return self.ippSeconds * self.nCohInt
426 return self.ippSeconds * self.nCohInt
428
427
429 noise = property(getNoise, "I'm the 'nHeights' property.")
428 noise = property(getNoise, "I'm the 'nHeights' property.")
430
429
431
430
432 class Spectra(JROData):
431 class Spectra(JROData):
433
432
434 def __init__(self):
433 def __init__(self):
435 '''
434 '''
436 Constructor
435 Constructor
437 '''
436 '''
438
437
439 self.data_dc = None
438 self.data_dc = None
440 self.data_spc = None
439 self.data_spc = None
441 self.data_cspc = None
440 self.data_cspc = None
442 self.useLocalTime = True
441 self.useLocalTime = True
443 self.radarControllerHeaderObj = RadarControllerHeader()
442 self.radarControllerHeaderObj = RadarControllerHeader()
444 self.systemHeaderObj = SystemHeader()
443 self.systemHeaderObj = SystemHeader()
445 self.type = "Spectra"
444 self.type = "Spectra"
446 self.timeZone = 0
445 self.timeZone = 0
447 self.nProfiles = None
446 self.nProfiles = None
448 self.heightList = None
447 self.heightList = None
449 self.channelList = None
448 self.channelList = None
450 self.pairsList = None
449 self.pairsList = None
451 self.flagNoData = True
450 self.flagNoData = True
452 self.flagDiscontinuousBlock = False
451 self.flagDiscontinuousBlock = False
453 self.utctime = None
452 self.utctime = None
454 self.nCohInt = None
453 self.nCohInt = None
455 self.nIncohInt = None
454 self.nIncohInt = None
456 self.blocksize = None
455 self.blocksize = None
457 self.nFFTPoints = None
456 self.nFFTPoints = None
458 self.wavelength = None
457 self.wavelength = None
459 self.flagDecodeData = False # asumo q la data no esta decodificada
458 self.flagDecodeData = False # asumo q la data no esta decodificada
460 self.flagDeflipData = False # asumo q la data no esta sin flip
459 self.flagDeflipData = False # asumo q la data no esta sin flip
461 self.flagShiftFFT = False
460 self.flagShiftFFT = False
462 self.ippFactor = 1
461 self.ippFactor = 1
463 self.beacon_heiIndexList = []
462 self.beacon_heiIndexList = []
464 self.noise_estimation = None
463 self.noise_estimation = None
465 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
464 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
466 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
465 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
467
466
468 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
467 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
469 """
468 """
470 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
469 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
471
470
472 Return:
471 Return:
473 noiselevel
472 noiselevel
474 """
473 """
475
474
476 noise = numpy.zeros(self.nChannels)
475 noise = numpy.zeros(self.nChannels)
477
476
478 for channel in range(self.nChannels):
477 for channel in range(self.nChannels):
479 daux = self.data_spc[channel,
478 daux = self.data_spc[channel,
480 xmin_index:xmax_index, ymin_index:ymax_index]
479 xmin_index:xmax_index, ymin_index:ymax_index]
481 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
480 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
482
481
483 return noise
482 return noise
484
483
485 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
484 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
486
485
487 if self.noise_estimation is not None:
486 if self.noise_estimation is not None:
488 # this was estimated by getNoise Operation defined in jroproc_spectra.py
487 # this was estimated by getNoise Operation defined in jroproc_spectra.py
489 return self.noise_estimation
488 return self.noise_estimation
490 else:
489 else:
491 noise = self.getNoisebyHildebrand(
490 noise = self.getNoisebyHildebrand(
492 xmin_index, xmax_index, ymin_index, ymax_index)
491 xmin_index, xmax_index, ymin_index, ymax_index)
493 return noise
492 return noise
494
493
495 def getFreqRangeTimeResponse(self, extrapoints=0):
494 def getFreqRangeTimeResponse(self, extrapoints=0):
496
495
497 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
496 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
498 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
497 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
499
498
500 return freqrange
499 return freqrange
501
500
502 def getAcfRange(self, extrapoints=0):
501 def getAcfRange(self, extrapoints=0):
503
502
504 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
503 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
505 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
504 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
506
505
507 return freqrange
506 return freqrange
508
507
509 def getFreqRange(self, extrapoints=0):
508 def getFreqRange(self, extrapoints=0):
510
509
511 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
510 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
512 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
511 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
513
512
514 return freqrange
513 return freqrange
515
514
516 def getVelRange(self, extrapoints=0):
515 def getVelRange(self, extrapoints=0):
517
516
518 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
517 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
519 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
518 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
520
519
521 if self.nmodes:
520 if self.nmodes:
522 return velrange/self.nmodes
521 return velrange/self.nmodes
523 else:
522 else:
524 return velrange
523 return velrange
525
524
526 @property
525 @property
527 def nPairs(self):
526 def nPairs(self):
528
527
529 return len(self.pairsList)
528 return len(self.pairsList)
530
529
531 @property
530 @property
532 def pairsIndexList(self):
531 def pairsIndexList(self):
533
532
534 return list(range(self.nPairs))
533 return list(range(self.nPairs))
535
534
536 @property
535 @property
537 def normFactor(self):
536 def normFactor(self):
538
537
539 pwcode = 1
538 pwcode = 1
540
539
541 if self.flagDecodeData:
540 if self.flagDecodeData:
542 pwcode = numpy.sum(self.code[0]**2)
541 pwcode = numpy.sum(self.code[0]**2)
543 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
542 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
544 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
543 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
545
544
546 return normFactor
545 return normFactor
547
546
548 @property
547 @property
549 def flag_cspc(self):
548 def flag_cspc(self):
550
549
551 if self.data_cspc is None:
550 if self.data_cspc is None:
552 return True
551 return True
553
552
554 return False
553 return False
555
554
556 @property
555 @property
557 def flag_dc(self):
556 def flag_dc(self):
558
557
559 if self.data_dc is None:
558 if self.data_dc is None:
560 return True
559 return True
561
560
562 return False
561 return False
563
562
564 @property
563 @property
565 def timeInterval(self):
564 def timeInterval(self):
566
565
567 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
566 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
568 if self.nmodes:
567 if self.nmodes:
569 return self.nmodes*timeInterval
568 return self.nmodes*timeInterval
570 else:
569 else:
571 return timeInterval
570 return timeInterval
572
571
573 def getPower(self):
572 def getPower(self):
574
573
575 factor = self.normFactor
574 factor = self.normFactor
576 z = self.data_spc / factor
575 z = self.data_spc / factor
577 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
576 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
578 avg = numpy.average(z, axis=1)
577 avg = numpy.average(z, axis=1)
579 return 10 * numpy.log10(avg)
578 return 10 * numpy.log10(avg)
580
579
581 def getCoherence(self, pairsList=None, phase=False):
580 def getCoherence(self, pairsList=None, phase=False):
582
581
583 z = []
582 z = []
584 if pairsList is None:
583 if pairsList is None:
585 pairsIndexList = self.pairsIndexList
584 pairsIndexList = self.pairsIndexList
586 else:
585 else:
587 pairsIndexList = []
586 pairsIndexList = []
588 for pair in pairsList:
587 for pair in pairsList:
589 if pair not in self.pairsList:
588 if pair not in self.pairsList:
590 raise ValueError("Pair %s is not in dataOut.pairsList" % (
589 raise ValueError("Pair %s is not in dataOut.pairsList" % (
591 pair))
590 pair))
592 pairsIndexList.append(self.pairsList.index(pair))
591 pairsIndexList.append(self.pairsList.index(pair))
593 for i in range(len(pairsIndexList)):
592 for i in range(len(pairsIndexList)):
594 pair = self.pairsList[pairsIndexList[i]]
593 pair = self.pairsList[pairsIndexList[i]]
595 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
594 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
596 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
595 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
597 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
596 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
598 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
597 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
599 if phase:
598 if phase:
600 data = numpy.arctan2(avgcoherenceComplex.imag,
599 data = numpy.arctan2(avgcoherenceComplex.imag,
601 avgcoherenceComplex.real) * 180 / numpy.pi
600 avgcoherenceComplex.real) * 180 / numpy.pi
602 else:
601 else:
603 data = numpy.abs(avgcoherenceComplex)
602 data = numpy.abs(avgcoherenceComplex)
604
603
605 z.append(data)
604 z.append(data)
606
605
607 return numpy.array(z)
606 return numpy.array(z)
608
607
609 def setValue(self, value):
608 def setValue(self, value):
610
609
611 print("This property should not be initialized")
610 print("This property should not be initialized")
612
611
613 return
612 return
614
613
615 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
614 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
616
615
617
616
618 class SpectraHeis(Spectra):
617 class SpectraHeis(Spectra):
619
618
620 def __init__(self):
619 def __init__(self):
621
620
622 self.radarControllerHeaderObj = RadarControllerHeader()
621 self.radarControllerHeaderObj = RadarControllerHeader()
623 self.systemHeaderObj = SystemHeader()
622 self.systemHeaderObj = SystemHeader()
624 self.type = "SpectraHeis"
623 self.type = "SpectraHeis"
625 self.nProfiles = None
624 self.nProfiles = None
626 self.heightList = None
625 self.heightList = None
627 self.channelList = None
626 self.channelList = None
628 self.flagNoData = True
627 self.flagNoData = True
629 self.flagDiscontinuousBlock = False
628 self.flagDiscontinuousBlock = False
630 self.utctime = None
629 self.utctime = None
631 self.blocksize = None
630 self.blocksize = None
632 self.profileIndex = 0
631 self.profileIndex = 0
633 self.nCohInt = 1
632 self.nCohInt = 1
634 self.nIncohInt = 1
633 self.nIncohInt = 1
635
634
636 @property
635 @property
637 def normFactor(self):
636 def normFactor(self):
638 pwcode = 1
637 pwcode = 1
639 if self.flagDecodeData:
638 if self.flagDecodeData:
640 pwcode = numpy.sum(self.code[0]**2)
639 pwcode = numpy.sum(self.code[0]**2)
641
640
642 normFactor = self.nIncohInt * self.nCohInt * pwcode
641 normFactor = self.nIncohInt * self.nCohInt * pwcode
643
642
644 return normFactor
643 return normFactor
645
644
646 @property
645 @property
647 def timeInterval(self):
646 def timeInterval(self):
648
647
649 return self.ippSeconds * self.nCohInt * self.nIncohInt
648 return self.ippSeconds * self.nCohInt * self.nIncohInt
650
649
651
650
652 class Fits(JROData):
651 class Fits(JROData):
653
652
654 def __init__(self):
653 def __init__(self):
655
654
656 self.type = "Fits"
655 self.type = "Fits"
657 self.nProfiles = None
656 self.nProfiles = None
658 self.heightList = None
657 self.heightList = None
659 self.channelList = None
658 self.channelList = None
660 self.flagNoData = True
659 self.flagNoData = True
661 self.utctime = None
660 self.utctime = None
662 self.nCohInt = 1
661 self.nCohInt = 1
663 self.nIncohInt = 1
662 self.nIncohInt = 1
664 self.useLocalTime = True
663 self.useLocalTime = True
665 self.profileIndex = 0
664 self.profileIndex = 0
666 self.timeZone = 0
665 self.timeZone = 0
667
666
668 def getTimeRange(self):
667 def getTimeRange(self):
669
668
670 datatime = []
669 datatime = []
671
670
672 datatime.append(self.ltctime)
671 datatime.append(self.ltctime)
673 datatime.append(self.ltctime + self.timeInterval)
672 datatime.append(self.ltctime + self.timeInterval)
674
673
675 datatime = numpy.array(datatime)
674 datatime = numpy.array(datatime)
676
675
677 return datatime
676 return datatime
678
677
679 def getChannelIndexList(self):
678 def getChannelIndexList(self):
680
679
681 return list(range(self.nChannels))
680 return list(range(self.nChannels))
682
681
683 def getNoise(self, type=1):
682 def getNoise(self, type=1):
684
683
685
684
686 if type == 1:
685 if type == 1:
687 noise = self.getNoisebyHildebrand()
686 noise = self.getNoisebyHildebrand()
688
687
689 if type == 2:
688 if type == 2:
690 noise = self.getNoisebySort()
689 noise = self.getNoisebySort()
691
690
692 if type == 3:
691 if type == 3:
693 noise = self.getNoisebyWindow()
692 noise = self.getNoisebyWindow()
694
693
695 return noise
694 return noise
696
695
697 @property
696 @property
698 def timeInterval(self):
697 def timeInterval(self):
699
698
700 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
699 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
701
700
702 return timeInterval
701 return timeInterval
703
702
704 @property
703 @property
705 def ippSeconds(self):
704 def ippSeconds(self):
706 '''
705 '''
707 '''
706 '''
708 return self.ipp_sec
707 return self.ipp_sec
709
708
710 noise = property(getNoise, "I'm the 'nHeights' property.")
709 noise = property(getNoise, "I'm the 'nHeights' property.")
711
710
712
711
713 class Correlation(JROData):
712 class Correlation(JROData):
714
713
715 def __init__(self):
714 def __init__(self):
716 '''
715 '''
717 Constructor
716 Constructor
718 '''
717 '''
719 self.radarControllerHeaderObj = RadarControllerHeader()
718 self.radarControllerHeaderObj = RadarControllerHeader()
720 self.systemHeaderObj = SystemHeader()
719 self.systemHeaderObj = SystemHeader()
721 self.type = "Correlation"
720 self.type = "Correlation"
722 self.data = None
721 self.data = None
723 self.dtype = None
722 self.dtype = None
724 self.nProfiles = None
723 self.nProfiles = None
725 self.heightList = None
724 self.heightList = None
726 self.channelList = None
725 self.channelList = None
727 self.flagNoData = True
726 self.flagNoData = True
728 self.flagDiscontinuousBlock = False
727 self.flagDiscontinuousBlock = False
729 self.utctime = None
728 self.utctime = None
730 self.timeZone = 0
729 self.timeZone = 0
731 self.dstFlag = None
730 self.dstFlag = None
732 self.errorCount = None
731 self.errorCount = None
733 self.blocksize = None
732 self.blocksize = None
734 self.flagDecodeData = False # asumo q la data no esta decodificada
733 self.flagDecodeData = False # asumo q la data no esta decodificada
735 self.flagDeflipData = False # asumo q la data no esta sin flip
734 self.flagDeflipData = False # asumo q la data no esta sin flip
736 self.pairsList = None
735 self.pairsList = None
737 self.nPoints = None
736 self.nPoints = None
738
737
739 def getPairsList(self):
738 def getPairsList(self):
740
739
741 return self.pairsList
740 return self.pairsList
742
741
743 def getNoise(self, mode=2):
742 def getNoise(self, mode=2):
744
743
745 indR = numpy.where(self.lagR == 0)[0][0]
744 indR = numpy.where(self.lagR == 0)[0][0]
746 indT = numpy.where(self.lagT == 0)[0][0]
745 indT = numpy.where(self.lagT == 0)[0][0]
747
746
748 jspectra0 = self.data_corr[:, :, indR, :]
747 jspectra0 = self.data_corr[:, :, indR, :]
749 jspectra = copy.copy(jspectra0)
748 jspectra = copy.copy(jspectra0)
750
749
751 num_chan = jspectra.shape[0]
750 num_chan = jspectra.shape[0]
752 num_hei = jspectra.shape[2]
751 num_hei = jspectra.shape[2]
753
752
754 freq_dc = jspectra.shape[1] / 2
753 freq_dc = jspectra.shape[1] / 2
755 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
754 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
756
755
757 if ind_vel[0] < 0:
756 if ind_vel[0] < 0:
758 ind_vel[list(range(0, 1))] = ind_vel[list(
757 ind_vel[list(range(0, 1))] = ind_vel[list(
759 range(0, 1))] + self.num_prof
758 range(0, 1))] + self.num_prof
760
759
761 if mode == 1:
760 if mode == 1:
762 jspectra[:, freq_dc, :] = (
761 jspectra[:, freq_dc, :] = (
763 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
762 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
764
763
765 if mode == 2:
764 if mode == 2:
766
765
767 vel = numpy.array([-2, -1, 1, 2])
766 vel = numpy.array([-2, -1, 1, 2])
768 xx = numpy.zeros([4, 4])
767 xx = numpy.zeros([4, 4])
769
768
770 for fil in range(4):
769 for fil in range(4):
771 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
770 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
772
771
773 xx_inv = numpy.linalg.inv(xx)
772 xx_inv = numpy.linalg.inv(xx)
774 xx_aux = xx_inv[0, :]
773 xx_aux = xx_inv[0, :]
775
774
776 for ich in range(num_chan):
775 for ich in range(num_chan):
777 yy = jspectra[ich, ind_vel, :]
776 yy = jspectra[ich, ind_vel, :]
778 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
777 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
779
778
780 junkid = jspectra[ich, freq_dc, :] <= 0
779 junkid = jspectra[ich, freq_dc, :] <= 0
781 cjunkid = sum(junkid)
780 cjunkid = sum(junkid)
782
781
783 if cjunkid.any():
782 if cjunkid.any():
784 jspectra[ich, freq_dc, junkid.nonzero()] = (
783 jspectra[ich, freq_dc, junkid.nonzero()] = (
785 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
784 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
786
785
787 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
786 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
788
787
789 return noise
788 return noise
790
789
791 @property
790 @property
792 def timeInterval(self):
791 def timeInterval(self):
793
792
794 return self.ippSeconds * self.nCohInt * self.nProfiles
793 return self.ippSeconds * self.nCohInt * self.nProfiles
795
794
796 def splitFunctions(self):
795 def splitFunctions(self):
797
796
798 pairsList = self.pairsList
797 pairsList = self.pairsList
799 ccf_pairs = []
798 ccf_pairs = []
800 acf_pairs = []
799 acf_pairs = []
801 ccf_ind = []
800 ccf_ind = []
802 acf_ind = []
801 acf_ind = []
803 for l in range(len(pairsList)):
802 for l in range(len(pairsList)):
804 chan0 = pairsList[l][0]
803 chan0 = pairsList[l][0]
805 chan1 = pairsList[l][1]
804 chan1 = pairsList[l][1]
806
805
807 # Obteniendo pares de Autocorrelacion
806 # Obteniendo pares de Autocorrelacion
808 if chan0 == chan1:
807 if chan0 == chan1:
809 acf_pairs.append(chan0)
808 acf_pairs.append(chan0)
810 acf_ind.append(l)
809 acf_ind.append(l)
811 else:
810 else:
812 ccf_pairs.append(pairsList[l])
811 ccf_pairs.append(pairsList[l])
813 ccf_ind.append(l)
812 ccf_ind.append(l)
814
813
815 data_acf = self.data_cf[acf_ind]
814 data_acf = self.data_cf[acf_ind]
816 data_ccf = self.data_cf[ccf_ind]
815 data_ccf = self.data_cf[ccf_ind]
817
816
818 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
817 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
819
818
820 @property
819 @property
821 def normFactor(self):
820 def normFactor(self):
822 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
821 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
823 acf_pairs = numpy.array(acf_pairs)
822 acf_pairs = numpy.array(acf_pairs)
824 normFactor = numpy.zeros((self.nPairs, self.nHeights))
823 normFactor = numpy.zeros((self.nPairs, self.nHeights))
825
824
826 for p in range(self.nPairs):
825 for p in range(self.nPairs):
827 pair = self.pairsList[p]
826 pair = self.pairsList[p]
828
827
829 ch0 = pair[0]
828 ch0 = pair[0]
830 ch1 = pair[1]
829 ch1 = pair[1]
831
830
832 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
831 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
833 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
832 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
834 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
833 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
835
834
836 return normFactor
835 return normFactor
837
836
838
837
839 class Parameters(Spectra):
838 class Parameters(Spectra):
840
839
841 groupList = None # List of Pairs, Groups, etc
840 groupList = None # List of Pairs, Groups, etc
842 data_param = None # Parameters obtained
841 data_param = None # Parameters obtained
843 data_pre = None # Data Pre Parametrization
842 data_pre = None # Data Pre Parametrization
844 data_SNR = None # Signal to Noise Ratio
843 data_SNR = None # Signal to Noise Ratio
845 abscissaList = None # Abscissa, can be velocities, lags or time
844 abscissaList = None # Abscissa, can be velocities, lags or time
846 utctimeInit = None # Initial UTC time
845 utctimeInit = None # Initial UTC time
847 paramInterval = None # Time interval to calculate Parameters in seconds
846 paramInterval = None # Time interval to calculate Parameters in seconds
848 useLocalTime = True
847 useLocalTime = True
849 # Fitting
848 # Fitting
850 data_error = None # Error of the estimation
849 data_error = None # Error of the estimation
851 constants = None
850 constants = None
852 library = None
851 library = None
853 # Output signal
852 # Output signal
854 outputInterval = None # Time interval to calculate output signal in seconds
853 outputInterval = None # Time interval to calculate output signal in seconds
855 data_output = None # Out signal
854 data_output = None # Out signal
856 nAvg = None
855 nAvg = None
857 noise_estimation = None
856 noise_estimation = None
858 GauSPC = None # Fit gaussian SPC
857 GauSPC = None # Fit gaussian SPC
859
858
860 def __init__(self):
859 def __init__(self):
861 '''
860 '''
862 Constructor
861 Constructor
863 '''
862 '''
864 self.radarControllerHeaderObj = RadarControllerHeader()
863 self.radarControllerHeaderObj = RadarControllerHeader()
865 self.systemHeaderObj = SystemHeader()
864 self.systemHeaderObj = SystemHeader()
866 self.type = "Parameters"
865 self.type = "Parameters"
867 self.timeZone = 0
866 self.timeZone = 0
868
867
869 def getTimeRange1(self, interval):
868 def getTimeRange1(self, interval):
870
869
871 datatime = []
870 datatime = []
872
871
873 if self.useLocalTime:
872 if self.useLocalTime:
874 time1 = self.utctimeInit - self.timeZone * 60
873 time1 = self.utctimeInit - self.timeZone * 60
875 else:
874 else:
876 time1 = self.utctimeInit
875 time1 = self.utctimeInit
877
876
878 datatime.append(time1)
877 datatime.append(time1)
879 datatime.append(time1 + interval)
878 datatime.append(time1 + interval)
880 datatime = numpy.array(datatime)
879 datatime = numpy.array(datatime)
881
880
882 return datatime
881 return datatime
883
882
884 @property
883 @property
885 def timeInterval(self):
884 def timeInterval(self):
886
885
887 if hasattr(self, 'timeInterval1'):
886 if hasattr(self, 'timeInterval1'):
888 return self.timeInterval1
887 return self.timeInterval1
889 else:
888 else:
890 return self.paramInterval
889 return self.paramInterval
891
890
892 def setValue(self, value):
891 def setValue(self, value):
893
892
894 print("This property should not be initialized")
893 print("This property should not be initialized")
895
894
896 return
895 return
897
896
898 def getNoise(self):
897 def getNoise(self):
899
898
900 return self.spc_noise
899 return self.spc_noise
901
900
902 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
901 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
903
902
904
903
905 class PlotterData(object):
904 class PlotterData(object):
906 '''
905 '''
907 Object to hold data to be plotted
906 Object to hold data to be plotted
908 '''
907 '''
909
908
910 MAXNUMX = 1000
909 MAXNUMX = 1000
911 MAXNUMY = 1000
910 MAXNUMY = 1000
912
911
913 def __init__(self, code, exp_code, localtime=True):
912 def __init__(self, code, exp_code, localtime=True):
914
913
915 self.key = code
914 self.key = code
916 self.exp_code = exp_code
915 self.exp_code = exp_code
917 self.ready = False
916 self.ready = False
918 self.flagNoData = False
917 self.flagNoData = False
919 self.localtime = localtime
918 self.localtime = localtime
920 self.data = {}
919 self.data = {}
921 self.meta = {}
920 self.meta = {}
922 self.__heights = []
921 self.__heights = []
923
922
924 def __str__(self):
923 def __str__(self):
925 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
924 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
926 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
925 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
927
926
928 def __len__(self):
927 def __len__(self):
929 return len(self.data)
928 return len(self.data)
930
929
931 def __getitem__(self, key):
930 def __getitem__(self, key):
932 if isinstance(key, int):
931 if isinstance(key, int):
933 return self.data[self.times[key]]
932 return self.data[self.times[key]]
934 elif isinstance(key, str):
933 elif isinstance(key, str):
935 ret = numpy.array([self.data[x][key] for x in self.times])
934 ret = numpy.array([self.data[x][key] for x in self.times])
936 if ret.ndim > 1:
935 if ret.ndim > 1:
937 ret = numpy.swapaxes(ret, 0, 1)
936 ret = numpy.swapaxes(ret, 0, 1)
938 return ret
937 return ret
939
938
940 def __contains__(self, key):
939 def __contains__(self, key):
941 return key in self.data[self.min_time]
940 return key in self.data[self.min_time]
942
941
943 def setup(self):
942 def setup(self):
944 '''
943 '''
945 Configure object
944 Configure object
946 '''
945 '''
947 self.type = ''
946 self.type = ''
948 self.ready = False
947 self.ready = False
949 del self.data
948 del self.data
950 self.data = {}
949 self.data = {}
951 self.__heights = []
950 self.__heights = []
952 self.__all_heights = set()
951 self.__all_heights = set()
953
952
954 def shape(self, key):
953 def shape(self, key):
955 '''
954 '''
956 Get the shape of the one-element data for the given key
955 Get the shape of the one-element data for the given key
957 '''
956 '''
958
957
959 if len(self.data[self.min_time][key]):
958 if len(self.data[self.min_time][key]):
960 return self.data[self.min_time][key].shape
959 return self.data[self.min_time][key].shape
961 return (0,)
960 return (0,)
962
961
963 def update(self, data, tm, meta={}):
962 def update(self, data, tm, meta={}):
964 '''
963 '''
965 Update data object with new dataOut
964 Update data object with new dataOut
966 '''
965 '''
967
966
968 self.data[tm] = data
967 self.data[tm] = data
969
968
970 for key, value in meta.items():
969 for key, value in meta.items():
971 setattr(self, key, value)
970 setattr(self, key, value)
972
971
973 def normalize_heights(self):
972 def normalize_heights(self):
974 '''
973 '''
975 Ensure same-dimension of the data for different heighList
974 Ensure same-dimension of the data for different heighList
976 '''
975 '''
977
976
978 H = numpy.array(list(self.__all_heights))
977 H = numpy.array(list(self.__all_heights))
979 H.sort()
978 H.sort()
980 for key in self.data:
979 for key in self.data:
981 shape = self.shape(key)[:-1] + H.shape
980 shape = self.shape(key)[:-1] + H.shape
982 for tm, obj in list(self.data[key].items()):
981 for tm, obj in list(self.data[key].items()):
983 h = self.__heights[self.times.tolist().index(tm)]
982 h = self.__heights[self.times.tolist().index(tm)]
984 if H.size == h.size:
983 if H.size == h.size:
985 continue
984 continue
986 index = numpy.where(numpy.in1d(H, h))[0]
985 index = numpy.where(numpy.in1d(H, h))[0]
987 dummy = numpy.zeros(shape) + numpy.nan
986 dummy = numpy.zeros(shape) + numpy.nan
988 if len(shape) == 2:
987 if len(shape) == 2:
989 dummy[:, index] = obj
988 dummy[:, index] = obj
990 else:
989 else:
991 dummy[index] = obj
990 dummy[index] = obj
992 self.data[key][tm] = dummy
991 self.data[key][tm] = dummy
993
992
994 self.__heights = [H for tm in self.times]
993 self.__heights = [H for tm in self.times]
995
994
996 def jsonify(self, tm, plot_name, plot_type, key=None, decimate=False):
995 def jsonify(self, tm, plot_name, plot_type, key=None, decimate=False):
997 '''
996 '''
998 Convert data to json
997 Convert data to json
999 '''
998 '''
1000
999
1001 if key is None:
1000 if key is None:
1002 key = self.key
1001 key = self.key
1003
1002
1004 meta = {}
1003 meta = {}
1005 meta['xrange'] = []
1004 meta['xrange'] = []
1006 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1005 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1007 tmp = self.data[tm][key]
1006 tmp = self.data[tm][key]
1008 shape = tmp.shape
1007 shape = tmp.shape
1009 if len(shape) == 2:
1008 if len(shape) == 2:
1010 data = self.roundFloats(self.data[tm][key][::, ::dy].tolist())
1009 data = self.roundFloats(self.data[tm][key][::, ::dy].tolist())
1011 elif len(shape) == 3:
1010 elif len(shape) == 3:
1012 dx = int(self.data[tm][key].shape[1]/self.MAXNUMX) + 1
1011 dx = int(self.data[tm][key].shape[1]/self.MAXNUMX) + 1
1013 data = self.roundFloats(
1012 data = self.roundFloats(
1014 self.data[tm][key][::, ::dx, ::dy].tolist())
1013 self.data[tm][key][::, ::dx, ::dy].tolist())
1015 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1014 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1016 else:
1015 else:
1017 data = self.roundFloats(self.data[tm][key].tolist())
1016 data = self.roundFloats(self.data[tm][key].tolist())
1018
1017
1019 ret = {
1018 ret = {
1020 'plot': plot_name,
1019 'plot': plot_name,
1021 'code': self.exp_code,
1020 'code': self.exp_code,
1022 'time': float(tm),
1021 'time': float(tm),
1023 'data': data,
1022 'data': data,
1024 }
1023 }
1025 meta['type'] = plot_type
1024 meta['type'] = plot_type
1026 meta['interval'] = float(self.interval)
1025 meta['interval'] = float(self.interval)
1027 meta['localtime'] = self.localtime
1026 meta['localtime'] = self.localtime
1028 #meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1027 #meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1029 meta['yrange'] = self.roundFloats(self.lat[::dy].tolist())
1028 meta['yrange'] = self.roundFloats(self.lat[::dy].tolist())
1030 meta['xrange'] = self.roundFloats(self.lon[::dy].tolist())
1029 meta['xrange'] = self.roundFloats(self.lon[::dy].tolist())
1031 meta.update(self.meta)
1030 meta.update(self.meta)
1032 ret['metadata'] = meta
1031 ret['metadata'] = meta
1033 return json.dumps(ret)
1032 return json.dumps(ret)
1034
1033
1035 @property
1034 @property
1036 def times(self):
1035 def times(self):
1037 '''
1036 '''
1038 Return the list of times of the current data
1037 Return the list of times of the current data
1039 '''
1038 '''
1040
1039
1041 ret = [t for t in self.data]
1040 ret = [t for t in self.data]
1042 ret.sort()
1041 ret.sort()
1043 return numpy.array(ret)
1042 return numpy.array(ret)
1044
1043
1045 @property
1044 @property
1046 def min_time(self):
1045 def min_time(self):
1047 '''
1046 '''
1048 Return the minimun time value
1047 Return the minimun time value
1049 '''
1048 '''
1050
1049
1051 return self.times[0]
1050 return self.times[0]
1052
1051
1053 @property
1052 @property
1054 def max_time(self):
1053 def max_time(self):
1055 '''
1054 '''
1056 Return the maximun time value
1055 Return the maximun time value
1057 '''
1056 '''
1058
1057
1059 return self.times[-1]
1058 return self.times[-1]
1060
1059
1061 # @property
1060 # @property
1062 # def heights(self):
1061 # def heights(self):
1063 # '''
1062 # '''
1064 # Return the list of heights of the current data
1063 # Return the list of heights of the current data
1065 # '''
1064 # '''
1066
1065
1067 # return numpy.array(self.__heights[-1])
1066 # return numpy.array(self.__heights[-1])
1068
1067
1069 @staticmethod
1068 @staticmethod
1070 def roundFloats(obj):
1069 def roundFloats(obj):
1071 if isinstance(obj, list):
1070 if isinstance(obj, list):
1072 return list(map(PlotterData.roundFloats, obj))
1071 return list(map(PlotterData.roundFloats, obj))
1073 elif isinstance(obj, float):
1072 elif isinstance(obj, float):
1074 return round(obj, 4)
1073 return round(obj, 4)
General Comments 0
You need to be logged in to leave comments. Login now