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