##// END OF EJS Templates
Correct localtime in plots, handle exception in send_to_server
Juan C. Espinoza -
r1327:e2336f44bb45
parent child
Show More
@@ -1,1402 +1,1400
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 import schainpy.admin
12 import schainpy.admin
13 from schainpy.utils import log
13 from schainpy.utils import log
14 from .jroheaderIO import SystemHeader, RadarControllerHeader
14 from .jroheaderIO import SystemHeader, RadarControllerHeader
15 from schainpy.model.data import _noise
15 from schainpy.model.data import _noise
16
16
17
17
18 def getNumpyDtype(dataTypeCode):
18 def getNumpyDtype(dataTypeCode):
19
19
20 if dataTypeCode == 0:
20 if dataTypeCode == 0:
21 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
21 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
22 elif dataTypeCode == 1:
22 elif dataTypeCode == 1:
23 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
23 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
24 elif dataTypeCode == 2:
24 elif dataTypeCode == 2:
25 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
25 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
26 elif dataTypeCode == 3:
26 elif dataTypeCode == 3:
27 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
27 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
28 elif dataTypeCode == 4:
28 elif dataTypeCode == 4:
29 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
29 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
30 elif dataTypeCode == 5:
30 elif dataTypeCode == 5:
31 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
31 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
32 else:
32 else:
33 raise ValueError('dataTypeCode was not defined')
33 raise ValueError('dataTypeCode was not defined')
34
34
35 return numpyDtype
35 return numpyDtype
36
36
37
37
38 def getDataTypeCode(numpyDtype):
38 def getDataTypeCode(numpyDtype):
39
39
40 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
40 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
41 datatype = 0
41 datatype = 0
42 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
42 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
43 datatype = 1
43 datatype = 1
44 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
44 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
45 datatype = 2
45 datatype = 2
46 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
46 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
47 datatype = 3
47 datatype = 3
48 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
48 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
49 datatype = 4
49 datatype = 4
50 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
50 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
51 datatype = 5
51 datatype = 5
52 else:
52 else:
53 datatype = None
53 datatype = None
54
54
55 return datatype
55 return datatype
56
56
57
57
58 def hildebrand_sekhon(data, navg):
58 def hildebrand_sekhon(data, navg):
59 """
59 """
60 This method is for the objective determination of the noise level in Doppler spectra. This
60 This method is for the objective determination of the noise level in Doppler spectra. This
61 implementation technique is based on the fact that the standard deviation of the spectral
61 implementation technique is based on the fact that the standard deviation of the spectral
62 densities is equal to the mean spectral density for white Gaussian noise
62 densities is equal to the mean spectral density for white Gaussian noise
63
63
64 Inputs:
64 Inputs:
65 Data : heights
65 Data : heights
66 navg : numbers of averages
66 navg : numbers of averages
67
67
68 Return:
68 Return:
69 mean : noise's level
69 mean : noise's level
70 """
70 """
71
71
72 sortdata = numpy.sort(data, axis=None)
72 sortdata = numpy.sort(data, axis=None)
73 '''
73 '''
74 lenOfData = len(sortdata)
74 lenOfData = len(sortdata)
75 nums_min = lenOfData*0.2
75 nums_min = lenOfData*0.2
76
76
77 if nums_min <= 5:
77 if nums_min <= 5:
78
78
79 nums_min = 5
79 nums_min = 5
80
80
81 sump = 0.
81 sump = 0.
82 sumq = 0.
82 sumq = 0.
83
83
84 j = 0
84 j = 0
85 cont = 1
85 cont = 1
86
86
87 while((cont == 1)and(j < lenOfData)):
87 while((cont == 1)and(j < lenOfData)):
88
88
89 sump += sortdata[j]
89 sump += sortdata[j]
90 sumq += sortdata[j]**2
90 sumq += sortdata[j]**2
91
91
92 if j > nums_min:
92 if j > nums_min:
93 rtest = float(j)/(j-1) + 1.0/navg
93 rtest = float(j)/(j-1) + 1.0/navg
94 if ((sumq*j) > (rtest*sump**2)):
94 if ((sumq*j) > (rtest*sump**2)):
95 j = j - 1
95 j = j - 1
96 sump = sump - sortdata[j]
96 sump = sump - sortdata[j]
97 sumq = sumq - sortdata[j]**2
97 sumq = sumq - sortdata[j]**2
98 cont = 0
98 cont = 0
99
99
100 j += 1
100 j += 1
101
101
102 lnoise = sump / j
102 lnoise = sump / j
103 '''
103 '''
104 return _noise.hildebrand_sekhon(sortdata, navg)
104 return _noise.hildebrand_sekhon(sortdata, navg)
105
105
106
106
107 class Beam:
107 class Beam:
108
108
109 def __init__(self):
109 def __init__(self):
110 self.codeList = []
110 self.codeList = []
111 self.azimuthList = []
111 self.azimuthList = []
112 self.zenithList = []
112 self.zenithList = []
113
113
114
114
115 class GenericData(object):
115 class GenericData(object):
116
116
117 flagNoData = True
117 flagNoData = True
118
118
119 def copy(self, inputObj=None):
119 def copy(self, inputObj=None):
120
120
121 if inputObj == None:
121 if inputObj == None:
122 return copy.deepcopy(self)
122 return copy.deepcopy(self)
123
123
124 for key in list(inputObj.__dict__.keys()):
124 for key in list(inputObj.__dict__.keys()):
125
125
126 attribute = inputObj.__dict__[key]
126 attribute = inputObj.__dict__[key]
127
127
128 # If this attribute is a tuple or list
128 # If this attribute is a tuple or list
129 if type(inputObj.__dict__[key]) in (tuple, list):
129 if type(inputObj.__dict__[key]) in (tuple, list):
130 self.__dict__[key] = attribute[:]
130 self.__dict__[key] = attribute[:]
131 continue
131 continue
132
132
133 # If this attribute is another object or instance
133 # If this attribute is another object or instance
134 if hasattr(attribute, '__dict__'):
134 if hasattr(attribute, '__dict__'):
135 self.__dict__[key] = attribute.copy()
135 self.__dict__[key] = attribute.copy()
136 continue
136 continue
137
137
138 self.__dict__[key] = inputObj.__dict__[key]
138 self.__dict__[key] = inputObj.__dict__[key]
139
139
140 def deepcopy(self):
140 def deepcopy(self):
141
141
142 return copy.deepcopy(self)
142 return copy.deepcopy(self)
143
143
144 def isEmpty(self):
144 def isEmpty(self):
145
145
146 return self.flagNoData
146 return self.flagNoData
147
147
148 def isReady(self):
148 def isReady(self):
149
149
150 return not self.flagNoData
150 return not self.flagNoData
151
151
152
152
153 class JROData(GenericData):
153 class JROData(GenericData):
154
154
155 # m_BasicHeader = BasicHeader()
155 # m_BasicHeader = BasicHeader()
156 # m_ProcessingHeader = ProcessingHeader()
156 # m_ProcessingHeader = ProcessingHeader()
157
157
158 systemHeaderObj = SystemHeader()
158 systemHeaderObj = SystemHeader()
159 radarControllerHeaderObj = RadarControllerHeader()
159 radarControllerHeaderObj = RadarControllerHeader()
160 # data = None
160 # data = None
161 type = None
161 type = None
162 datatype = None # dtype but in string
162 datatype = None # dtype but in string
163 # dtype = None
163 # dtype = None
164 # nChannels = None
164 # nChannels = None
165 # nHeights = None
165 # nHeights = None
166 nProfiles = None
166 nProfiles = None
167 heightList = None
167 heightList = None
168 channelList = None
168 channelList = None
169 flagDiscontinuousBlock = False
169 flagDiscontinuousBlock = False
170 useLocalTime = False
170 useLocalTime = False
171 utctime = None
171 utctime = None
172 timeZone = None
172 timeZone = None
173 dstFlag = None
173 dstFlag = None
174 errorCount = None
174 errorCount = None
175 blocksize = None
175 blocksize = None
176 # nCode = None
176 # nCode = None
177 # nBaud = None
177 # nBaud = None
178 # code = None
178 # code = None
179 flagDecodeData = False # asumo q la data no esta decodificada
179 flagDecodeData = False # asumo q la data no esta decodificada
180 flagDeflipData = False # asumo q la data no esta sin flip
180 flagDeflipData = False # asumo q la data no esta sin flip
181 flagShiftFFT = False
181 flagShiftFFT = False
182 # ippSeconds = None
182 # ippSeconds = None
183 # timeInterval = None
183 # timeInterval = None
184 nCohInt = None
184 nCohInt = None
185 # noise = None
185 # noise = None
186 windowOfFilter = 1
186 windowOfFilter = 1
187 # Speed of ligth
187 # Speed of ligth
188 C = 3e8
188 C = 3e8
189 frequency = 49.92e6
189 frequency = 49.92e6
190 realtime = False
190 realtime = False
191 beacon_heiIndexList = None
191 beacon_heiIndexList = None
192 last_block = None
192 last_block = None
193 blocknow = None
193 blocknow = None
194 azimuth = None
194 azimuth = None
195 zenith = None
195 zenith = None
196 beam = Beam()
196 beam = Beam()
197 profileIndex = None
197 profileIndex = None
198 error = None
198 error = None
199 data = None
199 data = None
200 nmodes = None
200 nmodes = None
201
201
202 def __str__(self):
202 def __str__(self):
203
203
204 return '{} - {}'.format(self.type, self.getDatatime())
204 return '{} - {}'.format(self.type, self.getDatatime())
205
205
206 def getNoise(self):
206 def getNoise(self):
207
207
208 raise NotImplementedError
208 raise NotImplementedError
209
209
210 def getNChannels(self):
210 def getNChannels(self):
211
211
212 return len(self.channelList)
212 return len(self.channelList)
213
213
214 def getChannelIndexList(self):
214 def getChannelIndexList(self):
215
215
216 return list(range(self.nChannels))
216 return list(range(self.nChannels))
217
217
218 def getNHeights(self):
218 def getNHeights(self):
219
219
220 return len(self.heightList)
220 return len(self.heightList)
221
221
222 def getHeiRange(self, extrapoints=0):
222 def getHeiRange(self, extrapoints=0):
223
223
224 heis = self.heightList
224 heis = self.heightList
225 # deltah = self.heightList[1] - self.heightList[0]
225 # deltah = self.heightList[1] - self.heightList[0]
226 #
226 #
227 # heis.append(self.heightList[-1])
227 # heis.append(self.heightList[-1])
228
228
229 return heis
229 return heis
230
230
231 def getDeltaH(self):
231 def getDeltaH(self):
232
232
233 delta = self.heightList[1] - self.heightList[0]
233 delta = self.heightList[1] - self.heightList[0]
234
234
235 return delta
235 return delta
236
236
237 def getltctime(self):
237 def getltctime(self):
238
238
239 if self.useLocalTime:
239 if self.useLocalTime:
240 return self.utctime - self.timeZone * 60
240 return self.utctime - self.timeZone * 60
241
241
242 return self.utctime
242 return self.utctime
243
243
244 def getDatatime(self):
244 def getDatatime(self):
245
245
246 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
246 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
247 return datatimeValue
247 return datatimeValue
248
248
249 def getTimeRange(self):
249 def getTimeRange(self):
250
250
251 datatime = []
251 datatime = []
252
252
253 datatime.append(self.ltctime)
253 datatime.append(self.ltctime)
254 datatime.append(self.ltctime + self.timeInterval + 1)
254 datatime.append(self.ltctime + self.timeInterval + 1)
255
255
256 datatime = numpy.array(datatime)
256 datatime = numpy.array(datatime)
257
257
258 return datatime
258 return datatime
259
259
260 def getFmaxTimeResponse(self):
260 def getFmaxTimeResponse(self):
261
261
262 period = (10**-6) * self.getDeltaH() / (0.15)
262 period = (10**-6) * self.getDeltaH() / (0.15)
263
263
264 PRF = 1. / (period * self.nCohInt)
264 PRF = 1. / (period * self.nCohInt)
265
265
266 fmax = PRF
266 fmax = PRF
267
267
268 return fmax
268 return fmax
269
269
270 def getFmax(self):
270 def getFmax(self):
271 PRF = 1. / (self.ippSeconds * self.nCohInt)
271 PRF = 1. / (self.ippSeconds * self.nCohInt)
272
272
273 fmax = PRF
273 fmax = PRF
274 return fmax
274 return fmax
275
275
276 def getVmax(self):
276 def getVmax(self):
277
277
278 _lambda = self.C / self.frequency
278 _lambda = self.C / self.frequency
279
279
280 vmax = self.getFmax() * _lambda / 2
280 vmax = self.getFmax() * _lambda / 2
281
281
282 return vmax
282 return vmax
283
283
284 def get_ippSeconds(self):
284 def get_ippSeconds(self):
285 '''
285 '''
286 '''
286 '''
287 return self.radarControllerHeaderObj.ippSeconds
287 return self.radarControllerHeaderObj.ippSeconds
288
288
289 def set_ippSeconds(self, ippSeconds):
289 def set_ippSeconds(self, ippSeconds):
290 '''
290 '''
291 '''
291 '''
292
292
293 self.radarControllerHeaderObj.ippSeconds = ippSeconds
293 self.radarControllerHeaderObj.ippSeconds = ippSeconds
294
294
295 return
295 return
296
296
297 def get_dtype(self):
297 def get_dtype(self):
298 '''
298 '''
299 '''
299 '''
300 return getNumpyDtype(self.datatype)
300 return getNumpyDtype(self.datatype)
301
301
302 def set_dtype(self, numpyDtype):
302 def set_dtype(self, numpyDtype):
303 '''
303 '''
304 '''
304 '''
305
305
306 self.datatype = getDataTypeCode(numpyDtype)
306 self.datatype = getDataTypeCode(numpyDtype)
307
307
308 def get_code(self):
308 def get_code(self):
309 '''
309 '''
310 '''
310 '''
311 return self.radarControllerHeaderObj.code
311 return self.radarControllerHeaderObj.code
312
312
313 def set_code(self, code):
313 def set_code(self, code):
314 '''
314 '''
315 '''
315 '''
316 self.radarControllerHeaderObj.code = code
316 self.radarControllerHeaderObj.code = code
317
317
318 return
318 return
319
319
320 def get_ncode(self):
320 def get_ncode(self):
321 '''
321 '''
322 '''
322 '''
323 return self.radarControllerHeaderObj.nCode
323 return self.radarControllerHeaderObj.nCode
324
324
325 def set_ncode(self, nCode):
325 def set_ncode(self, nCode):
326 '''
326 '''
327 '''
327 '''
328 self.radarControllerHeaderObj.nCode = nCode
328 self.radarControllerHeaderObj.nCode = nCode
329
329
330 return
330 return
331
331
332 def get_nbaud(self):
332 def get_nbaud(self):
333 '''
333 '''
334 '''
334 '''
335 return self.radarControllerHeaderObj.nBaud
335 return self.radarControllerHeaderObj.nBaud
336
336
337 def set_nbaud(self, nBaud):
337 def set_nbaud(self, nBaud):
338 '''
338 '''
339 '''
339 '''
340 self.radarControllerHeaderObj.nBaud = nBaud
340 self.radarControllerHeaderObj.nBaud = nBaud
341
341
342 return
342 return
343
343
344 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
344 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
345 channelIndexList = property(
345 channelIndexList = property(
346 getChannelIndexList, "I'm the 'channelIndexList' property.")
346 getChannelIndexList, "I'm the 'channelIndexList' property.")
347 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
347 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
348 #noise = property(getNoise, "I'm the 'nHeights' property.")
348 #noise = property(getNoise, "I'm the 'nHeights' property.")
349 datatime = property(getDatatime, "I'm the 'datatime' property")
349 datatime = property(getDatatime, "I'm the 'datatime' property")
350 ltctime = property(getltctime, "I'm the 'ltctime' property")
350 ltctime = property(getltctime, "I'm the 'ltctime' property")
351 ippSeconds = property(get_ippSeconds, set_ippSeconds)
351 ippSeconds = property(get_ippSeconds, set_ippSeconds)
352 dtype = property(get_dtype, set_dtype)
352 dtype = property(get_dtype, set_dtype)
353 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
353 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
354 code = property(get_code, set_code)
354 code = property(get_code, set_code)
355 nCode = property(get_ncode, set_ncode)
355 nCode = property(get_ncode, set_ncode)
356 nBaud = property(get_nbaud, set_nbaud)
356 nBaud = property(get_nbaud, set_nbaud)
357
357
358
358
359 class Voltage(JROData):
359 class Voltage(JROData):
360
360
361 # data es un numpy array de 2 dmensiones (canales, alturas)
361 # data es un numpy array de 2 dmensiones (canales, alturas)
362 data = None
362 data = None
363 dataPP_POW = None
363 dataPP_POW = None
364 dataPP_DOP = None
364 dataPP_DOP = None
365 dataPP_WIDTH = None
365 dataPP_WIDTH = None
366 dataPP_SNR = None
366 dataPP_SNR = None
367
367
368 def __init__(self):
368 def __init__(self):
369 '''
369 '''
370 Constructor
370 Constructor
371 '''
371 '''
372
372
373 self.useLocalTime = True
373 self.useLocalTime = True
374 self.radarControllerHeaderObj = RadarControllerHeader()
374 self.radarControllerHeaderObj = RadarControllerHeader()
375 self.systemHeaderObj = SystemHeader()
375 self.systemHeaderObj = SystemHeader()
376 self.type = "Voltage"
376 self.type = "Voltage"
377 self.data = None
377 self.data = None
378 # self.dtype = None
378 # self.dtype = None
379 # self.nChannels = 0
379 # self.nChannels = 0
380 # self.nHeights = 0
380 # self.nHeights = 0
381 self.nProfiles = None
381 self.nProfiles = None
382 self.heightList = None
382 self.heightList = None
383 self.channelList = None
383 self.channelList = None
384 # self.channelIndexList = None
384 # self.channelIndexList = None
385 self.flagNoData = True
385 self.flagNoData = True
386 self.flagDiscontinuousBlock = False
386 self.flagDiscontinuousBlock = False
387 self.utctime = None
387 self.utctime = None
388 self.timeZone = 0
388 self.timeZone = 0
389 self.dstFlag = None
389 self.dstFlag = None
390 self.errorCount = None
390 self.errorCount = None
391 self.nCohInt = None
391 self.nCohInt = None
392 self.blocksize = None
392 self.blocksize = None
393 self.flagCohInt = False
393 self.flagCohInt = False
394 self.flagDecodeData = False # asumo q la data no esta decodificada
394 self.flagDecodeData = False # asumo q la data no esta decodificada
395 self.flagDeflipData = False # asumo q la data no esta sin flip
395 self.flagDeflipData = False # asumo q la data no esta sin flip
396 self.flagShiftFFT = False
396 self.flagShiftFFT = False
397 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
397 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
398 self.profileIndex = 0
398 self.profileIndex = 0
399
399
400 def getNoisebyHildebrand(self, channel=None):
400 def getNoisebyHildebrand(self, channel=None):
401 """
401 """
402 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
402 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
403
403
404 Return:
404 Return:
405 noiselevel
405 noiselevel
406 """
406 """
407
407
408 if channel != None:
408 if channel != None:
409 data = self.data[channel]
409 data = self.data[channel]
410 nChannels = 1
410 nChannels = 1
411 else:
411 else:
412 data = self.data
412 data = self.data
413 nChannels = self.nChannels
413 nChannels = self.nChannels
414
414
415 noise = numpy.zeros(nChannels)
415 noise = numpy.zeros(nChannels)
416 power = data * numpy.conjugate(data)
416 power = data * numpy.conjugate(data)
417
417
418 for thisChannel in range(nChannels):
418 for thisChannel in range(nChannels):
419 if nChannels == 1:
419 if nChannels == 1:
420 daux = power[:].real
420 daux = power[:].real
421 else:
421 else:
422 daux = power[thisChannel, :].real
422 daux = power[thisChannel, :].real
423 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
423 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
424
424
425 return noise
425 return noise
426
426
427 def getNoise(self, type=1, channel=None):
427 def getNoise(self, type=1, channel=None):
428
428
429 if type == 1:
429 if type == 1:
430 noise = self.getNoisebyHildebrand(channel)
430 noise = self.getNoisebyHildebrand(channel)
431
431
432 return noise
432 return noise
433
433
434 def getPower(self, channel=None):
434 def getPower(self, channel=None):
435
435
436 if channel != None:
436 if channel != None:
437 data = self.data[channel]
437 data = self.data[channel]
438 else:
438 else:
439 data = self.data
439 data = self.data
440
440
441 power = data * numpy.conjugate(data)
441 power = data * numpy.conjugate(data)
442 powerdB = 10 * numpy.log10(power.real)
442 powerdB = 10 * numpy.log10(power.real)
443 powerdB = numpy.squeeze(powerdB)
443 powerdB = numpy.squeeze(powerdB)
444
444
445 return powerdB
445 return powerdB
446
446
447 def getTimeInterval(self):
447 def getTimeInterval(self):
448
448
449 timeInterval = self.ippSeconds * self.nCohInt
449 timeInterval = self.ippSeconds * self.nCohInt
450
450
451 return timeInterval
451 return timeInterval
452
452
453 noise = property(getNoise, "I'm the 'nHeights' property.")
453 noise = property(getNoise, "I'm the 'nHeights' property.")
454 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
454 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
455
455
456
456
457 class Spectra(JROData):
457 class Spectra(JROData):
458
458
459 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
459 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
460 data_spc = None
460 data_spc = None
461 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
461 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
462 data_cspc = None
462 data_cspc = None
463 # data dc es un numpy array de 2 dmensiones (canales, alturas)
463 # data dc es un numpy array de 2 dmensiones (canales, alturas)
464 data_dc = None
464 data_dc = None
465 # data power
465 # data power
466 data_pwr = None
466 data_pwr = None
467 nFFTPoints = None
467 nFFTPoints = None
468 # nPairs = None
468 # nPairs = None
469 pairsList = None
469 pairsList = None
470 nIncohInt = None
470 nIncohInt = None
471 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
471 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
472 nCohInt = None # se requiere para determinar el valor de timeInterval
472 nCohInt = None # se requiere para determinar el valor de timeInterval
473 ippFactor = None
473 ippFactor = None
474 profileIndex = 0
474 profileIndex = 0
475 plotting = "spectra"
475 plotting = "spectra"
476
476
477 def __init__(self):
477 def __init__(self):
478 '''
478 '''
479 Constructor
479 Constructor
480 '''
480 '''
481
481
482 self.useLocalTime = True
482 self.useLocalTime = True
483 self.radarControllerHeaderObj = RadarControllerHeader()
483 self.radarControllerHeaderObj = RadarControllerHeader()
484 self.systemHeaderObj = SystemHeader()
484 self.systemHeaderObj = SystemHeader()
485 self.type = "Spectra"
485 self.type = "Spectra"
486 self.timeZone = 0
486 self.timeZone = 0
487 # self.data = None
487 # self.data = None
488 # self.dtype = None
488 # self.dtype = None
489 # self.nChannels = 0
489 # self.nChannels = 0
490 # self.nHeights = 0
490 # self.nHeights = 0
491 self.nProfiles = None
491 self.nProfiles = None
492 self.heightList = None
492 self.heightList = None
493 self.channelList = None
493 self.channelList = None
494 # self.channelIndexList = None
494 # self.channelIndexList = None
495 self.pairsList = None
495 self.pairsList = None
496 self.flagNoData = True
496 self.flagNoData = True
497 self.flagDiscontinuousBlock = False
497 self.flagDiscontinuousBlock = False
498 self.utctime = None
498 self.utctime = None
499 self.nCohInt = None
499 self.nCohInt = None
500 self.nIncohInt = None
500 self.nIncohInt = None
501 self.blocksize = None
501 self.blocksize = None
502 self.nFFTPoints = None
502 self.nFFTPoints = None
503 self.wavelength = None
503 self.wavelength = None
504 self.flagDecodeData = False # asumo q la data no esta decodificada
504 self.flagDecodeData = False # asumo q la data no esta decodificada
505 self.flagDeflipData = False # asumo q la data no esta sin flip
505 self.flagDeflipData = False # asumo q la data no esta sin flip
506 self.flagShiftFFT = False
506 self.flagShiftFFT = False
507 self.ippFactor = 1
507 self.ippFactor = 1
508 #self.noise = None
508 #self.noise = None
509 self.beacon_heiIndexList = []
509 self.beacon_heiIndexList = []
510 self.noise_estimation = None
510 self.noise_estimation = None
511
511
512 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
512 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
513 """
513 """
514 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
514 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
515
515
516 Return:
516 Return:
517 noiselevel
517 noiselevel
518 """
518 """
519
519
520 noise = numpy.zeros(self.nChannels)
520 noise = numpy.zeros(self.nChannels)
521
521
522 for channel in range(self.nChannels):
522 for channel in range(self.nChannels):
523 daux = self.data_spc[channel,
523 daux = self.data_spc[channel,
524 xmin_index:xmax_index, ymin_index:ymax_index]
524 xmin_index:xmax_index, ymin_index:ymax_index]
525 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
525 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
526
526
527 return noise
527 return noise
528
528
529 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
529 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
530
530
531 if self.noise_estimation is not None:
531 if self.noise_estimation is not None:
532 # this was estimated by getNoise Operation defined in jroproc_spectra.py
532 # this was estimated by getNoise Operation defined in jroproc_spectra.py
533 return self.noise_estimation
533 return self.noise_estimation
534 else:
534 else:
535 noise = self.getNoisebyHildebrand(
535 noise = self.getNoisebyHildebrand(
536 xmin_index, xmax_index, ymin_index, ymax_index)
536 xmin_index, xmax_index, ymin_index, ymax_index)
537 return noise
537 return noise
538
538
539 def getFreqRangeTimeResponse(self, extrapoints=0):
539 def getFreqRangeTimeResponse(self, extrapoints=0):
540
540
541 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
541 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
542 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
542 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
543
543
544 return freqrange
544 return freqrange
545
545
546 def getAcfRange(self, extrapoints=0):
546 def getAcfRange(self, extrapoints=0):
547
547
548 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
548 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
549 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
549 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
550
550
551 return freqrange
551 return freqrange
552
552
553 def getFreqRange(self, extrapoints=0):
553 def getFreqRange(self, extrapoints=0):
554
554
555 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
555 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
556 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
556 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
557
557
558 return freqrange
558 return freqrange
559
559
560 def getVelRange(self, extrapoints=0):
560 def getVelRange(self, extrapoints=0):
561
561
562 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
562 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
563 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
563 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
564
564
565 if self.nmodes:
565 if self.nmodes:
566 return velrange/self.nmodes
566 return velrange/self.nmodes
567 else:
567 else:
568 return velrange
568 return velrange
569
569
570 def getNPairs(self):
570 def getNPairs(self):
571
571
572 return len(self.pairsList)
572 return len(self.pairsList)
573
573
574 def getPairsIndexList(self):
574 def getPairsIndexList(self):
575
575
576 return list(range(self.nPairs))
576 return list(range(self.nPairs))
577
577
578 def getNormFactor(self):
578 def getNormFactor(self):
579
579
580 pwcode = 1
580 pwcode = 1
581
581
582 if self.flagDecodeData:
582 if self.flagDecodeData:
583 pwcode = numpy.sum(self.code[0]**2)
583 pwcode = numpy.sum(self.code[0]**2)
584 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
584 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
585 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
585 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
586
586
587 return normFactor
587 return normFactor
588
588
589 def getFlagCspc(self):
589 def getFlagCspc(self):
590
590
591 if self.data_cspc is None:
591 if self.data_cspc is None:
592 return True
592 return True
593
593
594 return False
594 return False
595
595
596 def getFlagDc(self):
596 def getFlagDc(self):
597
597
598 if self.data_dc is None:
598 if self.data_dc is None:
599 return True
599 return True
600
600
601 return False
601 return False
602
602
603 def getTimeInterval(self):
603 def getTimeInterval(self):
604
604
605 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
605 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
606 if self.nmodes:
606 if self.nmodes:
607 return self.nmodes*timeInterval
607 return self.nmodes*timeInterval
608 else:
608 else:
609 return timeInterval
609 return timeInterval
610
610
611 def getPower(self):
611 def getPower(self):
612
612
613 factor = self.normFactor
613 factor = self.normFactor
614 z = self.data_spc / factor
614 z = self.data_spc / factor
615 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
615 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
616 avg = numpy.average(z, axis=1)
616 avg = numpy.average(z, axis=1)
617
617
618 return 10 * numpy.log10(avg)
618 return 10 * numpy.log10(avg)
619
619
620 def getCoherence(self, pairsList=None, phase=False):
620 def getCoherence(self, pairsList=None, phase=False):
621
621
622 z = []
622 z = []
623 if pairsList is None:
623 if pairsList is None:
624 pairsIndexList = self.pairsIndexList
624 pairsIndexList = self.pairsIndexList
625 else:
625 else:
626 pairsIndexList = []
626 pairsIndexList = []
627 for pair in pairsList:
627 for pair in pairsList:
628 if pair not in self.pairsList:
628 if pair not in self.pairsList:
629 raise ValueError("Pair %s is not in dataOut.pairsList" % (
629 raise ValueError("Pair %s is not in dataOut.pairsList" % (
630 pair))
630 pair))
631 pairsIndexList.append(self.pairsList.index(pair))
631 pairsIndexList.append(self.pairsList.index(pair))
632 for i in range(len(pairsIndexList)):
632 for i in range(len(pairsIndexList)):
633 pair = self.pairsList[pairsIndexList[i]]
633 pair = self.pairsList[pairsIndexList[i]]
634 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
634 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
635 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
635 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
636 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
636 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
637 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
637 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
638 if phase:
638 if phase:
639 data = numpy.arctan2(avgcoherenceComplex.imag,
639 data = numpy.arctan2(avgcoherenceComplex.imag,
640 avgcoherenceComplex.real) * 180 / numpy.pi
640 avgcoherenceComplex.real) * 180 / numpy.pi
641 else:
641 else:
642 data = numpy.abs(avgcoherenceComplex)
642 data = numpy.abs(avgcoherenceComplex)
643
643
644 z.append(data)
644 z.append(data)
645
645
646 return numpy.array(z)
646 return numpy.array(z)
647
647
648 def setValue(self, value):
648 def setValue(self, value):
649
649
650 print("This property should not be initialized")
650 print("This property should not be initialized")
651
651
652 return
652 return
653
653
654 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
654 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
655 pairsIndexList = property(
655 pairsIndexList = property(
656 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
656 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
657 normFactor = property(getNormFactor, setValue,
657 normFactor = property(getNormFactor, setValue,
658 "I'm the 'getNormFactor' property.")
658 "I'm the 'getNormFactor' property.")
659 flag_cspc = property(getFlagCspc, setValue)
659 flag_cspc = property(getFlagCspc, setValue)
660 flag_dc = property(getFlagDc, setValue)
660 flag_dc = property(getFlagDc, setValue)
661 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
661 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
662 timeInterval = property(getTimeInterval, setValue,
662 timeInterval = property(getTimeInterval, setValue,
663 "I'm the 'timeInterval' property")
663 "I'm the 'timeInterval' property")
664
664
665
665
666 class SpectraHeis(Spectra):
666 class SpectraHeis(Spectra):
667
667
668 data_spc = None
668 data_spc = None
669 data_cspc = None
669 data_cspc = None
670 data_dc = None
670 data_dc = None
671 nFFTPoints = None
671 nFFTPoints = None
672 # nPairs = None
672 # nPairs = None
673 pairsList = None
673 pairsList = None
674 nCohInt = None
674 nCohInt = None
675 nIncohInt = None
675 nIncohInt = None
676
676
677 def __init__(self):
677 def __init__(self):
678
678
679 self.radarControllerHeaderObj = RadarControllerHeader()
679 self.radarControllerHeaderObj = RadarControllerHeader()
680
680
681 self.systemHeaderObj = SystemHeader()
681 self.systemHeaderObj = SystemHeader()
682
682
683 self.type = "SpectraHeis"
683 self.type = "SpectraHeis"
684
684
685 # self.dtype = None
685 # self.dtype = None
686
686
687 # self.nChannels = 0
687 # self.nChannels = 0
688
688
689 # self.nHeights = 0
689 # self.nHeights = 0
690
690
691 self.nProfiles = None
691 self.nProfiles = None
692
692
693 self.heightList = None
693 self.heightList = None
694
694
695 self.channelList = None
695 self.channelList = None
696
696
697 # self.channelIndexList = None
697 # self.channelIndexList = None
698
698
699 self.flagNoData = True
699 self.flagNoData = True
700
700
701 self.flagDiscontinuousBlock = False
701 self.flagDiscontinuousBlock = False
702
702
703 # self.nPairs = 0
703 # self.nPairs = 0
704
704
705 self.utctime = None
705 self.utctime = None
706
706
707 self.blocksize = None
707 self.blocksize = None
708
708
709 self.profileIndex = 0
709 self.profileIndex = 0
710
710
711 self.nCohInt = 1
711 self.nCohInt = 1
712
712
713 self.nIncohInt = 1
713 self.nIncohInt = 1
714
714
715 def getNormFactor(self):
715 def getNormFactor(self):
716 pwcode = 1
716 pwcode = 1
717 if self.flagDecodeData:
717 if self.flagDecodeData:
718 pwcode = numpy.sum(self.code[0]**2)
718 pwcode = numpy.sum(self.code[0]**2)
719
719
720 normFactor = self.nIncohInt * self.nCohInt * pwcode
720 normFactor = self.nIncohInt * self.nCohInt * pwcode
721
721
722 return normFactor
722 return normFactor
723
723
724 def getTimeInterval(self):
724 def getTimeInterval(self):
725
725
726 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
726 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
727
727
728 return timeInterval
728 return timeInterval
729
729
730 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
730 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
731 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
731 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
732
732
733
733
734 class Fits(JROData):
734 class Fits(JROData):
735
735
736 heightList = None
736 heightList = None
737 channelList = None
737 channelList = None
738 flagNoData = True
738 flagNoData = True
739 flagDiscontinuousBlock = False
739 flagDiscontinuousBlock = False
740 useLocalTime = False
740 useLocalTime = False
741 utctime = None
741 utctime = None
742 # ippSeconds = None
742 # ippSeconds = None
743 # timeInterval = None
743 # timeInterval = None
744 nCohInt = None
744 nCohInt = None
745 nIncohInt = None
745 nIncohInt = None
746 noise = None
746 noise = None
747 windowOfFilter = 1
747 windowOfFilter = 1
748 # Speed of ligth
748 # Speed of ligth
749 C = 3e8
749 C = 3e8
750 frequency = 49.92e6
750 frequency = 49.92e6
751 realtime = False
751 realtime = False
752
752
753 def __init__(self):
753 def __init__(self):
754
754
755 self.type = "Fits"
755 self.type = "Fits"
756
756
757 self.nProfiles = None
757 self.nProfiles = None
758
758
759 self.heightList = None
759 self.heightList = None
760
760
761 self.channelList = None
761 self.channelList = None
762
762
763 # self.channelIndexList = None
763 # self.channelIndexList = None
764
764
765 self.flagNoData = True
765 self.flagNoData = True
766
766
767 self.utctime = None
767 self.utctime = None
768
768
769 self.nCohInt = 1
769 self.nCohInt = 1
770
770
771 self.nIncohInt = 1
771 self.nIncohInt = 1
772
772
773 self.useLocalTime = True
773 self.useLocalTime = True
774
774
775 self.profileIndex = 0
775 self.profileIndex = 0
776
776
777 # self.utctime = None
777 # self.utctime = None
778 self.timeZone = 0
778 self.timeZone = 0
779 # self.ltctime = None
779 # self.ltctime = None
780 # self.timeInterval = None
780 # self.timeInterval = None
781 # self.header = None
781 # self.header = None
782 # self.data_header = None
782 # self.data_header = None
783 # self.data = None
783 # self.data = None
784 # self.datatime = None
784 # self.datatime = None
785 # self.flagNoData = False
785 # self.flagNoData = False
786 # self.expName = ''
786 # self.expName = ''
787 # self.nChannels = None
787 # self.nChannels = None
788 # self.nSamples = None
788 # self.nSamples = None
789 # self.dataBlocksPerFile = None
789 # self.dataBlocksPerFile = None
790 # self.comments = ''
790 # self.comments = ''
791 #
791 #
792
792
793 def getltctime(self):
793 def getltctime(self):
794
794
795 if self.useLocalTime:
795 if self.useLocalTime:
796 return self.utctime - self.timeZone * 60
796 return self.utctime - self.timeZone * 60
797
797
798 return self.utctime
798 return self.utctime
799
799
800 def getDatatime(self):
800 def getDatatime(self):
801
801
802 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
802 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
803 return datatime
803 return datatime
804
804
805 def getTimeRange(self):
805 def getTimeRange(self):
806
806
807 datatime = []
807 datatime = []
808
808
809 datatime.append(self.ltctime)
809 datatime.append(self.ltctime)
810 datatime.append(self.ltctime + self.timeInterval)
810 datatime.append(self.ltctime + self.timeInterval)
811
811
812 datatime = numpy.array(datatime)
812 datatime = numpy.array(datatime)
813
813
814 return datatime
814 return datatime
815
815
816 def getHeiRange(self):
816 def getHeiRange(self):
817
817
818 heis = self.heightList
818 heis = self.heightList
819
819
820 return heis
820 return heis
821
821
822 def getNHeights(self):
822 def getNHeights(self):
823
823
824 return len(self.heightList)
824 return len(self.heightList)
825
825
826 def getNChannels(self):
826 def getNChannels(self):
827
827
828 return len(self.channelList)
828 return len(self.channelList)
829
829
830 def getChannelIndexList(self):
830 def getChannelIndexList(self):
831
831
832 return list(range(self.nChannels))
832 return list(range(self.nChannels))
833
833
834 def getNoise(self, type=1):
834 def getNoise(self, type=1):
835
835
836 #noise = numpy.zeros(self.nChannels)
836 #noise = numpy.zeros(self.nChannels)
837
837
838 if type == 1:
838 if type == 1:
839 noise = self.getNoisebyHildebrand()
839 noise = self.getNoisebyHildebrand()
840
840
841 if type == 2:
841 if type == 2:
842 noise = self.getNoisebySort()
842 noise = self.getNoisebySort()
843
843
844 if type == 3:
844 if type == 3:
845 noise = self.getNoisebyWindow()
845 noise = self.getNoisebyWindow()
846
846
847 return noise
847 return noise
848
848
849 def getTimeInterval(self):
849 def getTimeInterval(self):
850
850
851 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
851 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
852
852
853 return timeInterval
853 return timeInterval
854
854
855 def get_ippSeconds(self):
855 def get_ippSeconds(self):
856 '''
856 '''
857 '''
857 '''
858 return self.ipp_sec
858 return self.ipp_sec
859
859
860
860
861 datatime = property(getDatatime, "I'm the 'datatime' property")
861 datatime = property(getDatatime, "I'm the 'datatime' property")
862 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
862 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
863 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
863 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
864 channelIndexList = property(
864 channelIndexList = property(
865 getChannelIndexList, "I'm the 'channelIndexList' property.")
865 getChannelIndexList, "I'm the 'channelIndexList' property.")
866 noise = property(getNoise, "I'm the 'nHeights' property.")
866 noise = property(getNoise, "I'm the 'nHeights' property.")
867
867
868 ltctime = property(getltctime, "I'm the 'ltctime' property")
868 ltctime = property(getltctime, "I'm the 'ltctime' property")
869 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
869 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
870 ippSeconds = property(get_ippSeconds, '')
870 ippSeconds = property(get_ippSeconds, '')
871
871
872 class Correlation(JROData):
872 class Correlation(JROData):
873
873
874 noise = None
874 noise = None
875 SNR = None
875 SNR = None
876 #--------------------------------------------------
876 #--------------------------------------------------
877 mode = None
877 mode = None
878 split = False
878 split = False
879 data_cf = None
879 data_cf = None
880 lags = None
880 lags = None
881 lagRange = None
881 lagRange = None
882 pairsList = None
882 pairsList = None
883 normFactor = None
883 normFactor = None
884 #--------------------------------------------------
884 #--------------------------------------------------
885 # calculateVelocity = None
885 # calculateVelocity = None
886 nLags = None
886 nLags = None
887 nPairs = None
887 nPairs = None
888 nAvg = None
888 nAvg = None
889
889
890 def __init__(self):
890 def __init__(self):
891 '''
891 '''
892 Constructor
892 Constructor
893 '''
893 '''
894 self.radarControllerHeaderObj = RadarControllerHeader()
894 self.radarControllerHeaderObj = RadarControllerHeader()
895
895
896 self.systemHeaderObj = SystemHeader()
896 self.systemHeaderObj = SystemHeader()
897
897
898 self.type = "Correlation"
898 self.type = "Correlation"
899
899
900 self.data = None
900 self.data = None
901
901
902 self.dtype = None
902 self.dtype = None
903
903
904 self.nProfiles = None
904 self.nProfiles = None
905
905
906 self.heightList = None
906 self.heightList = None
907
907
908 self.channelList = None
908 self.channelList = None
909
909
910 self.flagNoData = True
910 self.flagNoData = True
911
911
912 self.flagDiscontinuousBlock = False
912 self.flagDiscontinuousBlock = False
913
913
914 self.utctime = None
914 self.utctime = None
915
915
916 self.timeZone = 0
916 self.timeZone = 0
917
917
918 self.dstFlag = None
918 self.dstFlag = None
919
919
920 self.errorCount = None
920 self.errorCount = None
921
921
922 self.blocksize = None
922 self.blocksize = None
923
923
924 self.flagDecodeData = False # asumo q la data no esta decodificada
924 self.flagDecodeData = False # asumo q la data no esta decodificada
925
925
926 self.flagDeflipData = False # asumo q la data no esta sin flip
926 self.flagDeflipData = False # asumo q la data no esta sin flip
927
927
928 self.pairsList = None
928 self.pairsList = None
929
929
930 self.nPoints = None
930 self.nPoints = None
931
931
932 def getPairsList(self):
932 def getPairsList(self):
933
933
934 return self.pairsList
934 return self.pairsList
935
935
936 def getNoise(self, mode=2):
936 def getNoise(self, mode=2):
937
937
938 indR = numpy.where(self.lagR == 0)[0][0]
938 indR = numpy.where(self.lagR == 0)[0][0]
939 indT = numpy.where(self.lagT == 0)[0][0]
939 indT = numpy.where(self.lagT == 0)[0][0]
940
940
941 jspectra0 = self.data_corr[:, :, indR, :]
941 jspectra0 = self.data_corr[:, :, indR, :]
942 jspectra = copy.copy(jspectra0)
942 jspectra = copy.copy(jspectra0)
943
943
944 num_chan = jspectra.shape[0]
944 num_chan = jspectra.shape[0]
945 num_hei = jspectra.shape[2]
945 num_hei = jspectra.shape[2]
946
946
947 freq_dc = jspectra.shape[1] / 2
947 freq_dc = jspectra.shape[1] / 2
948 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
948 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
949
949
950 if ind_vel[0] < 0:
950 if ind_vel[0] < 0:
951 ind_vel[list(range(0, 1))] = ind_vel[list(
951 ind_vel[list(range(0, 1))] = ind_vel[list(
952 range(0, 1))] + self.num_prof
952 range(0, 1))] + self.num_prof
953
953
954 if mode == 1:
954 if mode == 1:
955 jspectra[:, freq_dc, :] = (
955 jspectra[:, freq_dc, :] = (
956 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
956 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
957
957
958 if mode == 2:
958 if mode == 2:
959
959
960 vel = numpy.array([-2, -1, 1, 2])
960 vel = numpy.array([-2, -1, 1, 2])
961 xx = numpy.zeros([4, 4])
961 xx = numpy.zeros([4, 4])
962
962
963 for fil in range(4):
963 for fil in range(4):
964 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
964 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
965
965
966 xx_inv = numpy.linalg.inv(xx)
966 xx_inv = numpy.linalg.inv(xx)
967 xx_aux = xx_inv[0, :]
967 xx_aux = xx_inv[0, :]
968
968
969 for ich in range(num_chan):
969 for ich in range(num_chan):
970 yy = jspectra[ich, ind_vel, :]
970 yy = jspectra[ich, ind_vel, :]
971 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
971 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
972
972
973 junkid = jspectra[ich, freq_dc, :] <= 0
973 junkid = jspectra[ich, freq_dc, :] <= 0
974 cjunkid = sum(junkid)
974 cjunkid = sum(junkid)
975
975
976 if cjunkid.any():
976 if cjunkid.any():
977 jspectra[ich, freq_dc, junkid.nonzero()] = (
977 jspectra[ich, freq_dc, junkid.nonzero()] = (
978 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
978 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
979
979
980 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
980 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
981
981
982 return noise
982 return noise
983
983
984 def getTimeInterval(self):
984 def getTimeInterval(self):
985
985
986 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
986 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
987
987
988 return timeInterval
988 return timeInterval
989
989
990 def splitFunctions(self):
990 def splitFunctions(self):
991
991
992 pairsList = self.pairsList
992 pairsList = self.pairsList
993 ccf_pairs = []
993 ccf_pairs = []
994 acf_pairs = []
994 acf_pairs = []
995 ccf_ind = []
995 ccf_ind = []
996 acf_ind = []
996 acf_ind = []
997 for l in range(len(pairsList)):
997 for l in range(len(pairsList)):
998 chan0 = pairsList[l][0]
998 chan0 = pairsList[l][0]
999 chan1 = pairsList[l][1]
999 chan1 = pairsList[l][1]
1000
1000
1001 # Obteniendo pares de Autocorrelacion
1001 # Obteniendo pares de Autocorrelacion
1002 if chan0 == chan1:
1002 if chan0 == chan1:
1003 acf_pairs.append(chan0)
1003 acf_pairs.append(chan0)
1004 acf_ind.append(l)
1004 acf_ind.append(l)
1005 else:
1005 else:
1006 ccf_pairs.append(pairsList[l])
1006 ccf_pairs.append(pairsList[l])
1007 ccf_ind.append(l)
1007 ccf_ind.append(l)
1008
1008
1009 data_acf = self.data_cf[acf_ind]
1009 data_acf = self.data_cf[acf_ind]
1010 data_ccf = self.data_cf[ccf_ind]
1010 data_ccf = self.data_cf[ccf_ind]
1011
1011
1012 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1012 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1013
1013
1014 def getNormFactor(self):
1014 def getNormFactor(self):
1015 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1015 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1016 acf_pairs = numpy.array(acf_pairs)
1016 acf_pairs = numpy.array(acf_pairs)
1017 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1017 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1018
1018
1019 for p in range(self.nPairs):
1019 for p in range(self.nPairs):
1020 pair = self.pairsList[p]
1020 pair = self.pairsList[p]
1021
1021
1022 ch0 = pair[0]
1022 ch0 = pair[0]
1023 ch1 = pair[1]
1023 ch1 = pair[1]
1024
1024
1025 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1025 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1026 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1026 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1027 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1027 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1028
1028
1029 return normFactor
1029 return normFactor
1030
1030
1031 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1031 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1032 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1032 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1033
1033
1034
1034
1035 class Parameters(Spectra):
1035 class Parameters(Spectra):
1036
1036
1037 experimentInfo = None # Information about the experiment
1037 experimentInfo = None # Information about the experiment
1038 # Information from previous data
1038 # Information from previous data
1039 inputUnit = None # Type of data to be processed
1039 inputUnit = None # Type of data to be processed
1040 operation = None # Type of operation to parametrize
1040 operation = None # Type of operation to parametrize
1041 # normFactor = None #Normalization Factor
1041 # normFactor = None #Normalization Factor
1042 groupList = None # List of Pairs, Groups, etc
1042 groupList = None # List of Pairs, Groups, etc
1043 # Parameters
1043 # Parameters
1044 data_param = None # Parameters obtained
1044 data_param = None # Parameters obtained
1045 data_pre = None # Data Pre Parametrization
1045 data_pre = None # Data Pre Parametrization
1046 data_SNR = None # Signal to Noise Ratio
1046 data_SNR = None # Signal to Noise Ratio
1047 # heightRange = None #Heights
1047 # heightRange = None #Heights
1048 abscissaList = None # Abscissa, can be velocities, lags or time
1048 abscissaList = None # Abscissa, can be velocities, lags or time
1049 # noise = None #Noise Potency
1049 # noise = None #Noise Potency
1050 utctimeInit = None # Initial UTC time
1050 utctimeInit = None # Initial UTC time
1051 paramInterval = None # Time interval to calculate Parameters in seconds
1051 paramInterval = None # Time interval to calculate Parameters in seconds
1052 useLocalTime = True
1052 useLocalTime = True
1053 # Fitting
1053 # Fitting
1054 data_error = None # Error of the estimation
1054 data_error = None # Error of the estimation
1055 constants = None
1055 constants = None
1056 library = None
1056 library = None
1057 # Output signal
1057 # Output signal
1058 outputInterval = None # Time interval to calculate output signal in seconds
1058 outputInterval = None # Time interval to calculate output signal in seconds
1059 data_output = None # Out signal
1059 data_output = None # Out signal
1060 nAvg = None
1060 nAvg = None
1061 noise_estimation = None
1061 noise_estimation = None
1062 GauSPC = None # Fit gaussian SPC
1062 GauSPC = None # Fit gaussian SPC
1063
1063
1064 def __init__(self):
1064 def __init__(self):
1065 '''
1065 '''
1066 Constructor
1066 Constructor
1067 '''
1067 '''
1068 self.radarControllerHeaderObj = RadarControllerHeader()
1068 self.radarControllerHeaderObj = RadarControllerHeader()
1069 self.systemHeaderObj = SystemHeader()
1069 self.systemHeaderObj = SystemHeader()
1070 self.type = "Parameters"
1070 self.type = "Parameters"
1071 self.timeZone = 0
1071 self.timeZone = 0
1072
1072
1073 def getTimeRange1(self, interval):
1073 def getTimeRange1(self, interval):
1074
1074
1075 datatime = []
1075 datatime = []
1076
1076
1077 if self.useLocalTime:
1077 if self.useLocalTime:
1078 time1 = self.utctimeInit - self.timeZone * 60
1078 time1 = self.utctimeInit - self.timeZone * 60
1079 else:
1079 else:
1080 time1 = self.utctimeInit
1080 time1 = self.utctimeInit
1081
1081
1082 datatime.append(time1)
1082 datatime.append(time1)
1083 datatime.append(time1 + interval)
1083 datatime.append(time1 + interval)
1084 datatime = numpy.array(datatime)
1084 datatime = numpy.array(datatime)
1085
1085
1086 return datatime
1086 return datatime
1087
1087
1088 def getTimeInterval(self):
1088 def getTimeInterval(self):
1089
1089
1090 if hasattr(self, 'timeInterval1'):
1090 if hasattr(self, 'timeInterval1'):
1091 return self.timeInterval1
1091 return self.timeInterval1
1092 else:
1092 else:
1093 return self.paramInterval
1093 return self.paramInterval
1094
1094
1095 def setValue(self, value):
1095 def setValue(self, value):
1096
1096
1097 print("This property should not be initialized")
1097 print("This property should not be initialized")
1098
1098
1099 return
1099 return
1100
1100
1101 def getNoise(self):
1101 def getNoise(self):
1102
1102
1103 return self.spc_noise
1103 return self.spc_noise
1104
1104
1105 timeInterval = property(getTimeInterval)
1105 timeInterval = property(getTimeInterval)
1106 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1106 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1107
1107
1108
1108
1109 class PlotterData(object):
1109 class PlotterData(object):
1110 '''
1110 '''
1111 Object to hold data to be plotted
1111 Object to hold data to be plotted
1112 '''
1112 '''
1113
1113
1114 MAXNUMX = 200
1114 MAXNUMX = 200
1115 MAXNUMY = 200
1115 MAXNUMY = 200
1116
1116
1117 def __init__(self, code, throttle_value, exp_code, buffering=True, snr=False):
1117 def __init__(self, code, throttle_value, exp_code, localtime=True, buffering=True, snr=False):
1118
1118
1119 self.key = code
1119 self.key = code
1120 self.throttle = throttle_value
1120 self.throttle = throttle_value
1121 self.exp_code = exp_code
1121 self.exp_code = exp_code
1122 self.buffering = buffering
1122 self.buffering = buffering
1123 self.ready = False
1123 self.ready = False
1124 self.flagNoData = False
1124 self.flagNoData = False
1125 self.localtime = False
1125 self.localtime = localtime
1126 self.data = {}
1126 self.data = {}
1127 self.meta = {}
1127 self.meta = {}
1128 self.__heights = []
1128 self.__heights = []
1129
1129
1130 if 'snr' in code:
1130 if 'snr' in code:
1131 self.plottypes = ['snr']
1131 self.plottypes = ['snr']
1132 elif code == 'spc':
1132 elif code == 'spc':
1133 self.plottypes = ['spc', 'noise', 'rti']
1133 self.plottypes = ['spc', 'noise', 'rti']
1134 elif code == 'cspc':
1134 elif code == 'cspc':
1135 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
1135 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
1136 elif code == 'rti':
1136 elif code == 'rti':
1137 self.plottypes = ['noise', 'rti']
1137 self.plottypes = ['noise', 'rti']
1138 else:
1138 else:
1139 self.plottypes = [code]
1139 self.plottypes = [code]
1140
1140
1141 if 'snr' not in self.plottypes and snr:
1141 if 'snr' not in self.plottypes and snr:
1142 self.plottypes.append('snr')
1142 self.plottypes.append('snr')
1143
1143
1144 for plot in self.plottypes:
1144 for plot in self.plottypes:
1145 self.data[plot] = {}
1145 self.data[plot] = {}
1146
1146
1147
1148 def __str__(self):
1147 def __str__(self):
1149 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1148 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1150 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1149 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1151
1150
1152 def __len__(self):
1151 def __len__(self):
1153 return len(self.data[self.key])
1152 return len(self.data[self.key])
1154
1153
1155 def __getitem__(self, key):
1154 def __getitem__(self, key):
1156
1155
1157 if key not in self.data:
1156 if key not in self.data:
1158 raise KeyError(log.error('Missing key: {}'.format(key)))
1157 raise KeyError(log.error('Missing key: {}'.format(key)))
1159 if 'spc' in key or not self.buffering:
1158 if 'spc' in key or not self.buffering:
1160 ret = self.data[key][self.tm]
1159 ret = self.data[key][self.tm]
1161 elif 'scope' in key:
1160 elif 'scope' in key:
1162 ret = numpy.array(self.data[key][float(self.tm)])
1161 ret = numpy.array(self.data[key][float(self.tm)])
1163 else:
1162 else:
1164 ret = numpy.array([self.data[key][x] for x in self.times])
1163 ret = numpy.array([self.data[key][x] for x in self.times])
1165 if ret.ndim > 1:
1164 if ret.ndim > 1:
1166 ret = numpy.swapaxes(ret, 0, 1)
1165 ret = numpy.swapaxes(ret, 0, 1)
1167 return ret
1166 return ret
1168
1167
1169 def __contains__(self, key):
1168 def __contains__(self, key):
1170 return key in self.data
1169 return key in self.data
1171
1170
1172 def setup(self):
1171 def setup(self):
1173 '''
1172 '''
1174 Configure object
1173 Configure object
1175 '''
1174 '''
1176 self.type = ''
1175 self.type = ''
1177 self.ready = False
1176 self.ready = False
1178 del self.data
1177 del self.data
1179 self.data = {}
1178 self.data = {}
1180 self.__heights = []
1179 self.__heights = []
1181 self.__all_heights = set()
1180 self.__all_heights = set()
1182 for plot in self.plottypes:
1181 for plot in self.plottypes:
1183 if 'snr' in plot:
1182 if 'snr' in plot:
1184 plot = 'snr'
1183 plot = 'snr'
1185 elif 'spc_moments' == plot:
1184 elif 'spc_moments' == plot:
1186 plot = 'moments'
1185 plot = 'moments'
1187 self.data[plot] = {}
1186 self.data[plot] = {}
1188
1187
1189 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1188 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1190 self.data['noise'] = {}
1189 self.data['noise'] = {}
1191 self.data['rti'] = {}
1190 self.data['rti'] = {}
1192 if 'noise' not in self.plottypes:
1191 if 'noise' not in self.plottypes:
1193 self.plottypes.append('noise')
1192 self.plottypes.append('noise')
1194 if 'rti' not in self.plottypes:
1193 if 'rti' not in self.plottypes:
1195 self.plottypes.append('rti')
1194 self.plottypes.append('rti')
1196
1195
1197 def shape(self, key):
1196 def shape(self, key):
1198 '''
1197 '''
1199 Get the shape of the one-element data for the given key
1198 Get the shape of the one-element data for the given key
1200 '''
1199 '''
1201
1200
1202 if len(self.data[key]):
1201 if len(self.data[key]):
1203 if 'spc' in key or not self.buffering:
1202 if 'spc' in key or not self.buffering:
1204 return self.data[key].shape
1203 return self.data[key].shape
1205 return self.data[key][self.times[0]].shape
1204 return self.data[key][self.times[0]].shape
1206 return (0,)
1205 return (0,)
1207
1206
1208 def update(self, dataOut, tm):
1207 def update(self, dataOut, tm):
1209 '''
1208 '''
1210 Update data object with new dataOut
1209 Update data object with new dataOut
1211 '''
1210 '''
1212
1211
1213 self.profileIndex = dataOut.profileIndex
1212 self.profileIndex = dataOut.profileIndex
1214 self.tm = tm
1213 self.tm = tm
1215 self.type = dataOut.type
1214 self.type = dataOut.type
1216 self.parameters = getattr(dataOut, 'parameters', [])
1215 self.parameters = getattr(dataOut, 'parameters', [])
1217
1216
1218 if hasattr(dataOut, 'meta'):
1217 if hasattr(dataOut, 'meta'):
1219 self.meta.update(dataOut.meta)
1218 self.meta.update(dataOut.meta)
1220
1219
1221 if hasattr(dataOut, 'pairsList'):
1220 if hasattr(dataOut, 'pairsList'):
1222 self.pairs = dataOut.pairsList
1221 self.pairs = dataOut.pairsList
1223
1222
1224 self.interval = dataOut.getTimeInterval()
1223 self.interval = dataOut.getTimeInterval()
1225 self.localtime = dataOut.useLocalTime
1226 if True in ['spc' in ptype for ptype in self.plottypes]:
1224 if True in ['spc' in ptype for ptype in self.plottypes]:
1227 self.xrange = (dataOut.getFreqRange(1)/1000.,
1225 self.xrange = (dataOut.getFreqRange(1)/1000.,
1228 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1226 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1229 self.__heights.append(dataOut.heightList)
1227 self.__heights.append(dataOut.heightList)
1230 self.__all_heights.update(dataOut.heightList)
1228 self.__all_heights.update(dataOut.heightList)
1231
1229
1232 for plot in self.plottypes:
1230 for plot in self.plottypes:
1233 if plot in ('spc', 'spc_moments', 'spc_cut'):
1231 if plot in ('spc', 'spc_moments', 'spc_cut'):
1234 z = dataOut.data_spc/dataOut.normFactor
1232 z = dataOut.data_spc/dataOut.normFactor
1235 buffer = 10*numpy.log10(z)
1233 buffer = 10*numpy.log10(z)
1236 if plot == 'cspc':
1234 if plot == 'cspc':
1237 buffer = (dataOut.data_spc, dataOut.data_cspc)
1235 buffer = (dataOut.data_spc, dataOut.data_cspc)
1238 if plot == 'noise':
1236 if plot == 'noise':
1239 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1237 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1240 if plot in ('rti', 'spcprofile'):
1238 if plot in ('rti', 'spcprofile'):
1241 buffer = dataOut.getPower()
1239 buffer = dataOut.getPower()
1242 if plot == 'snr_db':
1240 if plot == 'snr_db':
1243 buffer = dataOut.data_SNR
1241 buffer = dataOut.data_SNR
1244 if plot == 'snr':
1242 if plot == 'snr':
1245 buffer = 10*numpy.log10(dataOut.data_SNR)
1243 buffer = 10*numpy.log10(dataOut.data_SNR)
1246 if plot == 'dop':
1244 if plot == 'dop':
1247 buffer = dataOut.data_DOP
1245 buffer = dataOut.data_DOP
1248 if plot == 'pow':
1246 if plot == 'pow':
1249 buffer = 10*numpy.log10(dataOut.data_POW)
1247 buffer = 10*numpy.log10(dataOut.data_POW)
1250 if plot == 'width':
1248 if plot == 'width':
1251 buffer = dataOut.data_WIDTH
1249 buffer = dataOut.data_WIDTH
1252 if plot == 'coh':
1250 if plot == 'coh':
1253 buffer = dataOut.getCoherence()
1251 buffer = dataOut.getCoherence()
1254 if plot == 'phase':
1252 if plot == 'phase':
1255 buffer = dataOut.getCoherence(phase=True)
1253 buffer = dataOut.getCoherence(phase=True)
1256 if plot == 'output':
1254 if plot == 'output':
1257 buffer = dataOut.data_output
1255 buffer = dataOut.data_output
1258 if plot == 'param':
1256 if plot == 'param':
1259 buffer = dataOut.data_param
1257 buffer = dataOut.data_param
1260 if plot == 'scope':
1258 if plot == 'scope':
1261 buffer = dataOut.data
1259 buffer = dataOut.data
1262 self.flagDataAsBlock = dataOut.flagDataAsBlock
1260 self.flagDataAsBlock = dataOut.flagDataAsBlock
1263 self.nProfiles = dataOut.nProfiles
1261 self.nProfiles = dataOut.nProfiles
1264 if plot == 'pp_power':
1262 if plot == 'pp_power':
1265 buffer = dataOut.dataPP_POWER
1263 buffer = dataOut.dataPP_POWER
1266 self.flagDataAsBlock = dataOut.flagDataAsBlock
1264 self.flagDataAsBlock = dataOut.flagDataAsBlock
1267 self.nProfiles = dataOut.nProfiles
1265 self.nProfiles = dataOut.nProfiles
1268 if plot == 'pp_signal':
1266 if plot == 'pp_signal':
1269 buffer = dataOut.dataPP_POW
1267 buffer = dataOut.dataPP_POW
1270 self.flagDataAsBlock = dataOut.flagDataAsBlock
1268 self.flagDataAsBlock = dataOut.flagDataAsBlock
1271 self.nProfiles = dataOut.nProfiles
1269 self.nProfiles = dataOut.nProfiles
1272 if plot == 'pp_velocity':
1270 if plot == 'pp_velocity':
1273 buffer = dataOut.dataPP_DOP
1271 buffer = dataOut.dataPP_DOP
1274 self.flagDataAsBlock = dataOut.flagDataAsBlock
1272 self.flagDataAsBlock = dataOut.flagDataAsBlock
1275 self.nProfiles = dataOut.nProfiles
1273 self.nProfiles = dataOut.nProfiles
1276 if plot == 'pp_specwidth':
1274 if plot == 'pp_specwidth':
1277 buffer = dataOut.dataPP_WIDTH
1275 buffer = dataOut.dataPP_WIDTH
1278 self.flagDataAsBlock = dataOut.flagDataAsBlock
1276 self.flagDataAsBlock = dataOut.flagDataAsBlock
1279 self.nProfiles = dataOut.nProfiles
1277 self.nProfiles = dataOut.nProfiles
1280
1278
1281 if plot == 'spc':
1279 if plot == 'spc':
1282 self.data['spc'][tm] = buffer
1280 self.data['spc'][tm] = buffer
1283 elif plot == 'cspc':
1281 elif plot == 'cspc':
1284 self.data['cspc'][tm] = buffer
1282 self.data['cspc'][tm] = buffer
1285 elif plot == 'spc_moments':
1283 elif plot == 'spc_moments':
1286 self.data['spc'][tm] = buffer
1284 self.data['spc'][tm] = buffer
1287 self.data['moments'][tm] = dataOut.moments
1285 self.data['moments'][tm] = dataOut.moments
1288 else:
1286 else:
1289 if self.buffering:
1287 if self.buffering:
1290 self.data[plot][tm] = buffer
1288 self.data[plot][tm] = buffer
1291 else:
1289 else:
1292 self.data[plot][tm] = buffer
1290 self.data[plot][tm] = buffer
1293
1291
1294 if dataOut.channelList is None:
1292 if dataOut.channelList is None:
1295 self.channels = range(buffer.shape[0])
1293 self.channels = range(buffer.shape[0])
1296 else:
1294 else:
1297 self.channels = dataOut.channelList
1295 self.channels = dataOut.channelList
1298
1296
1299 if buffer is None:
1297 if buffer is None:
1300 self.flagNoData = True
1298 self.flagNoData = True
1301 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
1299 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
1302
1300
1303 def normalize_heights(self):
1301 def normalize_heights(self):
1304 '''
1302 '''
1305 Ensure same-dimension of the data for different heighList
1303 Ensure same-dimension of the data for different heighList
1306 '''
1304 '''
1307
1305
1308 H = numpy.array(list(self.__all_heights))
1306 H = numpy.array(list(self.__all_heights))
1309 H.sort()
1307 H.sort()
1310 for key in self.data:
1308 for key in self.data:
1311 shape = self.shape(key)[:-1] + H.shape
1309 shape = self.shape(key)[:-1] + H.shape
1312 for tm, obj in list(self.data[key].items()):
1310 for tm, obj in list(self.data[key].items()):
1313 h = self.__heights[self.times.tolist().index(tm)]
1311 h = self.__heights[self.times.tolist().index(tm)]
1314 if H.size == h.size:
1312 if H.size == h.size:
1315 continue
1313 continue
1316 index = numpy.where(numpy.in1d(H, h))[0]
1314 index = numpy.where(numpy.in1d(H, h))[0]
1317 dummy = numpy.zeros(shape) + numpy.nan
1315 dummy = numpy.zeros(shape) + numpy.nan
1318 if len(shape) == 2:
1316 if len(shape) == 2:
1319 dummy[:, index] = obj
1317 dummy[:, index] = obj
1320 else:
1318 else:
1321 dummy[index] = obj
1319 dummy[index] = obj
1322 self.data[key][tm] = dummy
1320 self.data[key][tm] = dummy
1323
1321
1324 self.__heights = [H for tm in self.times]
1322 self.__heights = [H for tm in self.times]
1325
1323
1326 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1324 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1327 '''
1325 '''
1328 Convert data to json
1326 Convert data to json
1329 '''
1327 '''
1330
1328
1331 dy = int(self.heights.size/self.MAXNUMY) + 1
1329 dy = int(self.heights.size/self.MAXNUMY) + 1
1332 if self.key in ('spc', 'cspc'):
1330 if self.key in ('spc', 'cspc'):
1333 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
1331 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
1334 data = self.roundFloats(
1332 data = self.roundFloats(
1335 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1333 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1336 else:
1334 else:
1337 if self.key is 'noise':
1335 if self.key is 'noise':
1338 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1336 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1339 else:
1337 else:
1340 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1338 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1341
1339
1342 meta = {}
1340 meta = {}
1343 ret = {
1341 ret = {
1344 'plot': plot_name,
1342 'plot': plot_name,
1345 'code': self.exp_code,
1343 'code': self.exp_code,
1346 'time': float(tm),
1344 'time': float(tm),
1347 'data': data,
1345 'data': data,
1348 }
1346 }
1349 meta['type'] = plot_type
1347 meta['type'] = plot_type
1350 meta['interval'] = float(self.interval)
1348 meta['interval'] = float(self.interval)
1351 meta['localtime'] = self.localtime
1349 meta['localtime'] = self.localtime
1352 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1350 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1353 if 'spc' in self.data or 'cspc' in self.data:
1351 if 'spc' in self.data or 'cspc' in self.data:
1354 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1352 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1355 else:
1353 else:
1356 meta['xrange'] = []
1354 meta['xrange'] = []
1357
1355
1358 meta.update(self.meta)
1356 meta.update(self.meta)
1359 ret['metadata'] = meta
1357 ret['metadata'] = meta
1360 return json.dumps(ret)
1358 return json.dumps(ret)
1361
1359
1362 @property
1360 @property
1363 def times(self):
1361 def times(self):
1364 '''
1362 '''
1365 Return the list of times of the current data
1363 Return the list of times of the current data
1366 '''
1364 '''
1367
1365
1368 ret = numpy.array([*self.data[self.key]])
1366 ret = numpy.array([*self.data[self.key]])
1369 if self:
1367 if self:
1370 ret.sort()
1368 ret.sort()
1371 return ret
1369 return ret
1372
1370
1373 @property
1371 @property
1374 def min_time(self):
1372 def min_time(self):
1375 '''
1373 '''
1376 Return the minimun time value
1374 Return the minimun time value
1377 '''
1375 '''
1378
1376
1379 return self.times[0]
1377 return self.times[0]
1380
1378
1381 @property
1379 @property
1382 def max_time(self):
1380 def max_time(self):
1383 '''
1381 '''
1384 Return the maximun time value
1382 Return the maximun time value
1385 '''
1383 '''
1386
1384
1387 return self.times[-1]
1385 return self.times[-1]
1388
1386
1389 @property
1387 @property
1390 def heights(self):
1388 def heights(self):
1391 '''
1389 '''
1392 Return the list of heights of the current data
1390 Return the list of heights of the current data
1393 '''
1391 '''
1394
1392
1395 return numpy.array(self.__heights[-1])
1393 return numpy.array(self.__heights[-1])
1396
1394
1397 @staticmethod
1395 @staticmethod
1398 def roundFloats(obj):
1396 def roundFloats(obj):
1399 if isinstance(obj, list):
1397 if isinstance(obj, list):
1400 return list(map(PlotterData.roundFloats, obj))
1398 return list(map(PlotterData.roundFloats, obj))
1401 elif isinstance(obj, float):
1399 elif isinstance(obj, float):
1402 return round(obj, 2)
1400 return round(obj, 2)
@@ -1,717 +1,713
1
1
2 import os
2 import os
3 import sys
3 import sys
4 import zmq
4 import zmq
5 import time
5 import time
6 import numpy
6 import numpy
7 import datetime
7 import datetime
8 from queue import Queue
8 from queue import Queue
9 from functools import wraps
9 from functools import wraps
10 from threading import Thread
10 from threading import Thread
11 import matplotlib
11 import matplotlib
12
12
13 if 'BACKEND' in os.environ:
13 if 'BACKEND' in os.environ:
14 matplotlib.use(os.environ['BACKEND'])
14 matplotlib.use(os.environ['BACKEND'])
15 elif 'linux' in sys.platform:
15 elif 'linux' in sys.platform:
16 matplotlib.use("TkAgg")
16 matplotlib.use("TkAgg")
17 elif 'darwin' in sys.platform:
17 elif 'darwin' in sys.platform:
18 matplotlib.use('WxAgg')
18 matplotlib.use('WxAgg')
19 else:
19 else:
20 from schainpy.utils import log
20 from schainpy.utils import log
21 log.warning('Using default Backend="Agg"', 'INFO')
21 log.warning('Using default Backend="Agg"', 'INFO')
22 matplotlib.use('Agg')
22 matplotlib.use('Agg')
23
23
24 import matplotlib.pyplot as plt
24 import matplotlib.pyplot as plt
25 from matplotlib.patches import Polygon
25 from matplotlib.patches import Polygon
26 from mpl_toolkits.axes_grid1 import make_axes_locatable
26 from mpl_toolkits.axes_grid1 import make_axes_locatable
27 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
27 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
28
28
29 from schainpy.model.data.jrodata import PlotterData
29 from schainpy.model.data.jrodata import PlotterData
30 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
30 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
31 from schainpy.utils import log
31 from schainpy.utils import log
32
32
33 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
33 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
34 blu_values = matplotlib.pyplot.get_cmap(
34 blu_values = matplotlib.pyplot.get_cmap(
35 'seismic_r', 20)(numpy.arange(20))[10:15]
35 'seismic_r', 20)(numpy.arange(20))[10:15]
36 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
36 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
37 'jro', numpy.vstack((blu_values, jet_values)))
37 'jro', numpy.vstack((blu_values, jet_values)))
38 matplotlib.pyplot.register_cmap(cmap=ncmap)
38 matplotlib.pyplot.register_cmap(cmap=ncmap)
39
39
40 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
40 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
41 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
41 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
42
42
43 EARTH_RADIUS = 6.3710e3
43 EARTH_RADIUS = 6.3710e3
44
44
45 def ll2xy(lat1, lon1, lat2, lon2):
45 def ll2xy(lat1, lon1, lat2, lon2):
46
46
47 p = 0.017453292519943295
47 p = 0.017453292519943295
48 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
48 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
49 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
49 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
50 r = 12742 * numpy.arcsin(numpy.sqrt(a))
50 r = 12742 * numpy.arcsin(numpy.sqrt(a))
51 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
51 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
52 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
52 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
53 theta = -theta + numpy.pi/2
53 theta = -theta + numpy.pi/2
54 return r*numpy.cos(theta), r*numpy.sin(theta)
54 return r*numpy.cos(theta), r*numpy.sin(theta)
55
55
56
56
57 def km2deg(km):
57 def km2deg(km):
58 '''
58 '''
59 Convert distance in km to degrees
59 Convert distance in km to degrees
60 '''
60 '''
61
61
62 return numpy.rad2deg(km/EARTH_RADIUS)
62 return numpy.rad2deg(km/EARTH_RADIUS)
63
63
64
64
65 def figpause(interval):
65 def figpause(interval):
66 backend = plt.rcParams['backend']
66 backend = plt.rcParams['backend']
67 if backend in matplotlib.rcsetup.interactive_bk:
67 if backend in matplotlib.rcsetup.interactive_bk:
68 figManager = matplotlib._pylab_helpers.Gcf.get_active()
68 figManager = matplotlib._pylab_helpers.Gcf.get_active()
69 if figManager is not None:
69 if figManager is not None:
70 canvas = figManager.canvas
70 canvas = figManager.canvas
71 if canvas.figure.stale:
71 if canvas.figure.stale:
72 canvas.draw()
72 canvas.draw()
73 try:
73 try:
74 canvas.start_event_loop(interval)
74 canvas.start_event_loop(interval)
75 except:
75 except:
76 pass
76 pass
77 return
77 return
78
78
79
79
80 def popup(message):
80 def popup(message):
81 '''
81 '''
82 '''
82 '''
83
83
84 fig = plt.figure(figsize=(12, 8), facecolor='r')
84 fig = plt.figure(figsize=(12, 8), facecolor='r')
85 text = '\n'.join([s.strip() for s in message.split(':')])
85 text = '\n'.join([s.strip() for s in message.split(':')])
86 fig.text(0.01, 0.5, text, ha='left', va='center',
86 fig.text(0.01, 0.5, text, ha='left', va='center',
87 size='20', weight='heavy', color='w')
87 size='20', weight='heavy', color='w')
88 fig.show()
88 fig.show()
89 figpause(1000)
89 figpause(1000)
90
90
91
91
92 class Throttle(object):
92 class Throttle(object):
93 '''
93 '''
94 Decorator that prevents a function from being called more than once every
94 Decorator that prevents a function from being called more than once every
95 time period.
95 time period.
96 To create a function that cannot be called more than once a minute, but
96 To create a function that cannot be called more than once a minute, but
97 will sleep until it can be called:
97 will sleep until it can be called:
98 @Throttle(minutes=1)
98 @Throttle(minutes=1)
99 def foo():
99 def foo():
100 pass
100 pass
101
101
102 for i in range(10):
102 for i in range(10):
103 foo()
103 foo()
104 print "This function has run %s times." % i
104 print "This function has run %s times." % i
105 '''
105 '''
106
106
107 def __init__(self, seconds=0, minutes=0, hours=0):
107 def __init__(self, seconds=0, minutes=0, hours=0):
108 self.throttle_period = datetime.timedelta(
108 self.throttle_period = datetime.timedelta(
109 seconds=seconds, minutes=minutes, hours=hours
109 seconds=seconds, minutes=minutes, hours=hours
110 )
110 )
111
111
112 self.time_of_last_call = datetime.datetime.min
112 self.time_of_last_call = datetime.datetime.min
113
113
114 def __call__(self, fn):
114 def __call__(self, fn):
115 @wraps(fn)
115 @wraps(fn)
116 def wrapper(*args, **kwargs):
116 def wrapper(*args, **kwargs):
117 coerce = kwargs.pop('coerce', None)
117 coerce = kwargs.pop('coerce', None)
118 if coerce:
118 if coerce:
119 self.time_of_last_call = datetime.datetime.now()
119 self.time_of_last_call = datetime.datetime.now()
120 return fn(*args, **kwargs)
120 return fn(*args, **kwargs)
121 else:
121 else:
122 now = datetime.datetime.now()
122 now = datetime.datetime.now()
123 time_since_last_call = now - self.time_of_last_call
123 time_since_last_call = now - self.time_of_last_call
124 time_left = self.throttle_period - time_since_last_call
124 time_left = self.throttle_period - time_since_last_call
125
125
126 if time_left > datetime.timedelta(seconds=0):
126 if time_left > datetime.timedelta(seconds=0):
127 return
127 return
128
128
129 self.time_of_last_call = datetime.datetime.now()
129 self.time_of_last_call = datetime.datetime.now()
130 return fn(*args, **kwargs)
130 return fn(*args, **kwargs)
131
131
132 return wrapper
132 return wrapper
133
133
134 def apply_throttle(value):
134 def apply_throttle(value):
135
135
136 @Throttle(seconds=value)
136 @Throttle(seconds=value)
137 def fnThrottled(fn):
137 def fnThrottled(fn):
138 fn()
138 fn()
139
139
140 return fnThrottled
140 return fnThrottled
141
141
142
142
143 @MPDecorator
143 @MPDecorator
144 class Plot(Operation):
144 class Plot(Operation):
145 '''
145 '''
146 Base class for Schain plotting operations
146 Base class for Schain plotting operations
147 '''
147 '''
148
148
149 CODE = 'Figure'
149 CODE = 'Figure'
150 colormap = 'jet'
150 colormap = 'jet'
151 bgcolor = 'white'
151 bgcolor = 'white'
152 buffering = True
152 buffering = True
153 __missing = 1E30
153 __missing = 1E30
154
154
155 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
155 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
156 'showprofile']
156 'showprofile']
157
157
158 def __init__(self):
158 def __init__(self):
159
159
160 Operation.__init__(self)
160 Operation.__init__(self)
161 self.isConfig = False
161 self.isConfig = False
162 self.isPlotConfig = False
162 self.isPlotConfig = False
163 self.save_counter = 1
163 self.save_counter = 1
164 self.sender_time = 0
164 self.sender_time = 0
165 self.data = None
165 self.data = None
166 self.firsttime = True
166 self.firsttime = True
167 self.sender_queue = Queue(maxsize=10)
167 self.sender_queue = Queue(maxsize=60)
168 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
168 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
169
169
170 def __fmtTime(self, x, pos):
170 def __fmtTime(self, x, pos):
171 '''
171 '''
172 '''
172 '''
173
173
174 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
174 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
175
175
176 def __setup(self, **kwargs):
176 def __setup(self, **kwargs):
177 '''
177 '''
178 Initialize variables
178 Initialize variables
179 '''
179 '''
180
180
181 self.figures = []
181 self.figures = []
182 self.axes = []
182 self.axes = []
183 self.cb_axes = []
183 self.cb_axes = []
184 self.localtime = kwargs.pop('localtime', True)
184 self.localtime = kwargs.pop('localtime', True)
185 self.show = kwargs.get('show', True)
185 self.show = kwargs.get('show', True)
186 self.save = kwargs.get('save', False)
186 self.save = kwargs.get('save', False)
187 self.save_period = kwargs.get('save_period', 1)
187 self.save_period = kwargs.get('save_period', 1)
188 self.ftp = kwargs.get('ftp', False)
189 self.colormap = kwargs.get('colormap', self.colormap)
188 self.colormap = kwargs.get('colormap', self.colormap)
190 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
189 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
191 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
190 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
192 self.colormaps = kwargs.get('colormaps', None)
191 self.colormaps = kwargs.get('colormaps', None)
193 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
192 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
194 self.showprofile = kwargs.get('showprofile', False)
193 self.showprofile = kwargs.get('showprofile', False)
195 self.title = kwargs.get('wintitle', self.CODE.upper())
194 self.title = kwargs.get('wintitle', self.CODE.upper())
196 self.cb_label = kwargs.get('cb_label', None)
195 self.cb_label = kwargs.get('cb_label', None)
197 self.cb_labels = kwargs.get('cb_labels', None)
196 self.cb_labels = kwargs.get('cb_labels', None)
198 self.labels = kwargs.get('labels', None)
197 self.labels = kwargs.get('labels', None)
199 self.xaxis = kwargs.get('xaxis', 'frequency')
198 self.xaxis = kwargs.get('xaxis', 'frequency')
200 self.zmin = kwargs.get('zmin', None)
199 self.zmin = kwargs.get('zmin', None)
201 self.zmax = kwargs.get('zmax', None)
200 self.zmax = kwargs.get('zmax', None)
202 self.zlimits = kwargs.get('zlimits', None)
201 self.zlimits = kwargs.get('zlimits', None)
203 self.xmin = kwargs.get('xmin', None)
202 self.xmin = kwargs.get('xmin', None)
204 self.xmax = kwargs.get('xmax', None)
203 self.xmax = kwargs.get('xmax', None)
205 self.xrange = kwargs.get('xrange', 12)
204 self.xrange = kwargs.get('xrange', 12)
206 self.xscale = kwargs.get('xscale', None)
205 self.xscale = kwargs.get('xscale', None)
207 self.ymin = kwargs.get('ymin', None)
206 self.ymin = kwargs.get('ymin', None)
208 self.ymax = kwargs.get('ymax', None)
207 self.ymax = kwargs.get('ymax', None)
209 self.yscale = kwargs.get('yscale', None)
208 self.yscale = kwargs.get('yscale', None)
210 self.xlabel = kwargs.get('xlabel', None)
209 self.xlabel = kwargs.get('xlabel', None)
211 self.attr_time = kwargs.get('attr_time', 'utctime')
210 self.attr_time = kwargs.get('attr_time', 'utctime')
212 self.decimation = kwargs.get('decimation', None)
211 self.decimation = kwargs.get('decimation', None)
213 self.showSNR = kwargs.get('showSNR', False)
212 self.showSNR = kwargs.get('showSNR', False)
214 self.oneFigure = kwargs.get('oneFigure', True)
213 self.oneFigure = kwargs.get('oneFigure', True)
215 self.width = kwargs.get('width', None)
214 self.width = kwargs.get('width', None)
216 self.height = kwargs.get('height', None)
215 self.height = kwargs.get('height', None)
217 self.colorbar = kwargs.get('colorbar', True)
216 self.colorbar = kwargs.get('colorbar', True)
218 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
217 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
219 self.channels = kwargs.get('channels', None)
218 self.channels = kwargs.get('channels', None)
220 self.titles = kwargs.get('titles', [])
219 self.titles = kwargs.get('titles', [])
221 self.polar = False
220 self.polar = False
222 self.type = kwargs.get('type', 'iq')
221 self.type = kwargs.get('type', 'iq')
223 self.grid = kwargs.get('grid', False)
222 self.grid = kwargs.get('grid', False)
224 self.pause = kwargs.get('pause', False)
223 self.pause = kwargs.get('pause', False)
225 self.save_code = kwargs.get('save_code', None)
224 self.save_code = kwargs.get('save_code', None)
226 self.realtime = kwargs.get('realtime', True)
227 self.throttle = kwargs.get('throttle', 0)
225 self.throttle = kwargs.get('throttle', 0)
228 self.exp_code = kwargs.get('exp_code', None)
226 self.exp_code = kwargs.get('exp_code', None)
229 self.plot_server = kwargs.get('plot_server', False)
227 self.plot_server = kwargs.get('plot_server', False)
230 self.sender_period = kwargs.get('sender_period', 60)
228 self.sender_period = kwargs.get('sender_period', 60)
231 self.tag = kwargs.get('tag', '')
229 self.tag = kwargs.get('tag', '')
232 self.height_index = kwargs.get('height_index', None)
230 self.height_index = kwargs.get('height_index', None)
233 self.__throttle_plot = apply_throttle(self.throttle)
231 self.__throttle_plot = apply_throttle(self.throttle)
234 self.data = PlotterData(
232 self.data = PlotterData(
235 self.CODE, self.throttle, self.exp_code, self.buffering, snr=self.showSNR)
233 self.CODE, self.throttle, self.exp_code, self.localtime, self.buffering, snr=self.showSNR)
236
234
237 if self.plot_server:
235 if self.plot_server:
238 if not self.plot_server.startswith('tcp://'):
236 if not self.plot_server.startswith('tcp://'):
239 self.plot_server = 'tcp://{}'.format(self.plot_server)
237 self.plot_server = 'tcp://{}'.format(self.plot_server)
240 log.success(
238 log.success(
241 'Sending to server: {}'.format(self.plot_server),
239 'Sending to server: {}'.format(self.plot_server),
242 self.name
240 self.name
243 )
241 )
244 if 'plot_name' in kwargs:
242 if 'plot_name' in kwargs:
245 self.plot_name = kwargs['plot_name']
243 self.plot_name = kwargs['plot_name']
246
244
247 def __setup_plot(self):
245 def __setup_plot(self):
248 '''
246 '''
249 Common setup for all figures, here figures and axes are created
247 Common setup for all figures, here figures and axes are created
250 '''
248 '''
251
249
252 self.setup()
250 self.setup()
253
251
254 self.time_label = 'LT' if self.localtime else 'UTC'
252 self.time_label = 'LT' if self.localtime else 'UTC'
255
253
256 if self.width is None:
254 if self.width is None:
257 self.width = 8
255 self.width = 8
258
256
259 self.figures = []
257 self.figures = []
260 self.axes = []
258 self.axes = []
261 self.cb_axes = []
259 self.cb_axes = []
262 self.pf_axes = []
260 self.pf_axes = []
263 self.cmaps = []
261 self.cmaps = []
264
262
265 size = '15%' if self.ncols == 1 else '30%'
263 size = '15%' if self.ncols == 1 else '30%'
266 pad = '4%' if self.ncols == 1 else '8%'
264 pad = '4%' if self.ncols == 1 else '8%'
267
265
268 if self.oneFigure:
266 if self.oneFigure:
269 if self.height is None:
267 if self.height is None:
270 self.height = 1.4 * self.nrows + 1
268 self.height = 1.4 * self.nrows + 1
271 fig = plt.figure(figsize=(self.width, self.height),
269 fig = plt.figure(figsize=(self.width, self.height),
272 edgecolor='k',
270 edgecolor='k',
273 facecolor='w')
271 facecolor='w')
274 self.figures.append(fig)
272 self.figures.append(fig)
275 for n in range(self.nplots):
273 for n in range(self.nplots):
276 ax = fig.add_subplot(self.nrows, self.ncols,
274 ax = fig.add_subplot(self.nrows, self.ncols,
277 n + 1, polar=self.polar)
275 n + 1, polar=self.polar)
278 ax.tick_params(labelsize=8)
276 ax.tick_params(labelsize=8)
279 ax.firsttime = True
277 ax.firsttime = True
280 ax.index = 0
278 ax.index = 0
281 ax.press = None
279 ax.press = None
282 self.axes.append(ax)
280 self.axes.append(ax)
283 if self.showprofile:
281 if self.showprofile:
284 cax = self.__add_axes(ax, size=size, pad=pad)
282 cax = self.__add_axes(ax, size=size, pad=pad)
285 cax.tick_params(labelsize=8)
283 cax.tick_params(labelsize=8)
286 self.pf_axes.append(cax)
284 self.pf_axes.append(cax)
287 else:
285 else:
288 if self.height is None:
286 if self.height is None:
289 self.height = 3
287 self.height = 3
290 for n in range(self.nplots):
288 for n in range(self.nplots):
291 fig = plt.figure(figsize=(self.width, self.height),
289 fig = plt.figure(figsize=(self.width, self.height),
292 edgecolor='k',
290 edgecolor='k',
293 facecolor='w')
291 facecolor='w')
294 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
292 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
295 ax.tick_params(labelsize=8)
293 ax.tick_params(labelsize=8)
296 ax.firsttime = True
294 ax.firsttime = True
297 ax.index = 0
295 ax.index = 0
298 ax.press = None
296 ax.press = None
299 self.figures.append(fig)
297 self.figures.append(fig)
300 self.axes.append(ax)
298 self.axes.append(ax)
301 if self.showprofile:
299 if self.showprofile:
302 cax = self.__add_axes(ax, size=size, pad=pad)
300 cax = self.__add_axes(ax, size=size, pad=pad)
303 cax.tick_params(labelsize=8)
301 cax.tick_params(labelsize=8)
304 self.pf_axes.append(cax)
302 self.pf_axes.append(cax)
305
303
306 for n in range(self.nrows):
304 for n in range(self.nrows):
307 if self.colormaps is not None:
305 if self.colormaps is not None:
308 cmap = plt.get_cmap(self.colormaps[n])
306 cmap = plt.get_cmap(self.colormaps[n])
309 else:
307 else:
310 cmap = plt.get_cmap(self.colormap)
308 cmap = plt.get_cmap(self.colormap)
311 cmap.set_bad(self.bgcolor, 1.)
309 cmap.set_bad(self.bgcolor, 1.)
312 self.cmaps.append(cmap)
310 self.cmaps.append(cmap)
313
311
314 def __add_axes(self, ax, size='30%', pad='8%'):
312 def __add_axes(self, ax, size='30%', pad='8%'):
315 '''
313 '''
316 Add new axes to the given figure
314 Add new axes to the given figure
317 '''
315 '''
318 divider = make_axes_locatable(ax)
316 divider = make_axes_locatable(ax)
319 nax = divider.new_horizontal(size=size, pad=pad)
317 nax = divider.new_horizontal(size=size, pad=pad)
320 ax.figure.add_axes(nax)
318 ax.figure.add_axes(nax)
321 return nax
319 return nax
322
320
323 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
321 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
324 '''
322 '''
325 Create a masked array for missing data
323 Create a masked array for missing data
326 '''
324 '''
327 if x_buffer.shape[0] < 2:
325 if x_buffer.shape[0] < 2:
328 return x_buffer, y_buffer, z_buffer
326 return x_buffer, y_buffer, z_buffer
329
327
330 deltas = x_buffer[1:] - x_buffer[0:-1]
328 deltas = x_buffer[1:] - x_buffer[0:-1]
331 x_median = numpy.median(deltas)
329 x_median = numpy.median(deltas)
332
330
333 index = numpy.where(deltas > 5 * x_median)
331 index = numpy.where(deltas > 5 * x_median)
334
332
335 if len(index[0]) != 0:
333 if len(index[0]) != 0:
336 z_buffer[::, index[0], ::] = self.__missing
334 z_buffer[::, index[0], ::] = self.__missing
337 z_buffer = numpy.ma.masked_inside(z_buffer,
335 z_buffer = numpy.ma.masked_inside(z_buffer,
338 0.99 * self.__missing,
336 0.99 * self.__missing,
339 1.01 * self.__missing)
337 1.01 * self.__missing)
340
338
341 return x_buffer, y_buffer, z_buffer
339 return x_buffer, y_buffer, z_buffer
342
340
343 def decimate(self):
341 def decimate(self):
344
342
345 # dx = int(len(self.x)/self.__MAXNUMX) + 1
343 # dx = int(len(self.x)/self.__MAXNUMX) + 1
346 dy = int(len(self.y) / self.decimation) + 1
344 dy = int(len(self.y) / self.decimation) + 1
347
345
348 # x = self.x[::dx]
346 # x = self.x[::dx]
349 x = self.x
347 x = self.x
350 y = self.y[::dy]
348 y = self.y[::dy]
351 z = self.z[::, ::, ::dy]
349 z = self.z[::, ::, ::dy]
352
350
353 return x, y, z
351 return x, y, z
354
352
355 def format(self):
353 def format(self):
356 '''
354 '''
357 Set min and max values, labels, ticks and titles
355 Set min and max values, labels, ticks and titles
358 '''
356 '''
359
357
360 if self.xmin is None:
358 if self.xmin is None:
361 xmin = self.data.min_time
359 xmin = self.data.min_time
362 else:
360 else:
363 if self.xaxis is 'time':
361 if self.xaxis is 'time':
364 dt = self.getDateTime(self.data.min_time)
362 dt = self.getDateTime(self.data.min_time)
365 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
363 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
366 datetime.datetime(1970, 1, 1)).total_seconds()
364 datetime.datetime(1970, 1, 1)).total_seconds()
367 if self.data.localtime:
365 if self.data.localtime:
368 xmin += time.timezone
366 xmin += time.timezone
369 else:
367 else:
370 xmin = self.xmin
368 xmin = self.xmin
371
369
372 if self.xmax is None:
370 if self.xmax is None:
373 xmax = xmin + self.xrange * 60 * 60
371 xmax = xmin + self.xrange * 60 * 60
374 else:
372 else:
375 if self.xaxis is 'time':
373 if self.xaxis is 'time':
376 dt = self.getDateTime(self.data.max_time)
374 dt = self.getDateTime(self.data.max_time)
377 xmax = self.xmax - 1
375 xmax = self.xmax - 1
378 xmax = (dt.replace(hour=int(xmax), minute=59, second=59) -
376 xmax = (dt.replace(hour=int(xmax), minute=59, second=59) -
379 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
377 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
380 if self.data.localtime:
378 if self.data.localtime:
381 xmax += time.timezone
379 xmax += time.timezone
382 else:
380 else:
383 xmax = self.xmax
381 xmax = self.xmax
384
382
385 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
383 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
386 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
384 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
387
385
388 for n, ax in enumerate(self.axes):
386 for n, ax in enumerate(self.axes):
389 if ax.firsttime:
387 if ax.firsttime:
390
388
391 dig = int(numpy.log10(ymax))
389 dig = int(numpy.log10(ymax))
392 if dig == 0:
390 if dig == 0:
393 digD = len(str(ymax)) - 2
391 digD = len(str(ymax)) - 2
394 ydec = ymax*(10**digD)
392 ydec = ymax*(10**digD)
395
393
396 dig = int(numpy.log10(ydec))
394 dig = int(numpy.log10(ydec))
397 ystep = ((ydec + (10**(dig)))//10**(dig))*(10**(dig))
395 ystep = ((ydec + (10**(dig)))//10**(dig))*(10**(dig))
398 ystep = ystep/5
396 ystep = ystep/5
399 ystep = ystep/(10**digD)
397 ystep = ystep/(10**digD)
400
398
401 else:
399 else:
402 ystep = ((ymax + (10**(dig)))//10**(dig))*(10**(dig))
400 ystep = ((ymax + (10**(dig)))//10**(dig))*(10**(dig))
403 ystep = ystep/5
401 ystep = ystep/5
404
402
405 if self.xaxis is not 'time':
403 if self.xaxis is not 'time':
406
404
407 dig = int(numpy.log10(xmax))
405 dig = int(numpy.log10(xmax))
408
406
409 if dig <= 0:
407 if dig <= 0:
410 digD = len(str(xmax)) - 2
408 digD = len(str(xmax)) - 2
411 xdec = xmax*(10**digD)
409 xdec = xmax*(10**digD)
412
410
413 dig = int(numpy.log10(xdec))
411 dig = int(numpy.log10(xdec))
414 xstep = ((xdec + (10**(dig)))//10**(dig))*(10**(dig))
412 xstep = ((xdec + (10**(dig)))//10**(dig))*(10**(dig))
415 xstep = xstep*0.5
413 xstep = xstep*0.5
416 xstep = xstep/(10**digD)
414 xstep = xstep/(10**digD)
417
415
418 else:
416 else:
419 xstep = ((xmax + (10**(dig)))//10**(dig))*(10**(dig))
417 xstep = ((xmax + (10**(dig)))//10**(dig))*(10**(dig))
420 xstep = xstep/5
418 xstep = xstep/5
421
419
422 ax.set_facecolor(self.bgcolor)
420 ax.set_facecolor(self.bgcolor)
423 ax.yaxis.set_major_locator(MultipleLocator(ystep))
421 ax.yaxis.set_major_locator(MultipleLocator(ystep))
424 if self.xscale:
422 if self.xscale:
425 ax.xaxis.set_major_formatter(FuncFormatter(
423 ax.xaxis.set_major_formatter(FuncFormatter(
426 lambda x, pos: '{0:g}'.format(x*self.xscale)))
424 lambda x, pos: '{0:g}'.format(x*self.xscale)))
427 if self.xscale:
425 if self.xscale:
428 ax.yaxis.set_major_formatter(FuncFormatter(
426 ax.yaxis.set_major_formatter(FuncFormatter(
429 lambda x, pos: '{0:g}'.format(x*self.yscale)))
427 lambda x, pos: '{0:g}'.format(x*self.yscale)))
430 if self.xaxis is 'time':
428 if self.xaxis is 'time':
431 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
429 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
432 ax.xaxis.set_major_locator(LinearLocator(9))
430 ax.xaxis.set_major_locator(LinearLocator(9))
433 else:
431 else:
434 ax.xaxis.set_major_locator(MultipleLocator(xstep))
432 ax.xaxis.set_major_locator(MultipleLocator(xstep))
435 if self.xlabel is not None:
433 if self.xlabel is not None:
436 ax.set_xlabel(self.xlabel)
434 ax.set_xlabel(self.xlabel)
437 ax.set_ylabel(self.ylabel)
435 ax.set_ylabel(self.ylabel)
438 ax.firsttime = False
436 ax.firsttime = False
439 if self.showprofile:
437 if self.showprofile:
440 self.pf_axes[n].set_ylim(ymin, ymax)
438 self.pf_axes[n].set_ylim(ymin, ymax)
441 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
439 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
442 self.pf_axes[n].set_xlabel('dB')
440 self.pf_axes[n].set_xlabel('dB')
443 self.pf_axes[n].grid(b=True, axis='x')
441 self.pf_axes[n].grid(b=True, axis='x')
444 [tick.set_visible(False)
442 [tick.set_visible(False)
445 for tick in self.pf_axes[n].get_yticklabels()]
443 for tick in self.pf_axes[n].get_yticklabels()]
446 if self.colorbar:
444 if self.colorbar:
447 ax.cbar = plt.colorbar(
445 ax.cbar = plt.colorbar(
448 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
446 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
449 ax.cbar.ax.tick_params(labelsize=8)
447 ax.cbar.ax.tick_params(labelsize=8)
450 ax.cbar.ax.press = None
448 ax.cbar.ax.press = None
451 if self.cb_label:
449 if self.cb_label:
452 ax.cbar.set_label(self.cb_label, size=8)
450 ax.cbar.set_label(self.cb_label, size=8)
453 elif self.cb_labels:
451 elif self.cb_labels:
454 ax.cbar.set_label(self.cb_labels[n], size=8)
452 ax.cbar.set_label(self.cb_labels[n], size=8)
455 else:
453 else:
456 ax.cbar = None
454 ax.cbar = None
457 if self.grid:
455 if self.grid:
458 ax.grid(True)
456 ax.grid(True)
459
457
460 if not self.polar:
458 if not self.polar:
461 ax.set_xlim(xmin, xmax)
459 ax.set_xlim(xmin, xmax)
462 ax.set_ylim(ymin, ymax)
460 ax.set_ylim(ymin, ymax)
463 ax.set_title('{} {} {}'.format(
461 ax.set_title('{} {} {}'.format(
464 self.titles[n],
462 self.titles[n],
465 self.getDateTime(self.data.max_time).strftime(
463 self.getDateTime(self.data.max_time).strftime(
466 '%Y-%m-%d %H:%M:%S'),
464 '%Y-%m-%d %H:%M:%S'),
467 self.time_label),
465 self.time_label),
468 size=8)
466 size=8)
469 else:
467 else:
470 ax.set_title('{}'.format(self.titles[n]), size=8)
468 ax.set_title('{}'.format(self.titles[n]), size=8)
471 ax.set_ylim(0, 90)
469 ax.set_ylim(0, 90)
472 ax.set_yticks(numpy.arange(0, 90, 20))
470 ax.set_yticks(numpy.arange(0, 90, 20))
473 ax.yaxis.labelpad = 40
471 ax.yaxis.labelpad = 40
474
472
475 if self.firsttime:
473 if self.firsttime:
476 for n, fig in enumerate(self.figures):
474 for n, fig in enumerate(self.figures):
477 fig.subplots_adjust(**self.plots_adjust)
475 fig.subplots_adjust(**self.plots_adjust)
478 self.firsttime = False
476 self.firsttime = False
479
477
480 def clear_figures(self):
478 def clear_figures(self):
481 '''
479 '''
482 Reset axes for redraw plots
480 Reset axes for redraw plots
483 '''
481 '''
484
482
485 for ax in self.axes+self.pf_axes+self.cb_axes:
483 for ax in self.axes+self.pf_axes+self.cb_axes:
486 ax.clear()
484 ax.clear()
487 ax.firsttime = True
485 ax.firsttime = True
488 if ax.cbar:
486 if hasattr(ax, 'cbar') and ax.cbar:
489 ax.cbar.remove()
487 ax.cbar.remove()
490
488
491 def __plot(self):
489 def __plot(self):
492 '''
490 '''
493 Main function to plot, format and save figures
491 Main function to plot, format and save figures
494 '''
492 '''
495
493
496 self.plot()
494 self.plot()
497 self.format()
495 self.format()
498
496
499 for n, fig in enumerate(self.figures):
497 for n, fig in enumerate(self.figures):
500 if self.nrows == 0 or self.nplots == 0:
498 if self.nrows == 0 or self.nplots == 0:
501 log.warning('No data', self.name)
499 log.warning('No data', self.name)
502 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
500 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
503 fig.canvas.manager.set_window_title(self.CODE)
501 fig.canvas.manager.set_window_title(self.CODE)
504 continue
502 continue
505
503
506 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
504 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
507 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
505 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
508 fig.canvas.draw()
506 fig.canvas.draw()
509 if self.show:
507 if self.show:
510 fig.show()
508 fig.show()
511 figpause(0.01)
509 figpause(0.01)
512
510
513 if self.save:
511 if self.save:
514 self.save_figure(n)
512 self.save_figure(n)
515
513
516 if self.plot_server:
514 if self.plot_server:
517 self.send_to_server()
515 self.send_to_server()
518
516
519 def save_figure(self, n):
517 def save_figure(self, n):
520 '''
518 '''
521 '''
519 '''
522
520
523 if self.save_counter < self.save_period:
521 if self.save_counter < self.save_period:
524 self.save_counter += 1
522 self.save_counter += 1
525 return
523 return
526
524
527 self.save_counter = 1
525 self.save_counter = 1
528
526
529 fig = self.figures[n]
527 fig = self.figures[n]
530
528
531 if self.save_code:
529 if self.save_code:
532 if isinstance(self.save_code, str):
530 if isinstance(self.save_code, str):
533 labels = [self.save_code for x in self.figures]
531 labels = [self.save_code for x in self.figures]
534 else:
532 else:
535 labels = self.save_code
533 labels = self.save_code
536 else:
534 else:
537 labels = [self.CODE for x in self.figures]
535 labels = [self.CODE for x in self.figures]
538
536
539 figname = os.path.join(
537 figname = os.path.join(
540 self.save,
538 self.save,
541 labels[n],
539 labels[n],
542 '{}_{}.png'.format(
540 '{}_{}.png'.format(
543 labels[n],
541 labels[n],
544 self.getDateTime(self.data.max_time).strftime(
542 self.getDateTime(self.data.max_time).strftime(
545 '%Y%m%d_%H%M%S'
543 '%Y%m%d_%H%M%S'
546 ),
544 ),
547 )
545 )
548 )
546 )
549 log.log('Saving figure: {}'.format(figname), self.name)
547 log.log('Saving figure: {}'.format(figname), self.name)
550 if not os.path.isdir(os.path.dirname(figname)):
548 if not os.path.isdir(os.path.dirname(figname)):
551 os.makedirs(os.path.dirname(figname))
549 os.makedirs(os.path.dirname(figname))
552 fig.savefig(figname)
550 fig.savefig(figname)
553
551
554 if self.throttle == 0:
552 if self.throttle == 0:
555 figname = os.path.join(
553 figname = os.path.join(
556 self.save,
554 self.save,
557 '{}_{}.png'.format(
555 '{}_{}.png'.format(
558 labels[n],
556 labels[n],
559 self.getDateTime(self.data.min_time).strftime(
557 self.getDateTime(self.data.min_time).strftime(
560 '%Y%m%d'
558 '%Y%m%d'
561 ),
559 ),
562 )
560 )
563 )
561 )
564 fig.savefig(figname)
562 fig.savefig(figname)
565
563
566 def send_to_server(self):
564 def send_to_server(self):
567 '''
565 '''
568 '''
566 '''
569
567
570 interval = self.data.tm - self.sender_time
568 interval = self.data.tm - self.sender_time
571 if interval < self.sender_period:
569 if interval < self.sender_period:
572 return
570 return
573
571
574 self.sender_time = self.data.tm
572 self.sender_time = self.data.tm
575
573
576 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
574 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
577 for attr in attrs:
575 for attr in attrs:
578 value = getattr(self, attr)
576 value = getattr(self, attr)
579 if value:
577 if value:
580 if isinstance(value, (numpy.float32, numpy.float64)):
578 if isinstance(value, (numpy.float32, numpy.float64)):
581 value = round(float(value), 2)
579 value = round(float(value), 2)
582 self.data.meta[attr] = value
580 self.data.meta[attr] = value
583 if self.colormap == 'jet':
581 if self.colormap == 'jet':
584 self.data.meta['colormap'] = 'Jet'
582 self.data.meta['colormap'] = 'Jet'
585 elif 'RdBu' in self.colormap:
583 elif 'RdBu' in self.colormap:
586 self.data.meta['colormap'] = 'RdBu'
584 self.data.meta['colormap'] = 'RdBu'
587 else:
585 else:
588 self.data.meta['colormap'] = 'Viridis'
586 self.data.meta['colormap'] = 'Viridis'
589 self.data.meta['interval'] = int(interval)
587 self.data.meta['interval'] = int(interval)
590 # msg = self.data.jsonify(self.data.tm, self.plot_name, self.plot_type)
588 # msg = self.data.jsonify(self.data.tm, self.plot_name, self.plot_type)
591 self.sender_queue.put(self.data.tm)
589 try:
590 self.sender_queue.put(self.data.tm, block=False)
591 except:
592 tm = self.sender_queue.get()
593 self.sender_queue.put(self.data.tm)
592
594
593 while True:
595 while True:
594 if self.sender_queue.empty():
596 if self.sender_queue.empty():
595 break
597 break
596 tm = self.sender_queue.get()
598 tm = self.sender_queue.get()
597 msg = self.data.jsonify(tm, self.plot_name, self.plot_type)
599 try:
600 msg = self.data.jsonify(tm, self.plot_name, self.plot_type)
601 except:
602 continue
598 self.socket.send_string(msg)
603 self.socket.send_string(msg)
599 socks = dict(self.poll.poll(5000))
604 socks = dict(self.poll.poll(5000))
600 if socks.get(self.socket) == zmq.POLLIN:
605 if socks.get(self.socket) == zmq.POLLIN:
601 reply = self.socket.recv_string()
606 reply = self.socket.recv_string()
602 if reply == 'ok':
607 if reply == 'ok':
603 log.log("Response from server ok", self.name)
608 log.log("Response from server ok", self.name)
604 time.sleep(0.1)
609 time.sleep(0.2)
605 continue
610 continue
606 else:
611 else:
607 log.warning(
612 log.warning(
608 "Malformed reply from server: {}".format(reply), self.name)
613 "Malformed reply from server: {}".format(reply), self.name)
609 else:
614 else:
610 log.warning(
615 log.warning(
611 "No response from server, retrying...", self.name)
616 "No response from server, retrying...", self.name)
612 self.sender_queue.put(self.data.tm)
617 self.sender_queue.put(self.data.tm)
613 self.socket.setsockopt(zmq.LINGER, 0)
618 self.socket.setsockopt(zmq.LINGER, 0)
614 self.socket.close()
619 self.socket.close()
615 self.poll.unregister(self.socket)
620 self.poll.unregister(self.socket)
616 time.sleep(0.1)
621 time.sleep(0.1)
617 self.socket = self.context.socket(zmq.REQ)
622 self.socket = self.context.socket(zmq.REQ)
618 self.socket.connect(self.plot_server)
623 self.socket.connect(self.plot_server)
619 self.poll.register(self.socket, zmq.POLLIN)
624 self.poll.register(self.socket, zmq.POLLIN)
620 break
625 break
621
626
622 def setup(self):
627 def setup(self):
623 '''
628 '''
624 This method should be implemented in the child class, the following
629 This method should be implemented in the child class, the following
625 attributes should be set:
630 attributes should be set:
626
631
627 self.nrows: number of rows
632 self.nrows: number of rows
628 self.ncols: number of cols
633 self.ncols: number of cols
629 self.nplots: number of plots (channels or pairs)
634 self.nplots: number of plots (channels or pairs)
630 self.ylabel: label for Y axes
635 self.ylabel: label for Y axes
631 self.titles: list of axes title
636 self.titles: list of axes title
632
637
633 '''
638 '''
634 raise NotImplementedError
639 raise NotImplementedError
635
640
636 def plot(self):
641 def plot(self):
637 '''
642 '''
638 Must be defined in the child class
643 Must be defined in the child class
639 '''
644 '''
640 raise NotImplementedError
645 raise NotImplementedError
641
646
642 def run(self, dataOut, **kwargs):
647 def run(self, dataOut, **kwargs):
643 '''
648 '''
644 Main plotting routine
649 Main plotting routine
645 '''
650 '''
646
651
647 if self.isConfig is False:
652 if self.isConfig is False:
648 self.__setup(**kwargs)
653 self.__setup(**kwargs)
649
654
650 t = getattr(dataOut, self.attr_time)
655 t = getattr(dataOut, self.attr_time)
651
656
652 if dataOut.useLocalTime:
657 if self.localtime:
653 self.getDateTime = datetime.datetime.fromtimestamp
658 self.getDateTime = datetime.datetime.fromtimestamp
654 if not self.localtime:
655 t += time.timezone
656 else:
659 else:
657 self.getDateTime = datetime.datetime.utcfromtimestamp
660 self.getDateTime = datetime.datetime.utcfromtimestamp
658 if self.localtime:
659 t -= time.timezone
660
661
661 if self.xmin is None:
662 if self.xmin is None:
662 self.tmin = t
663 self.tmin = t
663 if 'buffer' in self.plot_type:
664 if 'buffer' in self.plot_type:
664 self.xmin = self.getDateTime(t).hour
665 self.xmin = self.getDateTime(t).hour
665 else:
666 else:
666 self.tmin = (
667 self.tmin = (
667 self.getDateTime(t).replace(
668 self.getDateTime(t).replace(
668 hour=int(self.xmin),
669 hour=int(self.xmin),
669 minute=0,
670 minute=0,
670 second=0) - self.getDateTime(0)).total_seconds()
671 second=0) - self.getDateTime(0)).total_seconds()
671
672
672 self.data.setup()
673 self.data.setup()
673 self.isConfig = True
674 self.isConfig = True
674 if self.plot_server:
675 if self.plot_server:
675 self.context = zmq.Context()
676 self.context = zmq.Context()
676 self.socket = self.context.socket(zmq.REQ)
677 self.socket = self.context.socket(zmq.REQ)
677 self.socket.connect(self.plot_server)
678 self.socket.connect(self.plot_server)
678 self.poll = zmq.Poller()
679 self.poll = zmq.Poller()
679 self.poll.register(self.socket, zmq.POLLIN)
680 self.poll.register(self.socket, zmq.POLLIN)
680
681
681 tm = getattr(dataOut, self.attr_time)
682 tm = getattr(dataOut, self.attr_time)
682
683 if not dataOut.useLocalTime and self.localtime:
684 tm -= time.timezone
685 if dataOut.useLocalTime and not self.localtime:
686 tm += time.timezone
687
683
688 if self.data and (tm - self.tmin) >= self.xrange*60*60:
684 if self.data and (tm - self.tmin) >= self.xrange*60*60:
689 self.save_counter = self.save_period
685 self.save_counter = self.save_period
690 self.__plot()
686 self.__plot()
691 if 'time' in self.xaxis:
687 if 'time' in self.xaxis:
692 self.xmin += self.xrange
688 self.xmin += self.xrange
693 if self.xmin >= 24:
689 if self.xmin >= 24:
694 self.xmin -= 24
690 self.xmin -= 24
695 self.tmin += self.xrange*60*60
691 self.tmin += self.xrange*60*60
696 self.data.setup()
692 self.data.setup()
697 self.clear_figures()
693 self.clear_figures()
698
694
699 self.data.update(dataOut, tm)
695 self.data.update(dataOut, tm)
700
696
701 if self.isPlotConfig is False:
697 if self.isPlotConfig is False:
702 self.__setup_plot()
698 self.__setup_plot()
703 self.isPlotConfig = True
699 self.isPlotConfig = True
704
700
705 if self.throttle == 0:
701 if self.throttle == 0:
706 self.__plot()
702 self.__plot()
707 else:
703 else:
708 self.__throttle_plot(self.__plot)#, coerce=coerce)
704 self.__throttle_plot(self.__plot)#, coerce=coerce)
709
705
710 def close(self):
706 def close(self):
711
707
712 if self.data and not self.data.flagNoData:
708 if self.data and not self.data.flagNoData:
713 self.save_counter = self.save_period
709 self.save_counter = self.save_period
714 self.__plot()
710 self.__plot()
715 if self.data and not self.data.flagNoData and self.pause:
711 if self.data and not self.data.flagNoData and self.pause:
716 figpause(10)
712 figpause(10)
717
713
General Comments 0
You need to be logged in to leave comments. Login now