##// END OF EJS Templates
DP+LP Join Spc+Voltage
rflores -
r1549:c70288c93a07
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,1079 +1,1079
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 #print(numpy.shape(data))
79 #print(numpy.shape(data))
80 #exit()
80 #exit()
81 '''
81 '''
82 lenOfData = len(sortdata)
82 lenOfData = len(sortdata)
83 nums_min = lenOfData*0.2
83 nums_min = lenOfData*0.2
84
84
85 if nums_min <= 5:
85 if nums_min <= 5:
86
86
87 nums_min = 5
87 nums_min = 5
88
88
89 sump = 0.
89 sump = 0.
90 sumq = 0.
90 sumq = 0.
91
91
92 j = 0
92 j = 0
93 cont = 1
93 cont = 1
94
94
95 while((cont == 1)and(j < lenOfData)):
95 while((cont == 1)and(j < lenOfData)):
96
96
97 sump += sortdata[j]
97 sump += sortdata[j]
98 sumq += sortdata[j]**2
98 sumq += sortdata[j]**2
99
99
100 if j > nums_min:
100 if j > nums_min:
101 rtest = float(j)/(j-1) + 1.0/navg
101 rtest = float(j)/(j-1) + 1.0/navg
102 if ((sumq*j) > (rtest*sump**2)):
102 if ((sumq*j) > (rtest*sump**2)):
103 j = j - 1
103 j = j - 1
104 sump = sump - sortdata[j]
104 sump = sump - sortdata[j]
105 sumq = sumq - sortdata[j]**2
105 sumq = sumq - sortdata[j]**2
106 cont = 0
106 cont = 0
107
107
108 j += 1
108 j += 1
109
109
110 lnoise = sump / j
110 lnoise = sump / j
111
111
112 return lnoise
112 return lnoise
113 '''
113 '''
114 return _noise.hildebrand_sekhon(sortdata, navg)
114 return _noise.hildebrand_sekhon(sortdata, navg)
115
115
116
116
117 class Beam:
117 class Beam:
118
118
119 def __init__(self):
119 def __init__(self):
120 self.codeList = []
120 self.codeList = []
121 self.azimuthList = []
121 self.azimuthList = []
122 self.zenithList = []
122 self.zenithList = []
123
123
124
124
125 class GenericData(object):
125 class GenericData(object):
126
126
127 flagNoData = True
127 flagNoData = True
128
128
129 def copy(self, inputObj=None):
129 def copy(self, inputObj=None):
130
130
131 if inputObj == None:
131 if inputObj == None:
132 return copy.deepcopy(self)
132 return copy.deepcopy(self)
133
133
134 for key in list(inputObj.__dict__.keys()):
134 for key in list(inputObj.__dict__.keys()):
135
135
136 attribute = inputObj.__dict__[key]
136 attribute = inputObj.__dict__[key]
137
137
138 # If this attribute is a tuple or list
138 # If this attribute is a tuple or list
139 if type(inputObj.__dict__[key]) in (tuple, list):
139 if type(inputObj.__dict__[key]) in (tuple, list):
140 self.__dict__[key] = attribute[:]
140 self.__dict__[key] = attribute[:]
141 continue
141 continue
142
142
143 # If this attribute is another object or instance
143 # If this attribute is another object or instance
144 if hasattr(attribute, '__dict__'):
144 if hasattr(attribute, '__dict__'):
145 self.__dict__[key] = attribute.copy()
145 self.__dict__[key] = attribute.copy()
146 continue
146 continue
147
147
148 self.__dict__[key] = inputObj.__dict__[key]
148 self.__dict__[key] = inputObj.__dict__[key]
149
149
150 def deepcopy(self):
150 def deepcopy(self):
151
151
152 return copy.deepcopy(self)
152 return copy.deepcopy(self)
153
153
154 def isEmpty(self):
154 def isEmpty(self):
155
155
156 return self.flagNoData
156 return self.flagNoData
157
157
158 def isReady(self):
158 def isReady(self):
159
159
160 return not self.flagNoData
160 return not self.flagNoData
161
161
162
162
163 class JROData(GenericData):
163 class JROData(GenericData):
164
164
165 systemHeaderObj = SystemHeader()
165 systemHeaderObj = SystemHeader()
166 radarControllerHeaderObj = RadarControllerHeader()
166 radarControllerHeaderObj = RadarControllerHeader()
167 type = None
167 type = None
168 datatype = None # dtype but in string
168 datatype = None # dtype but in string
169 nProfiles = None
169 nProfiles = None
170 heightList = None
170 heightList = None
171 channelList = None
171 channelList = None
172 flagDiscontinuousBlock = False
172 flagDiscontinuousBlock = False
173 useLocalTime = False
173 useLocalTime = False
174 utctime = None
174 utctime = None
175 timeZone = None
175 timeZone = None
176 dstFlag = None
176 dstFlag = None
177 errorCount = None
177 errorCount = None
178 blocksize = None
178 blocksize = 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 nCohInt = None
182 nCohInt = None
183 windowOfFilter = 1
183 windowOfFilter = 1
184 C = 3e8
184 C = 3e8
185 frequency = 49.92e6
185 frequency = 49.92e6
186 realtime = False
186 realtime = False
187 beacon_heiIndexList = None
187 beacon_heiIndexList = None
188 last_block = None
188 last_block = None
189 blocknow = None
189 blocknow = None
190 azimuth = None
190 azimuth = None
191 zenith = None
191 zenith = None
192 beam = Beam()
192 beam = Beam()
193 profileIndex = None
193 profileIndex = None
194 error = None
194 error = None
195 data = None
195 data = None
196 nmodes = None
196 nmodes = None
197 metadata_list = ['heightList', 'timeZone', 'type']
197 metadata_list = ['heightList', 'timeZone', 'type']
198
198
199 def __str__(self):
199 def __str__(self):
200
200
201 return '{} - {}'.format(self.type, self.datatime())
201 return '{} - {}'.format(self.type, self.datatime())
202
202
203 def getNoise(self):
203 def getNoise(self):
204
204
205 raise NotImplementedError
205 raise NotImplementedError
206
206
207 @property
207 @property
208 def nChannels(self):
208 def nChannels(self):
209
209
210 return len(self.channelList)
210 return len(self.channelList)
211
211
212 @property
212 @property
213 def channelIndexList(self):
213 def channelIndexList(self):
214
214
215 return list(range(self.nChannels))
215 return list(range(self.nChannels))
216
216
217 @property
217 @property
218 def nHeights(self):
218 def nHeights(self):
219
219
220 return len(self.heightList)
220 return len(self.heightList)
221
221
222 def getDeltaH(self):
222 def getDeltaH(self):
223
223
224 return self.heightList[1] - self.heightList[0]
224 return self.heightList[1] - self.heightList[0]
225
225
226 @property
226 @property
227 def ltctime(self):
227 def ltctime(self):
228
228
229 if self.useLocalTime:
229 if self.useLocalTime:
230 return self.utctime - self.timeZone * 60
230 return self.utctime - self.timeZone * 60
231
231
232 return self.utctime
232 return self.utctime
233
233
234 @property
234 @property
235 def datatime(self):
235 def datatime(self):
236
236
237 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
237 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
238 return datatimeValue
238 return datatimeValue
239
239
240 def getTimeRange(self):
240 def getTimeRange(self):
241
241
242 datatime = []
242 datatime = []
243
243
244 datatime.append(self.ltctime)
244 datatime.append(self.ltctime)
245 datatime.append(self.ltctime + self.timeInterval + 1)
245 datatime.append(self.ltctime + self.timeInterval + 1)
246
246
247 datatime = numpy.array(datatime)
247 datatime = numpy.array(datatime)
248
248
249 return datatime
249 return datatime
250
250
251 def getFmaxTimeResponse(self):
251 def getFmaxTimeResponse(self):
252
252
253 period = (10**-6) * self.getDeltaH() / (0.15)
253 period = (10**-6) * self.getDeltaH() / (0.15)
254
254
255 PRF = 1. / (period * self.nCohInt)
255 PRF = 1. / (period * self.nCohInt)
256
256
257 fmax = PRF
257 fmax = PRF
258
258
259 return fmax
259 return fmax
260
260
261 def getFmax(self):
261 def getFmax(self):
262 PRF = 1. / (self.ippSeconds * self.nCohInt)
262 PRF = 1. / (self.ippSeconds * self.nCohInt)
263
263 #print("ippsec",self.ippSeconds)
264 fmax = PRF
264 fmax = PRF
265 return fmax
265 return fmax
266
266
267 def getVmax(self):
267 def getVmax(self):
268
268
269 _lambda = self.C / self.frequency
269 _lambda = self.C / self.frequency
270
270
271 vmax = self.getFmax() * _lambda / 2
271 vmax = self.getFmax() * _lambda / 2
272
272
273 return vmax
273 return vmax
274
274
275 @property
275 @property
276 def ippSeconds(self):
276 def ippSeconds(self):
277 '''
277 '''
278 '''
278 '''
279 return self.radarControllerHeaderObj.ippSeconds
279 return self.radarControllerHeaderObj.ippSeconds
280
280
281 @ippSeconds.setter
281 @ippSeconds.setter
282 def ippSeconds(self, ippSeconds):
282 def ippSeconds(self, ippSeconds):
283 '''
283 '''
284 '''
284 '''
285 self.radarControllerHeaderObj.ippSeconds = ippSeconds
285 self.radarControllerHeaderObj.ippSeconds = ippSeconds
286
286
287 @property
287 @property
288 def code(self):
288 def code(self):
289 '''
289 '''
290 '''
290 '''
291 return self.radarControllerHeaderObj.code
291 return self.radarControllerHeaderObj.code
292
292
293 @code.setter
293 @code.setter
294 def code(self, code):
294 def code(self, code):
295 '''
295 '''
296 '''
296 '''
297 self.radarControllerHeaderObj.code = code
297 self.radarControllerHeaderObj.code = code
298
298
299 @property
299 @property
300 def nCode(self):
300 def nCode(self):
301 '''
301 '''
302 '''
302 '''
303 return self.radarControllerHeaderObj.nCode
303 return self.radarControllerHeaderObj.nCode
304
304
305 @nCode.setter
305 @nCode.setter
306 def nCode(self, ncode):
306 def nCode(self, ncode):
307 '''
307 '''
308 '''
308 '''
309 self.radarControllerHeaderObj.nCode = ncode
309 self.radarControllerHeaderObj.nCode = ncode
310
310
311 @property
311 @property
312 def nBaud(self):
312 def nBaud(self):
313 '''
313 '''
314 '''
314 '''
315 return self.radarControllerHeaderObj.nBaud
315 return self.radarControllerHeaderObj.nBaud
316
316
317 @nBaud.setter
317 @nBaud.setter
318 def nBaud(self, nbaud):
318 def nBaud(self, nbaud):
319 '''
319 '''
320 '''
320 '''
321 self.radarControllerHeaderObj.nBaud = nbaud
321 self.radarControllerHeaderObj.nBaud = nbaud
322
322
323 @property
323 @property
324 def ipp(self):
324 def ipp(self):
325 '''
325 '''
326 '''
326 '''
327 return self.radarControllerHeaderObj.ipp
327 return self.radarControllerHeaderObj.ipp
328
328
329 @ipp.setter
329 @ipp.setter
330 def ipp(self, ipp):
330 def ipp(self, ipp):
331 '''
331 '''
332 '''
332 '''
333 self.radarControllerHeaderObj.ipp = ipp
333 self.radarControllerHeaderObj.ipp = ipp
334
334
335 @property
335 @property
336 def metadata(self):
336 def metadata(self):
337 '''
337 '''
338 '''
338 '''
339
339
340 return {attr: getattr(self, attr) for attr in self.metadata_list}
340 return {attr: getattr(self, attr) for attr in self.metadata_list}
341
341
342
342
343 class Voltage(JROData):
343 class Voltage(JROData):
344
344
345 dataPP_POW = None
345 dataPP_POW = None
346 dataPP_DOP = None
346 dataPP_DOP = None
347 dataPP_WIDTH = None
347 dataPP_WIDTH = None
348 dataPP_SNR = None
348 dataPP_SNR = None
349
349
350 def __init__(self):
350 def __init__(self):
351 '''
351 '''
352 Constructor
352 Constructor
353 '''
353 '''
354
354
355 self.useLocalTime = True
355 self.useLocalTime = True
356 self.radarControllerHeaderObj = RadarControllerHeader()
356 self.radarControllerHeaderObj = RadarControllerHeader()
357 self.systemHeaderObj = SystemHeader()
357 self.systemHeaderObj = SystemHeader()
358 self.type = "Voltage"
358 self.type = "Voltage"
359 self.data = None
359 self.data = None
360 self.nProfiles = None
360 self.nProfiles = None
361 self.heightList = None
361 self.heightList = None
362 self.channelList = None
362 self.channelList = None
363 self.flagNoData = True
363 self.flagNoData = True
364 self.flagDiscontinuousBlock = False
364 self.flagDiscontinuousBlock = False
365 self.utctime = None
365 self.utctime = None
366 self.timeZone = 0
366 self.timeZone = 0
367 self.dstFlag = None
367 self.dstFlag = None
368 self.errorCount = None
368 self.errorCount = None
369 self.nCohInt = None
369 self.nCohInt = None
370 self.blocksize = None
370 self.blocksize = None
371 self.flagCohInt = False
371 self.flagCohInt = False
372 self.flagDecodeData = False # asumo q la data no esta decodificada
372 self.flagDecodeData = False # asumo q la data no esta decodificada
373 self.flagDeflipData = False # asumo q la data no esta sin flip
373 self.flagDeflipData = False # asumo q la data no esta sin flip
374 self.flagShiftFFT = False
374 self.flagShiftFFT = False
375 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
375 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
376 self.profileIndex = 0
376 self.profileIndex = 0
377 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
377 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
378 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
378 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
379
379
380 def getNoisebyHildebrand(self, channel=None, Profmin_index=None, Profmax_index=None):
380 def getNoisebyHildebrand(self, channel=None, Profmin_index=None, Profmax_index=None):
381 """
381 """
382 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
382 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
383
383
384 Return:
384 Return:
385 noiselevel
385 noiselevel
386 """
386 """
387
387
388 if channel != None:
388 if channel != None:
389 data = self.data[channel]
389 data = self.data[channel]
390 nChannels = 1
390 nChannels = 1
391 else:
391 else:
392 data = self.data
392 data = self.data
393 nChannels = self.nChannels
393 nChannels = self.nChannels
394
394
395 noise = numpy.zeros(nChannels)
395 noise = numpy.zeros(nChannels)
396 power = data * numpy.conjugate(data)
396 power = data * numpy.conjugate(data)
397
397
398 for thisChannel in range(nChannels):
398 for thisChannel in range(nChannels):
399 if nChannels == 1:
399 if nChannels == 1:
400 daux = power[:].real
400 daux = power[:].real
401 else:
401 else:
402 #print(power.shape)
402 #print(power.shape)
403 daux = power[thisChannel, Profmin_index:Profmax_index, :].real
403 daux = power[thisChannel, Profmin_index:Profmax_index, :].real
404 #print(daux.shape)
404 #print(daux.shape)
405 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
405 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
406
406
407 return noise
407 return noise
408
408
409 def getNoise(self, type=1, channel=None, Profmin_index=None, Profmax_index=None):
409 def getNoise(self, type=1, channel=None, Profmin_index=None, Profmax_index=None):
410
410
411 if type == 1:
411 if type == 1:
412 noise = self.getNoisebyHildebrand(channel, Profmin_index, Profmax_index)
412 noise = self.getNoisebyHildebrand(channel, Profmin_index, Profmax_index)
413
413
414 return noise
414 return noise
415
415
416 def getPower(self, channel=None):
416 def getPower(self, channel=None):
417
417
418 if channel != None:
418 if channel != None:
419 data = self.data[channel]
419 data = self.data[channel]
420 else:
420 else:
421 data = self.data
421 data = self.data
422
422
423 power = data * numpy.conjugate(data)
423 power = data * numpy.conjugate(data)
424 powerdB = 10 * numpy.log10(power.real)
424 powerdB = 10 * numpy.log10(power.real)
425 powerdB = numpy.squeeze(powerdB)
425 powerdB = numpy.squeeze(powerdB)
426
426
427 return powerdB
427 return powerdB
428
428
429 @property
429 @property
430 def timeInterval(self):
430 def timeInterval(self):
431
431
432 return self.ippSeconds * self.nCohInt
432 return self.ippSeconds * self.nCohInt
433
433
434 noise = property(getNoise, "I'm the 'nHeights' property.")
434 noise = property(getNoise, "I'm the 'nHeights' property.")
435
435
436
436
437 class Spectra(JROData):
437 class Spectra(JROData):
438
438
439 def __init__(self):
439 def __init__(self):
440 '''
440 '''
441 Constructor
441 Constructor
442 '''
442 '''
443
443
444 self.data_dc = None
444 self.data_dc = None
445 self.data_spc = None
445 self.data_spc = None
446 self.data_cspc = None
446 self.data_cspc = None
447 self.useLocalTime = True
447 self.useLocalTime = True
448 self.radarControllerHeaderObj = RadarControllerHeader()
448 self.radarControllerHeaderObj = RadarControllerHeader()
449 self.systemHeaderObj = SystemHeader()
449 self.systemHeaderObj = SystemHeader()
450 self.type = "Spectra"
450 self.type = "Spectra"
451 self.timeZone = 0
451 self.timeZone = 0
452 self.nProfiles = None
452 self.nProfiles = None
453 self.heightList = None
453 self.heightList = None
454 self.channelList = None
454 self.channelList = None
455 self.pairsList = None
455 self.pairsList = None
456 self.flagNoData = True
456 self.flagNoData = True
457 self.flagDiscontinuousBlock = False
457 self.flagDiscontinuousBlock = False
458 self.utctime = None
458 self.utctime = None
459 self.nCohInt = None
459 self.nCohInt = None
460 self.nIncohInt = None
460 self.nIncohInt = None
461 self.blocksize = None
461 self.blocksize = None
462 self.nFFTPoints = None
462 self.nFFTPoints = None
463 self.wavelength = None
463 self.wavelength = None
464 self.flagDecodeData = False # asumo q la data no esta decodificada
464 self.flagDecodeData = False # asumo q la data no esta decodificada
465 self.flagDeflipData = False # asumo q la data no esta sin flip
465 self.flagDeflipData = False # asumo q la data no esta sin flip
466 self.flagShiftFFT = False
466 self.flagShiftFFT = False
467 self.ippFactor = 1
467 self.ippFactor = 1
468 self.beacon_heiIndexList = []
468 self.beacon_heiIndexList = []
469 self.noise_estimation = None
469 self.noise_estimation = None
470 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
470 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
471 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
471 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
472
472
473 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
473 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
474 """
474 """
475 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
475 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
476
476
477 Return:
477 Return:
478 noiselevel
478 noiselevel
479 """
479 """
480
480
481 noise = numpy.zeros(self.nChannels)
481 noise = numpy.zeros(self.nChannels)
482
482
483 for channel in range(self.nChannels):
483 for channel in range(self.nChannels):
484 #print(self.data_spc[0])
484 #print(self.data_spc[0])
485 #exit(1)
485 #exit(1)
486 daux = self.data_spc[channel,
486 daux = self.data_spc[channel,
487 xmin_index:xmax_index, ymin_index:ymax_index]
487 xmin_index:xmax_index, ymin_index:ymax_index]
488 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
488 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
489
489
490 return noise
490 return noise
491
491
492 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
492 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
493
493
494 if self.noise_estimation is not None:
494 if self.noise_estimation is not None:
495 # this was estimated by getNoise Operation defined in jroproc_spectra.py
495 # this was estimated by getNoise Operation defined in jroproc_spectra.py
496 return self.noise_estimation
496 return self.noise_estimation
497 else:
497 else:
498
498
499 noise = self.getNoisebyHildebrand(
499 noise = self.getNoisebyHildebrand(
500 xmin_index, xmax_index, ymin_index, ymax_index)
500 xmin_index, xmax_index, ymin_index, ymax_index)
501 return noise
501 return noise
502
502
503 def getFreqRangeTimeResponse(self, extrapoints=0):
503 def getFreqRangeTimeResponse(self, extrapoints=0):
504
504
505 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
505 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
506 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
506 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
507
507
508 return freqrange
508 return freqrange
509
509
510 def getAcfRange(self, extrapoints=0):
510 def getAcfRange(self, extrapoints=0):
511
511
512 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
512 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
513 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
513 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
514
514
515 return freqrange
515 return freqrange
516
516
517 def getFreqRange(self, extrapoints=0):
517 def getFreqRange(self, extrapoints=0):
518
518
519 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
519 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
520 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
520 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
521
521
522 return freqrange
522 return freqrange
523
523
524 def getVelRange(self, extrapoints=0):
524 def getVelRange(self, extrapoints=0):
525
525
526 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
526 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
527 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
527 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
528
528
529 if self.nmodes:
529 if self.nmodes:
530 return velrange/self.nmodes
530 return velrange/self.nmodes
531 else:
531 else:
532 return velrange
532 return velrange
533
533
534 @property
534 @property
535 def nPairs(self):
535 def nPairs(self):
536
536
537 return len(self.pairsList)
537 return len(self.pairsList)
538
538
539 @property
539 @property
540 def pairsIndexList(self):
540 def pairsIndexList(self):
541
541
542 return list(range(self.nPairs))
542 return list(range(self.nPairs))
543
543
544 @property
544 @property
545 def normFactor(self):
545 def normFactor(self):
546
546
547 pwcode = 1
547 pwcode = 1
548
548
549 if self.flagDecodeData:
549 if self.flagDecodeData:
550 pwcode = numpy.sum(self.code[0]**2)
550 pwcode = numpy.sum(self.code[0]**2)
551 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
551 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
552 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
552 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
553
553
554 return normFactor
554 return normFactor
555
555
556 @property
556 @property
557 def flag_cspc(self):
557 def flag_cspc(self):
558
558
559 if self.data_cspc is None:
559 if self.data_cspc is None:
560 return True
560 return True
561
561
562 return False
562 return False
563
563
564 @property
564 @property
565 def flag_dc(self):
565 def flag_dc(self):
566
566
567 if self.data_dc is None:
567 if self.data_dc is None:
568 return True
568 return True
569
569
570 return False
570 return False
571
571
572 @property
572 @property
573 def timeInterval(self):
573 def timeInterval(self):
574
574
575 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
575 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
576 if self.nmodes:
576 if self.nmodes:
577 return self.nmodes*timeInterval
577 return self.nmodes*timeInterval
578 else:
578 else:
579 return timeInterval
579 return timeInterval
580
580
581 def getPower(self):
581 def getPower(self):
582
582
583 factor = self.normFactor
583 factor = self.normFactor
584 z = self.data_spc / factor
584 z = self.data_spc / factor
585 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
585 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
586 avg = numpy.average(z, axis=1)
586 avg = numpy.average(z, axis=1)
587
587
588 return 10 * numpy.log10(avg)
588 return 10 * numpy.log10(avg)
589
589
590 def getCoherence(self, pairsList=None, phase=False):
590 def getCoherence(self, pairsList=None, phase=False):
591
591
592 z = []
592 z = []
593 if pairsList is None:
593 if pairsList is None:
594 pairsIndexList = self.pairsIndexList
594 pairsIndexList = self.pairsIndexList
595 else:
595 else:
596 pairsIndexList = []
596 pairsIndexList = []
597 for pair in pairsList:
597 for pair in pairsList:
598 if pair not in self.pairsList:
598 if pair not in self.pairsList:
599 raise ValueError("Pair %s is not in dataOut.pairsList" % (
599 raise ValueError("Pair %s is not in dataOut.pairsList" % (
600 pair))
600 pair))
601 pairsIndexList.append(self.pairsList.index(pair))
601 pairsIndexList.append(self.pairsList.index(pair))
602 for i in range(len(pairsIndexList)):
602 for i in range(len(pairsIndexList)):
603 pair = self.pairsList[pairsIndexList[i]]
603 pair = self.pairsList[pairsIndexList[i]]
604 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
604 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
605 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
605 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
606 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
606 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
607 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
607 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
608 if phase:
608 if phase:
609 data = numpy.arctan2(avgcoherenceComplex.imag,
609 data = numpy.arctan2(avgcoherenceComplex.imag,
610 avgcoherenceComplex.real) * 180 / numpy.pi
610 avgcoherenceComplex.real) * 180 / numpy.pi
611 else:
611 else:
612 data = numpy.abs(avgcoherenceComplex)
612 data = numpy.abs(avgcoherenceComplex)
613
613
614 z.append(data)
614 z.append(data)
615
615
616 return numpy.array(z)
616 return numpy.array(z)
617
617
618 def setValue(self, value):
618 def setValue(self, value):
619
619
620 print("This property should not be initialized")
620 print("This property should not be initialized")
621
621
622 return
622 return
623
623
624 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
624 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
625
625
626
626
627 class SpectraHeis(Spectra):
627 class SpectraHeis(Spectra):
628
628
629 def __init__(self):
629 def __init__(self):
630
630
631 self.radarControllerHeaderObj = RadarControllerHeader()
631 self.radarControllerHeaderObj = RadarControllerHeader()
632 self.systemHeaderObj = SystemHeader()
632 self.systemHeaderObj = SystemHeader()
633 self.type = "SpectraHeis"
633 self.type = "SpectraHeis"
634 self.nProfiles = None
634 self.nProfiles = None
635 self.heightList = None
635 self.heightList = None
636 self.channelList = None
636 self.channelList = None
637 self.flagNoData = True
637 self.flagNoData = True
638 self.flagDiscontinuousBlock = False
638 self.flagDiscontinuousBlock = False
639 self.utctime = None
639 self.utctime = None
640 self.blocksize = None
640 self.blocksize = None
641 self.profileIndex = 0
641 self.profileIndex = 0
642 self.nCohInt = 1
642 self.nCohInt = 1
643 self.nIncohInt = 1
643 self.nIncohInt = 1
644
644
645 @property
645 @property
646 def normFactor(self):
646 def normFactor(self):
647 pwcode = 1
647 pwcode = 1
648 if self.flagDecodeData:
648 if self.flagDecodeData:
649 pwcode = numpy.sum(self.code[0]**2)
649 pwcode = numpy.sum(self.code[0]**2)
650
650
651 normFactor = self.nIncohInt * self.nCohInt * pwcode
651 normFactor = self.nIncohInt * self.nCohInt * pwcode
652
652
653 return normFactor
653 return normFactor
654
654
655 @property
655 @property
656 def timeInterval(self):
656 def timeInterval(self):
657
657
658 return self.ippSeconds * self.nCohInt * self.nIncohInt
658 return self.ippSeconds * self.nCohInt * self.nIncohInt
659
659
660
660
661 class Fits(JROData):
661 class Fits(JROData):
662
662
663 def __init__(self):
663 def __init__(self):
664
664
665 self.type = "Fits"
665 self.type = "Fits"
666 self.nProfiles = None
666 self.nProfiles = None
667 self.heightList = None
667 self.heightList = None
668 self.channelList = None
668 self.channelList = None
669 self.flagNoData = True
669 self.flagNoData = True
670 self.utctime = None
670 self.utctime = None
671 self.nCohInt = 1
671 self.nCohInt = 1
672 self.nIncohInt = 1
672 self.nIncohInt = 1
673 self.useLocalTime = True
673 self.useLocalTime = True
674 self.profileIndex = 0
674 self.profileIndex = 0
675 self.timeZone = 0
675 self.timeZone = 0
676
676
677 def getTimeRange(self):
677 def getTimeRange(self):
678
678
679 datatime = []
679 datatime = []
680
680
681 datatime.append(self.ltctime)
681 datatime.append(self.ltctime)
682 datatime.append(self.ltctime + self.timeInterval)
682 datatime.append(self.ltctime + self.timeInterval)
683
683
684 datatime = numpy.array(datatime)
684 datatime = numpy.array(datatime)
685
685
686 return datatime
686 return datatime
687
687
688 def getChannelIndexList(self):
688 def getChannelIndexList(self):
689
689
690 return list(range(self.nChannels))
690 return list(range(self.nChannels))
691
691
692 def getNoise(self, type=1):
692 def getNoise(self, type=1):
693
693
694
694
695 if type == 1:
695 if type == 1:
696 noise = self.getNoisebyHildebrand()
696 noise = self.getNoisebyHildebrand()
697
697
698 if type == 2:
698 if type == 2:
699 noise = self.getNoisebySort()
699 noise = self.getNoisebySort()
700
700
701 if type == 3:
701 if type == 3:
702 noise = self.getNoisebyWindow()
702 noise = self.getNoisebyWindow()
703
703
704 return noise
704 return noise
705
705
706 @property
706 @property
707 def timeInterval(self):
707 def timeInterval(self):
708
708
709 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
709 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
710
710
711 return timeInterval
711 return timeInterval
712
712
713 @property
713 @property
714 def ippSeconds(self):
714 def ippSeconds(self):
715 '''
715 '''
716 '''
716 '''
717 return self.ipp_sec
717 return self.ipp_sec
718
718
719 noise = property(getNoise, "I'm the 'nHeights' property.")
719 noise = property(getNoise, "I'm the 'nHeights' property.")
720
720
721
721
722 class Correlation(JROData):
722 class Correlation(JROData):
723
723
724 def __init__(self):
724 def __init__(self):
725 '''
725 '''
726 Constructor
726 Constructor
727 '''
727 '''
728 self.radarControllerHeaderObj = RadarControllerHeader()
728 self.radarControllerHeaderObj = RadarControllerHeader()
729 self.systemHeaderObj = SystemHeader()
729 self.systemHeaderObj = SystemHeader()
730 self.type = "Correlation"
730 self.type = "Correlation"
731 self.data = None
731 self.data = None
732 self.dtype = None
732 self.dtype = None
733 self.nProfiles = None
733 self.nProfiles = None
734 self.heightList = None
734 self.heightList = None
735 self.channelList = None
735 self.channelList = None
736 self.flagNoData = True
736 self.flagNoData = True
737 self.flagDiscontinuousBlock = False
737 self.flagDiscontinuousBlock = False
738 self.utctime = None
738 self.utctime = None
739 self.timeZone = 0
739 self.timeZone = 0
740 self.dstFlag = None
740 self.dstFlag = None
741 self.errorCount = None
741 self.errorCount = None
742 self.blocksize = None
742 self.blocksize = None
743 self.flagDecodeData = False # asumo q la data no esta decodificada
743 self.flagDecodeData = False # asumo q la data no esta decodificada
744 self.flagDeflipData = False # asumo q la data no esta sin flip
744 self.flagDeflipData = False # asumo q la data no esta sin flip
745 self.pairsList = None
745 self.pairsList = None
746 self.nPoints = None
746 self.nPoints = None
747
747
748 def getPairsList(self):
748 def getPairsList(self):
749
749
750 return self.pairsList
750 return self.pairsList
751
751
752 def getNoise(self, mode=2):
752 def getNoise(self, mode=2):
753
753
754 indR = numpy.where(self.lagR == 0)[0][0]
754 indR = numpy.where(self.lagR == 0)[0][0]
755 indT = numpy.where(self.lagT == 0)[0][0]
755 indT = numpy.where(self.lagT == 0)[0][0]
756
756
757 jspectra0 = self.data_corr[:, :, indR, :]
757 jspectra0 = self.data_corr[:, :, indR, :]
758 jspectra = copy.copy(jspectra0)
758 jspectra = copy.copy(jspectra0)
759
759
760 num_chan = jspectra.shape[0]
760 num_chan = jspectra.shape[0]
761 num_hei = jspectra.shape[2]
761 num_hei = jspectra.shape[2]
762
762
763 freq_dc = jspectra.shape[1] / 2
763 freq_dc = jspectra.shape[1] / 2
764 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
764 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
765
765
766 if ind_vel[0] < 0:
766 if ind_vel[0] < 0:
767 ind_vel[list(range(0, 1))] = ind_vel[list(
767 ind_vel[list(range(0, 1))] = ind_vel[list(
768 range(0, 1))] + self.num_prof
768 range(0, 1))] + self.num_prof
769
769
770 if mode == 1:
770 if mode == 1:
771 jspectra[:, freq_dc, :] = (
771 jspectra[:, freq_dc, :] = (
772 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
772 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
773
773
774 if mode == 2:
774 if mode == 2:
775
775
776 vel = numpy.array([-2, -1, 1, 2])
776 vel = numpy.array([-2, -1, 1, 2])
777 xx = numpy.zeros([4, 4])
777 xx = numpy.zeros([4, 4])
778
778
779 for fil in range(4):
779 for fil in range(4):
780 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
780 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
781
781
782 xx_inv = numpy.linalg.inv(xx)
782 xx_inv = numpy.linalg.inv(xx)
783 xx_aux = xx_inv[0, :]
783 xx_aux = xx_inv[0, :]
784
784
785 for ich in range(num_chan):
785 for ich in range(num_chan):
786 yy = jspectra[ich, ind_vel, :]
786 yy = jspectra[ich, ind_vel, :]
787 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
787 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
788
788
789 junkid = jspectra[ich, freq_dc, :] <= 0
789 junkid = jspectra[ich, freq_dc, :] <= 0
790 cjunkid = sum(junkid)
790 cjunkid = sum(junkid)
791
791
792 if cjunkid.any():
792 if cjunkid.any():
793 jspectra[ich, freq_dc, junkid.nonzero()] = (
793 jspectra[ich, freq_dc, junkid.nonzero()] = (
794 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
794 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
795
795
796 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
796 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
797
797
798 return noise
798 return noise
799
799
800 @property
800 @property
801 def timeInterval(self):
801 def timeInterval(self):
802
802
803 return self.ippSeconds * self.nCohInt * self.nProfiles
803 return self.ippSeconds * self.nCohInt * self.nProfiles
804
804
805 def splitFunctions(self):
805 def splitFunctions(self):
806
806
807 pairsList = self.pairsList
807 pairsList = self.pairsList
808 ccf_pairs = []
808 ccf_pairs = []
809 acf_pairs = []
809 acf_pairs = []
810 ccf_ind = []
810 ccf_ind = []
811 acf_ind = []
811 acf_ind = []
812 for l in range(len(pairsList)):
812 for l in range(len(pairsList)):
813 chan0 = pairsList[l][0]
813 chan0 = pairsList[l][0]
814 chan1 = pairsList[l][1]
814 chan1 = pairsList[l][1]
815
815
816 # Obteniendo pares de Autocorrelacion
816 # Obteniendo pares de Autocorrelacion
817 if chan0 == chan1:
817 if chan0 == chan1:
818 acf_pairs.append(chan0)
818 acf_pairs.append(chan0)
819 acf_ind.append(l)
819 acf_ind.append(l)
820 else:
820 else:
821 ccf_pairs.append(pairsList[l])
821 ccf_pairs.append(pairsList[l])
822 ccf_ind.append(l)
822 ccf_ind.append(l)
823
823
824 data_acf = self.data_cf[acf_ind]
824 data_acf = self.data_cf[acf_ind]
825 data_ccf = self.data_cf[ccf_ind]
825 data_ccf = self.data_cf[ccf_ind]
826
826
827 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
827 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
828
828
829 @property
829 @property
830 def normFactor(self):
830 def normFactor(self):
831 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
831 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
832 acf_pairs = numpy.array(acf_pairs)
832 acf_pairs = numpy.array(acf_pairs)
833 normFactor = numpy.zeros((self.nPairs, self.nHeights))
833 normFactor = numpy.zeros((self.nPairs, self.nHeights))
834
834
835 for p in range(self.nPairs):
835 for p in range(self.nPairs):
836 pair = self.pairsList[p]
836 pair = self.pairsList[p]
837
837
838 ch0 = pair[0]
838 ch0 = pair[0]
839 ch1 = pair[1]
839 ch1 = pair[1]
840
840
841 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
841 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
842 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
842 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
843 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
843 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
844
844
845 return normFactor
845 return normFactor
846
846
847
847
848 class Parameters(Spectra):
848 class Parameters(Spectra):
849
849
850 groupList = None # List of Pairs, Groups, etc
850 groupList = None # List of Pairs, Groups, etc
851 data_param = None # Parameters obtained
851 data_param = None # Parameters obtained
852 data_pre = None # Data Pre Parametrization
852 data_pre = None # Data Pre Parametrization
853 data_SNR = None # Signal to Noise Ratio
853 data_SNR = None # Signal to Noise Ratio
854 abscissaList = None # Abscissa, can be velocities, lags or time
854 abscissaList = None # Abscissa, can be velocities, lags or time
855 utctimeInit = None # Initial UTC time
855 utctimeInit = None # Initial UTC time
856 paramInterval = None # Time interval to calculate Parameters in seconds
856 paramInterval = None # Time interval to calculate Parameters in seconds
857 useLocalTime = True
857 useLocalTime = True
858 # Fitting
858 # Fitting
859 data_error = None # Error of the estimation
859 data_error = None # Error of the estimation
860 constants = None
860 constants = None
861 library = None
861 library = None
862 # Output signal
862 # Output signal
863 outputInterval = None # Time interval to calculate output signal in seconds
863 outputInterval = None # Time interval to calculate output signal in seconds
864 data_output = None # Out signal
864 data_output = None # Out signal
865 nAvg = None
865 nAvg = None
866 noise_estimation = None
866 noise_estimation = None
867 GauSPC = None # Fit gaussian SPC
867 GauSPC = None # Fit gaussian SPC
868
868
869 def __init__(self):
869 def __init__(self):
870 '''
870 '''
871 Constructor
871 Constructor
872 '''
872 '''
873 self.radarControllerHeaderObj = RadarControllerHeader()
873 self.radarControllerHeaderObj = RadarControllerHeader()
874 self.systemHeaderObj = SystemHeader()
874 self.systemHeaderObj = SystemHeader()
875 self.type = "Parameters"
875 self.type = "Parameters"
876 self.timeZone = 0
876 self.timeZone = 0
877
877
878 def getTimeRange1(self, interval):
878 def getTimeRange1(self, interval):
879
879
880 datatime = []
880 datatime = []
881
881
882 if self.useLocalTime:
882 if self.useLocalTime:
883 time1 = self.utctimeInit - self.timeZone * 60
883 time1 = self.utctimeInit - self.timeZone * 60
884 else:
884 else:
885 time1 = self.utctimeInit
885 time1 = self.utctimeInit
886
886
887 datatime.append(time1)
887 datatime.append(time1)
888 datatime.append(time1 + interval)
888 datatime.append(time1 + interval)
889 datatime = numpy.array(datatime)
889 datatime = numpy.array(datatime)
890
890
891 return datatime
891 return datatime
892
892
893 @property
893 @property
894 def timeInterval(self):
894 def timeInterval(self):
895
895
896 if hasattr(self, 'timeInterval1'):
896 if hasattr(self, 'timeInterval1'):
897 return self.timeInterval1
897 return self.timeInterval1
898 else:
898 else:
899 return self.paramInterval
899 return self.paramInterval
900
900
901
901
902 def setValue(self, value):
902 def setValue(self, value):
903
903
904 print("This property should not be initialized")
904 print("This property should not be initialized")
905
905
906 return
906 return
907
907
908 def getNoise(self):
908 def getNoise(self):
909
909
910 return self.spc_noise
910 return self.spc_noise
911
911
912 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
912 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
913
913
914
914
915 class PlotterData(object):
915 class PlotterData(object):
916 '''
916 '''
917 Object to hold data to be plotted
917 Object to hold data to be plotted
918 '''
918 '''
919
919
920 MAXNUMX = 200
920 MAXNUMX = 200
921 MAXNUMY = 200
921 MAXNUMY = 200
922
922
923 def __init__(self, code, exp_code, localtime=True):
923 def __init__(self, code, exp_code, localtime=True):
924
924
925 self.key = code
925 self.key = code
926 self.exp_code = exp_code
926 self.exp_code = exp_code
927 self.ready = False
927 self.ready = False
928 self.flagNoData = False
928 self.flagNoData = False
929 self.localtime = localtime
929 self.localtime = localtime
930 self.data = {}
930 self.data = {}
931 self.meta = {}
931 self.meta = {}
932 self.__heights = []
932 self.__heights = []
933
933
934 def __str__(self):
934 def __str__(self):
935 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
935 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
936 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
936 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
937
937
938 def __len__(self):
938 def __len__(self):
939 return len(self.data)
939 return len(self.data)
940
940
941 def __getitem__(self, key):
941 def __getitem__(self, key):
942 if isinstance(key, int):
942 if isinstance(key, int):
943 return self.data[self.times[key]]
943 return self.data[self.times[key]]
944 elif isinstance(key, str):
944 elif isinstance(key, str):
945 ret = numpy.array([self.data[x][key] for x in self.times])
945 ret = numpy.array([self.data[x][key] for x in self.times])
946 if ret.ndim > 1:
946 if ret.ndim > 1:
947 ret = numpy.swapaxes(ret, 0, 1)
947 ret = numpy.swapaxes(ret, 0, 1)
948 return ret
948 return ret
949
949
950 def __contains__(self, key):
950 def __contains__(self, key):
951 return key in self.data[self.min_time]
951 return key in self.data[self.min_time]
952
952
953 def setup(self):
953 def setup(self):
954 '''
954 '''
955 Configure object
955 Configure object
956 '''
956 '''
957 self.type = ''
957 self.type = ''
958 self.ready = False
958 self.ready = False
959 del self.data
959 del self.data
960 self.data = {}
960 self.data = {}
961 self.__heights = []
961 self.__heights = []
962 self.__all_heights = set()
962 self.__all_heights = set()
963
963
964 def shape(self, key):
964 def shape(self, key):
965 '''
965 '''
966 Get the shape of the one-element data for the given key
966 Get the shape of the one-element data for the given key
967 '''
967 '''
968
968
969 if len(self.data[self.min_time][key]):
969 if len(self.data[self.min_time][key]):
970 return self.data[self.min_time][key].shape
970 return self.data[self.min_time][key].shape
971 return (0,)
971 return (0,)
972
972
973 def update(self, data, tm, meta={}):
973 def update(self, data, tm, meta={}):
974 '''
974 '''
975 Update data object with new dataOut
975 Update data object with new dataOut
976 '''
976 '''
977
977
978 self.data[tm] = data
978 self.data[tm] = data
979
979
980 for key, value in meta.items():
980 for key, value in meta.items():
981 setattr(self, key, value)
981 setattr(self, key, value)
982
982
983 def normalize_heights(self):
983 def normalize_heights(self):
984 '''
984 '''
985 Ensure same-dimension of the data for different heighList
985 Ensure same-dimension of the data for different heighList
986 '''
986 '''
987
987
988 H = numpy.array(list(self.__all_heights))
988 H = numpy.array(list(self.__all_heights))
989 H.sort()
989 H.sort()
990 for key in self.data:
990 for key in self.data:
991 shape = self.shape(key)[:-1] + H.shape
991 shape = self.shape(key)[:-1] + H.shape
992 for tm, obj in list(self.data[key].items()):
992 for tm, obj in list(self.data[key].items()):
993 h = self.__heights[self.times.tolist().index(tm)]
993 h = self.__heights[self.times.tolist().index(tm)]
994 if H.size == h.size:
994 if H.size == h.size:
995 continue
995 continue
996 index = numpy.where(numpy.in1d(H, h))[0]
996 index = numpy.where(numpy.in1d(H, h))[0]
997 dummy = numpy.zeros(shape) + numpy.nan
997 dummy = numpy.zeros(shape) + numpy.nan
998 if len(shape) == 2:
998 if len(shape) == 2:
999 dummy[:, index] = obj
999 dummy[:, index] = obj
1000 else:
1000 else:
1001 dummy[index] = obj
1001 dummy[index] = obj
1002 self.data[key][tm] = dummy
1002 self.data[key][tm] = dummy
1003
1003
1004 self.__heights = [H for tm in self.times]
1004 self.__heights = [H for tm in self.times]
1005
1005
1006 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1006 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1007 '''
1007 '''
1008 Convert data to json
1008 Convert data to json
1009 '''
1009 '''
1010
1010
1011 meta = {}
1011 meta = {}
1012 meta['xrange'] = []
1012 meta['xrange'] = []
1013 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1013 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1014 tmp = self.data[tm][self.key]
1014 tmp = self.data[tm][self.key]
1015 shape = tmp.shape
1015 shape = tmp.shape
1016 if len(shape) == 2:
1016 if len(shape) == 2:
1017 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1017 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1018 elif len(shape) == 3:
1018 elif len(shape) == 3:
1019 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1019 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1020 data = self.roundFloats(
1020 data = self.roundFloats(
1021 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1021 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1022 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1022 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1023 else:
1023 else:
1024 data = self.roundFloats(self.data[tm][self.key].tolist())
1024 data = self.roundFloats(self.data[tm][self.key].tolist())
1025
1025
1026 ret = {
1026 ret = {
1027 'plot': plot_name,
1027 'plot': plot_name,
1028 'code': self.exp_code,
1028 'code': self.exp_code,
1029 'time': float(tm),
1029 'time': float(tm),
1030 'data': data,
1030 'data': data,
1031 }
1031 }
1032 meta['type'] = plot_type
1032 meta['type'] = plot_type
1033 meta['interval'] = float(self.interval)
1033 meta['interval'] = float(self.interval)
1034 meta['localtime'] = self.localtime
1034 meta['localtime'] = self.localtime
1035 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1035 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1036 meta.update(self.meta)
1036 meta.update(self.meta)
1037 ret['metadata'] = meta
1037 ret['metadata'] = meta
1038 return json.dumps(ret)
1038 return json.dumps(ret)
1039
1039
1040 @property
1040 @property
1041 def times(self):
1041 def times(self):
1042 '''
1042 '''
1043 Return the list of times of the current data
1043 Return the list of times of the current data
1044 '''
1044 '''
1045
1045
1046 ret = [t for t in self.data]
1046 ret = [t for t in self.data]
1047 ret.sort()
1047 ret.sort()
1048 return numpy.array(ret)
1048 return numpy.array(ret)
1049
1049
1050 @property
1050 @property
1051 def min_time(self):
1051 def min_time(self):
1052 '''
1052 '''
1053 Return the minimun time value
1053 Return the minimun time value
1054 '''
1054 '''
1055
1055
1056 return self.times[0]
1056 return self.times[0]
1057
1057
1058 @property
1058 @property
1059 def max_time(self):
1059 def max_time(self):
1060 '''
1060 '''
1061 Return the maximun time value
1061 Return the maximun time value
1062 '''
1062 '''
1063
1063
1064 return self.times[-1]
1064 return self.times[-1]
1065
1065
1066 # @property
1066 # @property
1067 # def heights(self):
1067 # def heights(self):
1068 # '''
1068 # '''
1069 # Return the list of heights of the current data
1069 # Return the list of heights of the current data
1070 # '''
1070 # '''
1071
1071
1072 # return numpy.array(self.__heights[-1])
1072 # return numpy.array(self.__heights[-1])
1073
1073
1074 @staticmethod
1074 @staticmethod
1075 def roundFloats(obj):
1075 def roundFloats(obj):
1076 if isinstance(obj, list):
1076 if isinstance(obj, list):
1077 return list(map(PlotterData.roundFloats, obj))
1077 return list(map(PlotterData.roundFloats, obj))
1078 elif isinstance(obj, float):
1078 elif isinstance(obj, float):
1079 return round(obj, 2)
1079 return round(obj, 2)
@@ -1,697 +1,698
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from collections import deque
15 from collections import deque
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib
18 import matplotlib
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("TkAgg")
23 matplotlib.use("TkAgg")
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('MacOSX')
25 matplotlib.use('MacOSX')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49
49
50 EARTH_RADIUS = 6.3710e3
50 EARTH_RADIUS = 6.3710e3
51
51
52 def ll2xy(lat1, lon1, lat2, lon2):
52 def ll2xy(lat1, lon1, lat2, lon2):
53
53
54 p = 0.017453292519943295
54 p = 0.017453292519943295
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 theta = -theta + numpy.pi/2
60 theta = -theta + numpy.pi/2
61 return r*numpy.cos(theta), r*numpy.sin(theta)
61 return r*numpy.cos(theta), r*numpy.sin(theta)
62
62
63
63
64 def km2deg(km):
64 def km2deg(km):
65 '''
65 '''
66 Convert distance in km to degrees
66 Convert distance in km to degrees
67 '''
67 '''
68
68
69 return numpy.rad2deg(km/EARTH_RADIUS)
69 return numpy.rad2deg(km/EARTH_RADIUS)
70
70
71
71
72 def figpause(interval):
72 def figpause(interval):
73 backend = plt.rcParams['backend']
73 backend = plt.rcParams['backend']
74 if backend in matplotlib.rcsetup.interactive_bk:
74 if backend in matplotlib.rcsetup.interactive_bk:
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 if figManager is not None:
76 if figManager is not None:
77 canvas = figManager.canvas
77 canvas = figManager.canvas
78 if canvas.figure.stale:
78 if canvas.figure.stale:
79 canvas.draw()
79 canvas.draw()
80 try:
80 try:
81 canvas.start_event_loop(interval)
81 canvas.start_event_loop(interval)
82 except:
82 except:
83 pass
83 pass
84 return
84 return
85
85
86 def popup(message):
86 def popup(message):
87 '''
87 '''
88 '''
88 '''
89
89
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 text = '\n'.join([s.strip() for s in message.split(':')])
91 text = '\n'.join([s.strip() for s in message.split(':')])
92 fig.text(0.01, 0.5, text, ha='left', va='center',
92 fig.text(0.01, 0.5, text, ha='left', va='center',
93 size='20', weight='heavy', color='w')
93 size='20', weight='heavy', color='w')
94 fig.show()
94 fig.show()
95 figpause(1000)
95 figpause(1000)
96
96
97
97
98 class Throttle(object):
98 class Throttle(object):
99 '''
99 '''
100 Decorator that prevents a function from being called more than once every
100 Decorator that prevents a function from being called more than once every
101 time period.
101 time period.
102 To create a function that cannot be called more than once a minute, but
102 To create a function that cannot be called more than once a minute, but
103 will sleep until it can be called:
103 will sleep until it can be called:
104 @Throttle(minutes=1)
104 @Throttle(minutes=1)
105 def foo():
105 def foo():
106 pass
106 pass
107
107
108 for i in range(10):
108 for i in range(10):
109 foo()
109 foo()
110 print "This function has run %s times." % i
110 print "This function has run %s times." % i
111 '''
111 '''
112
112
113 def __init__(self, seconds=0, minutes=0, hours=0):
113 def __init__(self, seconds=0, minutes=0, hours=0):
114 self.throttle_period = datetime.timedelta(
114 self.throttle_period = datetime.timedelta(
115 seconds=seconds, minutes=minutes, hours=hours
115 seconds=seconds, minutes=minutes, hours=hours
116 )
116 )
117
117
118 self.time_of_last_call = datetime.datetime.min
118 self.time_of_last_call = datetime.datetime.min
119
119
120 def __call__(self, fn):
120 def __call__(self, fn):
121 @wraps(fn)
121 @wraps(fn)
122 def wrapper(*args, **kwargs):
122 def wrapper(*args, **kwargs):
123 coerce = kwargs.pop('coerce', None)
123 coerce = kwargs.pop('coerce', None)
124 if coerce:
124 if coerce:
125 self.time_of_last_call = datetime.datetime.now()
125 self.time_of_last_call = datetime.datetime.now()
126 return fn(*args, **kwargs)
126 return fn(*args, **kwargs)
127 else:
127 else:
128 now = datetime.datetime.now()
128 now = datetime.datetime.now()
129 time_since_last_call = now - self.time_of_last_call
129 time_since_last_call = now - self.time_of_last_call
130 time_left = self.throttle_period - time_since_last_call
130 time_left = self.throttle_period - time_since_last_call
131
131
132 if time_left > datetime.timedelta(seconds=0):
132 if time_left > datetime.timedelta(seconds=0):
133 return
133 return
134
134
135 self.time_of_last_call = datetime.datetime.now()
135 self.time_of_last_call = datetime.datetime.now()
136 return fn(*args, **kwargs)
136 return fn(*args, **kwargs)
137
137
138 return wrapper
138 return wrapper
139
139
140 def apply_throttle(value):
140 def apply_throttle(value):
141
141
142 @Throttle(seconds=value)
142 @Throttle(seconds=value)
143 def fnThrottled(fn):
143 def fnThrottled(fn):
144 fn()
144 fn()
145
145
146 return fnThrottled
146 return fnThrottled
147
147
148
148
149 @MPDecorator
149 @MPDecorator
150 class Plot(Operation):
150 class Plot(Operation):
151 """Base class for Schain plotting operations
151 """Base class for Schain plotting operations
152
152
153 This class should never be use directtly you must subclass a new operation,
153 This class should never be use directtly you must subclass a new operation,
154 children classes must be defined as follow:
154 children classes must be defined as follow:
155
155
156 ExamplePlot(Plot):
156 ExamplePlot(Plot):
157
157
158 CODE = 'code'
158 CODE = 'code'
159 colormap = 'jet'
159 colormap = 'jet'
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161
161
162 def setup(self):
162 def setup(self):
163 pass
163 pass
164
164
165 def plot(self):
165 def plot(self):
166 pass
166 pass
167
167
168 """
168 """
169
169
170 CODE = 'Figure'
170 CODE = 'Figure'
171 colormap = 'jet'
171 colormap = 'jet'
172 bgcolor = 'white'
172 bgcolor = 'white'
173 buffering = True
173 buffering = True
174 __missing = 1E30
174 __missing = 1E30
175
175
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 'showprofile']
177 'showprofile']
178
178
179 def __init__(self):
179 def __init__(self):
180
180
181 Operation.__init__(self)
181 Operation.__init__(self)
182 self.isConfig = False
182 self.isConfig = False
183 self.isPlotConfig = False
183 self.isPlotConfig = False
184 self.save_time = 0
184 self.save_time = 0
185 self.sender_time = 0
185 self.sender_time = 0
186 self.data = None
186 self.data = None
187 self.firsttime = True
187 self.firsttime = True
188 self.sender_queue = deque(maxlen=10)
188 self.sender_queue = deque(maxlen=10)
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190
190
191 def __fmtTime(self, x, pos):
191 def __fmtTime(self, x, pos):
192 '''
192 '''
193 '''
193 '''
194
194
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196
196
197 def __setup(self, **kwargs):
197 def __setup(self, **kwargs):
198 '''
198 '''
199 Initialize variables
199 Initialize variables
200 '''
200 '''
201
201
202 self.figures = []
202 self.figures = []
203 self.axes = []
203 self.axes = []
204 self.cb_axes = []
204 self.cb_axes = []
205 self.localtime = kwargs.pop('localtime', True)
205 self.localtime = kwargs.pop('localtime', True)
206 self.show = kwargs.get('show', True)
206 self.show = kwargs.get('show', True)
207 self.save = kwargs.get('save', False)
207 self.save = kwargs.get('save', False)
208 self.save_period = kwargs.get('save_period', 0)
208 self.save_period = kwargs.get('save_period', 0)
209 self.colormap = kwargs.get('colormap', self.colormap)
209 self.colormap = kwargs.get('colormap', self.colormap)
210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
212 self.colormaps = kwargs.get('colormaps', None)
212 self.colormaps = kwargs.get('colormaps', None)
213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
214 self.showprofile = kwargs.get('showprofile', False)
214 self.showprofile = kwargs.get('showprofile', False)
215 self.title = kwargs.get('wintitle', self.CODE.upper())
215 self.title = kwargs.get('wintitle', self.CODE.upper())
216 self.cb_label = kwargs.get('cb_label', None)
216 self.cb_label = kwargs.get('cb_label', None)
217 self.cb_labels = kwargs.get('cb_labels', None)
217 self.cb_labels = kwargs.get('cb_labels', None)
218 self.labels = kwargs.get('labels', None)
218 self.labels = kwargs.get('labels', None)
219 self.xaxis = kwargs.get('xaxis', 'frequency')
219 self.xaxis = kwargs.get('xaxis', 'frequency')
220 self.zmin = kwargs.get('zmin', None)
220 self.zmin = kwargs.get('zmin', None)
221 self.zmax = kwargs.get('zmax', None)
221 self.zmax = kwargs.get('zmax', None)
222 self.zlimits = kwargs.get('zlimits', None)
222 self.zlimits = kwargs.get('zlimits', None)
223 self.xlimits = kwargs.get('xlimits', None)
223 self.xlimits = kwargs.get('xlimits', None)
224 self.xstep_given = kwargs.get('xstep_given', None)
224 self.xstep_given = kwargs.get('xstep_given', None)
225 self.ystep_given = kwargs.get('ystep_given', None)
225 self.ystep_given = kwargs.get('ystep_given', None)
226 self.autoxticks = kwargs.get('autoxticks', True)
226 self.autoxticks = kwargs.get('autoxticks', True)
227 self.xmin = kwargs.get('xmin', None)
227 self.xmin = kwargs.get('xmin', None)
228 self.xmax = kwargs.get('xmax', None)
228 self.xmax = kwargs.get('xmax', None)
229 self.xrange = kwargs.get('xrange', 12)
229 self.xrange = kwargs.get('xrange', 12)
230 self.xscale = kwargs.get('xscale', None)
230 self.xscale = kwargs.get('xscale', None)
231 self.ymin = kwargs.get('ymin', None)
231 self.ymin = kwargs.get('ymin', None)
232 self.ymax = kwargs.get('ymax', None)
232 self.ymax = kwargs.get('ymax', None)
233 self.yscale = kwargs.get('yscale', None)
233 self.yscale = kwargs.get('yscale', None)
234 self.xlabel = kwargs.get('xlabel', None)
234 self.xlabel = kwargs.get('xlabel', None)
235 self.attr_time = kwargs.get('attr_time', 'utctime')
235 self.attr_time = kwargs.get('attr_time', 'utctime')
236 self.attr_data = kwargs.get('attr_data', 'data_param')
236 self.attr_data = kwargs.get('attr_data', 'data_param')
237 self.decimation = kwargs.get('decimation', None)
237 self.decimation = kwargs.get('decimation', None)
238 self.oneFigure = kwargs.get('oneFigure', True)
238 self.oneFigure = kwargs.get('oneFigure', True)
239 self.width = kwargs.get('width', None)
239 self.width = kwargs.get('width', None)
240 self.height = kwargs.get('height', None)
240 self.height = kwargs.get('height', None)
241 self.colorbar = kwargs.get('colorbar', True)
241 self.colorbar = kwargs.get('colorbar', True)
242 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
242 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
243 self.channels = kwargs.get('channels', None)
243 self.channels = kwargs.get('channels', None)
244 self.titles = kwargs.get('titles', [])
244 self.titles = kwargs.get('titles', [])
245 self.polar = False
245 self.polar = False
246 self.type = kwargs.get('type', 'iq')
246 self.type = kwargs.get('type', 'iq')
247 self.grid = kwargs.get('grid', False)
247 self.grid = kwargs.get('grid', False)
248 self.pause = kwargs.get('pause', False)
248 self.pause = kwargs.get('pause', False)
249 self.save_code = kwargs.get('save_code', self.CODE)
249 self.save_code = kwargs.get('save_code', self.CODE)
250 self.throttle = kwargs.get('throttle', 0)
250 self.throttle = kwargs.get('throttle', 0)
251 self.exp_code = kwargs.get('exp_code', None)
251 self.exp_code = kwargs.get('exp_code', None)
252 self.server = kwargs.get('server', False)
252 self.server = kwargs.get('server', False)
253 self.sender_period = kwargs.get('sender_period', 60)
253 self.sender_period = kwargs.get('sender_period', 60)
254 self.tag = kwargs.get('tag', '')
254 self.tag = kwargs.get('tag', '')
255 self.height_index = kwargs.get('height_index', None)
255 self.height_index = kwargs.get('height_index', None)
256 self.__throttle_plot = apply_throttle(self.throttle)
256 self.__throttle_plot = apply_throttle(self.throttle)
257 code = self.attr_data if self.attr_data else self.CODE
257 code = self.attr_data if self.attr_data else self.CODE
258 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
258 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
259 #self.EEJtype = kwargs.get('EEJtype', 2)
259
260
260 if self.server:
261 if self.server:
261 if not self.server.startswith('tcp://'):
262 if not self.server.startswith('tcp://'):
262 self.server = 'tcp://{}'.format(self.server)
263 self.server = 'tcp://{}'.format(self.server)
263 log.success(
264 log.success(
264 'Sending to server: {}'.format(self.server),
265 'Sending to server: {}'.format(self.server),
265 self.name
266 self.name
266 )
267 )
267
268
268 if isinstance(self.attr_data, str):
269 if isinstance(self.attr_data, str):
269 self.attr_data = [self.attr_data]
270 self.attr_data = [self.attr_data]
270
271
271 def __setup_plot(self):
272 def __setup_plot(self):
272 '''
273 '''
273 Common setup for all figures, here figures and axes are created
274 Common setup for all figures, here figures and axes are created
274 '''
275 '''
275
276
276 self.setup()
277 self.setup()
277
278
278 self.time_label = 'LT' if self.localtime else 'UTC'
279 self.time_label = 'LT' if self.localtime else 'UTC'
279
280
280 if self.width is None:
281 if self.width is None:
281 self.width = 8
282 self.width = 8
282
283
283 self.figures = []
284 self.figures = []
284 self.axes = []
285 self.axes = []
285 self.cb_axes = []
286 self.cb_axes = []
286 self.pf_axes = []
287 self.pf_axes = []
287 self.cmaps = []
288 self.cmaps = []
288
289
289 size = '15%' if self.ncols == 1 else '30%'
290 size = '15%' if self.ncols == 1 else '30%'
290 pad = '4%' if self.ncols == 1 else '8%'
291 pad = '4%' if self.ncols == 1 else '8%'
291
292
292 if self.oneFigure:
293 if self.oneFigure:
293 if self.height is None:
294 if self.height is None:
294 self.height = 1.4 * self.nrows + 1
295 self.height = 1.4 * self.nrows + 1
295 fig = plt.figure(figsize=(self.width, self.height),
296 fig = plt.figure(figsize=(self.width, self.height),
296 edgecolor='k',
297 edgecolor='k',
297 facecolor='w')
298 facecolor='w')
298 self.figures.append(fig)
299 self.figures.append(fig)
299 for n in range(self.nplots):
300 for n in range(self.nplots):
300 ax = fig.add_subplot(self.nrows, self.ncols,
301 ax = fig.add_subplot(self.nrows, self.ncols,
301 n + 1, polar=self.polar)
302 n + 1, polar=self.polar)
302 ax.tick_params(labelsize=8)
303 ax.tick_params(labelsize=8)
303 ax.firsttime = True
304 ax.firsttime = True
304 ax.index = 0
305 ax.index = 0
305 ax.press = None
306 ax.press = None
306 self.axes.append(ax)
307 self.axes.append(ax)
307 if self.showprofile:
308 if self.showprofile:
308 cax = self.__add_axes(ax, size=size, pad=pad)
309 cax = self.__add_axes(ax, size=size, pad=pad)
309 cax.tick_params(labelsize=8)
310 cax.tick_params(labelsize=8)
310 self.pf_axes.append(cax)
311 self.pf_axes.append(cax)
311 else:
312 else:
312 if self.height is None:
313 if self.height is None:
313 self.height = 3
314 self.height = 3
314 for n in range(self.nplots):
315 for n in range(self.nplots):
315 fig = plt.figure(figsize=(self.width, self.height),
316 fig = plt.figure(figsize=(self.width, self.height),
316 edgecolor='k',
317 edgecolor='k',
317 facecolor='w')
318 facecolor='w')
318 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
319 ax.tick_params(labelsize=8)
320 ax.tick_params(labelsize=8)
320 ax.firsttime = True
321 ax.firsttime = True
321 ax.index = 0
322 ax.index = 0
322 ax.press = None
323 ax.press = None
323 self.figures.append(fig)
324 self.figures.append(fig)
324 self.axes.append(ax)
325 self.axes.append(ax)
325 if self.showprofile:
326 if self.showprofile:
326 cax = self.__add_axes(ax, size=size, pad=pad)
327 cax = self.__add_axes(ax, size=size, pad=pad)
327 cax.tick_params(labelsize=8)
328 cax.tick_params(labelsize=8)
328 self.pf_axes.append(cax)
329 self.pf_axes.append(cax)
329
330
330 for n in range(self.nrows):
331 for n in range(self.nrows):
331 if self.colormaps is not None:
332 if self.colormaps is not None:
332 cmap = plt.get_cmap(self.colormaps[n])
333 cmap = plt.get_cmap(self.colormaps[n])
333 else:
334 else:
334 cmap = plt.get_cmap(self.colormap)
335 cmap = plt.get_cmap(self.colormap)
335 cmap.set_bad(self.bgcolor, 1.)
336 cmap.set_bad(self.bgcolor, 1.)
336 self.cmaps.append(cmap)
337 self.cmaps.append(cmap)
337
338
338 def __add_axes(self, ax, size='30%', pad='8%'):
339 def __add_axes(self, ax, size='30%', pad='8%'):
339 '''
340 '''
340 Add new axes to the given figure
341 Add new axes to the given figure
341 '''
342 '''
342 divider = make_axes_locatable(ax)
343 divider = make_axes_locatable(ax)
343 nax = divider.new_horizontal(size=size, pad=pad)
344 nax = divider.new_horizontal(size=size, pad=pad)
344 ax.figure.add_axes(nax)
345 ax.figure.add_axes(nax)
345 return nax
346 return nax
346
347
347 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
348 '''
349 '''
349 Create a masked array for missing data
350 Create a masked array for missing data
350 '''
351 '''
351 if x_buffer.shape[0] < 2:
352 if x_buffer.shape[0] < 2:
352 return x_buffer, y_buffer, z_buffer
353 return x_buffer, y_buffer, z_buffer
353
354
354 deltas = x_buffer[1:] - x_buffer[0:-1]
355 deltas = x_buffer[1:] - x_buffer[0:-1]
355 x_median = numpy.median(deltas)
356 x_median = numpy.median(deltas)
356
357
357 index = numpy.where(deltas > 5 * x_median)
358 index = numpy.where(deltas > 5 * x_median)
358
359
359 if len(index[0]) != 0:
360 if len(index[0]) != 0:
360 z_buffer[::, index[0], ::] = self.__missing
361 z_buffer[::, index[0], ::] = self.__missing
361 z_buffer = numpy.ma.masked_inside(z_buffer,
362 z_buffer = numpy.ma.masked_inside(z_buffer,
362 0.99 * self.__missing,
363 0.99 * self.__missing,
363 1.01 * self.__missing)
364 1.01 * self.__missing)
364
365
365 return x_buffer, y_buffer, z_buffer
366 return x_buffer, y_buffer, z_buffer
366
367
367 def decimate(self):
368 def decimate(self):
368
369
369 # dx = int(len(self.x)/self.__MAXNUMX) + 1
370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
370 dy = int(len(self.y) / self.decimation) + 1
371 dy = int(len(self.y) / self.decimation) + 1
371
372
372 # x = self.x[::dx]
373 # x = self.x[::dx]
373 x = self.x
374 x = self.x
374 y = self.y[::dy]
375 y = self.y[::dy]
375 z = self.z[::, ::, ::dy]
376 z = self.z[::, ::, ::dy]
376
377
377 return x, y, z
378 return x, y, z
378
379
379 def format(self):
380 def format(self):
380 '''
381 '''
381 Set min and max values, labels, ticks and titles
382 Set min and max values, labels, ticks and titles
382 '''
383 '''
383
384
384 for n, ax in enumerate(self.axes):
385 for n, ax in enumerate(self.axes):
385 if ax.firsttime:
386 if ax.firsttime:
386 if self.xaxis != 'time':
387 if self.xaxis != 'time':
387 xmin = self.xmin
388 xmin = self.xmin
388 xmax = self.xmax
389 xmax = self.xmax
389 else:
390 else:
390 xmin = self.tmin
391 xmin = self.tmin
391 xmax = self.tmin + self.xrange*60*60
392 xmax = self.tmin + self.xrange*60*60
392 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
393 ax.xaxis.set_major_locator(LinearLocator(9))
394 ax.xaxis.set_major_locator(LinearLocator(9))
394 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
395 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
395 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
396 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
396 ax.set_facecolor(self.bgcolor)
397 ax.set_facecolor(self.bgcolor)
397 if self.xscale:
398 if self.xscale:
398 ax.xaxis.set_major_formatter(FuncFormatter(
399 ax.xaxis.set_major_formatter(FuncFormatter(
399 lambda x, pos: '{0:g}'.format(x*self.xscale)))
400 lambda x, pos: '{0:g}'.format(x*self.xscale)))
400 if self.yscale:
401 if self.yscale:
401 ax.yaxis.set_major_formatter(FuncFormatter(
402 ax.yaxis.set_major_formatter(FuncFormatter(
402 lambda x, pos: '{0:g}'.format(x*self.yscale)))
403 lambda x, pos: '{0:g}'.format(x*self.yscale)))
403 if self.xlabel is not None:
404 if self.xlabel is not None:
404 ax.set_xlabel(self.xlabel)
405 ax.set_xlabel(self.xlabel)
405 if self.ylabel is not None:
406 if self.ylabel is not None:
406 ax.set_ylabel(self.ylabel)
407 ax.set_ylabel(self.ylabel)
407 if self.showprofile:
408 if self.showprofile:
408 self.pf_axes[n].set_ylim(ymin, ymax)
409 self.pf_axes[n].set_ylim(ymin, ymax)
409 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
410 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
410 self.pf_axes[n].set_xlabel('dB')
411 self.pf_axes[n].set_xlabel('dB')
411 self.pf_axes[n].grid(b=True, axis='x')
412 self.pf_axes[n].grid(b=True, axis='x')
412 [tick.set_visible(False)
413 [tick.set_visible(False)
413 for tick in self.pf_axes[n].get_yticklabels()]
414 for tick in self.pf_axes[n].get_yticklabels()]
414 if self.colorbar:
415 if self.colorbar:
415 ax.cbar = plt.colorbar(
416 ax.cbar = plt.colorbar(
416 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
417 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
417 ax.cbar.ax.tick_params(labelsize=8)
418 ax.cbar.ax.tick_params(labelsize=8)
418 ax.cbar.ax.press = None
419 ax.cbar.ax.press = None
419 if self.cb_label:
420 if self.cb_label:
420 ax.cbar.set_label(self.cb_label, size=8)
421 ax.cbar.set_label(self.cb_label, size=8)
421 elif self.cb_labels:
422 elif self.cb_labels:
422 ax.cbar.set_label(self.cb_labels[n], size=8)
423 ax.cbar.set_label(self.cb_labels[n], size=8)
423 else:
424 else:
424 ax.cbar = None
425 ax.cbar = None
425 ax.set_xlim(xmin, xmax)
426 ax.set_xlim(xmin, xmax)
426 ax.set_ylim(ymin, ymax)
427 ax.set_ylim(ymin, ymax)
427 ax.firsttime = False
428 ax.firsttime = False
428 if self.grid:
429 if self.grid:
429 ax.grid(True)
430 ax.grid(True)
430 if not self.polar:
431 if not self.polar:
431 ax.set_title('{} {} {}'.format(
432 ax.set_title('{} {} {}'.format(
432 self.titles[n],
433 self.titles[n],
433 self.getDateTime(self.data.max_time).strftime(
434 self.getDateTime(self.data.max_time).strftime(
434 '%Y-%m-%d %H:%M:%S'),
435 '%Y-%m-%d %H:%M:%S'),
435 self.time_label),
436 self.time_label),
436 size=8)
437 size=8)
437 else:
438 else:
438 ax.set_title('{}'.format(self.titles[n]), size=8)
439 ax.set_title('{}'.format(self.titles[n]), size=8)
439 ax.set_ylim(0, 90)
440 ax.set_ylim(0, 90)
440 ax.set_yticks(numpy.arange(0, 90, 20))
441 ax.set_yticks(numpy.arange(0, 90, 20))
441 ax.yaxis.labelpad = 40
442 ax.yaxis.labelpad = 40
442
443
443 if self.firsttime:
444 if self.firsttime:
444 for n, fig in enumerate(self.figures):
445 for n, fig in enumerate(self.figures):
445 fig.subplots_adjust(**self.plots_adjust)
446 fig.subplots_adjust(**self.plots_adjust)
446 self.firsttime = False
447 self.firsttime = False
447
448
448 def clear_figures(self):
449 def clear_figures(self):
449 '''
450 '''
450 Reset axes for redraw plots
451 Reset axes for redraw plots
451 '''
452 '''
452
453
453 for ax in self.axes+self.pf_axes+self.cb_axes:
454 for ax in self.axes+self.pf_axes+self.cb_axes:
454 ax.clear()
455 ax.clear()
455 ax.firsttime = True
456 ax.firsttime = True
456 if hasattr(ax, 'cbar') and ax.cbar:
457 if hasattr(ax, 'cbar') and ax.cbar:
457 ax.cbar.remove()
458 ax.cbar.remove()
458
459
459 def __plot(self):
460 def __plot(self):
460 '''
461 '''
461 Main function to plot, format and save figures
462 Main function to plot, format and save figures
462 '''
463 '''
463
464
464 self.plot()
465 self.plot()
465 self.format()
466 self.format()
466
467
467 for n, fig in enumerate(self.figures):
468 for n, fig in enumerate(self.figures):
468 if self.nrows == 0 or self.nplots == 0:
469 if self.nrows == 0 or self.nplots == 0:
469 log.warning('No data', self.name)
470 log.warning('No data', self.name)
470 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
471 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
471 fig.canvas.manager.set_window_title(self.CODE)
472 fig.canvas.manager.set_window_title(self.CODE)
472 continue
473 continue
473
474
474 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
475 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
475 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
476 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
476 fig.canvas.draw()
477 fig.canvas.draw()
477 if self.show:
478 if self.show:
478 fig.show()
479 fig.show()
479 figpause(0.01)
480 figpause(0.01)
480
481
481 if self.save:
482 if self.save:
482 self.save_figure(n)
483 self.save_figure(n)
483
484
484 if self.server:
485 if self.server:
485 self.send_to_server()
486 self.send_to_server()
486
487
487 def __update(self, dataOut, timestamp):
488 def __update(self, dataOut, timestamp):
488 '''
489 '''
489 '''
490 '''
490
491
491 metadata = {
492 metadata = {
492 'yrange': dataOut.heightList,
493 'yrange': dataOut.heightList,
493 'interval': dataOut.timeInterval,
494 'interval': dataOut.timeInterval,
494 'channels': dataOut.channelList
495 'channels': dataOut.channelList
495 }
496 }
496
497
497 data, meta = self.update(dataOut)
498 data, meta = self.update(dataOut)
498 metadata.update(meta)
499 metadata.update(meta)
499 self.data.update(data, timestamp, metadata)
500 self.data.update(data, timestamp, metadata)
500
501
501 def save_figure(self, n):
502 def save_figure(self, n):
502 '''
503 '''
503 '''
504 '''
504
505
505 if (self.data.max_time - self.save_time) <= self.save_period:
506 if (self.data.max_time - self.save_time) <= self.save_period:
506 return
507 return
507
508
508 self.save_time = self.data.max_time
509 self.save_time = self.data.max_time
509
510
510 fig = self.figures[n]
511 fig = self.figures[n]
511
512
512 if self.throttle == 0:
513 if self.throttle == 0:
513 figname = os.path.join(
514 figname = os.path.join(
514 self.save,
515 self.save,
515 self.save_code,
516 self.save_code,
516 '{}_{}.png'.format(
517 '{}_{}.png'.format(
517 self.save_code,
518 self.save_code,
518 self.getDateTime(self.data.max_time).strftime(
519 self.getDateTime(self.data.max_time).strftime(
519 '%Y%m%d_%H%M%S'
520 '%Y%m%d_%H%M%S'
520 ),
521 ),
521 )
522 )
522 )
523 )
523 log.log('Saving figure: {}'.format(figname), self.name)
524 log.log('Saving figure: {}'.format(figname), self.name)
524 if not os.path.isdir(os.path.dirname(figname)):
525 if not os.path.isdir(os.path.dirname(figname)):
525 os.makedirs(os.path.dirname(figname))
526 os.makedirs(os.path.dirname(figname))
526 fig.savefig(figname)
527 fig.savefig(figname)
527
528
528 figname = os.path.join(
529 figname = os.path.join(
529 self.save,
530 self.save,
530 #self.save_code,
531 #self.save_code,
531 '{}_{}.png'.format(
532 '{}_{}.png'.format(
532 self.save_code,
533 self.save_code,
533 self.getDateTime(self.data.min_time).strftime(
534 self.getDateTime(self.data.min_time).strftime(
534 '%Y%m%d'
535 '%Y%m%d'
535 ),
536 ),
536 )
537 )
537 )
538 )
538 log.log('Saving figure: {}'.format(figname), self.name)
539 log.log('Saving figure: {}'.format(figname), self.name)
539 if not os.path.isdir(os.path.dirname(figname)):
540 if not os.path.isdir(os.path.dirname(figname)):
540 os.makedirs(os.path.dirname(figname))
541 os.makedirs(os.path.dirname(figname))
541 fig.savefig(figname)
542 fig.savefig(figname)
542
543
543 def send_to_server(self):
544 def send_to_server(self):
544 '''
545 '''
545 '''
546 '''
546
547
547 if self.exp_code == None:
548 if self.exp_code == None:
548 log.warning('Missing `exp_code` skipping sending to server...')
549 log.warning('Missing `exp_code` skipping sending to server...')
549
550
550 last_time = self.data.max_time
551 last_time = self.data.max_time
551 interval = last_time - self.sender_time
552 interval = last_time - self.sender_time
552 if interval < self.sender_period:
553 if interval < self.sender_period:
553 return
554 return
554
555
555 self.sender_time = last_time
556 self.sender_time = last_time
556
557
557 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
558 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
558 for attr in attrs:
559 for attr in attrs:
559 value = getattr(self, attr)
560 value = getattr(self, attr)
560 if value:
561 if value:
561 if isinstance(value, (numpy.float32, numpy.float64)):
562 if isinstance(value, (numpy.float32, numpy.float64)):
562 value = round(float(value), 2)
563 value = round(float(value), 2)
563 self.data.meta[attr] = value
564 self.data.meta[attr] = value
564 if self.colormap == 'jet':
565 if self.colormap == 'jet':
565 self.data.meta['colormap'] = 'Jet'
566 self.data.meta['colormap'] = 'Jet'
566 elif 'RdBu' in self.colormap:
567 elif 'RdBu' in self.colormap:
567 self.data.meta['colormap'] = 'RdBu'
568 self.data.meta['colormap'] = 'RdBu'
568 else:
569 else:
569 self.data.meta['colormap'] = 'Viridis'
570 self.data.meta['colormap'] = 'Viridis'
570 self.data.meta['interval'] = int(interval)
571 self.data.meta['interval'] = int(interval)
571
572
572 self.sender_queue.append(last_time)
573 self.sender_queue.append(last_time)
573
574
574 while True:
575 while True:
575 try:
576 try:
576 tm = self.sender_queue.popleft()
577 tm = self.sender_queue.popleft()
577 except IndexError:
578 except IndexError:
578 break
579 break
579 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
580 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
580 self.socket.send_string(msg)
581 self.socket.send_string(msg)
581 socks = dict(self.poll.poll(2000))
582 socks = dict(self.poll.poll(2000))
582 if socks.get(self.socket) == zmq.POLLIN:
583 if socks.get(self.socket) == zmq.POLLIN:
583 reply = self.socket.recv_string()
584 reply = self.socket.recv_string()
584 if reply == 'ok':
585 if reply == 'ok':
585 log.log("Response from server ok", self.name)
586 log.log("Response from server ok", self.name)
586 time.sleep(0.1)
587 time.sleep(0.1)
587 continue
588 continue
588 else:
589 else:
589 log.warning(
590 log.warning(
590 "Malformed reply from server: {}".format(reply), self.name)
591 "Malformed reply from server: {}".format(reply), self.name)
591 else:
592 else:
592 log.warning(
593 log.warning(
593 "No response from server, retrying...", self.name)
594 "No response from server, retrying...", self.name)
594 self.sender_queue.appendleft(tm)
595 self.sender_queue.appendleft(tm)
595 self.socket.setsockopt(zmq.LINGER, 0)
596 self.socket.setsockopt(zmq.LINGER, 0)
596 self.socket.close()
597 self.socket.close()
597 self.poll.unregister(self.socket)
598 self.poll.unregister(self.socket)
598 self.socket = self.context.socket(zmq.REQ)
599 self.socket = self.context.socket(zmq.REQ)
599 self.socket.connect(self.server)
600 self.socket.connect(self.server)
600 self.poll.register(self.socket, zmq.POLLIN)
601 self.poll.register(self.socket, zmq.POLLIN)
601 break
602 break
602
603
603 def setup(self):
604 def setup(self):
604 '''
605 '''
605 This method should be implemented in the child class, the following
606 This method should be implemented in the child class, the following
606 attributes should be set:
607 attributes should be set:
607
608
608 self.nrows: number of rows
609 self.nrows: number of rows
609 self.ncols: number of cols
610 self.ncols: number of cols
610 self.nplots: number of plots (channels or pairs)
611 self.nplots: number of plots (channels or pairs)
611 self.ylabel: label for Y axes
612 self.ylabel: label for Y axes
612 self.titles: list of axes title
613 self.titles: list of axes title
613
614
614 '''
615 '''
615 raise NotImplementedError
616 raise NotImplementedError
616
617
617 def plot(self):
618 def plot(self):
618 '''
619 '''
619 Must be defined in the child class, the actual plotting method
620 Must be defined in the child class, the actual plotting method
620 '''
621 '''
621 raise NotImplementedError
622 raise NotImplementedError
622
623
623 def update(self, dataOut):
624 def update(self, dataOut):
624 '''
625 '''
625 Must be defined in the child class, update self.data with new data
626 Must be defined in the child class, update self.data with new data
626 '''
627 '''
627
628
628 data = {
629 data = {
629 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
630 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
630 }
631 }
631 meta = {}
632 meta = {}
632
633
633 return data, meta
634 return data, meta
634
635
635 def run(self, dataOut, **kwargs):
636 def run(self, dataOut, **kwargs):
636 '''
637 '''
637 Main plotting routine
638 Main plotting routine
638 '''
639 '''
639
640
640 if self.isConfig is False:
641 if self.isConfig is False:
641 self.__setup(**kwargs)
642 self.__setup(**kwargs)
642
643
643 if self.localtime:
644 if self.localtime:
644 self.getDateTime = datetime.datetime.fromtimestamp
645 self.getDateTime = datetime.datetime.fromtimestamp
645 else:
646 else:
646 self.getDateTime = datetime.datetime.utcfromtimestamp
647 self.getDateTime = datetime.datetime.utcfromtimestamp
647
648
648 self.data.setup()
649 self.data.setup()
649 self.isConfig = True
650 self.isConfig = True
650 if self.server:
651 if self.server:
651 self.context = zmq.Context()
652 self.context = zmq.Context()
652 self.socket = self.context.socket(zmq.REQ)
653 self.socket = self.context.socket(zmq.REQ)
653 self.socket.connect(self.server)
654 self.socket.connect(self.server)
654 self.poll = zmq.Poller()
655 self.poll = zmq.Poller()
655 self.poll.register(self.socket, zmq.POLLIN)
656 self.poll.register(self.socket, zmq.POLLIN)
656
657
657 tm = getattr(dataOut, self.attr_time)
658 tm = getattr(dataOut, self.attr_time)
658
659
659 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
660 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
660 self.save_time = tm
661 self.save_time = tm
661 self.__plot()
662 self.__plot()
662 self.tmin += self.xrange*60*60
663 self.tmin += self.xrange*60*60
663 self.data.setup()
664 self.data.setup()
664 self.clear_figures()
665 self.clear_figures()
665
666
666 self.__update(dataOut, tm)
667 self.__update(dataOut, tm)
667
668
668 if self.isPlotConfig is False:
669 if self.isPlotConfig is False:
669 self.__setup_plot()
670 self.__setup_plot()
670 self.isPlotConfig = True
671 self.isPlotConfig = True
671 if self.xaxis == 'time':
672 if self.xaxis == 'time':
672 dt = self.getDateTime(tm)
673 dt = self.getDateTime(tm)
673 if self.xmin is None:
674 if self.xmin is None:
674 self.tmin = tm
675 self.tmin = tm
675 self.xmin = dt.hour
676 self.xmin = dt.hour
676 minutes = (self.xmin-int(self.xmin)) * 60
677 minutes = (self.xmin-int(self.xmin)) * 60
677 seconds = (minutes - int(minutes)) * 60
678 seconds = (minutes - int(minutes)) * 60
678 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
679 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
679 datetime.datetime(1970, 1, 1)).total_seconds()
680 datetime.datetime(1970, 1, 1)).total_seconds()
680 if self.localtime:
681 if self.localtime:
681 self.tmin += time.timezone
682 self.tmin += time.timezone
682
683
683 if self.xmin is not None and self.xmax is not None:
684 if self.xmin is not None and self.xmax is not None:
684 self.xrange = self.xmax - self.xmin
685 self.xrange = self.xmax - self.xmin
685
686
686 if self.throttle == 0:
687 if self.throttle == 0:
687 self.__plot()
688 self.__plot()
688 else:
689 else:
689 self.__throttle_plot(self.__plot)#, coerce=coerce)
690 self.__throttle_plot(self.__plot)#, coerce=coerce)
690
691
691 def close(self):
692 def close(self):
692
693
693 if self.data and not self.data.flagNoData:
694 if self.data and not self.data.flagNoData:
694 self.save_time = 0
695 self.save_time = 0
695 self.__plot()
696 self.__plot()
696 if self.data and not self.data.flagNoData and self.pause:
697 if self.data and not self.data.flagNoData and self.pause:
697 figpause(10)
698 figpause(10)
@@ -1,381 +1,494
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4
4
5 from schainpy.model.graphics.jroplot_base import Plot, plt
5 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
7 from schainpy.utils import log
7 from schainpy.utils import log
8
8
9 EARTH_RADIUS = 6.3710e3
9 EARTH_RADIUS = 6.3710e3
10
10
11
11
12 def ll2xy(lat1, lon1, lat2, lon2):
12 def ll2xy(lat1, lon1, lat2, lon2):
13
13
14 p = 0.017453292519943295
14 p = 0.017453292519943295
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
20 theta = -theta + numpy.pi/2
20 theta = -theta + numpy.pi/2
21 return r*numpy.cos(theta), r*numpy.sin(theta)
21 return r*numpy.cos(theta), r*numpy.sin(theta)
22
22
23
23
24 def km2deg(km):
24 def km2deg(km):
25 '''
25 '''
26 Convert distance in km to degrees
26 Convert distance in km to degrees
27 '''
27 '''
28
28
29 return numpy.rad2deg(km/EARTH_RADIUS)
29 return numpy.rad2deg(km/EARTH_RADIUS)
30
30
31
31
32
32
33 class SpectralMomentsPlot(SpectraPlot):
33 class SpectralMomentsPlot(SpectraPlot):
34 '''
34 '''
35 Plot for Spectral Moments
35 Plot for Spectral Moments
36 '''
36 '''
37 CODE = 'spc_moments'
37 CODE = 'spc_moments'
38 # colormap = 'jet'
38 # colormap = 'jet'
39 # plot_type = 'pcolor'
39 # plot_type = 'pcolor'
40
40
41 class DobleGaussianPlot(SpectraPlot):
41 class DobleGaussianPlot(SpectraPlot):
42 '''
42 '''
43 Plot for Double Gaussian Plot
43 Plot for Double Gaussian Plot
44 '''
44 '''
45 CODE = 'gaussian_fit'
45 CODE = 'gaussian_fit'
46 # colormap = 'jet'
46 # colormap = 'jet'
47 # plot_type = 'pcolor'
47 # plot_type = 'pcolor'
48
48
49
49
50 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
50 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
51 '''
51 '''
52 Plot SpectraCut with Double Gaussian Fit
52 Plot SpectraCut with Double Gaussian Fit
53 '''
53 '''
54 CODE = 'cut_gaussian_fit'
54 CODE = 'cut_gaussian_fit'
55
55
56
56
57 class SpectralFitObliquePlot(SpectraPlot):
57 class SpectralFitObliquePlot(SpectraPlot):
58 '''
58 '''
59 Plot for Spectral Oblique
59 Plot for Spectral Oblique
60 '''
60 '''
61 CODE = 'spc_moments'
61 CODE = 'spc_moments'
62 colormap = 'jet'
62 colormap = 'jet'
63 plot_type = 'pcolor'
63 plot_type = 'pcolor'
64
64
65
65
66
66
67 class SnrPlot(RTIPlot):
67 class SnrPlot(RTIPlot):
68 '''
68 '''
69 Plot for SNR Data
69 Plot for SNR Data
70 '''
70 '''
71
71
72 CODE = 'snr'
72 CODE = 'snr'
73 colormap = 'jet'
73 colormap = 'jet'
74
74
75 def update(self, dataOut):
75 def update(self, dataOut):
76
76
77 data = {
77 data = {
78 'snr': 10*numpy.log10(dataOut.data_snr)
78 'snr': 10*numpy.log10(dataOut.data_snr)
79 }
79 }
80
80
81 return data, {}
81 return data, {}
82
82
83 class DopplerPlot(RTIPlot):
83 class DopplerPlot(RTIPlot):
84 '''
84 '''
85 Plot for DOPPLER Data (1st moment)
85 Plot for DOPPLER Data (1st moment)
86 '''
86 '''
87
87
88 CODE = 'dop'
88 CODE = 'dop'
89 colormap = 'jet'
89 colormap = 'jet'
90
90
91 def update(self, dataOut):
91 def update(self, dataOut):
92
92
93 data = {
93 data = {
94 'dop': 10*numpy.log10(dataOut.data_dop)
94 'dop': 10*numpy.log10(dataOut.data_dop)
95 }
96
97 return data, {}
98
99 class DopplerEEJPlot_V0(RTIPlot):
100 '''
101 Written by R. Flores
102 '''
103 '''
104 Plot for EEJ
105 '''
106
107 CODE = 'dop'
108 colormap = 'RdBu_r'
109 colormap = 'jet'
110
111 def setup(self):
112
113 self.xaxis = 'time'
114 self.ncols = 1
115 self.nrows = len(self.data.channels)
116 self.nplots = len(self.data.channels)
117 self.ylabel = 'Range [km]'
118 self.xlabel = 'Time'
119 self.cb_label = '(m/s)'
120 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
121 self.titles = ['{} Channel {}'.format(
122 self.CODE.upper(), x) for x in range(self.nrows)]
123
124 def update(self, dataOut):
125 #print(self.EEJtype)
126
127 if self.EEJtype == 1:
128 data = {
129 'dop': dataOut.Oblique_params[:,-2,:]
130 }
131 elif self.EEJtype == 2:
132 data = {
133 'dop': dataOut.Oblique_params[:,-1,:]
134 }
135
136 return data, {}
137
138 class DopplerEEJPlot(RTIPlot):
139 '''
140 Written by R. Flores
141 '''
142 '''
143 Plot for Doppler Shift EEJ
144 '''
145
146 CODE = 'dop'
147 colormap = 'RdBu_r'
148 #colormap = 'jet'
149
150 def setup(self):
151
152 self.xaxis = 'time'
153 self.ncols = 1
154 self.nrows = 2
155 self.nplots = 2
156 self.ylabel = 'Range [km]'
157 self.xlabel = 'Time'
158 self.cb_label = '(m/s)'
159 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
160 self.titles = ['{} EJJ Type {} /'.format(
161 self.CODE.upper(), x) for x in range(1,1+self.nrows)]
162
163 def update(self, dataOut):
164
165 if dataOut.mode == 11: #Double Gaussian
166 doppler = numpy.append(dataOut.Oblique_params[:,1,:],dataOut.Oblique_params[:,4,:],axis=0)
167 elif dataOut.mode == 9: #Double Skew Gaussian
168 doppler = numpy.append(dataOut.Oblique_params[:,-2,:],dataOut.Oblique_params[:,-1,:],axis=0)
169 data = {
170 'dop': doppler
171 }
172
173 return data, {}
174
175 class SpcWidthEEJPlot(RTIPlot):
176 '''
177 Written by R. Flores
178 '''
179 '''
180 Plot for EEJ Spectral Width
181 '''
182
183 CODE = 'width'
184 colormap = 'RdBu_r'
185 colormap = 'jet'
186
187 def setup(self):
188
189 self.xaxis = 'time'
190 self.ncols = 1
191 self.nrows = 2
192 self.nplots = 2
193 self.ylabel = 'Range [km]'
194 self.xlabel = 'Time'
195 self.cb_label = '(m/s)'
196 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
197 self.titles = ['{} EJJ Type {} /'.format(
198 self.CODE.upper(), x) for x in range(1,1+self.nrows)]
199
200 def update(self, dataOut):
201
202 if dataOut.mode == 11: #Double Gaussian
203 width = numpy.append(dataOut.Oblique_params[:,2,:],dataOut.Oblique_params[:,5,:],axis=0)
204 elif dataOut.mode == 9: #Double Skew Gaussian
205 width = numpy.append(dataOut.Oblique_params[:,2,:],dataOut.Oblique_params[:,6,:],axis=0)
206 data = {
207 'width': width
95 }
208 }
96
209
97 return data, {}
210 return data, {}
98
211
99 class PowerPlot(RTIPlot):
212 class PowerPlot(RTIPlot):
100 '''
213 '''
101 Plot for Power Data (0 moment)
214 Plot for Power Data (0 moment)
102 '''
215 '''
103
216
104 CODE = 'pow'
217 CODE = 'pow'
105 colormap = 'jet'
218 colormap = 'jet'
106
219
107 def update(self, dataOut):
220 def update(self, dataOut):
108
221
109 data = {
222 data = {
110 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
223 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
111 }
224 }
112
225
113 return data, {}
226 return data, {}
114
227
115 class SpectralWidthPlot(RTIPlot):
228 class SpectralWidthPlot(RTIPlot):
116 '''
229 '''
117 Plot for Spectral Width Data (2nd moment)
230 Plot for Spectral Width Data (2nd moment)
118 '''
231 '''
119
232
120 CODE = 'width'
233 CODE = 'width'
121 colormap = 'jet'
234 colormap = 'jet'
122
235
123 def update(self, dataOut):
236 def update(self, dataOut):
124
237
125 data = {
238 data = {
126 'width': dataOut.data_width
239 'width': dataOut.data_width
127 }
240 }
128
241
129 return data, {}
242 return data, {}
130
243
131 class SkyMapPlot(Plot):
244 class SkyMapPlot(Plot):
132 '''
245 '''
133 Plot for meteors detection data
246 Plot for meteors detection data
134 '''
247 '''
135
248
136 CODE = 'param'
249 CODE = 'param'
137
250
138 def setup(self):
251 def setup(self):
139
252
140 self.ncols = 1
253 self.ncols = 1
141 self.nrows = 1
254 self.nrows = 1
142 self.width = 7.2
255 self.width = 7.2
143 self.height = 7.2
256 self.height = 7.2
144 self.nplots = 1
257 self.nplots = 1
145 self.xlabel = 'Zonal Zenith Angle (deg)'
258 self.xlabel = 'Zonal Zenith Angle (deg)'
146 self.ylabel = 'Meridional Zenith Angle (deg)'
259 self.ylabel = 'Meridional Zenith Angle (deg)'
147 self.polar = True
260 self.polar = True
148 self.ymin = -180
261 self.ymin = -180
149 self.ymax = 180
262 self.ymax = 180
150 self.colorbar = False
263 self.colorbar = False
151
264
152 def plot(self):
265 def plot(self):
153
266
154 arrayParameters = numpy.concatenate(self.data['param'])
267 arrayParameters = numpy.concatenate(self.data['param'])
155 error = arrayParameters[:, -1]
268 error = arrayParameters[:, -1]
156 indValid = numpy.where(error == 0)[0]
269 indValid = numpy.where(error == 0)[0]
157 finalMeteor = arrayParameters[indValid, :]
270 finalMeteor = arrayParameters[indValid, :]
158 finalAzimuth = finalMeteor[:, 3]
271 finalAzimuth = finalMeteor[:, 3]
159 finalZenith = finalMeteor[:, 4]
272 finalZenith = finalMeteor[:, 4]
160
273
161 x = finalAzimuth * numpy.pi / 180
274 x = finalAzimuth * numpy.pi / 180
162 y = finalZenith
275 y = finalZenith
163
276
164 ax = self.axes[0]
277 ax = self.axes[0]
165
278
166 if ax.firsttime:
279 if ax.firsttime:
167 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
280 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
168 else:
281 else:
169 ax.plot.set_data(x, y)
282 ax.plot.set_data(x, y)
170
283
171 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
284 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
172 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
285 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
173 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
286 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
174 dt2,
287 dt2,
175 len(x))
288 len(x))
176 self.titles[0] = title
289 self.titles[0] = title
177
290
178
291
179 class GenericRTIPlot(Plot):
292 class GenericRTIPlot(Plot):
180 '''
293 '''
181 Plot for data_xxxx object
294 Plot for data_xxxx object
182 '''
295 '''
183
296
184 CODE = 'param'
297 CODE = 'param'
185 colormap = 'viridis'
298 colormap = 'viridis'
186 plot_type = 'pcolorbuffer'
299 plot_type = 'pcolorbuffer'
187
300
188 def setup(self):
301 def setup(self):
189 self.xaxis = 'time'
302 self.xaxis = 'time'
190 self.ncols = 1
303 self.ncols = 1
191 self.nrows = self.data.shape('param')[0]
304 self.nrows = self.data.shape('param')[0]
192 self.nplots = self.nrows
305 self.nplots = self.nrows
193 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
306 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
194
307
195 if not self.xlabel:
308 if not self.xlabel:
196 self.xlabel = 'Time'
309 self.xlabel = 'Time'
197
310
198 self.ylabel = 'Range [km]'
311 self.ylabel = 'Range [km]'
199 if not self.titles:
312 if not self.titles:
200 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
313 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
201
314
202 def update(self, dataOut):
315 def update(self, dataOut):
203
316
204 data = {
317 data = {
205 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
318 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
206 }
319 }
207
320
208 meta = {}
321 meta = {}
209
322
210 return data, meta
323 return data, meta
211
324
212 def plot(self):
325 def plot(self):
213 # self.data.normalize_heights()
326 # self.data.normalize_heights()
214 self.x = self.data.times
327 self.x = self.data.times
215 self.y = self.data.yrange
328 self.y = self.data.yrange
216 self.z = self.data['param']
329 self.z = self.data['param']
217
330
218 self.z = numpy.ma.masked_invalid(self.z)
331 self.z = numpy.ma.masked_invalid(self.z)
219
332
220 if self.decimation is None:
333 if self.decimation is None:
221 x, y, z = self.fill_gaps(self.x, self.y, self.z)
334 x, y, z = self.fill_gaps(self.x, self.y, self.z)
222 else:
335 else:
223 x, y, z = self.fill_gaps(*self.decimate())
336 x, y, z = self.fill_gaps(*self.decimate())
224
337
225 for n, ax in enumerate(self.axes):
338 for n, ax in enumerate(self.axes):
226
339
227 self.zmax = self.zmax if self.zmax is not None else numpy.max(
340 self.zmax = self.zmax if self.zmax is not None else numpy.max(
228 self.z[n])
341 self.z[n])
229 self.zmin = self.zmin if self.zmin is not None else numpy.min(
342 self.zmin = self.zmin if self.zmin is not None else numpy.min(
230 self.z[n])
343 self.z[n])
231
344
232 if ax.firsttime:
345 if ax.firsttime:
233 if self.zlimits is not None:
346 if self.zlimits is not None:
234 self.zmin, self.zmax = self.zlimits[n]
347 self.zmin, self.zmax = self.zlimits[n]
235
348
236 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
349 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
237 vmin=self.zmin,
350 vmin=self.zmin,
238 vmax=self.zmax,
351 vmax=self.zmax,
239 cmap=self.cmaps[n]
352 cmap=self.cmaps[n]
240 )
353 )
241 else:
354 else:
242 if self.zlimits is not None:
355 if self.zlimits is not None:
243 self.zmin, self.zmax = self.zlimits[n]
356 self.zmin, self.zmax = self.zlimits[n]
244 ax.collections.remove(ax.collections[0])
357 ax.collections.remove(ax.collections[0])
245 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
358 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
246 vmin=self.zmin,
359 vmin=self.zmin,
247 vmax=self.zmax,
360 vmax=self.zmax,
248 cmap=self.cmaps[n]
361 cmap=self.cmaps[n]
249 )
362 )
250
363
251
364
252 class PolarMapPlot(Plot):
365 class PolarMapPlot(Plot):
253 '''
366 '''
254 Plot for weather radar
367 Plot for weather radar
255 '''
368 '''
256
369
257 CODE = 'param'
370 CODE = 'param'
258 colormap = 'seismic'
371 colormap = 'seismic'
259
372
260 def setup(self):
373 def setup(self):
261 self.ncols = 1
374 self.ncols = 1
262 self.nrows = 1
375 self.nrows = 1
263 self.width = 9
376 self.width = 9
264 self.height = 8
377 self.height = 8
265 self.mode = self.data.meta['mode']
378 self.mode = self.data.meta['mode']
266 if self.channels is not None:
379 if self.channels is not None:
267 self.nplots = len(self.channels)
380 self.nplots = len(self.channels)
268 self.nrows = len(self.channels)
381 self.nrows = len(self.channels)
269 else:
382 else:
270 self.nplots = self.data.shape(self.CODE)[0]
383 self.nplots = self.data.shape(self.CODE)[0]
271 self.nrows = self.nplots
384 self.nrows = self.nplots
272 self.channels = list(range(self.nplots))
385 self.channels = list(range(self.nplots))
273 if self.mode == 'E':
386 if self.mode == 'E':
274 self.xlabel = 'Longitude'
387 self.xlabel = 'Longitude'
275 self.ylabel = 'Latitude'
388 self.ylabel = 'Latitude'
276 else:
389 else:
277 self.xlabel = 'Range (km)'
390 self.xlabel = 'Range (km)'
278 self.ylabel = 'Height (km)'
391 self.ylabel = 'Height (km)'
279 self.bgcolor = 'white'
392 self.bgcolor = 'white'
280 self.cb_labels = self.data.meta['units']
393 self.cb_labels = self.data.meta['units']
281 self.lat = self.data.meta['latitude']
394 self.lat = self.data.meta['latitude']
282 self.lon = self.data.meta['longitude']
395 self.lon = self.data.meta['longitude']
283 self.xmin, self.xmax = float(
396 self.xmin, self.xmax = float(
284 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
397 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
285 self.ymin, self.ymax = float(
398 self.ymin, self.ymax = float(
286 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
399 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
287 # self.polar = True
400 # self.polar = True
288
401
289 def plot(self):
402 def plot(self):
290
403
291 for n, ax in enumerate(self.axes):
404 for n, ax in enumerate(self.axes):
292 data = self.data['param'][self.channels[n]]
405 data = self.data['param'][self.channels[n]]
293
406
294 zeniths = numpy.linspace(
407 zeniths = numpy.linspace(
295 0, self.data.meta['max_range'], data.shape[1])
408 0, self.data.meta['max_range'], data.shape[1])
296 if self.mode == 'E':
409 if self.mode == 'E':
297 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
410 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
298 r, theta = numpy.meshgrid(zeniths, azimuths)
411 r, theta = numpy.meshgrid(zeniths, azimuths)
299 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
412 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
300 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
413 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
301 x = km2deg(x) + self.lon
414 x = km2deg(x) + self.lon
302 y = km2deg(y) + self.lat
415 y = km2deg(y) + self.lat
303 else:
416 else:
304 azimuths = numpy.radians(self.data.yrange)
417 azimuths = numpy.radians(self.data.yrange)
305 r, theta = numpy.meshgrid(zeniths, azimuths)
418 r, theta = numpy.meshgrid(zeniths, azimuths)
306 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
419 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
307 self.y = zeniths
420 self.y = zeniths
308
421
309 if ax.firsttime:
422 if ax.firsttime:
310 if self.zlimits is not None:
423 if self.zlimits is not None:
311 self.zmin, self.zmax = self.zlimits[n]
424 self.zmin, self.zmax = self.zlimits[n]
312 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
425 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
313 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
426 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
314 vmin=self.zmin,
427 vmin=self.zmin,
315 vmax=self.zmax,
428 vmax=self.zmax,
316 cmap=self.cmaps[n])
429 cmap=self.cmaps[n])
317 else:
430 else:
318 if self.zlimits is not None:
431 if self.zlimits is not None:
319 self.zmin, self.zmax = self.zlimits[n]
432 self.zmin, self.zmax = self.zlimits[n]
320 ax.collections.remove(ax.collections[0])
433 ax.collections.remove(ax.collections[0])
321 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
434 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
322 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
435 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
323 vmin=self.zmin,
436 vmin=self.zmin,
324 vmax=self.zmax,
437 vmax=self.zmax,
325 cmap=self.cmaps[n])
438 cmap=self.cmaps[n])
326
439
327 if self.mode == 'A':
440 if self.mode == 'A':
328 continue
441 continue
329
442
330 # plot district names
443 # plot district names
331 f = open('/data/workspace/schain_scripts/distrito.csv')
444 f = open('/data/workspace/schain_scripts/distrito.csv')
332 for line in f:
445 for line in f:
333 label, lon, lat = [s.strip() for s in line.split(',') if s]
446 label, lon, lat = [s.strip() for s in line.split(',') if s]
334 lat = float(lat)
447 lat = float(lat)
335 lon = float(lon)
448 lon = float(lon)
336 # ax.plot(lon, lat, '.b', ms=2)
449 # ax.plot(lon, lat, '.b', ms=2)
337 ax.text(lon, lat, label.decode('utf8'), ha='center',
450 ax.text(lon, lat, label.decode('utf8'), ha='center',
338 va='bottom', size='8', color='black')
451 va='bottom', size='8', color='black')
339
452
340 # plot limites
453 # plot limites
341 limites = []
454 limites = []
342 tmp = []
455 tmp = []
343 for line in open('/data/workspace/schain_scripts/lima.csv'):
456 for line in open('/data/workspace/schain_scripts/lima.csv'):
344 if '#' in line:
457 if '#' in line:
345 if tmp:
458 if tmp:
346 limites.append(tmp)
459 limites.append(tmp)
347 tmp = []
460 tmp = []
348 continue
461 continue
349 values = line.strip().split(',')
462 values = line.strip().split(',')
350 tmp.append((float(values[0]), float(values[1])))
463 tmp.append((float(values[0]), float(values[1])))
351 for points in limites:
464 for points in limites:
352 ax.add_patch(
465 ax.add_patch(
353 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
466 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
354
467
355 # plot Cuencas
468 # plot Cuencas
356 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
469 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
357 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
470 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
358 values = [line.strip().split(',') for line in f]
471 values = [line.strip().split(',') for line in f]
359 points = [(float(s[0]), float(s[1])) for s in values]
472 points = [(float(s[0]), float(s[1])) for s in values]
360 ax.add_patch(Polygon(points, ec='b', fc='none'))
473 ax.add_patch(Polygon(points, ec='b', fc='none'))
361
474
362 # plot grid
475 # plot grid
363 for r in (15, 30, 45, 60):
476 for r in (15, 30, 45, 60):
364 ax.add_artist(plt.Circle((self.lon, self.lat),
477 ax.add_artist(plt.Circle((self.lon, self.lat),
365 km2deg(r), color='0.6', fill=False, lw=0.2))
478 km2deg(r), color='0.6', fill=False, lw=0.2))
366 ax.text(
479 ax.text(
367 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
480 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
368 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
481 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
369 '{}km'.format(r),
482 '{}km'.format(r),
370 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
483 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
371
484
372 if self.mode == 'E':
485 if self.mode == 'E':
373 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
486 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
374 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
487 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
375 else:
488 else:
376 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
489 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
377 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
490 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
378
491
379 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
492 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
380 self.titles = ['{} {}'.format(
493 self.titles = ['{} {}'.format(
381 self.data.parameters[x], title) for x in self.channels]
494 self.data.parameters[x], title) for x in self.channels]
@@ -1,1290 +1,1315
1 # Copyright (c) 2012-2021 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2021 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Classes to plot Spectra data
5 """Classes to plot Spectra data
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import numpy
10 import numpy
11
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13
13
14 class SpectraPlot(Plot):
14 class SpectraPlot(Plot):
15 '''
15 '''
16 Plot for Spectra data
16 Plot for Spectra data
17 '''
17 '''
18
18
19 CODE = 'spc'
19 CODE = 'spc'
20 colormap = 'jet'
20 colormap = 'jet'
21 plot_type = 'pcolor'
21 plot_type = 'pcolor'
22 buffering = False
22 buffering = False
23
23
24 def setup(self):
24 def setup(self):
25
25
26 self.nplots = len(self.data.channels)
26 self.nplots = len(self.data.channels)
27 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
27 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
28 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
28 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
29 self.height = 2.6 * self.nrows
29 self.height = 2.6 * self.nrows
30 self.cb_label = 'dB'
30 self.cb_label = 'dB'
31 if self.showprofile:
31 if self.showprofile:
32 self.width = 4 * self.ncols
32 self.width = 4 * self.ncols
33 else:
33 else:
34 self.width = 3.5 * self.ncols
34 self.width = 3.5 * self.ncols
35 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
35 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
36 self.ylabel = 'Range [km]'
36 self.ylabel = 'Range [km]'
37
37
38 def update(self, dataOut):
38 def update(self, dataOut):
39
39
40 data = {}
40 data = {}
41 meta = {}
41 meta = {}
42
42 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
43 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
44 #print("Spc: ",spc[0])
45 #exit(1)
43 data['spc'] = spc
46 data['spc'] = spc
44 data['rti'] = dataOut.getPower()
47 data['rti'] = dataOut.getPower()
48 #print(data['rti'][0])
49 #exit(1)
45 #print("NormFactor: ",dataOut.normFactor)
50 #print("NormFactor: ",dataOut.normFactor)
46 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
51 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
47 if hasattr(dataOut, 'LagPlot'): #Double Pulse
52 if hasattr(dataOut, 'LagPlot'): #Double Pulse
48 max_hei_id = dataOut.nHeights - 2*dataOut.LagPlot
53 max_hei_id = dataOut.nHeights - 2*dataOut.LagPlot
49 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=46,ymax_index=max_hei_id)/dataOut.normFactor)
54 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=46,ymax_index=max_hei_id)/dataOut.normFactor)
50 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=40,ymax_index=max_hei_id)/dataOut.normFactor)
55 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=40,ymax_index=max_hei_id)/dataOut.normFactor)
51 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=53,ymax_index=max_hei_id)/dataOut.normFactor)
56 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=53,ymax_index=max_hei_id)/dataOut.normFactor)
52 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=53)[0]/dataOut.normFactor)
57 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=53)[0]/dataOut.normFactor)
53 #data['noise'][1] = 22.035507
58 #data['noise'][1] = 22.035507
54 else:
59 else:
55 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
60 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
56 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=26,ymax_index=44)/dataOut.normFactor)
61 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=26,ymax_index=44)/dataOut.normFactor)
57 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
62 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
58
63
59 if self.CODE == 'spc_moments':
64 if self.CODE == 'spc_moments':
60 data['moments'] = dataOut.moments
65 data['moments'] = dataOut.moments
61 if self.CODE == 'gaussian_fit':
66 if self.CODE == 'gaussian_fit':
62 data['gaussfit'] = dataOut.DGauFitParams
67 data['gaussfit'] = dataOut.DGauFitParams
63
68
64 return data, meta
69 return data, meta
65
70
66 def plot(self):
71 def plot(self):
67
72
68 if self.xaxis == "frequency":
73 if self.xaxis == "frequency":
69 x = self.data.xrange[0]
74 x = self.data.xrange[0]
70 self.xlabel = "Frequency (kHz)"
75 self.xlabel = "Frequency (kHz)"
71 elif self.xaxis == "time":
76 elif self.xaxis == "time":
72 x = self.data.xrange[1]
77 x = self.data.xrange[1]
73 self.xlabel = "Time (ms)"
78 self.xlabel = "Time (ms)"
74 else:
79 else:
75 x = self.data.xrange[2]
80 x = self.data.xrange[2]
76 self.xlabel = "Velocity (m/s)"
81 self.xlabel = "Velocity (m/s)"
77
82
78 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
83 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
79 x = self.data.xrange[2]
84 x = self.data.xrange[2]
80 self.xlabel = "Velocity (m/s)"
85 self.xlabel = "Velocity (m/s)"
81
86
82 self.titles = []
87 self.titles = []
83
88
84 y = self.data.yrange
89 y = self.data.yrange
85 self.y = y
90 self.y = y
86
91
87 data = self.data[-1]
92 data = self.data[-1]
88 z = data['spc']
93 z = data['spc']
89
94
90 self.CODE2 = 'spc_oblique'
95 self.CODE2 = 'spc_oblique'
91
96
92
97
93 for n, ax in enumerate(self.axes):
98 for n, ax in enumerate(self.axes):
94 noise = data['noise'][n]
99 noise = data['noise'][n]
95 if self.CODE == 'spc_moments':
100 if self.CODE == 'spc_moments':
96 mean = data['moments'][n, 1]
101 mean = data['moments'][n, 1]
97 if self.CODE == 'gaussian_fit':
102 if self.CODE == 'gaussian_fit':
98 gau0 = data['gaussfit'][n][2,:,0]
103 gau0 = data['gaussfit'][n][2,:,0]
99 gau1 = data['gaussfit'][n][2,:,1]
104 gau1 = data['gaussfit'][n][2,:,1]
100 if ax.firsttime:
105 if ax.firsttime:
101 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
106 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
102 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)#-self.xmax
107 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)#-self.xmax
103 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
108 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
104 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
109 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
105
110
106 ax.plt = ax.pcolormesh(x, y, z[n].T,
111 ax.plt = ax.pcolormesh(x, y, z[n].T,
107 vmin=self.zmin,
112 vmin=self.zmin,
108 vmax=self.zmax,
113 vmax=self.zmax,
109 cmap=plt.get_cmap(self.colormap),
114 cmap=plt.get_cmap(self.colormap),
110 )
115 )
111
116
112 if self.showprofile:
117 if self.showprofile:
113 ax.plt_profile = self.pf_axes[n].plot(
118 ax.plt_profile = self.pf_axes[n].plot(
114 data['rti'][n], y)[0]
119 data['rti'][n], y)[0]
115 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
120 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
116 color="k", linestyle="dashed", lw=1)[0]
121 color="k", linestyle="dashed", lw=1)[0]
117 if self.CODE == 'spc_moments':
122 if self.CODE == 'spc_moments':
118 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
123 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
119 if self.CODE == 'gaussian_fit':
124 if self.CODE == 'gaussian_fit':
120 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
125 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
121 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
126 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
122 else:
127 else:
123 ax.plt.set_array(z[n].T.ravel())
128 ax.plt.set_array(z[n].T.ravel())
124 if self.showprofile:
129 if self.showprofile:
125 ax.plt_profile.set_data(data['rti'][n], y)
130 ax.plt_profile.set_data(data['rti'][n], y)
126 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
131 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
127 if self.CODE == 'spc_moments':
132 if self.CODE == 'spc_moments':
128 ax.plt_mean.set_data(mean, y)
133 ax.plt_mean.set_data(mean, y)
129 if self.CODE == 'gaussian_fit':
134 if self.CODE == 'gaussian_fit':
130 ax.plt_gau0.set_data(gau0, y)
135 ax.plt_gau0.set_data(gau0, y)
131 ax.plt_gau1.set_data(gau1, y)
136 ax.plt_gau1.set_data(gau1, y)
132 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
137 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
133
138
134 class SpectraObliquePlot(Plot):
139 class SpectraObliquePlot(Plot):
135 '''
140 '''
136 Plot for Spectra data
141 Plot for Spectra data
137 '''
142 '''
138
143
139 CODE = 'spc_oblique'
144 CODE = 'spc_oblique'
140 colormap = 'jet'
145 colormap = 'jet'
141 plot_type = 'pcolor'
146 plot_type = 'pcolor'
142
147
143 def setup(self):
148 def setup(self):
144 self.xaxis = "oblique"
149 self.xaxis = "oblique"
145 self.nplots = len(self.data.channels)
150 self.nplots = len(self.data.channels)
146 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
151 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
147 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
152 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
148 self.height = 2.6 * self.nrows
153 self.height = 2.6 * self.nrows
149 self.cb_label = 'dB'
154 self.cb_label = 'dB'
150 if self.showprofile:
155 if self.showprofile:
151 self.width = 4 * self.ncols
156 self.width = 4 * self.ncols
152 else:
157 else:
153 self.width = 3.5 * self.ncols
158 self.width = 3.5 * self.ncols
154 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
159 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
155 self.ylabel = 'Range [km]'
160 self.ylabel = 'Range [km]'
156
161
157 def update(self, dataOut):
162 def update(self, dataOut):
158
163
159 data = {}
164 data = {}
160 meta = {}
165 meta = {}
161 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
166 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
162 data['spc'] = spc
167 data['spc'] = spc
163 data['rti'] = dataOut.getPower()
168 data['rti'] = dataOut.getPower()
164 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
169 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
165 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
170 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
166
171 '''
167 data['shift1'] = dataOut.Oblique_params[0][1]
172 data['shift1'] = dataOut.Oblique_params[0,-2,:]
168 data['shift2'] = dataOut.Oblique_params[0][4]
173 data['shift2'] = dataOut.Oblique_params[0,-1,:]
169 data['shift1_error'] = dataOut.Oblique_param_errors[0][1]
174 data['shift1_error'] = dataOut.Oblique_param_errors[0,-2,:]
170 data['shift2_error'] = dataOut.Oblique_param_errors[0][4]
175 data['shift2_error'] = dataOut.Oblique_param_errors[0,-1,:]
176 '''
177 '''
178 data['shift1'] = dataOut.Oblique_params[0,1,:]
179 data['shift2'] = dataOut.Oblique_params[0,4,:]
180 data['shift1_error'] = dataOut.Oblique_param_errors[0,1,:]
181 data['shift2_error'] = dataOut.Oblique_param_errors[0,4,:]
182 '''
183 data['shift1'] = dataOut.Dop_EEJ_T1[0]
184 data['shift2'] = dataOut.Dop_EEJ_T2[0]
185 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
186 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
171
187
172 return data, meta
188 return data, meta
173
189
174 def plot(self):
190 def plot(self):
175
191
176 if self.xaxis == "frequency":
192 if self.xaxis == "frequency":
177 x = self.data.xrange[0]
193 x = self.data.xrange[0]
178 self.xlabel = "Frequency (kHz)"
194 self.xlabel = "Frequency (kHz)"
179 elif self.xaxis == "time":
195 elif self.xaxis == "time":
180 x = self.data.xrange[1]
196 x = self.data.xrange[1]
181 self.xlabel = "Time (ms)"
197 self.xlabel = "Time (ms)"
182 else:
198 else:
183 x = self.data.xrange[2]
199 x = self.data.xrange[2]
184 self.xlabel = "Velocity (m/s)"
200 self.xlabel = "Velocity (m/s)"
185
201
186 self.titles = []
202 self.titles = []
187
203
188 y = self.data.yrange
204 y = self.data.yrange
189 self.y = y
205 self.y = y
190 z = self.data['spc']
206
207 data = self.data[-1]
208 z = data['spc']
191
209
192 for n, ax in enumerate(self.axes):
210 for n, ax in enumerate(self.axes):
193 noise = self.data['noise'][n][-1]
211 noise = self.data['noise'][n][-1]
194 shift1 = self.data['shift1']
212 shift1 = data['shift1']
195 shift2 = self.data['shift2']
213 #print(shift1)
196 err1 = self.data['shift1_error']
214 shift2 = data['shift2']
197 err2 = self.data['shift2_error']
215 err1 = data['shift1_error']
216 err2 = data['shift2_error']
198 if ax.firsttime:
217 if ax.firsttime:
218
199 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
219 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
200 self.xmin = self.xmin if self.xmin else -self.xmax
220 self.xmin = self.xmin if self.xmin else -self.xmax
201 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
221 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
202 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
222 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
203 ax.plt = ax.pcolormesh(x, y, z[n].T,
223 ax.plt = ax.pcolormesh(x, y, z[n].T,
204 vmin=self.zmin,
224 vmin=self.zmin,
205 vmax=self.zmax,
225 vmax=self.zmax,
206 cmap=plt.get_cmap(self.colormap)
226 cmap=plt.get_cmap(self.colormap)
207 )
227 )
208
228
209 if self.showprofile:
229 if self.showprofile:
210 ax.plt_profile = self.pf_axes[n].plot(
230 ax.plt_profile = self.pf_axes[n].plot(
211 self.data['rti'][n][-1], y)[0]
231 self.data['rti'][n][-1], y)[0]
212 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
232 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
213 color="k", linestyle="dashed", lw=1)[0]
233 color="k", linestyle="dashed", lw=1)[0]
214
234
215 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=0.2, marker='x', linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
235 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
216 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
236 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
237 #print("plotter1: ", self.ploterr1,shift1)
238
217 else:
239 else:
240 #print("else plotter1: ", self.ploterr1,shift1)
218 self.ploterr1.remove()
241 self.ploterr1.remove()
219 self.ploterr2.remove()
242 self.ploterr2.remove()
220 ax.plt.set_array(z[n].T.ravel())
243 ax.plt.set_array(z[n].T.ravel())
221 if self.showprofile:
244 if self.showprofile:
222 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
245 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
223 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
246 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
224 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
247 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
225 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
248 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
226
249
227 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
250 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
228
251
229
252
230 class CrossSpectraPlot(Plot):
253 class CrossSpectraPlot(Plot):
231
254
232 CODE = 'cspc'
255 CODE = 'cspc'
233 colormap = 'jet'
256 colormap = 'jet'
234 plot_type = 'pcolor'
257 plot_type = 'pcolor'
235 zmin_coh = None
258 zmin_coh = None
236 zmax_coh = None
259 zmax_coh = None
237 zmin_phase = None
260 zmin_phase = None
238 zmax_phase = None
261 zmax_phase = None
239
262
240 def setup(self):
263 def setup(self):
241
264
242 self.ncols = 4
265 self.ncols = 4
243 self.nplots = len(self.data.pairs) * 2
266 self.nplots = len(self.data.pairs) * 2
244 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
267 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
245 self.width = 3.1 * self.ncols
268 self.width = 3.1 * self.ncols
246 self.height = 5 * self.nrows
269 self.height = 5 * self.nrows
247 self.ylabel = 'Range [km]'
270 self.ylabel = 'Range [km]'
248 self.showprofile = False
271 self.showprofile = False
249 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
272 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
250
273
251 def update(self, dataOut):
274 def update(self, dataOut):
252
275
253 data = {}
276 data = {}
254 meta = {}
277 meta = {}
255
278
256 spc = dataOut.data_spc
279 spc = dataOut.data_spc
257 cspc = dataOut.data_cspc
280 cspc = dataOut.data_cspc
258 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
281 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
259 meta['pairs'] = dataOut.pairsList
282 meta['pairs'] = dataOut.pairsList
260
283
261 tmp = []
284 tmp = []
262
285
263 for n, pair in enumerate(meta['pairs']):
286 for n, pair in enumerate(meta['pairs']):
264 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
287 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
265 coh = numpy.abs(out)
288 coh = numpy.abs(out)
266 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
289 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
267 tmp.append(coh)
290 tmp.append(coh)
268 tmp.append(phase)
291 tmp.append(phase)
269
292
270 data['cspc'] = numpy.array(tmp)
293 data['cspc'] = numpy.array(tmp)
271
294
272 return data, meta
295 return data, meta
273
296
274 def plot(self):
297 def plot(self):
275
298
276 if self.xaxis == "frequency":
299 if self.xaxis == "frequency":
277 x = self.data.xrange[0]
300 x = self.data.xrange[0]
278 self.xlabel = "Frequency (kHz)"
301 self.xlabel = "Frequency (kHz)"
279 elif self.xaxis == "time":
302 elif self.xaxis == "time":
280 x = self.data.xrange[1]
303 x = self.data.xrange[1]
281 self.xlabel = "Time (ms)"
304 self.xlabel = "Time (ms)"
282 else:
305 else:
283 x = self.data.xrange[2]
306 x = self.data.xrange[2]
284 self.xlabel = "Velocity (m/s)"
307 self.xlabel = "Velocity (m/s)"
285
308
286 self.titles = []
309 self.titles = []
287
310
288 y = self.data.yrange
311 y = self.data.yrange
289 self.y = y
312 self.y = y
290
313
291 data = self.data[-1]
314 data = self.data[-1]
292 cspc = data['cspc']
315 cspc = data['cspc']
293
316
294 for n in range(len(self.data.pairs)):
317 for n in range(len(self.data.pairs)):
295 pair = self.data.pairs[n]
318 pair = self.data.pairs[n]
296 coh = cspc[n*2]
319 coh = cspc[n*2]
297 phase = cspc[n*2+1]
320 phase = cspc[n*2+1]
298 ax = self.axes[2 * n]
321 ax = self.axes[2 * n]
299 if ax.firsttime:
322 if ax.firsttime:
300 ax.plt = ax.pcolormesh(x, y, coh.T,
323 ax.plt = ax.pcolormesh(x, y, coh.T,
301 vmin=0,
324 vmin=0,
302 vmax=1,
325 vmax=1,
303 cmap=plt.get_cmap(self.colormap_coh)
326 cmap=plt.get_cmap(self.colormap_coh)
304 )
327 )
305 else:
328 else:
306 ax.plt.set_array(coh.T.ravel())
329 ax.plt.set_array(coh.T.ravel())
307 self.titles.append(
330 self.titles.append(
308 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
331 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
309
332
310 ax = self.axes[2 * n + 1]
333 ax = self.axes[2 * n + 1]
311 if ax.firsttime:
334 if ax.firsttime:
312 ax.plt = ax.pcolormesh(x, y, phase.T,
335 ax.plt = ax.pcolormesh(x, y, phase.T,
313 vmin=-180,
336 vmin=-180,
314 vmax=180,
337 vmax=180,
315 cmap=plt.get_cmap(self.colormap_phase)
338 cmap=plt.get_cmap(self.colormap_phase)
316 )
339 )
317 else:
340 else:
318 ax.plt.set_array(phase.T.ravel())
341 ax.plt.set_array(phase.T.ravel())
319 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
342 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
320
343
321
344
322 class CrossSpectra4Plot(Plot):
345 class CrossSpectra4Plot(Plot):
323
346
324 CODE = 'cspc'
347 CODE = 'cspc'
325 colormap = 'jet'
348 colormap = 'jet'
326 plot_type = 'pcolor'
349 plot_type = 'pcolor'
327 zmin_coh = None
350 zmin_coh = None
328 zmax_coh = None
351 zmax_coh = None
329 zmin_phase = None
352 zmin_phase = None
330 zmax_phase = None
353 zmax_phase = None
331
354
332 def setup(self):
355 def setup(self):
333
356
334 self.ncols = 4
357 self.ncols = 4
335 self.nrows = len(self.data.pairs)
358 self.nrows = len(self.data.pairs)
336 self.nplots = self.nrows * 4
359 self.nplots = self.nrows * 4
337 self.width = 3.1 * self.ncols
360 self.width = 3.1 * self.ncols
338 self.height = 5 * self.nrows
361 self.height = 5 * self.nrows
339 self.ylabel = 'Range [km]'
362 self.ylabel = 'Range [km]'
340 self.showprofile = False
363 self.showprofile = False
341 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
364 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
342
365
343 def plot(self):
366 def plot(self):
344
367
345 if self.xaxis == "frequency":
368 if self.xaxis == "frequency":
346 x = self.data.xrange[0]
369 x = self.data.xrange[0]
347 self.xlabel = "Frequency (kHz)"
370 self.xlabel = "Frequency (kHz)"
348 elif self.xaxis == "time":
371 elif self.xaxis == "time":
349 x = self.data.xrange[1]
372 x = self.data.xrange[1]
350 self.xlabel = "Time (ms)"
373 self.xlabel = "Time (ms)"
351 else:
374 else:
352 x = self.data.xrange[2]
375 x = self.data.xrange[2]
353 self.xlabel = "Velocity (m/s)"
376 self.xlabel = "Velocity (m/s)"
354
377
355 self.titles = []
378 self.titles = []
356
379
357
380
358 y = self.data.heights
381 y = self.data.heights
359 self.y = y
382 self.y = y
360 nspc = self.data['spc']
383 nspc = self.data['spc']
361 #print(numpy.shape(self.data['spc']))
384 #print(numpy.shape(self.data['spc']))
362 spc = self.data['cspc'][0]
385 spc = self.data['cspc'][0]
363 #print(numpy.shape(nspc))
386 #print(numpy.shape(nspc))
364 #exit()
387 #exit()
365 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
388 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
366 #print(numpy.shape(spc))
389 #print(numpy.shape(spc))
367 #exit()
390 #exit()
368 cspc = self.data['cspc'][1]
391 cspc = self.data['cspc'][1]
369
392
370 #xflip=numpy.flip(x)
393 #xflip=numpy.flip(x)
371 #print(numpy.shape(cspc))
394 #print(numpy.shape(cspc))
372 #exit()
395 #exit()
373
396
374 for n in range(self.nrows):
397 for n in range(self.nrows):
375 noise = self.data['noise'][:,-1]
398 noise = self.data['noise'][:,-1]
376 pair = self.data.pairs[n]
399 pair = self.data.pairs[n]
377 #print(pair)
400 #print(pair)
378 #exit()
401 #exit()
379 ax = self.axes[4 * n]
402 ax = self.axes[4 * n]
380 if ax.firsttime:
403 if ax.firsttime:
381 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
404 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
382 self.xmin = self.xmin if self.xmin else -self.xmax
405 self.xmin = self.xmin if self.xmin else -self.xmax
383 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
406 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
384 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
407 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
385 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
408 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
386 vmin=self.zmin,
409 vmin=self.zmin,
387 vmax=self.zmax,
410 vmax=self.zmax,
388 cmap=plt.get_cmap(self.colormap)
411 cmap=plt.get_cmap(self.colormap)
389 )
412 )
390 else:
413 else:
391 #print(numpy.shape(nspc[pair[0]].T))
414 #print(numpy.shape(nspc[pair[0]].T))
392 #exit()
415 #exit()
393 ax.plt.set_array(nspc[pair[0]].T.ravel())
416 ax.plt.set_array(nspc[pair[0]].T.ravel())
394 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
417 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
395
418
396 ax = self.axes[4 * n + 1]
419 ax = self.axes[4 * n + 1]
397
420
398 if ax.firsttime:
421 if ax.firsttime:
399 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
422 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
400 vmin=self.zmin,
423 vmin=self.zmin,
401 vmax=self.zmax,
424 vmax=self.zmax,
402 cmap=plt.get_cmap(self.colormap)
425 cmap=plt.get_cmap(self.colormap)
403 )
426 )
404 else:
427 else:
405
428
406 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
429 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
407 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
430 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
408
431
409 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
432 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
410 coh = numpy.abs(out)
433 coh = numpy.abs(out)
411 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
434 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
412
435
413 ax = self.axes[4 * n + 2]
436 ax = self.axes[4 * n + 2]
414 if ax.firsttime:
437 if ax.firsttime:
415 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
438 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
416 vmin=0,
439 vmin=0,
417 vmax=1,
440 vmax=1,
418 cmap=plt.get_cmap(self.colormap_coh)
441 cmap=plt.get_cmap(self.colormap_coh)
419 )
442 )
420 else:
443 else:
421 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
444 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
422 self.titles.append(
445 self.titles.append(
423 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
446 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
424
447
425 ax = self.axes[4 * n + 3]
448 ax = self.axes[4 * n + 3]
426 if ax.firsttime:
449 if ax.firsttime:
427 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
450 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
428 vmin=-180,
451 vmin=-180,
429 vmax=180,
452 vmax=180,
430 cmap=plt.get_cmap(self.colormap_phase)
453 cmap=plt.get_cmap(self.colormap_phase)
431 )
454 )
432 else:
455 else:
433 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
456 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
434 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
457 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
435
458
436
459
437 class CrossSpectra2Plot(Plot):
460 class CrossSpectra2Plot(Plot):
438
461
439 CODE = 'cspc'
462 CODE = 'cspc'
440 colormap = 'jet'
463 colormap = 'jet'
441 plot_type = 'pcolor'
464 plot_type = 'pcolor'
442 zmin_coh = None
465 zmin_coh = None
443 zmax_coh = None
466 zmax_coh = None
444 zmin_phase = None
467 zmin_phase = None
445 zmax_phase = None
468 zmax_phase = None
446
469
447 def setup(self):
470 def setup(self):
448
471
449 self.ncols = 1
472 self.ncols = 1
450 self.nrows = len(self.data.pairs)
473 self.nrows = len(self.data.pairs)
451 self.nplots = self.nrows * 1
474 self.nplots = self.nrows * 1
452 self.width = 3.1 * self.ncols
475 self.width = 3.1 * self.ncols
453 self.height = 5 * self.nrows
476 self.height = 5 * self.nrows
454 self.ylabel = 'Range [km]'
477 self.ylabel = 'Range [km]'
455 self.showprofile = False
478 self.showprofile = False
456 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
479 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
457
480
458 def plot(self):
481 def plot(self):
459
482
460 if self.xaxis == "frequency":
483 if self.xaxis == "frequency":
461 x = self.data.xrange[0]
484 x = self.data.xrange[0]
462 self.xlabel = "Frequency (kHz)"
485 self.xlabel = "Frequency (kHz)"
463 elif self.xaxis == "time":
486 elif self.xaxis == "time":
464 x = self.data.xrange[1]
487 x = self.data.xrange[1]
465 self.xlabel = "Time (ms)"
488 self.xlabel = "Time (ms)"
466 else:
489 else:
467 x = self.data.xrange[2]
490 x = self.data.xrange[2]
468 self.xlabel = "Velocity (m/s)"
491 self.xlabel = "Velocity (m/s)"
469
492
470 self.titles = []
493 self.titles = []
471
494
472
495
473 y = self.data.heights
496 y = self.data.heights
474 self.y = y
497 self.y = y
475 #nspc = self.data['spc']
498 #nspc = self.data['spc']
476 #print(numpy.shape(self.data['spc']))
499 #print(numpy.shape(self.data['spc']))
477 #spc = self.data['cspc'][0]
500 #spc = self.data['cspc'][0]
478 #print(numpy.shape(spc))
501 #print(numpy.shape(spc))
479 #exit()
502 #exit()
480 cspc = self.data['cspc'][1]
503 cspc = self.data['cspc'][1]
481 #print(numpy.shape(cspc))
504 #print(numpy.shape(cspc))
482 #exit()
505 #exit()
483
506
484 for n in range(self.nrows):
507 for n in range(self.nrows):
485 noise = self.data['noise'][:,-1]
508 noise = self.data['noise'][:,-1]
486 pair = self.data.pairs[n]
509 pair = self.data.pairs[n]
487 #print(pair) #exit()
510 #print(pair) #exit()
488
511
489
512
490
513
491 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
514 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
492
515
493 #print(out[:,53])
516 #print(out[:,53])
494 #exit()
517 #exit()
495 cross = numpy.abs(out)
518 cross = numpy.abs(out)
496 z = cross/self.data.nFactor
519 z = cross/self.data.nFactor
497 #print("here")
520 #print("here")
498 #print(dataOut.data_spc[0,0,0])
521 #print(dataOut.data_spc[0,0,0])
499 #exit()
522 #exit()
500
523
501 cross = 10*numpy.log10(z)
524 cross = 10*numpy.log10(z)
502 #print(numpy.shape(cross))
525 #print(numpy.shape(cross))
503 #print(cross[0,:])
526 #print(cross[0,:])
504 #print(self.data.nFactor)
527 #print(self.data.nFactor)
505 #exit()
528 #exit()
506 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
529 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
507
530
508 ax = self.axes[1 * n]
531 ax = self.axes[1 * n]
509 if ax.firsttime:
532 if ax.firsttime:
510 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
533 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
511 self.xmin = self.xmin if self.xmin else -self.xmax
534 self.xmin = self.xmin if self.xmin else -self.xmax
512 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
535 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
513 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
536 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
514 ax.plt = ax.pcolormesh(x, y, cross.T,
537 ax.plt = ax.pcolormesh(x, y, cross.T,
515 vmin=self.zmin,
538 vmin=self.zmin,
516 vmax=self.zmax,
539 vmax=self.zmax,
517 cmap=plt.get_cmap(self.colormap)
540 cmap=plt.get_cmap(self.colormap)
518 )
541 )
519 else:
542 else:
520 ax.plt.set_array(cross.T.ravel())
543 ax.plt.set_array(cross.T.ravel())
521 self.titles.append(
544 self.titles.append(
522 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
545 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
523
546
524
547
525 class CrossSpectra3Plot(Plot):
548 class CrossSpectra3Plot(Plot):
526
549
527 CODE = 'cspc'
550 CODE = 'cspc'
528 colormap = 'jet'
551 colormap = 'jet'
529 plot_type = 'pcolor'
552 plot_type = 'pcolor'
530 zmin_coh = None
553 zmin_coh = None
531 zmax_coh = None
554 zmax_coh = None
532 zmin_phase = None
555 zmin_phase = None
533 zmax_phase = None
556 zmax_phase = None
534
557
535 def setup(self):
558 def setup(self):
536
559
537 self.ncols = 3
560 self.ncols = 3
538 self.nrows = len(self.data.pairs)
561 self.nrows = len(self.data.pairs)
539 self.nplots = self.nrows * 3
562 self.nplots = self.nrows * 3
540 self.width = 3.1 * self.ncols
563 self.width = 3.1 * self.ncols
541 self.height = 5 * self.nrows
564 self.height = 5 * self.nrows
542 self.ylabel = 'Range [km]'
565 self.ylabel = 'Range [km]'
543 self.showprofile = False
566 self.showprofile = False
544 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
567 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
545
568
546 def plot(self):
569 def plot(self):
547
570
548 if self.xaxis == "frequency":
571 if self.xaxis == "frequency":
549 x = self.data.xrange[0]
572 x = self.data.xrange[0]
550 self.xlabel = "Frequency (kHz)"
573 self.xlabel = "Frequency (kHz)"
551 elif self.xaxis == "time":
574 elif self.xaxis == "time":
552 x = self.data.xrange[1]
575 x = self.data.xrange[1]
553 self.xlabel = "Time (ms)"
576 self.xlabel = "Time (ms)"
554 else:
577 else:
555 x = self.data.xrange[2]
578 x = self.data.xrange[2]
556 self.xlabel = "Velocity (m/s)"
579 self.xlabel = "Velocity (m/s)"
557
580
558 self.titles = []
581 self.titles = []
559
582
560
583
561 y = self.data.heights
584 y = self.data.heights
562 self.y = y
585 self.y = y
563 #nspc = self.data['spc']
586 #nspc = self.data['spc']
564 #print(numpy.shape(self.data['spc']))
587 #print(numpy.shape(self.data['spc']))
565 #spc = self.data['cspc'][0]
588 #spc = self.data['cspc'][0]
566 #print(numpy.shape(spc))
589 #print(numpy.shape(spc))
567 #exit()
590 #exit()
568 cspc = self.data['cspc'][1]
591 cspc = self.data['cspc'][1]
569 #print(numpy.shape(cspc))
592 #print(numpy.shape(cspc))
570 #exit()
593 #exit()
571
594
572 for n in range(self.nrows):
595 for n in range(self.nrows):
573 noise = self.data['noise'][:,-1]
596 noise = self.data['noise'][:,-1]
574 pair = self.data.pairs[n]
597 pair = self.data.pairs[n]
575 #print(pair) #exit()
598 #print(pair) #exit()
576
599
577
600
578
601
579 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
602 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
580
603
581 #print(out[:,53])
604 #print(out[:,53])
582 #exit()
605 #exit()
583 cross = numpy.abs(out)
606 cross = numpy.abs(out)
584 z = cross/self.data.nFactor
607 z = cross/self.data.nFactor
585 cross = 10*numpy.log10(z)
608 cross = 10*numpy.log10(z)
586
609
587 out_r= out.real/self.data.nFactor
610 out_r= out.real/self.data.nFactor
588 #out_r = 10*numpy.log10(out_r)
611 #out_r = 10*numpy.log10(out_r)
589
612
590 out_i= out.imag/self.data.nFactor
613 out_i= out.imag/self.data.nFactor
591 #out_i = 10*numpy.log10(out_i)
614 #out_i = 10*numpy.log10(out_i)
592 #print(numpy.shape(cross))
615 #print(numpy.shape(cross))
593 #print(cross[0,:])
616 #print(cross[0,:])
594 #print(self.data.nFactor)
617 #print(self.data.nFactor)
595 #exit()
618 #exit()
596 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
619 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
597
620
598 ax = self.axes[3 * n]
621 ax = self.axes[3 * n]
599 if ax.firsttime:
622 if ax.firsttime:
600 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
623 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
601 self.xmin = self.xmin if self.xmin else -self.xmax
624 self.xmin = self.xmin if self.xmin else -self.xmax
602 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
625 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
603 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
626 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
604 ax.plt = ax.pcolormesh(x, y, cross.T,
627 ax.plt = ax.pcolormesh(x, y, cross.T,
605 vmin=self.zmin,
628 vmin=self.zmin,
606 vmax=self.zmax,
629 vmax=self.zmax,
607 cmap=plt.get_cmap(self.colormap)
630 cmap=plt.get_cmap(self.colormap)
608 )
631 )
609 else:
632 else:
610 ax.plt.set_array(cross.T.ravel())
633 ax.plt.set_array(cross.T.ravel())
611 self.titles.append(
634 self.titles.append(
612 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
635 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
613
636
614 ax = self.axes[3 * n + 1]
637 ax = self.axes[3 * n + 1]
615 if ax.firsttime:
638 if ax.firsttime:
616 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
639 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
617 self.xmin = self.xmin if self.xmin else -self.xmax
640 self.xmin = self.xmin if self.xmin else -self.xmax
618 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
641 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
619 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
642 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
620 ax.plt = ax.pcolormesh(x, y, out_r.T,
643 ax.plt = ax.pcolormesh(x, y, out_r.T,
621 vmin=-1.e6,
644 vmin=-1.e6,
622 vmax=0,
645 vmax=0,
623 cmap=plt.get_cmap(self.colormap)
646 cmap=plt.get_cmap(self.colormap)
624 )
647 )
625 else:
648 else:
626 ax.plt.set_array(out_r.T.ravel())
649 ax.plt.set_array(out_r.T.ravel())
627 self.titles.append(
650 self.titles.append(
628 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
651 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
629
652
630 ax = self.axes[3 * n + 2]
653 ax = self.axes[3 * n + 2]
631
654
632
655
633 if ax.firsttime:
656 if ax.firsttime:
634 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
657 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
635 self.xmin = self.xmin if self.xmin else -self.xmax
658 self.xmin = self.xmin if self.xmin else -self.xmax
636 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
659 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
637 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
660 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
638 ax.plt = ax.pcolormesh(x, y, out_i.T,
661 ax.plt = ax.pcolormesh(x, y, out_i.T,
639 vmin=-1.e6,
662 vmin=-1.e6,
640 vmax=1.e6,
663 vmax=1.e6,
641 cmap=plt.get_cmap(self.colormap)
664 cmap=plt.get_cmap(self.colormap)
642 )
665 )
643 else:
666 else:
644 ax.plt.set_array(out_i.T.ravel())
667 ax.plt.set_array(out_i.T.ravel())
645 self.titles.append(
668 self.titles.append(
646 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
669 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
647
670
648 class RTIPlot(Plot):
671 class RTIPlot(Plot):
649 '''
672 '''
650 Plot for RTI data
673 Plot for RTI data
651 '''
674 '''
652
675
653 CODE = 'rti'
676 CODE = 'rti'
654 colormap = 'jet'
677 colormap = 'jet'
655 plot_type = 'pcolorbuffer'
678 plot_type = 'pcolorbuffer'
656
679
657 def setup(self):
680 def setup(self):
658 self.xaxis = 'time'
681 self.xaxis = 'time'
659 self.ncols = 1
682 self.ncols = 1
660 self.nrows = len(self.data.channels)
683 self.nrows = len(self.data.channels)
661 self.nplots = len(self.data.channels)
684 self.nplots = len(self.data.channels)
662 self.ylabel = 'Range [km]'
685 self.ylabel = 'Range [km]'
663 self.xlabel = 'Time'
686 self.xlabel = 'Time'
664 self.cb_label = 'dB'
687 self.cb_label = 'dB'
665 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
688 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
666 self.titles = ['{} Channel {}'.format(
689 self.titles = ['{} Channel {}'.format(
667 self.CODE.upper(), x) for x in range(self.nrows)]
690 self.CODE.upper(), x) for x in range(self.nrows)]
668
691
669 def update(self, dataOut):
692 def update(self, dataOut):
670
693
671 data = {}
694 data = {}
672 meta = {}
695 meta = {}
673 data['rti'] = dataOut.getPower()
696 data['rti'] = dataOut.getPower()
697 #print(numpy.shape(data['rti']))
674
698
675 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
699 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
676
700
677 return data, meta
701 return data, meta
678
702
679 def plot(self):
703 def plot(self):
680
704
681 self.x = self.data.times
705 self.x = self.data.times
682 self.y = self.data.yrange
706 self.y = self.data.yrange
683 self.z = self.data[self.CODE]
707 self.z = self.data[self.CODE]
684
708
685 self.z = numpy.ma.masked_invalid(self.z)
709 self.z = numpy.ma.masked_invalid(self.z)
686
710
687 if self.decimation is None:
711 if self.decimation is None:
688 x, y, z = self.fill_gaps(self.x, self.y, self.z)
712 x, y, z = self.fill_gaps(self.x, self.y, self.z)
689 else:
713 else:
690 x, y, z = self.fill_gaps(*self.decimate())
714 x, y, z = self.fill_gaps(*self.decimate())
691
715
692 for n, ax in enumerate(self.axes):
716 for n, ax in enumerate(self.axes):
693 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
717 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
694 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
718 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
719
695 if ax.firsttime:
720 if ax.firsttime:
696 ax.plt = ax.pcolormesh(x, y, z[n].T,
721 ax.plt = ax.pcolormesh(x, y, z[n].T,
697 vmin=self.zmin,
722 vmin=self.zmin,
698 vmax=self.zmax,
723 vmax=self.zmax,
699 cmap=plt.get_cmap(self.colormap)
724 cmap=plt.get_cmap(self.colormap)
700 )
725 )
701 if self.showprofile:
726 if self.showprofile:
702 ax.plot_profile = self.pf_axes[n].plot(
727 ax.plot_profile = self.pf_axes[n].plot(
703 self.data['rti'][n][-1], self.y)[0]
728 self.data['rti'][n][-1], self.y)[0]
704 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
729 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
705 color="k", linestyle="dashed", lw=1)[0]
730 color="k", linestyle="dashed", lw=1)[0]
706 else:
731 else:
707 ax.collections.remove(ax.collections[0])
732 ax.collections.remove(ax.collections[0])
708 ax.plt = ax.pcolormesh(x, y, z[n].T,
733 ax.plt = ax.pcolormesh(x, y, z[n].T,
709 vmin=self.zmin,
734 vmin=self.zmin,
710 vmax=self.zmax,
735 vmax=self.zmax,
711 cmap=plt.get_cmap(self.colormap)
736 cmap=plt.get_cmap(self.colormap)
712 )
737 )
713 if self.showprofile:
738 if self.showprofile:
714 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
739 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
715 ax.plot_noise.set_data(numpy.repeat(
740 ax.plot_noise.set_data(numpy.repeat(
716 self.data['noise'][n][-1], len(self.y)), self.y)
741 self.data['noise'][n][-1], len(self.y)), self.y)
717
742
718
743
719 class SpectrogramPlot(Plot):
744 class SpectrogramPlot(Plot):
720 '''
745 '''
721 Plot for Spectrogram data
746 Plot for Spectrogram data
722 '''
747 '''
723
748
724 CODE = 'Spectrogram_Profile'
749 CODE = 'Spectrogram_Profile'
725 colormap = 'binary'
750 colormap = 'binary'
726 plot_type = 'pcolorbuffer'
751 plot_type = 'pcolorbuffer'
727
752
728 def setup(self):
753 def setup(self):
729 self.xaxis = 'time'
754 self.xaxis = 'time'
730 self.ncols = 1
755 self.ncols = 1
731 self.nrows = len(self.data.channels)
756 self.nrows = len(self.data.channels)
732 self.nplots = len(self.data.channels)
757 self.nplots = len(self.data.channels)
733 self.xlabel = 'Time'
758 self.xlabel = 'Time'
734 #self.cb_label = 'dB'
759 #self.cb_label = 'dB'
735 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
760 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
736 self.titles = []
761 self.titles = []
737
762
738 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
763 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
739 #self.CODE.upper(), x, self.data.heightList[self.data.hei], self.data.heightList[self.data.hei],self.data.heightList[self.data.hei]+(self.data.DH*self.data.nProfiles)) for x in range(self.nrows)]
764 #self.CODE.upper(), x, self.data.heightList[self.data.hei], self.data.heightList[self.data.hei],self.data.heightList[self.data.hei]+(self.data.DH*self.data.nProfiles)) for x in range(self.nrows)]
740
765
741 self.titles = ['{} Channel {}'.format(
766 self.titles = ['{} Channel {}'.format(
742 self.CODE.upper(), x) for x in range(self.nrows)]
767 self.CODE.upper(), x) for x in range(self.nrows)]
743
768
744
769
745 def update(self, dataOut):
770 def update(self, dataOut):
746 data = {}
771 data = {}
747 meta = {}
772 meta = {}
748
773
749 maxHei = 1620#+12000
774 maxHei = 1620#+12000
750 indb = numpy.where(dataOut.heightList <= maxHei)
775 indb = numpy.where(dataOut.heightList <= maxHei)
751 hei = indb[0][-1]
776 hei = indb[0][-1]
752 #print(dataOut.heightList)
777 #print(dataOut.heightList)
753
778
754 factor = dataOut.nIncohInt
779 factor = dataOut.nIncohInt
755 z = dataOut.data_spc[:,:,hei] / factor
780 z = dataOut.data_spc[:,:,hei] / factor
756 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
781 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
757 #buffer = 10 * numpy.log10(z)
782 #buffer = 10 * numpy.log10(z)
758
783
759 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
784 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
760
785
761
786
762 #self.hei = hei
787 #self.hei = hei
763 #self.heightList = dataOut.heightList
788 #self.heightList = dataOut.heightList
764 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
789 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
765 #self.nProfiles = dataOut.nProfiles
790 #self.nProfiles = dataOut.nProfiles
766
791
767 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
792 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
768
793
769 data['hei'] = hei
794 data['hei'] = hei
770 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
795 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
771 data['nProfiles'] = dataOut.nProfiles
796 data['nProfiles'] = dataOut.nProfiles
772 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
797 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
773 '''
798 '''
774 import matplotlib.pyplot as plt
799 import matplotlib.pyplot as plt
775 plt.plot(10 * numpy.log10(z[0,:]))
800 plt.plot(10 * numpy.log10(z[0,:]))
776 plt.show()
801 plt.show()
777
802
778 from time import sleep
803 from time import sleep
779 sleep(10)
804 sleep(10)
780 '''
805 '''
781 return data, meta
806 return data, meta
782
807
783 def plot(self):
808 def plot(self):
784
809
785 self.x = self.data.times
810 self.x = self.data.times
786 self.z = self.data[self.CODE]
811 self.z = self.data[self.CODE]
787 self.y = self.data.xrange[0]
812 self.y = self.data.xrange[0]
788
813
789 hei = self.data['hei'][-1]
814 hei = self.data['hei'][-1]
790 DH = self.data['DH'][-1]
815 DH = self.data['DH'][-1]
791 nProfiles = self.data['nProfiles'][-1]
816 nProfiles = self.data['nProfiles'][-1]
792
817
793 self.ylabel = "Frequency (kHz)"
818 self.ylabel = "Frequency (kHz)"
794
819
795 self.z = numpy.ma.masked_invalid(self.z)
820 self.z = numpy.ma.masked_invalid(self.z)
796
821
797 if self.decimation is None:
822 if self.decimation is None:
798 x, y, z = self.fill_gaps(self.x, self.y, self.z)
823 x, y, z = self.fill_gaps(self.x, self.y, self.z)
799 else:
824 else:
800 x, y, z = self.fill_gaps(*self.decimate())
825 x, y, z = self.fill_gaps(*self.decimate())
801
826
802 for n, ax in enumerate(self.axes):
827 for n, ax in enumerate(self.axes):
803 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
828 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
804 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
829 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
805 data = self.data[-1]
830 data = self.data[-1]
806 if ax.firsttime:
831 if ax.firsttime:
807 ax.plt = ax.pcolormesh(x, y, z[n].T,
832 ax.plt = ax.pcolormesh(x, y, z[n].T,
808 vmin=self.zmin,
833 vmin=self.zmin,
809 vmax=self.zmax,
834 vmax=self.zmax,
810 cmap=plt.get_cmap(self.colormap)
835 cmap=plt.get_cmap(self.colormap)
811 )
836 )
812 else:
837 else:
813 ax.collections.remove(ax.collections[0])
838 ax.collections.remove(ax.collections[0])
814 ax.plt = ax.pcolormesh(x, y, z[n].T,
839 ax.plt = ax.pcolormesh(x, y, z[n].T,
815 vmin=self.zmin,
840 vmin=self.zmin,
816 vmax=self.zmax,
841 vmax=self.zmax,
817 cmap=plt.get_cmap(self.colormap)
842 cmap=plt.get_cmap(self.colormap)
818 )
843 )
819
844
820 #self.titles.append('Spectrogram')
845 #self.titles.append('Spectrogram')
821
846
822 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
847 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
823 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
848 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
824
849
825
850
826
851
827
852
828 class CoherencePlot(RTIPlot):
853 class CoherencePlot(RTIPlot):
829 '''
854 '''
830 Plot for Coherence data
855 Plot for Coherence data
831 '''
856 '''
832
857
833 CODE = 'coh'
858 CODE = 'coh'
834
859
835 def setup(self):
860 def setup(self):
836 self.xaxis = 'time'
861 self.xaxis = 'time'
837 self.ncols = 1
862 self.ncols = 1
838 self.nrows = len(self.data.pairs)
863 self.nrows = len(self.data.pairs)
839 self.nplots = len(self.data.pairs)
864 self.nplots = len(self.data.pairs)
840 self.ylabel = 'Range [km]'
865 self.ylabel = 'Range [km]'
841 self.xlabel = 'Time'
866 self.xlabel = 'Time'
842 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
867 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
843 if self.CODE == 'coh':
868 if self.CODE == 'coh':
844 self.cb_label = ''
869 self.cb_label = ''
845 self.titles = [
870 self.titles = [
846 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
871 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
847 else:
872 else:
848 self.cb_label = 'Degrees'
873 self.cb_label = 'Degrees'
849 self.titles = [
874 self.titles = [
850 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
875 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
851
876
852 def update(self, dataOut):
877 def update(self, dataOut):
853
878
854 data = {}
879 data = {}
855 meta = {}
880 meta = {}
856 data['coh'] = dataOut.getCoherence()
881 data['coh'] = dataOut.getCoherence()
857 meta['pairs'] = dataOut.pairsList
882 meta['pairs'] = dataOut.pairsList
858
883
859 return data, meta
884 return data, meta
860
885
861 class PhasePlot(CoherencePlot):
886 class PhasePlot(CoherencePlot):
862 '''
887 '''
863 Plot for Phase map data
888 Plot for Phase map data
864 '''
889 '''
865
890
866 CODE = 'phase'
891 CODE = 'phase'
867 colormap = 'seismic'
892 colormap = 'seismic'
868
893
869 def update(self, dataOut):
894 def update(self, dataOut):
870
895
871 data = {}
896 data = {}
872 meta = {}
897 meta = {}
873 data['phase'] = dataOut.getCoherence(phase=True)
898 data['phase'] = dataOut.getCoherence(phase=True)
874 meta['pairs'] = dataOut.pairsList
899 meta['pairs'] = dataOut.pairsList
875
900
876 return data, meta
901 return data, meta
877
902
878 class NoisePlot(Plot):
903 class NoisePlot(Plot):
879 '''
904 '''
880 Plot for noise
905 Plot for noise
881 '''
906 '''
882
907
883 CODE = 'noise'
908 CODE = 'noise'
884 plot_type = 'scatterbuffer'
909 plot_type = 'scatterbuffer'
885
910
886 def setup(self):
911 def setup(self):
887 self.xaxis = 'time'
912 self.xaxis = 'time'
888 self.ncols = 1
913 self.ncols = 1
889 self.nrows = 1
914 self.nrows = 1
890 self.nplots = 1
915 self.nplots = 1
891 self.ylabel = 'Intensity [dB]'
916 self.ylabel = 'Intensity [dB]'
892 self.xlabel = 'Time'
917 self.xlabel = 'Time'
893 self.titles = ['Noise']
918 self.titles = ['Noise']
894 self.colorbar = False
919 self.colorbar = False
895 self.plots_adjust.update({'right': 0.85 })
920 self.plots_adjust.update({'right': 0.85 })
896
921
897 def update(self, dataOut):
922 def update(self, dataOut):
898
923
899 data = {}
924 data = {}
900 meta = {}
925 meta = {}
901 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
926 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
902 meta['yrange'] = numpy.array([])
927 meta['yrange'] = numpy.array([])
903
928
904 return data, meta
929 return data, meta
905
930
906 def plot(self):
931 def plot(self):
907
932
908 x = self.data.times
933 x = self.data.times
909 xmin = self.data.min_time
934 xmin = self.data.min_time
910 xmax = xmin + self.xrange * 60 * 60
935 xmax = xmin + self.xrange * 60 * 60
911 Y = self.data['noise']
936 Y = self.data['noise']
912
937
913 if self.axes[0].firsttime:
938 if self.axes[0].firsttime:
914 self.ymin = numpy.nanmin(Y) - 5
939 self.ymin = numpy.nanmin(Y) - 5
915 self.ymax = numpy.nanmax(Y) + 5
940 self.ymax = numpy.nanmax(Y) + 5
916 for ch in self.data.channels:
941 for ch in self.data.channels:
917 y = Y[ch]
942 y = Y[ch]
918 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
943 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
919 plt.legend(bbox_to_anchor=(1.18, 1.0))
944 plt.legend(bbox_to_anchor=(1.18, 1.0))
920 else:
945 else:
921 for ch in self.data.channels:
946 for ch in self.data.channels:
922 y = Y[ch]
947 y = Y[ch]
923 self.axes[0].lines[ch].set_data(x, y)
948 self.axes[0].lines[ch].set_data(x, y)
924
949
925 self.ymin = numpy.nanmin(Y) - 5
950 self.ymin = numpy.nanmin(Y) - 5
926 self.ymax = numpy.nanmax(Y) + 10
951 self.ymax = numpy.nanmax(Y) + 10
927
952
928
953
929 class PowerProfilePlot(Plot):
954 class PowerProfilePlot(Plot):
930
955
931 CODE = 'pow_profile'
956 CODE = 'pow_profile'
932 plot_type = 'scatter'
957 plot_type = 'scatter'
933
958
934 def setup(self):
959 def setup(self):
935
960
936 self.ncols = 1
961 self.ncols = 1
937 self.nrows = 1
962 self.nrows = 1
938 self.nplots = 1
963 self.nplots = 1
939 self.height = 4
964 self.height = 4
940 self.width = 3
965 self.width = 3
941 self.ylabel = 'Range [km]'
966 self.ylabel = 'Range [km]'
942 self.xlabel = 'Intensity [dB]'
967 self.xlabel = 'Intensity [dB]'
943 self.titles = ['Power Profile']
968 self.titles = ['Power Profile']
944 self.colorbar = False
969 self.colorbar = False
945
970
946 def update(self, dataOut):
971 def update(self, dataOut):
947
972
948 data = {}
973 data = {}
949 meta = {}
974 meta = {}
950 data[self.CODE] = dataOut.getPower()
975 data[self.CODE] = dataOut.getPower()
951
976
952 return data, meta
977 return data, meta
953
978
954 def plot(self):
979 def plot(self):
955
980
956 y = self.data.yrange
981 y = self.data.yrange
957 self.y = y
982 self.y = y
958
983
959 x = self.data[-1][self.CODE]
984 x = self.data[-1][self.CODE]
960
985
961 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
986 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
962 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
987 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
963
988
964 if self.axes[0].firsttime:
989 if self.axes[0].firsttime:
965 for ch in self.data.channels:
990 for ch in self.data.channels:
966 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
991 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
967 plt.legend()
992 plt.legend()
968 else:
993 else:
969 for ch in self.data.channels:
994 for ch in self.data.channels:
970 self.axes[0].lines[ch].set_data(x[ch], y)
995 self.axes[0].lines[ch].set_data(x[ch], y)
971
996
972
997
973 class SpectraCutPlot(Plot):
998 class SpectraCutPlot(Plot):
974
999
975 CODE = 'spc_cut'
1000 CODE = 'spc_cut'
976 plot_type = 'scatter'
1001 plot_type = 'scatter'
977 buffering = False
1002 buffering = False
978
1003
979 def setup(self):
1004 def setup(self):
980
1005
981 self.nplots = len(self.data.channels)
1006 self.nplots = len(self.data.channels)
982 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1007 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
983 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1008 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
984 self.width = 3.4 * self.ncols + 1.5
1009 self.width = 3.4 * self.ncols + 1.5
985 self.height = 3 * self.nrows
1010 self.height = 3 * self.nrows
986 self.ylabel = 'Power [dB]'
1011 self.ylabel = 'Power [dB]'
987 self.colorbar = False
1012 self.colorbar = False
988 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
1013 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
989
1014
990 def update(self, dataOut):
1015 def update(self, dataOut):
991
1016
992 data = {}
1017 data = {}
993 meta = {}
1018 meta = {}
994 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
1019 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
995 data['spc'] = spc
1020 data['spc'] = spc
996 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
1021 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
997 if self.CODE == 'cut_gaussian_fit':
1022 if self.CODE == 'cut_gaussian_fit':
998 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
1023 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
999 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1024 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1000 return data, meta
1025 return data, meta
1001
1026
1002 def plot(self):
1027 def plot(self):
1003 if self.xaxis == "frequency":
1028 if self.xaxis == "frequency":
1004 x = self.data.xrange[0][1:]
1029 x = self.data.xrange[0][1:]
1005 self.xlabel = "Frequency (kHz)"
1030 self.xlabel = "Frequency (kHz)"
1006 elif self.xaxis == "time":
1031 elif self.xaxis == "time":
1007 x = self.data.xrange[1]
1032 x = self.data.xrange[1]
1008 self.xlabel = "Time (ms)"
1033 self.xlabel = "Time (ms)"
1009 else:
1034 else:
1010 x = self.data.xrange[2][:-1]
1035 x = self.data.xrange[2][:-1]
1011 self.xlabel = "Velocity (m/s)"
1036 self.xlabel = "Velocity (m/s)"
1012
1037
1013 if self.CODE == 'cut_gaussian_fit':
1038 if self.CODE == 'cut_gaussian_fit':
1014 x = self.data.xrange[2][:-1]
1039 x = self.data.xrange[2][:-1]
1015 self.xlabel = "Velocity (m/s)"
1040 self.xlabel = "Velocity (m/s)"
1016
1041
1017 self.titles = []
1042 self.titles = []
1018
1043
1019 y = self.data.yrange
1044 y = self.data.yrange
1020 data = self.data[-1]
1045 data = self.data[-1]
1021 z = data['spc']
1046 z = data['spc']
1022
1047
1023 if self.height_index:
1048 if self.height_index:
1024 index = numpy.array(self.height_index)
1049 index = numpy.array(self.height_index)
1025 else:
1050 else:
1026 index = numpy.arange(0, len(y), int((len(y))/9))
1051 index = numpy.arange(0, len(y), int((len(y))/9))
1027
1052
1028 for n, ax in enumerate(self.axes):
1053 for n, ax in enumerate(self.axes):
1029 if self.CODE == 'cut_gaussian_fit':
1054 if self.CODE == 'cut_gaussian_fit':
1030 gau0 = data['gauss_fit0']
1055 gau0 = data['gauss_fit0']
1031 gau1 = data['gauss_fit1']
1056 gau1 = data['gauss_fit1']
1032 if ax.firsttime:
1057 if ax.firsttime:
1033 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1058 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1034 self.xmin = self.xmin if self.xmin else -self.xmax
1059 self.xmin = self.xmin if self.xmin else -self.xmax
1035 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1060 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1036 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1061 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1037 #print(self.ymax)
1062 #print(self.ymax)
1038 #print(z[n, :, index])
1063 #print(z[n, :, index])
1039 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1064 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1040 if self.CODE == 'cut_gaussian_fit':
1065 if self.CODE == 'cut_gaussian_fit':
1041 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1066 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1042 for i, line in enumerate(ax.plt_gau0):
1067 for i, line in enumerate(ax.plt_gau0):
1043 line.set_color(ax.plt[i].get_color())
1068 line.set_color(ax.plt[i].get_color())
1044 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1069 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1045 for i, line in enumerate(ax.plt_gau1):
1070 for i, line in enumerate(ax.plt_gau1):
1046 line.set_color(ax.plt[i].get_color())
1071 line.set_color(ax.plt[i].get_color())
1047 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1072 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1048 self.figures[0].legend(ax.plt, labels, loc='center right')
1073 self.figures[0].legend(ax.plt, labels, loc='center right')
1049 else:
1074 else:
1050 for i, line in enumerate(ax.plt):
1075 for i, line in enumerate(ax.plt):
1051 line.set_data(x, z[n, :, index[i]].T)
1076 line.set_data(x, z[n, :, index[i]].T)
1052 for i, line in enumerate(ax.plt_gau0):
1077 for i, line in enumerate(ax.plt_gau0):
1053 line.set_data(x, gau0[n, :, index[i]].T)
1078 line.set_data(x, gau0[n, :, index[i]].T)
1054 line.set_color(ax.plt[i].get_color())
1079 line.set_color(ax.plt[i].get_color())
1055 for i, line in enumerate(ax.plt_gau1):
1080 for i, line in enumerate(ax.plt_gau1):
1056 line.set_data(x, gau1[n, :, index[i]].T)
1081 line.set_data(x, gau1[n, :, index[i]].T)
1057 line.set_color(ax.plt[i].get_color())
1082 line.set_color(ax.plt[i].get_color())
1058 self.titles.append('CH {}'.format(n))
1083 self.titles.append('CH {}'.format(n))
1059
1084
1060
1085
1061 class BeaconPhase(Plot):
1086 class BeaconPhase(Plot):
1062
1087
1063 __isConfig = None
1088 __isConfig = None
1064 __nsubplots = None
1089 __nsubplots = None
1065
1090
1066 PREFIX = 'beacon_phase'
1091 PREFIX = 'beacon_phase'
1067
1092
1068 def __init__(self):
1093 def __init__(self):
1069 Plot.__init__(self)
1094 Plot.__init__(self)
1070 self.timerange = 24*60*60
1095 self.timerange = 24*60*60
1071 self.isConfig = False
1096 self.isConfig = False
1072 self.__nsubplots = 1
1097 self.__nsubplots = 1
1073 self.counter_imagwr = 0
1098 self.counter_imagwr = 0
1074 self.WIDTH = 800
1099 self.WIDTH = 800
1075 self.HEIGHT = 400
1100 self.HEIGHT = 400
1076 self.WIDTHPROF = 120
1101 self.WIDTHPROF = 120
1077 self.HEIGHTPROF = 0
1102 self.HEIGHTPROF = 0
1078 self.xdata = None
1103 self.xdata = None
1079 self.ydata = None
1104 self.ydata = None
1080
1105
1081 self.PLOT_CODE = BEACON_CODE
1106 self.PLOT_CODE = BEACON_CODE
1082
1107
1083 self.FTP_WEI = None
1108 self.FTP_WEI = None
1084 self.EXP_CODE = None
1109 self.EXP_CODE = None
1085 self.SUB_EXP_CODE = None
1110 self.SUB_EXP_CODE = None
1086 self.PLOT_POS = None
1111 self.PLOT_POS = None
1087
1112
1088 self.filename_phase = None
1113 self.filename_phase = None
1089
1114
1090 self.figfile = None
1115 self.figfile = None
1091
1116
1092 self.xmin = None
1117 self.xmin = None
1093 self.xmax = None
1118 self.xmax = None
1094
1119
1095 def getSubplots(self):
1120 def getSubplots(self):
1096
1121
1097 ncol = 1
1122 ncol = 1
1098 nrow = 1
1123 nrow = 1
1099
1124
1100 return nrow, ncol
1125 return nrow, ncol
1101
1126
1102 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1127 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1103
1128
1104 self.__showprofile = showprofile
1129 self.__showprofile = showprofile
1105 self.nplots = nplots
1130 self.nplots = nplots
1106
1131
1107 ncolspan = 7
1132 ncolspan = 7
1108 colspan = 6
1133 colspan = 6
1109 self.__nsubplots = 2
1134 self.__nsubplots = 2
1110
1135
1111 self.createFigure(id = id,
1136 self.createFigure(id = id,
1112 wintitle = wintitle,
1137 wintitle = wintitle,
1113 widthplot = self.WIDTH+self.WIDTHPROF,
1138 widthplot = self.WIDTH+self.WIDTHPROF,
1114 heightplot = self.HEIGHT+self.HEIGHTPROF,
1139 heightplot = self.HEIGHT+self.HEIGHTPROF,
1115 show=show)
1140 show=show)
1116
1141
1117 nrow, ncol = self.getSubplots()
1142 nrow, ncol = self.getSubplots()
1118
1143
1119 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1144 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1120
1145
1121 def save_phase(self, filename_phase):
1146 def save_phase(self, filename_phase):
1122 f = open(filename_phase,'w+')
1147 f = open(filename_phase,'w+')
1123 f.write('\n\n')
1148 f.write('\n\n')
1124 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1149 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1125 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1150 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1126 f.close()
1151 f.close()
1127
1152
1128 def save_data(self, filename_phase, data, data_datetime):
1153 def save_data(self, filename_phase, data, data_datetime):
1129 f=open(filename_phase,'a')
1154 f=open(filename_phase,'a')
1130 timetuple_data = data_datetime.timetuple()
1155 timetuple_data = data_datetime.timetuple()
1131 day = str(timetuple_data.tm_mday)
1156 day = str(timetuple_data.tm_mday)
1132 month = str(timetuple_data.tm_mon)
1157 month = str(timetuple_data.tm_mon)
1133 year = str(timetuple_data.tm_year)
1158 year = str(timetuple_data.tm_year)
1134 hour = str(timetuple_data.tm_hour)
1159 hour = str(timetuple_data.tm_hour)
1135 minute = str(timetuple_data.tm_min)
1160 minute = str(timetuple_data.tm_min)
1136 second = str(timetuple_data.tm_sec)
1161 second = str(timetuple_data.tm_sec)
1137 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1162 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1138 f.close()
1163 f.close()
1139
1164
1140 def plot(self):
1165 def plot(self):
1141 log.warning('TODO: Not yet implemented...')
1166 log.warning('TODO: Not yet implemented...')
1142
1167
1143 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1168 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1144 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1169 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1145 timerange=None,
1170 timerange=None,
1146 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1171 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1147 server=None, folder=None, username=None, password=None,
1172 server=None, folder=None, username=None, password=None,
1148 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1173 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1149
1174
1150 if dataOut.flagNoData:
1175 if dataOut.flagNoData:
1151 return dataOut
1176 return dataOut
1152
1177
1153 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1178 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1154 return
1179 return
1155
1180
1156 if pairsList == None:
1181 if pairsList == None:
1157 pairsIndexList = dataOut.pairsIndexList[:10]
1182 pairsIndexList = dataOut.pairsIndexList[:10]
1158 else:
1183 else:
1159 pairsIndexList = []
1184 pairsIndexList = []
1160 for pair in pairsList:
1185 for pair in pairsList:
1161 if pair not in dataOut.pairsList:
1186 if pair not in dataOut.pairsList:
1162 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1187 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1163 pairsIndexList.append(dataOut.pairsList.index(pair))
1188 pairsIndexList.append(dataOut.pairsList.index(pair))
1164
1189
1165 if pairsIndexList == []:
1190 if pairsIndexList == []:
1166 return
1191 return
1167
1192
1168 # if len(pairsIndexList) > 4:
1193 # if len(pairsIndexList) > 4:
1169 # pairsIndexList = pairsIndexList[0:4]
1194 # pairsIndexList = pairsIndexList[0:4]
1170
1195
1171 hmin_index = None
1196 hmin_index = None
1172 hmax_index = None
1197 hmax_index = None
1173
1198
1174 if hmin != None and hmax != None:
1199 if hmin != None and hmax != None:
1175 indexes = numpy.arange(dataOut.nHeights)
1200 indexes = numpy.arange(dataOut.nHeights)
1176 hmin_list = indexes[dataOut.heightList >= hmin]
1201 hmin_list = indexes[dataOut.heightList >= hmin]
1177 hmax_list = indexes[dataOut.heightList <= hmax]
1202 hmax_list = indexes[dataOut.heightList <= hmax]
1178
1203
1179 if hmin_list.any():
1204 if hmin_list.any():
1180 hmin_index = hmin_list[0]
1205 hmin_index = hmin_list[0]
1181
1206
1182 if hmax_list.any():
1207 if hmax_list.any():
1183 hmax_index = hmax_list[-1]+1
1208 hmax_index = hmax_list[-1]+1
1184
1209
1185 x = dataOut.getTimeRange()
1210 x = dataOut.getTimeRange()
1186
1211
1187 thisDatetime = dataOut.datatime
1212 thisDatetime = dataOut.datatime
1188
1213
1189 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1214 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1190 xlabel = "Local Time"
1215 xlabel = "Local Time"
1191 ylabel = "Phase (degrees)"
1216 ylabel = "Phase (degrees)"
1192
1217
1193 update_figfile = False
1218 update_figfile = False
1194
1219
1195 nplots = len(pairsIndexList)
1220 nplots = len(pairsIndexList)
1196 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1221 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1197 phase_beacon = numpy.zeros(len(pairsIndexList))
1222 phase_beacon = numpy.zeros(len(pairsIndexList))
1198 for i in range(nplots):
1223 for i in range(nplots):
1199 pair = dataOut.pairsList[pairsIndexList[i]]
1224 pair = dataOut.pairsList[pairsIndexList[i]]
1200 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1225 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1201 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1226 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1202 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1227 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1203 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1228 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1204 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1229 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1205
1230
1206 if dataOut.beacon_heiIndexList:
1231 if dataOut.beacon_heiIndexList:
1207 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1232 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1208 else:
1233 else:
1209 phase_beacon[i] = numpy.average(phase)
1234 phase_beacon[i] = numpy.average(phase)
1210
1235
1211 if not self.isConfig:
1236 if not self.isConfig:
1212
1237
1213 nplots = len(pairsIndexList)
1238 nplots = len(pairsIndexList)
1214
1239
1215 self.setup(id=id,
1240 self.setup(id=id,
1216 nplots=nplots,
1241 nplots=nplots,
1217 wintitle=wintitle,
1242 wintitle=wintitle,
1218 showprofile=showprofile,
1243 showprofile=showprofile,
1219 show=show)
1244 show=show)
1220
1245
1221 if timerange != None:
1246 if timerange != None:
1222 self.timerange = timerange
1247 self.timerange = timerange
1223
1248
1224 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1249 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1225
1250
1226 if ymin == None: ymin = 0
1251 if ymin == None: ymin = 0
1227 if ymax == None: ymax = 360
1252 if ymax == None: ymax = 360
1228
1253
1229 self.FTP_WEI = ftp_wei
1254 self.FTP_WEI = ftp_wei
1230 self.EXP_CODE = exp_code
1255 self.EXP_CODE = exp_code
1231 self.SUB_EXP_CODE = sub_exp_code
1256 self.SUB_EXP_CODE = sub_exp_code
1232 self.PLOT_POS = plot_pos
1257 self.PLOT_POS = plot_pos
1233
1258
1234 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1259 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1235 self.isConfig = True
1260 self.isConfig = True
1236 self.figfile = figfile
1261 self.figfile = figfile
1237 self.xdata = numpy.array([])
1262 self.xdata = numpy.array([])
1238 self.ydata = numpy.array([])
1263 self.ydata = numpy.array([])
1239
1264
1240 update_figfile = True
1265 update_figfile = True
1241
1266
1242 #open file beacon phase
1267 #open file beacon phase
1243 path = '%s%03d' %(self.PREFIX, self.id)
1268 path = '%s%03d' %(self.PREFIX, self.id)
1244 beacon_file = os.path.join(path,'%s.txt'%self.name)
1269 beacon_file = os.path.join(path,'%s.txt'%self.name)
1245 self.filename_phase = os.path.join(figpath,beacon_file)
1270 self.filename_phase = os.path.join(figpath,beacon_file)
1246 #self.save_phase(self.filename_phase)
1271 #self.save_phase(self.filename_phase)
1247
1272
1248
1273
1249 #store data beacon phase
1274 #store data beacon phase
1250 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1275 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1251
1276
1252 self.setWinTitle(title)
1277 self.setWinTitle(title)
1253
1278
1254
1279
1255 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1280 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1256
1281
1257 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1282 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1258
1283
1259 axes = self.axesList[0]
1284 axes = self.axesList[0]
1260
1285
1261 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1286 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1262
1287
1263 if len(self.ydata)==0:
1288 if len(self.ydata)==0:
1264 self.ydata = phase_beacon.reshape(-1,1)
1289 self.ydata = phase_beacon.reshape(-1,1)
1265 else:
1290 else:
1266 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1291 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1267
1292
1268
1293
1269 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1294 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1270 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1295 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1271 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1296 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1272 XAxisAsTime=True, grid='both'
1297 XAxisAsTime=True, grid='both'
1273 )
1298 )
1274
1299
1275 self.draw()
1300 self.draw()
1276
1301
1277 if dataOut.ltctime >= self.xmax:
1302 if dataOut.ltctime >= self.xmax:
1278 self.counter_imagwr = wr_period
1303 self.counter_imagwr = wr_period
1279 self.isConfig = False
1304 self.isConfig = False
1280 update_figfile = True
1305 update_figfile = True
1281
1306
1282 self.save(figpath=figpath,
1307 self.save(figpath=figpath,
1283 figfile=figfile,
1308 figfile=figfile,
1284 save=save,
1309 save=save,
1285 ftp=ftp,
1310 ftp=ftp,
1286 wr_period=wr_period,
1311 wr_period=wr_period,
1287 thisDatetime=thisDatetime,
1312 thisDatetime=thisDatetime,
1288 update_figfile=update_figfile)
1313 update_figfile=update_figfile)
1289
1314
1290 return dataOut
1315 return dataOut
@@ -1,1285 +1,1285
1
1
2 import os
2 import os
3 import time
3 import time
4 import math
4 import math
5 import datetime
5 import datetime
6 import numpy
6 import numpy
7 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
7 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
8
8
9 from .jroplot_spectra import RTIPlot, NoisePlot
9 from .jroplot_spectra import RTIPlot, NoisePlot
10
10
11 from schainpy.utils import log
11 from schainpy.utils import log
12 from .plotting_codes import *
12 from .plotting_codes import *
13
13
14 from schainpy.model.graphics.jroplot_base import Plot, plt
14 from schainpy.model.graphics.jroplot_base import Plot, plt
15
15
16 import matplotlib.pyplot as plt
16 import matplotlib.pyplot as plt
17 import matplotlib.colors as colors
17 import matplotlib.colors as colors
18 from matplotlib.ticker import MultipleLocator
18 from matplotlib.ticker import MultipleLocator
19
19
20
20
21 class RTIDPPlot(RTIPlot):
21 class RTIDPPlot(RTIPlot):
22
22
23 '''Plot for RTI Double Pulse Experiment
23 '''Plot for RTI Double Pulse Experiment
24 '''
24 '''
25
25
26 CODE = 'RTIDP'
26 CODE = 'RTIDP'
27 colormap = 'jet'
27 colormap = 'jet'
28 plot_name = 'RTI'
28 plot_name = 'RTI'
29 plot_type = 'pcolorbuffer'
29 plot_type = 'pcolorbuffer'
30
30
31 def setup(self):
31 def setup(self):
32 self.xaxis = 'time'
32 self.xaxis = 'time'
33 self.ncols = 1
33 self.ncols = 1
34 self.nrows = 3
34 self.nrows = 3
35 self.nplots = self.nrows
35 self.nplots = self.nrows
36
36
37 self.ylabel = 'Range [km]'
37 self.ylabel = 'Range [km]'
38 self.xlabel = 'Time (LT)'
38 self.xlabel = 'Time (LT)'
39
39
40 self.cb_label = 'Intensity (dB)'
40 self.cb_label = 'Intensity (dB)'
41
41
42 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
42 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
43
43
44 self.titles = ['{} Channel {}'.format(
44 self.titles = ['{} Channel {}'.format(
45 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
45 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
46 self.plot_name.upper(), '0'),'{} Channel {}'.format(
46 self.plot_name.upper(), '0'),'{} Channel {}'.format(
47 self.plot_name.upper(), '1')]
47 self.plot_name.upper(), '1')]
48
48
49 def update(self, dataOut):
49 def update(self, dataOut):
50
50
51 data = {}
51 data = {}
52 meta = {}
52 meta = {}
53 data['rti'] = dataOut.data_for_RTI_DP
53 data['rti'] = dataOut.data_for_RTI_DP
54 data['NDP'] = dataOut.NDP
54 data['NDP'] = dataOut.NDP
55
55
56 return data, meta
56 return data, meta
57
57
58 def plot(self):
58 def plot(self):
59
59
60 NDP = self.data['NDP'][-1]
60 NDP = self.data['NDP'][-1]
61 self.x = self.data.times
61 self.x = self.data.times
62 self.y = self.data.yrange[0:NDP]
62 self.y = self.data.yrange[0:NDP]
63 self.z = self.data['rti']
63 self.z = self.data['rti']
64 self.z = numpy.ma.masked_invalid(self.z)
64 self.z = numpy.ma.masked_invalid(self.z)
65
65
66 if self.decimation is None:
66 if self.decimation is None:
67 x, y, z = self.fill_gaps(self.x, self.y, self.z)
67 x, y, z = self.fill_gaps(self.x, self.y, self.z)
68 else:
68 else:
69 x, y, z = self.fill_gaps(*self.decimate())
69 x, y, z = self.fill_gaps(*self.decimate())
70
70
71 for n, ax in enumerate(self.axes):
71 for n, ax in enumerate(self.axes):
72
72
73 self.zmax = self.zmax if self.zmax is not None else numpy.max(
73 self.zmax = self.zmax if self.zmax is not None else numpy.max(
74 self.z[1][0,12:40])
74 self.z[1][0,12:40])
75 self.zmin = self.zmin if self.zmin is not None else numpy.min(
75 self.zmin = self.zmin if self.zmin is not None else numpy.min(
76 self.z[1][0,12:40])
76 self.z[1][0,12:40])
77
77
78 if ax.firsttime:
78 if ax.firsttime:
79
79
80 if self.zlimits is not None:
80 if self.zlimits is not None:
81 self.zmin, self.zmax = self.zlimits[n]
81 self.zmin, self.zmax = self.zlimits[n]
82
82
83 ax.plt = ax.pcolormesh(x, y, z[n].T,
83 ax.plt = ax.pcolormesh(x, y, z[n].T,
84 vmin=self.zmin,
84 vmin=self.zmin,
85 vmax=self.zmax,
85 vmax=self.zmax,
86 cmap=plt.get_cmap(self.colormap)
86 cmap=plt.get_cmap(self.colormap)
87 )
87 )
88 else:
88 else:
89 #if self.zlimits is not None:
89 #if self.zlimits is not None:
90 #self.zmin, self.zmax = self.zlimits[n]
90 #self.zmin, self.zmax = self.zlimits[n]
91 ax.collections.remove(ax.collections[0])
91 ax.collections.remove(ax.collections[0])
92 ax.plt = ax.pcolormesh(x, y, z[n].T,
92 ax.plt = ax.pcolormesh(x, y, z[n].T,
93 vmin=self.zmin,
93 vmin=self.zmin,
94 vmax=self.zmax,
94 vmax=self.zmax,
95 cmap=plt.get_cmap(self.colormap)
95 cmap=plt.get_cmap(self.colormap)
96 )
96 )
97
97
98
98
99 class RTILPPlot(RTIPlot):
99 class RTILPPlot(RTIPlot):
100
100
101 '''
101 '''
102 Plot for RTI Long Pulse
102 Plot for RTI Long Pulse
103 '''
103 '''
104
104
105 CODE = 'RTILP'
105 CODE = 'RTILP'
106 colormap = 'jet'
106 colormap = 'jet'
107 plot_name = 'RTI LP'
107 plot_name = 'RTI LP'
108 plot_type = 'pcolorbuffer'
108 plot_type = 'pcolorbuffer'
109
109
110 def setup(self):
110 def setup(self):
111 self.xaxis = 'time'
111 self.xaxis = 'time'
112 self.ncols = 1
112 self.ncols = 1
113 self.nrows = 4
113 self.nrows = 4
114 self.nplots = self.nrows
114 self.nplots = self.nrows
115
115
116 self.ylabel = 'Range [km]'
116 self.ylabel = 'Range [km]'
117 self.xlabel = 'Time (LT)'
117 self.xlabel = 'Time (LT)'
118
118
119 self.cb_label = 'Intensity (dB)'
119 self.cb_label = 'Intensity (dB)'
120
120
121 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
121 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
122
122
123
123
124 self.titles = ['{} Channel {}'.format(
124 self.titles = ['{} Channel {}'.format(
125 self.plot_name.upper(), '0'),'{} Channel {}'.format(
125 self.plot_name.upper(), '0'),'{} Channel {}'.format(
126 self.plot_name.upper(), '1'),'{} Channel {}'.format(
126 self.plot_name.upper(), '1'),'{} Channel {}'.format(
127 self.plot_name.upper(), '2'),'{} Channel {}'.format(
127 self.plot_name.upper(), '2'),'{} Channel {}'.format(
128 self.plot_name.upper(), '3')]
128 self.plot_name.upper(), '3')]
129
129
130
130
131 def update(self, dataOut):
131 def update(self, dataOut):
132
132
133 data = {}
133 data = {}
134 meta = {}
134 meta = {}
135 data['rti'] = dataOut.data_for_RTI_LP
135 data['rti'] = dataOut.data_for_RTI_LP
136 data['NRANGE'] = dataOut.NRANGE
136 data['NRANGE'] = dataOut.NRANGE
137
137
138 return data, meta
138 return data, meta
139
139
140 def plot(self):
140 def plot(self):
141
141
142 NRANGE = self.data['NRANGE'][-1]
142 NRANGE = self.data['NRANGE'][-1]
143 self.x = self.data.times
143 self.x = self.data.times
144 self.y = self.data.yrange[0:NRANGE]
144 self.y = self.data.yrange[0:NRANGE]
145
145
146 self.z = self.data['rti']
146 self.z = self.data['rti']
147
147
148 self.z = numpy.ma.masked_invalid(self.z)
148 self.z = numpy.ma.masked_invalid(self.z)
149
149
150 if self.decimation is None:
150 if self.decimation is None:
151 x, y, z = self.fill_gaps(self.x, self.y, self.z)
151 x, y, z = self.fill_gaps(self.x, self.y, self.z)
152 else:
152 else:
153 x, y, z = self.fill_gaps(*self.decimate())
153 x, y, z = self.fill_gaps(*self.decimate())
154
154
155 for n, ax in enumerate(self.axes):
155 for n, ax in enumerate(self.axes):
156
156
157 self.zmax = self.zmax if self.zmax is not None else numpy.max(
157 self.zmax = self.zmax if self.zmax is not None else numpy.max(
158 self.z[1][0,12:40])
158 self.z[1][0,12:40])
159 self.zmin = self.zmin if self.zmin is not None else numpy.min(
159 self.zmin = self.zmin if self.zmin is not None else numpy.min(
160 self.z[1][0,12:40])
160 self.z[1][0,12:40])
161
161
162 if ax.firsttime:
162 if ax.firsttime:
163
163
164 if self.zlimits is not None:
164 if self.zlimits is not None:
165 self.zmin, self.zmax = self.zlimits[n]
165 self.zmin, self.zmax = self.zlimits[n]
166
166
167
167
168 ax.plt = ax.pcolormesh(x, y, z[n].T,
168 ax.plt = ax.pcolormesh(x, y, z[n].T,
169 vmin=self.zmin,
169 vmin=self.zmin,
170 vmax=self.zmax,
170 vmax=self.zmax,
171 cmap=plt.get_cmap(self.colormap)
171 cmap=plt.get_cmap(self.colormap)
172 )
172 )
173
173
174 else:
174 else:
175 #if self.zlimits is not None:
175 #if self.zlimits is not None:
176 #self.zmin, self.zmax = self.zlimits[n]
176 #self.zmin, self.zmax = self.zlimits[n]
177 ax.collections.remove(ax.collections[0])
177 ax.collections.remove(ax.collections[0])
178 ax.plt = ax.pcolormesh(x, y, z[n].T,
178 ax.plt = ax.pcolormesh(x, y, z[n].T,
179 vmin=self.zmin,
179 vmin=self.zmin,
180 vmax=self.zmax,
180 vmax=self.zmax,
181 cmap=plt.get_cmap(self.colormap)
181 cmap=plt.get_cmap(self.colormap)
182 )
182 )
183
183
184
184
185 class DenRTIPlot(RTIPlot):
185 class DenRTIPlot(RTIPlot):
186
186
187 '''
187 '''
188 Plot for Den
188 Plot for Den
189 '''
189 '''
190
190
191 CODE = 'denrti'
191 CODE = 'denrti'
192 colormap = 'jet'
192 colormap = 'jet'
193
193
194 def setup(self):
194 def setup(self):
195 self.xaxis = 'time'
195 self.xaxis = 'time'
196 self.ncols = 1
196 self.ncols = 1
197 self.nrows = self.data.shape(self.CODE)[0]
197 self.nrows = self.data.shape(self.CODE)[0]
198 self.nplots = self.nrows
198 self.nplots = self.nrows
199
199
200 self.ylabel = 'Range [km]'
200 self.ylabel = 'Range [km]'
201 self.xlabel = 'Time (LT)'
201 self.xlabel = 'Time (LT)'
202
202
203 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
203 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
204
204
205 if self.CODE == 'denrti':
205 if self.CODE == 'denrti':
206 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
206 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
207
207
208
208
209 self.titles = ['Electron Density RTI']
209 self.titles = ['Electron Density RTI']
210
210
211 def update(self, dataOut):
211 def update(self, dataOut):
212
212
213 data = {}
213 data = {}
214 meta = {}
214 meta = {}
215
215
216 data['denrti'] = dataOut.DensityFinal
216 data['denrti'] = dataOut.DensityFinal*1.e-6 #To Plot in cm^-3
217
217
218 return data, meta
218 return data, meta
219
219
220 def plot(self):
220 def plot(self):
221
221
222 self.x = self.data.times
222 self.x = self.data.times
223 self.y = self.data.yrange
223 self.y = self.data.yrange
224
224
225 self.z = self.data[self.CODE]
225 self.z = self.data[self.CODE]
226
226
227 self.z = numpy.ma.masked_invalid(self.z)
227 self.z = numpy.ma.masked_invalid(self.z)
228
228
229 if self.decimation is None:
229 if self.decimation is None:
230 x, y, z = self.fill_gaps(self.x, self.y, self.z)
230 x, y, z = self.fill_gaps(self.x, self.y, self.z)
231 else:
231 else:
232 x, y, z = self.fill_gaps(*self.decimate())
232 x, y, z = self.fill_gaps(*self.decimate())
233
233
234 for n, ax in enumerate(self.axes):
234 for n, ax in enumerate(self.axes):
235
235
236 self.zmax = self.zmax if self.zmax is not None else numpy.max(
236 self.zmax = self.zmax if self.zmax is not None else numpy.max(
237 self.z[n])
237 self.z[n])
238 self.zmin = self.zmin if self.zmin is not None else numpy.min(
238 self.zmin = self.zmin if self.zmin is not None else numpy.min(
239 self.z[n])
239 self.z[n])
240
240
241 if ax.firsttime:
241 if ax.firsttime:
242
242
243 if self.zlimits is not None:
243 if self.zlimits is not None:
244 self.zmin, self.zmax = self.zlimits[n]
244 self.zmin, self.zmax = self.zlimits[n]
245 if numpy.log10(self.zmin)<0:
245 if numpy.log10(self.zmin)<0:
246 self.zmin=1
246 self.zmin=1
247 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
247 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
248 vmin=self.zmin,
248 vmin=self.zmin,
249 vmax=self.zmax,
249 vmax=self.zmax,
250 cmap=self.cmaps[n],
250 cmap=self.cmaps[n],
251 norm=colors.LogNorm()
251 norm=colors.LogNorm()
252 )
252 )
253
253
254 else:
254 else:
255 if self.zlimits is not None:
255 if self.zlimits is not None:
256 self.zmin, self.zmax = self.zlimits[n]
256 self.zmin, self.zmax = self.zlimits[n]
257 ax.collections.remove(ax.collections[0])
257 ax.collections.remove(ax.collections[0])
258 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
258 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
259 vmin=self.zmin,
259 vmin=self.zmin,
260 vmax=self.zmax,
260 vmax=self.zmax,
261 cmap=self.cmaps[n],
261 cmap=self.cmaps[n],
262 norm=colors.LogNorm()
262 norm=colors.LogNorm()
263 )
263 )
264
264
265
265
266 class ETempRTIPlot(RTIPlot):
266 class ETempRTIPlot(RTIPlot):
267
267
268 '''
268 '''
269 Plot for Electron Temperature
269 Plot for Electron Temperature
270 '''
270 '''
271
271
272 CODE = 'ETemp'
272 CODE = 'ETemp'
273 colormap = 'jet'
273 colormap = 'jet'
274
274
275 def setup(self):
275 def setup(self):
276 self.xaxis = 'time'
276 self.xaxis = 'time'
277 self.ncols = 1
277 self.ncols = 1
278 self.nrows = self.data.shape(self.CODE)[0]
278 self.nrows = self.data.shape(self.CODE)[0]
279 self.nplots = self.nrows
279 self.nplots = self.nrows
280
280
281 self.ylabel = 'Range [km]'
281 self.ylabel = 'Range [km]'
282 self.xlabel = 'Time (LT)'
282 self.xlabel = 'Time (LT)'
283 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
283 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
284 if self.CODE == 'ETemp':
284 if self.CODE == 'ETemp':
285 self.cb_label = 'Electron Temperature (K)'
285 self.cb_label = 'Electron Temperature (K)'
286 self.titles = ['Electron Temperature RTI']
286 self.titles = ['Electron Temperature RTI']
287 if self.CODE == 'ITemp':
287 if self.CODE == 'ITemp':
288 self.cb_label = 'Ion Temperature (K)'
288 self.cb_label = 'Ion Temperature (K)'
289 self.titles = ['Ion Temperature RTI']
289 self.titles = ['Ion Temperature RTI']
290 if self.CODE == 'HeFracLP':
290 if self.CODE == 'HeFracLP':
291 self.cb_label='He+ Fraction'
291 self.cb_label='He+ Fraction'
292 self.titles = ['He+ Fraction RTI']
292 self.titles = ['He+ Fraction RTI']
293 self.zmax=0.16
293 self.zmax=0.16
294 if self.CODE== 'HFracLP':
294 if self.CODE== 'HFracLP':
295 self.cb_label='H+ Fraction'
295 self.cb_label='H+ Fraction'
296 self.titles = ['H+ Fraction RTI']
296 self.titles = ['H+ Fraction RTI']
297
297
298 def update(self, dataOut):
298 def update(self, dataOut):
299
299
300 data = {}
300 data = {}
301 meta = {}
301 meta = {}
302
302
303 data['ETemp'] = dataOut.ElecTempFinal
303 data['ETemp'] = dataOut.ElecTempFinal
304
304
305 return data, meta
305 return data, meta
306
306
307 def plot(self):
307 def plot(self):
308
308
309 self.x = self.data.times
309 self.x = self.data.times
310 self.y = self.data.yrange
310 self.y = self.data.yrange
311
311
312
312
313 self.z = self.data[self.CODE]
313 self.z = self.data[self.CODE]
314
314
315 self.z = numpy.ma.masked_invalid(self.z)
315 self.z = numpy.ma.masked_invalid(self.z)
316
316
317 if self.decimation is None:
317 if self.decimation is None:
318 x, y, z = self.fill_gaps(self.x, self.y, self.z)
318 x, y, z = self.fill_gaps(self.x, self.y, self.z)
319 else:
319 else:
320 x, y, z = self.fill_gaps(*self.decimate())
320 x, y, z = self.fill_gaps(*self.decimate())
321
321
322 for n, ax in enumerate(self.axes):
322 for n, ax in enumerate(self.axes):
323
323
324 self.zmax = self.zmax if self.zmax is not None else numpy.max(
324 self.zmax = self.zmax if self.zmax is not None else numpy.max(
325 self.z[n])
325 self.z[n])
326 self.zmin = self.zmin if self.zmin is not None else numpy.min(
326 self.zmin = self.zmin if self.zmin is not None else numpy.min(
327 self.z[n])
327 self.z[n])
328
328
329 if ax.firsttime:
329 if ax.firsttime:
330
330
331 if self.zlimits is not None:
331 if self.zlimits is not None:
332 self.zmin, self.zmax = self.zlimits[n]
332 self.zmin, self.zmax = self.zlimits[n]
333
333
334 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
334 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
335 vmin=self.zmin,
335 vmin=self.zmin,
336 vmax=self.zmax,
336 vmax=self.zmax,
337 cmap=self.cmaps[n]
337 cmap=self.cmaps[n]
338 )
338 )
339 #plt.tight_layout()
339 #plt.tight_layout()
340
340
341 else:
341 else:
342 if self.zlimits is not None:
342 if self.zlimits is not None:
343 self.zmin, self.zmax = self.zlimits[n]
343 self.zmin, self.zmax = self.zlimits[n]
344 ax.collections.remove(ax.collections[0])
344 ax.collections.remove(ax.collections[0])
345 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
345 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
346 vmin=self.zmin,
346 vmin=self.zmin,
347 vmax=self.zmax,
347 vmax=self.zmax,
348 cmap=self.cmaps[n]
348 cmap=self.cmaps[n]
349 )
349 )
350
350
351
351
352 class ITempRTIPlot(ETempRTIPlot):
352 class ITempRTIPlot(ETempRTIPlot):
353
353
354 '''
354 '''
355 Plot for Ion Temperature
355 Plot for Ion Temperature
356 '''
356 '''
357
357
358 CODE = 'ITemp'
358 CODE = 'ITemp'
359 colormap = 'jet'
359 colormap = 'jet'
360 plot_name = 'Ion Temperature'
360 plot_name = 'Ion Temperature'
361
361
362 def update(self, dataOut):
362 def update(self, dataOut):
363
363
364 data = {}
364 data = {}
365 meta = {}
365 meta = {}
366
366
367 data['ITemp'] = dataOut.IonTempFinal
367 data['ITemp'] = dataOut.IonTempFinal
368
368
369 return data, meta
369 return data, meta
370
370
371
371
372 class HFracRTIPlot(ETempRTIPlot):
372 class HFracRTIPlot(ETempRTIPlot):
373
373
374 '''
374 '''
375 Plot for H+ LP
375 Plot for H+ LP
376 '''
376 '''
377
377
378 CODE = 'HFracLP'
378 CODE = 'HFracLP'
379 colormap = 'jet'
379 colormap = 'jet'
380 plot_name = 'H+ Frac'
380 plot_name = 'H+ Frac'
381
381
382 def update(self, dataOut):
382 def update(self, dataOut):
383
383
384 data = {}
384 data = {}
385 meta = {}
385 meta = {}
386 data['HFracLP'] = dataOut.PhyFinal
386 data['HFracLP'] = dataOut.PhyFinal
387
387
388 return data, meta
388 return data, meta
389
389
390
390
391 class HeFracRTIPlot(ETempRTIPlot):
391 class HeFracRTIPlot(ETempRTIPlot):
392
392
393 '''
393 '''
394 Plot for He+ LP
394 Plot for He+ LP
395 '''
395 '''
396
396
397 CODE = 'HeFracLP'
397 CODE = 'HeFracLP'
398 colormap = 'jet'
398 colormap = 'jet'
399 plot_name = 'He+ Frac'
399 plot_name = 'He+ Frac'
400
400
401 def update(self, dataOut):
401 def update(self, dataOut):
402
402
403 data = {}
403 data = {}
404 meta = {}
404 meta = {}
405 data['HeFracLP'] = dataOut.PheFinal
405 data['HeFracLP'] = dataOut.PheFinal
406
406
407 return data, meta
407 return data, meta
408
408
409
409
410 class TempsDPPlot(Plot):
410 class TempsDPPlot(Plot):
411 '''
411 '''
412 Plot for Electron - Ion Temperatures
412 Plot for Electron - Ion Temperatures
413 '''
413 '''
414
414
415 CODE = 'tempsDP'
415 CODE = 'tempsDP'
416 #plot_name = 'Temperatures'
416 #plot_name = 'Temperatures'
417 plot_type = 'scatterbuffer'
417 plot_type = 'scatterbuffer'
418
418
419 def setup(self):
419 def setup(self):
420
420
421 self.ncols = 1
421 self.ncols = 1
422 self.nrows = 1
422 self.nrows = 1
423 self.nplots = 1
423 self.nplots = 1
424 self.ylabel = 'Range [km]'
424 self.ylabel = 'Range [km]'
425 self.xlabel = 'Temperature (K)'
425 self.xlabel = 'Temperature (K)'
426 self.titles = ['Electron/Ion Temperatures']
426 self.titles = ['Electron/Ion Temperatures']
427 self.width = 3.5
427 self.width = 3.5
428 self.height = 5.5
428 self.height = 5.5
429 self.colorbar = False
429 self.colorbar = False
430 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
430 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
431
431
432 def update(self, dataOut):
432 def update(self, dataOut):
433 data = {}
433 data = {}
434 meta = {}
434 meta = {}
435
435
436 data['Te'] = dataOut.te2
436 data['Te'] = dataOut.te2
437 data['Ti'] = dataOut.ti2
437 data['Ti'] = dataOut.ti2
438 data['Te_error'] = dataOut.ete2
438 data['Te_error'] = dataOut.ete2
439 data['Ti_error'] = dataOut.eti2
439 data['Ti_error'] = dataOut.eti2
440
440
441 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
441 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
442
442
443 return data, meta
443 return data, meta
444
444
445 def plot(self):
445 def plot(self):
446
446
447 y = self.data.yrange
447 y = self.data.yrange
448
448
449 self.xmin = -100
449 self.xmin = -100
450 self.xmax = 5000
450 self.xmax = 5000
451
451
452 ax = self.axes[0]
452 ax = self.axes[0]
453
453
454 data = self.data[-1]
454 data = self.data[-1]
455
455
456 Te = data['Te']
456 Te = data['Te']
457 Ti = data['Ti']
457 Ti = data['Ti']
458 errTe = data['Te_error']
458 errTe = data['Te_error']
459 errTi = data['Ti_error']
459 errTi = data['Ti_error']
460
460
461 if ax.firsttime:
461 if ax.firsttime:
462 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
462 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
463 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
463 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
464 plt.legend(loc='lower right')
464 plt.legend(loc='lower right')
465 self.ystep_given = 50
465 self.ystep_given = 50
466 ax.yaxis.set_minor_locator(MultipleLocator(15))
466 ax.yaxis.set_minor_locator(MultipleLocator(15))
467 ax.grid(which='minor')
467 ax.grid(which='minor')
468
468
469 else:
469 else:
470 self.clear_figures()
470 self.clear_figures()
471 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
471 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
472 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
472 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
473 plt.legend(loc='lower right')
473 plt.legend(loc='lower right')
474 ax.yaxis.set_minor_locator(MultipleLocator(15))
474 ax.yaxis.set_minor_locator(MultipleLocator(15))
475
475
476
476
477 class TempsHPPlot(Plot):
477 class TempsHPPlot(Plot):
478 '''
478 '''
479 Plot for Temperatures Hybrid Experiment
479 Plot for Temperatures Hybrid Experiment
480 '''
480 '''
481
481
482 CODE = 'temps_LP'
482 CODE = 'temps_LP'
483 #plot_name = 'Temperatures'
483 #plot_name = 'Temperatures'
484 plot_type = 'scatterbuffer'
484 plot_type = 'scatterbuffer'
485
485
486
486
487 def setup(self):
487 def setup(self):
488
488
489 self.ncols = 1
489 self.ncols = 1
490 self.nrows = 1
490 self.nrows = 1
491 self.nplots = 1
491 self.nplots = 1
492 self.ylabel = 'Range [km]'
492 self.ylabel = 'Range [km]'
493 self.xlabel = 'Temperature (K)'
493 self.xlabel = 'Temperature (K)'
494 self.titles = ['Electron/Ion Temperatures']
494 self.titles = ['Electron/Ion Temperatures']
495 self.width = 3.5
495 self.width = 3.5
496 self.height = 6.5
496 self.height = 6.5
497 self.colorbar = False
497 self.colorbar = False
498 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
498 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
499
499
500 def update(self, dataOut):
500 def update(self, dataOut):
501 data = {}
501 data = {}
502 meta = {}
502 meta = {}
503
503
504
504
505 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
505 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
506 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
506 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
507 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
507 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
508 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
508 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
509
509
510 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
510 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
511
511
512 return data, meta
512 return data, meta
513
513
514 def plot(self):
514 def plot(self):
515
515
516
516
517 self.y = self.data.yrange
517 self.y = self.data.yrange
518 self.xmin = -100
518 self.xmin = -100
519 self.xmax = 4500
519 self.xmax = 4500
520 ax = self.axes[0]
520 ax = self.axes[0]
521
521
522 data = self.data[-1]
522 data = self.data[-1]
523
523
524 Te = data['Te']
524 Te = data['Te']
525 Ti = data['Ti']
525 Ti = data['Ti']
526 errTe = data['Te_error']
526 errTe = data['Te_error']
527 errTi = data['Ti_error']
527 errTi = data['Ti_error']
528
528
529 if ax.firsttime:
529 if ax.firsttime:
530
530
531 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
531 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
532 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
532 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
533 plt.legend(loc='lower right')
533 plt.legend(loc='lower right')
534 self.ystep_given = 200
534 self.ystep_given = 200
535 ax.yaxis.set_minor_locator(MultipleLocator(15))
535 ax.yaxis.set_minor_locator(MultipleLocator(15))
536 ax.grid(which='minor')
536 ax.grid(which='minor')
537
537
538 else:
538 else:
539 self.clear_figures()
539 self.clear_figures()
540 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
540 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
541 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
541 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
542 plt.legend(loc='lower right')
542 plt.legend(loc='lower right')
543 ax.yaxis.set_minor_locator(MultipleLocator(15))
543 ax.yaxis.set_minor_locator(MultipleLocator(15))
544 ax.grid(which='minor')
544 ax.grid(which='minor')
545
545
546
546
547 class FracsHPPlot(Plot):
547 class FracsHPPlot(Plot):
548 '''
548 '''
549 Plot for Composition LP
549 Plot for Composition LP
550 '''
550 '''
551
551
552 CODE = 'fracs_LP'
552 CODE = 'fracs_LP'
553 plot_type = 'scatterbuffer'
553 plot_type = 'scatterbuffer'
554
554
555
555
556 def setup(self):
556 def setup(self):
557
557
558 self.ncols = 1
558 self.ncols = 1
559 self.nrows = 1
559 self.nrows = 1
560 self.nplots = 1
560 self.nplots = 1
561 self.ylabel = 'Range [km]'
561 self.ylabel = 'Range [km]'
562 self.xlabel = 'Frac'
562 self.xlabel = 'Frac'
563 self.titles = ['Composition']
563 self.titles = ['Composition']
564 self.width = 3.5
564 self.width = 3.5
565 self.height = 6.5
565 self.height = 6.5
566 self.colorbar = False
566 self.colorbar = False
567 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
567 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
568
568
569 def update(self, dataOut):
569 def update(self, dataOut):
570 data = {}
570 data = {}
571 meta = {}
571 meta = {}
572
572
573 #aux_nan=numpy.zeros(dataOut.cut,'float32')
573 #aux_nan=numpy.zeros(dataOut.cut,'float32')
574 #aux_nan[:]=numpy.nan
574 #aux_nan[:]=numpy.nan
575 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
575 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
576 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
576 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
577
577
578 data['ph'] = dataOut.ph[dataOut.cut:]
578 data['ph'] = dataOut.ph[dataOut.cut:]
579 data['eph'] = dataOut.eph[dataOut.cut:]
579 data['eph'] = dataOut.eph[dataOut.cut:]
580 data['phe'] = dataOut.phe[dataOut.cut:]
580 data['phe'] = dataOut.phe[dataOut.cut:]
581 data['ephe'] = dataOut.ephe[dataOut.cut:]
581 data['ephe'] = dataOut.ephe[dataOut.cut:]
582
582
583 data['cut'] = dataOut.cut
583 data['cut'] = dataOut.cut
584
584
585 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
585 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
586
586
587
587
588 return data, meta
588 return data, meta
589
589
590 def plot(self):
590 def plot(self):
591
591
592 data = self.data[-1]
592 data = self.data[-1]
593
593
594 ph = data['ph']
594 ph = data['ph']
595 eph = data['eph']
595 eph = data['eph']
596 phe = data['phe']
596 phe = data['phe']
597 ephe = data['ephe']
597 ephe = data['ephe']
598 cut = data['cut']
598 cut = data['cut']
599 self.y = self.data.yrange
599 self.y = self.data.yrange
600
600
601 self.xmin = 0
601 self.xmin = 0
602 self.xmax = 1
602 self.xmax = 1
603 ax = self.axes[0]
603 ax = self.axes[0]
604
604
605 if ax.firsttime:
605 if ax.firsttime:
606
606
607 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
607 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
608 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
608 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
609 plt.legend(loc='lower right')
609 plt.legend(loc='lower right')
610 self.xstep_given = 0.2
610 self.xstep_given = 0.2
611 self.ystep_given = 200
611 self.ystep_given = 200
612 ax.yaxis.set_minor_locator(MultipleLocator(15))
612 ax.yaxis.set_minor_locator(MultipleLocator(15))
613 ax.grid(which='minor')
613 ax.grid(which='minor')
614
614
615 else:
615 else:
616 self.clear_figures()
616 self.clear_figures()
617 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
617 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
618 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
618 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
619 plt.legend(loc='lower right')
619 plt.legend(loc='lower right')
620 ax.yaxis.set_minor_locator(MultipleLocator(15))
620 ax.yaxis.set_minor_locator(MultipleLocator(15))
621
621
622 class EDensityPlot(Plot):
622 class EDensityPlot(Plot):
623 '''
623 '''
624 Plot for electron density
624 Plot for electron density
625 '''
625 '''
626
626
627 CODE = 'den'
627 CODE = 'den'
628 #plot_name = 'Electron Density'
628 #plot_name = 'Electron Density'
629 plot_type = 'scatterbuffer'
629 plot_type = 'scatterbuffer'
630
630
631 def setup(self):
631 def setup(self):
632
632
633 self.ncols = 1
633 self.ncols = 1
634 self.nrows = 1
634 self.nrows = 1
635 self.nplots = 1
635 self.nplots = 1
636 self.ylabel = 'Range [km]'
636 self.ylabel = 'Range [km]'
637 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
637 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
638 self.titles = ['Electron Density']
638 self.titles = ['Electron Density']
639 self.width = 3.5
639 self.width = 3.5
640 self.height = 5.5
640 self.height = 5.5
641 self.colorbar = False
641 self.colorbar = False
642 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
642 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
643
643
644 def update(self, dataOut):
644 def update(self, dataOut):
645 data = {}
645 data = {}
646 meta = {}
646 meta = {}
647
647
648 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
648 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
649 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
649 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
650 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
650 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
651 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
651 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
652
652
653 data['NSHTS'] = dataOut.NSHTS
653 data['NSHTS'] = dataOut.NSHTS
654
654
655 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
655 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
656
656
657 return data, meta
657 return data, meta
658
658
659 def plot(self):
659 def plot(self):
660
660
661 y = self.data.yrange
661 y = self.data.yrange
662
662
663 self.xmin = 1e3
663 self.xmin = 1e3
664 self.xmax = 1e7
664 self.xmax = 1e7
665
665
666 ax = self.axes[0]
666 ax = self.axes[0]
667
667
668 data = self.data[-1]
668 data = self.data[-1]
669
669
670 DenPow = data['den_power']
670 DenPow = data['den_power']
671 DenFar = data['den_Faraday']
671 DenFar = data['den_Faraday']
672 errDenPow = data['den_error']
672 errDenPow = data['den_error']
673 #errFaraday = data['err_Faraday']
673 #errFaraday = data['err_Faraday']
674
674
675 NSHTS = data['NSHTS']
675 NSHTS = data['NSHTS']
676
676
677 if self.CODE == 'denLP':
677 if self.CODE == 'denLP':
678 DenPowLP = data['den_LP']
678 DenPowLP = data['den_LP']
679 errDenPowLP = data['den_LP_error']
679 errDenPowLP = data['den_LP_error']
680 cut = data['cut']
680 cut = data['cut']
681
681
682 if ax.firsttime:
682 if ax.firsttime:
683 self.autoxticks=False
683 self.autoxticks=False
684 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
684 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
685 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
685 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
686 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
686 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
687 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
687 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
688
688
689 if self.CODE=='denLP':
689 if self.CODE=='denLP':
690 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
690 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
691
691
692 plt.legend(loc='upper left',fontsize=8.5)
692 plt.legend(loc='upper left',fontsize=8.5)
693 #plt.legend(loc='lower left',fontsize=8.5)
693 #plt.legend(loc='lower left',fontsize=8.5)
694 ax.set_xscale("log", nonposx='clip')
694 ax.set_xscale("log", nonposx='clip')
695 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
695 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
696 self.ystep_given=100
696 self.ystep_given=100
697 if self.CODE=='denLP':
697 if self.CODE=='denLP':
698 self.ystep_given=200
698 self.ystep_given=200
699 ax.set_yticks(grid_y_ticks,minor=True)
699 ax.set_yticks(grid_y_ticks,minor=True)
700 ax.grid(which='minor')
700 ax.grid(which='minor')
701
701
702 else:
702 else:
703 dataBefore = self.data[-2]
703 dataBefore = self.data[-2]
704 DenPowBefore = dataBefore['den_power']
704 DenPowBefore = dataBefore['den_power']
705 self.clear_figures()
705 self.clear_figures()
706 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
706 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
707 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
707 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
708 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
708 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
709 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
709 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
710 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
710 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
711
711
712 if self.CODE=='denLP':
712 if self.CODE=='denLP':
713 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
713 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
714
714
715 ax.set_xscale("log", nonposx='clip')
715 ax.set_xscale("log", nonposx='clip')
716 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
716 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
717 ax.set_yticks(grid_y_ticks,minor=True)
717 ax.set_yticks(grid_y_ticks,minor=True)
718 ax.grid(which='minor')
718 ax.grid(which='minor')
719 plt.legend(loc='upper left',fontsize=8.5)
719 plt.legend(loc='upper left',fontsize=8.5)
720 #plt.legend(loc='lower left',fontsize=8.5)
720 #plt.legend(loc='lower left',fontsize=8.5)
721
721
722 class FaradayAnglePlot(Plot):
722 class FaradayAnglePlot(Plot):
723 '''
723 '''
724 Plot for electron density
724 Plot for electron density
725 '''
725 '''
726
726
727 CODE = 'angle'
727 CODE = 'angle'
728 plot_name = 'Faraday Angle'
728 plot_name = 'Faraday Angle'
729 plot_type = 'scatterbuffer'
729 plot_type = 'scatterbuffer'
730
730
731 def setup(self):
731 def setup(self):
732
732
733 self.ncols = 1
733 self.ncols = 1
734 self.nrows = 1
734 self.nrows = 1
735 self.nplots = 1
735 self.nplots = 1
736 self.ylabel = 'Range [km]'
736 self.ylabel = 'Range [km]'
737 self.xlabel = 'Faraday Angle (º)'
737 self.xlabel = 'Faraday Angle (º)'
738 self.titles = ['Electron Density']
738 self.titles = ['Electron Density']
739 self.width = 3.5
739 self.width = 3.5
740 self.height = 5.5
740 self.height = 5.5
741 self.colorbar = False
741 self.colorbar = False
742 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
742 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
743
743
744 def update(self, dataOut):
744 def update(self, dataOut):
745 data = {}
745 data = {}
746 meta = {}
746 meta = {}
747
747
748 data['angle'] = numpy.degrees(dataOut.phi)
748 data['angle'] = numpy.degrees(dataOut.phi)
749 #'''
749 #'''
750 print(dataOut.phi_uwrp)
750 print(dataOut.phi_uwrp)
751 print(data['angle'])
751 print(data['angle'])
752 exit(1)
752 exit(1)
753 #'''
753 #'''
754 data['dphi'] = dataOut.dphi_uc*10
754 data['dphi'] = dataOut.dphi_uc*10
755 #print(dataOut.dphi)
755 #print(dataOut.dphi)
756
756
757 #data['NSHTS'] = dataOut.NSHTS
757 #data['NSHTS'] = dataOut.NSHTS
758
758
759 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
759 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
760
760
761 return data, meta
761 return data, meta
762
762
763 def plot(self):
763 def plot(self):
764
764
765 data = self.data[-1]
765 data = self.data[-1]
766 self.x = data[self.CODE]
766 self.x = data[self.CODE]
767 dphi = data['dphi']
767 dphi = data['dphi']
768 self.y = self.data.yrange
768 self.y = self.data.yrange
769 self.xmin = -360#-180
769 self.xmin = -360#-180
770 self.xmax = 360#180
770 self.xmax = 360#180
771 ax = self.axes[0]
771 ax = self.axes[0]
772
772
773 if ax.firsttime:
773 if ax.firsttime:
774 self.autoxticks=False
774 self.autoxticks=False
775 #if self.CODE=='den':
775 #if self.CODE=='den':
776 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
776 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
777 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
777 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
778
778
779 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
779 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
780 self.ystep_given=100
780 self.ystep_given=100
781 if self.CODE=='denLP':
781 if self.CODE=='denLP':
782 self.ystep_given=200
782 self.ystep_given=200
783 ax.set_yticks(grid_y_ticks,minor=True)
783 ax.set_yticks(grid_y_ticks,minor=True)
784 ax.grid(which='minor')
784 ax.grid(which='minor')
785 #plt.tight_layout()
785 #plt.tight_layout()
786 else:
786 else:
787
787
788 self.clear_figures()
788 self.clear_figures()
789 #if self.CODE=='den':
789 #if self.CODE=='den':
790 #print(numpy.shape(self.x))
790 #print(numpy.shape(self.x))
791 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
791 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
792 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
792 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
793
793
794 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
794 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
795 ax.set_yticks(grid_y_ticks,minor=True)
795 ax.set_yticks(grid_y_ticks,minor=True)
796 ax.grid(which='minor')
796 ax.grid(which='minor')
797
797
798 class EDensityHPPlot(EDensityPlot):
798 class EDensityHPPlot(EDensityPlot):
799
799
800 '''
800 '''
801 Plot for Electron Density Hybrid Experiment
801 Plot for Electron Density Hybrid Experiment
802 '''
802 '''
803
803
804 CODE = 'denLP'
804 CODE = 'denLP'
805 plot_name = 'Electron Density'
805 plot_name = 'Electron Density'
806 plot_type = 'scatterbuffer'
806 plot_type = 'scatterbuffer'
807
807
808 def update(self, dataOut):
808 def update(self, dataOut):
809 data = {}
809 data = {}
810 meta = {}
810 meta = {}
811
811
812 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
812 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
813 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
813 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
814 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
814 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
815 data['den_LP']=dataOut.ne[:dataOut.NACF]
815 data['den_LP']=dataOut.ne[:dataOut.NACF]
816 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
816 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
817 #self.ene=10**dataOut.ene[:dataOut.NACF]
817 #self.ene=10**dataOut.ene[:dataOut.NACF]
818 data['NSHTS']=dataOut.NSHTS
818 data['NSHTS']=dataOut.NSHTS
819 data['cut']=dataOut.cut
819 data['cut']=dataOut.cut
820
820
821 return data, meta
821 return data, meta
822
822
823
823
824 class ACFsPlot(Plot):
824 class ACFsPlot(Plot):
825 '''
825 '''
826 Plot for ACFs Double Pulse Experiment
826 Plot for ACFs Double Pulse Experiment
827 '''
827 '''
828
828
829 CODE = 'acfs'
829 CODE = 'acfs'
830 #plot_name = 'ACF'
830 #plot_name = 'ACF'
831 plot_type = 'scatterbuffer'
831 plot_type = 'scatterbuffer'
832
832
833
833
834 def setup(self):
834 def setup(self):
835 self.ncols = 1
835 self.ncols = 1
836 self.nrows = 1
836 self.nrows = 1
837 self.nplots = 1
837 self.nplots = 1
838 self.ylabel = 'Range [km]'
838 self.ylabel = 'Range [km]'
839 self.xlabel = 'Lag (ms)'
839 self.xlabel = 'Lag (ms)'
840 self.titles = ['ACFs']
840 self.titles = ['ACFs']
841 self.width = 3.5
841 self.width = 3.5
842 self.height = 5.5
842 self.height = 5.5
843 self.colorbar = False
843 self.colorbar = False
844 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
844 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
845
845
846 def update(self, dataOut):
846 def update(self, dataOut):
847 data = {}
847 data = {}
848 meta = {}
848 meta = {}
849
849
850 data['ACFs'] = dataOut.acfs_to_plot
850 data['ACFs'] = dataOut.acfs_to_plot
851 data['ACFs_error'] = dataOut.acfs_error_to_plot
851 data['ACFs_error'] = dataOut.acfs_error_to_plot
852 data['lags'] = dataOut.lags_to_plot
852 data['lags'] = dataOut.lags_to_plot
853 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
853 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
854 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
854 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
855 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
855 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
856 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
856 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
857
857
858 meta['yrange'] = numpy.array([])
858 meta['yrange'] = numpy.array([])
859 #meta['NSHTS'] = dataOut.NSHTS
859 #meta['NSHTS'] = dataOut.NSHTS
860 #meta['DPL'] = dataOut.DPL
860 #meta['DPL'] = dataOut.DPL
861 data['NSHTS'] = dataOut.NSHTS #This is metadata
861 data['NSHTS'] = dataOut.NSHTS #This is metadata
862 data['DPL'] = dataOut.DPL #This is metadata
862 data['DPL'] = dataOut.DPL #This is metadata
863
863
864 return data, meta
864 return data, meta
865
865
866 def plot(self):
866 def plot(self):
867
867
868 data = self.data[-1]
868 data = self.data[-1]
869 #NSHTS = self.meta['NSHTS']
869 #NSHTS = self.meta['NSHTS']
870 #DPL = self.meta['DPL']
870 #DPL = self.meta['DPL']
871 NSHTS = data['NSHTS'] #This is metadata
871 NSHTS = data['NSHTS'] #This is metadata
872 DPL = data['DPL'] #This is metadata
872 DPL = data['DPL'] #This is metadata
873
873
874 lags = data['lags']
874 lags = data['lags']
875 ACFs = data['ACFs']
875 ACFs = data['ACFs']
876 errACFs = data['ACFs_error']
876 errACFs = data['ACFs_error']
877 BadLag1 = data['Lag_contaminated_1']
877 BadLag1 = data['Lag_contaminated_1']
878 BadLag2 = data['Lag_contaminated_2']
878 BadLag2 = data['Lag_contaminated_2']
879 BadHei1 = data['Height_contaminated_1']
879 BadHei1 = data['Height_contaminated_1']
880 BadHei2 = data['Height_contaminated_2']
880 BadHei2 = data['Height_contaminated_2']
881
881
882 self.xmin = 0.0
882 self.xmin = 0.0
883 self.xmax = 2.0
883 self.xmax = 2.0
884 self.y = ACFs
884 self.y = ACFs
885
885
886 ax = self.axes[0]
886 ax = self.axes[0]
887
887
888 if ax.firsttime:
888 if ax.firsttime:
889
889
890 for i in range(NSHTS):
890 for i in range(NSHTS):
891 x_aux = numpy.isfinite(lags[i,:])
891 x_aux = numpy.isfinite(lags[i,:])
892 y_aux = numpy.isfinite(ACFs[i,:])
892 y_aux = numpy.isfinite(ACFs[i,:])
893 yerr_aux = numpy.isfinite(errACFs[i,:])
893 yerr_aux = numpy.isfinite(errACFs[i,:])
894 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
894 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
895 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
895 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
896 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
896 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
897 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
897 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
898 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
898 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
899 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
899 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
900 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
900 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
901 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
901 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
902
902
903 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
903 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
904 self.ystep_given = 50
904 self.ystep_given = 50
905 ax.yaxis.set_minor_locator(MultipleLocator(15))
905 ax.yaxis.set_minor_locator(MultipleLocator(15))
906 ax.grid(which='minor')
906 ax.grid(which='minor')
907
907
908 else:
908 else:
909 self.clear_figures()
909 self.clear_figures()
910 for i in range(NSHTS):
910 for i in range(NSHTS):
911 x_aux = numpy.isfinite(lags[i,:])
911 x_aux = numpy.isfinite(lags[i,:])
912 y_aux = numpy.isfinite(ACFs[i,:])
912 y_aux = numpy.isfinite(ACFs[i,:])
913 yerr_aux = numpy.isfinite(errACFs[i,:])
913 yerr_aux = numpy.isfinite(errACFs[i,:])
914 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
914 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
915 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
915 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
916 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
916 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
917 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
917 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
918 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
918 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
919 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
919 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
920 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
920 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
921 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
921 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
922 ax.yaxis.set_minor_locator(MultipleLocator(15))
922 ax.yaxis.set_minor_locator(MultipleLocator(15))
923
923
924 class ACFsLPPlot(Plot):
924 class ACFsLPPlot(Plot):
925 '''
925 '''
926 Plot for ACFs Double Pulse Experiment
926 Plot for ACFs Double Pulse Experiment
927 '''
927 '''
928
928
929 CODE = 'acfs_LP'
929 CODE = 'acfs_LP'
930 #plot_name = 'ACF'
930 #plot_name = 'ACF'
931 plot_type = 'scatterbuffer'
931 plot_type = 'scatterbuffer'
932
932
933
933
934 def setup(self):
934 def setup(self):
935 self.ncols = 1
935 self.ncols = 1
936 self.nrows = 1
936 self.nrows = 1
937 self.nplots = 1
937 self.nplots = 1
938 self.ylabel = 'Range [km]'
938 self.ylabel = 'Range [km]'
939 self.xlabel = 'Lag (ms)'
939 self.xlabel = 'Lag (ms)'
940 self.titles = ['ACFs']
940 self.titles = ['ACFs']
941 self.width = 3.5
941 self.width = 3.5
942 self.height = 5.5
942 self.height = 5.5
943 self.colorbar = False
943 self.colorbar = False
944 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
944 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
945
945
946 def update(self, dataOut):
946 def update(self, dataOut):
947 data = {}
947 data = {}
948 meta = {}
948 meta = {}
949
949
950 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
950 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
951 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
951 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
952 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
952 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
953
953
954 for i in range(dataOut.NACF):
954 for i in range(dataOut.NACF):
955 for j in range(dataOut.IBITS):
955 for j in range(dataOut.IBITS):
956 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
956 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
957 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
957 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
958 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
958 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
959 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
959 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
960 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
960 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
961 else:
961 else:
962 aux[i,j]=numpy.nan
962 aux[i,j]=numpy.nan
963 lags_LP_to_plot[i,j]=numpy.nan
963 lags_LP_to_plot[i,j]=numpy.nan
964 errors[i,j]=numpy.nan
964 errors[i,j]=numpy.nan
965
965
966 data['ACFs'] = aux
966 data['ACFs'] = aux
967 data['ACFs_error'] = errors
967 data['ACFs_error'] = errors
968 data['lags'] = lags_LP_to_plot
968 data['lags'] = lags_LP_to_plot
969
969
970 meta['yrange'] = numpy.array([])
970 meta['yrange'] = numpy.array([])
971 #meta['NACF'] = dataOut.NACF
971 #meta['NACF'] = dataOut.NACF
972 #meta['NLAG'] = dataOut.NLAG
972 #meta['NLAG'] = dataOut.NLAG
973 data['NACF'] = dataOut.NACF #This is metadata
973 data['NACF'] = dataOut.NACF #This is metadata
974 data['NLAG'] = dataOut.NLAG #This is metadata
974 data['NLAG'] = dataOut.NLAG #This is metadata
975
975
976 return data, meta
976 return data, meta
977
977
978 def plot(self):
978 def plot(self):
979
979
980 data = self.data[-1]
980 data = self.data[-1]
981 #NACF = self.meta['NACF']
981 #NACF = self.meta['NACF']
982 #NLAG = self.meta['NLAG']
982 #NLAG = self.meta['NLAG']
983 NACF = data['NACF'] #This is metadata
983 NACF = data['NACF'] #This is metadata
984 NLAG = data['NLAG'] #This is metadata
984 NLAG = data['NLAG'] #This is metadata
985
985
986 lags = data['lags']
986 lags = data['lags']
987 ACFs = data['ACFs']
987 ACFs = data['ACFs']
988 errACFs = data['ACFs_error']
988 errACFs = data['ACFs_error']
989
989
990 self.xmin = 0.0
990 self.xmin = 0.0
991 self.xmax = 1.5
991 self.xmax = 1.5
992
992
993 self.y = ACFs
993 self.y = ACFs
994
994
995 ax = self.axes[0]
995 ax = self.axes[0]
996
996
997 if ax.firsttime:
997 if ax.firsttime:
998
998
999 for i in range(NACF):
999 for i in range(NACF):
1000 x_aux = numpy.isfinite(lags[i,:])
1000 x_aux = numpy.isfinite(lags[i,:])
1001 y_aux = numpy.isfinite(ACFs[i,:])
1001 y_aux = numpy.isfinite(ACFs[i,:])
1002 yerr_aux = numpy.isfinite(errACFs[i,:])
1002 yerr_aux = numpy.isfinite(errACFs[i,:])
1003
1003
1004 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1004 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1005 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1005 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1006
1006
1007 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1007 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1008 self.xstep_given=0.3
1008 self.xstep_given=0.3
1009 self.ystep_given = 200
1009 self.ystep_given = 200
1010 ax.yaxis.set_minor_locator(MultipleLocator(15))
1010 ax.yaxis.set_minor_locator(MultipleLocator(15))
1011 ax.grid(which='minor')
1011 ax.grid(which='minor')
1012
1012
1013 else:
1013 else:
1014 self.clear_figures()
1014 self.clear_figures()
1015
1015
1016 for i in range(NACF):
1016 for i in range(NACF):
1017 x_aux = numpy.isfinite(lags[i,:])
1017 x_aux = numpy.isfinite(lags[i,:])
1018 y_aux = numpy.isfinite(ACFs[i,:])
1018 y_aux = numpy.isfinite(ACFs[i,:])
1019 yerr_aux = numpy.isfinite(errACFs[i,:])
1019 yerr_aux = numpy.isfinite(errACFs[i,:])
1020
1020
1021 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1021 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1022 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1022 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1023
1023
1024 ax.yaxis.set_minor_locator(MultipleLocator(15))
1024 ax.yaxis.set_minor_locator(MultipleLocator(15))
1025
1025
1026
1026
1027 class CrossProductsPlot(Plot):
1027 class CrossProductsPlot(Plot):
1028 '''
1028 '''
1029 Plot for cross products
1029 Plot for cross products
1030 '''
1030 '''
1031
1031
1032 CODE = 'crossprod'
1032 CODE = 'crossprod'
1033 plot_name = 'Cross Products'
1033 plot_name = 'Cross Products'
1034 plot_type = 'scatterbuffer'
1034 plot_type = 'scatterbuffer'
1035
1035
1036 def setup(self):
1036 def setup(self):
1037
1037
1038 self.ncols = 3
1038 self.ncols = 3
1039 self.nrows = 1
1039 self.nrows = 1
1040 self.nplots = 3
1040 self.nplots = 3
1041 self.ylabel = 'Range [km]'
1041 self.ylabel = 'Range [km]'
1042 self.titles = []
1042 self.titles = []
1043 self.width = 3.5*self.nplots
1043 self.width = 3.5*self.nplots
1044 self.height = 5.5
1044 self.height = 5.5
1045 self.colorbar = False
1045 self.colorbar = False
1046 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1046 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1047
1047
1048
1048
1049 def update(self, dataOut):
1049 def update(self, dataOut):
1050
1050
1051 data = {}
1051 data = {}
1052 meta = {}
1052 meta = {}
1053
1053
1054 data['crossprod'] = dataOut.crossprods
1054 data['crossprod'] = dataOut.crossprods
1055 data['NDP'] = dataOut.NDP
1055 data['NDP'] = dataOut.NDP
1056
1056
1057 return data, meta
1057 return data, meta
1058
1058
1059 def plot(self):
1059 def plot(self):
1060
1060
1061 NDP = self.data['NDP'][-1]
1061 NDP = self.data['NDP'][-1]
1062 x = self.data['crossprod'][:,-1,:,:,:,:]
1062 x = self.data['crossprod'][:,-1,:,:,:,:]
1063 y = self.data.yrange[0:NDP]
1063 y = self.data.yrange[0:NDP]
1064
1064
1065 for n, ax in enumerate(self.axes):
1065 for n, ax in enumerate(self.axes):
1066
1066
1067 self.xmin=numpy.min(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1067 self.xmin=numpy.min(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1068 self.xmax=numpy.max(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1068 self.xmax=numpy.max(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1069
1069
1070 if ax.firsttime:
1070 if ax.firsttime:
1071
1071
1072 self.autoxticks=False
1072 self.autoxticks=False
1073 if n==0:
1073 if n==0:
1074 label1='kax'
1074 label1='kax'
1075 label2='kay'
1075 label2='kay'
1076 label3='kbx'
1076 label3='kbx'
1077 label4='kby'
1077 label4='kby'
1078 self.xlimits=[(self.xmin,self.xmax)]
1078 self.xlimits=[(self.xmin,self.xmax)]
1079 elif n==1:
1079 elif n==1:
1080 label1='kax2'
1080 label1='kax2'
1081 label2='kay2'
1081 label2='kay2'
1082 label3='kbx2'
1082 label3='kbx2'
1083 label4='kby2'
1083 label4='kby2'
1084 self.xlimits.append((self.xmin,self.xmax))
1084 self.xlimits.append((self.xmin,self.xmax))
1085 elif n==2:
1085 elif n==2:
1086 label1='kaxay'
1086 label1='kaxay'
1087 label2='kbxby'
1087 label2='kbxby'
1088 label3='kaxbx'
1088 label3='kaxbx'
1089 label4='kaxby'
1089 label4='kaxby'
1090 self.xlimits.append((self.xmin,self.xmax))
1090 self.xlimits.append((self.xmin,self.xmax))
1091
1091
1092 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1092 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1093 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1093 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1094 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1094 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1095 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1095 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1096 ax.legend(loc='upper right')
1096 ax.legend(loc='upper right')
1097 ax.set_xlim(self.xmin, self.xmax)
1097 ax.set_xlim(self.xmin, self.xmax)
1098 self.titles.append('{}'.format(self.plot_name.upper()))
1098 self.titles.append('{}'.format(self.plot_name.upper()))
1099
1099
1100 else:
1100 else:
1101
1101
1102 if n==0:
1102 if n==0:
1103 self.xlimits=[(self.xmin,self.xmax)]
1103 self.xlimits=[(self.xmin,self.xmax)]
1104 else:
1104 else:
1105 self.xlimits.append((self.xmin,self.xmax))
1105 self.xlimits.append((self.xmin,self.xmax))
1106
1106
1107 ax.set_xlim(self.xmin, self.xmax)
1107 ax.set_xlim(self.xmin, self.xmax)
1108
1108
1109 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1109 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1110 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1110 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1111 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1111 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1112 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1112 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1113 self.titles.append('{}'.format(self.plot_name.upper()))
1113 self.titles.append('{}'.format(self.plot_name.upper()))
1114
1114
1115
1115
1116 class CrossProductsLPPlot(Plot):
1116 class CrossProductsLPPlot(Plot):
1117 '''
1117 '''
1118 Plot for cross products LP
1118 Plot for cross products LP
1119 '''
1119 '''
1120
1120
1121 CODE = 'crossprodslp'
1121 CODE = 'crossprodslp'
1122 plot_name = 'Cross Products LP'
1122 plot_name = 'Cross Products LP'
1123 plot_type = 'scatterbuffer'
1123 plot_type = 'scatterbuffer'
1124
1124
1125
1125
1126 def setup(self):
1126 def setup(self):
1127
1127
1128 self.ncols = 2
1128 self.ncols = 2
1129 self.nrows = 1
1129 self.nrows = 1
1130 self.nplots = 2
1130 self.nplots = 2
1131 self.ylabel = 'Range [km]'
1131 self.ylabel = 'Range [km]'
1132 self.xlabel = 'dB'
1132 self.xlabel = 'dB'
1133 self.width = 3.5*self.nplots
1133 self.width = 3.5*self.nplots
1134 self.height = 5.5
1134 self.height = 5.5
1135 self.colorbar = False
1135 self.colorbar = False
1136 self.titles = []
1136 self.titles = []
1137 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1137 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1138
1138
1139 def update(self, dataOut):
1139 def update(self, dataOut):
1140 data = {}
1140 data = {}
1141 meta = {}
1141 meta = {}
1142
1142
1143 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1143 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1144
1144
1145 data['NRANGE'] = dataOut.NRANGE #This is metadata
1145 data['NRANGE'] = dataOut.NRANGE #This is metadata
1146 data['NLAG'] = dataOut.NLAG #This is metadata
1146 data['NLAG'] = dataOut.NLAG #This is metadata
1147
1147
1148 return data, meta
1148 return data, meta
1149
1149
1150 def plot(self):
1150 def plot(self):
1151
1151
1152 NRANGE = self.data['NRANGE'][-1]
1152 NRANGE = self.data['NRANGE'][-1]
1153 NLAG = self.data['NLAG'][-1]
1153 NLAG = self.data['NLAG'][-1]
1154
1154
1155 x = self.data[self.CODE][:,-1,:,:]
1155 x = self.data[self.CODE][:,-1,:,:]
1156 self.y = self.data.yrange[0:NRANGE]
1156 self.y = self.data.yrange[0:NRANGE]
1157
1157
1158 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1158 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1159 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1159 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1160
1160
1161
1161
1162 for n, ax in enumerate(self.axes):
1162 for n, ax in enumerate(self.axes):
1163
1163
1164 self.xmin=28#30
1164 self.xmin=28#30
1165 self.xmax=70#70
1165 self.xmax=70#70
1166 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1166 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1167 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1167 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1168
1168
1169 if ax.firsttime:
1169 if ax.firsttime:
1170
1170
1171 self.autoxticks=False
1171 self.autoxticks=False
1172 if n == 0:
1172 if n == 0:
1173 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1173 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1174
1174
1175 for i in range(NLAG):
1175 for i in range(NLAG):
1176 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1176 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1177
1177
1178 ax.legend(loc='upper right')
1178 ax.legend(loc='upper right')
1179 ax.set_xlim(self.xmin, self.xmax)
1179 ax.set_xlim(self.xmin, self.xmax)
1180 if n==0:
1180 if n==0:
1181 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1181 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1182 if n==1:
1182 if n==1:
1183 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1183 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1184 else:
1184 else:
1185 for i in range(NLAG):
1185 for i in range(NLAG):
1186 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1186 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1187
1187
1188 if n==0:
1188 if n==0:
1189 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1189 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1190 if n==1:
1190 if n==1:
1191 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1191 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1192
1192
1193
1193
1194 class NoiseDPPlot(NoisePlot):
1194 class NoiseDPPlot(NoisePlot):
1195 '''
1195 '''
1196 Plot for noise Double Pulse
1196 Plot for noise Double Pulse
1197 '''
1197 '''
1198
1198
1199 CODE = 'noise'
1199 CODE = 'noise'
1200 #plot_name = 'Noise'
1200 #plot_name = 'Noise'
1201 #plot_type = 'scatterbuffer'
1201 #plot_type = 'scatterbuffer'
1202
1202
1203 def update(self, dataOut):
1203 def update(self, dataOut):
1204
1204
1205 data = {}
1205 data = {}
1206 meta = {}
1206 meta = {}
1207 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1207 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1208
1208
1209 return data, meta
1209 return data, meta
1210
1210
1211
1211
1212 class XmitWaveformPlot(Plot):
1212 class XmitWaveformPlot(Plot):
1213 '''
1213 '''
1214 Plot for xmit waveform
1214 Plot for xmit waveform
1215 '''
1215 '''
1216
1216
1217 CODE = 'xmit'
1217 CODE = 'xmit'
1218 plot_name = 'Xmit Waveform'
1218 plot_name = 'Xmit Waveform'
1219 plot_type = 'scatterbuffer'
1219 plot_type = 'scatterbuffer'
1220
1220
1221
1221
1222 def setup(self):
1222 def setup(self):
1223
1223
1224 self.ncols = 1
1224 self.ncols = 1
1225 self.nrows = 1
1225 self.nrows = 1
1226 self.nplots = 1
1226 self.nplots = 1
1227 self.ylabel = ''
1227 self.ylabel = ''
1228 self.xlabel = 'Number of Lag'
1228 self.xlabel = 'Number of Lag'
1229 self.width = 5.5
1229 self.width = 5.5
1230 self.height = 3.5
1230 self.height = 3.5
1231 self.colorbar = False
1231 self.colorbar = False
1232 self.plots_adjust.update({'right': 0.85 })
1232 self.plots_adjust.update({'right': 0.85 })
1233 self.titles = [self.plot_name]
1233 self.titles = [self.plot_name]
1234 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1234 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1235
1235
1236 #if not self.titles:
1236 #if not self.titles:
1237 #self.titles = self.data.parameters \
1237 #self.titles = self.data.parameters \
1238 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1238 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1239
1239
1240 def update(self, dataOut):
1240 def update(self, dataOut):
1241
1241
1242 data = {}
1242 data = {}
1243 meta = {}
1243 meta = {}
1244
1244
1245 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1245 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1246 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1246 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1247 norm=numpy.max(y_2)
1247 norm=numpy.max(y_2)
1248 norm=max(norm,0.1)
1248 norm=max(norm,0.1)
1249 y_2=y_2/norm
1249 y_2=y_2/norm
1250
1250
1251 meta['yrange'] = numpy.array([])
1251 meta['yrange'] = numpy.array([])
1252
1252
1253 data['xmit'] = numpy.vstack((y_1,y_2))
1253 data['xmit'] = numpy.vstack((y_1,y_2))
1254 data['NLAG'] = dataOut.NLAG
1254 data['NLAG'] = dataOut.NLAG
1255
1255
1256 return data, meta
1256 return data, meta
1257
1257
1258 def plot(self):
1258 def plot(self):
1259
1259
1260 data = self.data[-1]
1260 data = self.data[-1]
1261 NLAG = data['NLAG']
1261 NLAG = data['NLAG']
1262 x = numpy.arange(0,NLAG,1,'float32')
1262 x = numpy.arange(0,NLAG,1,'float32')
1263 y = data['xmit']
1263 y = data['xmit']
1264
1264
1265 self.xmin = 0
1265 self.xmin = 0
1266 self.xmax = NLAG-1
1266 self.xmax = NLAG-1
1267 self.ymin = -1.0
1267 self.ymin = -1.0
1268 self.ymax = 1.0
1268 self.ymax = 1.0
1269 ax = self.axes[0]
1269 ax = self.axes[0]
1270
1270
1271 if ax.firsttime:
1271 if ax.firsttime:
1272 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1272 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1273 ax.plotline1=ax.plot(x,y[1,:],color='red')
1273 ax.plotline1=ax.plot(x,y[1,:],color='red')
1274 secax=ax.secondary_xaxis(location=0.5)
1274 secax=ax.secondary_xaxis(location=0.5)
1275 secax.xaxis.tick_bottom()
1275 secax.xaxis.tick_bottom()
1276 secax.tick_params( labelleft=False, labeltop=False,
1276 secax.tick_params( labelleft=False, labeltop=False,
1277 labelright=False, labelbottom=False)
1277 labelright=False, labelbottom=False)
1278
1278
1279 self.xstep_given = 3
1279 self.xstep_given = 3
1280 self.ystep_given = .25
1280 self.ystep_given = .25
1281 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1281 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1282
1282
1283 else:
1283 else:
1284 ax.plotline0[0].set_data(x,y[0,:])
1284 ax.plotline0[0].set_data(x,y[0,:])
1285 ax.plotline1[0].set_data(x,y[1,:])
1285 ax.plotline1[0].set_data(x,y[1,:])
@@ -1,251 +1,252
1 '''
1 '''
2 Base clases to create Processing units and operations, the MPDecorator
2 Base clases to create Processing units and operations, the MPDecorator
3 must be used in plotting and writing operations to allow to run as an
3 must be used in plotting and writing operations to allow to run as an
4 external process.
4 external process.
5 '''
5 '''
6
6
7 import os
7 import os
8 import inspect
8 import inspect
9 import zmq
9 import zmq
10 import time
10 import time
11 import pickle
11 import pickle
12 import traceback
12 import traceback
13 from threading import Thread
13 from threading import Thread
14 from multiprocessing import Process, Queue
14 from multiprocessing import Process, Queue
15 from schainpy.utils import log
15 from schainpy.utils import log
16
16
17 import copy
17 import copy
18
18
19 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
19 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
20
20
21 class ProcessingUnit(object):
21 class ProcessingUnit(object):
22 '''
22 '''
23 Base class to create Signal Chain Units
23 Base class to create Signal Chain Units
24 '''
24 '''
25
25
26 proc_type = 'processing'
26 proc_type = 'processing'
27
27
28 def __init__(self):
28 def __init__(self):
29
29
30 self.dataIn = None
30 self.dataIn = None
31 self.dataOut = None
31 self.dataOut = None
32 self.isConfig = False
32 self.isConfig = False
33 self.operations = []
33 self.operations = []
34 self.name = 'Test'
34 self.name = 'Test'
35 self.inputs = []
35 self.inputs = []
36
36
37 def setInput(self, unit):
37 def setInput(self, unit):
38
38
39 attr = 'dataIn'
39 attr = 'dataIn'
40 for i, u in enumerate(unit):
40 for i, u in enumerate(unit):
41 if i==0:
41 if i==0:
42 #print(u.dataOut.flagNoData)
42 #print(u.dataOut.flagNoData)
43 #exit(1)
43 #exit(1)
44 self.dataIn = u.dataOut#.copy()
44 self.dataIn = u.dataOut#.copy()
45 self.inputs.append('dataIn')
45 self.inputs.append('dataIn')
46 else:
46 else:
47 setattr(self, 'dataIn{}'.format(i), u.dataOut)#.copy())
47 setattr(self, 'dataIn{}'.format(i), u.dataOut)#.copy())
48 self.inputs.append('dataIn{}'.format(i))
48 self.inputs.append('dataIn{}'.format(i))
49
49
50
50
51 def getAllowedArgs(self):
51 def getAllowedArgs(self):
52 if hasattr(self, '__attrs__'):
52 if hasattr(self, '__attrs__'):
53 return self.__attrs__
53 return self.__attrs__
54 else:
54 else:
55 return inspect.getargspec(self.run).args
55 return inspect.getargspec(self.run).args
56
56
57 def addOperation(self, conf, operation):
57 def addOperation(self, conf, operation):
58 '''
58 '''
59 '''
59 '''
60
60
61 self.operations.append((operation, conf.type, conf.getKwargs()))
61 self.operations.append((operation, conf.type, conf.getKwargs()))
62
62
63 def getOperationObj(self, objId):
63 def getOperationObj(self, objId):
64
64
65 if objId not in list(self.operations.keys()):
65 if objId not in list(self.operations.keys()):
66 return None
66 return None
67
67
68 return self.operations[objId]
68 return self.operations[objId]
69
69
70 def call(self, **kwargs):
70 def call(self, **kwargs):
71 '''
71 '''
72 '''
72 '''
73 #print("call")
73
74 try:
74 try:
75 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
75 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
76 #if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error and not self.dataIn.runNextUnit:
76 #if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error and not self.dataIn.runNextUnit:
77 if self.dataIn.runNextUnit:
77 if self.dataIn.runNextUnit:
78 #print("SUCCESSSSSSS")
78 #print("SUCCESSSSSSS")
79 #exit(1)
79 #exit(1)
80 return not self.dataIn.isReady()
80 return not self.dataIn.isReady()
81 else:
81 else:
82 return self.dataIn.isReady()
82 return self.dataIn.isReady()
83 elif self.dataIn is None or not self.dataIn.error:
83 elif self.dataIn is None or not self.dataIn.error:
84 #print([getattr(self, at) for at in self.inputs])
84 #print([getattr(self, at) for at in self.inputs])
85 #print("Elif 1")
85 #print("Elif 1")
86 self.run(**kwargs)
86 self.run(**kwargs)
87 elif self.dataIn.error:
87 elif self.dataIn.error:
88 #print("Elif 2")
88 #print("Elif 2")
89 self.dataOut.error = self.dataIn.error
89 self.dataOut.error = self.dataIn.error
90 self.dataOut.flagNoData = True
90 self.dataOut.flagNoData = True
91 except:
91 except:
92 #print("Except")
92 #print("Except")
93 err = traceback.format_exc()
93 err = traceback.format_exc()
94 if 'SchainWarning' in err:
94 if 'SchainWarning' in err:
95 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
95 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
96 elif 'SchainError' in err:
96 elif 'SchainError' in err:
97 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
97 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
98 else:
98 else:
99 log.error(err, self.name)
99 log.error(err, self.name)
100 self.dataOut.error = True
100 self.dataOut.error = True
101 #print("before op")
101 #print("before op")
102 for op, optype, opkwargs in self.operations:
102 for op, optype, opkwargs in self.operations:
103 aux = self.dataOut.copy()
103 aux = self.dataOut.copy()
104 #aux = copy.deepcopy(self.dataOut)
104 #aux = copy.deepcopy(self.dataOut)
105 #print("**********************Before",op)
105 #print("**********************Before",op)
106 if optype == 'other' and not self.dataOut.flagNoData:
106 if optype == 'other' and not self.dataOut.flagNoData:
107 #print("**********************Other",op)
107 #print("**********************Other",op)
108 #print(self.dataOut.flagNoData)
108 #print(self.dataOut.flagNoData)
109 self.dataOut = op.run(self.dataOut, **opkwargs)
109 self.dataOut = op.run(self.dataOut, **opkwargs)
110 elif optype == 'external' and not self.dataOut.flagNoData:
110 elif optype == 'external' and not self.dataOut.flagNoData:
111 op.queue.put(aux)
111 op.queue.put(aux)
112 elif optype == 'external' and self.dataOut.error:
112 elif optype == 'external' and self.dataOut.error:
113 op.queue.put(aux)
113 op.queue.put(aux)
114 #elif optype == 'external' and self.dataOut.isReady():
114 #elif optype == 'external' and self.dataOut.isReady():
115 #op.queue.put(copy.deepcopy(self.dataOut))
115 #op.queue.put(copy.deepcopy(self.dataOut))
116 #print(not self.dataOut.isReady())
116 #print(not self.dataOut.isReady())
117
117
118 try:
118 try:
119 if self.dataOut.runNextUnit:
119 if self.dataOut.runNextUnit:
120 runNextUnit = self.dataOut.runNextUnit
120 runNextUnit = self.dataOut.runNextUnit
121 #print(self.operations)
121 #print(self.operations)
122 #print("Tru")
122 #print("Tru")
123
123
124 else:
124 else:
125 runNextUnit = self.dataOut.isReady()
125 runNextUnit = self.dataOut.isReady()
126 except:
126 except:
127 runNextUnit = self.dataOut.isReady()
127 runNextUnit = self.dataOut.isReady()
128 #exit(1)
128 #if not self.dataOut.isReady():
129 #if not self.dataOut.isReady():
129 #return 'Error' if self.dataOut.error else input()
130 #return 'Error' if self.dataOut.error else input()
130 #print("NexT",runNextUnit)
131 #print("NexT",runNextUnit)
131 #print("error: ",self.dataOut.error)
132 #print("error: ",self.dataOut.error)
132 return 'Error' if self.dataOut.error else runNextUnit# self.dataOut.isReady()
133 return 'Error' if self.dataOut.error else runNextUnit# self.dataOut.isReady()
133
134
134 def setup(self):
135 def setup(self):
135
136
136 raise NotImplementedError
137 raise NotImplementedError
137
138
138 def run(self):
139 def run(self):
139
140
140 raise NotImplementedError
141 raise NotImplementedError
141
142
142 def close(self):
143 def close(self):
143
144
144 return
145 return
145
146
146
147
147 class Operation(object):
148 class Operation(object):
148
149
149 '''
150 '''
150 '''
151 '''
151
152
152 proc_type = 'operation'
153 proc_type = 'operation'
153
154
154 def __init__(self):
155 def __init__(self):
155
156
156 self.id = None
157 self.id = None
157 self.isConfig = False
158 self.isConfig = False
158
159
159 if not hasattr(self, 'name'):
160 if not hasattr(self, 'name'):
160 self.name = self.__class__.__name__
161 self.name = self.__class__.__name__
161
162
162 def getAllowedArgs(self):
163 def getAllowedArgs(self):
163 if hasattr(self, '__attrs__'):
164 if hasattr(self, '__attrs__'):
164 return self.__attrs__
165 return self.__attrs__
165 else:
166 else:
166 return inspect.getargspec(self.run).args
167 return inspect.getargspec(self.run).args
167
168
168 def setup(self):
169 def setup(self):
169
170
170 self.isConfig = True
171 self.isConfig = True
171
172
172 raise NotImplementedError
173 raise NotImplementedError
173
174
174 def run(self, dataIn, **kwargs):
175 def run(self, dataIn, **kwargs):
175 """
176 """
176 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
177 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
177 atributos del objeto dataIn.
178 atributos del objeto dataIn.
178
179
179 Input:
180 Input:
180
181
181 dataIn : objeto del tipo JROData
182 dataIn : objeto del tipo JROData
182
183
183 Return:
184 Return:
184
185
185 None
186 None
186
187
187 Affected:
188 Affected:
188 __buffer : buffer de recepcion de datos.
189 __buffer : buffer de recepcion de datos.
189
190
190 """
191 """
191 if not self.isConfig:
192 if not self.isConfig:
192 self.setup(**kwargs)
193 self.setup(**kwargs)
193
194
194 raise NotImplementedError
195 raise NotImplementedError
195
196
196 def close(self):
197 def close(self):
197
198
198 return
199 return
199
200
200
201
201 def MPDecorator(BaseClass):
202 def MPDecorator(BaseClass):
202 """
203 """
203 Multiprocessing class decorator
204 Multiprocessing class decorator
204
205
205 This function add multiprocessing features to a BaseClass.
206 This function add multiprocessing features to a BaseClass.
206 """
207 """
207
208
208 class MPClass(BaseClass, Process):
209 class MPClass(BaseClass, Process):
209
210
210 def __init__(self, *args, **kwargs):
211 def __init__(self, *args, **kwargs):
211 super(MPClass, self).__init__()
212 super(MPClass, self).__init__()
212 Process.__init__(self)
213 Process.__init__(self)
213
214
214 self.args = args
215 self.args = args
215 self.kwargs = kwargs
216 self.kwargs = kwargs
216 self.t = time.time()
217 self.t = time.time()
217 self.op_type = 'external'
218 self.op_type = 'external'
218 self.name = BaseClass.__name__
219 self.name = BaseClass.__name__
219 self.__doc__ = BaseClass.__doc__
220 self.__doc__ = BaseClass.__doc__
220
221
221 if 'plot' in self.name.lower() and not self.name.endswith('_'):
222 if 'plot' in self.name.lower() and not self.name.endswith('_'):
222 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
223 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
223
224
224 self.start_time = time.time()
225 self.start_time = time.time()
225 self.err_queue = args[3]
226 self.err_queue = args[3]
226 self.queue = Queue(maxsize=QUEUE_SIZE)
227 self.queue = Queue(maxsize=QUEUE_SIZE)
227 self.myrun = BaseClass.run
228 self.myrun = BaseClass.run
228
229
229 def run(self):
230 def run(self):
230
231
231 while True:
232 while True:
232
233
233 dataOut = self.queue.get()
234 dataOut = self.queue.get()
234
235
235 if not dataOut.error:
236 if not dataOut.error:
236 try:
237 try:
237 BaseClass.run(self, dataOut, **self.kwargs)
238 BaseClass.run(self, dataOut, **self.kwargs)
238 except:
239 except:
239 err = traceback.format_exc()
240 err = traceback.format_exc()
240 log.error(err, self.name)
241 log.error(err, self.name)
241 else:
242 else:
242 break
243 break
243
244
244 self.close()
245 self.close()
245
246
246 def close(self):
247 def close(self):
247
248
248 BaseClass.close(self)
249 BaseClass.close(self)
249 log.success('Done...(Time:{:4.2f} secs)'.format(time.time() - self.start_time), self.name)
250 log.success('Done...(Time:{:4.2f} secs)'.format(time.time() - self.start_time), self.name)
250
251
251 return MPClass
252 return MPClass
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,910 +1,957
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Spectra processing Unit and operations
5 """Spectra processing Unit and operations
6
6
7 Here you will find the processing unit `SpectraProc` and several operations
7 Here you will find the processing unit `SpectraProc` and several operations
8 to work with Spectra data type
8 to work with Spectra data type
9 """
9 """
10
10
11 import time
11 import time
12 import itertools
12 import itertools
13
13
14 import numpy
14 import numpy
15
15
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
17 from schainpy.model.data.jrodata import Spectra
17 from schainpy.model.data.jrodata import Spectra
18 from schainpy.model.data.jrodata import hildebrand_sekhon
18 from schainpy.model.data.jrodata import hildebrand_sekhon
19 from schainpy.utils import log
19 from schainpy.utils import log
20
20
21
21
22 class SpectraProc(ProcessingUnit):
22 class SpectraProc(ProcessingUnit):
23
23
24 def __init__(self):
24 def __init__(self):
25
25
26 ProcessingUnit.__init__(self)
26 ProcessingUnit.__init__(self)
27
27
28 self.buffer = None
28 self.buffer = None
29 self.firstdatatime = None
29 self.firstdatatime = None
30 self.profIndex = 0
30 self.profIndex = 0
31 self.dataOut = Spectra()
31 self.dataOut = Spectra()
32 self.id_min = None
32 self.id_min = None
33 self.id_max = None
33 self.id_max = None
34 self.setupReq = False #Agregar a todas las unidades de proc
34 self.setupReq = False #Agregar a todas las unidades de proc
35
35
36 def __updateSpecFromVoltage(self):
36 def __updateSpecFromVoltage(self):
37
37
38 self.dataOut.timeZone = self.dataIn.timeZone
38 self.dataOut.timeZone = self.dataIn.timeZone
39 self.dataOut.dstFlag = self.dataIn.dstFlag
39 self.dataOut.dstFlag = self.dataIn.dstFlag
40 self.dataOut.errorCount = self.dataIn.errorCount
40 self.dataOut.errorCount = self.dataIn.errorCount
41 self.dataOut.useLocalTime = self.dataIn.useLocalTime
41 self.dataOut.useLocalTime = self.dataIn.useLocalTime
42 try:
42 try:
43 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
43 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
44 except:
44 except:
45 pass
45 pass
46 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
46 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
47 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
47 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
48 self.dataOut.channelList = self.dataIn.channelList
48 self.dataOut.channelList = self.dataIn.channelList
49 self.dataOut.heightList = self.dataIn.heightList
49 self.dataOut.heightList = self.dataIn.heightList
50 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
50 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
51 self.dataOut.nProfiles = self.dataOut.nFFTPoints
51 self.dataOut.nProfiles = self.dataOut.nFFTPoints
52 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
52 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
53 self.dataOut.utctime = self.firstdatatime
53 self.dataOut.utctime = self.firstdatatime
54 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
54 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
55 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
55 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
56 self.dataOut.flagShiftFFT = False
56 self.dataOut.flagShiftFFT = False
57 self.dataOut.nCohInt = self.dataIn.nCohInt
57 self.dataOut.nCohInt = self.dataIn.nCohInt
58 self.dataOut.nIncohInt = 1
58 self.dataOut.nIncohInt = 1
59 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
59 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
60 self.dataOut.frequency = self.dataIn.frequency
60 self.dataOut.frequency = self.dataIn.frequency
61 self.dataOut.realtime = self.dataIn.realtime
61 self.dataOut.realtime = self.dataIn.realtime
62 self.dataOut.azimuth = self.dataIn.azimuth
62 self.dataOut.azimuth = self.dataIn.azimuth
63 self.dataOut.zenith = self.dataIn.zenith
63 self.dataOut.zenith = self.dataIn.zenith
64 self.dataOut.beam.codeList = self.dataIn.beam.codeList
64 self.dataOut.beam.codeList = self.dataIn.beam.codeList
65 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
65 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
66 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
66 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
67 self.dataOut.runNextUnit = self.dataIn.runNextUnit
67 self.dataOut.runNextUnit = self.dataIn.runNextUnit
68 try:
68 try:
69 self.dataOut.step = self.dataIn.step
69 self.dataOut.step = self.dataIn.step
70 except:
70 except:
71 pass
71 pass
72
72
73 def __getFft(self):
73 def __getFft(self):
74 """
74 """
75 Convierte valores de Voltaje a Spectra
75 Convierte valores de Voltaje a Spectra
76
76
77 Affected:
77 Affected:
78 self.dataOut.data_spc
78 self.dataOut.data_spc
79 self.dataOut.data_cspc
79 self.dataOut.data_cspc
80 self.dataOut.data_dc
80 self.dataOut.data_dc
81 self.dataOut.heightList
81 self.dataOut.heightList
82 self.profIndex
82 self.profIndex
83 self.buffer
83 self.buffer
84 self.dataOut.flagNoData
84 self.dataOut.flagNoData
85 """
85 """
86 fft_volt = numpy.fft.fft(
86 fft_volt = numpy.fft.fft(
87 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
87 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
88 fft_volt = fft_volt.astype(numpy.dtype('complex'))
88 fft_volt = fft_volt.astype(numpy.dtype('complex'))
89 dc = fft_volt[:, 0, :]
89 dc = fft_volt[:, 0, :]
90
90
91 # calculo de self-spectra
91 # calculo de self-spectra
92 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
92 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
93 spc = fft_volt * numpy.conjugate(fft_volt)
93 spc = fft_volt * numpy.conjugate(fft_volt)
94 spc = spc.real
94 spc = spc.real
95
95
96 blocksize = 0
96 blocksize = 0
97 blocksize += dc.size
97 blocksize += dc.size
98 blocksize += spc.size
98 blocksize += spc.size
99
99
100 cspc = None
100 cspc = None
101 pairIndex = 0
101 pairIndex = 0
102 if self.dataOut.pairsList != None:
102 if self.dataOut.pairsList != None:
103 # calculo de cross-spectra
103 # calculo de cross-spectra
104 cspc = numpy.zeros(
104 cspc = numpy.zeros(
105 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
105 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
106 for pair in self.dataOut.pairsList:
106 for pair in self.dataOut.pairsList:
107 if pair[0] not in self.dataOut.channelList:
107 if pair[0] not in self.dataOut.channelList:
108 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
108 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
109 str(pair), str(self.dataOut.channelList)))
109 str(pair), str(self.dataOut.channelList)))
110 if pair[1] not in self.dataOut.channelList:
110 if pair[1] not in self.dataOut.channelList:
111 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
111 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
112 str(pair), str(self.dataOut.channelList)))
112 str(pair), str(self.dataOut.channelList)))
113
113
114 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
114 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
115 numpy.conjugate(fft_volt[pair[1], :, :])
115 numpy.conjugate(fft_volt[pair[1], :, :])
116 pairIndex += 1
116 pairIndex += 1
117 blocksize += cspc.size
117 blocksize += cspc.size
118
118
119 self.dataOut.data_spc = spc
119 self.dataOut.data_spc = spc
120 self.dataOut.data_cspc = cspc
120 self.dataOut.data_cspc = cspc
121 self.dataOut.data_dc = dc
121 self.dataOut.data_dc = dc
122 self.dataOut.blockSize = blocksize
122 self.dataOut.blockSize = blocksize
123 self.dataOut.flagShiftFFT = False
123 self.dataOut.flagShiftFFT = False
124
124
125 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False, runNextUnit = 0):
125 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False, runNextUnit = 0):
126
126
127 self.dataIn.runNextUnit = runNextUnit
127 self.dataIn.runNextUnit = runNextUnit
128 if self.dataIn.type == "Spectra":
128 if self.dataIn.type == "Spectra":
129
129 self.dataOut.copy(self.dataIn)
130 self.dataOut.copy(self.dataIn)
130 if shift_fft:
131 if shift_fft:
131 #desplaza a la derecha en el eje 2 determinadas posiciones
132 #desplaza a la derecha en el eje 2 determinadas posiciones
132 shift = int(self.dataOut.nFFTPoints/2)
133 shift = int(self.dataOut.nFFTPoints/2)
133 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
134 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
134
135
135 if self.dataOut.data_cspc is not None:
136 if self.dataOut.data_cspc is not None:
136 #desplaza a la derecha en el eje 2 determinadas posiciones
137 #desplaza a la derecha en el eje 2 determinadas posiciones
137 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
138 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
138 if pairsList:
139 if pairsList:
139 self.__selectPairs(pairsList)
140 self.__selectPairs(pairsList)
140
141
141 elif self.dataIn.type == "Voltage":
142 elif self.dataIn.type == "Voltage":
142
143
143 self.dataOut.flagNoData = True
144 self.dataOut.flagNoData = True
144
145
145 if nFFTPoints == None:
146 if nFFTPoints == None:
146 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
147 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
147
148
148 if nProfiles == None:
149 if nProfiles == None:
149 nProfiles = nFFTPoints
150 nProfiles = nFFTPoints
150
151 #print(self.dataOut.ipp)
152 #exit(1)
151 if ippFactor == None:
153 if ippFactor == None:
152 self.dataOut.ippFactor = 1
154 self.dataOut.ippFactor = 1
155 #if ippFactor is not None:
156 #self.dataOut.ippFactor = ippFactor
157 #print(ippFactor)
158 #print(self.dataOut.ippFactor)
159 #exit(1)
153
160
154 self.dataOut.nFFTPoints = nFFTPoints
161 self.dataOut.nFFTPoints = nFFTPoints
155
162
156 if self.buffer is None:
163 if self.buffer is None:
157 self.buffer = numpy.zeros((self.dataIn.nChannels,
164 self.buffer = numpy.zeros((self.dataIn.nChannels,
158 nProfiles,
165 nProfiles,
159 self.dataIn.nHeights),
166 self.dataIn.nHeights),
160 dtype='complex')
167 dtype='complex')
161
168
162 if self.dataIn.flagDataAsBlock:
169 if self.dataIn.flagDataAsBlock:
163 nVoltProfiles = self.dataIn.data.shape[1]
170 nVoltProfiles = self.dataIn.data.shape[1]
164
171
165 if nVoltProfiles == nProfiles:
172 if nVoltProfiles == nProfiles:
166 self.buffer = self.dataIn.data.copy()
173 self.buffer = self.dataIn.data.copy()
167 self.profIndex = nVoltProfiles
174 self.profIndex = nVoltProfiles
168
175
169 elif nVoltProfiles < nProfiles:
176 elif nVoltProfiles < nProfiles:
170
177
171 if self.profIndex == 0:
178 if self.profIndex == 0:
172 self.id_min = 0
179 self.id_min = 0
173 self.id_max = nVoltProfiles
180 self.id_max = nVoltProfiles
174 #print(self.id_min)
181 #print(self.id_min)
175 #print(self.id_max)
182 #print(self.id_max)
176 #print(numpy.shape(self.buffer))
183 #print(numpy.shape(self.buffer))
177 self.buffer[:, self.id_min:self.id_max,
184 self.buffer[:, self.id_min:self.id_max,
178 :] = self.dataIn.data
185 :] = self.dataIn.data
179 self.profIndex += nVoltProfiles
186 self.profIndex += nVoltProfiles
180 self.id_min += nVoltProfiles
187 self.id_min += nVoltProfiles
181 self.id_max += nVoltProfiles
188 self.id_max += nVoltProfiles
182 else:
189 else:
183 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
190 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
184 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
191 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
185 self.dataOut.flagNoData = True
192 self.dataOut.flagNoData = True
186 else:
193 else:
187 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
194 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
188 self.profIndex += 1
195 self.profIndex += 1
189
196
190 if self.firstdatatime == None:
197 if self.firstdatatime == None:
191 self.firstdatatime = self.dataIn.utctime
198 self.firstdatatime = self.dataIn.utctime
192
199
193 if self.profIndex == nProfiles:
200 if self.profIndex == nProfiles:
194 self.__updateSpecFromVoltage()
201 self.__updateSpecFromVoltage()
195 if pairsList == None:
202 if pairsList == None:
196 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
203 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
197 else:
204 else:
198 self.dataOut.pairsList = pairsList
205 self.dataOut.pairsList = pairsList
199 self.__getFft()
206 self.__getFft()
200 self.dataOut.flagNoData = False
207 self.dataOut.flagNoData = False
201 self.firstdatatime = None
208 self.firstdatatime = None
202 self.profIndex = 0
209 self.profIndex = 0
203 else:
210 else:
204 raise ValueError("The type of input object '%s' is not valid".format(
211 raise ValueError("The type of input object '%s' is not valid".format(
205 self.dataIn.type))
212 self.dataIn.type))
206
213
207
214
208 def __selectPairs(self, pairsList):
215 def __selectPairs(self, pairsList):
209
216
210 if not pairsList:
217 if not pairsList:
211 return
218 return
212
219
213 pairs = []
220 pairs = []
214 pairsIndex = []
221 pairsIndex = []
215
222
216 for pair in pairsList:
223 for pair in pairsList:
217 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
224 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
218 continue
225 continue
219 pairs.append(pair)
226 pairs.append(pair)
220 pairsIndex.append(pairs.index(pair))
227 pairsIndex.append(pairs.index(pair))
221
228
222 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
229 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
223 self.dataOut.pairsList = pairs
230 self.dataOut.pairsList = pairs
224
231
225 return
232 return
226
233
227 def selectFFTs(self, minFFT, maxFFT ):
234 def selectFFTs(self, minFFT, maxFFT ):
228 """
235 """
229 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
236 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
230 minFFT<= FFT <= maxFFT
237 minFFT<= FFT <= maxFFT
231 """
238 """
232
239
233 if (minFFT > maxFFT):
240 if (minFFT > maxFFT):
234 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
241 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
235
242
236 if (minFFT < self.dataOut.getFreqRange()[0]):
243 if (minFFT < self.dataOut.getFreqRange()[0]):
237 minFFT = self.dataOut.getFreqRange()[0]
244 minFFT = self.dataOut.getFreqRange()[0]
238
245
239 if (maxFFT > self.dataOut.getFreqRange()[-1]):
246 if (maxFFT > self.dataOut.getFreqRange()[-1]):
240 maxFFT = self.dataOut.getFreqRange()[-1]
247 maxFFT = self.dataOut.getFreqRange()[-1]
241
248
242 minIndex = 0
249 minIndex = 0
243 maxIndex = 0
250 maxIndex = 0
244 FFTs = self.dataOut.getFreqRange()
251 FFTs = self.dataOut.getFreqRange()
245
252
246 inda = numpy.where(FFTs >= minFFT)
253 inda = numpy.where(FFTs >= minFFT)
247 indb = numpy.where(FFTs <= maxFFT)
254 indb = numpy.where(FFTs <= maxFFT)
248
255
249 try:
256 try:
250 minIndex = inda[0][0]
257 minIndex = inda[0][0]
251 except:
258 except:
252 minIndex = 0
259 minIndex = 0
253
260
254 try:
261 try:
255 maxIndex = indb[0][-1]
262 maxIndex = indb[0][-1]
256 except:
263 except:
257 maxIndex = len(FFTs)
264 maxIndex = len(FFTs)
258
265
259 self.selectFFTsByIndex(minIndex, maxIndex)
266 self.selectFFTsByIndex(minIndex, maxIndex)
260
267
261 return 1
268 return 1
262
269
263 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
270 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
264 newheis = numpy.where(
271 newheis = numpy.where(
265 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
272 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
266
273
267 if hei_ref != None:
274 if hei_ref != None:
268 newheis = numpy.where(self.dataOut.heightList > hei_ref)
275 newheis = numpy.where(self.dataOut.heightList > hei_ref)
269
276
270 minIndex = min(newheis[0])
277 minIndex = min(newheis[0])
271 maxIndex = max(newheis[0])
278 maxIndex = max(newheis[0])
272 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
279 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
273 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
280 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
274
281
275 # determina indices
282 # determina indices
276 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
283 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
277 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
284 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
278 avg_dB = 10 * \
285 avg_dB = 10 * \
279 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
286 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
280 beacon_dB = numpy.sort(avg_dB)[-nheis:]
287 beacon_dB = numpy.sort(avg_dB)[-nheis:]
281 beacon_heiIndexList = []
288 beacon_heiIndexList = []
282 for val in avg_dB.tolist():
289 for val in avg_dB.tolist():
283 if val >= beacon_dB[0]:
290 if val >= beacon_dB[0]:
284 beacon_heiIndexList.append(avg_dB.tolist().index(val))
291 beacon_heiIndexList.append(avg_dB.tolist().index(val))
285
292
286 #data_spc = data_spc[:,:,beacon_heiIndexList]
293 #data_spc = data_spc[:,:,beacon_heiIndexList]
287 data_cspc = None
294 data_cspc = None
288 if self.dataOut.data_cspc is not None:
295 if self.dataOut.data_cspc is not None:
289 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
296 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
290 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
297 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
291
298
292 data_dc = None
299 data_dc = None
293 if self.dataOut.data_dc is not None:
300 if self.dataOut.data_dc is not None:
294 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
301 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
295 #data_dc = data_dc[:,beacon_heiIndexList]
302 #data_dc = data_dc[:,beacon_heiIndexList]
296
303
297 self.dataOut.data_spc = data_spc
304 self.dataOut.data_spc = data_spc
298 self.dataOut.data_cspc = data_cspc
305 self.dataOut.data_cspc = data_cspc
299 self.dataOut.data_dc = data_dc
306 self.dataOut.data_dc = data_dc
300 self.dataOut.heightList = heightList
307 self.dataOut.heightList = heightList
301 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
308 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
302
309
303 return 1
310 return 1
304
311
305 def selectFFTsByIndex(self, minIndex, maxIndex):
312 def selectFFTsByIndex(self, minIndex, maxIndex):
306 """
313 """
307
314
308 """
315 """
309
316
310 if (minIndex < 0) or (minIndex > maxIndex):
317 if (minIndex < 0) or (minIndex > maxIndex):
311 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
318 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
312
319
313 if (maxIndex >= self.dataOut.nProfiles):
320 if (maxIndex >= self.dataOut.nProfiles):
314 maxIndex = self.dataOut.nProfiles-1
321 maxIndex = self.dataOut.nProfiles-1
315
322
316 #Spectra
323 #Spectra
317 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
324 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
318
325
319 data_cspc = None
326 data_cspc = None
320 if self.dataOut.data_cspc is not None:
327 if self.dataOut.data_cspc is not None:
321 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
328 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
322
329
323 data_dc = None
330 data_dc = None
324 if self.dataOut.data_dc is not None:
331 if self.dataOut.data_dc is not None:
325 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
332 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
326
333
327 self.dataOut.data_spc = data_spc
334 self.dataOut.data_spc = data_spc
328 self.dataOut.data_cspc = data_cspc
335 self.dataOut.data_cspc = data_cspc
329 self.dataOut.data_dc = data_dc
336 self.dataOut.data_dc = data_dc
330
337
331 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
338 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
332 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
339 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
333 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
340 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
334
341
335 return 1
342 return 1
336
343
337 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
344 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
338 # validacion de rango
345 # validacion de rango
339 print("NOISeeee")
346 print("NOISeeee")
340 if minHei == None:
347 if minHei == None:
341 minHei = self.dataOut.heightList[0]
348 minHei = self.dataOut.heightList[0]
342
349
343 if maxHei == None:
350 if maxHei == None:
344 maxHei = self.dataOut.heightList[-1]
351 maxHei = self.dataOut.heightList[-1]
345
352
346 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
353 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
347 print('minHei: %.2f is out of the heights range' % (minHei))
354 print('minHei: %.2f is out of the heights range' % (minHei))
348 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
355 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
349 minHei = self.dataOut.heightList[0]
356 minHei = self.dataOut.heightList[0]
350
357
351 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
358 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
352 print('maxHei: %.2f is out of the heights range' % (maxHei))
359 print('maxHei: %.2f is out of the heights range' % (maxHei))
353 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
360 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
354 maxHei = self.dataOut.heightList[-1]
361 maxHei = self.dataOut.heightList[-1]
355
362
356 # validacion de velocidades
363 # validacion de velocidades
357 velrange = self.dataOut.getVelRange(1)
364 velrange = self.dataOut.getVelRange(1)
358
365
359 if minVel == None:
366 if minVel == None:
360 minVel = velrange[0]
367 minVel = velrange[0]
361
368
362 if maxVel == None:
369 if maxVel == None:
363 maxVel = velrange[-1]
370 maxVel = velrange[-1]
364
371
365 if (minVel < velrange[0]) or (minVel > maxVel):
372 if (minVel < velrange[0]) or (minVel > maxVel):
366 print('minVel: %.2f is out of the velocity range' % (minVel))
373 print('minVel: %.2f is out of the velocity range' % (minVel))
367 print('minVel is setting to %.2f' % (velrange[0]))
374 print('minVel is setting to %.2f' % (velrange[0]))
368 minVel = velrange[0]
375 minVel = velrange[0]
369
376
370 if (maxVel > velrange[-1]) or (maxVel < minVel):
377 if (maxVel > velrange[-1]) or (maxVel < minVel):
371 print('maxVel: %.2f is out of the velocity range' % (maxVel))
378 print('maxVel: %.2f is out of the velocity range' % (maxVel))
372 print('maxVel is setting to %.2f' % (velrange[-1]))
379 print('maxVel is setting to %.2f' % (velrange[-1]))
373 maxVel = velrange[-1]
380 maxVel = velrange[-1]
374
381
375 # seleccion de indices para rango
382 # seleccion de indices para rango
376 minIndex = 0
383 minIndex = 0
377 maxIndex = 0
384 maxIndex = 0
378 heights = self.dataOut.heightList
385 heights = self.dataOut.heightList
379
386
380 inda = numpy.where(heights >= minHei)
387 inda = numpy.where(heights >= minHei)
381 indb = numpy.where(heights <= maxHei)
388 indb = numpy.where(heights <= maxHei)
382
389
383 try:
390 try:
384 minIndex = inda[0][0]
391 minIndex = inda[0][0]
385 except:
392 except:
386 minIndex = 0
393 minIndex = 0
387
394
388 try:
395 try:
389 maxIndex = indb[0][-1]
396 maxIndex = indb[0][-1]
390 except:
397 except:
391 maxIndex = len(heights)
398 maxIndex = len(heights)
392
399
393 if (minIndex < 0) or (minIndex > maxIndex):
400 if (minIndex < 0) or (minIndex > maxIndex):
394 raise ValueError("some value in (%d,%d) is not valid" % (
401 raise ValueError("some value in (%d,%d) is not valid" % (
395 minIndex, maxIndex))
402 minIndex, maxIndex))
396
403
397 if (maxIndex >= self.dataOut.nHeights):
404 if (maxIndex >= self.dataOut.nHeights):
398 maxIndex = self.dataOut.nHeights - 1
405 maxIndex = self.dataOut.nHeights - 1
399
406
400 # seleccion de indices para velocidades
407 # seleccion de indices para velocidades
401 indminvel = numpy.where(velrange >= minVel)
408 indminvel = numpy.where(velrange >= minVel)
402 indmaxvel = numpy.where(velrange <= maxVel)
409 indmaxvel = numpy.where(velrange <= maxVel)
403 try:
410 try:
404 minIndexVel = indminvel[0][0]
411 minIndexVel = indminvel[0][0]
405 except:
412 except:
406 minIndexVel = 0
413 minIndexVel = 0
407
414
408 try:
415 try:
409 maxIndexVel = indmaxvel[0][-1]
416 maxIndexVel = indmaxvel[0][-1]
410 except:
417 except:
411 maxIndexVel = len(velrange)
418 maxIndexVel = len(velrange)
412
419
413 # seleccion del espectro
420 # seleccion del espectro
414 data_spc = self.dataOut.data_spc[:,
421 data_spc = self.dataOut.data_spc[:,
415 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
422 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
416 # estimacion de ruido
423 # estimacion de ruido
417 noise = numpy.zeros(self.dataOut.nChannels)
424 noise = numpy.zeros(self.dataOut.nChannels)
418
425
419 for channel in range(self.dataOut.nChannels):
426 for channel in range(self.dataOut.nChannels):
420 daux = data_spc[channel, :, :]
427 daux = data_spc[channel, :, :]
421 sortdata = numpy.sort(daux, axis=None)
428 sortdata = numpy.sort(daux, axis=None)
422 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
429 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
423
430
424 self.dataOut.noise_estimation = noise.copy()
431 self.dataOut.noise_estimation = noise.copy()
425
432
426 return 1
433 return 1
427
434
435 class GetSNR(Operation):
436 '''
437 Written by R. Flores
438 '''
439 """Operation to get SNR.
440
441 Parameters:
442 -----------
443
444 Example
445 --------
446
447 op = proc_unit.addOperation(name='GetSNR', optype='other')
448
449 """
450
451 def __init__(self, **kwargs):
452
453 Operation.__init__(self, **kwargs)
454
455
456 def run(self,dataOut):
457
458 noise = dataOut.getNoise()
459 maxdB = 16
460
461 normFactor = 24
462
463 #dataOut.data_snr = (dataOut.data_spc.sum(axis=1))/(noise[:,None]*dataOut.normFactor)
464 dataOut.data_snr = (dataOut.data_spc.sum(axis=1))/(noise[:,None]*dataOut.nFFTPoints)
465
466 dataOut.data_snr = numpy.where(10*numpy.log10(dataOut.data_snr)<.5, numpy.nan, dataOut.data_snr)
467 #dataOut.data_snr = 10*numpy.log10(dataOut.data_snr)
468 #dataOut.data_snr = numpy.expand_dims(dataOut.data_snr,axis=0)
469 #print(dataOut.data_snr.shape)
470 #exit(1)
471
472
473 return dataOut
474
428 class removeDC(Operation):
475 class removeDC(Operation):
429
476
430 def run(self, dataOut, mode=2):
477 def run(self, dataOut, mode=2):
431 self.dataOut = dataOut
478 self.dataOut = dataOut
432 jspectra = self.dataOut.data_spc
479 jspectra = self.dataOut.data_spc
433 jcspectra = self.dataOut.data_cspc
480 jcspectra = self.dataOut.data_cspc
434
481
435 num_chan = jspectra.shape[0]
482 num_chan = jspectra.shape[0]
436 num_hei = jspectra.shape[2]
483 num_hei = jspectra.shape[2]
437
484
438 if jcspectra is not None:
485 if jcspectra is not None:
439 jcspectraExist = True
486 jcspectraExist = True
440 num_pairs = jcspectra.shape[0]
487 num_pairs = jcspectra.shape[0]
441 else:
488 else:
442 jcspectraExist = False
489 jcspectraExist = False
443
490
444 freq_dc = int(jspectra.shape[1] / 2)
491 freq_dc = int(jspectra.shape[1] / 2)
445 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
492 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
446 ind_vel = ind_vel.astype(int)
493 ind_vel = ind_vel.astype(int)
447
494
448 if ind_vel[0] < 0:
495 if ind_vel[0] < 0:
449 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
496 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
450
497
451 if mode == 1:
498 if mode == 1:
452 jspectra[:, freq_dc, :] = (
499 jspectra[:, freq_dc, :] = (
453 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
500 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
454
501
455 if jcspectraExist:
502 if jcspectraExist:
456 jcspectra[:, freq_dc, :] = (
503 jcspectra[:, freq_dc, :] = (
457 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
504 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
458
505
459 if mode == 2:
506 if mode == 2:
460
507
461 vel = numpy.array([-2, -1, 1, 2])
508 vel = numpy.array([-2, -1, 1, 2])
462 xx = numpy.zeros([4, 4])
509 xx = numpy.zeros([4, 4])
463
510
464 for fil in range(4):
511 for fil in range(4):
465 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
512 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
466
513
467 xx_inv = numpy.linalg.inv(xx)
514 xx_inv = numpy.linalg.inv(xx)
468 xx_aux = xx_inv[0, :]
515 xx_aux = xx_inv[0, :]
469
516
470 for ich in range(num_chan):
517 for ich in range(num_chan):
471 yy = jspectra[ich, ind_vel, :]
518 yy = jspectra[ich, ind_vel, :]
472 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
519 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
473
520
474 junkid = jspectra[ich, freq_dc, :] <= 0
521 junkid = jspectra[ich, freq_dc, :] <= 0
475 cjunkid = sum(junkid)
522 cjunkid = sum(junkid)
476
523
477 if cjunkid.any():
524 if cjunkid.any():
478 jspectra[ich, freq_dc, junkid.nonzero()] = (
525 jspectra[ich, freq_dc, junkid.nonzero()] = (
479 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
526 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
480
527
481 if jcspectraExist:
528 if jcspectraExist:
482 for ip in range(num_pairs):
529 for ip in range(num_pairs):
483 yy = jcspectra[ip, ind_vel, :]
530 yy = jcspectra[ip, ind_vel, :]
484 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
531 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
485
532
486 self.dataOut.data_spc = jspectra
533 self.dataOut.data_spc = jspectra
487 self.dataOut.data_cspc = jcspectra
534 self.dataOut.data_cspc = jcspectra
488
535
489 return self.dataOut
536 return self.dataOut
490
537
491 class removeInterference(Operation):
538 class removeInterference(Operation):
492
539
493 def removeInterference2(self):
540 def removeInterference2(self):
494
541
495 cspc = self.dataOut.data_cspc
542 cspc = self.dataOut.data_cspc
496 spc = self.dataOut.data_spc
543 spc = self.dataOut.data_spc
497 Heights = numpy.arange(cspc.shape[2])
544 Heights = numpy.arange(cspc.shape[2])
498 realCspc = numpy.abs(cspc)
545 realCspc = numpy.abs(cspc)
499
546
500 for i in range(cspc.shape[0]):
547 for i in range(cspc.shape[0]):
501 LinePower= numpy.sum(realCspc[i], axis=0)
548 LinePower= numpy.sum(realCspc[i], axis=0)
502 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
549 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
503 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
550 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
504 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
551 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
505 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
552 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
506 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
553 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
507
554
508
555
509 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
556 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
510 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
557 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
511 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
558 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
512 cspc[i,InterferenceRange,:] = numpy.NaN
559 cspc[i,InterferenceRange,:] = numpy.NaN
513
560
514 self.dataOut.data_cspc = cspc
561 self.dataOut.data_cspc = cspc
515
562
516 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
563 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
517
564
518 jspectra = self.dataOut.data_spc
565 jspectra = self.dataOut.data_spc
519 jcspectra = self.dataOut.data_cspc
566 jcspectra = self.dataOut.data_cspc
520 jnoise = self.dataOut.getNoise()
567 jnoise = self.dataOut.getNoise()
521 num_incoh = self.dataOut.nIncohInt
568 num_incoh = self.dataOut.nIncohInt
522
569
523 num_channel = jspectra.shape[0]
570 num_channel = jspectra.shape[0]
524 num_prof = jspectra.shape[1]
571 num_prof = jspectra.shape[1]
525 num_hei = jspectra.shape[2]
572 num_hei = jspectra.shape[2]
526
573
527 # hei_interf
574 # hei_interf
528 if hei_interf is None:
575 if hei_interf is None:
529 count_hei = int(num_hei / 2)
576 count_hei = int(num_hei / 2)
530 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
577 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
531 hei_interf = numpy.asarray(hei_interf)[0]
578 hei_interf = numpy.asarray(hei_interf)[0]
532 # nhei_interf
579 # nhei_interf
533 if (nhei_interf == None):
580 if (nhei_interf == None):
534 nhei_interf = 5
581 nhei_interf = 5
535 if (nhei_interf < 1):
582 if (nhei_interf < 1):
536 nhei_interf = 1
583 nhei_interf = 1
537 if (nhei_interf > count_hei):
584 if (nhei_interf > count_hei):
538 nhei_interf = count_hei
585 nhei_interf = count_hei
539 if (offhei_interf == None):
586 if (offhei_interf == None):
540 offhei_interf = 0
587 offhei_interf = 0
541
588
542 ind_hei = list(range(num_hei))
589 ind_hei = list(range(num_hei))
543 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
590 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
544 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
591 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
545 mask_prof = numpy.asarray(list(range(num_prof)))
592 mask_prof = numpy.asarray(list(range(num_prof)))
546 num_mask_prof = mask_prof.size
593 num_mask_prof = mask_prof.size
547 comp_mask_prof = [0, num_prof / 2]
594 comp_mask_prof = [0, num_prof / 2]
548
595
549 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
596 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
550 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
597 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
551 jnoise = numpy.nan
598 jnoise = numpy.nan
552 noise_exist = jnoise[0] < numpy.Inf
599 noise_exist = jnoise[0] < numpy.Inf
553
600
554 # Subrutina de Remocion de la Interferencia
601 # Subrutina de Remocion de la Interferencia
555 for ich in range(num_channel):
602 for ich in range(num_channel):
556 # Se ordena los espectros segun su potencia (menor a mayor)
603 # Se ordena los espectros segun su potencia (menor a mayor)
557 power = jspectra[ich, mask_prof, :]
604 power = jspectra[ich, mask_prof, :]
558 power = power[:, hei_interf]
605 power = power[:, hei_interf]
559 power = power.sum(axis=0)
606 power = power.sum(axis=0)
560 psort = power.ravel().argsort()
607 psort = power.ravel().argsort()
561
608
562 # Se estima la interferencia promedio en los Espectros de Potencia empleando
609 # Se estima la interferencia promedio en los Espectros de Potencia empleando
563 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
610 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
564 offhei_interf, nhei_interf + offhei_interf))]]]
611 offhei_interf, nhei_interf + offhei_interf))]]]
565
612
566 if noise_exist:
613 if noise_exist:
567 # tmp_noise = jnoise[ich] / num_prof
614 # tmp_noise = jnoise[ich] / num_prof
568 tmp_noise = jnoise[ich]
615 tmp_noise = jnoise[ich]
569 junkspc_interf = junkspc_interf - tmp_noise
616 junkspc_interf = junkspc_interf - tmp_noise
570 #junkspc_interf[:,comp_mask_prof] = 0
617 #junkspc_interf[:,comp_mask_prof] = 0
571
618
572 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
619 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
573 jspc_interf = jspc_interf.transpose()
620 jspc_interf = jspc_interf.transpose()
574 # Calculando el espectro de interferencia promedio
621 # Calculando el espectro de interferencia promedio
575 noiseid = numpy.where(
622 noiseid = numpy.where(
576 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
623 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
577 noiseid = noiseid[0]
624 noiseid = noiseid[0]
578 cnoiseid = noiseid.size
625 cnoiseid = noiseid.size
579 interfid = numpy.where(
626 interfid = numpy.where(
580 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
627 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
581 interfid = interfid[0]
628 interfid = interfid[0]
582 cinterfid = interfid.size
629 cinterfid = interfid.size
583
630
584 if (cnoiseid > 0):
631 if (cnoiseid > 0):
585 jspc_interf[noiseid] = 0
632 jspc_interf[noiseid] = 0
586
633
587 # Expandiendo los perfiles a limpiar
634 # Expandiendo los perfiles a limpiar
588 if (cinterfid > 0):
635 if (cinterfid > 0):
589 new_interfid = (
636 new_interfid = (
590 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
637 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
591 new_interfid = numpy.asarray(new_interfid)
638 new_interfid = numpy.asarray(new_interfid)
592 new_interfid = {x for x in new_interfid}
639 new_interfid = {x for x in new_interfid}
593 new_interfid = numpy.array(list(new_interfid))
640 new_interfid = numpy.array(list(new_interfid))
594 new_cinterfid = new_interfid.size
641 new_cinterfid = new_interfid.size
595 else:
642 else:
596 new_cinterfid = 0
643 new_cinterfid = 0
597
644
598 for ip in range(new_cinterfid):
645 for ip in range(new_cinterfid):
599 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
646 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
600 jspc_interf[new_interfid[ip]
647 jspc_interf[new_interfid[ip]
601 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
648 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
602
649
603 jspectra[ich, :, ind_hei] = jspectra[ich, :,
650 jspectra[ich, :, ind_hei] = jspectra[ich, :,
604 ind_hei] - jspc_interf # Corregir indices
651 ind_hei] - jspc_interf # Corregir indices
605
652
606 # Removiendo la interferencia del punto de mayor interferencia
653 # Removiendo la interferencia del punto de mayor interferencia
607 ListAux = jspc_interf[mask_prof].tolist()
654 ListAux = jspc_interf[mask_prof].tolist()
608 maxid = ListAux.index(max(ListAux))
655 maxid = ListAux.index(max(ListAux))
609
656
610 if cinterfid > 0:
657 if cinterfid > 0:
611 for ip in range(cinterfid * (interf == 2) - 1):
658 for ip in range(cinterfid * (interf == 2) - 1):
612 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
659 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
613 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
660 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
614 cind = len(ind)
661 cind = len(ind)
615
662
616 if (cind > 0):
663 if (cind > 0):
617 jspectra[ich, interfid[ip], ind] = tmp_noise * \
664 jspectra[ich, interfid[ip], ind] = tmp_noise * \
618 (1 + (numpy.random.uniform(cind) - 0.5) /
665 (1 + (numpy.random.uniform(cind) - 0.5) /
619 numpy.sqrt(num_incoh))
666 numpy.sqrt(num_incoh))
620
667
621 ind = numpy.array([-2, -1, 1, 2])
668 ind = numpy.array([-2, -1, 1, 2])
622 xx = numpy.zeros([4, 4])
669 xx = numpy.zeros([4, 4])
623
670
624 for id1 in range(4):
671 for id1 in range(4):
625 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
672 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
626
673
627 xx_inv = numpy.linalg.inv(xx)
674 xx_inv = numpy.linalg.inv(xx)
628 xx = xx_inv[:, 0]
675 xx = xx_inv[:, 0]
629 ind = (ind + maxid + num_mask_prof) % num_mask_prof
676 ind = (ind + maxid + num_mask_prof) % num_mask_prof
630 yy = jspectra[ich, mask_prof[ind], :]
677 yy = jspectra[ich, mask_prof[ind], :]
631 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
678 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
632 yy.transpose(), xx)
679 yy.transpose(), xx)
633
680
634 indAux = (jspectra[ich, :, :] < tmp_noise *
681 indAux = (jspectra[ich, :, :] < tmp_noise *
635 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
682 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
636 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
683 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
637 (1 - 1 / numpy.sqrt(num_incoh))
684 (1 - 1 / numpy.sqrt(num_incoh))
638
685
639 # Remocion de Interferencia en el Cross Spectra
686 # Remocion de Interferencia en el Cross Spectra
640 if jcspectra is None:
687 if jcspectra is None:
641 return jspectra, jcspectra
688 return jspectra, jcspectra
642 num_pairs = int(jcspectra.size / (num_prof * num_hei))
689 num_pairs = int(jcspectra.size / (num_prof * num_hei))
643 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
690 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
644
691
645 for ip in range(num_pairs):
692 for ip in range(num_pairs):
646
693
647 #-------------------------------------------
694 #-------------------------------------------
648
695
649 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
696 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
650 cspower = cspower[:, hei_interf]
697 cspower = cspower[:, hei_interf]
651 cspower = cspower.sum(axis=0)
698 cspower = cspower.sum(axis=0)
652
699
653 cspsort = cspower.ravel().argsort()
700 cspsort = cspower.ravel().argsort()
654 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
701 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
655 offhei_interf, nhei_interf + offhei_interf))]]]
702 offhei_interf, nhei_interf + offhei_interf))]]]
656 junkcspc_interf = junkcspc_interf.transpose()
703 junkcspc_interf = junkcspc_interf.transpose()
657 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
704 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
658
705
659 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
706 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
660
707
661 median_real = int(numpy.median(numpy.real(
708 median_real = int(numpy.median(numpy.real(
662 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
709 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
663 median_imag = int(numpy.median(numpy.imag(
710 median_imag = int(numpy.median(numpy.imag(
664 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
711 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
665 comp_mask_prof = [int(e) for e in comp_mask_prof]
712 comp_mask_prof = [int(e) for e in comp_mask_prof]
666 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
713 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
667 median_real, median_imag)
714 median_real, median_imag)
668
715
669 for iprof in range(num_prof):
716 for iprof in range(num_prof):
670 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
717 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
671 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
718 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
672
719
673 # Removiendo la Interferencia
720 # Removiendo la Interferencia
674 jcspectra[ip, :, ind_hei] = jcspectra[ip,
721 jcspectra[ip, :, ind_hei] = jcspectra[ip,
675 :, ind_hei] - jcspc_interf
722 :, ind_hei] - jcspc_interf
676
723
677 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
724 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
678 maxid = ListAux.index(max(ListAux))
725 maxid = ListAux.index(max(ListAux))
679
726
680 ind = numpy.array([-2, -1, 1, 2])
727 ind = numpy.array([-2, -1, 1, 2])
681 xx = numpy.zeros([4, 4])
728 xx = numpy.zeros([4, 4])
682
729
683 for id1 in range(4):
730 for id1 in range(4):
684 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
731 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
685
732
686 xx_inv = numpy.linalg.inv(xx)
733 xx_inv = numpy.linalg.inv(xx)
687 xx = xx_inv[:, 0]
734 xx = xx_inv[:, 0]
688
735
689 ind = (ind + maxid + num_mask_prof) % num_mask_prof
736 ind = (ind + maxid + num_mask_prof) % num_mask_prof
690 yy = jcspectra[ip, mask_prof[ind], :]
737 yy = jcspectra[ip, mask_prof[ind], :]
691 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
738 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
692
739
693 # Guardar Resultados
740 # Guardar Resultados
694 self.dataOut.data_spc = jspectra
741 self.dataOut.data_spc = jspectra
695 self.dataOut.data_cspc = jcspectra
742 self.dataOut.data_cspc = jcspectra
696
743
697 return 1
744 return 1
698
745
699 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
746 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
700
747
701 self.dataOut = dataOut
748 self.dataOut = dataOut
702
749
703 if mode == 1:
750 if mode == 1:
704 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
751 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
705 elif mode == 2:
752 elif mode == 2:
706 self.removeInterference2()
753 self.removeInterference2()
707
754
708 return self.dataOut
755 return self.dataOut
709
756
710
757
711 class IncohInt(Operation):
758 class IncohInt(Operation):
712
759
713 __profIndex = 0
760 __profIndex = 0
714 __withOverapping = False
761 __withOverapping = False
715
762
716 __byTime = False
763 __byTime = False
717 __initime = None
764 __initime = None
718 __lastdatatime = None
765 __lastdatatime = None
719 __integrationtime = None
766 __integrationtime = None
720
767
721 __buffer_spc = None
768 __buffer_spc = None
722 __buffer_cspc = None
769 __buffer_cspc = None
723 __buffer_dc = None
770 __buffer_dc = None
724
771
725 __dataReady = False
772 __dataReady = False
726
773
727 __timeInterval = None
774 __timeInterval = None
728
775
729 n = None
776 n = None
730
777
731 def __init__(self):
778 def __init__(self):
732
779
733 Operation.__init__(self)
780 Operation.__init__(self)
734
781
735 def setup(self, n=None, timeInterval=None, overlapping=False):
782 def setup(self, n=None, timeInterval=None, overlapping=False):
736 """
783 """
737 Set the parameters of the integration class.
784 Set the parameters of the integration class.
738
785
739 Inputs:
786 Inputs:
740
787
741 n : Number of coherent integrations
788 n : Number of coherent integrations
742 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
789 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
743 overlapping :
790 overlapping :
744
791
745 """
792 """
746
793
747 self.__initime = None
794 self.__initime = None
748 self.__lastdatatime = 0
795 self.__lastdatatime = 0
749
796
750 self.__buffer_spc = 0
797 self.__buffer_spc = 0
751 self.__buffer_cspc = 0
798 self.__buffer_cspc = 0
752 self.__buffer_dc = 0
799 self.__buffer_dc = 0
753
800
754 self.__profIndex = 0
801 self.__profIndex = 0
755 self.__dataReady = False
802 self.__dataReady = False
756 self.__byTime = False
803 self.__byTime = False
757
804
758 if n is None and timeInterval is None:
805 if n is None and timeInterval is None:
759 raise ValueError("n or timeInterval should be specified ...")
806 raise ValueError("n or timeInterval should be specified ...")
760
807
761 if n is not None:
808 if n is not None:
762 self.n = int(n)
809 self.n = int(n)
763 else:
810 else:
764
811
765 self.__integrationtime = int(timeInterval)
812 self.__integrationtime = int(timeInterval)
766 self.n = None
813 self.n = None
767 self.__byTime = True
814 self.__byTime = True
768
815
769 def putData(self, data_spc, data_cspc, data_dc):
816 def putData(self, data_spc, data_cspc, data_dc):
770 """
817 """
771 Add a profile to the __buffer_spc and increase in one the __profileIndex
818 Add a profile to the __buffer_spc and increase in one the __profileIndex
772
819
773 """
820 """
774
821
775 self.__buffer_spc += data_spc
822 self.__buffer_spc += data_spc
776
823
777 if data_cspc is None:
824 if data_cspc is None:
778 self.__buffer_cspc = None
825 self.__buffer_cspc = None
779 else:
826 else:
780 self.__buffer_cspc += data_cspc
827 self.__buffer_cspc += data_cspc
781
828
782 if data_dc is None:
829 if data_dc is None:
783 self.__buffer_dc = None
830 self.__buffer_dc = None
784 else:
831 else:
785 self.__buffer_dc += data_dc
832 self.__buffer_dc += data_dc
786
833
787 self.__profIndex += 1
834 self.__profIndex += 1
788
835
789 return
836 return
790
837
791 def pushData(self):
838 def pushData(self):
792 """
839 """
793 Return the sum of the last profiles and the profiles used in the sum.
840 Return the sum of the last profiles and the profiles used in the sum.
794
841
795 Affected:
842 Affected:
796
843
797 self.__profileIndex
844 self.__profileIndex
798
845
799 """
846 """
800
847
801 data_spc = self.__buffer_spc
848 data_spc = self.__buffer_spc
802 data_cspc = self.__buffer_cspc
849 data_cspc = self.__buffer_cspc
803 data_dc = self.__buffer_dc
850 data_dc = self.__buffer_dc
804 n = self.__profIndex
851 n = self.__profIndex
805
852
806 self.__buffer_spc = 0
853 self.__buffer_spc = 0
807 self.__buffer_cspc = 0
854 self.__buffer_cspc = 0
808 self.__buffer_dc = 0
855 self.__buffer_dc = 0
809 self.__profIndex = 0
856 self.__profIndex = 0
810
857
811 return data_spc, data_cspc, data_dc, n
858 return data_spc, data_cspc, data_dc, n
812
859
813 def byProfiles(self, *args):
860 def byProfiles(self, *args):
814
861
815 self.__dataReady = False
862 self.__dataReady = False
816 avgdata_spc = None
863 avgdata_spc = None
817 avgdata_cspc = None
864 avgdata_cspc = None
818 avgdata_dc = None
865 avgdata_dc = None
819
866
820 self.putData(*args)
867 self.putData(*args)
821
868
822 if self.__profIndex == self.n:
869 if self.__profIndex == self.n:
823
870
824 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
871 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
825 self.n = n
872 self.n = n
826 self.__dataReady = True
873 self.__dataReady = True
827
874
828 return avgdata_spc, avgdata_cspc, avgdata_dc
875 return avgdata_spc, avgdata_cspc, avgdata_dc
829
876
830 def byTime(self, datatime, *args):
877 def byTime(self, datatime, *args):
831
878
832 self.__dataReady = False
879 self.__dataReady = False
833 avgdata_spc = None
880 avgdata_spc = None
834 avgdata_cspc = None
881 avgdata_cspc = None
835 avgdata_dc = None
882 avgdata_dc = None
836
883
837 self.putData(*args)
884 self.putData(*args)
838
885
839 if (datatime - self.__initime) >= self.__integrationtime:
886 if (datatime - self.__initime) >= self.__integrationtime:
840 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
887 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
841 self.n = n
888 self.n = n
842 self.__dataReady = True
889 self.__dataReady = True
843
890
844 return avgdata_spc, avgdata_cspc, avgdata_dc
891 return avgdata_spc, avgdata_cspc, avgdata_dc
845
892
846 def integrate(self, datatime, *args):
893 def integrate(self, datatime, *args):
847
894
848 if self.__profIndex == 0:
895 if self.__profIndex == 0:
849 self.__initime = datatime
896 self.__initime = datatime
850
897
851 if self.__byTime:
898 if self.__byTime:
852 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
899 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
853 datatime, *args)
900 datatime, *args)
854 else:
901 else:
855 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
902 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
856
903
857 if not self.__dataReady:
904 if not self.__dataReady:
858 return None, None, None, None
905 return None, None, None, None
859
906
860 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
907 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
861
908
862 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
909 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
863 if n == 1:
910 if n == 1:
864 return dataOut
911 return dataOut
865 print("JERE")
912 print("JERE")
866 dataOut.flagNoData = True
913 dataOut.flagNoData = True
867
914
868 if not self.isConfig:
915 if not self.isConfig:
869 self.setup(n, timeInterval, overlapping)
916 self.setup(n, timeInterval, overlapping)
870 self.isConfig = True
917 self.isConfig = True
871
918
872 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
919 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
873 dataOut.data_spc,
920 dataOut.data_spc,
874 dataOut.data_cspc,
921 dataOut.data_cspc,
875 dataOut.data_dc)
922 dataOut.data_dc)
876
923
877 if self.__dataReady:
924 if self.__dataReady:
878
925
879 dataOut.data_spc = avgdata_spc
926 dataOut.data_spc = avgdata_spc
880 print(numpy.sum(dataOut.data_spc))
927 print(numpy.sum(dataOut.data_spc))
881 exit(1)
928 exit(1)
882 dataOut.data_cspc = avgdata_cspc
929 dataOut.data_cspc = avgdata_cspc
883 dataOut.data_dc = avgdata_dc
930 dataOut.data_dc = avgdata_dc
884 dataOut.nIncohInt *= self.n
931 dataOut.nIncohInt *= self.n
885 dataOut.utctime = avgdatatime
932 dataOut.utctime = avgdatatime
886 dataOut.flagNoData = False
933 dataOut.flagNoData = False
887
934
888 return dataOut
935 return dataOut
889
936
890 class dopplerFlip(Operation):
937 class dopplerFlip(Operation):
891
938
892 def run(self, dataOut):
939 def run(self, dataOut):
893 # arreglo 1: (num_chan, num_profiles, num_heights)
940 # arreglo 1: (num_chan, num_profiles, num_heights)
894 self.dataOut = dataOut
941 self.dataOut = dataOut
895 # JULIA-oblicua, indice 2
942 # JULIA-oblicua, indice 2
896 # arreglo 2: (num_profiles, num_heights)
943 # arreglo 2: (num_profiles, num_heights)
897 jspectra = self.dataOut.data_spc[2]
944 jspectra = self.dataOut.data_spc[2]
898 jspectra_tmp = numpy.zeros(jspectra.shape)
945 jspectra_tmp = numpy.zeros(jspectra.shape)
899 num_profiles = jspectra.shape[0]
946 num_profiles = jspectra.shape[0]
900 freq_dc = int(num_profiles / 2)
947 freq_dc = int(num_profiles / 2)
901 # Flip con for
948 # Flip con for
902 for j in range(num_profiles):
949 for j in range(num_profiles):
903 jspectra_tmp[num_profiles-j-1]= jspectra[j]
950 jspectra_tmp[num_profiles-j-1]= jspectra[j]
904 # Intercambio perfil de DC con perfil inmediato anterior
951 # Intercambio perfil de DC con perfil inmediato anterior
905 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
952 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
906 jspectra_tmp[freq_dc]= jspectra[freq_dc]
953 jspectra_tmp[freq_dc]= jspectra[freq_dc]
907 # canal modificado es re-escrito en el arreglo de canales
954 # canal modificado es re-escrito en el arreglo de canales
908 self.dataOut.data_spc[2] = jspectra_tmp
955 self.dataOut.data_spc[2] = jspectra_tmp
909
956
910 return self.dataOut
957 return self.dataOut
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now