##// END OF EJS Templates
Tested window 20
Christianpl -
r1782:c73c874ee2f8
parent child
Show More

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

@@ -1,1093 +1,1094
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 blockReader = False
128 blockReader = False
129
129
130 def copy(self, inputObj=None):
130 def copy(self, inputObj=None):
131
131
132 if inputObj == None:
132 if inputObj == None:
133 return copy.deepcopy(self)
133 return copy.deepcopy(self)
134
134
135 for key in list(inputObj.__dict__.keys()):
135 for key in list(inputObj.__dict__.keys()):
136
136
137 attribute = inputObj.__dict__[key]
137 attribute = inputObj.__dict__[key]
138
138
139 # If this attribute is a tuple or list
139 # If this attribute is a tuple or list
140 if type(inputObj.__dict__[key]) in (tuple, list):
140 if type(inputObj.__dict__[key]) in (tuple, list):
141 self.__dict__[key] = attribute[:]
141 self.__dict__[key] = attribute[:]
142 continue
142 continue
143
143
144 # If this attribute is another object or instance
144 # If this attribute is another object or instance
145 if hasattr(attribute, '__dict__'):
145 if hasattr(attribute, '__dict__'):
146 self.__dict__[key] = attribute.copy()
146 self.__dict__[key] = attribute.copy()
147 continue
147 continue
148
148
149 self.__dict__[key] = inputObj.__dict__[key]
149 self.__dict__[key] = inputObj.__dict__[key]
150
150
151 def deepcopy(self):
151 def deepcopy(self):
152
152
153 return copy.deepcopy(self)
153 return copy.deepcopy(self)
154
154
155 def isEmpty(self):
155 def isEmpty(self):
156
156
157 return self.flagNoData
157 return self.flagNoData
158
158
159 def isReady(self):
159 def isReady(self):
160
160
161 return not self.flagNoData
161 return not self.flagNoData
162
162
163
163
164 class JROData(GenericData):
164 class JROData(GenericData):
165
165
166 systemHeaderObj = SystemHeader()
166 systemHeaderObj = SystemHeader()
167 radarControllerHeaderObj = RadarControllerHeader()
167 radarControllerHeaderObj = RadarControllerHeader()
168 type = None
168 type = None
169 datatype = None # dtype but in string
169 datatype = None # dtype but in string
170 nProfiles = None
170 nProfiles = None
171 heightList = None
171 heightList = None
172 channelList = None
172 channelList = None
173 flagDiscontinuousBlock = False
173 flagDiscontinuousBlock = False
174 useLocalTime = False
174 useLocalTime = False
175 utctime = None
175 utctime = None
176 timeZone = None
176 timeZone = None
177 dstFlag = None
177 dstFlag = None
178 errorCount = None
178 errorCount = None
179 blocksize = None
179 blocksize = None
180 flagDecodeData = False # asumo q la data no esta decodificada
180 flagDecodeData = False # asumo q la data no esta decodificada
181 flagDeflipData = False # asumo q la data no esta sin flip
181 flagDeflipData = False # asumo q la data no esta sin flip
182 flagShiftFFT = False
182 flagShiftFFT = False
183 nCohInt = None
183 nCohInt = None
184 windowOfFilter = 1
184 windowOfFilter = 1
185 C = 3e8
185 C = 3e8
186 frequency = 49.92e6
186 frequency = 49.92e6
187 realtime = False
187 realtime = False
188 beacon_heiIndexList = None
188 beacon_heiIndexList = None
189 last_block = None
189 last_block = None
190 blocknow = None
190 blocknow = None
191 azimuth = None
191 azimuth = None
192 zenith = None
192 zenith = None
193 beam = Beam()
193 beam = Beam()
194 profileIndex = None
194 profileIndex = None
195 error = None
195 error = None
196 data = None
196 data = None
197 nmodes = None
197 nmodes = None
198 metadata_list = ['heightList', 'timeZone', 'type']
198 metadata_list = ['heightList', 'timeZone', 'type']
199
199
200 def __str__(self):
200 def __str__(self):
201
201
202 try:
202 try:
203 dt = self.datatime
203 dt = self.datatime
204 except:
204 except:
205 dt = 'None'
205 dt = 'None'
206 return '{} - {}'.format(self.type, dt)
206 return '{} - {}'.format(self.type, dt)
207
207
208 def getNoise(self):
208 def getNoise(self):
209
209
210 raise NotImplementedError
210 raise NotImplementedError
211
211
212 @property
212 @property
213 def nChannels(self):
213 def nChannels(self):
214
214
215 return len(self.channelList)
215 return len(self.channelList)
216
216
217 @property
217 @property
218 def channelIndexList(self):
218 def channelIndexList(self):
219
219
220 return list(range(self.nChannels))
220 return list(range(self.nChannels))
221
221
222 @property
222 @property
223 def nHeights(self):
223 def nHeights(self):
224
224
225 return len(self.heightList)
225 return len(self.heightList)
226
226
227 def getDeltaH(self):
227 def getDeltaH(self):
228
228
229 return self.heightList[1] - self.heightList[0]
229 return self.heightList[1] - self.heightList[0]
230
230
231 @property
231 @property
232 def ltctime(self):
232 def ltctime(self):
233
233
234 if self.useLocalTime:
234 if self.useLocalTime:
235 return self.utctime - self.timeZone * 60
235 return self.utctime - self.timeZone * 60
236
236
237 return self.utctime
237 return self.utctime
238
238
239 @property
239 @property
240 def datatime(self):
240 def datatime(self):
241
241
242 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
242 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
243 return datatimeValue
243 return datatimeValue
244
244
245 def getTimeRange(self):
245 def getTimeRange(self):
246
246
247 datatime = []
247 datatime = []
248
248
249 datatime.append(self.ltctime)
249 datatime.append(self.ltctime)
250 datatime.append(self.ltctime + self.timeInterval + 1)
250 datatime.append(self.ltctime + self.timeInterval + 1)
251
251
252 datatime = numpy.array(datatime)
252 datatime = numpy.array(datatime)
253
253
254 return datatime
254 return datatime
255
255
256 def getFmaxTimeResponse(self):
256 def getFmaxTimeResponse(self):
257
257
258 period = (10**-6) * self.getDeltaH() / (0.15)
258 period = (10**-6) * self.getDeltaH() / (0.15)
259
259
260 PRF = 1. / (period * self.nCohInt)
260 PRF = 1. / (period * self.nCohInt)
261
261
262 fmax = PRF
262 fmax = PRF
263
263
264 return fmax
264 return fmax
265
265
266 def getFmax(self):
266 def getFmax(self):
267 PRF = 1. / (self.ippSeconds * self.nCohInt)
267 PRF = 1. / (self.ippSeconds * self.nCohInt)
268 #print("ippsec",self.ippSeconds)
268 #print("ippsec",self.ippSeconds)
269 fmax = PRF
269 fmax = PRF
270 return fmax
270 return fmax
271
271
272 def getVmax(self):
272 def getVmax(self):
273
273
274 _lambda = self.C / self.frequency
274 _lambda = self.C / self.frequency
275
275
276 vmax = self.getFmax() * _lambda / 2
276 vmax = self.getFmax() * _lambda / 2
277
277
278 return vmax
278 return vmax
279
279
280 @property
280 @property
281 def ippSeconds(self):
281 def ippSeconds(self):
282 '''
282 '''
283 '''
283 '''
284 return self.radarControllerHeaderObj.ippSeconds
284 return self.radarControllerHeaderObj.ippSeconds
285
285
286 @ippSeconds.setter
286 @ippSeconds.setter
287 def ippSeconds(self, ippSeconds):
287 def ippSeconds(self, ippSeconds):
288 '''
288 '''
289 '''
289 '''
290 self.radarControllerHeaderObj.ippSeconds = ippSeconds
290 self.radarControllerHeaderObj.ippSeconds = ippSeconds
291
291
292 @property
292 @property
293 def code(self):
293 def code(self):
294 '''
294 '''
295 '''
295 '''
296 return self.radarControllerHeaderObj.code
296 return self.radarControllerHeaderObj.code
297
297
298 @code.setter
298 @code.setter
299 def code(self, code):
299 def code(self, code):
300 '''
300 '''
301 '''
301 '''
302 self.radarControllerHeaderObj.code = code
302 self.radarControllerHeaderObj.code = code
303
303
304 @property
304 @property
305 def nCode(self):
305 def nCode(self):
306 '''
306 '''
307 '''
307 '''
308 return self.radarControllerHeaderObj.nCode
308 return self.radarControllerHeaderObj.nCode
309
309
310 @nCode.setter
310 @nCode.setter
311 def nCode(self, ncode):
311 def nCode(self, ncode):
312 '''
312 '''
313 '''
313 '''
314 self.radarControllerHeaderObj.nCode = ncode
314 self.radarControllerHeaderObj.nCode = ncode
315
315
316 @property
316 @property
317 def nBaud(self):
317 def nBaud(self):
318 '''
318 '''
319 '''
319 '''
320 return self.radarControllerHeaderObj.nBaud
320 return self.radarControllerHeaderObj.nBaud
321
321
322 @nBaud.setter
322 @nBaud.setter
323 def nBaud(self, nbaud):
323 def nBaud(self, nbaud):
324 '''
324 '''
325 '''
325 '''
326 self.radarControllerHeaderObj.nBaud = nbaud
326 self.radarControllerHeaderObj.nBaud = nbaud
327
327
328 @property
328 @property
329 def ipp(self):
329 def ipp(self):
330 '''
330 '''
331 '''
331 '''
332 return self.radarControllerHeaderObj.ipp
332 return self.radarControllerHeaderObj.ipp
333
333
334 @ipp.setter
334 @ipp.setter
335 def ipp(self, ipp):
335 def ipp(self, ipp):
336 '''
336 '''
337 '''
337 '''
338 self.radarControllerHeaderObj.ipp = ipp
338 self.radarControllerHeaderObj.ipp = ipp
339
339
340 @property
340 @property
341 def metadata(self):
341 def metadata(self):
342 '''
342 '''
343 '''
343 '''
344
344
345 return {attr: getattr(self, attr) for attr in self.metadata_list}
345 return {attr: getattr(self, attr) for attr in self.metadata_list}
346
346
347
347
348 class Voltage(JROData):
348 class Voltage(JROData):
349
349
350 dataPP_POW = None
350 dataPP_POW = None
351 dataPP_DOP = None
351 dataPP_DOP = None
352 dataPP_WIDTH = None
352 dataPP_WIDTH = None
353 dataPP_SNR = None
353 dataPP_SNR = None
354
354
355 def __init__(self):
355 def __init__(self):
356 '''
356 '''
357 Constructor
357 Constructor
358 '''
358 '''
359
359
360 self.useLocalTime = True
360 self.useLocalTime = True
361 self.radarControllerHeaderObj = RadarControllerHeader()
361 self.radarControllerHeaderObj = RadarControllerHeader()
362 self.systemHeaderObj = SystemHeader()
362 self.systemHeaderObj = SystemHeader()
363 self.type = "Voltage"
363 self.type = "Voltage"
364 self.data = None
364 self.data = None
365 self.nProfiles = None
365 self.nProfiles = None
366 self.heightList = None
366 self.heightList = None
367 self.channelList = None
367 self.channelList = None
368 self.flagNoData = True
368 self.flagNoData = True
369 self.flagDiscontinuousBlock = False
369 self.flagDiscontinuousBlock = False
370 self.utctime = None
370 self.utctime = None
371 self.timeZone = 0
371 self.timeZone = 0
372 self.dstFlag = None
372 self.dstFlag = None
373 self.errorCount = None
373 self.errorCount = None
374 self.nCohInt = None
374 self.nCohInt = None
375 self.blocksize = None
375 self.blocksize = None
376 self.flagCohInt = False
376 self.flagCohInt = False
377 self.flagDecodeData = False # asumo q la data no esta decodificada
377 self.flagDecodeData = False # asumo q la data no esta decodificada
378 self.flagDeflipData = False # asumo q la data no esta sin flip
378 self.flagDeflipData = False # asumo q la data no esta sin flip
379 self.flagShiftFFT = False
379 self.flagShiftFFT = False
380 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
380 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
381 self.profileIndex = 0
381 self.profileIndex = 0
382 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
382 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
383 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
383 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
384
384
385 def getNoisebyHildebrand(self, channel=None, Profmin_index=None, Profmax_index=None):
385 def getNoisebyHildebrand(self, channel=None, Profmin_index=None, Profmax_index=None):
386 """
386 """
387 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
387 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
388
388
389 Return:
389 Return:
390 noiselevel
390 noiselevel
391 """
391 """
392
392
393 if channel != None:
393 if channel != None:
394 data = self.data[channel]
394 data = self.data[channel]
395 nChannels = 1
395 nChannels = 1
396 else:
396 else:
397 data = self.data
397 data = self.data
398 nChannels = self.nChannels
398 nChannels = self.nChannels
399
399
400 noise = numpy.zeros(nChannels)
400 noise = numpy.zeros(nChannels)
401 power = data * numpy.conjugate(data)
401 power = data * numpy.conjugate(data)
402
402
403 for thisChannel in range(nChannels):
403 for thisChannel in range(nChannels):
404 if nChannels == 1:
404 if nChannels == 1:
405 daux = power[:].real
405 daux = power[:].real
406 else:
406 else:
407 #print(power.shape)
407 #print(power.shape)
408 daux = power[thisChannel, Profmin_index:Profmax_index, :].real
408 daux = power[thisChannel, Profmin_index:Profmax_index, :].real
409 #print(daux.shape)
409 #print(daux.shape)
410 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
410 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
411
411
412 return noise
412 return noise
413
413
414 def getNoise(self, type=1, channel=None, Profmin_index=None, Profmax_index=None):
414 def getNoise(self, type=1, channel=None, Profmin_index=None, Profmax_index=None):
415
415
416 if type == 1:
416 if type == 1:
417 noise = self.getNoisebyHildebrand(channel, Profmin_index, Profmax_index)
417 noise = self.getNoisebyHildebrand(channel, Profmin_index, Profmax_index)
418
418
419 return noise
419 return noise
420
420
421 def getPower(self, channel=None):
421 def getPower(self, channel=None):
422
422
423 if channel != None:
423 if channel != None:
424 data = self.data[channel]
424 data = self.data[channel]
425 else:
425 else:
426 data = self.data
426 data = self.data
427
427
428 power = data * numpy.conjugate(data)
428 power = data * numpy.conjugate(data)
429 powerdB = 10 * numpy.log10(power.real)
429 powerdB = 10 * numpy.log10(power.real)
430 powerdB = numpy.squeeze(powerdB)
430 powerdB = numpy.squeeze(powerdB)
431
431
432 return powerdB
432 return powerdB
433
433
434 @property
434 @property
435 def timeInterval(self):
435 def timeInterval(self):
436
436
437 return self.ippSeconds * self.nCohInt
437 return self.ippSeconds * self.nCohInt
438
438
439 noise = property(getNoise, "I'm the 'nHeights' property.")
439 noise = property(getNoise, "I'm the 'nHeights' property.")
440
440
441
441
442 class Spectra(JROData):
442 class Spectra(JROData):
443
443
444 def __init__(self):
444 def __init__(self):
445 '''
445 '''
446 Constructor
446 Constructor
447 '''
447 '''
448
448
449 self.data_dc = None
449 self.data_dc = None
450 self.data_spc = None
450 self.data_spc = None
451 self.data_cspc = None
451 self.data_cspc = None
452 self.useLocalTime = True
452 self.useLocalTime = True
453 self.radarControllerHeaderObj = RadarControllerHeader()
453 self.radarControllerHeaderObj = RadarControllerHeader()
454 self.systemHeaderObj = SystemHeader()
454 self.systemHeaderObj = SystemHeader()
455 self.type = "Spectra"
455 self.type = "Spectra"
456 self.timeZone = 0
456 self.timeZone = 0
457 self.nProfiles = None
457 self.nProfiles = None
458 self.heightList = None
458 self.heightList = None
459 self.channelList = None
459 self.channelList = None
460 self.pairsList = None
460 self.pairsList = None
461 self.flagNoData = True
461 self.flagNoData = True
462 self.flagDiscontinuousBlock = False
462 self.flagDiscontinuousBlock = False
463 self.utctime = None
463 self.utctime = None
464 self.nCohInt = None
464 self.nCohInt = None
465 self.nIncohInt = None
465 self.nIncohInt = None
466 self.blocksize = None
466 self.blocksize = None
467 self.nFFTPoints = None
467 self.nFFTPoints = None
468 self.wavelength = None
468 self.wavelength = None
469 self.flagDecodeData = False # asumo q la data no esta decodificada
469 self.flagDecodeData = False # asumo q la data no esta decodificada
470 self.flagDeflipData = False # asumo q la data no esta sin flip
470 self.flagDeflipData = False # asumo q la data no esta sin flip
471 self.flagShiftFFT = False
471 self.flagShiftFFT = False
472 self.ippFactor = 1
472 self.ippFactor = 1
473 self.beacon_heiIndexList = []
473 self.beacon_heiIndexList = []
474 self.noise_estimation = None
474 self.noise_estimation = None
475 self.spc_noise = None
475 self.spc_noise = None
476 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
476 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
477 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp', 'nIncohInt', 'nFFTPoints', 'nProfiles', 'flagDecodeData']
477 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp', 'nIncohInt', 'nFFTPoints', 'nProfiles', 'flagDecodeData']
478
478
479 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
479 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
480 """
480 """
481 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
481 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
482
482
483 Return:
483 Return:
484 noiselevel
484 noiselevel
485 """
485 """
486
486
487 noise = numpy.zeros(self.nChannels)
487 noise = numpy.zeros(self.nChannels)
488
488
489 for channel in range(self.nChannels):
489 for channel in range(self.nChannels):
490 #print(self.data_spc[0])
490 #print(self.data_spc[0])
491 #exit(1)
491 #exit(1)
492 daux = self.data_spc[channel,
492 daux = self.data_spc[channel,
493 xmin_index:xmax_index, ymin_index:ymax_index]
493 xmin_index:xmax_index, ymin_index:ymax_index]
494 #print("daux",daux)
494 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
495 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
495
496
496 return noise
497 return noise
497
498
498 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
499 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
499
500
500 if self.spc_noise is not None:
501 if self.spc_noise is not None:
501 # this was estimated by getNoise Operation defined in jroproc_parameters.py
502 # this was estimated by getNoise Operation defined in jroproc_parameters.py
502 return self.spc_noise
503 return self.spc_noise
503 elif self.noise_estimation is not None:
504 elif self.noise_estimation is not None:
504 # this was estimated by getNoise Operation defined in jroproc_spectra.py
505 # this was estimated by getNoise Operation defined in jroproc_spectra.py
505 return self.noise_estimation
506 return self.noise_estimation
506 else:
507 else:
507
508
508 noise = self.getNoisebyHildebrand(
509 noise = self.getNoisebyHildebrand(
509 xmin_index, xmax_index, ymin_index, ymax_index)
510 xmin_index, xmax_index, ymin_index, ymax_index)
510 return noise
511 return noise
511
512
512 def getFreqRangeTimeResponse(self, extrapoints=0):
513 def getFreqRangeTimeResponse(self, extrapoints=0):
513
514
514 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
515 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
515 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
516 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
516
517
517 return freqrange
518 return freqrange
518
519
519 def getAcfRange(self, extrapoints=0):
520 def getAcfRange(self, extrapoints=0):
520
521
521 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
522 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
522 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
523 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
523
524
524 return freqrange
525 return freqrange
525
526
526 def getFreqRange(self, extrapoints=0):
527 def getFreqRange(self, extrapoints=0):
527
528
528 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
529 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
529 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
530 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
530
531
531 return freqrange
532 return freqrange
532
533
533 def getVelRange(self, extrapoints=0):
534 def getVelRange(self, extrapoints=0):
534
535
535 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
536 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
536 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
537 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
537
538
538 if self.nmodes:
539 if self.nmodes:
539 return velrange/self.nmodes
540 return velrange/self.nmodes
540 else:
541 else:
541 return velrange
542 return velrange
542
543
543 @property
544 @property
544 def nPairs(self):
545 def nPairs(self):
545
546
546 return len(self.pairsList)
547 return len(self.pairsList)
547
548
548 @property
549 @property
549 def pairsIndexList(self):
550 def pairsIndexList(self):
550
551
551 return list(range(self.nPairs))
552 return list(range(self.nPairs))
552
553
553 @property
554 @property
554 def normFactor(self):
555 def normFactor(self):
555
556
556 pwcode = 1
557 pwcode = 1
557
558
558 if self.flagDecodeData:
559 if self.flagDecodeData:
559 pwcode = numpy.sum(self.code[0]**2)
560 pwcode = numpy.sum(self.code[0]**2)
560 #pwcode = 64
561 #pwcode = 64
561 #print("pwcode: ", pwcode)
562 #print("pwcode: ", pwcode)
562 #exit(1)
563 #exit(1)
563 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
564 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
564 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
565 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
565
566
566 return normFactor
567 return normFactor
567
568
568 @property
569 @property
569 def flag_cspc(self):
570 def flag_cspc(self):
570
571
571 if self.data_cspc is None:
572 if self.data_cspc is None:
572 return True
573 return True
573
574
574 return False
575 return False
575
576
576 @property
577 @property
577 def flag_dc(self):
578 def flag_dc(self):
578
579
579 if self.data_dc is None:
580 if self.data_dc is None:
580 return True
581 return True
581
582
582 return False
583 return False
583
584
584 @property
585 @property
585 def timeInterval(self):
586 def timeInterval(self):
586
587
587 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
588 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
588 if self.nmodes:
589 if self.nmodes:
589 return self.nmodes*timeInterval
590 return self.nmodes*timeInterval
590 else:
591 else:
591 return timeInterval
592 return timeInterval
592
593
593 def getPower(self):
594 def getPower(self):
594
595
595 factor = self.normFactor
596 factor = self.normFactor
596 z = self.data_spc / factor
597 z = self.data_spc / factor
597 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
598 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
598 avg = numpy.average(z, axis=1)
599 avg = numpy.average(z, axis=1)
599
600
600 return 10 * numpy.log10(avg)
601 return 10 * numpy.log10(avg)
601
602
602 def getCoherence(self, pairsList=None, phase=False):
603 def getCoherence(self, pairsList=None, phase=False):
603
604
604 z = []
605 z = []
605 if pairsList is None:
606 if pairsList is None:
606 pairsIndexList = self.pairsIndexList
607 pairsIndexList = self.pairsIndexList
607 else:
608 else:
608 pairsIndexList = []
609 pairsIndexList = []
609 for pair in pairsList:
610 for pair in pairsList:
610 if pair not in self.pairsList:
611 if pair not in self.pairsList:
611 raise ValueError("Pair %s is not in dataOut.pairsList" % (
612 raise ValueError("Pair %s is not in dataOut.pairsList" % (
612 pair))
613 pair))
613 pairsIndexList.append(self.pairsList.index(pair))
614 pairsIndexList.append(self.pairsList.index(pair))
614 for i in range(len(pairsIndexList)):
615 for i in range(len(pairsIndexList)):
615 pair = self.pairsList[pairsIndexList[i]]
616 pair = self.pairsList[pairsIndexList[i]]
616 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
617 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
617 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
618 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
618 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
619 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
619 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
620 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
620 if phase:
621 if phase:
621 data = numpy.arctan2(avgcoherenceComplex.imag,
622 data = numpy.arctan2(avgcoherenceComplex.imag,
622 avgcoherenceComplex.real) * 180 / numpy.pi
623 avgcoherenceComplex.real) * 180 / numpy.pi
623 else:
624 else:
624 data = numpy.abs(avgcoherenceComplex)
625 data = numpy.abs(avgcoherenceComplex)
625
626
626 z.append(data)
627 z.append(data)
627
628
628 return numpy.array(z)
629 return numpy.array(z)
629
630
630 def setValue(self, value):
631 def setValue(self, value):
631
632
632 print("This property should not be initialized")
633 print("This property should not be initialized")
633
634
634 return
635 return
635
636
636 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
637 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
637
638
638
639
639 class SpectraHeis(Spectra):
640 class SpectraHeis(Spectra):
640
641
641 def __init__(self):
642 def __init__(self):
642
643
643 self.radarControllerHeaderObj = RadarControllerHeader()
644 self.radarControllerHeaderObj = RadarControllerHeader()
644 self.systemHeaderObj = SystemHeader()
645 self.systemHeaderObj = SystemHeader()
645 self.type = "SpectraHeis"
646 self.type = "SpectraHeis"
646 self.nProfiles = None
647 self.nProfiles = None
647 self.heightList = None
648 self.heightList = None
648 self.channelList = None
649 self.channelList = None
649 self.flagNoData = True
650 self.flagNoData = True
650 self.flagDiscontinuousBlock = False
651 self.flagDiscontinuousBlock = False
651 self.utctime = None
652 self.utctime = None
652 self.blocksize = None
653 self.blocksize = None
653 self.profileIndex = 0
654 self.profileIndex = 0
654 self.nCohInt = 1
655 self.nCohInt = 1
655 self.nIncohInt = 1
656 self.nIncohInt = 1
656
657
657 @property
658 @property
658 def normFactor(self):
659 def normFactor(self):
659 pwcode = 1
660 pwcode = 1
660 if self.flagDecodeData:
661 if self.flagDecodeData:
661 pwcode = numpy.sum(self.code[0]**2)
662 pwcode = numpy.sum(self.code[0]**2)
662
663
663 normFactor = self.nIncohInt * self.nCohInt * pwcode
664 normFactor = self.nIncohInt * self.nCohInt * pwcode
664
665
665 return normFactor
666 return normFactor
666
667
667 @property
668 @property
668 def timeInterval(self):
669 def timeInterval(self):
669
670
670 return self.ippSeconds * self.nCohInt * self.nIncohInt
671 return self.ippSeconds * self.nCohInt * self.nIncohInt
671
672
672
673
673 class Fits(JROData):
674 class Fits(JROData):
674
675
675 def __init__(self):
676 def __init__(self):
676
677
677 self.type = "Fits"
678 self.type = "Fits"
678 self.nProfiles = None
679 self.nProfiles = None
679 self.heightList = None
680 self.heightList = None
680 self.channelList = None
681 self.channelList = None
681 self.flagNoData = True
682 self.flagNoData = True
682 self.utctime = None
683 self.utctime = None
683 self.nCohInt = 1
684 self.nCohInt = 1
684 self.nIncohInt = 1
685 self.nIncohInt = 1
685 self.useLocalTime = True
686 self.useLocalTime = True
686 self.profileIndex = 0
687 self.profileIndex = 0
687 self.timeZone = 0
688 self.timeZone = 0
688
689
689 def getTimeRange(self):
690 def getTimeRange(self):
690
691
691 datatime = []
692 datatime = []
692
693
693 datatime.append(self.ltctime)
694 datatime.append(self.ltctime)
694 datatime.append(self.ltctime + self.timeInterval)
695 datatime.append(self.ltctime + self.timeInterval)
695
696
696 datatime = numpy.array(datatime)
697 datatime = numpy.array(datatime)
697
698
698 return datatime
699 return datatime
699
700
700 def getChannelIndexList(self):
701 def getChannelIndexList(self):
701
702
702 return list(range(self.nChannels))
703 return list(range(self.nChannels))
703
704
704 def getNoise(self, type=1):
705 def getNoise(self, type=1):
705
706
706
707
707 if type == 1:
708 if type == 1:
708 noise = self.getNoisebyHildebrand()
709 noise = self.getNoisebyHildebrand()
709
710
710 if type == 2:
711 if type == 2:
711 noise = self.getNoisebySort()
712 noise = self.getNoisebySort()
712
713
713 if type == 3:
714 if type == 3:
714 noise = self.getNoisebyWindow()
715 noise = self.getNoisebyWindow()
715
716
716 return noise
717 return noise
717
718
718 @property
719 @property
719 def timeInterval(self):
720 def timeInterval(self):
720
721
721 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
722 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
722
723
723 return timeInterval
724 return timeInterval
724
725
725 @property
726 @property
726 def ippSeconds(self):
727 def ippSeconds(self):
727 '''
728 '''
728 '''
729 '''
729 return self.ipp_sec
730 return self.ipp_sec
730
731
731 noise = property(getNoise, "I'm the 'nHeights' property.")
732 noise = property(getNoise, "I'm the 'nHeights' property.")
732
733
733
734
734 class Correlation(JROData):
735 class Correlation(JROData):
735
736
736 def __init__(self):
737 def __init__(self):
737 '''
738 '''
738 Constructor
739 Constructor
739 '''
740 '''
740 self.radarControllerHeaderObj = RadarControllerHeader()
741 self.radarControllerHeaderObj = RadarControllerHeader()
741 self.systemHeaderObj = SystemHeader()
742 self.systemHeaderObj = SystemHeader()
742 self.type = "Correlation"
743 self.type = "Correlation"
743 self.data = None
744 self.data = None
744 self.dtype = None
745 self.dtype = None
745 self.nProfiles = None
746 self.nProfiles = None
746 self.heightList = None
747 self.heightList = None
747 self.channelList = None
748 self.channelList = None
748 self.flagNoData = True
749 self.flagNoData = True
749 self.flagDiscontinuousBlock = False
750 self.flagDiscontinuousBlock = False
750 self.utctime = None
751 self.utctime = None
751 self.timeZone = 0
752 self.timeZone = 0
752 self.dstFlag = None
753 self.dstFlag = None
753 self.errorCount = None
754 self.errorCount = None
754 self.blocksize = None
755 self.blocksize = None
755 self.flagDecodeData = False # asumo q la data no esta decodificada
756 self.flagDecodeData = False # asumo q la data no esta decodificada
756 self.flagDeflipData = False # asumo q la data no esta sin flip
757 self.flagDeflipData = False # asumo q la data no esta sin flip
757 self.pairsList = None
758 self.pairsList = None
758 self.nPoints = None
759 self.nPoints = None
759
760
760 def getPairsList(self):
761 def getPairsList(self):
761
762
762 return self.pairsList
763 return self.pairsList
763
764
764 def getNoise(self, mode=2):
765 def getNoise(self, mode=2):
765
766
766 indR = numpy.where(self.lagR == 0)[0][0]
767 indR = numpy.where(self.lagR == 0)[0][0]
767 indT = numpy.where(self.lagT == 0)[0][0]
768 indT = numpy.where(self.lagT == 0)[0][0]
768
769
769 jspectra0 = self.data_corr[:, :, indR, :]
770 jspectra0 = self.data_corr[:, :, indR, :]
770 jspectra = copy.copy(jspectra0)
771 jspectra = copy.copy(jspectra0)
771
772
772 num_chan = jspectra.shape[0]
773 num_chan = jspectra.shape[0]
773 num_hei = jspectra.shape[2]
774 num_hei = jspectra.shape[2]
774
775
775 freq_dc = jspectra.shape[1] / 2
776 freq_dc = jspectra.shape[1] / 2
776 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
777 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
777
778
778 if ind_vel[0] < 0:
779 if ind_vel[0] < 0:
779 ind_vel[list(range(0, 1))] = ind_vel[list(
780 ind_vel[list(range(0, 1))] = ind_vel[list(
780 range(0, 1))] + self.num_prof
781 range(0, 1))] + self.num_prof
781
782
782 if mode == 1:
783 if mode == 1:
783 jspectra[:, freq_dc, :] = (
784 jspectra[:, freq_dc, :] = (
784 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
785 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
785
786
786 if mode == 2:
787 if mode == 2:
787
788
788 vel = numpy.array([-2, -1, 1, 2])
789 vel = numpy.array([-2, -1, 1, 2])
789 xx = numpy.zeros([4, 4])
790 xx = numpy.zeros([4, 4])
790
791
791 for fil in range(4):
792 for fil in range(4):
792 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
793 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
793
794
794 xx_inv = numpy.linalg.inv(xx)
795 xx_inv = numpy.linalg.inv(xx)
795 xx_aux = xx_inv[0, :]
796 xx_aux = xx_inv[0, :]
796
797
797 for ich in range(num_chan):
798 for ich in range(num_chan):
798 yy = jspectra[ich, ind_vel, :]
799 yy = jspectra[ich, ind_vel, :]
799 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
800 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
800
801
801 junkid = jspectra[ich, freq_dc, :] <= 0
802 junkid = jspectra[ich, freq_dc, :] <= 0
802 cjunkid = sum(junkid)
803 cjunkid = sum(junkid)
803
804
804 if cjunkid.any():
805 if cjunkid.any():
805 jspectra[ich, freq_dc, junkid.nonzero()] = (
806 jspectra[ich, freq_dc, junkid.nonzero()] = (
806 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
807 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
807
808
808 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
809 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
809
810
810 return noise
811 return noise
811
812
812 @property
813 @property
813 def timeInterval(self):
814 def timeInterval(self):
814
815
815 return self.ippSeconds * self.nCohInt * self.nProfiles
816 return self.ippSeconds * self.nCohInt * self.nProfiles
816
817
817 def splitFunctions(self):
818 def splitFunctions(self):
818
819
819 pairsList = self.pairsList
820 pairsList = self.pairsList
820 ccf_pairs = []
821 ccf_pairs = []
821 acf_pairs = []
822 acf_pairs = []
822 ccf_ind = []
823 ccf_ind = []
823 acf_ind = []
824 acf_ind = []
824 for l in range(len(pairsList)):
825 for l in range(len(pairsList)):
825 chan0 = pairsList[l][0]
826 chan0 = pairsList[l][0]
826 chan1 = pairsList[l][1]
827 chan1 = pairsList[l][1]
827
828
828 # Obteniendo pares de Autocorrelacion
829 # Obteniendo pares de Autocorrelacion
829 if chan0 == chan1:
830 if chan0 == chan1:
830 acf_pairs.append(chan0)
831 acf_pairs.append(chan0)
831 acf_ind.append(l)
832 acf_ind.append(l)
832 else:
833 else:
833 ccf_pairs.append(pairsList[l])
834 ccf_pairs.append(pairsList[l])
834 ccf_ind.append(l)
835 ccf_ind.append(l)
835
836
836 data_acf = self.data_cf[acf_ind]
837 data_acf = self.data_cf[acf_ind]
837 data_ccf = self.data_cf[ccf_ind]
838 data_ccf = self.data_cf[ccf_ind]
838
839
839 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
840 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
840
841
841 @property
842 @property
842 def normFactor(self):
843 def normFactor(self):
843 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
844 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
844 acf_pairs = numpy.array(acf_pairs)
845 acf_pairs = numpy.array(acf_pairs)
845 normFactor = numpy.zeros((self.nPairs, self.nHeights))
846 normFactor = numpy.zeros((self.nPairs, self.nHeights))
846
847
847 for p in range(self.nPairs):
848 for p in range(self.nPairs):
848 pair = self.pairsList[p]
849 pair = self.pairsList[p]
849
850
850 ch0 = pair[0]
851 ch0 = pair[0]
851 ch1 = pair[1]
852 ch1 = pair[1]
852
853
853 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
854 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
854 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
855 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
855 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
856 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
856
857
857 return normFactor
858 return normFactor
858
859
859
860
860 class Parameters(Spectra):
861 class Parameters(Spectra):
861
862
862 groupList = None # List of Pairs, Groups, etc
863 groupList = None # List of Pairs, Groups, etc
863 data_param = None # Parameters obtained
864 data_param = None # Parameters obtained
864 data_pre = None # Data Pre Parametrization
865 data_pre = None # Data Pre Parametrization
865 data_SNR = None # Signal to Noise Ratio
866 data_SNR = None # Signal to Noise Ratio
866 abscissaList = None # Abscissa, can be velocities, lags or time
867 abscissaList = None # Abscissa, can be velocities, lags or time
867 utctimeInit = None # Initial UTC time
868 utctimeInit = None # Initial UTC time
868 paramInterval = None # Time interval to calculate Parameters in seconds
869 paramInterval = None # Time interval to calculate Parameters in seconds
869 useLocalTime = True
870 useLocalTime = True
870 # Fitting
871 # Fitting
871 data_error = None # Error of the estimation
872 data_error = None # Error of the estimation
872 constants = None
873 constants = None
873 library = None
874 library = None
874 # Output signal
875 # Output signal
875 outputInterval = None # Time interval to calculate output signal in seconds
876 outputInterval = None # Time interval to calculate output signal in seconds
876 data_output = None # Out signal
877 data_output = None # Out signal
877 nAvg = None
878 nAvg = None
878 noise_estimation = None
879 noise_estimation = None
879 GauSPC = None # Fit gaussian SPC
880 GauSPC = None # Fit gaussian SPC
880 spc_noise = None
881 spc_noise = None
881
882
882 def __init__(self):
883 def __init__(self):
883 '''
884 '''
884 Constructor
885 Constructor
885 '''
886 '''
886 self.radarControllerHeaderObj = RadarControllerHeader()
887 self.radarControllerHeaderObj = RadarControllerHeader()
887 self.systemHeaderObj = SystemHeader()
888 self.systemHeaderObj = SystemHeader()
888 self.type = "Parameters"
889 self.type = "Parameters"
889 self.timeZone = 0
890 self.timeZone = 0
890 self.ippFactor = 1
891 self.ippFactor = 1
891
892
892 def getTimeRange1(self, interval):
893 def getTimeRange1(self, interval):
893
894
894 datatime = []
895 datatime = []
895
896
896 if self.useLocalTime:
897 if self.useLocalTime:
897 time1 = self.utctimeInit - self.timeZone * 60
898 time1 = self.utctimeInit - self.timeZone * 60
898 else:
899 else:
899 time1 = self.utctimeInit
900 time1 = self.utctimeInit
900
901
901 datatime.append(time1)
902 datatime.append(time1)
902 datatime.append(time1 + interval)
903 datatime.append(time1 + interval)
903 datatime = numpy.array(datatime)
904 datatime = numpy.array(datatime)
904
905
905 return datatime
906 return datatime
906
907
907 @property
908 @property
908 def timeInterval(self):
909 def timeInterval(self):
909
910
910 if hasattr(self, 'timeInterval1'):
911 if hasattr(self, 'timeInterval1'):
911 return self.timeInterval1
912 return self.timeInterval1
912 else:
913 else:
913 return self.paramInterval
914 return self.paramInterval
914
915
915
916
916 def setValue(self, value):
917 def setValue(self, value):
917
918
918 print("This property should not be initialized")
919 print("This property should not be initialized")
919
920
920 return
921 return
921
922
922 def getNoise(self):
923 def getNoise(self):
923
924
924 return self.spc_noise
925 return self.spc_noise
925
926
926 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
927 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
927
928
928
929
929 class PlotterData(object):
930 class PlotterData(object):
930 '''
931 '''
931 Object to hold data to be plotted
932 Object to hold data to be plotted
932 '''
933 '''
933
934
934 MAXNUMX = 200
935 MAXNUMX = 200
935 MAXNUMY = 200
936 MAXNUMY = 200
936
937
937 def __init__(self, code, exp_code, localtime=True):
938 def __init__(self, code, exp_code, localtime=True):
938
939
939 self.key = code
940 self.key = code
940 self.exp_code = exp_code
941 self.exp_code = exp_code
941 self.ready = False
942 self.ready = False
942 self.flagNoData = False
943 self.flagNoData = False
943 self.localtime = localtime
944 self.localtime = localtime
944 self.data = {}
945 self.data = {}
945 self.meta = {}
946 self.meta = {}
946 self.__heights = []
947 self.__heights = []
947
948
948 def __str__(self):
949 def __str__(self):
949 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
950 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
950 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
951 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
951
952
952 def __len__(self):
953 def __len__(self):
953 return len(self.data)
954 return len(self.data)
954
955
955 def __getitem__(self, key):
956 def __getitem__(self, key):
956 if isinstance(key, int):
957 if isinstance(key, int):
957 return self.data[self.times[key]]
958 return self.data[self.times[key]]
958 elif isinstance(key, str):
959 elif isinstance(key, str):
959 ret = numpy.array([self.data[x][key] for x in self.times])
960 ret = numpy.array([self.data[x][key] for x in self.times])
960 if ret.ndim > 1:
961 if ret.ndim > 1:
961 ret = numpy.swapaxes(ret, 0, 1)
962 ret = numpy.swapaxes(ret, 0, 1)
962 return ret
963 return ret
963
964
964 def __contains__(self, key):
965 def __contains__(self, key):
965 return key in self.data[self.min_time]
966 return key in self.data[self.min_time]
966
967
967 def setup(self):
968 def setup(self):
968 '''
969 '''
969 Configure object
970 Configure object
970 '''
971 '''
971 self.type = ''
972 self.type = ''
972 self.ready = False
973 self.ready = False
973 del self.data
974 del self.data
974 self.data = {}
975 self.data = {}
975 self.__heights = []
976 self.__heights = []
976 self.__all_heights = set()
977 self.__all_heights = set()
977
978
978 def shape(self, key):
979 def shape(self, key):
979 '''
980 '''
980 Get the shape of the one-element data for the given key
981 Get the shape of the one-element data for the given key
981 '''
982 '''
982
983
983 if len(self.data[self.min_time][key]):
984 if len(self.data[self.min_time][key]):
984 return self.data[self.min_time][key].shape
985 return self.data[self.min_time][key].shape
985 return (0,)
986 return (0,)
986
987
987 def update(self, data, tm, meta={}):
988 def update(self, data, tm, meta={}):
988 '''
989 '''
989 Update data object with new dataOut
990 Update data object with new dataOut
990 '''
991 '''
991
992
992 self.data[tm] = data
993 self.data[tm] = data
993
994
994 for key, value in meta.items():
995 for key, value in meta.items():
995 setattr(self, key, value)
996 setattr(self, key, value)
996
997
997 def normalize_heights(self):
998 def normalize_heights(self):
998 '''
999 '''
999 Ensure same-dimension of the data for different heighList
1000 Ensure same-dimension of the data for different heighList
1000 '''
1001 '''
1001
1002
1002 H = numpy.array(list(self.__all_heights))
1003 H = numpy.array(list(self.__all_heights))
1003 H.sort()
1004 H.sort()
1004 for key in self.data:
1005 for key in self.data:
1005 shape = self.shape(key)[:-1] + H.shape
1006 shape = self.shape(key)[:-1] + H.shape
1006 for tm, obj in list(self.data[key].items()):
1007 for tm, obj in list(self.data[key].items()):
1007 h = self.__heights[self.times.tolist().index(tm)]
1008 h = self.__heights[self.times.tolist().index(tm)]
1008 if H.size == h.size:
1009 if H.size == h.size:
1009 continue
1010 continue
1010 index = numpy.where(numpy.in1d(H, h))[0]
1011 index = numpy.where(numpy.in1d(H, h))[0]
1011 dummy = numpy.zeros(shape) + numpy.nan
1012 dummy = numpy.zeros(shape) + numpy.nan
1012 if len(shape) == 2:
1013 if len(shape) == 2:
1013 dummy[:, index] = obj
1014 dummy[:, index] = obj
1014 else:
1015 else:
1015 dummy[index] = obj
1016 dummy[index] = obj
1016 self.data[key][tm] = dummy
1017 self.data[key][tm] = dummy
1017
1018
1018 self.__heights = [H for tm in self.times]
1019 self.__heights = [H for tm in self.times]
1019
1020
1020 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1021 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1021 '''
1022 '''
1022 Convert data to json
1023 Convert data to json
1023 '''
1024 '''
1024
1025
1025 meta = {}
1026 meta = {}
1026 meta['xrange'] = []
1027 meta['xrange'] = []
1027 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1028 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1028 tmp = self.data[tm][self.key]
1029 tmp = self.data[tm][self.key]
1029 shape = tmp.shape
1030 shape = tmp.shape
1030 if len(shape) == 2:
1031 if len(shape) == 2:
1031 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1032 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1032 elif len(shape) == 3:
1033 elif len(shape) == 3:
1033 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1034 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1034 data = self.roundFloats(
1035 data = self.roundFloats(
1035 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1036 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1036 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1037 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1037 else:
1038 else:
1038 data = self.roundFloats(self.data[tm][self.key].tolist())
1039 data = self.roundFloats(self.data[tm][self.key].tolist())
1039
1040
1040 ret = {
1041 ret = {
1041 'plot': plot_name,
1042 'plot': plot_name,
1042 'code': self.exp_code,
1043 'code': self.exp_code,
1043 'time': float(tm),
1044 'time': float(tm),
1044 'data': data,
1045 'data': data,
1045 }
1046 }
1046 meta['type'] = plot_type
1047 meta['type'] = plot_type
1047 meta['interval'] = float(self.interval)
1048 meta['interval'] = float(self.interval)
1048 meta['localtime'] = self.localtime
1049 meta['localtime'] = self.localtime
1049 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1050 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1050 meta.update(self.meta)
1051 meta.update(self.meta)
1051 ret['metadata'] = meta
1052 ret['metadata'] = meta
1052 return json.dumps(ret)
1053 return json.dumps(ret)
1053
1054
1054 @property
1055 @property
1055 def times(self):
1056 def times(self):
1056 '''
1057 '''
1057 Return the list of times of the current data
1058 Return the list of times of the current data
1058 '''
1059 '''
1059
1060
1060 ret = [t for t in self.data]
1061 ret = [t for t in self.data]
1061 ret.sort()
1062 ret.sort()
1062 return numpy.array(ret)
1063 return numpy.array(ret)
1063
1064
1064 @property
1065 @property
1065 def min_time(self):
1066 def min_time(self):
1066 '''
1067 '''
1067 Return the minimun time value
1068 Return the minimun time value
1068 '''
1069 '''
1069
1070
1070 return self.times[0]
1071 return self.times[0]
1071
1072
1072 @property
1073 @property
1073 def max_time(self):
1074 def max_time(self):
1074 '''
1075 '''
1075 Return the maximun time value
1076 Return the maximun time value
1076 '''
1077 '''
1077
1078
1078 return self.times[-1]
1079 return self.times[-1]
1079
1080
1080 # @property
1081 # @property
1081 # def heights(self):
1082 # def heights(self):
1082 # '''
1083 # '''
1083 # Return the list of heights of the current data
1084 # Return the list of heights of the current data
1084 # '''
1085 # '''
1085
1086
1086 # return numpy.array(self.__heights[-1])
1087 # return numpy.array(self.__heights[-1])
1087
1088
1088 @staticmethod
1089 @staticmethod
1089 def roundFloats(obj):
1090 def roundFloats(obj):
1090 if isinstance(obj, list):
1091 if isinstance(obj, list):
1091 return list(map(PlotterData.roundFloats, obj))
1092 return list(map(PlotterData.roundFloats, obj))
1092 elif isinstance(obj, float):
1093 elif isinstance(obj, float):
1093 return round(obj, 2)
1094 return round(obj, 2)
@@ -1,1350 +1,1349
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 #import collections.abc
11 #import collections.abc
12
12
13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
14
14
15 class SpectraPlot(Plot):
15 class SpectraPlot(Plot):
16 '''
16 '''
17 Plot for Spectra data
17 Plot for Spectra data
18 '''
18 '''
19
19
20 CODE = 'spc'
20 CODE = 'spc'
21 colormap = 'jet'
21 colormap = 'jet'
22 plot_type = 'pcolor'
22 plot_type = 'pcolor'
23 buffering = False
23 buffering = False
24
24
25 def setup(self):
25 def setup(self):
26
26
27 self.nplots = len(self.data.channels)
27 self.nplots = len(self.data.channels)
28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
30 self.height = 2.6 * self.nrows
30 self.height = 2.6 * self.nrows
31 self.cb_label = 'dB'
31 self.cb_label = 'dB'
32 if self.showprofile:
32 if self.showprofile:
33 self.width = 4 * self.ncols
33 self.width = 4 * self.ncols
34 else:
34 else:
35 self.width = 3.5 * self.ncols
35 self.width = 3.5 * self.ncols
36 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
36 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
37 self.ylabel = 'Range [km]'
37 self.ylabel = 'Range [km]'
38
38
39 def update(self, dataOut):
39 def update(self, dataOut):
40
40
41 data = {}
41 data = {}
42 meta = {}
42 meta = {}
43
43
44 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
44 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
45 #print("dataOut.normFactor: ", dataOut.normFactor)
45 #print("dataOut.normFactor: ", dataOut.normFactor)
46 #print("spc: ", dataOut.data_spc[0,0,0])
46 #print("spc: ", dataOut.data_spc[0,0,0])
47 #spc = 10*numpy.log10(dataOut.data_spc)
47 #spc = 10*numpy.log10(dataOut.data_spc)
48 #print("Spc: ",spc[0])
48 #print("Spc: ",spc[0])
49 #exit(1)
49 #exit(1)
50 data['spc'] = spc
50 data['spc'] = spc
51 data['rti'] = dataOut.getPower()
51 data['rti'] = dataOut.getPower()
52 #print(data['rti'][0])
52 #print(data['rti'][0])
53 #exit(1)
53 #exit(1)
54 #print("NormFactor: ",dataOut.normFactor)
54 #print("NormFactor: ",dataOut.normFactor)
55 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
55 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
56 if hasattr(dataOut, 'LagPlot'): #Double Pulse
56 if hasattr(dataOut, 'LagPlot'): #Double Pulse
57 max_hei_id = dataOut.nHeights - 2*dataOut.LagPlot
57 ymin_index = numpy.abs(dataOut.heightList - 800).argmin()
58 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=46,ymax_index=max_hei_id)/dataOut.normFactor)
58 max_hei_id = dataOut.nHeights - dataOut.TxLagRate*dataOut.LagPlot
59 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=40,ymax_index=max_hei_id)/dataOut.normFactor)
59 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=ymin_index,ymax_index=max_hei_id)/dataOut.normFactor)
60 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=53,ymax_index=max_hei_id)/dataOut.normFactor)
60 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=ymin_index)[0]/dataOut.normFactor)
61 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=53)[0]/dataOut.normFactor)
62 #data['noise'][1] = 22.035507
61 #data['noise'][1] = 22.035507
63 else:
62 else:
64 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
63 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
65 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=26,ymax_index=44)/dataOut.normFactor)
64
66 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
65 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
67
66
68 if self.CODE == 'spc_moments':
67 if self.CODE == 'spc_moments':
69 data['moments'] = dataOut.moments
68 data['moments'] = dataOut.moments
70 if self.CODE == 'gaussian_fit':
69 if self.CODE == 'gaussian_fit':
71 data['gaussfit'] = dataOut.DGauFitParams
70 data['gaussfit'] = dataOut.DGauFitParams
72
71
73 return data, meta
72 return data, meta
74
73
75 def plot(self):
74 def plot(self):
76
75
77 if self.xaxis == "frequency":
76 if self.xaxis == "frequency":
78 x = self.data.xrange[0]
77 x = self.data.xrange[0]
79 self.xlabel = "Frequency (kHz)"
78 self.xlabel = "Frequency (kHz)"
80 elif self.xaxis == "time":
79 elif self.xaxis == "time":
81 x = self.data.xrange[1]
80 x = self.data.xrange[1]
82 self.xlabel = "Time (ms)"
81 self.xlabel = "Time (ms)"
83 else:
82 else:
84 x = self.data.xrange[2]
83 x = self.data.xrange[2]
85 self.xlabel = "Velocity (m/s)"
84 self.xlabel = "Velocity (m/s)"
86
85
87 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
86 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
88 x = self.data.xrange[2]
87 x = self.data.xrange[2]
89 self.xlabel = "Velocity (m/s)"
88 self.xlabel = "Velocity (m/s)"
90
89
91 self.titles = []
90 self.titles = []
92
91
93 y = self.data.yrange
92 y = self.data.yrange
94 self.y = y
93 self.y = y
95
94
96 data = self.data[-1]
95 data = self.data[-1]
97 z = data['spc']
96 z = data['spc']
98
97
99 self.CODE2 = 'spc_oblique'
98 self.CODE2 = 'spc_oblique'
100
99
101 for n, ax in enumerate(self.axes):
100 for n, ax in enumerate(self.axes):
102 noise = data['noise'][n]
101 noise = data['noise'][n]
103 if self.CODE == 'spc_moments':
102 if self.CODE == 'spc_moments':
104 mean = data['moments'][n, 1]
103 mean = data['moments'][n, 1]
105 if self.CODE == 'gaussian_fit':
104 if self.CODE == 'gaussian_fit':
106 gau0 = data['gaussfit'][n][2,:,0]
105 gau0 = data['gaussfit'][n][2,:,0]
107 gau1 = data['gaussfit'][n][2,:,1]
106 gau1 = data['gaussfit'][n][2,:,1]
108 if ax.firsttime:
107 if ax.firsttime:
109 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
108 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
110 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)#-self.xmax
109 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)#-self.xmax
111 #self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
110 #self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
112 #self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
111 #self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
113 if self.zlimits is not None:
112 if self.zlimits is not None:
114 self.zmin, self.zmax = self.zlimits[n]
113 self.zmin, self.zmax = self.zlimits[n]
115
114
116 ax.plt = ax.pcolormesh(x, y, z[n].T,
115 ax.plt = ax.pcolormesh(x, y, z[n].T,
117 vmin=self.zmin,
116 vmin=self.zmin,
118 vmax=self.zmax,
117 vmax=self.zmax,
119 cmap=plt.get_cmap(self.colormap),
118 cmap=plt.get_cmap(self.colormap),
120 )
119 )
121
120
122 if self.showprofile:
121 if self.showprofile:
123 ax.plt_profile = self.pf_axes[n].plot(
122 ax.plt_profile = self.pf_axes[n].plot(
124 data['rti'][n], y)[0]
123 data['rti'][n], y)[0]
125 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
124 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
126 color="k", linestyle="dashed", lw=1)[0]
125 color="k", linestyle="dashed", lw=1)[0]
127 if self.CODE == 'spc_moments':
126 if self.CODE == 'spc_moments':
128 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
127 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
129 if self.CODE == 'gaussian_fit':
128 if self.CODE == 'gaussian_fit':
130 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
129 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
131 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
130 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
132 else:
131 else:
133 if self.zlimits is not None:
132 if self.zlimits is not None:
134 self.zmin, self.zmax = self.zlimits[n]
133 self.zmin, self.zmax = self.zlimits[n]
135 ax.plt.set_array(z[n].T.ravel())
134 ax.plt.set_array(z[n].T.ravel())
136 if self.showprofile:
135 if self.showprofile:
137 ax.plt_profile.set_data(data['rti'][n], y)
136 ax.plt_profile.set_data(data['rti'][n], y)
138 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
137 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
139 if self.CODE == 'spc_moments':
138 if self.CODE == 'spc_moments':
140 ax.plt_mean.set_data(mean, y)
139 ax.plt_mean.set_data(mean, y)
141 if self.CODE == 'gaussian_fit':
140 if self.CODE == 'gaussian_fit':
142 ax.plt_gau0.set_data(gau0, y)
141 ax.plt_gau0.set_data(gau0, y)
143 ax.plt_gau1.set_data(gau1, y)
142 ax.plt_gau1.set_data(gau1, y)
144 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
143 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
145
144
146 class SpectraObliquePlot(Plot):
145 class SpectraObliquePlot(Plot):
147 '''
146 '''
148 Plot for Spectra data
147 Plot for Spectra data
149 '''
148 '''
150
149
151 CODE = 'spc_oblique'
150 CODE = 'spc_oblique'
152 colormap = 'jet'
151 colormap = 'jet'
153 plot_type = 'pcolor'
152 plot_type = 'pcolor'
154
153
155 def setup(self):
154 def setup(self):
156 self.xaxis = "oblique"
155 self.xaxis = "oblique"
157 self.nplots = len(self.data.channels)
156 self.nplots = len(self.data.channels)
158 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
157 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
159 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
158 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
160 self.height = 2.6 * self.nrows
159 self.height = 2.6 * self.nrows
161 self.cb_label = 'dB'
160 self.cb_label = 'dB'
162 if self.showprofile:
161 if self.showprofile:
163 self.width = 4 * self.ncols
162 self.width = 4 * self.ncols
164 else:
163 else:
165 self.width = 3.5 * self.ncols
164 self.width = 3.5 * self.ncols
166 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
165 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
167 self.ylabel = 'Range [km]'
166 self.ylabel = 'Range [km]'
168
167
169 def update(self, dataOut):
168 def update(self, dataOut):
170
169
171 data = {}
170 data = {}
172 meta = {}
171 meta = {}
173
172
174 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
173 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
175 data['spc'] = spc
174 data['spc'] = spc
176 data['rti'] = dataOut.getPower()
175 data['rti'] = dataOut.getPower()
177 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
176 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
178 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
177 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
179 '''
178 '''
180 data['shift1'] = dataOut.Oblique_params[0,-2,:]
179 data['shift1'] = dataOut.Oblique_params[0,-2,:]
181 data['shift2'] = dataOut.Oblique_params[0,-1,:]
180 data['shift2'] = dataOut.Oblique_params[0,-1,:]
182 data['shift1_error'] = dataOut.Oblique_param_errors[0,-2,:]
181 data['shift1_error'] = dataOut.Oblique_param_errors[0,-2,:]
183 data['shift2_error'] = dataOut.Oblique_param_errors[0,-1,:]
182 data['shift2_error'] = dataOut.Oblique_param_errors[0,-1,:]
184 '''
183 '''
185 '''
184 '''
186 data['shift1'] = dataOut.Oblique_params[0,1,:]
185 data['shift1'] = dataOut.Oblique_params[0,1,:]
187 data['shift2'] = dataOut.Oblique_params[0,4,:]
186 data['shift2'] = dataOut.Oblique_params[0,4,:]
188 data['shift1_error'] = dataOut.Oblique_param_errors[0,1,:]
187 data['shift1_error'] = dataOut.Oblique_param_errors[0,1,:]
189 data['shift2_error'] = dataOut.Oblique_param_errors[0,4,:]
188 data['shift2_error'] = dataOut.Oblique_param_errors[0,4,:]
190 '''
189 '''
191 data['shift1'] = dataOut.Dop_EEJ_T1[0]
190 data['shift1'] = dataOut.Dop_EEJ_T1[0]
192 data['shift2'] = dataOut.Dop_EEJ_T2[0]
191 data['shift2'] = dataOut.Dop_EEJ_T2[0]
193 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
192 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
194 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
193 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
195 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
194 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
196
195
197 return data, meta
196 return data, meta
198
197
199 def plot(self):
198 def plot(self):
200
199
201 if self.xaxis == "frequency":
200 if self.xaxis == "frequency":
202 x = self.data.xrange[0]
201 x = self.data.xrange[0]
203 self.xlabel = "Frequency (kHz)"
202 self.xlabel = "Frequency (kHz)"
204 elif self.xaxis == "time":
203 elif self.xaxis == "time":
205 x = self.data.xrange[1]
204 x = self.data.xrange[1]
206 self.xlabel = "Time (ms)"
205 self.xlabel = "Time (ms)"
207 else:
206 else:
208 x = self.data.xrange[2]
207 x = self.data.xrange[2]
209 self.xlabel = "Velocity (m/s)"
208 self.xlabel = "Velocity (m/s)"
210
209
211 self.titles = []
210 self.titles = []
212
211
213 y = self.data.yrange
212 y = self.data.yrange
214 self.y = y
213 self.y = y
215
214
216 data = self.data[-1]
215 data = self.data[-1]
217 z = data['spc']
216 z = data['spc']
218
217
219 for n, ax in enumerate(self.axes):
218 for n, ax in enumerate(self.axes):
220 noise = self.data['noise'][n][-1]
219 noise = self.data['noise'][n][-1]
221 shift1 = data['shift1']
220 shift1 = data['shift1']
222 #print(shift1)
221 #print(shift1)
223 shift2 = data['shift2']
222 shift2 = data['shift2']
224 max_val_2 = data['max_val_2']
223 max_val_2 = data['max_val_2']
225 err1 = data['shift1_error']
224 err1 = data['shift1_error']
226 err2 = data['shift2_error']
225 err2 = data['shift2_error']
227 if ax.firsttime:
226 if ax.firsttime:
228
227
229 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
228 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
230 self.xmin = self.xmin if self.xmin else -self.xmax
229 self.xmin = self.xmin if self.xmin else -self.xmax
231 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
230 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
232 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
231 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
233 ax.plt = ax.pcolormesh(x, y, z[n].T,
232 ax.plt = ax.pcolormesh(x, y, z[n].T,
234 vmin=self.zmin,
233 vmin=self.zmin,
235 vmax=self.zmax,
234 vmax=self.zmax,
236 cmap=plt.get_cmap(self.colormap)
235 cmap=plt.get_cmap(self.colormap)
237 )
236 )
238
237
239 if self.showprofile:
238 if self.showprofile:
240 ax.plt_profile = self.pf_axes[n].plot(
239 ax.plt_profile = self.pf_axes[n].plot(
241 self.data['rti'][n][-1], y)[0]
240 self.data['rti'][n][-1], y)[0]
242 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
241 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
243 color="k", linestyle="dashed", lw=1)[0]
242 color="k", linestyle="dashed", lw=1)[0]
244
243
245 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)
244 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)
246 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)
245 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)
247 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
246 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
248
247
249 #print("plotter1: ", self.ploterr1,shift1)
248 #print("plotter1: ", self.ploterr1,shift1)
250
249
251 else:
250 else:
252 #print("else plotter1: ", self.ploterr1,shift1)
251 #print("else plotter1: ", self.ploterr1,shift1)
253 self.ploterr1.remove()
252 self.ploterr1.remove()
254 self.ploterr2.remove()
253 self.ploterr2.remove()
255 self.ploterr3.remove()
254 self.ploterr3.remove()
256 ax.plt.set_array(z[n].T.ravel())
255 ax.plt.set_array(z[n].T.ravel())
257 if self.showprofile:
256 if self.showprofile:
258 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
257 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
259 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
258 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
260 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)
259 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)
261 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)
260 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)
262 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
261 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
263
262
264 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
263 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
265
264
266
265
267 class CrossSpectraPlot(Plot):
266 class CrossSpectraPlot(Plot):
268
267
269 CODE = 'cspc'
268 CODE = 'cspc'
270 colormap = 'jet'
269 colormap = 'jet'
271 plot_type = 'pcolor'
270 plot_type = 'pcolor'
272 zmin_coh = None
271 zmin_coh = None
273 zmax_coh = None
272 zmax_coh = None
274 zmin_phase = None
273 zmin_phase = None
275 zmax_phase = None
274 zmax_phase = None
276
275
277 def setup(self):
276 def setup(self):
278
277
279 self.ncols = 4
278 self.ncols = 4
280 self.nplots = len(self.data.pairs) * 2
279 self.nplots = len(self.data.pairs) * 2
281 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
280 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
282 self.width = 3.1 * self.ncols
281 self.width = 3.1 * self.ncols
283 self.height = 5 * self.nrows
282 self.height = 5 * self.nrows
284 self.ylabel = 'Range [km]'
283 self.ylabel = 'Range [km]'
285 self.showprofile = False
284 self.showprofile = False
286 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
285 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
287
286
288 def update(self, dataOut):
287 def update(self, dataOut):
289
288
290 data = {}
289 data = {}
291 meta = {}
290 meta = {}
292
291
293 spc = dataOut.data_spc
292 spc = dataOut.data_spc
294 cspc = dataOut.data_cspc
293 cspc = dataOut.data_cspc
295 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
294 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
296 meta['pairs'] = dataOut.pairsList
295 meta['pairs'] = dataOut.pairsList
297
296
298 tmp = []
297 tmp = []
299
298
300 for n, pair in enumerate(meta['pairs']):
299 for n, pair in enumerate(meta['pairs']):
301 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
300 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
302 coh = numpy.abs(out)
301 coh = numpy.abs(out)
303 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
302 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
304 tmp.append(coh)
303 tmp.append(coh)
305 tmp.append(phase)
304 tmp.append(phase)
306
305
307 data['cspc'] = numpy.array(tmp)
306 data['cspc'] = numpy.array(tmp)
308
307
309 return data, meta
308 return data, meta
310
309
311 def plot(self):
310 def plot(self):
312
311
313 if self.xaxis == "frequency":
312 if self.xaxis == "frequency":
314 x = self.data.xrange[0]
313 x = self.data.xrange[0]
315 self.xlabel = "Frequency (kHz)"
314 self.xlabel = "Frequency (kHz)"
316 elif self.xaxis == "time":
315 elif self.xaxis == "time":
317 x = self.data.xrange[1]
316 x = self.data.xrange[1]
318 self.xlabel = "Time (ms)"
317 self.xlabel = "Time (ms)"
319 else:
318 else:
320 x = self.data.xrange[2]
319 x = self.data.xrange[2]
321 self.xlabel = "Velocity (m/s)"
320 self.xlabel = "Velocity (m/s)"
322
321
323 self.titles = []
322 self.titles = []
324
323
325 y = self.data.yrange
324 y = self.data.yrange
326 self.y = y
325 self.y = y
327
326
328 data = self.data[-1]
327 data = self.data[-1]
329 cspc = data['cspc']
328 cspc = data['cspc']
330
329
331 for n in range(len(self.data.pairs)):
330 for n in range(len(self.data.pairs)):
332 pair = self.data.pairs[n]
331 pair = self.data.pairs[n]
333 coh = cspc[n*2]
332 coh = cspc[n*2]
334 phase = cspc[n*2+1]
333 phase = cspc[n*2+1]
335 ax = self.axes[2 * n]
334 ax = self.axes[2 * n]
336 if ax.firsttime:
335 if ax.firsttime:
337 ax.plt = ax.pcolormesh(x, y, coh.T,
336 ax.plt = ax.pcolormesh(x, y, coh.T,
338 vmin=0,
337 vmin=0,
339 vmax=1,
338 vmax=1,
340 cmap=plt.get_cmap(self.colormap_coh)
339 cmap=plt.get_cmap(self.colormap_coh)
341 )
340 )
342 else:
341 else:
343 ax.plt.set_array(coh.T.ravel())
342 ax.plt.set_array(coh.T.ravel())
344 self.titles.append(
343 self.titles.append(
345 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
344 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
346
345
347 ax = self.axes[2 * n + 1]
346 ax = self.axes[2 * n + 1]
348 if ax.firsttime:
347 if ax.firsttime:
349 ax.plt = ax.pcolormesh(x, y, phase.T,
348 ax.plt = ax.pcolormesh(x, y, phase.T,
350 vmin=-180,
349 vmin=-180,
351 vmax=180,
350 vmax=180,
352 cmap=plt.get_cmap(self.colormap_phase)
351 cmap=plt.get_cmap(self.colormap_phase)
353 )
352 )
354 else:
353 else:
355 ax.plt.set_array(phase.T.ravel())
354 ax.plt.set_array(phase.T.ravel())
356 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
355 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
357
356
358
357
359 class CrossSpectra4Plot(Plot):
358 class CrossSpectra4Plot(Plot):
360
359
361 CODE = 'cspc'
360 CODE = 'cspc'
362 colormap = 'jet'
361 colormap = 'jet'
363 plot_type = 'pcolor'
362 plot_type = 'pcolor'
364 zmin_coh = None
363 zmin_coh = None
365 zmax_coh = None
364 zmax_coh = None
366 zmin_phase = None
365 zmin_phase = None
367 zmax_phase = None
366 zmax_phase = None
368
367
369 def setup(self):
368 def setup(self):
370
369
371 self.ncols = 4
370 self.ncols = 4
372 self.nrows = len(self.data.pairs)
371 self.nrows = len(self.data.pairs)
373 self.nplots = self.nrows * 4
372 self.nplots = self.nrows * 4
374 self.width = 3.1 * self.ncols
373 self.width = 3.1 * self.ncols
375 self.height = 5 * self.nrows
374 self.height = 5 * self.nrows
376 self.ylabel = 'Range [km]'
375 self.ylabel = 'Range [km]'
377 self.showprofile = False
376 self.showprofile = False
378 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
377 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
379
378
380 def plot(self):
379 def plot(self):
381
380
382 if self.xaxis == "frequency":
381 if self.xaxis == "frequency":
383 x = self.data.xrange[0]
382 x = self.data.xrange[0]
384 self.xlabel = "Frequency (kHz)"
383 self.xlabel = "Frequency (kHz)"
385 elif self.xaxis == "time":
384 elif self.xaxis == "time":
386 x = self.data.xrange[1]
385 x = self.data.xrange[1]
387 self.xlabel = "Time (ms)"
386 self.xlabel = "Time (ms)"
388 else:
387 else:
389 x = self.data.xrange[2]
388 x = self.data.xrange[2]
390 self.xlabel = "Velocity (m/s)"
389 self.xlabel = "Velocity (m/s)"
391
390
392 self.titles = []
391 self.titles = []
393
392
394
393
395 y = self.data.heights
394 y = self.data.heights
396 self.y = y
395 self.y = y
397 nspc = self.data['spc']
396 nspc = self.data['spc']
398 #print(numpy.shape(self.data['spc']))
397 #print(numpy.shape(self.data['spc']))
399 spc = self.data['cspc'][0]
398 spc = self.data['cspc'][0]
400 #print(numpy.shape(nspc))
399 #print(numpy.shape(nspc))
401 #exit()
400 #exit()
402 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
401 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
403 #print(numpy.shape(spc))
402 #print(numpy.shape(spc))
404 #exit()
403 #exit()
405 cspc = self.data['cspc'][1]
404 cspc = self.data['cspc'][1]
406
405
407 #xflip=numpy.flip(x)
406 #xflip=numpy.flip(x)
408 #print(numpy.shape(cspc))
407 #print(numpy.shape(cspc))
409 #exit()
408 #exit()
410
409
411 for n in range(self.nrows):
410 for n in range(self.nrows):
412 noise = self.data['noise'][:,-1]
411 noise = self.data['noise'][:,-1]
413 pair = self.data.pairs[n]
412 pair = self.data.pairs[n]
414 #print(pair)
413 #print(pair)
415 #exit()
414 #exit()
416 ax = self.axes[4 * n]
415 ax = self.axes[4 * n]
417 if ax.firsttime:
416 if ax.firsttime:
418 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
417 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
419 self.xmin = self.xmin if self.xmin else -self.xmax
418 self.xmin = self.xmin if self.xmin else -self.xmax
420 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
419 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
421 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
420 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
422 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
421 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
423 vmin=self.zmin,
422 vmin=self.zmin,
424 vmax=self.zmax,
423 vmax=self.zmax,
425 cmap=plt.get_cmap(self.colormap)
424 cmap=plt.get_cmap(self.colormap)
426 )
425 )
427 else:
426 else:
428 #print(numpy.shape(nspc[pair[0]].T))
427 #print(numpy.shape(nspc[pair[0]].T))
429 #exit()
428 #exit()
430 ax.plt.set_array(nspc[pair[0]].T.ravel())
429 ax.plt.set_array(nspc[pair[0]].T.ravel())
431 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
430 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
432
431
433 ax = self.axes[4 * n + 1]
432 ax = self.axes[4 * n + 1]
434
433
435 if ax.firsttime:
434 if ax.firsttime:
436 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
435 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
437 vmin=self.zmin,
436 vmin=self.zmin,
438 vmax=self.zmax,
437 vmax=self.zmax,
439 cmap=plt.get_cmap(self.colormap)
438 cmap=plt.get_cmap(self.colormap)
440 )
439 )
441 else:
440 else:
442
441
443 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
442 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
444 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
443 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
445
444
446 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
445 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
447 coh = numpy.abs(out)
446 coh = numpy.abs(out)
448 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
447 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
449
448
450 ax = self.axes[4 * n + 2]
449 ax = self.axes[4 * n + 2]
451 if ax.firsttime:
450 if ax.firsttime:
452 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
451 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
453 vmin=0,
452 vmin=0,
454 vmax=1,
453 vmax=1,
455 cmap=plt.get_cmap(self.colormap_coh)
454 cmap=plt.get_cmap(self.colormap_coh)
456 )
455 )
457 else:
456 else:
458 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
457 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
459 self.titles.append(
458 self.titles.append(
460 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
459 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
461
460
462 ax = self.axes[4 * n + 3]
461 ax = self.axes[4 * n + 3]
463 if ax.firsttime:
462 if ax.firsttime:
464 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
463 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
465 vmin=-180,
464 vmin=-180,
466 vmax=180,
465 vmax=180,
467 cmap=plt.get_cmap(self.colormap_phase)
466 cmap=plt.get_cmap(self.colormap_phase)
468 )
467 )
469 else:
468 else:
470 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
469 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
471 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
470 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
472
471
473
472
474 class CrossSpectra2Plot(Plot):
473 class CrossSpectra2Plot(Plot):
475
474
476 CODE = 'cspc'
475 CODE = 'cspc'
477 colormap = 'jet'
476 colormap = 'jet'
478 plot_type = 'pcolor'
477 plot_type = 'pcolor'
479 zmin_coh = None
478 zmin_coh = None
480 zmax_coh = None
479 zmax_coh = None
481 zmin_phase = None
480 zmin_phase = None
482 zmax_phase = None
481 zmax_phase = None
483
482
484 def setup(self):
483 def setup(self):
485
484
486 self.ncols = 1
485 self.ncols = 1
487 self.nrows = len(self.data.pairs)
486 self.nrows = len(self.data.pairs)
488 self.nplots = self.nrows * 1
487 self.nplots = self.nrows * 1
489 self.width = 3.1 * self.ncols
488 self.width = 3.1 * self.ncols
490 self.height = 5 * self.nrows
489 self.height = 5 * self.nrows
491 self.ylabel = 'Range [km]'
490 self.ylabel = 'Range [km]'
492 self.showprofile = False
491 self.showprofile = False
493 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
492 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
494
493
495 def plot(self):
494 def plot(self):
496
495
497 if self.xaxis == "frequency":
496 if self.xaxis == "frequency":
498 x = self.data.xrange[0]
497 x = self.data.xrange[0]
499 self.xlabel = "Frequency (kHz)"
498 self.xlabel = "Frequency (kHz)"
500 elif self.xaxis == "time":
499 elif self.xaxis == "time":
501 x = self.data.xrange[1]
500 x = self.data.xrange[1]
502 self.xlabel = "Time (ms)"
501 self.xlabel = "Time (ms)"
503 else:
502 else:
504 x = self.data.xrange[2]
503 x = self.data.xrange[2]
505 self.xlabel = "Velocity (m/s)"
504 self.xlabel = "Velocity (m/s)"
506
505
507 self.titles = []
506 self.titles = []
508
507
509
508
510 y = self.data.heights
509 y = self.data.heights
511 self.y = y
510 self.y = y
512 #nspc = self.data['spc']
511 #nspc = self.data['spc']
513 #print(numpy.shape(self.data['spc']))
512 #print(numpy.shape(self.data['spc']))
514 #spc = self.data['cspc'][0]
513 #spc = self.data['cspc'][0]
515 #print(numpy.shape(spc))
514 #print(numpy.shape(spc))
516 #exit()
515 #exit()
517 cspc = self.data['cspc'][1]
516 cspc = self.data['cspc'][1]
518 #print(numpy.shape(cspc))
517 #print(numpy.shape(cspc))
519 #exit()
518 #exit()
520
519
521 for n in range(self.nrows):
520 for n in range(self.nrows):
522 noise = self.data['noise'][:,-1]
521 noise = self.data['noise'][:,-1]
523 pair = self.data.pairs[n]
522 pair = self.data.pairs[n]
524 #print(pair) #exit()
523 #print(pair) #exit()
525
524
526
525
527
526
528 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
527 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
529
528
530 #print(out[:,53])
529 #print(out[:,53])
531 #exit()
530 #exit()
532 cross = numpy.abs(out)
531 cross = numpy.abs(out)
533 z = cross/self.data.nFactor
532 z = cross/self.data.nFactor
534 #print("here")
533 #print("here")
535 #print(dataOut.data_spc[0,0,0])
534 #print(dataOut.data_spc[0,0,0])
536 #exit()
535 #exit()
537
536
538 cross = 10*numpy.log10(z)
537 cross = 10*numpy.log10(z)
539 #print(numpy.shape(cross))
538 #print(numpy.shape(cross))
540 #print(cross[0,:])
539 #print(cross[0,:])
541 #print(self.data.nFactor)
540 #print(self.data.nFactor)
542 #exit()
541 #exit()
543 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
542 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
544
543
545 ax = self.axes[1 * n]
544 ax = self.axes[1 * n]
546 if ax.firsttime:
545 if ax.firsttime:
547 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
546 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
548 self.xmin = self.xmin if self.xmin else -self.xmax
547 self.xmin = self.xmin if self.xmin else -self.xmax
549 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
548 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
550 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
549 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
551 ax.plt = ax.pcolormesh(x, y, cross.T,
550 ax.plt = ax.pcolormesh(x, y, cross.T,
552 vmin=self.zmin,
551 vmin=self.zmin,
553 vmax=self.zmax,
552 vmax=self.zmax,
554 cmap=plt.get_cmap(self.colormap)
553 cmap=plt.get_cmap(self.colormap)
555 )
554 )
556 else:
555 else:
557 ax.plt.set_array(cross.T.ravel())
556 ax.plt.set_array(cross.T.ravel())
558 self.titles.append(
557 self.titles.append(
559 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
558 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
560
559
561
560
562 class CrossSpectra3Plot(Plot):
561 class CrossSpectra3Plot(Plot):
563
562
564 CODE = 'cspc'
563 CODE = 'cspc'
565 colormap = 'jet'
564 colormap = 'jet'
566 plot_type = 'pcolor'
565 plot_type = 'pcolor'
567 zmin_coh = None
566 zmin_coh = None
568 zmax_coh = None
567 zmax_coh = None
569 zmin_phase = None
568 zmin_phase = None
570 zmax_phase = None
569 zmax_phase = None
571
570
572 def setup(self):
571 def setup(self):
573
572
574 self.ncols = 3
573 self.ncols = 3
575 self.nrows = len(self.data.pairs)
574 self.nrows = len(self.data.pairs)
576 self.nplots = self.nrows * 3
575 self.nplots = self.nrows * 3
577 self.width = 3.1 * self.ncols
576 self.width = 3.1 * self.ncols
578 self.height = 5 * self.nrows
577 self.height = 5 * self.nrows
579 self.ylabel = 'Range [km]'
578 self.ylabel = 'Range [km]'
580 self.showprofile = False
579 self.showprofile = False
581 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
580 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
582
581
583 def plot(self):
582 def plot(self):
584
583
585 if self.xaxis == "frequency":
584 if self.xaxis == "frequency":
586 x = self.data.xrange[0]
585 x = self.data.xrange[0]
587 self.xlabel = "Frequency (kHz)"
586 self.xlabel = "Frequency (kHz)"
588 elif self.xaxis == "time":
587 elif self.xaxis == "time":
589 x = self.data.xrange[1]
588 x = self.data.xrange[1]
590 self.xlabel = "Time (ms)"
589 self.xlabel = "Time (ms)"
591 else:
590 else:
592 x = self.data.xrange[2]
591 x = self.data.xrange[2]
593 self.xlabel = "Velocity (m/s)"
592 self.xlabel = "Velocity (m/s)"
594
593
595 self.titles = []
594 self.titles = []
596
595
597
596
598 y = self.data.heights
597 y = self.data.heights
599 self.y = y
598 self.y = y
600 #nspc = self.data['spc']
599 #nspc = self.data['spc']
601 #print(numpy.shape(self.data['spc']))
600 #print(numpy.shape(self.data['spc']))
602 #spc = self.data['cspc'][0]
601 #spc = self.data['cspc'][0]
603 #print(numpy.shape(spc))
602 #print(numpy.shape(spc))
604 #exit()
603 #exit()
605 cspc = self.data['cspc'][1]
604 cspc = self.data['cspc'][1]
606 #print(numpy.shape(cspc))
605 #print(numpy.shape(cspc))
607 #exit()
606 #exit()
608
607
609 for n in range(self.nrows):
608 for n in range(self.nrows):
610 noise = self.data['noise'][:,-1]
609 noise = self.data['noise'][:,-1]
611 pair = self.data.pairs[n]
610 pair = self.data.pairs[n]
612 #print(pair) #exit()
611 #print(pair) #exit()
613
612
614
613
615
614
616 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
615 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
617
616
618 #print(out[:,53])
617 #print(out[:,53])
619 #exit()
618 #exit()
620 cross = numpy.abs(out)
619 cross = numpy.abs(out)
621 z = cross/self.data.nFactor
620 z = cross/self.data.nFactor
622 cross = 10*numpy.log10(z)
621 cross = 10*numpy.log10(z)
623
622
624 out_r= out.real/self.data.nFactor
623 out_r= out.real/self.data.nFactor
625 #out_r = 10*numpy.log10(out_r)
624 #out_r = 10*numpy.log10(out_r)
626
625
627 out_i= out.imag/self.data.nFactor
626 out_i= out.imag/self.data.nFactor
628 #out_i = 10*numpy.log10(out_i)
627 #out_i = 10*numpy.log10(out_i)
629 #print(numpy.shape(cross))
628 #print(numpy.shape(cross))
630 #print(cross[0,:])
629 #print(cross[0,:])
631 #print(self.data.nFactor)
630 #print(self.data.nFactor)
632 #exit()
631 #exit()
633 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
632 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
634
633
635 ax = self.axes[3 * n]
634 ax = self.axes[3 * n]
636 if ax.firsttime:
635 if ax.firsttime:
637 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
636 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
638 self.xmin = self.xmin if self.xmin else -self.xmax
637 self.xmin = self.xmin if self.xmin else -self.xmax
639 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
638 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
640 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
639 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
641 ax.plt = ax.pcolormesh(x, y, cross.T,
640 ax.plt = ax.pcolormesh(x, y, cross.T,
642 vmin=self.zmin,
641 vmin=self.zmin,
643 vmax=self.zmax,
642 vmax=self.zmax,
644 cmap=plt.get_cmap(self.colormap)
643 cmap=plt.get_cmap(self.colormap)
645 )
644 )
646 else:
645 else:
647 ax.plt.set_array(cross.T.ravel())
646 ax.plt.set_array(cross.T.ravel())
648 self.titles.append(
647 self.titles.append(
649 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
648 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
650
649
651 ax = self.axes[3 * n + 1]
650 ax = self.axes[3 * n + 1]
652 if ax.firsttime:
651 if ax.firsttime:
653 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
652 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
654 self.xmin = self.xmin if self.xmin else -self.xmax
653 self.xmin = self.xmin if self.xmin else -self.xmax
655 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
654 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
656 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
655 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
657 ax.plt = ax.pcolormesh(x, y, out_r.T,
656 ax.plt = ax.pcolormesh(x, y, out_r.T,
658 vmin=-1.e6,
657 vmin=-1.e6,
659 vmax=0,
658 vmax=0,
660 cmap=plt.get_cmap(self.colormap)
659 cmap=plt.get_cmap(self.colormap)
661 )
660 )
662 else:
661 else:
663 ax.plt.set_array(out_r.T.ravel())
662 ax.plt.set_array(out_r.T.ravel())
664 self.titles.append(
663 self.titles.append(
665 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
664 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
666
665
667 ax = self.axes[3 * n + 2]
666 ax = self.axes[3 * n + 2]
668
667
669
668
670 if ax.firsttime:
669 if ax.firsttime:
671 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
670 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
672 self.xmin = self.xmin if self.xmin else -self.xmax
671 self.xmin = self.xmin if self.xmin else -self.xmax
673 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
672 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
674 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
673 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
675 ax.plt = ax.pcolormesh(x, y, out_i.T,
674 ax.plt = ax.pcolormesh(x, y, out_i.T,
676 vmin=-1.e6,
675 vmin=-1.e6,
677 vmax=1.e6,
676 vmax=1.e6,
678 cmap=plt.get_cmap(self.colormap)
677 cmap=plt.get_cmap(self.colormap)
679 )
678 )
680 else:
679 else:
681 ax.plt.set_array(out_i.T.ravel())
680 ax.plt.set_array(out_i.T.ravel())
682 self.titles.append(
681 self.titles.append(
683 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
682 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
684
683
685 class RTIPlot(Plot):
684 class RTIPlot(Plot):
686 '''
685 '''
687 Plot for RTI data
686 Plot for RTI data
688 '''
687 '''
689
688
690 CODE = 'rti'
689 CODE = 'rti'
691 colormap = 'jet'
690 colormap = 'jet'
692 plot_type = 'pcolorbuffer'
691 plot_type = 'pcolorbuffer'
693
692
694 def setup(self):
693 def setup(self):
695 self.xaxis = 'time'
694 self.xaxis = 'time'
696 self.ncols = 1
695 self.ncols = 1
697 self.nrows = len(self.data.channels)
696 self.nrows = len(self.data.channels)
698 self.nplots = len(self.data.channels)
697 self.nplots = len(self.data.channels)
699 self.ylabel = 'Range [km]'
698 self.ylabel = 'Range [km]'
700 self.xlabel = 'Time'
699 self.xlabel = 'Time'
701 self.cb_label = 'dB'
700 self.cb_label = 'dB'
702 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
701 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
703 self.titles = ['{} Channel {}'.format(
702 self.titles = ['{} Channel {}'.format(
704 self.CODE.upper(), x) for x in range(self.nrows)]
703 self.CODE.upper(), x) for x in range(self.nrows)]
705
704
706 def update(self, dataOut):
705 def update(self, dataOut):
707
706
708 data = {}
707 data = {}
709 meta = {}
708 meta = {}
710 data['rti'] = dataOut.getPower()
709 data['rti'] = dataOut.getPower()
711 #print(numpy.shape(data['rti']))
710 #print(numpy.shape(data['rti']))
712
711
713 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
712 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
714
713
715 return data, meta
714 return data, meta
716
715
717 def plot(self):
716 def plot(self):
718
717
719 self.x = self.data.times
718 self.x = self.data.times
720 self.y = self.data.yrange
719 self.y = self.data.yrange
721 self.z = self.data[self.CODE]
720 self.z = self.data[self.CODE]
722 #print("Inside RTI: ", self.z)
721 #print("Inside RTI: ", self.z)
723 self.z = numpy.ma.masked_invalid(self.z)
722 self.z = numpy.ma.masked_invalid(self.z)
724
723
725 if self.decimation is None:
724 if self.decimation is None:
726 x, y, z = self.fill_gaps(self.x, self.y, self.z)
725 x, y, z = self.fill_gaps(self.x, self.y, self.z)
727 else:
726 else:
728 x, y, z = self.fill_gaps(*self.decimate())
727 x, y, z = self.fill_gaps(*self.decimate())
729 #print("self.z: ", self.z)
728 #print("self.z: ", self.z)
730 #exit(1)
729 #exit(1)
731 '''
730 '''
732 if not isinstance(self.zmin, collections.abc.Sequence):
731 if not isinstance(self.zmin, collections.abc.Sequence):
733 if not self.zmin:
732 if not self.zmin:
734 self.zmin = [numpy.min(self.z)]*len(self.axes)
733 self.zmin = [numpy.min(self.z)]*len(self.axes)
735 else:
734 else:
736 self.zmin = [self.zmin]*len(self.axes)
735 self.zmin = [self.zmin]*len(self.axes)
737
736
738 if not isinstance(self.zmax, collections.abc.Sequence):
737 if not isinstance(self.zmax, collections.abc.Sequence):
739 if not self.zmax:
738 if not self.zmax:
740 self.zmax = [numpy.max(self.z)]*len(self.axes)
739 self.zmax = [numpy.max(self.z)]*len(self.axes)
741 else:
740 else:
742 self.zmax = [self.zmax]*len(self.axes)
741 self.zmax = [self.zmax]*len(self.axes)
743 '''
742 '''
744 for n, ax in enumerate(self.axes):
743 for n, ax in enumerate(self.axes):
745
744
746 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
745 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
747 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
746 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
748
747
749 if ax.firsttime:
748 if ax.firsttime:
750 if self.zlimits is not None:
749 if self.zlimits is not None:
751 self.zmin, self.zmax = self.zlimits[n]
750 self.zmin, self.zmax = self.zlimits[n]
752 ax.plt = ax.pcolormesh(x, y, z[n].T,
751 ax.plt = ax.pcolormesh(x, y, z[n].T,
753 vmin=self.zmin,
752 vmin=self.zmin,
754 vmax=self.zmax,
753 vmax=self.zmax,
755 cmap=plt.get_cmap(self.colormap)
754 cmap=plt.get_cmap(self.colormap)
756 )
755 )
757 if self.showprofile:
756 if self.showprofile:
758 ax.plot_profile = self.pf_axes[n].plot(
757 ax.plot_profile = self.pf_axes[n].plot(
759 self.data['rti'][n][-1], self.y)[0]
758 self.data['rti'][n][-1], self.y)[0]
760 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
759 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
761 color="k", linestyle="dashed", lw=1)[0]
760 color="k", linestyle="dashed", lw=1)[0]
762 else:
761 else:
763 if self.zlimits is not None:
762 if self.zlimits is not None:
764 self.zmin, self.zmax = self.zlimits[n]
763 self.zmin, self.zmax = self.zlimits[n]
765 ax.plt.remove()
764 ax.plt.remove()
766 ax.plt = ax.pcolormesh(x, y, z[n].T,
765 ax.plt = ax.pcolormesh(x, y, z[n].T,
767 vmin=self.zmin,
766 vmin=self.zmin,
768 vmax=self.zmax,
767 vmax=self.zmax,
769 cmap=plt.get_cmap(self.colormap)
768 cmap=plt.get_cmap(self.colormap)
770 )
769 )
771 if self.showprofile:
770 if self.showprofile:
772 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
771 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
773 ax.plot_noise.set_data(numpy.repeat(
772 ax.plot_noise.set_data(numpy.repeat(
774 self.data['noise'][n][-1], len(self.y)), self.y)
773 self.data['noise'][n][-1], len(self.y)), self.y)
775
774
776
775
777 class SpectrogramPlot(Plot):
776 class SpectrogramPlot(Plot):
778 '''
777 '''
779 Plot for Spectrogram data
778 Plot for Spectrogram data
780 '''
779 '''
781
780
782 CODE = 'Spectrogram_Profile'
781 CODE = 'Spectrogram_Profile'
783 colormap = 'binary'
782 colormap = 'binary'
784 plot_type = 'pcolorbuffer'
783 plot_type = 'pcolorbuffer'
785
784
786 def setup(self):
785 def setup(self):
787 self.xaxis = 'time'
786 self.xaxis = 'time'
788 self.ncols = 1
787 self.ncols = 1
789 self.nrows = len(self.data.channels)
788 self.nrows = len(self.data.channels)
790 self.nplots = len(self.data.channels)
789 self.nplots = len(self.data.channels)
791 self.xlabel = 'Time'
790 self.xlabel = 'Time'
792 #self.cb_label = 'dB'
791 #self.cb_label = 'dB'
793 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
792 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
794 self.titles = []
793 self.titles = []
795
794
796 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
795 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
797 #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)]
796 #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)]
798
797
799 self.titles = ['{} Channel {}'.format(
798 self.titles = ['{} Channel {}'.format(
800 self.CODE.upper(), x) for x in range(self.nrows)]
799 self.CODE.upper(), x) for x in range(self.nrows)]
801
800
802
801
803 def update(self, dataOut):
802 def update(self, dataOut):
804 data = {}
803 data = {}
805 meta = {}
804 meta = {}
806
805
807 maxHei = 1620#+12000
806 maxHei = 1620#+12000
808 maxHei = 1180
807 maxHei = 1180
809 maxHei = 500
808 maxHei = 500
810 indb = numpy.where(dataOut.heightList <= maxHei)
809 indb = numpy.where(dataOut.heightList <= maxHei)
811 hei = indb[0][-1]
810 hei = indb[0][-1]
812 #print(dataOut.heightList)
811 #print(dataOut.heightList)
813
812
814 factor = dataOut.nIncohInt
813 factor = dataOut.nIncohInt
815 z = dataOut.data_spc[:,:,hei] / factor
814 z = dataOut.data_spc[:,:,hei] / factor
816 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
815 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
817 #buffer = 10 * numpy.log10(z)
816 #buffer = 10 * numpy.log10(z)
818
817
819 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
818 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
820
819
821
820
822 #self.hei = hei
821 #self.hei = hei
823 #self.heightList = dataOut.heightList
822 #self.heightList = dataOut.heightList
824 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
823 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
825 #self.nProfiles = dataOut.nProfiles
824 #self.nProfiles = dataOut.nProfiles
826
825
827 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
826 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
828
827
829 data['hei'] = hei
828 data['hei'] = hei
830 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
829 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
831 data['nProfiles'] = dataOut.nProfiles
830 data['nProfiles'] = dataOut.nProfiles
832 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
831 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
833 '''
832 '''
834 import matplotlib.pyplot as plt
833 import matplotlib.pyplot as plt
835 plt.plot(10 * numpy.log10(z[0,:]))
834 plt.plot(10 * numpy.log10(z[0,:]))
836 plt.show()
835 plt.show()
837
836
838 from time import sleep
837 from time import sleep
839 sleep(10)
838 sleep(10)
840 '''
839 '''
841 return data, meta
840 return data, meta
842
841
843 def plot(self):
842 def plot(self):
844
843
845 self.x = self.data.times
844 self.x = self.data.times
846 self.z = self.data[self.CODE]
845 self.z = self.data[self.CODE]
847 self.y = self.data.xrange[0]
846 self.y = self.data.xrange[0]
848
847
849 hei = self.data['hei'][-1]
848 hei = self.data['hei'][-1]
850 DH = self.data['DH'][-1]
849 DH = self.data['DH'][-1]
851 nProfiles = self.data['nProfiles'][-1]
850 nProfiles = self.data['nProfiles'][-1]
852
851
853 self.ylabel = "Frequency (kHz)"
852 self.ylabel = "Frequency (kHz)"
854
853
855 self.z = numpy.ma.masked_invalid(self.z)
854 self.z = numpy.ma.masked_invalid(self.z)
856
855
857 if self.decimation is None:
856 if self.decimation is None:
858 x, y, z = self.fill_gaps(self.x, self.y, self.z)
857 x, y, z = self.fill_gaps(self.x, self.y, self.z)
859 else:
858 else:
860 x, y, z = self.fill_gaps(*self.decimate())
859 x, y, z = self.fill_gaps(*self.decimate())
861
860
862 for n, ax in enumerate(self.axes):
861 for n, ax in enumerate(self.axes):
863 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
862 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
864 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
863 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
865 data = self.data[-1]
864 data = self.data[-1]
866 if ax.firsttime:
865 if ax.firsttime:
867 ax.plt = ax.pcolormesh(x, y, z[n].T,
866 ax.plt = ax.pcolormesh(x, y, z[n].T,
868 vmin=self.zmin,
867 vmin=self.zmin,
869 vmax=self.zmax,
868 vmax=self.zmax,
870 cmap=plt.get_cmap(self.colormap)
869 cmap=plt.get_cmap(self.colormap)
871 )
870 )
872 else:
871 else:
873 ax.plt.remove()
872 ax.plt.remove()
874 ax.plt = ax.pcolormesh(x, y, z[n].T,
873 ax.plt = ax.pcolormesh(x, y, z[n].T,
875 vmin=self.zmin,
874 vmin=self.zmin,
876 vmax=self.zmax,
875 vmax=self.zmax,
877 cmap=plt.get_cmap(self.colormap)
876 cmap=plt.get_cmap(self.colormap)
878 )
877 )
879
878
880 #self.titles.append('Spectrogram')
879 #self.titles.append('Spectrogram')
881
880
882 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
881 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
883 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
882 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
884
883
885
884
886
885
887
886
888 class CoherencePlot(RTIPlot):
887 class CoherencePlot(RTIPlot):
889 '''
888 '''
890 Plot for Coherence data
889 Plot for Coherence data
891 '''
890 '''
892
891
893 CODE = 'coh'
892 CODE = 'coh'
894
893
895 def setup(self):
894 def setup(self):
896 self.xaxis = 'time'
895 self.xaxis = 'time'
897 self.ncols = 1
896 self.ncols = 1
898 self.nrows = len(self.data.pairs)
897 self.nrows = len(self.data.pairs)
899 self.nplots = len(self.data.pairs)
898 self.nplots = len(self.data.pairs)
900 self.ylabel = 'Range [km]'
899 self.ylabel = 'Range [km]'
901 self.xlabel = 'Time'
900 self.xlabel = 'Time'
902 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
901 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
903 if self.CODE == 'coh':
902 if self.CODE == 'coh':
904 self.cb_label = ''
903 self.cb_label = ''
905 self.titles = [
904 self.titles = [
906 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
905 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
907 else:
906 else:
908 self.cb_label = 'Degrees'
907 self.cb_label = 'Degrees'
909 self.titles = [
908 self.titles = [
910 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
909 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
911
910
912 def update(self, dataOut):
911 def update(self, dataOut):
913
912
914 data = {}
913 data = {}
915 meta = {}
914 meta = {}
916 data['coh'] = dataOut.getCoherence()
915 data['coh'] = dataOut.getCoherence()
917 meta['pairs'] = dataOut.pairsList
916 meta['pairs'] = dataOut.pairsList
918
917
919 return data, meta
918 return data, meta
920
919
921 class PhasePlot(CoherencePlot):
920 class PhasePlot(CoherencePlot):
922 '''
921 '''
923 Plot for Phase map data
922 Plot for Phase map data
924 '''
923 '''
925
924
926 CODE = 'phase'
925 CODE = 'phase'
927 colormap = 'seismic'
926 colormap = 'seismic'
928
927
929 def update(self, dataOut):
928 def update(self, dataOut):
930
929
931 data = {}
930 data = {}
932 meta = {}
931 meta = {}
933 data['phase'] = dataOut.getCoherence(phase=True)
932 data['phase'] = dataOut.getCoherence(phase=True)
934 meta['pairs'] = dataOut.pairsList
933 meta['pairs'] = dataOut.pairsList
935
934
936 return data, meta
935 return data, meta
937
936
938 class NoisePlot(Plot):
937 class NoisePlot(Plot):
939 '''
938 '''
940 Plot for noise
939 Plot for noise
941 '''
940 '''
942
941
943 CODE = 'noise'
942 CODE = 'noise'
944 plot_type = 'scatterbuffer'
943 plot_type = 'scatterbuffer'
945
944
946 def setup(self):
945 def setup(self):
947 self.xaxis = 'time'
946 self.xaxis = 'time'
948 self.ncols = 1
947 self.ncols = 1
949 self.nrows = 1
948 self.nrows = 1
950 self.nplots = 1
949 self.nplots = 1
951 self.ylabel = 'Intensity [dB]'
950 self.ylabel = 'Intensity [dB]'
952 self.xlabel = 'Time'
951 self.xlabel = 'Time'
953 self.titles = ['Noise']
952 self.titles = ['Noise']
954 self.colorbar = False
953 self.colorbar = False
955 self.plots_adjust.update({'right': 0.85 })
954 self.plots_adjust.update({'right': 0.85 })
956
955
957 def update(self, dataOut):
956 def update(self, dataOut):
958
957
959 data = {}
958 data = {}
960 meta = {}
959 meta = {}
961 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
960 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
962 meta['yrange'] = numpy.array([])
961 meta['yrange'] = numpy.array([])
963
962
964 return data, meta
963 return data, meta
965
964
966 def plot(self):
965 def plot(self):
967
966
968 x = self.data.times
967 x = self.data.times
969 xmin = self.data.min_time
968 xmin = self.data.min_time
970 xmax = xmin + self.xrange * 60 * 60
969 xmax = xmin + self.xrange * 60 * 60
971 Y = self.data['noise']
970 Y = self.data['noise']
972
971
973 if self.axes[0].firsttime:
972 if self.axes[0].firsttime:
974 self.ymin = numpy.nanmin(Y) - 5
973 self.ymin = numpy.nanmin(Y) - 5
975 self.ymax = numpy.nanmax(Y) + 5
974 self.ymax = numpy.nanmax(Y) + 5
976 for ch in self.data.channels:
975 for ch in self.data.channels:
977 y = Y[ch]
976 y = Y[ch]
978 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
977 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
979 plt.legend(bbox_to_anchor=(1.18, 1.0))
978 plt.legend(bbox_to_anchor=(1.18, 1.0))
980 else:
979 else:
981 for ch in self.data.channels:
980 for ch in self.data.channels:
982 y = Y[ch]
981 y = Y[ch]
983 self.axes[0].lines[ch].set_data(x, y)
982 self.axes[0].lines[ch].set_data(x, y)
984
983
985 self.ymin = numpy.nanmin(Y) - 5
984 self.ymin = numpy.nanmin(Y) - 5
986 self.ymax = numpy.nanmax(Y) + 10
985 self.ymax = numpy.nanmax(Y) + 10
987
986
988
987
989 class PowerProfilePlot(Plot):
988 class PowerProfilePlot(Plot):
990
989
991 CODE = 'pow_profile'
990 CODE = 'pow_profile'
992 plot_type = 'scatter'
991 plot_type = 'scatter'
993
992
994 def setup(self):
993 def setup(self):
995
994
996 self.ncols = 1
995 self.ncols = 1
997 self.nrows = 1
996 self.nrows = 1
998 self.nplots = 1
997 self.nplots = 1
999 self.height = 4
998 self.height = 4
1000 self.width = 3
999 self.width = 3
1001 self.ylabel = 'Range [km]'
1000 self.ylabel = 'Range [km]'
1002 self.xlabel = 'Intensity [dB]'
1001 self.xlabel = 'Intensity [dB]'
1003 self.titles = ['Power Profile']
1002 self.titles = ['Power Profile']
1004 self.colorbar = False
1003 self.colorbar = False
1005
1004
1006 def update(self, dataOut):
1005 def update(self, dataOut):
1007
1006
1008 data = {}
1007 data = {}
1009 meta = {}
1008 meta = {}
1010 data[self.CODE] = dataOut.getPower()
1009 data[self.CODE] = dataOut.getPower()
1011
1010
1012 return data, meta
1011 return data, meta
1013
1012
1014 def plot(self):
1013 def plot(self):
1015
1014
1016 y = self.data.yrange
1015 y = self.data.yrange
1017 self.y = y
1016 self.y = y
1018
1017
1019 x = self.data[-1][self.CODE]
1018 x = self.data[-1][self.CODE]
1020
1019
1021 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
1020 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
1022 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
1021 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
1023
1022
1024 if self.axes[0].firsttime:
1023 if self.axes[0].firsttime:
1025 for ch in self.data.channels:
1024 for ch in self.data.channels:
1026 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
1025 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
1027 plt.legend()
1026 plt.legend()
1028 else:
1027 else:
1029 for ch in self.data.channels:
1028 for ch in self.data.channels:
1030 self.axes[0].lines[ch].set_data(x[ch], y)
1029 self.axes[0].lines[ch].set_data(x[ch], y)
1031
1030
1032
1031
1033 class SpectraCutPlot(Plot):
1032 class SpectraCutPlot(Plot):
1034
1033
1035 CODE = 'spc_cut'
1034 CODE = 'spc_cut'
1036 plot_type = 'scatter'
1035 plot_type = 'scatter'
1037 buffering = False
1036 buffering = False
1038
1037
1039 def setup(self):
1038 def setup(self):
1040
1039
1041 self.nplots = len(self.data.channels)
1040 self.nplots = len(self.data.channels)
1042 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1041 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1043 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1042 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1044 self.width = 3.4 * self.ncols + 1.5
1043 self.width = 3.4 * self.ncols + 1.5
1045 self.height = 3 * self.nrows
1044 self.height = 3 * self.nrows
1046 self.ylabel = 'Power [dB]'
1045 self.ylabel = 'Power [dB]'
1047 self.colorbar = False
1046 self.colorbar = False
1048 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
1047 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
1049
1048
1050 def update(self, dataOut):
1049 def update(self, dataOut):
1051
1050
1052 data = {}
1051 data = {}
1053 meta = {}
1052 meta = {}
1054 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
1053 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
1055 data['spc'] = spc
1054 data['spc'] = spc
1056 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
1055 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
1057 if self.CODE == 'cut_gaussian_fit':
1056 if self.CODE == 'cut_gaussian_fit':
1058 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
1057 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
1059 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1058 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1060 return data, meta
1059 return data, meta
1061
1060
1062 def plot(self):
1061 def plot(self):
1063 if self.xaxis == "frequency":
1062 if self.xaxis == "frequency":
1064 x = self.data.xrange[0][1:]
1063 x = self.data.xrange[0][1:]
1065 self.xlabel = "Frequency (kHz)"
1064 self.xlabel = "Frequency (kHz)"
1066 elif self.xaxis == "time":
1065 elif self.xaxis == "time":
1067 x = self.data.xrange[1]
1066 x = self.data.xrange[1]
1068 self.xlabel = "Time (ms)"
1067 self.xlabel = "Time (ms)"
1069 else:
1068 else:
1070 x = self.data.xrange[2][:-1]
1069 x = self.data.xrange[2][:-1]
1071 self.xlabel = "Velocity (m/s)"
1070 self.xlabel = "Velocity (m/s)"
1072
1071
1073 if self.CODE == 'cut_gaussian_fit':
1072 if self.CODE == 'cut_gaussian_fit':
1074 x = self.data.xrange[2][:-1]
1073 x = self.data.xrange[2][:-1]
1075 self.xlabel = "Velocity (m/s)"
1074 self.xlabel = "Velocity (m/s)"
1076
1075
1077 self.titles = []
1076 self.titles = []
1078
1077
1079 y = self.data.yrange
1078 y = self.data.yrange
1080 data = self.data[-1]
1079 data = self.data[-1]
1081 z = data['spc']
1080 z = data['spc']
1082
1081
1083 if self.height_index:
1082 if self.height_index:
1084 index = numpy.array(self.height_index)
1083 index = numpy.array(self.height_index)
1085 else:
1084 else:
1086 index = numpy.arange(0, len(y), int((len(y))/9))
1085 index = numpy.arange(0, len(y), int((len(y))/9))
1087
1086
1088 for n, ax in enumerate(self.axes):
1087 for n, ax in enumerate(self.axes):
1089 if self.CODE == 'cut_gaussian_fit':
1088 if self.CODE == 'cut_gaussian_fit':
1090 gau0 = data['gauss_fit0']
1089 gau0 = data['gauss_fit0']
1091 gau1 = data['gauss_fit1']
1090 gau1 = data['gauss_fit1']
1092 if ax.firsttime:
1091 if ax.firsttime:
1093 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1092 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1094 self.xmin = self.xmin if self.xmin else -self.xmax
1093 self.xmin = self.xmin if self.xmin else -self.xmax
1095 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1094 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1096 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1095 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1097 #print(self.ymax)
1096 #print(self.ymax)
1098 #print(z[n, :, index])
1097 #print(z[n, :, index])
1099 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1098 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1100 if self.CODE == 'cut_gaussian_fit':
1099 if self.CODE == 'cut_gaussian_fit':
1101 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1100 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1102 for i, line in enumerate(ax.plt_gau0):
1101 for i, line in enumerate(ax.plt_gau0):
1103 line.set_color(ax.plt[i].get_color())
1102 line.set_color(ax.plt[i].get_color())
1104 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1103 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1105 for i, line in enumerate(ax.plt_gau1):
1104 for i, line in enumerate(ax.plt_gau1):
1106 line.set_color(ax.plt[i].get_color())
1105 line.set_color(ax.plt[i].get_color())
1107 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1106 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1108 self.figures[0].legend(ax.plt, labels, loc='center right')
1107 self.figures[0].legend(ax.plt, labels, loc='center right')
1109 else:
1108 else:
1110 for i, line in enumerate(ax.plt):
1109 for i, line in enumerate(ax.plt):
1111 line.set_data(x, z[n, :, index[i]].T)
1110 line.set_data(x, z[n, :, index[i]].T)
1112 for i, line in enumerate(ax.plt_gau0):
1111 for i, line in enumerate(ax.plt_gau0):
1113 line.set_data(x, gau0[n, :, index[i]].T)
1112 line.set_data(x, gau0[n, :, index[i]].T)
1114 line.set_color(ax.plt[i].get_color())
1113 line.set_color(ax.plt[i].get_color())
1115 for i, line in enumerate(ax.plt_gau1):
1114 for i, line in enumerate(ax.plt_gau1):
1116 line.set_data(x, gau1[n, :, index[i]].T)
1115 line.set_data(x, gau1[n, :, index[i]].T)
1117 line.set_color(ax.plt[i].get_color())
1116 line.set_color(ax.plt[i].get_color())
1118 self.titles.append('CH {}'.format(n))
1117 self.titles.append('CH {}'.format(n))
1119
1118
1120
1119
1121 class BeaconPhase(Plot):
1120 class BeaconPhase(Plot):
1122
1121
1123 __isConfig = None
1122 __isConfig = None
1124 __nsubplots = None
1123 __nsubplots = None
1125
1124
1126 PREFIX = 'beacon_phase'
1125 PREFIX = 'beacon_phase'
1127
1126
1128 def __init__(self):
1127 def __init__(self):
1129 Plot.__init__(self)
1128 Plot.__init__(self)
1130 self.timerange = 24*60*60
1129 self.timerange = 24*60*60
1131 self.isConfig = False
1130 self.isConfig = False
1132 self.__nsubplots = 1
1131 self.__nsubplots = 1
1133 self.counter_imagwr = 0
1132 self.counter_imagwr = 0
1134 self.WIDTH = 800
1133 self.WIDTH = 800
1135 self.HEIGHT = 400
1134 self.HEIGHT = 400
1136 self.WIDTHPROF = 120
1135 self.WIDTHPROF = 120
1137 self.HEIGHTPROF = 0
1136 self.HEIGHTPROF = 0
1138 self.xdata = None
1137 self.xdata = None
1139 self.ydata = None
1138 self.ydata = None
1140
1139
1141 self.PLOT_CODE = BEACON_CODE
1140 self.PLOT_CODE = BEACON_CODE
1142
1141
1143 self.FTP_WEI = None
1142 self.FTP_WEI = None
1144 self.EXP_CODE = None
1143 self.EXP_CODE = None
1145 self.SUB_EXP_CODE = None
1144 self.SUB_EXP_CODE = None
1146 self.PLOT_POS = None
1145 self.PLOT_POS = None
1147
1146
1148 self.filename_phase = None
1147 self.filename_phase = None
1149
1148
1150 self.figfile = None
1149 self.figfile = None
1151
1150
1152 self.xmin = None
1151 self.xmin = None
1153 self.xmax = None
1152 self.xmax = None
1154
1153
1155 def getSubplots(self):
1154 def getSubplots(self):
1156
1155
1157 ncol = 1
1156 ncol = 1
1158 nrow = 1
1157 nrow = 1
1159
1158
1160 return nrow, ncol
1159 return nrow, ncol
1161
1160
1162 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1161 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1163
1162
1164 self.__showprofile = showprofile
1163 self.__showprofile = showprofile
1165 self.nplots = nplots
1164 self.nplots = nplots
1166
1165
1167 ncolspan = 7
1166 ncolspan = 7
1168 colspan = 6
1167 colspan = 6
1169 self.__nsubplots = 2
1168 self.__nsubplots = 2
1170
1169
1171 self.createFigure(id = id,
1170 self.createFigure(id = id,
1172 wintitle = wintitle,
1171 wintitle = wintitle,
1173 widthplot = self.WIDTH+self.WIDTHPROF,
1172 widthplot = self.WIDTH+self.WIDTHPROF,
1174 heightplot = self.HEIGHT+self.HEIGHTPROF,
1173 heightplot = self.HEIGHT+self.HEIGHTPROF,
1175 show=show)
1174 show=show)
1176
1175
1177 nrow, ncol = self.getSubplots()
1176 nrow, ncol = self.getSubplots()
1178
1177
1179 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1178 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1180
1179
1181 def save_phase(self, filename_phase):
1180 def save_phase(self, filename_phase):
1182 f = open(filename_phase,'w+')
1181 f = open(filename_phase,'w+')
1183 f.write('\n\n')
1182 f.write('\n\n')
1184 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1183 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1185 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1184 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1186 f.close()
1185 f.close()
1187
1186
1188 def save_data(self, filename_phase, data, data_datetime):
1187 def save_data(self, filename_phase, data, data_datetime):
1189 f=open(filename_phase,'a')
1188 f=open(filename_phase,'a')
1190 timetuple_data = data_datetime.timetuple()
1189 timetuple_data = data_datetime.timetuple()
1191 day = str(timetuple_data.tm_mday)
1190 day = str(timetuple_data.tm_mday)
1192 month = str(timetuple_data.tm_mon)
1191 month = str(timetuple_data.tm_mon)
1193 year = str(timetuple_data.tm_year)
1192 year = str(timetuple_data.tm_year)
1194 hour = str(timetuple_data.tm_hour)
1193 hour = str(timetuple_data.tm_hour)
1195 minute = str(timetuple_data.tm_min)
1194 minute = str(timetuple_data.tm_min)
1196 second = str(timetuple_data.tm_sec)
1195 second = str(timetuple_data.tm_sec)
1197 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1196 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1198 f.close()
1197 f.close()
1199
1198
1200 def plot(self):
1199 def plot(self):
1201 log.warning('TODO: Not yet implemented...')
1200 log.warning('TODO: Not yet implemented...')
1202
1201
1203 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1202 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1204 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1203 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1205 timerange=None,
1204 timerange=None,
1206 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1205 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1207 server=None, folder=None, username=None, password=None,
1206 server=None, folder=None, username=None, password=None,
1208 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1207 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1209
1208
1210 if dataOut.flagNoData:
1209 if dataOut.flagNoData:
1211 return dataOut
1210 return dataOut
1212
1211
1213 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1212 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1214 return
1213 return
1215
1214
1216 if pairsList == None:
1215 if pairsList == None:
1217 pairsIndexList = dataOut.pairsIndexList[:10]
1216 pairsIndexList = dataOut.pairsIndexList[:10]
1218 else:
1217 else:
1219 pairsIndexList = []
1218 pairsIndexList = []
1220 for pair in pairsList:
1219 for pair in pairsList:
1221 if pair not in dataOut.pairsList:
1220 if pair not in dataOut.pairsList:
1222 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1221 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1223 pairsIndexList.append(dataOut.pairsList.index(pair))
1222 pairsIndexList.append(dataOut.pairsList.index(pair))
1224
1223
1225 if pairsIndexList == []:
1224 if pairsIndexList == []:
1226 return
1225 return
1227
1226
1228 # if len(pairsIndexList) > 4:
1227 # if len(pairsIndexList) > 4:
1229 # pairsIndexList = pairsIndexList[0:4]
1228 # pairsIndexList = pairsIndexList[0:4]
1230
1229
1231 hmin_index = None
1230 hmin_index = None
1232 hmax_index = None
1231 hmax_index = None
1233
1232
1234 if hmin != None and hmax != None:
1233 if hmin != None and hmax != None:
1235 indexes = numpy.arange(dataOut.nHeights)
1234 indexes = numpy.arange(dataOut.nHeights)
1236 hmin_list = indexes[dataOut.heightList >= hmin]
1235 hmin_list = indexes[dataOut.heightList >= hmin]
1237 hmax_list = indexes[dataOut.heightList <= hmax]
1236 hmax_list = indexes[dataOut.heightList <= hmax]
1238
1237
1239 if hmin_list.any():
1238 if hmin_list.any():
1240 hmin_index = hmin_list[0]
1239 hmin_index = hmin_list[0]
1241
1240
1242 if hmax_list.any():
1241 if hmax_list.any():
1243 hmax_index = hmax_list[-1]+1
1242 hmax_index = hmax_list[-1]+1
1244
1243
1245 x = dataOut.getTimeRange()
1244 x = dataOut.getTimeRange()
1246
1245
1247 thisDatetime = dataOut.datatime
1246 thisDatetime = dataOut.datatime
1248
1247
1249 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1248 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1250 xlabel = "Local Time"
1249 xlabel = "Local Time"
1251 ylabel = "Phase (degrees)"
1250 ylabel = "Phase (degrees)"
1252
1251
1253 update_figfile = False
1252 update_figfile = False
1254
1253
1255 nplots = len(pairsIndexList)
1254 nplots = len(pairsIndexList)
1256 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1255 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1257 phase_beacon = numpy.zeros(len(pairsIndexList))
1256 phase_beacon = numpy.zeros(len(pairsIndexList))
1258 for i in range(nplots):
1257 for i in range(nplots):
1259 pair = dataOut.pairsList[pairsIndexList[i]]
1258 pair = dataOut.pairsList[pairsIndexList[i]]
1260 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1259 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1261 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1260 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1262 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1261 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1263 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1262 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1264 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1263 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1265
1264
1266 if dataOut.beacon_heiIndexList:
1265 if dataOut.beacon_heiIndexList:
1267 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1266 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1268 else:
1267 else:
1269 phase_beacon[i] = numpy.average(phase)
1268 phase_beacon[i] = numpy.average(phase)
1270
1269
1271 if not self.isConfig:
1270 if not self.isConfig:
1272
1271
1273 nplots = len(pairsIndexList)
1272 nplots = len(pairsIndexList)
1274
1273
1275 self.setup(id=id,
1274 self.setup(id=id,
1276 nplots=nplots,
1275 nplots=nplots,
1277 wintitle=wintitle,
1276 wintitle=wintitle,
1278 showprofile=showprofile,
1277 showprofile=showprofile,
1279 show=show)
1278 show=show)
1280
1279
1281 if timerange != None:
1280 if timerange != None:
1282 self.timerange = timerange
1281 self.timerange = timerange
1283
1282
1284 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1283 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1285
1284
1286 if ymin == None: ymin = 0
1285 if ymin == None: ymin = 0
1287 if ymax == None: ymax = 360
1286 if ymax == None: ymax = 360
1288
1287
1289 self.FTP_WEI = ftp_wei
1288 self.FTP_WEI = ftp_wei
1290 self.EXP_CODE = exp_code
1289 self.EXP_CODE = exp_code
1291 self.SUB_EXP_CODE = sub_exp_code
1290 self.SUB_EXP_CODE = sub_exp_code
1292 self.PLOT_POS = plot_pos
1291 self.PLOT_POS = plot_pos
1293
1292
1294 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1293 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1295 self.isConfig = True
1294 self.isConfig = True
1296 self.figfile = figfile
1295 self.figfile = figfile
1297 self.xdata = numpy.array([])
1296 self.xdata = numpy.array([])
1298 self.ydata = numpy.array([])
1297 self.ydata = numpy.array([])
1299
1298
1300 update_figfile = True
1299 update_figfile = True
1301
1300
1302 #open file beacon phase
1301 #open file beacon phase
1303 path = '%s%03d' %(self.PREFIX, self.id)
1302 path = '%s%03d' %(self.PREFIX, self.id)
1304 beacon_file = os.path.join(path,'%s.txt'%self.name)
1303 beacon_file = os.path.join(path,'%s.txt'%self.name)
1305 self.filename_phase = os.path.join(figpath,beacon_file)
1304 self.filename_phase = os.path.join(figpath,beacon_file)
1306 #self.save_phase(self.filename_phase)
1305 #self.save_phase(self.filename_phase)
1307
1306
1308
1307
1309 #store data beacon phase
1308 #store data beacon phase
1310 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1309 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1311
1310
1312 self.setWinTitle(title)
1311 self.setWinTitle(title)
1313
1312
1314
1313
1315 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1314 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1316
1315
1317 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1316 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1318
1317
1319 axes = self.axesList[0]
1318 axes = self.axesList[0]
1320
1319
1321 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1320 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1322
1321
1323 if len(self.ydata)==0:
1322 if len(self.ydata)==0:
1324 self.ydata = phase_beacon.reshape(-1,1)
1323 self.ydata = phase_beacon.reshape(-1,1)
1325 else:
1324 else:
1326 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1325 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1327
1326
1328
1327
1329 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1328 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1330 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1329 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1331 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1330 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1332 XAxisAsTime=True, grid='both'
1331 XAxisAsTime=True, grid='both'
1333 )
1332 )
1334
1333
1335 self.draw()
1334 self.draw()
1336
1335
1337 if dataOut.ltctime >= self.xmax:
1336 if dataOut.ltctime >= self.xmax:
1338 self.counter_imagwr = wr_period
1337 self.counter_imagwr = wr_period
1339 self.isConfig = False
1338 self.isConfig = False
1340 update_figfile = True
1339 update_figfile = True
1341
1340
1342 self.save(figpath=figpath,
1341 self.save(figpath=figpath,
1343 figfile=figfile,
1342 figfile=figfile,
1344 save=save,
1343 save=save,
1345 ftp=ftp,
1344 ftp=ftp,
1346 wr_period=wr_period,
1345 wr_period=wr_period,
1347 thisDatetime=thisDatetime,
1346 thisDatetime=thisDatetime,
1348 update_figfile=update_figfile)
1347 update_figfile=update_figfile)
1349
1348
1350 return dataOut
1349 return dataOut
@@ -1,1428 +1,1428
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
7
8 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
8 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
9
9
10 from .jroplot_spectra import RTIPlot, NoisePlot
10 from .jroplot_spectra import RTIPlot, NoisePlot
11
11
12 from schainpy.utils import log
12 from schainpy.utils import log
13 from .plotting_codes import *
13 from .plotting_codes import *
14
14
15 from schainpy.model.graphics.jroplot_base import Plot, plt
15 from schainpy.model.graphics.jroplot_base import Plot, plt
16
16
17 import matplotlib.pyplot as plt
17 import matplotlib.pyplot as plt
18 import matplotlib.colors as colors
18 import matplotlib.colors as colors
19 from matplotlib.ticker import MultipleLocator, LogLocator, NullFormatter
19 from matplotlib.ticker import MultipleLocator, LogLocator, NullFormatter
20
20
21 class RTIDPPlot(RTIPlot):
21 class RTIDPPlot(RTIPlot):
22 '''
22 '''
23 Written by R. Flores
23 Written by R. Flores
24 '''
24 '''
25 '''Plot for RTI Double Pulse Experiment Using Cross Products Analysis
25 '''Plot for RTI Double Pulse Experiment Using Cross Products Analysis
26 '''
26 '''
27
27
28 CODE = 'RTIDP'
28 CODE = 'RTIDP'
29 colormap = 'jet'
29 colormap = 'jet'
30 plot_name = 'RTI'
30 plot_name = 'RTI'
31 plot_type = 'pcolorbuffer'
31 plot_type = 'pcolorbuffer'
32
32
33 def setup(self):
33 def setup(self):
34 self.xaxis = 'time'
34 self.xaxis = 'time'
35 self.ncols = 1
35 self.ncols = 1
36 self.nrows = 3
36 self.nrows = 3
37 self.nplots = self.nrows
37 self.nplots = self.nrows
38
38
39 self.ylabel = 'Range [km]'
39 self.ylabel = 'Range [km]'
40 self.xlabel = 'Time (LT)'
40 self.xlabel = 'Time (LT)'
41
41
42 self.cb_label = 'Intensity (dB)'
42 self.cb_label = 'Intensity (dB)'
43
43
44 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
44 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
45
45
46 self.titles = ['{} Channel {}'.format(
46 self.titles = ['{} Channel {}'.format(
47 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
47 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
48 self.plot_name.upper(), '0'),'{} Channel {}'.format(
48 self.plot_name.upper(), '0'),'{} Channel {}'.format(
49 self.plot_name.upper(), '1')]
49 self.plot_name.upper(), '1')]
50
50
51 def update(self, dataOut):
51 def update(self, dataOut):
52
52
53 data = {}
53 data = {}
54 meta = {}
54 meta = {}
55 data['rti'] = dataOut.data_for_RTI_DP
55 data['rti'] = dataOut.data_for_RTI_DP
56 data['NDP'] = dataOut.NDP
56 data['NDP'] = dataOut.NDP
57
57
58 return data, meta
58 return data, meta
59
59
60 def plot(self):
60 def plot(self):
61
61
62 NDP = self.data['NDP'][-1]
62 NDP = self.data['NDP'][-1]
63 self.x = self.data.times
63 self.x = self.data.times
64 self.y = self.data.yrange[0:NDP]
64 self.y = self.data.yrange[0:NDP]
65 self.z = self.data['rti']
65 self.z = self.data['rti']
66 self.z = numpy.ma.masked_invalid(self.z)
66 self.z = numpy.ma.masked_invalid(self.z)
67
67
68 if self.decimation is None:
68 if self.decimation is None:
69 x, y, z = self.fill_gaps(self.x, self.y, self.z)
69 x, y, z = self.fill_gaps(self.x, self.y, self.z)
70 else:
70 else:
71 x, y, z = self.fill_gaps(*self.decimate())
71 x, y, z = self.fill_gaps(*self.decimate())
72
72
73 for n, ax in enumerate(self.axes):
73 for n, ax in enumerate(self.axes):
74
74
75 self.zmax = self.zmax if self.zmax is not None else numpy.max(
75 self.zmax = self.zmax if self.zmax is not None else numpy.max(
76 self.z[1][0,12:40])
76 self.z[1][0,12:40])
77 self.zmin = self.zmin if self.zmin is not None else numpy.min(
77 self.zmin = self.zmin if self.zmin is not None else numpy.min(
78 self.z[1][0,12:40])
78 self.z[1][0,12:40])
79
79
80 if ax.firsttime:
80 if ax.firsttime:
81
81
82 if self.zlimits is not None:
82 if self.zlimits is not None:
83 self.zmin, self.zmax = self.zlimits[n]
83 self.zmin, self.zmax = self.zlimits[n]
84
84
85 ax.plt = ax.pcolormesh(x, y, z[n].T,
85 ax.plt = ax.pcolormesh(x, y, z[n].T,
86 vmin=self.zmin,
86 vmin=self.zmin,
87 vmax=self.zmax,
87 vmax=self.zmax,
88 cmap=plt.get_cmap(self.colormap)
88 cmap=plt.get_cmap(self.colormap)
89 )
89 )
90 else:
90 else:
91 #if self.zlimits is not None:
91 #if self.zlimits is not None:
92 #self.zmin, self.zmax = self.zlimits[n]
92 #self.zmin, self.zmax = self.zlimits[n]
93 ax.plt.remove()
93 ax.plt.remove()
94 ax.plt = ax.pcolormesh(x, y, z[n].T,
94 ax.plt = ax.pcolormesh(x, y, z[n].T,
95 vmin=self.zmin,
95 vmin=self.zmin,
96 vmax=self.zmax,
96 vmax=self.zmax,
97 cmap=plt.get_cmap(self.colormap)
97 cmap=plt.get_cmap(self.colormap)
98 )
98 )
99
99
100
100
101 class RTILPPlot(RTIPlot):
101 class RTILPPlot(RTIPlot):
102 '''
102 '''
103 Written by R. Flores
103 Written by R. Flores
104 '''
104 '''
105 '''
105 '''
106 Plot for RTI Long Pulse Using Cross Products Analysis
106 Plot for RTI Long Pulse Using Cross Products Analysis
107 '''
107 '''
108
108
109 CODE = 'RTILP'
109 CODE = 'RTILP'
110 colormap = 'jet'
110 colormap = 'jet'
111 plot_name = 'RTI LP'
111 plot_name = 'RTI LP'
112 plot_type = 'pcolorbuffer'
112 plot_type = 'pcolorbuffer'
113
113
114 def setup(self):
114 def setup(self):
115 self.xaxis = 'time'
115 self.xaxis = 'time'
116 self.ncols = 1
116 self.ncols = 1
117 self.nrows = 2
117 self.nrows = 2
118 self.nplots = self.nrows
118 self.nplots = self.nrows
119
119
120 self.ylabel = 'Range [km]'
120 self.ylabel = 'Range [km]'
121 self.xlabel = 'Time (LT)'
121 self.xlabel = 'Time (LT)'
122
122
123 self.cb_label = 'Intensity (dB)'
123 self.cb_label = 'Intensity (dB)'
124
124
125 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
125 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
126
126
127
127
128 self.titles = ['{} Channel {}'.format(
128 self.titles = ['{} Channel {}'.format(
129 self.plot_name.upper(), '0'),'{} Channel {}'.format(
129 self.plot_name.upper(), '0'),'{} Channel {}'.format(
130 self.plot_name.upper(), '1'),'{} Channel {}'.format(
130 self.plot_name.upper(), '1'),'{} Channel {}'.format(
131 self.plot_name.upper(), '2'),'{} Channel {}'.format(
131 self.plot_name.upper(), '2'),'{} Channel {}'.format(
132 self.plot_name.upper(), '3')]
132 self.plot_name.upper(), '3')]
133
133
134
134
135 def update(self, dataOut):
135 def update(self, dataOut):
136
136
137 data = {}
137 data = {}
138 meta = {}
138 meta = {}
139 data['rti'] = dataOut.data_for_RTI_LP
139 data['rti'] = dataOut.data_for_RTI_LP
140 data['NRANGE'] = dataOut.NRANGE
140 data['NRANGE'] = dataOut.NRANGE
141
141
142 return data, meta
142 return data, meta
143
143
144 def plot(self):
144 def plot(self):
145
145
146 NRANGE = self.data['NRANGE'][-1]
146 NRANGE = self.data['NRANGE'][-1]
147 self.x = self.data.times
147 self.x = self.data.times
148 self.y = self.data.yrange[0:NRANGE]
148 self.y = self.data.yrange[0:NRANGE]
149
149
150 self.z = self.data['rti']
150 self.z = self.data['rti']
151
151
152 self.z = numpy.ma.masked_invalid(self.z)
152 self.z = numpy.ma.masked_invalid(self.z)
153
153
154 if self.decimation is None:
154 if self.decimation is None:
155 x, y, z = self.fill_gaps(self.x, self.y, self.z)
155 x, y, z = self.fill_gaps(self.x, self.y, self.z)
156 else:
156 else:
157 x, y, z = self.fill_gaps(*self.decimate())
157 x, y, z = self.fill_gaps(*self.decimate())
158
158
159 for n, ax in enumerate(self.axes):
159 for n, ax in enumerate(self.axes):
160
160
161 self.zmax = self.zmax if self.zmax is not None else numpy.max(
161 self.zmax = self.zmax if self.zmax is not None else numpy.max(
162 self.z[1][0,12:40])
162 self.z[1][0,12:40])
163 self.zmin = self.zmin if self.zmin is not None else numpy.min(
163 self.zmin = self.zmin if self.zmin is not None else numpy.min(
164 self.z[1][0,12:40])
164 self.z[1][0,12:40])
165
165
166 if ax.firsttime:
166 if ax.firsttime:
167
167
168 if self.zlimits is not None:
168 if self.zlimits is not None:
169 self.zmin, self.zmax = self.zlimits[n]
169 self.zmin, self.zmax = self.zlimits[n]
170
170
171
171
172 ax.plt = ax.pcolormesh(x, y, z[n].T,
172 ax.plt = ax.pcolormesh(x, y, z[n].T,
173 vmin=self.zmin,
173 vmin=self.zmin,
174 vmax=self.zmax,
174 vmax=self.zmax,
175 cmap=plt.get_cmap(self.colormap)
175 cmap=plt.get_cmap(self.colormap)
176 )
176 )
177
177
178 else:
178 else:
179 if self.zlimits is not None:
179 if self.zlimits is not None:
180 self.zmin, self.zmax = self.zlimits[n]
180 self.zmin, self.zmax = self.zlimits[n]
181 ax.plt.remove()
181 ax.plt.remove()
182 ax.plt = ax.pcolormesh(x, y, z[n].T,
182 ax.plt = ax.pcolormesh(x, y, z[n].T,
183 vmin=self.zmin,
183 vmin=self.zmin,
184 vmax=self.zmax,
184 vmax=self.zmax,
185 cmap=plt.get_cmap(self.colormap)
185 cmap=plt.get_cmap(self.colormap)
186 )
186 )
187
187
188
188
189 class DenRTIPlot(RTIPlot):
189 class DenRTIPlot(RTIPlot):
190 '''
190 '''
191 Written by R. Flores
191 Written by R. Flores
192 '''
192 '''
193 '''
193 '''
194 RTI Plot for Electron Densities
194 RTI Plot for Electron Densities
195 '''
195 '''
196
196
197 CODE = 'denrti'
197 CODE = 'denrti'
198 colormap = 'jet'
198 colormap = 'jet'
199
199
200 def setup(self):
200 def setup(self):
201 self.xaxis = 'time'
201 self.xaxis = 'time'
202 self.ncols = 1
202 self.ncols = 1
203 self.nrows = self.data.shape(self.CODE)[0]
203 self.nrows = self.data.shape(self.CODE)[0]
204 self.nplots = self.nrows
204 self.nplots = self.nrows
205
205
206 self.ylabel = 'Range [km]'
206 self.ylabel = 'Range [km]'
207 self.xlabel = 'Time (LT)'
207 self.xlabel = 'Time (LT)'
208
208
209 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
209 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
210
210
211 if self.CODE == 'denrti':
211 if self.CODE == 'denrti':
212 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
212 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
213
213
214 self.titles = ['Electron Density RTI']
214 self.titles = ['Electron Density RTI']
215
215
216 def update(self, dataOut):
216 def update(self, dataOut):
217
217
218 data = {}
218 data = {}
219 meta = {}
219 meta = {}
220
220
221 data['denrti'] = dataOut.DensityFinal*1.e-6 #To Plot in cm^-3
221 data['denrti'] = dataOut.DensityFinal*1.e-6 #To Plot in cm^-3
222
222
223 return data, meta
223 return data, meta
224
224
225 def plot(self):
225 def plot(self):
226
226
227 self.x = self.data.times
227 self.x = self.data.times
228 self.y = self.data.yrange
228 self.y = self.data.yrange
229
229
230 self.z = self.data[self.CODE]
230 self.z = self.data[self.CODE]
231
231
232 self.z = numpy.ma.masked_invalid(self.z)
232 self.z = numpy.ma.masked_invalid(self.z)
233
233
234 if self.decimation is None:
234 if self.decimation is None:
235 x, y, z = self.fill_gaps(self.x, self.y, self.z)
235 x, y, z = self.fill_gaps(self.x, self.y, self.z)
236 else:
236 else:
237 x, y, z = self.fill_gaps(*self.decimate())
237 x, y, z = self.fill_gaps(*self.decimate())
238
238
239 for n, ax in enumerate(self.axes):
239 for n, ax in enumerate(self.axes):
240
240
241 self.zmax = self.zmax if self.zmax is not None else numpy.max(
241 self.zmax = self.zmax if self.zmax is not None else numpy.max(
242 self.z[n])
242 self.z[n])
243 self.zmin = self.zmin if self.zmin is not None else numpy.min(
243 self.zmin = self.zmin if self.zmin is not None else numpy.min(
244 self.z[n])
244 self.z[n])
245
245
246 if ax.firsttime:
246 if ax.firsttime:
247
247
248 if self.zlimits is not None:
248 if self.zlimits is not None:
249 self.zmin, self.zmax = self.zlimits[n]
249 self.zmin, self.zmax = self.zlimits[n]
250 if numpy.log10(self.zmin)<0:
250 if numpy.log10(self.zmin)<0:
251 self.zmin=1
251 self.zmin=1
252 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
252 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
253 #vmin=self.zmin,
253 #vmin=self.zmin,
254 #vmax=self.zmax,
254 #vmax=self.zmax,
255 cmap=self.cmaps[n],
255 cmap=self.cmaps[n],
256 norm=colors.LogNorm(vmin=self.zmin,vmax=self.zmax)
256 norm=colors.LogNorm(vmin=self.zmin,vmax=self.zmax)
257 )
257 )
258
258
259 else:
259 else:
260 if self.zlimits is not None:
260 if self.zlimits is not None:
261 self.zmin, self.zmax = self.zlimits[n]
261 self.zmin, self.zmax = self.zlimits[n]
262 ax.plt.remove()
262 ax.plt.remove()
263 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
263 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
264 #vmin=self.zmin,
264 #vmin=self.zmin,
265 #vmax=self.zmax,
265 #vmax=self.zmax,
266 cmap=self.cmaps[n],
266 cmap=self.cmaps[n],
267 norm=colors.LogNorm(vmin=self.zmin,vmax=self.zmax)
267 norm=colors.LogNorm(vmin=self.zmin,vmax=self.zmax)
268 )
268 )
269
269
270
270
271 class ETempRTIPlot(RTIPlot):
271 class ETempRTIPlot(RTIPlot):
272 '''
272 '''
273 Written by R. Flores
273 Written by R. Flores
274 '''
274 '''
275 '''
275 '''
276 Plot for Electron Temperature
276 Plot for Electron Temperature
277 '''
277 '''
278
278
279 CODE = 'ETemp'
279 CODE = 'ETemp'
280 colormap = 'jet'
280 colormap = 'jet'
281
281
282 def setup(self):
282 def setup(self):
283 self.xaxis = 'time'
283 self.xaxis = 'time'
284 self.ncols = 1
284 self.ncols = 1
285 self.nrows = self.data.shape(self.CODE)[0]
285 self.nrows = self.data.shape(self.CODE)[0]
286 self.nplots = self.nrows
286 self.nplots = self.nrows
287
287
288 self.ylabel = 'Range [km]'
288 self.ylabel = 'Range [km]'
289 self.xlabel = 'Time (LT)'
289 self.xlabel = 'Time (LT)'
290 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
290 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
291 if self.CODE == 'ETemp':
291 if self.CODE == 'ETemp':
292 self.cb_label = 'Electron Temperature (K)'
292 self.cb_label = 'Electron Temperature (K)'
293 self.titles = ['Electron Temperature RTI']
293 self.titles = ['Electron Temperature RTI']
294 if self.CODE == 'ITemp':
294 if self.CODE == 'ITemp':
295 self.cb_label = 'Ion Temperature (K)'
295 self.cb_label = 'Ion Temperature (K)'
296 self.titles = ['Ion Temperature RTI']
296 self.titles = ['Ion Temperature RTI']
297 if self.CODE == 'HeFracLP':
297 if self.CODE == 'HeFracLP':
298 self.cb_label ='He+ Fraction'
298 self.cb_label ='He+ Fraction'
299 self.titles = ['He+ Fraction RTI']
299 self.titles = ['He+ Fraction RTI']
300 self.zmax=0.16
300 self.zmax=0.16
301 if self.CODE == 'HFracLP':
301 if self.CODE == 'HFracLP':
302 self.cb_label ='H+ Fraction'
302 self.cb_label ='H+ Fraction'
303 self.titles = ['H+ Fraction RTI']
303 self.titles = ['H+ Fraction RTI']
304
304
305 def update(self, dataOut):
305 def update(self, dataOut):
306
306
307 data = {}
307 data = {}
308 meta = {}
308 meta = {}
309
309
310 data['ETemp'] = dataOut.ElecTempFinal
310 data['ETemp'] = dataOut.ElecTempFinal
311
311
312 return data, meta
312 return data, meta
313
313
314 def plot(self):
314 def plot(self):
315
315
316 self.x = self.data.times
316 self.x = self.data.times
317 self.y = self.data.yrange
317 self.y = self.data.yrange
318 self.z = self.data[self.CODE]
318 self.z = self.data[self.CODE]
319
319
320 self.z = numpy.ma.masked_invalid(self.z)
320 self.z = numpy.ma.masked_invalid(self.z)
321
321
322 if self.decimation is None:
322 if self.decimation is None:
323 x, y, z = self.fill_gaps(self.x, self.y, self.z)
323 x, y, z = self.fill_gaps(self.x, self.y, self.z)
324 else:
324 else:
325 x, y, z = self.fill_gaps(*self.decimate())
325 x, y, z = self.fill_gaps(*self.decimate())
326
326
327 for n, ax in enumerate(self.axes):
327 for n, ax in enumerate(self.axes):
328
328
329 self.zmax = self.zmax if self.zmax is not None else numpy.max(
329 self.zmax = self.zmax if self.zmax is not None else numpy.max(
330 self.z[n])
330 self.z[n])
331 self.zmin = self.zmin if self.zmin is not None else numpy.min(
331 self.zmin = self.zmin if self.zmin is not None else numpy.min(
332 self.z[n])
332 self.z[n])
333
333
334 if ax.firsttime:
334 if ax.firsttime:
335
335
336 if self.zlimits is not None:
336 if self.zlimits is not None:
337 self.zmin, self.zmax = self.zlimits[n]
337 self.zmin, self.zmax = self.zlimits[n]
338
338
339 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
339 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
340 vmin=self.zmin,
340 vmin=self.zmin,
341 vmax=self.zmax,
341 vmax=self.zmax,
342 cmap=self.cmaps[n]
342 cmap=self.cmaps[n]
343 )
343 )
344 #plt.tight_layout()
344 #plt.tight_layout()
345
345
346 else:
346 else:
347 if self.zlimits is not None:
347 if self.zlimits is not None:
348 self.zmin, self.zmax = self.zlimits[n]
348 self.zmin, self.zmax = self.zlimits[n]
349 ax.plt.remove()
349 ax.plt.remove()
350 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
350 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
351 vmin=self.zmin,
351 vmin=self.zmin,
352 vmax=self.zmax,
352 vmax=self.zmax,
353 cmap=self.cmaps[n]
353 cmap=self.cmaps[n]
354 )
354 )
355
355
356
356
357 class ITempRTIPlot(ETempRTIPlot):
357 class ITempRTIPlot(ETempRTIPlot):
358 '''
358 '''
359 Written by R. Flores
359 Written by R. Flores
360 '''
360 '''
361 '''
361 '''
362 Plot for Ion Temperature
362 Plot for Ion Temperature
363 '''
363 '''
364
364
365 CODE = 'ITemp'
365 CODE = 'ITemp'
366 colormap = 'jet'
366 colormap = 'jet'
367 plot_name = 'Ion Temperature'
367 plot_name = 'Ion Temperature'
368
368
369 def update(self, dataOut):
369 def update(self, dataOut):
370
370
371 data = {}
371 data = {}
372 meta = {}
372 meta = {}
373
373
374 data['ITemp'] = dataOut.IonTempFinal
374 data['ITemp'] = dataOut.IonTempFinal
375
375
376 return data, meta
376 return data, meta
377
377
378
378
379 class HFracRTIPlot(ETempRTIPlot):
379 class HFracRTIPlot(ETempRTIPlot):
380 '''
380 '''
381 Written by R. Flores
381 Written by R. Flores
382 '''
382 '''
383 '''
383 '''
384 Plot for H+ LP
384 Plot for H+ LP
385 '''
385 '''
386
386
387 CODE = 'HFracLP'
387 CODE = 'HFracLP'
388 colormap = 'jet'
388 colormap = 'jet'
389 plot_name = 'H+ Frac'
389 plot_name = 'H+ Frac'
390
390
391 def update(self, dataOut):
391 def update(self, dataOut):
392
392
393 data = {}
393 data = {}
394 meta = {}
394 meta = {}
395 data['HFracLP'] = dataOut.PhyFinal
395 data['HFracLP'] = dataOut.PhyFinal
396
396
397 return data, meta
397 return data, meta
398
398
399
399
400 class HeFracRTIPlot(ETempRTIPlot):
400 class HeFracRTIPlot(ETempRTIPlot):
401 '''
401 '''
402 Written by R. Flores
402 Written by R. Flores
403 '''
403 '''
404 '''
404 '''
405 Plot for He+ LP
405 Plot for He+ LP
406 '''
406 '''
407
407
408 CODE = 'HeFracLP'
408 CODE = 'HeFracLP'
409 colormap = 'jet'
409 colormap = 'jet'
410 plot_name = 'He+ Frac'
410 plot_name = 'He+ Frac'
411
411
412 def update(self, dataOut):
412 def update(self, dataOut):
413
413
414 data = {}
414 data = {}
415 meta = {}
415 meta = {}
416 data['HeFracLP'] = dataOut.PheFinal
416 data['HeFracLP'] = dataOut.PheFinal
417
417
418 return data, meta
418 return data, meta
419
419
420
420
421 class TempsDPPlot(Plot):
421 class TempsDPPlot(Plot):
422 '''
422 '''
423 Written by R. Flores
423 Written by R. Flores
424 '''
424 '''
425 '''
425 '''
426 Plot for Electron - Ion Temperatures
426 Plot for Electron - Ion Temperatures
427 '''
427 '''
428
428
429 CODE = 'tempsDP'
429 CODE = 'tempsDP'
430 #plot_name = 'Temperatures'
430 #plot_name = 'Temperatures'
431 plot_type = 'scatterbuffer'
431 plot_type = 'scatterbuffer'
432
432
433 def setup(self):
433 def setup(self):
434
434
435 self.ncols = 1
435 self.ncols = 1
436 self.nrows = 1
436 self.nrows = 1
437 self.nplots = 1
437 self.nplots = 1
438 self.ylabel = 'Range [km]'
438 self.ylabel = 'Range [km]'
439 self.xlabel = 'Temperature (K)'
439 self.xlabel = 'Temperature (K)'
440 self.titles = ['Electron/Ion Temperatures']
440 self.titles = ['Electron/Ion Temperatures']
441 self.width = 3.5
441 self.width = 3.5
442 self.height = 5.5
442 self.height = 5.5
443 self.colorbar = False
443 self.colorbar = False
444 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
444 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
445
445
446 def update(self, dataOut):
446 def update(self, dataOut):
447 data = {}
447 data = {}
448 meta = {}
448 meta = {}
449
449
450 data['Te'] = dataOut.te2
450 data['Te'] = dataOut.te2
451 data['Ti'] = dataOut.ti2
451 data['Ti'] = dataOut.ti2
452 data['Te_error'] = dataOut.ete2
452 data['Te_error'] = dataOut.ete2
453 data['Ti_error'] = dataOut.eti2
453 data['Ti_error'] = dataOut.eti2
454
454
455 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
455 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
456
456
457 return data, meta
457 return data, meta
458
458
459 def plot(self):
459 def plot(self):
460
460
461 y = self.data.yrange
461 y = self.data.yrange
462
462
463 self.xmin = -100
463 self.xmin = -100
464 self.xmax = 5000
464 self.xmax = 5000
465
465
466 ax = self.axes[0]
466 ax = self.axes[0]
467
467
468 data = self.data[-1]
468 data = self.data[-1]
469
469
470 Te = data['Te']
470 Te = data['Te']
471 Ti = data['Ti']
471 Ti = data['Ti']
472 errTe = data['Te_error']
472 errTe = data['Te_error']
473 errTi = data['Ti_error']
473 errTi = data['Ti_error']
474
474
475 if ax.firsttime:
475 if ax.firsttime:
476 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
476 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
477 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='k',linewidth=2.0, label='Ti')
477 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='k',linewidth=2.0, label='Ti')
478 plt.legend(loc='lower right')
478 plt.legend(loc='lower right')
479 self.ystep_given = 50
479 self.ystep_given = 50
480 ax.yaxis.set_minor_locator(MultipleLocator(15))
480 ax.yaxis.set_minor_locator(MultipleLocator(15))
481 ax.grid(which='minor')
481 ax.grid(which='minor')
482
482
483 else:
483 else:
484 self.clear_figures()
484 self.clear_figures()
485 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
485 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
486 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='k',linewidth=2.0, label='Ti')
486 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='k',linewidth=2.0, label='Ti')
487 plt.legend(loc='lower right')
487 plt.legend(loc='lower right')
488 ax.yaxis.set_minor_locator(MultipleLocator(15))
488 ax.yaxis.set_minor_locator(MultipleLocator(15))
489
489
490
490
491 class TempsHPPlot(Plot):
491 class TempsHPPlot(Plot):
492 '''
492 '''
493 Written by R. Flores
493 Written by R. Flores
494 '''
494 '''
495 '''
495 '''
496 Plot for Temperatures Hybrid Experiment
496 Plot for Temperatures Hybrid Experiment
497 '''
497 '''
498
498
499 CODE = 'temps_LP'
499 CODE = 'temps_LP'
500 #plot_name = 'Temperatures'
500 #plot_name = 'Temperatures'
501 plot_type = 'scatterbuffer'
501 plot_type = 'scatterbuffer'
502
502
503
503
504 def setup(self):
504 def setup(self):
505
505
506 self.ncols = 1
506 self.ncols = 1
507 self.nrows = 1
507 self.nrows = 1
508 self.nplots = 1
508 self.nplots = 1
509 self.ylabel = 'Range [km]'
509 self.ylabel = 'Range [km]'
510 self.xlabel = 'Temperature (K)'
510 self.xlabel = 'Temperature (K)'
511 self.titles = ['Electron/Ion Temperatures']
511 self.titles = ['Electron/Ion Temperatures']
512 self.width = 3.5
512 self.width = 3.5
513 self.height = 6.5
513 self.height = 6.5
514 self.colorbar = False
514 self.colorbar = False
515 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
515 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
516
516
517 def update(self, dataOut):
517 def update(self, dataOut):
518 data = {}
518 data = {}
519 meta = {}
519 meta = {}
520
520
521
521
522 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
522 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
523 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
523 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
524 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
524 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
525 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
525 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
526
526
527 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
527 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
528
528
529 return data, meta
529 return data, meta
530
530
531 def plot(self):
531 def plot(self):
532
532
533
533
534 self.y = self.data.yrange
534 self.y = self.data.yrange
535 self.xmin = -100
535 self.xmin = -100
536 self.xmax = 4500
536 self.xmax = 4500
537 ax = self.axes[0]
537 ax = self.axes[0]
538
538
539 data = self.data[-1]
539 data = self.data[-1]
540
540
541 Te = data['Te']
541 Te = data['Te']
542 Ti = data['Ti']
542 Ti = data['Ti']
543 errTe = data['Te_error']
543 errTe = data['Te_error']
544 errTi = data['Ti_error']
544 errTi = data['Ti_error']
545
545
546 if ax.firsttime:
546 if ax.firsttime:
547
547
548 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
548 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
549 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='',linewidth=2.0, label='Ti')
549 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='',linewidth=2.0, label='Ti')
550 plt.legend(loc='lower right')
550 plt.legend(loc='lower right')
551 self.ystep_given = 200
551 self.ystep_given = 200
552 ax.yaxis.set_minor_locator(MultipleLocator(15))
552 ax.yaxis.set_minor_locator(MultipleLocator(15))
553 ax.grid(which='minor')
553 ax.grid(which='minor')
554
554
555 else:
555 else:
556 self.clear_figures()
556 self.clear_figures()
557 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
557 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='Te')
558 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='k',linewidth=2.0, label='Ti')
558 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='k',linewidth=2.0, label='Ti')
559 plt.legend(loc='lower right')
559 plt.legend(loc='lower right')
560 ax.yaxis.set_minor_locator(MultipleLocator(15))
560 ax.yaxis.set_minor_locator(MultipleLocator(15))
561 ax.grid(which='minor')
561 ax.grid(which='minor')
562
562
563
563
564 class FracsHPPlot(Plot):
564 class FracsHPPlot(Plot):
565 '''
565 '''
566 Written by R. Flores
566 Written by R. Flores
567 '''
567 '''
568 '''
568 '''
569 Plot for Composition LP
569 Plot for Composition LP
570 '''
570 '''
571
571
572 CODE = 'fracs_LP'
572 CODE = 'fracs_LP'
573 plot_type = 'scatterbuffer'
573 plot_type = 'scatterbuffer'
574
574
575
575
576 def setup(self):
576 def setup(self):
577
577
578 self.ncols = 1
578 self.ncols = 1
579 self.nrows = 1
579 self.nrows = 1
580 self.nplots = 1
580 self.nplots = 1
581 self.ylabel = 'Range [km]'
581 self.ylabel = 'Range [km]'
582 self.xlabel = 'Frac'
582 self.xlabel = 'Frac'
583 self.titles = ['Composition']
583 self.titles = ['Composition']
584 self.width = 3.5
584 self.width = 3.5
585 self.height = 6.5
585 self.height = 6.5
586 self.colorbar = False
586 self.colorbar = False
587 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
587 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
588
588
589 def update(self, dataOut):
589 def update(self, dataOut):
590 data = {}
590 data = {}
591 meta = {}
591 meta = {}
592
592
593 #aux_nan=numpy.zeros(dataOut.cut,'float32')
593 #aux_nan=numpy.zeros(dataOut.cut,'float32')
594 #aux_nan[:]=numpy.nan
594 #aux_nan[:]=numpy.nan
595 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
595 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
596 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
596 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
597
597
598 data['ph'] = dataOut.ph[dataOut.cut:]
598 data['ph'] = dataOut.ph[dataOut.cut:]
599 data['eph'] = dataOut.eph[dataOut.cut:]
599 data['eph'] = dataOut.eph[dataOut.cut:]
600 data['phe'] = dataOut.phe[dataOut.cut:]
600 data['phe'] = dataOut.phe[dataOut.cut:]
601 data['ephe'] = dataOut.ephe[dataOut.cut:]
601 data['ephe'] = dataOut.ephe[dataOut.cut:]
602
602
603 data['cut'] = dataOut.cut
603 data['cut'] = dataOut.cut
604
604
605 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
605 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
606
606
607
607
608 return data, meta
608 return data, meta
609
609
610 def plot(self):
610 def plot(self):
611
611
612 data = self.data[-1]
612 data = self.data[-1]
613
613
614 ph = data['ph']
614 ph = data['ph']
615 eph = data['eph']
615 eph = data['eph']
616 phe = data['phe']
616 phe = data['phe']
617 ephe = data['ephe']
617 ephe = data['ephe']
618 cut = data['cut']
618 cut = data['cut']
619 self.y = self.data.yrange
619 self.y = self.data.yrange
620
620
621 self.xmin = 0
621 self.xmin = 0
622 self.xmax = 1
622 self.xmax = 1
623 ax = self.axes[0]
623 ax = self.axes[0]
624
624
625 if ax.firsttime:
625 if ax.firsttime:
626
626
627 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='H+')
627 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='H+')
628 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='k',linewidth=2.0, label='He+')
628 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='k',linewidth=2.0, label='He+')
629 plt.legend(loc='lower right')
629 plt.legend(loc='lower right')
630 self.xstep_given = 0.2
630 self.xstep_given = 0.2
631 self.ystep_given = 200
631 self.ystep_given = 200
632 ax.yaxis.set_minor_locator(MultipleLocator(15))
632 ax.yaxis.set_minor_locator(MultipleLocator(15))
633 ax.grid(which='minor')
633 ax.grid(which='minor')
634
634
635 else:
635 else:
636 self.clear_figures()
636 self.clear_figures()
637 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='H+')
637 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='r',linewidth=2.0, label='H+')
638 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='k',linewidth=2.0, label='He+')
638 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='k',linewidth=2.0, label='He+')
639 plt.legend(loc='lower right')
639 plt.legend(loc='lower right')
640 ax.yaxis.set_minor_locator(MultipleLocator(15))
640 ax.yaxis.set_minor_locator(MultipleLocator(15))
641 ax.grid(which='minor')
641 ax.grid(which='minor')
642
642
643 class EDensityPlot(Plot):
643 class EDensityPlot(Plot):
644 '''
644 '''
645 Written by R. Flores
645 Written by R. Flores
646 '''
646 '''
647 '''
647 '''
648 Plot for electron density
648 Plot for electron density
649 '''
649 '''
650
650
651 CODE = 'den'
651 CODE = 'den'
652 #plot_name = 'Electron Density'
652 #plot_name = 'Electron Density'
653 plot_type = 'scatterbuffer'
653 plot_type = 'scatterbuffer'
654
654
655 def setup(self):
655 def setup(self):
656
656
657 self.ncols = 1
657 self.ncols = 1
658 self.nrows = 1
658 self.nrows = 1
659 self.nplots = 1
659 self.nplots = 1
660 self.ylabel = 'Range [km]'
660 self.ylabel = 'Range [km]'
661 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
661 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
662 self.titles = ['Electron Density']
662 self.titles = ['Electron Density']
663 self.width = 3.5
663 self.width = 3.5
664 self.height = 5.5
664 self.height = 5.5
665 self.colorbar = False
665 self.colorbar = False
666 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
666 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
667
667
668 def update(self, dataOut):
668 def update(self, dataOut):
669 data = {}
669 data = {}
670 meta = {}
670 meta = {}
671
671
672 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
672 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
673 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
673 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
674 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
674 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
675 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
675 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
676 #print(numpy.shape(data['den_power']))
676 #print(numpy.shape(data['den_power']))
677 #print(numpy.shape(data['den_Faraday']))
677 #print(numpy.shape(data['den_Faraday']))
678 #print(numpy.shape(data['den_error']))
678 #print(numpy.shape(data['den_error']))
679
679
680 data['NSHTS'] = dataOut.NSHTS
680 data['NSHTS'] = dataOut.NSHTS
681
681
682 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
682 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
683
683
684 return data, meta
684 return data, meta
685
685
686 def plot(self):
686 def plot(self):
687
687
688 y = self.data.yrange
688 y = self.data.yrange
689
689
690 #self.xmin = 1e3
690 #self.xmin = 1e3
691 #self.xmax = 1e7
691 #self.xmax = 1e7
692
692
693 ax = self.axes[0]
693 ax = self.axes[0]
694
694
695 data = self.data[-1]
695 data = self.data[-1]
696
696
697 DenPow = data['den_power']
697 DenPow = data['den_power']
698 DenFar = data['den_Faraday']
698 DenFar = data['den_Faraday']
699 errDenPow = data['den_error']
699 errDenPow = data['den_error']
700 #errFaraday = data['err_Faraday']
700 #errFaraday = data['err_Faraday']
701
701
702 NSHTS = data['NSHTS']
702 NSHTS = data['NSHTS']
703
703
704 if self.CODE == 'denLP':
704 if self.CODE == 'denLP':
705 DenPowLP = data['den_LP']
705 DenPowLP = data['den_LP']
706 errDenPowLP = data['den_LP_error']
706 errDenPowLP = data['den_LP_error']
707 cut = data['cut']
707 cut = data['cut']
708
708
709 if ax.firsttime:
709 if ax.firsttime:
710 self.autoxticks=False
710 self.autoxticks=False
711 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
711 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
712 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2,linestyle='-')
712 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2,linestyle='-')
713 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
713 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
714 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
714 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
715
715
716 if self.CODE=='denLP':
716 if self.CODE=='denLP':
717 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
717 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
718
718
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 ax.set_xscale("log")#, nonposx='clip')
721 ax.set_xscale("log")#, nonposx='clip')
722 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
722 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
723 self.ystep_given=100
723 self.ystep_given=100
724 if self.CODE=='denLP':
724 if self.CODE=='denLP':
725 self.ystep_given=200
725 self.ystep_given=200
726 ax.set_yticks(grid_y_ticks,minor=True)
726 ax.set_yticks(grid_y_ticks,minor=True)
727 locmaj = LogLocator(base=10,numticks=12)
727 locmaj = LogLocator(base=10,numticks=12)
728 ax.xaxis.set_major_locator(locmaj)
728 ax.xaxis.set_major_locator(locmaj)
729 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
729 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
730 ax.xaxis.set_minor_locator(locmin)
730 ax.xaxis.set_minor_locator(locmin)
731 ax.xaxis.set_minor_formatter(NullFormatter())
731 ax.xaxis.set_minor_formatter(NullFormatter())
732 ax.grid(which='minor')
732 ax.grid(which='minor')
733
733
734 else:
734 else:
735 dataBefore = self.data[-2]
735 dataBefore = self.data[-2]
736 DenPowBefore = dataBefore['den_power']
736 DenPowBefore = dataBefore['den_power']
737 self.clear_figures()
737 self.clear_figures()
738 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
738 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
739 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2,linestyle='-')
739 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2,linestyle='-')
740 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
740 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
741 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
741 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
742 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
742 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
743
743
744 if self.CODE=='denLP':
744 if self.CODE=='denLP':
745 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
745 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
746
746
747 ax.set_xscale("log")#, nonposx='clip')
747 ax.set_xscale("log")#, nonposx='clip')
748 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
748 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
749 ax.set_yticks(grid_y_ticks,minor=True)
749 ax.set_yticks(grid_y_ticks,minor=True)
750 locmaj = LogLocator(base=10,numticks=12)
750 locmaj = LogLocator(base=10,numticks=12)
751 ax.xaxis.set_major_locator(locmaj)
751 ax.xaxis.set_major_locator(locmaj)
752 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
752 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
753 ax.xaxis.set_minor_locator(locmin)
753 ax.xaxis.set_minor_locator(locmin)
754 ax.xaxis.set_minor_formatter(NullFormatter())
754 ax.xaxis.set_minor_formatter(NullFormatter())
755 ax.grid(which='minor')
755 ax.grid(which='minor')
756 plt.legend(loc='upper left',fontsize=8.5)
756 plt.legend(loc='upper left',fontsize=8.5)
757 #plt.legend(loc='lower left',fontsize=8.5)
757 #plt.legend(loc='lower left',fontsize=8.5)
758
758
759 class RelativeDenPlot(Plot):
759 class RelativeDenPlot(Plot):
760 '''
760 '''
761 Written by R. Flores
761 Written by R. Flores
762 '''
762 '''
763 '''
763 '''
764 Plot for electron density
764 Plot for electron density
765 '''
765 '''
766
766
767 CODE = 'den'
767 CODE = 'den'
768 #plot_name = 'Electron Density'
768 #plot_name = 'Electron Density'
769 plot_type = 'scatterbuffer'
769 plot_type = 'scatterbuffer'
770
770
771 def setup(self):
771 def setup(self):
772
772
773 self.ncols = 1
773 self.ncols = 1
774 self.nrows = 1
774 self.nrows = 1
775 self.nplots = 1
775 self.nplots = 1
776 self.ylabel = 'Range [km]'
776 self.ylabel = 'Range [km]'
777 self.xlabel = r'$\mathrm{N_e}$ Relative Electron Density ($\mathrm{1/cm^3}$)'
777 self.xlabel = r'$\mathrm{N_e}$ Relative Electron Density ($\mathrm{1/cm^3}$)'
778 self.titles = ['Electron Density']
778 self.titles = ['Electron Density']
779 self.width = 3.5
779 self.width = 3.5
780 self.height = 5.5
780 self.height = 5.5
781 self.colorbar = False
781 self.colorbar = False
782 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
782 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
783
783
784 def update(self, dataOut):
784 def update(self, dataOut):
785 data = {}
785 data = {}
786 meta = {}
786 meta = {}
787
787
788 data['den_power'] = dataOut.ph2
788 data['den_power'] = dataOut.ph2
789 data['den_error'] = dataOut.sdp2
789 data['den_error'] = dataOut.sdp2
790
790
791 meta['yrange'] = dataOut.heightList
791 meta['yrange'] = dataOut.heightList
792
792
793 return data, meta
793 return data, meta
794
794
795 def plot(self):
795 def plot(self):
796
796
797 y = self.data.yrange
797 y = self.data.yrange
798
798
799 ax = self.axes[0]
799 ax = self.axes[0]
800
800
801 data = self.data[-1]
801 data = self.data[-1]
802
802
803 DenPow = data['den_power']
803 DenPow = data['den_power']
804 errDenPow = data['den_error']
804 errDenPow = data['den_error']
805
805
806 if ax.firsttime:
806 if ax.firsttime:
807 self.autoxticks=False
807 self.autoxticks=False
808 ax.errorbar(DenPow, y, fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
808 ax.errorbar(DenPow, y, fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
809
809
810 plt.legend(loc='upper left',fontsize=8.5)
810 plt.legend(loc='upper left',fontsize=8.5)
811 #plt.legend(loc='lower left',fontsize=8.5)
811 #plt.legend(loc='lower left',fontsize=8.5)
812 ax.set_xscale("log")#, nonposx='clip')
812 ax.set_xscale("log")#, nonposx='clip')
813 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
813 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
814 self.ystep_given=100
814 self.ystep_given=100
815 ax.set_yticks(grid_y_ticks,minor=True)
815 ax.set_yticks(grid_y_ticks,minor=True)
816 locmaj = LogLocator(base=10,numticks=12)
816 locmaj = LogLocator(base=10,numticks=12)
817 ax.xaxis.set_major_locator(locmaj)
817 ax.xaxis.set_major_locator(locmaj)
818 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
818 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
819 ax.xaxis.set_minor_locator(locmin)
819 ax.xaxis.set_minor_locator(locmin)
820 ax.xaxis.set_minor_formatter(NullFormatter())
820 ax.xaxis.set_minor_formatter(NullFormatter())
821 ax.grid(which='minor')
821 ax.grid(which='minor')
822
822
823 else:
823 else:
824 dataBefore = self.data[-2]
824 dataBefore = self.data[-2]
825 DenPowBefore = dataBefore['den_power']
825 DenPowBefore = dataBefore['den_power']
826 self.clear_figures()
826 self.clear_figures()
827 ax.errorbar(DenPow, y, fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
827 ax.errorbar(DenPow, y, fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='k',linewidth=1.0, label='Power',markersize=2,linestyle='-')
828 ax.errorbar(DenPowBefore, y, elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
828 ax.errorbar(DenPowBefore, y, elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
829
829
830 ax.set_xscale("log")#, nonposx='clip')
830 ax.set_xscale("log")#, nonposx='clip')
831 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
831 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
832 ax.set_yticks(grid_y_ticks,minor=True)
832 ax.set_yticks(grid_y_ticks,minor=True)
833 locmaj = LogLocator(base=10,numticks=12)
833 locmaj = LogLocator(base=10,numticks=12)
834 ax.xaxis.set_major_locator(locmaj)
834 ax.xaxis.set_major_locator(locmaj)
835 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
835 locmin = LogLocator(base=10.0,subs=(0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=12)
836 ax.xaxis.set_minor_locator(locmin)
836 ax.xaxis.set_minor_locator(locmin)
837 ax.xaxis.set_minor_formatter(NullFormatter())
837 ax.xaxis.set_minor_formatter(NullFormatter())
838 ax.grid(which='minor')
838 ax.grid(which='minor')
839 plt.legend(loc='upper left',fontsize=8.5)
839 plt.legend(loc='upper left',fontsize=8.5)
840 #plt.legend(loc='lower left',fontsize=8.5)
840 #plt.legend(loc='lower left',fontsize=8.5)
841
841
842 class FaradayAnglePlot(Plot):
842 class FaradayAnglePlot(Plot):
843 '''
843 '''
844 Written by R. Flores
844 Written by R. Flores
845 '''
845 '''
846 '''
846 '''
847 Plot for electron density
847 Plot for electron density
848 '''
848 '''
849
849
850 CODE = 'angle'
850 CODE = 'angle'
851 plot_name = 'Faraday Angle'
851 plot_name = 'Faraday Angle'
852 plot_type = 'scatterbuffer'
852 plot_type = 'scatterbuffer'
853
853
854 def setup(self):
854 def setup(self):
855
855
856 self.ncols = 1
856 self.ncols = 1
857 self.nrows = 1
857 self.nrows = 1
858 self.nplots = 1
858 self.nplots = 1
859 self.ylabel = 'Range [km]'
859 self.ylabel = 'Range [km]'
860 self.xlabel = 'Faraday Angle (º)'
860 self.xlabel = 'Faraday Angle (º)'
861 self.titles = ['Electron Density']
861 self.titles = ['Electron Density']
862 self.width = 3.5
862 self.width = 3.5
863 self.height = 5.5
863 self.height = 5.5
864 self.colorbar = False
864 self.colorbar = False
865 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
865 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
866
866
867 def update(self, dataOut):
867 def update(self, dataOut):
868 data = {}
868 data = {}
869 meta = {}
869 meta = {}
870
870
871 data['angle'] = numpy.degrees(dataOut.phi)
871 data['angle'] = numpy.degrees(dataOut.phi)
872 #'''
872 #'''
873 #print(dataOut.phi_uwrp)
873 #print(dataOut.phi_uwrp)
874 #print(data['angle'])
874 #print(data['angle'])
875 #exit(1)
875 #exit(1)
876 #'''
876 #'''
877 data['dphi'] = dataOut.dphi_uc*10
877 data['dphi'] = dataOut.dphi_uc*10
878 #print(dataOut.dphi)
878 #print(dataOut.dphi)
879
879
880 #data['NSHTS'] = dataOut.NSHTS
880 #data['NSHTS'] = dataOut.NSHTS
881
881
882 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
882 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
883
883
884 return data, meta
884 return data, meta
885
885
886 def plot(self):
886 def plot(self):
887
887
888 data = self.data[-1]
888 data = self.data[-1]
889 self.x = data[self.CODE]
889 self.x = data[self.CODE]
890 dphi = data['dphi']
890 dphi = data['dphi']
891 self.y = self.data.yrange
891 self.y = self.data.yrange
892 self.xmin = -360#-180
892 self.xmin = -360#-180
893 self.xmax = 360#180
893 self.xmax = 360#180
894 ax = self.axes[0]
894 ax = self.axes[0]
895
895
896 if ax.firsttime:
896 if ax.firsttime:
897 self.autoxticks=False
897 self.autoxticks=False
898 #if self.CODE=='den':
898 #if self.CODE=='den':
899 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
899 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
900 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
900 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
901
901
902 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
902 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
903 self.ystep_given=100
903 self.ystep_given=100
904 if self.CODE=='denLP':
904 if self.CODE=='denLP':
905 self.ystep_given=200
905 self.ystep_given=200
906 ax.set_yticks(grid_y_ticks,minor=True)
906 ax.set_yticks(grid_y_ticks,minor=True)
907 ax.grid(which='minor')
907 ax.grid(which='minor')
908 #plt.tight_layout()
908 #plt.tight_layout()
909 else:
909 else:
910
910
911 self.clear_figures()
911 self.clear_figures()
912 #if self.CODE=='den':
912 #if self.CODE=='den':
913 #print(numpy.shape(self.x))
913 #print(numpy.shape(self.x))
914 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
914 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
915 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
915 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
916
916
917 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
917 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
918 ax.set_yticks(grid_y_ticks,minor=True)
918 ax.set_yticks(grid_y_ticks,minor=True)
919 ax.grid(which='minor')
919 ax.grid(which='minor')
920
920
921 class EDensityHPPlot(EDensityPlot):
921 class EDensityHPPlot(EDensityPlot):
922 '''
922 '''
923 Written by R. Flores
923 Written by R. Flores
924 '''
924 '''
925 '''
925 '''
926 Plot for Electron Density Hybrid Experiment
926 Plot for Electron Density Hybrid Experiment
927 '''
927 '''
928
928
929 CODE = 'denLP'
929 CODE = 'denLP'
930 plot_name = 'Electron Density'
930 plot_name = 'Electron Density'
931 plot_type = 'scatterbuffer'
931 plot_type = 'scatterbuffer'
932
932
933 def update(self, dataOut):
933 def update(self, dataOut):
934 data = {}
934 data = {}
935 meta = {}
935 meta = {}
936
936
937 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
937 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
938 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
938 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
939 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
939 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
940 data['den_LP']=dataOut.ne[:dataOut.NACF]
940 data['den_LP']=dataOut.ne[:dataOut.NACF]
941 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
941 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
942 #self.ene=10**dataOut.ene[:dataOut.NACF]
942 #self.ene=10**dataOut.ene[:dataOut.NACF]
943 data['NSHTS']=dataOut.NSHTS
943 data['NSHTS']=dataOut.NSHTS
944 data['cut']=dataOut.cut
944 data['cut']=dataOut.cut
945
945
946 return data, meta
946 return data, meta
947
947
948
948
949 class ACFsPlot(Plot):
949 class ACFsPlot(Plot):
950 '''
950 '''
951 Written by R. Flores
951 Written by R. Flores
952 '''
952 '''
953 '''
953 '''
954 Plot for ACFs Double Pulse Experiment
954 Plot for ACFs Double Pulse Experiment
955 '''
955 '''
956
956
957 CODE = 'acfs'
957 CODE = 'acfs'
958 #plot_name = 'ACF'
958 #plot_name = 'ACF'
959 plot_type = 'scatterbuffer'
959 plot_type = 'scatterbuffer'
960
960
961
961
962 def setup(self):
962 def setup(self):
963 self.ncols = 1
963 self.ncols = 1
964 self.nrows = 1
964 self.nrows = 1
965 self.nplots = 1
965 self.nplots = 1
966 self.ylabel = 'Range [km]'
966 self.ylabel = 'Range [km]'
967 self.xlabel = 'Lag (ms)'
967 self.xlabel = 'Lag (ms)'
968 self.titles = ['ACFs']
968 self.titles = ['ACFs']
969 self.width = 3.5
969 self.width = 3.5
970 self.height = 5.5
970 self.height = 5.5
971 self.colorbar = False
971 self.colorbar = False
972 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
972 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
973
973
974 def update(self, dataOut):
974 def update(self, dataOut):
975 data = {}
975 data = {}
976 meta = {}
976 meta = {}
977
977
978 data['ACFs'] = dataOut.acfs_to_plot
978 data['ACFs'] = dataOut.acfs_to_plot
979 data['ACFs_error'] = dataOut.acfs_error_to_plot
979 data['ACFs_error'] = dataOut.acfs_error_to_plot
980 data['lags'] = dataOut.lags_to_plot
980 data['lags'] = dataOut.lags_to_plot
981 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
981 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
982 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
982 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
983 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
983 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
984 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
984 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
985
985
986 meta['yrange'] = numpy.array([])
986 meta['yrange'] = numpy.array([])
987 #meta['NSHTS'] = dataOut.NSHTS
987 #meta['NSHTS'] = dataOut.NSHTS
988 #meta['DPL'] = dataOut.DPL
988 #meta['DPL'] = dataOut.DPL
989 data['NSHTS'] = dataOut.NSHTS #This is metadata
989 data['NSHTS'] = dataOut.NSHTS #This is metadata
990 data['DPL'] = dataOut.DPL #This is metadata
990 data['DPL'] = dataOut.DPL #This is metadata
991
991
992 return data, meta
992 return data, meta
993
993
994 def plot(self):
994 def plot(self):
995
995
996 data = self.data[-1]
996 data = self.data[-1]
997 #NSHTS = self.meta['NSHTS']
997 #NSHTS = self.meta['NSHTS']
998 #DPL = self.meta['DPL']
998 #DPL = self.meta['DPL']
999 NSHTS = data['NSHTS'] #This is metadata
999 NSHTS = data['NSHTS'] #This is metadata
1000 DPL = data['DPL'] #This is metadata
1000 DPL = data['DPL'] #This is metadata
1001
1001
1002 lags = data['lags']
1002 lags = data['lags']
1003 ACFs = data['ACFs']
1003 ACFs = data['ACFs']
1004 errACFs = data['ACFs_error']
1004 errACFs = data['ACFs_error']
1005 BadLag1 = data['Lag_contaminated_1']
1005 BadLag1 = data['Lag_contaminated_1']
1006 BadLag2 = data['Lag_contaminated_2']
1006 BadLag2 = data['Lag_contaminated_2']
1007 BadHei1 = data['Height_contaminated_1']
1007 BadHei1 = data['Height_contaminated_1']
1008 BadHei2 = data['Height_contaminated_2']
1008 BadHei2 = data['Height_contaminated_2']
1009
1009
1010 self.xmin = 0.0
1010 self.xmin = 0.0
1011 self.xmax = 2.0
1011 #self.xmax = 2.0
1012 self.y = ACFs
1012 self.y = ACFs
1013
1013
1014 ax = self.axes[0]
1014 ax = self.axes[0]
1015
1015
1016 if ax.firsttime:
1016 if ax.firsttime:
1017
1017
1018 for i in range(NSHTS):
1018 for i in range(NSHTS):
1019 x_aux = numpy.isfinite(lags[i,:])
1019 x_aux = numpy.isfinite(lags[i,:])
1020 y_aux = numpy.isfinite(ACFs[i,:])
1020 y_aux = numpy.isfinite(ACFs[i,:])
1021 yerr_aux = numpy.isfinite(errACFs[i,:])
1021 yerr_aux = numpy.isfinite(errACFs[i,:])
1022 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
1022 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
1023 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
1023 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
1024 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
1024 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
1025 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
1025 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
1026 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1026 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1027 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
1027 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
1028 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
1028 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
1029 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
1029 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
1030
1030
1031 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
1031 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
1032 self.ystep_given = 50
1032 self.ystep_given = 50
1033 ax.yaxis.set_minor_locator(MultipleLocator(15))
1033 ax.yaxis.set_minor_locator(MultipleLocator(15))
1034 ax.grid(which='minor')
1034 ax.grid(which='minor')
1035
1035
1036 else:
1036 else:
1037 self.clear_figures()
1037 self.clear_figures()
1038 for i in range(NSHTS):
1038 for i in range(NSHTS):
1039 x_aux = numpy.isfinite(lags[i,:])
1039 x_aux = numpy.isfinite(lags[i,:])
1040 y_aux = numpy.isfinite(ACFs[i,:])
1040 y_aux = numpy.isfinite(ACFs[i,:])
1041 yerr_aux = numpy.isfinite(errACFs[i,:])
1041 yerr_aux = numpy.isfinite(errACFs[i,:])
1042 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
1042 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
1043 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
1043 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
1044 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
1044 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
1045 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
1045 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
1046 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1046 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1047 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
1047 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
1048 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
1048 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
1049 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
1049 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
1050 ax.yaxis.set_minor_locator(MultipleLocator(15))
1050 ax.yaxis.set_minor_locator(MultipleLocator(15))
1051
1051
1052 class ACFsLPPlot(Plot):
1052 class ACFsLPPlot(Plot):
1053 '''
1053 '''
1054 Written by R. Flores
1054 Written by R. Flores
1055 '''
1055 '''
1056 '''
1056 '''
1057 Plot for ACFs Double Pulse Experiment
1057 Plot for ACFs Double Pulse Experiment
1058 '''
1058 '''
1059
1059
1060 CODE = 'acfs_LP'
1060 CODE = 'acfs_LP'
1061 #plot_name = 'ACF'
1061 #plot_name = 'ACF'
1062 plot_type = 'scatterbuffer'
1062 plot_type = 'scatterbuffer'
1063
1063
1064
1064
1065 def setup(self):
1065 def setup(self):
1066 self.ncols = 1
1066 self.ncols = 1
1067 self.nrows = 1
1067 self.nrows = 1
1068 self.nplots = 1
1068 self.nplots = 1
1069 self.ylabel = 'Range [km]'
1069 self.ylabel = 'Range [km]'
1070 self.xlabel = 'Lag (ms)'
1070 self.xlabel = 'Lag (ms)'
1071 self.titles = ['ACFs']
1071 self.titles = ['ACFs']
1072 self.width = 3.5
1072 self.width = 3.5
1073 self.height = 5.5
1073 self.height = 5.5
1074 self.colorbar = False
1074 self.colorbar = False
1075 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1075 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1076
1076
1077 def update(self, dataOut):
1077 def update(self, dataOut):
1078 data = {}
1078 data = {}
1079 meta = {}
1079 meta = {}
1080
1080
1081 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1081 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1082 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1082 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1083 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1083 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1084
1084
1085 for i in range(dataOut.NACF):
1085 for i in range(dataOut.NACF):
1086 for j in range(dataOut.IBITS):
1086 for j in range(dataOut.IBITS):
1087 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
1087 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
1088 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
1088 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
1089 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
1089 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
1090 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
1090 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
1091 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
1091 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
1092 else:
1092 else:
1093 aux[i,j]=numpy.nan
1093 aux[i,j]=numpy.nan
1094 lags_LP_to_plot[i,j]=numpy.nan
1094 lags_LP_to_plot[i,j]=numpy.nan
1095 errors[i,j]=numpy.nan
1095 errors[i,j]=numpy.nan
1096
1096
1097 data['ACFs'] = aux
1097 data['ACFs'] = aux
1098 data['ACFs_error'] = errors
1098 data['ACFs_error'] = errors
1099 data['lags'] = lags_LP_to_plot
1099 data['lags'] = lags_LP_to_plot
1100
1100
1101 meta['yrange'] = numpy.array([])
1101 meta['yrange'] = numpy.array([])
1102 #meta['NACF'] = dataOut.NACF
1102 #meta['NACF'] = dataOut.NACF
1103 #meta['NLAG'] = dataOut.NLAG
1103 #meta['NLAG'] = dataOut.NLAG
1104 data['NACF'] = dataOut.NACF #This is metadata
1104 data['NACF'] = dataOut.NACF #This is metadata
1105 data['NLAG'] = dataOut.NLAG #This is metadata
1105 data['NLAG'] = dataOut.NLAG #This is metadata
1106
1106
1107 return data, meta
1107 return data, meta
1108
1108
1109 def plot(self):
1109 def plot(self):
1110
1110
1111 data = self.data[-1]
1111 data = self.data[-1]
1112 #NACF = self.meta['NACF']
1112 #NACF = self.meta['NACF']
1113 #NLAG = self.meta['NLAG']
1113 #NLAG = self.meta['NLAG']
1114 NACF = data['NACF'] #This is metadata
1114 NACF = data['NACF'] #This is metadata
1115 NLAG = data['NLAG'] #This is metadata
1115 NLAG = data['NLAG'] #This is metadata
1116
1116
1117 lags = data['lags']
1117 lags = data['lags']
1118 ACFs = data['ACFs']
1118 ACFs = data['ACFs']
1119 errACFs = data['ACFs_error']
1119 errACFs = data['ACFs_error']
1120
1120
1121 self.xmin = 0.0
1121 self.xmin = 0.0
1122 self.xmax = 1.5
1122 self.xmax = 1.5
1123
1123
1124 self.y = ACFs
1124 self.y = ACFs
1125
1125
1126 ax = self.axes[0]
1126 ax = self.axes[0]
1127
1127
1128 if ax.firsttime:
1128 if ax.firsttime:
1129
1129
1130 for i in range(NACF):
1130 for i in range(NACF):
1131 x_aux = numpy.isfinite(lags[i,:])
1131 x_aux = numpy.isfinite(lags[i,:])
1132 y_aux = numpy.isfinite(ACFs[i,:])
1132 y_aux = numpy.isfinite(ACFs[i,:])
1133 yerr_aux = numpy.isfinite(errACFs[i,:])
1133 yerr_aux = numpy.isfinite(errACFs[i,:])
1134
1134
1135 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1135 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1136 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1136 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1137
1137
1138 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1138 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1139 self.xstep_given=0.3
1139 self.xstep_given=0.3
1140 self.ystep_given = 200
1140 self.ystep_given = 200
1141 ax.yaxis.set_minor_locator(MultipleLocator(15))
1141 ax.yaxis.set_minor_locator(MultipleLocator(15))
1142 ax.grid(which='minor')
1142 ax.grid(which='minor')
1143
1143
1144 else:
1144 else:
1145 self.clear_figures()
1145 self.clear_figures()
1146
1146
1147 for i in range(NACF):
1147 for i in range(NACF):
1148 x_aux = numpy.isfinite(lags[i,:])
1148 x_aux = numpy.isfinite(lags[i,:])
1149 y_aux = numpy.isfinite(ACFs[i,:])
1149 y_aux = numpy.isfinite(ACFs[i,:])
1150 yerr_aux = numpy.isfinite(errACFs[i,:])
1150 yerr_aux = numpy.isfinite(errACFs[i,:])
1151
1151
1152 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1152 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1153 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1153 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1154
1154
1155 ax.yaxis.set_minor_locator(MultipleLocator(15))
1155 ax.yaxis.set_minor_locator(MultipleLocator(15))
1156
1156
1157
1157
1158 class CrossProductsPlot(Plot):
1158 class CrossProductsPlot(Plot):
1159 '''
1159 '''
1160 Written by R. Flores
1160 Written by R. Flores
1161 '''
1161 '''
1162 '''
1162 '''
1163 Plot for cross products
1163 Plot for cross products
1164 '''
1164 '''
1165
1165
1166 CODE = 'crossprod'
1166 CODE = 'crossprod'
1167 plot_name = 'Cross Products'
1167 plot_name = 'Cross Products'
1168 plot_type = 'scatterbuffer'
1168 plot_type = 'scatterbuffer'
1169
1169
1170 def setup(self):
1170 def setup(self):
1171
1171
1172 self.ncols = 3
1172 self.ncols = 3
1173 self.nrows = 1
1173 self.nrows = 1
1174 self.nplots = 3
1174 self.nplots = 3
1175 self.ylabel = 'Range [km]'
1175 self.ylabel = 'Range [km]'
1176 self.titles = []
1176 self.titles = []
1177 self.width = 3.5*self.nplots
1177 self.width = 3.5*self.nplots
1178 self.height = 5.5
1178 self.height = 5.5
1179 self.colorbar = False
1179 self.colorbar = False
1180 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1180 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1181
1181
1182
1182
1183 def update(self, dataOut):
1183 def update(self, dataOut):
1184
1184
1185 data = {}
1185 data = {}
1186 meta = {}
1186 meta = {}
1187
1187
1188 data['crossprod'] = dataOut.crossprods
1188 data['crossprod'] = dataOut.crossprods
1189 data['NDP'] = dataOut.NDP
1189 data['NDP'] = dataOut.NDP
1190
1190
1191 return data, meta
1191 return data, meta
1192
1192
1193 def plot(self):
1193 def plot(self):
1194
1194
1195 NDP = self.data['NDP'][-1]
1195 NDP = self.data['NDP'][-1]
1196 x = self.data['crossprod'][:,-1,:,:,:,:]
1196 x = self.data['crossprod'][:,-1,:,:,:,:]
1197 y = self.data.yrange[0:NDP]
1197 y = self.data.yrange[0:NDP]
1198
1198
1199 for n, ax in enumerate(self.axes):
1199 for n, ax in enumerate(self.axes):
1200
1200
1201 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])))
1201 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])))
1202 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])))
1202 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])))
1203
1203
1204 if ax.firsttime:
1204 if ax.firsttime:
1205
1205
1206 self.autoxticks=False
1206 self.autoxticks=False
1207 if n==0:
1207 if n==0:
1208 label1='kax'
1208 label1='kax'
1209 label2='kay'
1209 label2='kay'
1210 label3='kbx'
1210 label3='kbx'
1211 label4='kby'
1211 label4='kby'
1212 self.xlimits=[(self.xmin,self.xmax)]
1212 self.xlimits=[(self.xmin,self.xmax)]
1213 elif n==1:
1213 elif n==1:
1214 label1='kax2'
1214 label1='kax2'
1215 label2='kay2'
1215 label2='kay2'
1216 label3='kbx2'
1216 label3='kbx2'
1217 label4='kby2'
1217 label4='kby2'
1218 self.xlimits.append((self.xmin,self.xmax))
1218 self.xlimits.append((self.xmin,self.xmax))
1219 elif n==2:
1219 elif n==2:
1220 label1='kaxay'
1220 label1='kaxay'
1221 label2='kbxby'
1221 label2='kbxby'
1222 label3='kaxbx'
1222 label3='kaxbx'
1223 label4='kaxby'
1223 label4='kaxby'
1224 self.xlimits.append((self.xmin,self.xmax))
1224 self.xlimits.append((self.xmin,self.xmax))
1225
1225
1226 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1226 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1227 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1227 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1228 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1228 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1229 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1229 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1230 ax.legend(loc='upper right')
1230 ax.legend(loc='upper right')
1231 ax.set_xlim(self.xmin, self.xmax)
1231 ax.set_xlim(self.xmin, self.xmax)
1232 self.titles.append('{}'.format(self.plot_name.upper()))
1232 self.titles.append('{}'.format(self.plot_name.upper()))
1233
1233
1234 else:
1234 else:
1235
1235
1236 if n==0:
1236 if n==0:
1237 self.xlimits=[(self.xmin,self.xmax)]
1237 self.xlimits=[(self.xmin,self.xmax)]
1238 else:
1238 else:
1239 self.xlimits.append((self.xmin,self.xmax))
1239 self.xlimits.append((self.xmin,self.xmax))
1240
1240
1241 ax.set_xlim(self.xmin, self.xmax)
1241 ax.set_xlim(self.xmin, self.xmax)
1242
1242
1243 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1243 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1244 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1244 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1245 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1245 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1246 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1246 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1247 self.titles.append('{}'.format(self.plot_name.upper()))
1247 self.titles.append('{}'.format(self.plot_name.upper()))
1248
1248
1249
1249
1250 class CrossProductsLPPlot(Plot):
1250 class CrossProductsLPPlot(Plot):
1251 '''
1251 '''
1252 Written by R. Flores
1252 Written by R. Flores
1253 '''
1253 '''
1254 '''
1254 '''
1255 Plot for cross products LP
1255 Plot for cross products LP
1256 '''
1256 '''
1257
1257
1258 CODE = 'crossprodslp'
1258 CODE = 'crossprodslp'
1259 plot_name = 'Cross Products LP'
1259 plot_name = 'Cross Products LP'
1260 plot_type = 'scatterbuffer'
1260 plot_type = 'scatterbuffer'
1261
1261
1262
1262
1263 def setup(self):
1263 def setup(self):
1264
1264
1265 self.ncols = 2
1265 self.ncols = 2
1266 self.nrows = 1
1266 self.nrows = 1
1267 self.nplots = 2
1267 self.nplots = 2
1268 self.ylabel = 'Range [km]'
1268 self.ylabel = 'Range [km]'
1269 self.xlabel = 'dB'
1269 self.xlabel = 'dB'
1270 self.width = 3.5*self.nplots
1270 self.width = 3.5*self.nplots
1271 self.height = 5.5
1271 self.height = 5.5
1272 self.colorbar = False
1272 self.colorbar = False
1273 self.titles = []
1273 self.titles = []
1274 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1274 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1275
1275
1276 def update(self, dataOut):
1276 def update(self, dataOut):
1277 data = {}
1277 data = {}
1278 meta = {}
1278 meta = {}
1279
1279
1280 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1280 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1281
1281
1282 data['NRANGE'] = dataOut.NRANGE #This is metadata
1282 data['NRANGE'] = dataOut.NRANGE #This is metadata
1283 data['NLAG'] = dataOut.NLAG #This is metadata
1283 data['NLAG'] = dataOut.NLAG #This is metadata
1284
1284
1285 return data, meta
1285 return data, meta
1286
1286
1287 def plot(self):
1287 def plot(self):
1288
1288
1289 NRANGE = self.data['NRANGE'][-1]
1289 NRANGE = self.data['NRANGE'][-1]
1290 NLAG = self.data['NLAG'][-1]
1290 NLAG = self.data['NLAG'][-1]
1291
1291
1292 x = self.data[self.CODE][:,-1,:,:]
1292 x = self.data[self.CODE][:,-1,:,:]
1293 self.y = self.data.yrange[0:NRANGE]
1293 self.y = self.data.yrange[0:NRANGE]
1294
1294
1295 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1295 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1296 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1296 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1297
1297
1298
1298
1299 for n, ax in enumerate(self.axes):
1299 for n, ax in enumerate(self.axes):
1300
1300
1301 self.xmin=28#30
1301 self.xmin=28#30
1302 self.xmax=70#70
1302 self.xmax=70#70
1303 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1303 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1304 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1304 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1305
1305
1306 if ax.firsttime:
1306 if ax.firsttime:
1307
1307
1308 self.autoxticks=False
1308 self.autoxticks=False
1309 if n == 0:
1309 if n == 0:
1310 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1310 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1311
1311
1312 for i in range(NLAG):
1312 for i in range(NLAG):
1313 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1313 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1314
1314
1315 ax.legend(loc='upper right')
1315 ax.legend(loc='upper right')
1316 ax.set_xlim(self.xmin, self.xmax)
1316 ax.set_xlim(self.xmin, self.xmax)
1317 if n==0:
1317 if n==0:
1318 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1318 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1319 if n==1:
1319 if n==1:
1320 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1320 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1321 else:
1321 else:
1322 for i in range(NLAG):
1322 for i in range(NLAG):
1323 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1323 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1324
1324
1325 if n==0:
1325 if n==0:
1326 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1326 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1327 if n==1:
1327 if n==1:
1328 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1328 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1329
1329
1330
1330
1331 class NoiseDPPlot(NoisePlot):
1331 class NoiseDPPlot(NoisePlot):
1332 '''
1332 '''
1333 Written by R. Flores
1333 Written by R. Flores
1334 '''
1334 '''
1335 '''
1335 '''
1336 Plot for noise Double Pulse
1336 Plot for noise Double Pulse
1337 '''
1337 '''
1338
1338
1339 CODE = 'noise'
1339 CODE = 'noise'
1340 #plot_name = 'Noise'
1340 #plot_name = 'Noise'
1341 #plot_type = 'scatterbuffer'
1341 #plot_type = 'scatterbuffer'
1342
1342
1343 def update(self, dataOut):
1343 def update(self, dataOut):
1344
1344
1345 data = {}
1345 data = {}
1346 meta = {}
1346 meta = {}
1347 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1347 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1348
1348
1349 return data, meta
1349 return data, meta
1350
1350
1351
1351
1352 class XmitWaveformPlot(Plot):
1352 class XmitWaveformPlot(Plot):
1353 '''
1353 '''
1354 Written by R. Flores
1354 Written by R. Flores
1355 '''
1355 '''
1356 '''
1356 '''
1357 Plot for xmit waveform
1357 Plot for xmit waveform
1358 '''
1358 '''
1359
1359
1360 CODE = 'xmit'
1360 CODE = 'xmit'
1361 plot_name = 'Xmit Waveform'
1361 plot_name = 'Xmit Waveform'
1362 plot_type = 'scatterbuffer'
1362 plot_type = 'scatterbuffer'
1363
1363
1364
1364
1365 def setup(self):
1365 def setup(self):
1366
1366
1367 self.ncols = 1
1367 self.ncols = 1
1368 self.nrows = 1
1368 self.nrows = 1
1369 self.nplots = 1
1369 self.nplots = 1
1370 self.ylabel = ''
1370 self.ylabel = ''
1371 self.xlabel = 'Number of Lag'
1371 self.xlabel = 'Number of Lag'
1372 self.width = 5.5
1372 self.width = 5.5
1373 self.height = 3.5
1373 self.height = 3.5
1374 self.colorbar = False
1374 self.colorbar = False
1375 self.plots_adjust.update({'right': 0.85 })
1375 self.plots_adjust.update({'right': 0.85 })
1376 self.titles = [self.plot_name]
1376 self.titles = [self.plot_name]
1377 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1377 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1378
1378
1379 #if not self.titles:
1379 #if not self.titles:
1380 #self.titles = self.data.parameters \
1380 #self.titles = self.data.parameters \
1381 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1381 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1382
1382
1383 def update(self, dataOut):
1383 def update(self, dataOut):
1384
1384
1385 data = {}
1385 data = {}
1386 meta = {}
1386 meta = {}
1387
1387
1388 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1388 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1389 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1389 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1390 norm=numpy.max(y_2)
1390 norm=numpy.max(y_2)
1391 norm=max(norm,0.1)
1391 norm=max(norm,0.1)
1392 y_2=y_2/norm
1392 y_2=y_2/norm
1393
1393
1394 meta['yrange'] = numpy.array([])
1394 meta['yrange'] = numpy.array([])
1395
1395
1396 data['xmit'] = numpy.vstack((y_1,y_2))
1396 data['xmit'] = numpy.vstack((y_1,y_2))
1397 data['NLAG'] = dataOut.NLAG
1397 data['NLAG'] = dataOut.NLAG
1398
1398
1399 return data, meta
1399 return data, meta
1400
1400
1401 def plot(self):
1401 def plot(self):
1402
1402
1403 data = self.data[-1]
1403 data = self.data[-1]
1404 NLAG = data['NLAG']
1404 NLAG = data['NLAG']
1405 x = numpy.arange(0,NLAG,1,'float32')
1405 x = numpy.arange(0,NLAG,1,'float32')
1406 y = data['xmit']
1406 y = data['xmit']
1407
1407
1408 self.xmin = 0
1408 self.xmin = 0
1409 self.xmax = NLAG-1
1409 self.xmax = NLAG-1
1410 self.ymin = -1.0
1410 self.ymin = -1.0
1411 self.ymax = 1.0
1411 self.ymax = 1.0
1412 ax = self.axes[0]
1412 ax = self.axes[0]
1413
1413
1414 if ax.firsttime:
1414 if ax.firsttime:
1415 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1415 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1416 ax.plotline1=ax.plot(x,y[1,:],color='red')
1416 ax.plotline1=ax.plot(x,y[1,:],color='red')
1417 secax=ax.secondary_xaxis(location=0.5)
1417 secax=ax.secondary_xaxis(location=0.5)
1418 secax.xaxis.tick_bottom()
1418 secax.xaxis.tick_bottom()
1419 secax.tick_params( labelleft=False, labeltop=False,
1419 secax.tick_params( labelleft=False, labeltop=False,
1420 labelright=False, labelbottom=False)
1420 labelright=False, labelbottom=False)
1421
1421
1422 self.xstep_given = 3
1422 self.xstep_given = 3
1423 self.ystep_given = .25
1423 self.ystep_given = .25
1424 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1424 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1425
1425
1426 else:
1426 else:
1427 ax.plotline0[0].set_data(x,y[0,:])
1427 ax.plotline0[0].set_data(x,y[0,:])
1428 ax.plotline1[0].set_data(x,y[1,:])
1428 ax.plotline1[0].set_data(x,y[1,:])
@@ -1,191 +1,241
1 {"conditions": [
1 {"conditions": [
2
2
3 {"year": 2024, "doy": 47, "initial_time": [5,32], "final_time": [6,42], "aux_index": [ null, 11]},
3 {"year": 2024, "doy": 47, "initial_time": [5,32], "final_time": [6,42], "aux_index": [ null, 11]},
4
4
5 {"year": 2024, "doy": 247, "initial_time": [2,0], "final_time": [5,0], "aux_index": [ null, 11]},
5 {"year": 2024, "doy": 247, "initial_time": [2,0], "final_time": [5,0], "aux_index": [ null, 11]},
6 {"year": 2024, "doy": 247, "initial_time": [1,40], "final_time": [2,0], "aux_index": [ null, 26]},
6 {"year": 2024, "doy": 247, "initial_time": [1,40], "final_time": [2,0], "aux_index": [ null, 26]},
7 {"year": 2024, "doy": 247, "initial_time": [0,45], "final_time": [0,45], "aux_index": [ null, 28]},
7 {"year": 2024, "doy": 247, "initial_time": [0,45], "final_time": [0,45], "aux_index": [ null, 28]},
8 {"year": 2024, "doy": 246, "initial_time": [23,15], "final_time": [23,59], "aux_index": [ null, 21]},
8 {"year": 2024, "doy": 246, "initial_time": [23,15], "final_time": [23,59], "aux_index": [ null, 21]},
9 {"year": 2024, "doy": 246, "initial_time": [13,55], "final_time": [23,59], "aux_index": [ null, 11]},
9 {"year": 2024, "doy": 246, "initial_time": [13,55], "final_time": [23,59], "aux_index": [ null, 11]},
10 {"year": 2024, "doy": 247, "initial_time": [0,0], "final_time": [2,25], "aux_index": [ null, 22]},
10 {"year": 2024, "doy": 247, "initial_time": [0,0], "final_time": [2,25], "aux_index": [ null, 22]},
11 {"year": 2024, "doy": 247, "initial_time": [3,0], "final_time": [3,0], "aux_index": [ 34, null]},
11 {"year": 2024, "doy": 247, "initial_time": [3,0], "final_time": [3,0], "aux_index": [ 34, null]},
12
12
13 {"year": 2024, "doy": 247, "initial_time": [5,0], "final_time": [23,59], "aux_index": [ null, 11]},
13 {"year": 2024, "doy": 247, "initial_time": [5,0], "final_time": [23,59], "aux_index": [ null, 11]},
14 {"year": 2024, "doy": 247, "initial_time": [5,0], "final_time": [11,25], "aux_index": [ 11, 13]},
14 {"year": 2024, "doy": 247, "initial_time": [5,0], "final_time": [11,25], "aux_index": [ 11, 13]},
15 {"year": 2024, "doy": 247, "initial_time": [5,30], "final_time": [9,50], "aux_index": [ 13, 13]},
15 {"year": 2024, "doy": 247, "initial_time": [5,30], "final_time": [9,50], "aux_index": [ 13, 13]},
16 {"year": 2024, "doy": 247, "initial_time": [23,15], "final_time": [23,59], "aux_index": [ null, 15]},
16 {"year": 2024, "doy": 247, "initial_time": [23,15], "final_time": [23,59], "aux_index": [ null, 15]},
17 {"year": 2024, "doy": 248, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 13]},
17 {"year": 2024, "doy": 248, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 13]},
18 {"year": 2024, "doy": 248, "initial_time": [0,0], "final_time": [1,50], "aux_index": [ null, 21]},
18 {"year": 2024, "doy": 248, "initial_time": [0,0], "final_time": [1,50], "aux_index": [ null, 21]},
19 {"year": 2024, "doy": 248, "initial_time": [0,0], "final_time": [2,50], "aux_index": [ null, 17]},
19 {"year": 2024, "doy": 248, "initial_time": [0,0], "final_time": [2,50], "aux_index": [ null, 17]},
20 {"year": 2024, "doy": 247, "initial_time": [8,5], "final_time": [8,10], "aux_index": [ null, null]},
20 {"year": 2024, "doy": 247, "initial_time": [8,5], "final_time": [8,10], "aux_index": [ null, null]},
21 {"year": 2024, "doy": 248, "initial_time": [2,50], "final_time": [2,50], "aux_index": [ 30, null]},
21 {"year": 2024, "doy": 248, "initial_time": [2,50], "final_time": [2,50], "aux_index": [ 30, null]},
22 {"year": 2024, "doy": 248, "initial_time": [3,55], "final_time": [4,0], "aux_index": [ 26, null]},
22 {"year": 2024, "doy": 248, "initial_time": [3,55], "final_time": [4,0], "aux_index": [ 26, null]},
23 {"year": 2024, "doy": 247, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 18, 24]},
23 {"year": 2024, "doy": 247, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 18, 24]},
24 {"year": 2024, "doy": 247, "initial_time": [5,5], "final_time": [5,5], "aux_index": [ 21, 26]},
24 {"year": 2024, "doy": 247, "initial_time": [5,5], "final_time": [5,5], "aux_index": [ 21, 26]},
25 {"year": 2024, "doy": 247, "initial_time": [5,15], "final_time": [5,15], "aux_index": [ 19, 21]},
25 {"year": 2024, "doy": 247, "initial_time": [5,15], "final_time": [5,15], "aux_index": [ 19, 21]},
26 {"year": 2024, "doy": 247, "initial_time": [5,20], "final_time": [5,20], "aux_index": [ 21, 23]},
26 {"year": 2024, "doy": 247, "initial_time": [5,20], "final_time": [5,20], "aux_index": [ 21, 23]},
27 {"year": 2024, "doy": 247, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 21, 26]},
27 {"year": 2024, "doy": 247, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 21, 26]},
28 {"year": 2024, "doy": 247, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 20, 27]},
28 {"year": 2024, "doy": 247, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 20, 27]},
29 {"year": 2024, "doy": 247, "initial_time": [5,35], "final_time": [5,35], "aux_index": [ 22, 27]},
29 {"year": 2024, "doy": 247, "initial_time": [5,35], "final_time": [5,35], "aux_index": [ 22, 27]},
30 {"year": 2024, "doy": 247, "initial_time": [8,5], "final_time": [8,10], "aux_index": [ null, null]},
30 {"year": 2024, "doy": 247, "initial_time": [8,5], "final_time": [8,10], "aux_index": [ null, null]},
31 {"year": 2024, "doy": 247, "initial_time": [15,30], "final_time": [15,30], "aux_index": [ null, null]},
31 {"year": 2024, "doy": 247, "initial_time": [15,30], "final_time": [15,30], "aux_index": [ null, null]},
32
32
33
33
34 {"year": 2024, "doy": 248, "initial_time": [5,20], "final_time": [5,35], "aux_index": [ 20, null]},
34 {"year": 2024, "doy": 248, "initial_time": [5,20], "final_time": [5,35], "aux_index": [ 20, null]},
35 {"year": 2024, "doy": 248, "initial_time": [5,40], "final_time": [5,55], "aux_index": [ 23, null]},
35 {"year": 2024, "doy": 248, "initial_time": [5,40], "final_time": [5,55], "aux_index": [ 23, null]},
36 {"year": 2024, "doy": 248, "initial_time": [5,0], "final_time": [23,59], "aux_index": [ null, 11]},
36 {"year": 2024, "doy": 248, "initial_time": [5,0], "final_time": [23,59], "aux_index": [ null, 11]},
37 {"year": 2024, "doy": 249, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 12]},
37 {"year": 2024, "doy": 249, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 12]},
38 {"year": 2024, "doy": 248, "initial_time": [5,0], "final_time": [9,0], "aux_index": [ null, 13]},
38 {"year": 2024, "doy": 248, "initial_time": [5,0], "final_time": [9,0], "aux_index": [ null, 13]},
39 {"year": 2024, "doy": 249, "initial_time": [2,0], "final_time": [2,20], "aux_index": [ null, 17]},
39 {"year": 2024, "doy": 249, "initial_time": [2,0], "final_time": [2,20], "aux_index": [ null, 17]},
40 {"year": 2024, "doy": 249, "initial_time": [2,55], "final_time": [2,55], "aux_index": [ 27, null]},
40 {"year": 2024, "doy": 249, "initial_time": [2,55], "final_time": [2,55], "aux_index": [ 27, null]},
41 {"year": 2024, "doy": 249, "initial_time": [3,0], "final_time": [3,5], "aux_index": [ 25, null]},
41 {"year": 2024, "doy": 249, "initial_time": [3,0], "final_time": [3,5], "aux_index": [ 25, null]},
42 {"year": 2024, "doy": 249, "initial_time": [4,5], "final_time": [4,5], "aux_index": [ 23, null]},
42 {"year": 2024, "doy": 249, "initial_time": [4,5], "final_time": [4,5], "aux_index": [ 23, null]},
43 {"year": 2024, "doy": 249, "initial_time": [4,10], "final_time": [4,10], "aux_index": [ 26, null]},
43 {"year": 2024, "doy": 249, "initial_time": [4,10], "final_time": [4,10], "aux_index": [ 26, null]},
44 {"year": 2024, "doy": 249, "initial_time": [4,15], "final_time": [4,15], "aux_index": [ 30, null]},
44 {"year": 2024, "doy": 249, "initial_time": [4,15], "final_time": [4,15], "aux_index": [ 30, null]},
45 {"year": 2024, "doy": 249, "initial_time": [0,30], "final_time": [0,40], "aux_index": [ null, null]},
45 {"year": 2024, "doy": 249, "initial_time": [0,30], "final_time": [0,40], "aux_index": [ null, null]},
46
46
47 {"year": 2024, "doy": 249, "initial_time": [5,20], "final_time": [5,20], "aux_index": [ 22, null]},
47 {"year": 2024, "doy": 249, "initial_time": [5,20], "final_time": [5,20], "aux_index": [ 22, null]},
48 {"year": 2024, "doy": 249, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 23, null]},
48 {"year": 2024, "doy": 249, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 23, null]},
49 {"year": 2024, "doy": 249, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 18, 37]},
49 {"year": 2024, "doy": 249, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 18, 37]},
50 {"year": 2024, "doy": 249, "initial_time": [5,35], "final_time": [5,40], "aux_index": [ 18, 34]},
50 {"year": 2024, "doy": 249, "initial_time": [5,35], "final_time": [5,40], "aux_index": [ 18, 34]},
51 {"year": 2024, "doy": 249, "initial_time": [5,45], "final_time": [5,45], "aux_index": [ 20, 30]},
51 {"year": 2024, "doy": 249, "initial_time": [5,45], "final_time": [5,45], "aux_index": [ 20, 30]},
52 {"year": 2024, "doy": 249, "initial_time": [6,5], "final_time": [6,5], "aux_index": [ 24, null]},
52 {"year": 2024, "doy": 249, "initial_time": [6,5], "final_time": [6,5], "aux_index": [ 24, null]},
53 {"year": 2024, "doy": 249, "initial_time": [10,5], "final_time": [10,5], "aux_index": [ null, null]},
53 {"year": 2024, "doy": 249, "initial_time": [10,5], "final_time": [10,5], "aux_index": [ null, null]},
54 {"year": 2024, "doy": 249, "initial_time": [6,10], "final_time": [6,10], "aux_index": [ 29, null]},
54 {"year": 2024, "doy": 249, "initial_time": [6,10], "final_time": [6,10], "aux_index": [ 29, null]},
55 {"year": 2024, "doy": 249, "initial_time": [6,45], "final_time": [6,45], "aux_index": [ 21, null]},
55 {"year": 2024, "doy": 249, "initial_time": [6,45], "final_time": [6,45], "aux_index": [ 21, null]},
56 {"year": 2024, "doy": 249, "initial_time": [5,0], "final_time": [20,0], "aux_index": [ null, 11]},
56 {"year": 2024, "doy": 249, "initial_time": [5,0], "final_time": [20,0], "aux_index": [ null, 11]},
57 {"year": 2024, "doy": 249, "initial_time": [23,10], "final_time": [23,59], "aux_index": [ null, 11]},
57 {"year": 2024, "doy": 249, "initial_time": [23,10], "final_time": [23,59], "aux_index": [ null, 11]},
58 {"year": 2024, "doy": 250, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 13]},
58 {"year": 2024, "doy": 250, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 13]},
59 {"year": 2024, "doy": 249, "initial_time": [5,0], "final_time": [8,50], "aux_index": [ null, 12]},
59 {"year": 2024, "doy": 249, "initial_time": [5,0], "final_time": [8,50], "aux_index": [ null, 12]},
60 {"year": 2024, "doy": 250, "initial_time": [0,0], "final_time": [3,35], "aux_index": [ null, 23]},
60 {"year": 2024, "doy": 250, "initial_time": [0,0], "final_time": [3,35], "aux_index": [ null, 23]},
61 {"year": 2024, "doy": 250, "initial_time": [0,0], "final_time": [0,55], "aux_index": [ null, null]},
61 {"year": 2024, "doy": 250, "initial_time": [0,0], "final_time": [0,55], "aux_index": [ null, null]},
62 {"year": 2024, "doy": 249, "initial_time": [7,15], "final_time": [7,15], "aux_index": [ null, 14]},
62 {"year": 2024, "doy": 249, "initial_time": [7,15], "final_time": [7,15], "aux_index": [ null, 14]},
63 {"year": 2024, "doy": 250, "initial_time": [3,15], "final_time": [3,35], "aux_index": [ 46, null]},
63 {"year": 2024, "doy": 250, "initial_time": [3,15], "final_time": [3,35], "aux_index": [ 46, null]},
64 {"year": 2024, "doy": 250, "initial_time": [3,25], "final_time": [3,25], "aux_index": [ null, 30]},
64 {"year": 2024, "doy": 250, "initial_time": [3,25], "final_time": [3,25], "aux_index": [ null, 30]},
65 {"year": 2024, "doy": 250, "initial_time": [3,30], "final_time": [3,30], "aux_index": [ null, 32]},
65 {"year": 2024, "doy": 250, "initial_time": [3,30], "final_time": [3,30], "aux_index": [ null, 32]},
66 {"year": 2024, "doy": 250, "initial_time": [3,35], "final_time": [3,35], "aux_index": [ null, 34]},
66 {"year": 2024, "doy": 250, "initial_time": [3,35], "final_time": [3,35], "aux_index": [ null, 34]},
67 {"year": 2024, "doy": 250, "initial_time": [3,40], "final_time": [3,40], "aux_index": [ 21, 38]},
67 {"year": 2024, "doy": 250, "initial_time": [3,40], "final_time": [3,40], "aux_index": [ 21, 38]},
68 {"year": 2024, "doy": 250, "initial_time": [3,45], "final_time": [3,45], "aux_index": [ 22, 37]},
68 {"year": 2024, "doy": 250, "initial_time": [3,45], "final_time": [3,45], "aux_index": [ 22, 37]},
69 {"year": 2024, "doy": 250, "initial_time": [1,35], "final_time": [1,35], "aux_index": [ 36, null]},
69 {"year": 2024, "doy": 250, "initial_time": [1,35], "final_time": [1,35], "aux_index": [ 36, null]},
70 {"year": 2024, "doy": 250, "initial_time": [1,40], "final_time": [1,40], "aux_index": [ 32, null]},
70 {"year": 2024, "doy": 250, "initial_time": [1,40], "final_time": [1,40], "aux_index": [ 32, null]},
71 {"year": 2024, "doy": 250, "initial_time": [1,45], "final_time": [1,45], "aux_index": [ 31, null]},
71 {"year": 2024, "doy": 250, "initial_time": [1,45], "final_time": [1,45], "aux_index": [ 31, null]},
72 {"year": 2024, "doy": 250, "initial_time": [2,30], "final_time": [2,30], "aux_index": [ 30, null]},
72 {"year": 2024, "doy": 250, "initial_time": [2,30], "final_time": [2,30], "aux_index": [ 30, null]},
73 {"year": 2024, "doy": 250, "initial_time": [2,35], "final_time": [2,35], "aux_index": [ 33, null]},
73 {"year": 2024, "doy": 250, "initial_time": [2,35], "final_time": [2,35], "aux_index": [ 33, null]},
74 {"year": 2024, "doy": 250, "initial_time": [2,40], "final_time": [2,40], "aux_index": [ 27, null]},
74 {"year": 2024, "doy": 250, "initial_time": [2,40], "final_time": [2,40], "aux_index": [ 27, null]},
75
75
76 {"year": 2024, "doy": 251, "initial_time": [3,0], "final_time": [3,45], "aux_index": [ null, null]},
76 {"year": 2024, "doy": 251, "initial_time": [3,0], "final_time": [3,45], "aux_index": [ null, null]},
77 {"year": 2024, "doy": 251, "initial_time": [0,30], "final_time": [0,45], "aux_index": [ null, null]},
77 {"year": 2024, "doy": 251, "initial_time": [0,30], "final_time": [0,45], "aux_index": [ null, null]},
78
78
79 {"year": 2024, "doy": 250, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 20, 41]},
79 {"year": 2024, "doy": 250, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 20, 41]},
80 {"year": 2024, "doy": 250, "initial_time": [5,5], "final_time": [5,10], "aux_index": [ 24, 37]},
80 {"year": 2024, "doy": 250, "initial_time": [5,5], "final_time": [5,10], "aux_index": [ 24, 37]},
81 {"year": 2024, "doy": 250, "initial_time": [5,20], "final_time": [5,25], "aux_index": [ 23, 39]},
81 {"year": 2024, "doy": 250, "initial_time": [5,20], "final_time": [5,25], "aux_index": [ 23, 39]},
82 {"year": 2024, "doy": 250, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 19, null]},
82 {"year": 2024, "doy": 250, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 19, null]},
83 {"year": 2024, "doy": 250, "initial_time": [6,5], "final_time": [6,5], "aux_index": [ 24, null]},
83 {"year": 2024, "doy": 250, "initial_time": [6,5], "final_time": [6,5], "aux_index": [ 24, null]},
84 {"year": 2024, "doy": 250, "initial_time": [6,10], "final_time": [6,10], "aux_index": [ 20, 41]},
84 {"year": 2024, "doy": 250, "initial_time": [6,10], "final_time": [6,10], "aux_index": [ 20, 41]},
85 {"year": 2024, "doy": 250, "initial_time": [6,15], "final_time": [6,15], "aux_index": [ 20, 39]},
85 {"year": 2024, "doy": 250, "initial_time": [6,15], "final_time": [6,15], "aux_index": [ 20, 39]},
86 {"year": 2024, "doy": 250, "initial_time": [6,20], "final_time": [6,20], "aux_index": [ 20, 37]},
86 {"year": 2024, "doy": 250, "initial_time": [6,20], "final_time": [6,20], "aux_index": [ 20, 37]},
87 {"year": 2024, "doy": 250, "initial_time": [6,25], "final_time": [6,25], "aux_index": [ 21, 29]},
87 {"year": 2024, "doy": 250, "initial_time": [6,25], "final_time": [6,25], "aux_index": [ 21, 29]},
88 {"year": 2024, "doy": 250, "initial_time": [6,30], "final_time": [6,30], "aux_index": [ 22, 29]},
88 {"year": 2024, "doy": 250, "initial_time": [6,30], "final_time": [6,30], "aux_index": [ 22, 29]},
89 {"year": 2024, "doy": 250, "initial_time": [6,45], "final_time": [6,45], "aux_index": [ 20, null]},
89 {"year": 2024, "doy": 250, "initial_time": [6,45], "final_time": [6,45], "aux_index": [ 20, null]},
90 {"year": 2024, "doy": 250, "initial_time": [6,50], "final_time": [6,50], "aux_index": [ 19, 38]},
90 {"year": 2024, "doy": 250, "initial_time": [6,50], "final_time": [6,50], "aux_index": [ 19, 38]},
91 {"year": 2024, "doy": 250, "initial_time": [6,55], "final_time": [6,55], "aux_index": [ 23, 42]},
91 {"year": 2024, "doy": 250, "initial_time": [6,55], "final_time": [6,55], "aux_index": [ 23, 42]},
92 {"year": 2024, "doy": 250, "initial_time": [7,0], "final_time": [7,0], "aux_index": [ 20, null]},
92 {"year": 2024, "doy": 250, "initial_time": [7,0], "final_time": [7,0], "aux_index": [ 20, null]},
93 {"year": 2024, "doy": 250, "initial_time": [7,5], "final_time": [7,5], "aux_index": [ 23, 40]},
93 {"year": 2024, "doy": 250, "initial_time": [7,5], "final_time": [7,5], "aux_index": [ 23, 40]},
94 {"year": 2024, "doy": 250, "initial_time": [7,10], "final_time": [7,10], "aux_index": [ 23, 42]},
94 {"year": 2024, "doy": 250, "initial_time": [7,10], "final_time": [7,10], "aux_index": [ 23, 42]},
95 {"year": 2024, "doy": 250, "initial_time": [7,15], "final_time": [7,15], "aux_index": [ 25, 37]},
95 {"year": 2024, "doy": 250, "initial_time": [7,15], "final_time": [7,15], "aux_index": [ 25, 37]},
96 {"year": 2024, "doy": 250, "initial_time": [7,30], "final_time": [7,30], "aux_index": [ 25, 40]},
96 {"year": 2024, "doy": 250, "initial_time": [7,30], "final_time": [7,30], "aux_index": [ 25, 40]},
97 {"year": 2024, "doy": 250, "initial_time": [7,35], "final_time": [7,35], "aux_index": [ 25, 39]},
97 {"year": 2024, "doy": 250, "initial_time": [7,35], "final_time": [7,35], "aux_index": [ 25, 39]},
98 {"year": 2024, "doy": 250, "initial_time": [7,40], "final_time": [7,40], "aux_index": [ 23, 41]},
98 {"year": 2024, "doy": 250, "initial_time": [7,40], "final_time": [7,40], "aux_index": [ 23, 41]},
99 {"year": 2024, "doy": 250, "initial_time": [7,45], "final_time": [7,45], "aux_index": [ 27, 38]},
99 {"year": 2024, "doy": 250, "initial_time": [7,45], "final_time": [7,45], "aux_index": [ 27, 38]},
100 {"year": 2024, "doy": 250, "initial_time": [23,10], "final_time": [23,59], "aux_index": [ null, 12]},
100 {"year": 2024, "doy": 250, "initial_time": [23,10], "final_time": [23,59], "aux_index": [ null, 12]},
101 {"year": 2024, "doy": 251, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 13]},
101 {"year": 2024, "doy": 251, "initial_time": [0,0], "final_time": [4,59], "aux_index": [ null, 13]},
102 {"year": 2024, "doy": 250, "initial_time": [5,0], "final_time": [8,10], "aux_index": [ null, 12]},
102 {"year": 2024, "doy": 250, "initial_time": [5,0], "final_time": [8,10], "aux_index": [ null, 12]},
103 {"year": 2024, "doy": 250, "initial_time": [9,10], "final_time": [10,50], "aux_index": [ null, 12]},
103 {"year": 2024, "doy": 250, "initial_time": [9,10], "final_time": [10,50], "aux_index": [ null, 12]},
104 {"year": 2024, "doy": 251, "initial_time": [0,0], "final_time": [3,30], "aux_index": [ null, 27]},
104 {"year": 2024, "doy": 251, "initial_time": [0,0], "final_time": [3,30], "aux_index": [ null, 27]},
105 {"year": 2024, "doy": 250, "initial_time": [19,30], "final_time": [19,30], "aux_index": [ 19, 26]},
105 {"year": 2024, "doy": 250, "initial_time": [19,30], "final_time": [19,30], "aux_index": [ 19, 26]},
106 {"year": 2024, "doy": 250, "initial_time": [10,50], "final_time": [13,20], "aux_index": [ null, 12]},
106 {"year": 2024, "doy": 250, "initial_time": [10,50], "final_time": [13,20], "aux_index": [ null, 12]},
107
107
108
108
109 {"year": 2024, "doy": 251, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 23, 40]},
109 {"year": 2024, "doy": 251, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 23, 40]},
110 {"year": 2024, "doy": 251, "initial_time": [5,5], "final_time": [5,10], "aux_index": [ 25, 40]},
110 {"year": 2024, "doy": 251, "initial_time": [5,5], "final_time": [5,10], "aux_index": [ 25, 40]},
111 {"year": 2024, "doy": 251, "initial_time": [17,30], "final_time": [20,30], "aux_index": [ 56, null]},
111 {"year": 2024, "doy": 251, "initial_time": [17,30], "final_time": [20,30], "aux_index": [ 56, null]},
112 {"year": 2024, "doy": 251, "initial_time": [5,0], "final_time": [8,10], "aux_index": [ null, 12]},
112 {"year": 2024, "doy": 251, "initial_time": [5,0], "final_time": [8,10], "aux_index": [ null, 12]},
113 {"year": 2024, "doy": 251, "initial_time": [5,0], "final_time": [20,0], "aux_index": [ null, 11]},
113 {"year": 2024, "doy": 251, "initial_time": [5,0], "final_time": [20,0], "aux_index": [ null, 11]},
114 {"year": 2024, "doy": 251, "initial_time": [19,50], "final_time": [19,50], "aux_index": [ null, null]},
114 {"year": 2024, "doy": 251, "initial_time": [19,50], "final_time": [19,50], "aux_index": [ null, null]},
115 {"year": 2024, "doy": 252, "initial_time": [0,30], "final_time": [0,55], "aux_index": [ null, null]},
115 {"year": 2024, "doy": 252, "initial_time": [0,30], "final_time": [0,55], "aux_index": [ null, null]},
116 {"year": 2024, "doy": 252, "initial_time": [0,55], "final_time": [1,0], "aux_index": [ null, 40]},
116 {"year": 2024, "doy": 252, "initial_time": [0,55], "final_time": [1,0], "aux_index": [ null, 40]},
117 {"year": 2024, "doy": 252, "initial_time": [1,0], "final_time": [1,15], "aux_index": [ null, 34]},
117 {"year": 2024, "doy": 252, "initial_time": [1,0], "final_time": [1,15], "aux_index": [ null, 34]},
118 {"year": 2024, "doy": 252, "initial_time": [0,30], "final_time": [0,55], "aux_index": [ null, null]},
118 {"year": 2024, "doy": 252, "initial_time": [0,30], "final_time": [0,55], "aux_index": [ null, null]},
119 {"year": 2024, "doy": 252, "initial_time": [1,35], "final_time": [1,55], "aux_index": [ null, null]},
119 {"year": 2024, "doy": 252, "initial_time": [1,35], "final_time": [1,55], "aux_index": [ null, null]},
120 {"year": 2024, "doy": 251, "initial_time": [23,10], "final_time": [23,59], "aux_index": [ null, 20]},
120 {"year": 2024, "doy": 251, "initial_time": [23,10], "final_time": [23,59], "aux_index": [ null, 20]},
121 {"year": 2024, "doy": 252, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 12]},
121 {"year": 2024, "doy": 252, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 12]},
122 {"year": 2024, "doy": 252, "initial_time": [0,0], "final_time": [1,50], "aux_index": [ null, 31]},
122 {"year": 2024, "doy": 252, "initial_time": [0,0], "final_time": [1,50], "aux_index": [ null, 31]},
123 {"year": 2024, "doy": 252, "initial_time": [3,20], "final_time": [3,25], "aux_index": [ 22, null]},
123 {"year": 2024, "doy": 252, "initial_time": [3,20], "final_time": [3,25], "aux_index": [ 22, null]},
124 {"year": 2024, "doy": 252, "initial_time": [3,30], "final_time": [3,35], "aux_index": [ 23, null]},
124 {"year": 2024, "doy": 252, "initial_time": [3,30], "final_time": [3,35], "aux_index": [ 23, null]},
125 {"year": 2024, "doy": 252, "initial_time": [3,50], "final_time": [3,50], "aux_index": [ 22, null]},
125 {"year": 2024, "doy": 252, "initial_time": [3,50], "final_time": [3,50], "aux_index": [ 22, null]},
126 {"year": 2024, "doy": 252, "initial_time": [3,55], "final_time": [4,5], "aux_index": [ 21, null]},
126 {"year": 2024, "doy": 252, "initial_time": [3,55], "final_time": [4,5], "aux_index": [ 21, null]},
127 {"year": 2024, "doy": 252, "initial_time": [4,10], "final_time": [4,10], "aux_index": [ 21, 36]},
127 {"year": 2024, "doy": 252, "initial_time": [4,10], "final_time": [4,10], "aux_index": [ 21, 36]},
128
128
129 {"year": 2024, "doy": 252, "initial_time": [5,0], "final_time": [20,0], "aux_index": [ null, 12]},
129 {"year": 2024, "doy": 252, "initial_time": [5,0], "final_time": [20,0], "aux_index": [ null, 12]},
130 {"year": 2024, "doy": 252, "initial_time": [13,0], "final_time": [13,0], "aux_index": [ null, null]},
130 {"year": 2024, "doy": 252, "initial_time": [13,0], "final_time": [13,0], "aux_index": [ null, null]},
131 {"year": 2024, "doy": 252, "initial_time": [5,15], "final_time": [5,20], "aux_index": [ 23, null]},
131 {"year": 2024, "doy": 252, "initial_time": [5,15], "final_time": [5,20], "aux_index": [ 23, null]},
132 {"year": 2024, "doy": 252, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 27, 36]},
132 {"year": 2024, "doy": 252, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 27, 36]},
133 {"year": 2024, "doy": 252, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 27, null]},
133 {"year": 2024, "doy": 252, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 27, null]},
134 {"year": 2024, "doy": 252, "initial_time": [5,35], "final_time": [5,35], "aux_index": [ 31, null]},
134 {"year": 2024, "doy": 252, "initial_time": [5,35], "final_time": [5,35], "aux_index": [ 31, null]},
135 {"year": 2024, "doy": 252, "initial_time": [5,20], "final_time": [5,40], "aux_index": [ 33, null]},
135 {"year": 2024, "doy": 252, "initial_time": [5,20], "final_time": [5,40], "aux_index": [ 33, null]},
136 {"year": 2024, "doy": 252, "initial_time": [7,5], "final_time": [7,5], "aux_index": [ 21, null]},
136 {"year": 2024, "doy": 252, "initial_time": [7,5], "final_time": [7,5], "aux_index": [ 21, null]},
137 {"year": 2024, "doy": 252, "initial_time": [7,10], "final_time": [7,10], "aux_index": [ 23, null]},
137 {"year": 2024, "doy": 252, "initial_time": [7,10], "final_time": [7,10], "aux_index": [ 23, null]},
138
138
139
139
140
140
141 {"year": 2025, "doy": 21, "initial_time": [19,45], "final_time": [19,50], "aux_index": [ null, null]},
141 {"year": 2025, "doy": 21, "initial_time": [19,45], "final_time": [19,50], "aux_index": [ null, null]},
142 {"year": 2025, "doy": 22, "initial_time": [0,50], "final_time": [3,30], "aux_index": [ null, 30]},
142 {"year": 2025, "doy": 22, "initial_time": [0,50], "final_time": [3,30], "aux_index": [ null, 30]},
143 {"year": 2025, "doy": 22, "initial_time": [1,50], "final_time": [1,50], "aux_index": [ null, null]},
143 {"year": 2025, "doy": 22, "initial_time": [1,50], "final_time": [1,50], "aux_index": [ null, null]},
144 {"year": 2025, "doy": 22, "initial_time": [2,15], "final_time": [2,25], "aux_index": [ null, 38]},
144 {"year": 2025, "doy": 22, "initial_time": [2,15], "final_time": [2,25], "aux_index": [ null, 38]},
145 {"year": 2025, "doy": 22, "initial_time": [2,25], "final_time": [2,35], "aux_index": [ null, null]},
145 {"year": 2025, "doy": 22, "initial_time": [2,25], "final_time": [2,35], "aux_index": [ null, null]},
146 {"year": 2025, "doy": 22, "initial_time": [2,40], "final_time": [2,50], "aux_index": [ null, 40]},
146 {"year": 2025, "doy": 22, "initial_time": [2,40], "final_time": [2,50], "aux_index": [ null, 40]},
147 {"year": 2025, "doy": 22, "initial_time": [2,40], "final_time": [2,40], "aux_index": [ 44, null]},
147 {"year": 2025, "doy": 22, "initial_time": [2,40], "final_time": [2,40], "aux_index": [ 44, null]},
148 {"year": 2025, "doy": 22, "initial_time": [2,45], "final_time": [2,45], "aux_index": [ 50, null]},
148 {"year": 2025, "doy": 22, "initial_time": [2,45], "final_time": [2,45], "aux_index": [ 50, null]},
149 {"year": 2025, "doy": 22, "initial_time": [3,0], "final_time": [3,15], "aux_index": [ null, 33]},
149 {"year": 2025, "doy": 22, "initial_time": [3,0], "final_time": [3,15], "aux_index": [ null, 33]},
150 {"year": 2025, "doy": 22, "initial_time": [3,30], "final_time": [4,15], "aux_index": [ null, 28]},
150 {"year": 2025, "doy": 22, "initial_time": [3,30], "final_time": [4,15], "aux_index": [ null, 28]},
151 {"year": 2025, "doy": 22, "initial_time": [4,15], "final_time": [4,25], "aux_index": [ null, 24]},
151 {"year": 2025, "doy": 22, "initial_time": [4,15], "final_time": [4,25], "aux_index": [ null, 24]},
152 {"year": 2025, "doy": 22, "initial_time": [3,50], "final_time": [4,15], "aux_index": [ null, 15]},
152 {"year": 2025, "doy": 22, "initial_time": [3,50], "final_time": [4,15], "aux_index": [ null, 15]},
153 {"year": 2025, "doy": 22, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
153 {"year": 2025, "doy": 22, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
154
154
155 {"year": 2025, "doy": 22, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
155 {"year": 2025, "doy": 22, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
156 {"year": 2025, "doy": 22, "initial_time": [14,20], "final_time": [14,20], "aux_index": [ null, null]},
156 {"year": 2025, "doy": 22, "initial_time": [14,20], "final_time": [14,20], "aux_index": [ null, null]},
157 {"year": 2025, "doy": 23, "initial_time": [0,10], "final_time": [0,10], "aux_index": [ null, null]},
157 {"year": 2025, "doy": 23, "initial_time": [0,10], "final_time": [0,10], "aux_index": [ null, null]},
158 {"year": 2025, "doy": 23, "initial_time": [0,55], "final_time": [3,30], "aux_index": [ null, 26]},
158 {"year": 2025, "doy": 23, "initial_time": [0,55], "final_time": [3,30], "aux_index": [ null, 26]},
159 {"year": 2025, "doy": 23, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
159 {"year": 2025, "doy": 23, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
160 {"year": 2025, "doy": 23, "initial_time": [2,25], "final_time": [2,25], "aux_index": [ null, 34]},
160 {"year": 2025, "doy": 23, "initial_time": [2,25], "final_time": [2,25], "aux_index": [ null, 34]},
161 {"year": 2025, "doy": 23, "initial_time": [2,10], "final_time": [2,10], "aux_index": [ 44, 48]},
161 {"year": 2025, "doy": 23, "initial_time": [2,10], "final_time": [2,10], "aux_index": [ 44, 48]},
162 {"year": 2025, "doy": 23, "initial_time": [0,50], "final_time": [0,50], "aux_index": [ 53, 53]},
162 {"year": 2025, "doy": 23, "initial_time": [0,50], "final_time": [0,50], "aux_index": [ 53, 53]},
163
163
164 {"year": 2025, "doy": 23, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
164 {"year": 2025, "doy": 23, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
165 {"year": 2025, "doy": 23, "initial_time": [5,0], "final_time": [8,0], "aux_index": [ null, 14]},
165 {"year": 2025, "doy": 23, "initial_time": [5,0], "final_time": [8,0], "aux_index": [ null, 14]},
166 {"year": 2025, "doy": 23, "initial_time": [12,5], "final_time": [12,5], "aux_index": [ null, null]},
166 {"year": 2025, "doy": 23, "initial_time": [12,5], "final_time": [12,5], "aux_index": [ null, null]},
167 {"year": 2025, "doy": 24, "initial_time": [1,40], "final_time": [3,15], "aux_index": [ null, null]},
167 {"year": 2025, "doy": 24, "initial_time": [1,40], "final_time": [3,15], "aux_index": [ null, null]},
168 {"year": 2025, "doy": 24, "initial_time": [3,25], "final_time": [3,30], "aux_index": [ 44, null]},
168 {"year": 2025, "doy": 24, "initial_time": [3,25], "final_time": [3,30], "aux_index": [ 44, null]},
169 {"year": 2025, "doy": 24, "initial_time": [3,20], "final_time": [3,40], "aux_index": [ null, 31]},
169 {"year": 2025, "doy": 24, "initial_time": [3,20], "final_time": [3,40], "aux_index": [ null, 31]},
170 {"year": 2025, "doy": 24, "initial_time": [3,40], "final_time": [4,55], "aux_index": [ null, 29]},
170 {"year": 2025, "doy": 24, "initial_time": [3,40], "final_time": [4,55], "aux_index": [ null, 29]},
171 {"year": 2025, "doy": 24, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
171 {"year": 2025, "doy": 24, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
172
172
173 {"year": 2025, "doy": 24, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
173 {"year": 2025, "doy": 24, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
174 {"year": 2025, "doy": 25, "initial_time": [0,0], "final_time": [4,55], "aux_index": [ null, 27]},
174 {"year": 2025, "doy": 24, "initial_time": [5,0], "final_time": [5,5], "aux_index": [ null, 34]},
175 {"year": 2025, "doy": 24, "initial_time": [5,10], "final_time": [5,10], "aux_index": [ 24, 35]},
176 {"year": 2025, "doy": 24, "initial_time": [5,15], "final_time": [5,15], "aux_index": [ 25, 33]},
177 {"year": 2025, "doy": 24, "initial_time": [5,20], "final_time": [5,20], "aux_index": [ 26, 33]},
178 {"year": 2025, "doy": 24, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 27, 32]},
179 {"year": 2025, "doy": 24, "initial_time": [5,30], "final_time": [5,30], "aux_index": [ 23, 24]},
180 {"year": 2025, "doy": 24, "initial_time": [5,35], "final_time": [5,35], "aux_index": [ 22, 27]},
181 {"year": 2025, "doy": 24, "initial_time": [5,40], "final_time": [5,55], "aux_index": [ 22, 31]},
182 {"year": 2025, "doy": 24, "initial_time": [6,0], "final_time": [6,0], "aux_index": [ 22, 33]},
183 {"year": 2025, "doy": 24, "initial_time": [6,30], "final_time": [6,30], "aux_index": [ 22, 25]},
184 {"year": 2025, "doy": 24, "initial_time": [6,35], "final_time": [6,35], "aux_index": [ 22, 32]},
185 {"year": 2025, "doy": 24, "initial_time": [6,35], "final_time": [6,40], "aux_index": [ 22, 32]},
186 {"year": 2025, "doy": 24, "initial_time": [6,45], "final_time": [6,45], "aux_index": [ 23, 32]},
187 {"year": 2025, "doy": 24, "initial_time": [6,50], "final_time": [6,50], "aux_index": [ 24, 34]},
188 {"year": 2025, "doy": 24, "initial_time": [6,55], "final_time": [6,55], "aux_index": [ 25, 32]},
189 {"year": 2025, "doy": 25, "initial_time": [0,50], "final_time": [4,55], "aux_index": [ null, 27]},
175 {"year": 2025, "doy": 25, "initial_time": [2,50], "final_time": [4,55], "aux_index": [ null, 30]},
190 {"year": 2025, "doy": 25, "initial_time": [2,50], "final_time": [4,55], "aux_index": [ null, 30]},
191 {"year": 2025, "doy": 25, "initial_time": [3,5], "final_time": [3,45], "aux_index": [ null, 33]},
176 {"year": 2025, "doy": 25, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
192 {"year": 2025, "doy": 25, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
177
193
178 {"year": 2025, "doy": 25, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
194 {"year": 2025, "doy": 25, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
179 {"year": 2025, "doy": 26, "initial_time": [2,50], "final_time": [4,5], "aux_index": [ null, null]},
195 {"year": 2025, "doy": 26, "initial_time": [2,50], "final_time": [4,5], "aux_index": [ null, null]},
180 {"year": 2025, "doy": 26, "initial_time": [2,50], "final_time": [4,5], "aux_index": [ null, null]},
196 {"year": 2025, "doy": 26, "initial_time": [2,50], "final_time": [4,5], "aux_index": [ null, null]},
181 {"year": 2025, "doy": 26, "initial_time": [0,40], "final_time": [4,20], "aux_index": [ null, 24]},
197 {"year": 2025, "doy": 26, "initial_time": [0,40], "final_time": [4,20], "aux_index": [ null, 24]},
182 {"year": 2025, "doy": 26, "initial_time": [4,30], "final_time": [4,30], "aux_index": [ null, 20]},
198 {"year": 2025, "doy": 26, "initial_time": [4,30], "final_time": [4,30], "aux_index": [ null, 20]},
183 {"year": 2025, "doy": 26, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
199 {"year": 2025, "doy": 26, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
184
200
185 {"year": 2025, "doy": 26, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
201 {"year": 2025, "doy": 26, "initial_time": [5,0], "final_time": [23,55], "aux_index": [ null, 13]},
202 {"year": 2025, "doy": 26, "initial_time": [5,20], "final_time": [5,20], "aux_index": [ null, 28]},
203 {"year": 2025, "doy": 26, "initial_time": [5,25], "final_time": [5,25], "aux_index": [ 25, 34]},
186 {"year": 2025, "doy": 26, "initial_time": [0,55], "final_time": [0,55], "aux_index": [ null, null]},
204 {"year": 2025, "doy": 26, "initial_time": [0,55], "final_time": [0,55], "aux_index": [ null, null]},
187 {"year": 2025, "doy": 26, "initial_time": [0,55], "final_time": [4,55], "aux_index": [ null, 24]},
205 {"year": 2025, "doy": 26, "initial_time": [0,55], "final_time": [4,55], "aux_index": [ null, 24]},
188 {"year": 2025, "doy": 27, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]}
206 {"year": 2025, "doy": 27, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 13]},
207
208 {"year": 2025, "doy": 41, "initial_time": [23,0], "final_time": [23,0], "aux_index": [ null, null]},
209 {"year": 2025, "doy": 42, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 14]},
210 {"year": 2025, "doy": 42, "initial_time": [4,24], "final_time": [4,24], "aux_index": [ 35, 38]},
211 {"year": 2025, "doy": 42, "initial_time": [1,30], "final_time": [5,0], "aux_index": [ null, 26]},
212 {"year": 2025, "doy": 42, "initial_time": [2,12], "final_time": [4,0], "aux_index": [ null, null]},
213 {"year": 2025, "doy": 42, "initial_time": [1,24], "final_time": [1,24], "aux_index": [ 39, 40]},
214 {"year": 2025, "doy": 42, "initial_time": [1,18], "final_time": [1,18], "aux_index": [ 48, 50]},
215
216 {"year": 2025, "doy": 42, "initial_time": [5,0], "final_time": [12,0], "aux_index": [ null, 7]},
217 {"year": 2025, "doy": 42, "initial_time": [5,0], "final_time": [7,30], "aux_index": [ null, 13]},
218 {"year": 2025, "doy": 42, "initial_time": [5,0], "final_time": [11,0], "aux_index": [ null, 10]},
219 {"year": 2025, "doy": 42, "initial_time": [5,0], "final_time": [5,0], "aux_index": [ 20, 22]},
220
221 {"year": 2025, "doy": 43, "initial_time": [0,0], "final_time": [5,0], "aux_index": [ null, 19]},
222 {"year": 2025, "doy": 43, "initial_time": [2,25], "final_time": [2,38], "aux_index": [ null, 24]},
223 {"year": 2025, "doy": 43, "initial_time": [2,2], "final_time": [2,2], "aux_index": [ null, null]},
224
225 {"year": 2025, "doy": 43, "initial_time": [5,0], "final_time": [10,50], "aux_index": [ null, 12]},
226 {"year": 2025, "doy": 43, "initial_time": [5,0], "final_time": [23,0], "aux_index": [ null, 8]},
227 {"year": 2025, "doy": 44, "initial_time": [0,50], "final_time": [0,50], "aux_index": [ 47, null]},
228 {"year": 2025, "doy": 44, "initial_time": [1,0], "final_time": [1,15], "aux_index": [ 39, null]},
229 {"year": 2025, "doy": 44, "initial_time": [3,14], "final_time": [3,40], "aux_index": [ null, 30]},
230 {"year": 2025, "doy": 44, "initial_time": [3,26], "final_time": [3,26], "aux_index": [ null, 32]},
231 {"year": 2025, "doy": 44, "initial_time": [0,14], "final_time": [3,40], "aux_index": [ null, 22]},
232 {"year": 2025, "doy": 44, "initial_time": [0,40], "final_time": [3,40], "aux_index": [ null, 25]},
233 {"year": 2025, "doy": 44, "initial_time": [4,0], "final_time": [5,0], "aux_index": [ null, null]},
234
235 {"year": 2025, "doy": 44, "initial_time": [5,50], "final_time": [5,50], "aux_index": [ null, null]},
236 {"year": 2025, "doy": 44, "initial_time": [7,50], "final_time": [8,38], "aux_index": [ null, null]},
237 {"year": 2025, "doy": 44, "initial_time": [5,0], "final_time": [9,14], "aux_index": [ null, 14]}
238
189
239
190 ]}
240 ]}
191
241
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
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
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