##// END OF EJS Templates
test 2
joabAM -
r1751:2d2f96339643
parent child
Show More
@@ -1,1163 +1,1167
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,ProcessingHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader,ProcessingHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22 SPEED_OF_LIGHT = 3e8
22 SPEED_OF_LIGHT = 3e8
23
23
24
24
25 def getNumpyDtype(dataTypeCode):
25 def getNumpyDtype(dataTypeCode):
26
26
27 if dataTypeCode == 0:
27 if dataTypeCode == 0:
28 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
29 elif dataTypeCode == 1:
29 elif dataTypeCode == 1:
30 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
31 elif dataTypeCode == 2:
31 elif dataTypeCode == 2:
32 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
33 elif dataTypeCode == 3:
33 elif dataTypeCode == 3:
34 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
35 elif dataTypeCode == 4:
35 elif dataTypeCode == 4:
36 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
37 elif dataTypeCode == 5:
37 elif dataTypeCode == 5:
38 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
39 else:
39 else:
40 raise ValueError('dataTypeCode was not defined')
40 raise ValueError('dataTypeCode was not defined')
41
41
42 return numpyDtype
42 return numpyDtype
43
43
44
44
45 def getDataTypeCode(numpyDtype):
45 def getDataTypeCode(numpyDtype):
46
46
47 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
48 datatype = 0
48 datatype = 0
49 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
50 datatype = 1
50 datatype = 1
51 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
52 datatype = 2
52 datatype = 2
53 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
54 datatype = 3
54 datatype = 3
55 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
56 datatype = 4
56 datatype = 4
57 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
58 datatype = 5
58 datatype = 5
59 else:
59 else:
60 datatype = None
60 datatype = None
61
61
62 return datatype
62 return datatype
63
63
64
64
65 def hildebrand_sekhon(data, navg):
65 def hildebrand_sekhon(data, navg):
66 """
66 """
67 This method is for the objective determination of the noise level in Doppler spectra. This
67 This method is for the objective determination of the noise level in Doppler spectra. This
68 implementation technique is based on the fact that the standard deviation of the spectral
68 implementation technique is based on the fact that the standard deviation of the spectral
69 densities is equal to the mean spectral density for white Gaussian noise
69 densities is equal to the mean spectral density for white Gaussian noise
70
70
71 Inputs:
71 Inputs:
72 Data : heights
72 Data : heights
73 navg : numbers of averages
73 navg : numbers of averages
74
74
75 Return:
75 Return:
76 mean : noise's level
76 mean : noise's level
77 """
77 """
78
78
79 sortdata = numpy.sort(data, axis=None)
79 sortdata = numpy.sort(data, axis=None)
80 '''
80 '''
81 lenOfData = len(sortdata)
81 lenOfData = len(sortdata)
82 nums_min = lenOfData*0.2
82 nums_min = lenOfData*0.2
83
83
84 if nums_min <= 5:
84 if nums_min <= 5:
85
85
86 nums_min = 5
86 nums_min = 5
87
87
88 sump = 0.
88 sump = 0.
89 sumq = 0.
89 sumq = 0.
90
90
91 j = 0
91 j = 0
92 cont = 1
92 cont = 1
93
93
94 while((cont == 1)and(j < lenOfData)):
94 while((cont == 1)and(j < lenOfData)):
95
95
96 sump += sortdata[j]
96 sump += sortdata[j]
97 sumq += sortdata[j]**2
97 sumq += sortdata[j]**2
98
98
99 if j > nums_min:
99 if j > nums_min:
100 rtest = float(j)/(j-1) + 1.0/navg
100 rtest = float(j)/(j-1) + 1.0/navg
101 if ((sumq*j) > (rtest*sump**2)):
101 if ((sumq*j) > (rtest*sump**2)):
102 j = j - 1
102 j = j - 1
103 sump = sump - sortdata[j]
103 sump = sump - sortdata[j]
104 sumq = sumq - sortdata[j]**2
104 sumq = sumq - sortdata[j]**2
105 cont = 0
105 cont = 0
106
106
107 j += 1
107 j += 1
108
108
109 lnoise = sump / j
109 lnoise = sump / j
110 '''
110 '''
111 return _noise.hildebrand_sekhon(sortdata, navg)
111 return _noise.hildebrand_sekhon(sortdata, navg)
112
112
113
113
114 class Beam:
114 class Beam:
115
115
116 def __init__(self):
116 def __init__(self):
117 self.codeList = []
117 self.codeList = []
118 self.azimuthList = []
118 self.azimuthList = []
119 self.zenithList = []
119 self.zenithList = []
120
120
121
121
122 class GenericData(object):
122 class GenericData(object):
123
123
124 flagNoData = True
124 flagNoData = True
125
125
126 def copy(self, inputObj=None):
126 def copy(self, inputObj=None):
127
127
128 if inputObj == None:
128 if inputObj == None:
129 return copy.deepcopy(self)
129 return copy.deepcopy(self)
130
130
131 for key in list(inputObj.__dict__.keys()):
131 for key in list(inputObj.__dict__.keys()):
132
132
133 attribute = inputObj.__dict__[key]
133 attribute = inputObj.__dict__[key]
134
134
135 # If this attribute is a tuple or list
135 # If this attribute is a tuple or list
136 if type(inputObj.__dict__[key]) in (tuple, list):
136 if type(inputObj.__dict__[key]) in (tuple, list):
137 self.__dict__[key] = attribute[:]
137 self.__dict__[key] = attribute[:]
138 continue
138 continue
139
139
140 # If this attribute is another object or instance
140 # If this attribute is another object or instance
141 if hasattr(attribute, '__dict__'):
141 if hasattr(attribute, '__dict__'):
142 self.__dict__[key] = attribute.copy()
142 self.__dict__[key] = attribute.copy()
143 continue
143 continue
144
144
145 self.__dict__[key] = inputObj.__dict__[key]
145 self.__dict__[key] = inputObj.__dict__[key]
146
146
147 def deepcopy(self):
147 def deepcopy(self):
148
148
149 return copy.deepcopy(self)
149 return copy.deepcopy(self)
150
150
151 def isEmpty(self):
151 def isEmpty(self):
152
152
153 return self.flagNoData
153 return self.flagNoData
154
154
155 def isReady(self):
155 def isReady(self):
156
156
157 return not self.flagNoData
157 return not self.flagNoData
158
158
159
159
160 class JROData(GenericData):
160 class JROData(GenericData):
161
161
162 systemHeaderObj = SystemHeader()
162 systemHeaderObj = SystemHeader()
163 radarControllerHeaderObj = RadarControllerHeader()
163 radarControllerHeaderObj = RadarControllerHeader()
164 type = None
164 type = None
165 datatype = None # dtype but in string
165 datatype = None # dtype but in string
166 nProfiles = None
166 nProfiles = None
167 heightList = None
167 heightList = None
168 channelList = None
168 channelList = None
169 flagDiscontinuousBlock = False
169 flagDiscontinuousBlock = False
170 useLocalTime = False
170 useLocalTime = False
171 utctime = None
171 utctime = None
172 timeZone = None
172 timeZone = None
173 dstFlag = None
173 dstFlag = None
174 errorCount = None
174 errorCount = None
175 blocksize = None
175 blocksize = None
176 flagDecodeData = False # asumo q la data no esta decodificada
176 flagDecodeData = False # asumo q la data no esta decodificada
177 flagDeflipData = False # asumo q la data no esta sin flip
177 flagDeflipData = False # asumo q la data no esta sin flip
178 flagShiftFFT = False
178 flagShiftFFT = False
179 nCohInt = None
179 nCohInt = None
180 windowOfFilter = 1
180 windowOfFilter = 1
181 C = 3e8
181 C = 3e8
182 frequency = 49.92e6
182 frequency = 49.92e6
183 realtime = False
183 realtime = False
184 beacon_heiIndexList = None
184 beacon_heiIndexList = None
185 last_block = None
185 last_block = None
186 blocknow = None
186 blocknow = None
187 azimuth = None
187 azimuth = None
188 zenith = None
188 zenith = None
189 beam = Beam()
189 beam = Beam()
190 profileIndex = None
190 profileIndex = None
191 error = None
191 error = None
192 data = None
192 data = None
193 nmodes = None
193 nmodes = None
194 metadata_list = ['heightList', 'timeZone', 'type']
194 metadata_list = ['heightList', 'timeZone', 'type']
195
195
196 ippFactor = 1 #Added to correct the freq and vel range for AMISR data
196 ippFactor = 1 #Added to correct the freq and vel range for AMISR data
197 useInputBuffer = False
197 useInputBuffer = False
198 buffer_empty = True
198 buffer_empty = True
199 codeList = []
199 codeList = []
200 azimuthList = []
200 azimuthList = []
201 elevationList = []
201 elevationList = []
202 last_noise = None
202 last_noise = None
203 __ipp = None
203 __ipp = None
204 __ippSeconds = None
204 __ippSeconds = None
205 sampled_heightsFFT = None
205 sampled_heightsFFT = None
206 pulseLength_TxA = None
206 pulseLength_TxA = None
207 deltaHeight = None
207 deltaHeight = None
208 __code = None
208 __code = None
209 __nCode = None
209 __nCode = None
210 __nBaud = None
210 __nBaud = None
211 unitsDescription = "The units of the parameters are according to the International System of units (Seconds, Meter, Hertz, ...), except \
211 unitsDescription = "The units of the parameters are according to the International System of units (Seconds, Meter, Hertz, ...), except \
212 the parameters related to distances such as heightList, or heightResolution wich are in Km"
212 the parameters related to distances such as heightList, or heightResolution wich are in Km"
213
213
214
214
215
215
216 def __str__(self):
216 def __str__(self):
217
217
218 return '{} - {}'.format(self.type, self.datatime())
218 return '{} - {}'.format(self.type, self.datatime())
219
219
220 def getNoise(self):
220 def getNoise(self):
221
221
222 raise NotImplementedError
222 raise NotImplementedError
223
223
224 @property
224 @property
225 def nChannels(self):
225 def nChannels(self):
226
226
227 return len(self.channelList)
227 return len(self.channelList)
228
228
229 @property
229 @property
230 def channelIndexList(self):
230 def channelIndexList(self):
231
231
232 return list(range(self.nChannels))
232 return list(range(self.nChannels))
233
233
234 @property
234 @property
235 def nHeights(self):
235 def nHeights(self):
236
236
237 return len(self.heightList)
237 return len(self.heightList)
238
238
239 def getDeltaH(self):
239 def getDeltaH(self):
240
240
241 return self.heightList[1] - self.heightList[0]
241 return self.heightList[1] - self.heightList[0]
242
242
243 @property
243 @property
244 def ltctime(self):
244 def ltctime(self):
245
245 try:
246 self.timeZone = self.timeZone.decode("utf-8")
247 except Exception as e:
248 pass
249
246 if self.useLocalTime:
250 if self.useLocalTime:
247 if self.timeZone =='lt':
251 if self.timeZone =='lt':
248 return self.utctime - 300 * 60
252 return self.utctime - 300 * 60
249 elif self.timeZone =='ut':
253 elif self.timeZone =='ut':
250 return self.utctime
254 return self.utctime
251 else:
255 else:
252 log.error("No valid timeZone detected")
256 log.error("No valid timeZone detected:{}".format(self.timeZone))
253 return self.utctime
257 return self.utctime
254
258
255 @property
259 @property
256 def datatime(self):
260 def datatime(self):
257
261
258 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
262 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
259 return datatimeValue
263 return datatimeValue
260
264
261 def getTimeRange(self):
265 def getTimeRange(self):
262
266
263 datatime = []
267 datatime = []
264
268
265 datatime.append(self.ltctime)
269 datatime.append(self.ltctime)
266 datatime.append(self.ltctime + self.timeInterval + 1)
270 datatime.append(self.ltctime + self.timeInterval + 1)
267
271
268 datatime = numpy.array(datatime)
272 datatime = numpy.array(datatime)
269
273
270 return datatime
274 return datatime
271
275
272 def getFmaxTimeResponse(self):
276 def getFmaxTimeResponse(self):
273
277
274 period = (10**-6) * self.getDeltaH() / (0.15)
278 period = (10**-6) * self.getDeltaH() / (0.15)
275
279
276 PRF = 1. / (period * self.nCohInt)
280 PRF = 1. / (period * self.nCohInt)
277
281
278 fmax = PRF
282 fmax = PRF
279
283
280 return fmax
284 return fmax
281
285
282 def getFmax(self):
286 def getFmax(self):
283 PRF = 1. / (self.__ippSeconds * self.nCohInt)
287 PRF = 1. / (self.__ippSeconds * self.nCohInt)
284
288
285 fmax = PRF
289 fmax = PRF
286 return fmax
290 return fmax
287
291
288 def getVmax(self):
292 def getVmax(self):
289
293
290 _lambda = self.C / self.frequency
294 _lambda = self.C / self.frequency
291
295
292 vmax = self.getFmax() * _lambda / 2
296 vmax = self.getFmax() * _lambda / 2
293
297
294 return vmax
298 return vmax
295
299
296 ## Radar Controller Header must be immutable
300 ## Radar Controller Header must be immutable
297 @property
301 @property
298 def ippSeconds(self):
302 def ippSeconds(self):
299 '''
303 '''
300 '''
304 '''
301 #return self.radarControllerHeaderObj.ippSeconds
305 #return self.radarControllerHeaderObj.ippSeconds
302 return self.__ippSeconds
306 return self.__ippSeconds
303
307
304 @ippSeconds.setter
308 @ippSeconds.setter
305 def ippSeconds(self, ippSeconds):
309 def ippSeconds(self, ippSeconds):
306 '''
310 '''
307 '''
311 '''
308 #self.radarControllerHeaderObj.ippSeconds = ippSeconds
312 #self.radarControllerHeaderObj.ippSeconds = ippSeconds
309 self.__ippSeconds = ippSeconds
313 self.__ippSeconds = ippSeconds
310 self.__ipp = ippSeconds*SPEED_OF_LIGHT/2000.0
314 self.__ipp = ippSeconds*SPEED_OF_LIGHT/2000.0
311
315
312 @property
316 @property
313 def code(self):
317 def code(self):
314 '''
318 '''
315 '''
319 '''
316 # return self.radarControllerHeaderObj.code
320 # return self.radarControllerHeaderObj.code
317 return self.__code
321 return self.__code
318
322
319 @code.setter
323 @code.setter
320 def code(self, code):
324 def code(self, code):
321 '''
325 '''
322 '''
326 '''
323 # self.radarControllerHeaderObj.code = code
327 # self.radarControllerHeaderObj.code = code
324 self.__code = code
328 self.__code = code
325
329
326 @property
330 @property
327 def nCode(self):
331 def nCode(self):
328 '''
332 '''
329 '''
333 '''
330 # return self.radarControllerHeaderObj.nCode
334 # return self.radarControllerHeaderObj.nCode
331 return self.__nCode
335 return self.__nCode
332
336
333 @nCode.setter
337 @nCode.setter
334 def nCode(self, ncode):
338 def nCode(self, ncode):
335 '''
339 '''
336 '''
340 '''
337 # self.radarControllerHeaderObj.nCode = ncode
341 # self.radarControllerHeaderObj.nCode = ncode
338 self.__nCode = ncode
342 self.__nCode = ncode
339
343
340 @property
344 @property
341 def nBaud(self):
345 def nBaud(self):
342 '''
346 '''
343 '''
347 '''
344 # return self.radarControllerHeaderObj.nBaud
348 # return self.radarControllerHeaderObj.nBaud
345 return self.__nBaud
349 return self.__nBaud
346
350
347 @nBaud.setter
351 @nBaud.setter
348 def nBaud(self, nbaud):
352 def nBaud(self, nbaud):
349 '''
353 '''
350 '''
354 '''
351 # self.radarControllerHeaderObj.nBaud = nbaud
355 # self.radarControllerHeaderObj.nBaud = nbaud
352 self.__nBaud = nbaud
356 self.__nBaud = nbaud
353
357
354 @property
358 @property
355 def ipp(self):
359 def ipp(self):
356 '''
360 '''
357 '''
361 '''
358 # return self.radarControllerHeaderObj.ipp
362 # return self.radarControllerHeaderObj.ipp
359 return self.__ipp
363 return self.__ipp
360
364
361 @ipp.setter
365 @ipp.setter
362 def ipp(self, ipp):
366 def ipp(self, ipp):
363 '''
367 '''
364 '''
368 '''
365 # self.radarControllerHeaderObj.ipp = ipp
369 # self.radarControllerHeaderObj.ipp = ipp
366 self.__ipp = ipp
370 self.__ipp = ipp
367
371
368 @property
372 @property
369 def metadata(self):
373 def metadata(self):
370 '''
374 '''
371 '''
375 '''
372
376
373 return {attr: getattr(self, attr) for attr in self.metadata_list}
377 return {attr: getattr(self, attr) for attr in self.metadata_list}
374
378
375
379
376 class Voltage(JROData):
380 class Voltage(JROData):
377
381
378 dataPP_POW = None
382 dataPP_POW = None
379 dataPP_DOP = None
383 dataPP_DOP = None
380 dataPP_WIDTH = None
384 dataPP_WIDTH = None
381 dataPP_SNR = None
385 dataPP_SNR = None
382
386
383 # To use oper
387 # To use oper
384 flagProfilesByRange = False
388 flagProfilesByRange = False
385 nProfilesByRange = None
389 nProfilesByRange = None
386 max_nIncohInt = 1
390 max_nIncohInt = 1
387
391
388 def __init__(self):
392 def __init__(self):
389 '''
393 '''
390 Constructor
394 Constructor
391 '''
395 '''
392
396
393 self.useLocalTime = True
397 self.useLocalTime = True
394 self.radarControllerHeaderObj = RadarControllerHeader()
398 self.radarControllerHeaderObj = RadarControllerHeader()
395 self.systemHeaderObj = SystemHeader()
399 self.systemHeaderObj = SystemHeader()
396 self.processingHeaderObj = ProcessingHeader()
400 self.processingHeaderObj = ProcessingHeader()
397 self.type = "Voltage"
401 self.type = "Voltage"
398 self.data = None
402 self.data = None
399 self.nProfiles = None
403 self.nProfiles = None
400 self.heightList = None
404 self.heightList = None
401 self.channelList = None
405 self.channelList = None
402 self.flagNoData = True
406 self.flagNoData = True
403 self.flagDiscontinuousBlock = False
407 self.flagDiscontinuousBlock = False
404 self.utctime = None
408 self.utctime = None
405 self.timeZone = 0
409 self.timeZone = 0
406 self.dstFlag = None
410 self.dstFlag = None
407 self.errorCount = None
411 self.errorCount = None
408 self.nCohInt = None
412 self.nCohInt = None
409 self.blocksize = None
413 self.blocksize = None
410 self.flagCohInt = False
414 self.flagCohInt = False
411 self.flagDecodeData = False # asumo q la data no esta decodificada
415 self.flagDecodeData = False # asumo q la data no esta decodificada
412 self.flagDeflipData = False # asumo q la data no esta sin flip
416 self.flagDeflipData = False # asumo q la data no esta sin flip
413 self.flagShiftFFT = False
417 self.flagShiftFFT = False
414 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
418 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
415 self.profileIndex = 0
419 self.profileIndex = 0
416 self.ippFactor=1
420 self.ippFactor=1
417 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
421 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
418 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
422 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
419
423
420 def getNoisebyHildebrand(self, channel=None, ymin_index=None, ymax_index=None):
424 def getNoisebyHildebrand(self, channel=None, ymin_index=None, ymax_index=None):
421 """
425 """
422 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
426 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
423
427
424 Return:
428 Return:
425 noiselevel
429 noiselevel
426 """
430 """
427
431
428 if channel != None:
432 if channel != None:
429 data = self.data[channel,ymin_index:ymax_index]
433 data = self.data[channel,ymin_index:ymax_index]
430 nChannels = 1
434 nChannels = 1
431 else:
435 else:
432 data = self.data[:,ymin_index:ymax_index]
436 data = self.data[:,ymin_index:ymax_index]
433 nChannels = self.nChannels
437 nChannels = self.nChannels
434
438
435 noise = numpy.zeros(nChannels)
439 noise = numpy.zeros(nChannels)
436 power = data * numpy.conjugate(data)
440 power = data * numpy.conjugate(data)
437
441
438 for thisChannel in range(nChannels):
442 for thisChannel in range(nChannels):
439 if nChannels == 1:
443 if nChannels == 1:
440 daux = power[:].real
444 daux = power[:].real
441 else:
445 else:
442 daux = power[thisChannel, :].real
446 daux = power[thisChannel, :].real
443 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
447 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
444
448
445 return noise
449 return noise
446
450
447 def getNoise(self, type=1, channel=None,ymin_index=None, ymax_index=None):
451 def getNoise(self, type=1, channel=None,ymin_index=None, ymax_index=None):
448
452
449 if type == 1:
453 if type == 1:
450 noise = self.getNoisebyHildebrand(channel,ymin_index, ymax_index)
454 noise = self.getNoisebyHildebrand(channel,ymin_index, ymax_index)
451
455
452 return noise
456 return noise
453
457
454 def getPower(self, channel=None):
458 def getPower(self, channel=None):
455
459
456 if channel != None:
460 if channel != None:
457 data = self.data[channel]
461 data = self.data[channel]
458 else:
462 else:
459 data = self.data
463 data = self.data
460
464
461 power = data * numpy.conjugate(data)
465 power = data * numpy.conjugate(data)
462 powerdB = 10 * numpy.log10(power.real)
466 powerdB = 10 * numpy.log10(power.real)
463 powerdB = numpy.squeeze(powerdB)
467 powerdB = numpy.squeeze(powerdB)
464
468
465 return powerdB
469 return powerdB
466 @property
470 @property
467 def data_pow(self):
471 def data_pow(self):
468 return self.getPower()
472 return self.getPower()
469
473
470 @property
474 @property
471 def timeInterval(self):
475 def timeInterval(self):
472
476
473 return self.ippSeconds * self.nCohInt
477 return self.ippSeconds * self.nCohInt
474
478
475 noise = property(getNoise, "I'm the 'nHeights' property.")
479 noise = property(getNoise, "I'm the 'nHeights' property.")
476
480
477
481
478 class Spectra(JROData):
482 class Spectra(JROData):
479
483
480 data_outlier = None
484 data_outlier = None
481 flagProfilesByRange = False
485 flagProfilesByRange = False
482 nProfilesByRange = None
486 nProfilesByRange = None
483
487
484 def __init__(self):
488 def __init__(self):
485 '''
489 '''
486 Constructor
490 Constructor
487 '''
491 '''
488
492
489 self.data_dc = None
493 self.data_dc = None
490 self.data_spc = None
494 self.data_spc = None
491 self.data_cspc = None
495 self.data_cspc = None
492 self.useLocalTime = True
496 self.useLocalTime = True
493 self.radarControllerHeaderObj = RadarControllerHeader()
497 self.radarControllerHeaderObj = RadarControllerHeader()
494 self.systemHeaderObj = SystemHeader()
498 self.systemHeaderObj = SystemHeader()
495 self.processingHeaderObj = ProcessingHeader()
499 self.processingHeaderObj = ProcessingHeader()
496 self.type = "Spectra"
500 self.type = "Spectra"
497 self.timeZone = 0
501 self.timeZone = 0
498 self.nProfiles = None
502 self.nProfiles = None
499 self.heightList = None
503 self.heightList = None
500 self.channelList = None
504 self.channelList = None
501 self.pairsList = None
505 self.pairsList = None
502 self.flagNoData = True
506 self.flagNoData = True
503 self.flagDiscontinuousBlock = False
507 self.flagDiscontinuousBlock = False
504 self.utctime = None
508 self.utctime = None
505 self.nCohInt = None
509 self.nCohInt = None
506 self.nIncohInt = None
510 self.nIncohInt = None
507 self.blocksize = None
511 self.blocksize = None
508 self.nFFTPoints = None
512 self.nFFTPoints = None
509 self.wavelength = None
513 self.wavelength = None
510 self.flagDecodeData = False # asumo q la data no esta decodificada
514 self.flagDecodeData = False # asumo q la data no esta decodificada
511 self.flagDeflipData = False # asumo q la data no esta sin flip
515 self.flagDeflipData = False # asumo q la data no esta sin flip
512 self.flagShiftFFT = False
516 self.flagShiftFFT = False
513 self.ippFactor = 1
517 self.ippFactor = 1
514 self.beacon_heiIndexList = []
518 self.beacon_heiIndexList = []
515 self.noise_estimation = None
519 self.noise_estimation = None
516 self.codeList = []
520 self.codeList = []
517 self.azimuthList = []
521 self.azimuthList = []
518 self.elevationList = []
522 self.elevationList = []
519 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
523 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
520 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
524 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
521
525
522 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
526 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
523 """
527 """
524 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
528 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
525
529
526 Return:
530 Return:
527 noiselevel
531 noiselevel
528 """
532 """
529
533
530 noise = numpy.zeros(self.nChannels)
534 noise = numpy.zeros(self.nChannels)
531
535
532 for channel in range(self.nChannels):
536 for channel in range(self.nChannels):
533 daux = self.data_spc[channel,
537 daux = self.data_spc[channel,
534 xmin_index:xmax_index, ymin_index:ymax_index]
538 xmin_index:xmax_index, ymin_index:ymax_index]
535 # noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
539 # noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
536 noise[channel] = hildebrand_sekhon(daux, self.max_nIncohInt[channel])
540 noise[channel] = hildebrand_sekhon(daux, self.max_nIncohInt[channel])
537
541
538 return noise
542 return noise
539
543
540 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
544 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
541
545
542 if self.noise_estimation is not None:
546 if self.noise_estimation is not None:
543 # this was estimated by getNoise Operation defined in jroproc_spectra.py
547 # this was estimated by getNoise Operation defined in jroproc_spectra.py
544 return self.noise_estimation
548 return self.noise_estimation
545 else:
549 else:
546 noise = self.getNoisebyHildebrand(
550 noise = self.getNoisebyHildebrand(
547 xmin_index, xmax_index, ymin_index, ymax_index)
551 xmin_index, xmax_index, ymin_index, ymax_index)
548 return noise
552 return noise
549
553
550 def getFreqRangeTimeResponse(self, extrapoints=0):
554 def getFreqRangeTimeResponse(self, extrapoints=0):
551
555
552 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
556 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
553 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
557 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
554
558
555 return freqrange
559 return freqrange
556
560
557 def getAcfRange(self, extrapoints=0):
561 def getAcfRange(self, extrapoints=0):
558
562
559 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
563 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
560 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
564 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
561
565
562 return freqrange
566 return freqrange
563
567
564 def getFreqRange(self, extrapoints=0):
568 def getFreqRange(self, extrapoints=0):
565
569
566 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
570 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
567 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
571 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
568
572
569 return freqrange
573 return freqrange
570
574
571 def getVelRange(self, extrapoints=0):
575 def getVelRange(self, extrapoints=0):
572
576
573 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
577 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
574 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
578 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
575
579
576 if self.nmodes:
580 if self.nmodes:
577 return velrange/self.nmodes
581 return velrange/self.nmodes
578 else:
582 else:
579 return velrange
583 return velrange
580
584
581 @property
585 @property
582 def nPairs(self):
586 def nPairs(self):
583
587
584 return len(self.pairsList)
588 return len(self.pairsList)
585
589
586 @property
590 @property
587 def pairsIndexList(self):
591 def pairsIndexList(self):
588
592
589 return list(range(self.nPairs))
593 return list(range(self.nPairs))
590
594
591 @property
595 @property
592 def normFactor(self):
596 def normFactor(self):
593
597
594 pwcode = 1
598 pwcode = 1
595 if self.flagDecodeData:
599 if self.flagDecodeData:
596 try:
600 try:
597 pwcode = numpy.sum(self.code[0]**2)
601 pwcode = numpy.sum(self.code[0]**2)
598 except Exception as e:
602 except Exception as e:
599 log.warning("Failed pwcode read, setting to 1")
603 log.warning("Failed pwcode read, setting to 1")
600 pwcode = 1
604 pwcode = 1
601 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
605 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
602 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
606 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
603 if self.flagProfilesByRange:
607 if self.flagProfilesByRange:
604 normFactor *= (self.nProfilesByRange/self.nProfilesByRange.max())
608 normFactor *= (self.nProfilesByRange/self.nProfilesByRange.max())
605 return normFactor
609 return normFactor
606
610
607 @property
611 @property
608 def flag_cspc(self):
612 def flag_cspc(self):
609
613
610 if self.data_cspc is None:
614 if self.data_cspc is None:
611 return True
615 return True
612
616
613 return False
617 return False
614
618
615 @property
619 @property
616 def flag_dc(self):
620 def flag_dc(self):
617
621
618 if self.data_dc is None:
622 if self.data_dc is None:
619 return True
623 return True
620
624
621 return False
625 return False
622
626
623 @property
627 @property
624 def timeInterval(self):
628 def timeInterval(self):
625
629
626 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
630 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
627 if self.nmodes:
631 if self.nmodes:
628 return self.nmodes*timeInterval
632 return self.nmodes*timeInterval
629 else:
633 else:
630 return timeInterval
634 return timeInterval
631
635
632 def getPower(self):
636 def getPower(self):
633
637
634 factor = self.normFactor
638 factor = self.normFactor
635 power = numpy.zeros( (self.nChannels,self.nHeights) )
639 power = numpy.zeros( (self.nChannels,self.nHeights) )
636 for ch in range(self.nChannels):
640 for ch in range(self.nChannels):
637 z = None
641 z = None
638 if hasattr(factor,'shape'):
642 if hasattr(factor,'shape'):
639 if factor.ndim > 1:
643 if factor.ndim > 1:
640 z = self.data_spc[ch]/factor[ch]
644 z = self.data_spc[ch]/factor[ch]
641 else:
645 else:
642 z = self.data_spc[ch]/factor
646 z = self.data_spc[ch]/factor
643 else:
647 else:
644 z = self.data_spc[ch]/factor
648 z = self.data_spc[ch]/factor
645 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
649 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
646 avg = numpy.average(z, axis=0)
650 avg = numpy.average(z, axis=0)
647 power[ch] = 10 * numpy.log10(avg)
651 power[ch] = 10 * numpy.log10(avg)
648 return power
652 return power
649
653
650 @property
654 @property
651 def max_nIncohInt(self):
655 def max_nIncohInt(self):
652
656
653 ints = numpy.zeros(self.nChannels)
657 ints = numpy.zeros(self.nChannels)
654 for ch in range(self.nChannels):
658 for ch in range(self.nChannels):
655 if hasattr(self.nIncohInt,'shape'):
659 if hasattr(self.nIncohInt,'shape'):
656 if self.nIncohInt.ndim > 1:
660 if self.nIncohInt.ndim > 1:
657 ints[ch,] = self.nIncohInt[ch].max()
661 ints[ch,] = self.nIncohInt[ch].max()
658 else:
662 else:
659 ints[ch,] = self.nIncohInt
663 ints[ch,] = self.nIncohInt
660 self.nIncohInt = int(self.nIncohInt)
664 self.nIncohInt = int(self.nIncohInt)
661 else:
665 else:
662 ints[ch,] = self.nIncohInt
666 ints[ch,] = self.nIncohInt
663
667
664 return ints
668 return ints
665
669
666 def getCoherence(self, pairsList=None, phase=False):
670 def getCoherence(self, pairsList=None, phase=False):
667
671
668 z = []
672 z = []
669 if pairsList is None:
673 if pairsList is None:
670 pairsIndexList = self.pairsIndexList
674 pairsIndexList = self.pairsIndexList
671 else:
675 else:
672 pairsIndexList = []
676 pairsIndexList = []
673 for pair in pairsList:
677 for pair in pairsList:
674 if pair not in self.pairsList:
678 if pair not in self.pairsList:
675 raise ValueError("Pair %s is not in dataOut.pairsList" % (
679 raise ValueError("Pair %s is not in dataOut.pairsList" % (
676 pair))
680 pair))
677 pairsIndexList.append(self.pairsList.index(pair))
681 pairsIndexList.append(self.pairsList.index(pair))
678 for i in range(len(pairsIndexList)):
682 for i in range(len(pairsIndexList)):
679 pair = self.pairsList[pairsIndexList[i]]
683 pair = self.pairsList[pairsIndexList[i]]
680 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
684 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
681 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
685 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
682 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
686 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
683 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
687 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
684 if phase:
688 if phase:
685 data = numpy.arctan2(avgcoherenceComplex.imag,
689 data = numpy.arctan2(avgcoherenceComplex.imag,
686 avgcoherenceComplex.real) * 180 / numpy.pi
690 avgcoherenceComplex.real) * 180 / numpy.pi
687 else:
691 else:
688 data = numpy.abs(avgcoherenceComplex)
692 data = numpy.abs(avgcoherenceComplex)
689
693
690 z.append(data)
694 z.append(data)
691
695
692 return numpy.array(z)
696 return numpy.array(z)
693
697
694 def setValue(self, value):
698 def setValue(self, value):
695
699
696 print("This property should not be initialized", value)
700 print("This property should not be initialized", value)
697
701
698 return
702 return
699
703
700 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
704 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
701
705
702
706
703 class SpectraHeis(Spectra):
707 class SpectraHeis(Spectra):
704
708
705 def __init__(self):
709 def __init__(self):
706
710
707 self.radarControllerHeaderObj = RadarControllerHeader()
711 self.radarControllerHeaderObj = RadarControllerHeader()
708 self.systemHeaderObj = SystemHeader()
712 self.systemHeaderObj = SystemHeader()
709 self.type = "SpectraHeis"
713 self.type = "SpectraHeis"
710 self.nProfiles = None
714 self.nProfiles = None
711 self.heightList = None
715 self.heightList = None
712 self.channelList = None
716 self.channelList = None
713 self.flagNoData = True
717 self.flagNoData = True
714 self.flagDiscontinuousBlock = False
718 self.flagDiscontinuousBlock = False
715 self.utctime = None
719 self.utctime = None
716 self.blocksize = None
720 self.blocksize = None
717 self.profileIndex = 0
721 self.profileIndex = 0
718 self.nCohInt = 1
722 self.nCohInt = 1
719 self.nIncohInt = 1
723 self.nIncohInt = 1
720
724
721 @property
725 @property
722 def normFactor(self):
726 def normFactor(self):
723 pwcode = 1
727 pwcode = 1
724 if self.flagDecodeData:
728 if self.flagDecodeData:
725 pwcode = numpy.sum(self.code[0]**2)
729 pwcode = numpy.sum(self.code[0]**2)
726
730
727 normFactor = self.nIncohInt * self.nCohInt * pwcode
731 normFactor = self.nIncohInt * self.nCohInt * pwcode
728
732
729 return normFactor
733 return normFactor
730
734
731 @property
735 @property
732 def timeInterval(self):
736 def timeInterval(self):
733
737
734 return self.ippSeconds * self.nCohInt * self.nIncohInt
738 return self.ippSeconds * self.nCohInt * self.nIncohInt
735
739
736
740
737 class Fits(JROData):
741 class Fits(JROData):
738
742
739 def __init__(self):
743 def __init__(self):
740
744
741 self.type = "Fits"
745 self.type = "Fits"
742 self.nProfiles = None
746 self.nProfiles = None
743 self.heightList = None
747 self.heightList = None
744 self.channelList = None
748 self.channelList = None
745 self.flagNoData = True
749 self.flagNoData = True
746 self.utctime = None
750 self.utctime = None
747 self.nCohInt = 1
751 self.nCohInt = 1
748 self.nIncohInt = 1
752 self.nIncohInt = 1
749 self.useLocalTime = True
753 self.useLocalTime = True
750 self.profileIndex = 0
754 self.profileIndex = 0
751 self.timeZone = 0
755 self.timeZone = 0
752
756
753 def getTimeRange(self):
757 def getTimeRange(self):
754
758
755 datatime = []
759 datatime = []
756
760
757 datatime.append(self.ltctime)
761 datatime.append(self.ltctime)
758 datatime.append(self.ltctime + self.timeInterval)
762 datatime.append(self.ltctime + self.timeInterval)
759
763
760 datatime = numpy.array(datatime)
764 datatime = numpy.array(datatime)
761
765
762 return datatime
766 return datatime
763
767
764 def getChannelIndexList(self):
768 def getChannelIndexList(self):
765
769
766 return list(range(self.nChannels))
770 return list(range(self.nChannels))
767
771
768 def getNoise(self, type=1):
772 def getNoise(self, type=1):
769
773
770
774
771 if type == 1:
775 if type == 1:
772 noise = self.getNoisebyHildebrand()
776 noise = self.getNoisebyHildebrand()
773
777
774 if type == 2:
778 if type == 2:
775 noise = self.getNoisebySort()
779 noise = self.getNoisebySort()
776
780
777 if type == 3:
781 if type == 3:
778 noise = self.getNoisebyWindow()
782 noise = self.getNoisebyWindow()
779
783
780 return noise
784 return noise
781
785
782 @property
786 @property
783 def timeInterval(self):
787 def timeInterval(self):
784
788
785 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
789 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
786
790
787 return timeInterval
791 return timeInterval
788
792
789 @property
793 @property
790 def ippSeconds(self):
794 def ippSeconds(self):
791 '''
795 '''
792 '''
796 '''
793 return self.ipp_sec
797 return self.ipp_sec
794
798
795 noise = property(getNoise, "I'm the 'nHeights' property.")
799 noise = property(getNoise, "I'm the 'nHeights' property.")
796
800
797
801
798 class Correlation(JROData):
802 class Correlation(JROData):
799
803
800 def __init__(self):
804 def __init__(self):
801 '''
805 '''
802 Constructor
806 Constructor
803 '''
807 '''
804 self.radarControllerHeaderObj = RadarControllerHeader()
808 self.radarControllerHeaderObj = RadarControllerHeader()
805 self.systemHeaderObj = SystemHeader()
809 self.systemHeaderObj = SystemHeader()
806 self.type = "Correlation"
810 self.type = "Correlation"
807 self.data = None
811 self.data = None
808 self.dtype = None
812 self.dtype = None
809 self.nProfiles = None
813 self.nProfiles = None
810 self.heightList = None
814 self.heightList = None
811 self.channelList = None
815 self.channelList = None
812 self.flagNoData = True
816 self.flagNoData = True
813 self.flagDiscontinuousBlock = False
817 self.flagDiscontinuousBlock = False
814 self.utctime = None
818 self.utctime = None
815 self.timeZone = 0
819 self.timeZone = 0
816 self.dstFlag = None
820 self.dstFlag = None
817 self.errorCount = None
821 self.errorCount = None
818 self.blocksize = None
822 self.blocksize = None
819 self.flagDecodeData = False # asumo q la data no esta decodificada
823 self.flagDecodeData = False # asumo q la data no esta decodificada
820 self.flagDeflipData = False # asumo q la data no esta sin flip
824 self.flagDeflipData = False # asumo q la data no esta sin flip
821 self.pairsList = None
825 self.pairsList = None
822 self.nPoints = None
826 self.nPoints = None
823
827
824 def getPairsList(self):
828 def getPairsList(self):
825
829
826 return self.pairsList
830 return self.pairsList
827
831
828 def getNoise(self, mode=2):
832 def getNoise(self, mode=2):
829
833
830 indR = numpy.where(self.lagR == 0)[0][0]
834 indR = numpy.where(self.lagR == 0)[0][0]
831 indT = numpy.where(self.lagT == 0)[0][0]
835 indT = numpy.where(self.lagT == 0)[0][0]
832
836
833 jspectra0 = self.data_corr[:, :, indR, :]
837 jspectra0 = self.data_corr[:, :, indR, :]
834 jspectra = copy.copy(jspectra0)
838 jspectra = copy.copy(jspectra0)
835
839
836 num_chan = jspectra.shape[0]
840 num_chan = jspectra.shape[0]
837 num_hei = jspectra.shape[2]
841 num_hei = jspectra.shape[2]
838
842
839 freq_dc = jspectra.shape[1] / 2
843 freq_dc = jspectra.shape[1] / 2
840 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
844 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
841
845
842 if ind_vel[0] < 0:
846 if ind_vel[0] < 0:
843 ind_vel[list(range(0, 1))] = ind_vel[list(
847 ind_vel[list(range(0, 1))] = ind_vel[list(
844 range(0, 1))] + self.num_prof
848 range(0, 1))] + self.num_prof
845
849
846 if mode == 1:
850 if mode == 1:
847 jspectra[:, freq_dc, :] = (
851 jspectra[:, freq_dc, :] = (
848 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
852 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
849
853
850 if mode == 2:
854 if mode == 2:
851
855
852 vel = numpy.array([-2, -1, 1, 2])
856 vel = numpy.array([-2, -1, 1, 2])
853 xx = numpy.zeros([4, 4])
857 xx = numpy.zeros([4, 4])
854
858
855 for fil in range(4):
859 for fil in range(4):
856 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
860 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
857
861
858 xx_inv = numpy.linalg.inv(xx)
862 xx_inv = numpy.linalg.inv(xx)
859 xx_aux = xx_inv[0, :]
863 xx_aux = xx_inv[0, :]
860
864
861 for ich in range(num_chan):
865 for ich in range(num_chan):
862 yy = jspectra[ich, ind_vel, :]
866 yy = jspectra[ich, ind_vel, :]
863 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
867 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
864
868
865 junkid = jspectra[ich, freq_dc, :] <= 0
869 junkid = jspectra[ich, freq_dc, :] <= 0
866 cjunkid = sum(junkid)
870 cjunkid = sum(junkid)
867
871
868 if cjunkid.any():
872 if cjunkid.any():
869 jspectra[ich, freq_dc, junkid.nonzero()] = (
873 jspectra[ich, freq_dc, junkid.nonzero()] = (
870 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
874 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
871
875
872 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
876 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
873
877
874 return noise
878 return noise
875
879
876 @property
880 @property
877 def timeInterval(self):
881 def timeInterval(self):
878
882
879 return self.ippSeconds * self.nCohInt * self.nProfiles
883 return self.ippSeconds * self.nCohInt * self.nProfiles
880
884
881 def splitFunctions(self):
885 def splitFunctions(self):
882
886
883 pairsList = self.pairsList
887 pairsList = self.pairsList
884 ccf_pairs = []
888 ccf_pairs = []
885 acf_pairs = []
889 acf_pairs = []
886 ccf_ind = []
890 ccf_ind = []
887 acf_ind = []
891 acf_ind = []
888 for l in range(len(pairsList)):
892 for l in range(len(pairsList)):
889 chan0 = pairsList[l][0]
893 chan0 = pairsList[l][0]
890 chan1 = pairsList[l][1]
894 chan1 = pairsList[l][1]
891
895
892 # Obteniendo pares de Autocorrelacion
896 # Obteniendo pares de Autocorrelacion
893 if chan0 == chan1:
897 if chan0 == chan1:
894 acf_pairs.append(chan0)
898 acf_pairs.append(chan0)
895 acf_ind.append(l)
899 acf_ind.append(l)
896 else:
900 else:
897 ccf_pairs.append(pairsList[l])
901 ccf_pairs.append(pairsList[l])
898 ccf_ind.append(l)
902 ccf_ind.append(l)
899
903
900 data_acf = self.data_cf[acf_ind]
904 data_acf = self.data_cf[acf_ind]
901 data_ccf = self.data_cf[ccf_ind]
905 data_ccf = self.data_cf[ccf_ind]
902
906
903 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
907 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
904
908
905 @property
909 @property
906 def normFactor(self):
910 def normFactor(self):
907 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
911 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
908 acf_pairs = numpy.array(acf_pairs)
912 acf_pairs = numpy.array(acf_pairs)
909 normFactor = numpy.zeros((self.nPairs, self.nHeights))
913 normFactor = numpy.zeros((self.nPairs, self.nHeights))
910
914
911 for p in range(self.nPairs):
915 for p in range(self.nPairs):
912 pair = self.pairsList[p]
916 pair = self.pairsList[p]
913
917
914 ch0 = pair[0]
918 ch0 = pair[0]
915 ch1 = pair[1]
919 ch1 = pair[1]
916
920
917 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
921 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
918 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
922 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
919 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
923 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
920
924
921 return normFactor
925 return normFactor
922
926
923
927
924 class Parameters(Spectra):
928 class Parameters(Spectra):
925
929
926 groupList = None # List of Pairs, Groups, etc
930 groupList = None # List of Pairs, Groups, etc
927 data_param = None # Parameters obtained
931 data_param = None # Parameters obtained
928 data_pre = None # Data Pre Parametrization
932 data_pre = None # Data Pre Parametrization
929 data_SNR = None # Signal to Noise Ratio
933 data_SNR = None # Signal to Noise Ratio
930 abscissaList = None # Abscissa, can be velocities, lags or time
934 abscissaList = None # Abscissa, can be velocities, lags or time
931 utctimeInit = None # Initial UTC time
935 utctimeInit = None # Initial UTC time
932 paramInterval = None # Time interval to calculate Parameters in seconds
936 paramInterval = None # Time interval to calculate Parameters in seconds
933 useLocalTime = True
937 useLocalTime = True
934 # Fitting
938 # Fitting
935 data_error = None # Error of the estimation
939 data_error = None # Error of the estimation
936 constants = None
940 constants = None
937 library = None
941 library = None
938 # Output signal
942 # Output signal
939 outputInterval = None # Time interval to calculate output signal in seconds
943 outputInterval = None # Time interval to calculate output signal in seconds
940 data_output = None # Out signal
944 data_output = None # Out signal
941 nAvg = None
945 nAvg = None
942 noise_estimation = None
946 noise_estimation = None
943 GauSPC = None # Fit gaussian SPC
947 GauSPC = None # Fit gaussian SPC
944
948
945 data_outlier = None
949 data_outlier = None
946 data_vdrift = None
950 data_vdrift = None
947 radarControllerHeaderTxt=None #header Controller like text
951 radarControllerHeaderTxt=None #header Controller like text
948 txPower = None
952 txPower = None
949 flagProfilesByRange = False
953 flagProfilesByRange = False
950 nProfilesByRange = None
954 nProfilesByRange = None
951
955
952
956
953 def __init__(self):
957 def __init__(self):
954 '''
958 '''
955 Constructor
959 Constructor
956 '''
960 '''
957 self.radarControllerHeaderObj = RadarControllerHeader()
961 self.radarControllerHeaderObj = RadarControllerHeader()
958 self.systemHeaderObj = SystemHeader()
962 self.systemHeaderObj = SystemHeader()
959 self.processingHeaderObj = ProcessingHeader()
963 self.processingHeaderObj = ProcessingHeader()
960 self.type = "Parameters"
964 self.type = "Parameters"
961 self.timeZone = 0
965 self.timeZone = 0
962
966
963 def getTimeRange1(self, interval):
967 def getTimeRange1(self, interval):
964
968
965 datatime = []
969 datatime = []
966
970
967 if self.useLocalTime:
971 if self.useLocalTime:
968 time1 = self.utctimeInit - self.timeZone * 60
972 time1 = self.utctimeInit - self.timeZone * 60
969 else:
973 else:
970 time1 = self.utctimeInit
974 time1 = self.utctimeInit
971
975
972 datatime.append(time1)
976 datatime.append(time1)
973 datatime.append(time1 + interval)
977 datatime.append(time1 + interval)
974 datatime = numpy.array(datatime)
978 datatime = numpy.array(datatime)
975
979
976 return datatime
980 return datatime
977
981
978 @property
982 @property
979 def timeInterval(self):
983 def timeInterval(self):
980
984
981 if hasattr(self, 'timeInterval1'):
985 if hasattr(self, 'timeInterval1'):
982 return self.timeInterval1
986 return self.timeInterval1
983 else:
987 else:
984 return self.paramInterval
988 return self.paramInterval
985
989
986 def setValue(self, value):
990 def setValue(self, value):
987
991
988 print("This property should not be initialized")
992 print("This property should not be initialized")
989
993
990 return
994 return
991
995
992 def getNoise(self):
996 def getNoise(self):
993
997
994 return self.spc_noise
998 return self.spc_noise
995
999
996 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1000 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
997
1001
998
1002
999 class PlotterData(object):
1003 class PlotterData(object):
1000 '''
1004 '''
1001 Object to hold data to be plotted
1005 Object to hold data to be plotted
1002 '''
1006 '''
1003
1007
1004 MAXNUMX = 200
1008 MAXNUMX = 200
1005 MAXNUMY = 200
1009 MAXNUMY = 200
1006
1010
1007 def __init__(self, code, exp_code, localtime=True):
1011 def __init__(self, code, exp_code, localtime=True):
1008
1012
1009 self.key = code
1013 self.key = code
1010 self.exp_code = exp_code
1014 self.exp_code = exp_code
1011 self.ready = False
1015 self.ready = False
1012 self.flagNoData = False
1016 self.flagNoData = False
1013 self.localtime = localtime
1017 self.localtime = localtime
1014 self.data = {}
1018 self.data = {}
1015 self.meta = {}
1019 self.meta = {}
1016 self.__heights = []
1020 self.__heights = []
1017
1021
1018 def __str__(self):
1022 def __str__(self):
1019 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1023 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1020 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1024 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1021
1025
1022 def __len__(self):
1026 def __len__(self):
1023 return len(self.data)
1027 return len(self.data)
1024
1028
1025 def __getitem__(self, key):
1029 def __getitem__(self, key):
1026 if isinstance(key, int):
1030 if isinstance(key, int):
1027 return self.data[self.times[key]]
1031 return self.data[self.times[key]]
1028 elif isinstance(key, str):
1032 elif isinstance(key, str):
1029 ret = numpy.array([self.data[x][key] for x in self.times])
1033 ret = numpy.array([self.data[x][key] for x in self.times])
1030 if ret.ndim > 1:
1034 if ret.ndim > 1:
1031 ret = numpy.swapaxes(ret, 0, 1)
1035 ret = numpy.swapaxes(ret, 0, 1)
1032 return ret
1036 return ret
1033
1037
1034 def __contains__(self, key):
1038 def __contains__(self, key):
1035 return key in self.data[self.min_time]
1039 return key in self.data[self.min_time]
1036
1040
1037 def setup(self):
1041 def setup(self):
1038 '''
1042 '''
1039 Configure object
1043 Configure object
1040 '''
1044 '''
1041 self.type = ''
1045 self.type = ''
1042 self.ready = False
1046 self.ready = False
1043 del self.data
1047 del self.data
1044 self.data = {}
1048 self.data = {}
1045 self.__heights = []
1049 self.__heights = []
1046 self.__all_heights = set()
1050 self.__all_heights = set()
1047
1051
1048 def shape(self, key):
1052 def shape(self, key):
1049 '''
1053 '''
1050 Get the shape of the one-element data for the given key
1054 Get the shape of the one-element data for the given key
1051 '''
1055 '''
1052
1056
1053 if len(self.data[self.min_time][key]):
1057 if len(self.data[self.min_time][key]):
1054 return self.data[self.min_time][key].shape
1058 return self.data[self.min_time][key].shape
1055 return (0,)
1059 return (0,)
1056
1060
1057 def update(self, data, tm, meta={}):
1061 def update(self, data, tm, meta={}):
1058 '''
1062 '''
1059 Update data object with new dataOut
1063 Update data object with new dataOut
1060 '''
1064 '''
1061
1065
1062 self.data[tm] = data
1066 self.data[tm] = data
1063
1067
1064 for key, value in meta.items():
1068 for key, value in meta.items():
1065 setattr(self, key, value)
1069 setattr(self, key, value)
1066
1070
1067 def normalize_heights(self):
1071 def normalize_heights(self):
1068 '''
1072 '''
1069 Ensure same-dimension of the data for different heighList
1073 Ensure same-dimension of the data for different heighList
1070 '''
1074 '''
1071
1075
1072 H = numpy.array(list(self.__all_heights))
1076 H = numpy.array(list(self.__all_heights))
1073 H.sort()
1077 H.sort()
1074 for key in self.data:
1078 for key in self.data:
1075 shape = self.shape(key)[:-1] + H.shape
1079 shape = self.shape(key)[:-1] + H.shape
1076 for tm, obj in list(self.data[key].items()):
1080 for tm, obj in list(self.data[key].items()):
1077 h = self.__heights[self.times.tolist().index(tm)]
1081 h = self.__heights[self.times.tolist().index(tm)]
1078 if H.size == h.size:
1082 if H.size == h.size:
1079 continue
1083 continue
1080 index = numpy.where(numpy.in1d(H, h))[0]
1084 index = numpy.where(numpy.in1d(H, h))[0]
1081 dummy = numpy.zeros(shape) + numpy.nan
1085 dummy = numpy.zeros(shape) + numpy.nan
1082 if len(shape) == 2:
1086 if len(shape) == 2:
1083 dummy[:, index] = obj
1087 dummy[:, index] = obj
1084 else:
1088 else:
1085 dummy[index] = obj
1089 dummy[index] = obj
1086 self.data[key][tm] = dummy
1090 self.data[key][tm] = dummy
1087
1091
1088 self.__heights = [H for tm in self.times]
1092 self.__heights = [H for tm in self.times]
1089
1093
1090 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1094 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1091 '''
1095 '''
1092 Convert data to json
1096 Convert data to json
1093 '''
1097 '''
1094
1098
1095 meta = {}
1099 meta = {}
1096 meta['xrange'] = []
1100 meta['xrange'] = []
1097 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1101 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1098 tmp = self.data[tm][self.key]
1102 tmp = self.data[tm][self.key]
1099 shape = tmp.shape
1103 shape = tmp.shape
1100 if len(shape) == 2:
1104 if len(shape) == 2:
1101 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1105 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1102 elif len(shape) == 3:
1106 elif len(shape) == 3:
1103 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1107 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1104 data = self.roundFloats(
1108 data = self.roundFloats(
1105 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1109 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1106 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1110 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1107 else:
1111 else:
1108 data = self.roundFloats(self.data[tm][self.key].tolist())
1112 data = self.roundFloats(self.data[tm][self.key].tolist())
1109
1113
1110 ret = {
1114 ret = {
1111 'plot': plot_name,
1115 'plot': plot_name,
1112 'code': self.exp_code,
1116 'code': self.exp_code,
1113 'time': float(tm),
1117 'time': float(tm),
1114 'data': data,
1118 'data': data,
1115 }
1119 }
1116 meta['type'] = plot_type
1120 meta['type'] = plot_type
1117 meta['interval'] = float(self.interval)
1121 meta['interval'] = float(self.interval)
1118 meta['localtime'] = self.localtime
1122 meta['localtime'] = self.localtime
1119 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1123 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1120 meta.update(self.meta)
1124 meta.update(self.meta)
1121 ret['metadata'] = meta
1125 ret['metadata'] = meta
1122 return json.dumps(ret)
1126 return json.dumps(ret)
1123
1127
1124 @property
1128 @property
1125 def times(self):
1129 def times(self):
1126 '''
1130 '''
1127 Return the list of times of the current data
1131 Return the list of times of the current data
1128 '''
1132 '''
1129
1133
1130 ret = [t for t in self.data]
1134 ret = [t for t in self.data]
1131 ret.sort()
1135 ret.sort()
1132 return numpy.array(ret)
1136 return numpy.array(ret)
1133
1137
1134 @property
1138 @property
1135 def min_time(self):
1139 def min_time(self):
1136 '''
1140 '''
1137 Return the minimun time value
1141 Return the minimun time value
1138 '''
1142 '''
1139
1143
1140 return self.times[0]
1144 return self.times[0]
1141
1145
1142 @property
1146 @property
1143 def max_time(self):
1147 def max_time(self):
1144 '''
1148 '''
1145 Return the maximun time value
1149 Return the maximun time value
1146 '''
1150 '''
1147
1151
1148 return self.times[-1]
1152 return self.times[-1]
1149
1153
1150 # @property
1154 # @property
1151 # def heights(self):
1155 # def heights(self):
1152 # '''
1156 # '''
1153 # Return the list of heights of the current data
1157 # Return the list of heights of the current data
1154 # '''
1158 # '''
1155
1159
1156 # return numpy.array(self.__heights[-1])
1160 # return numpy.array(self.__heights[-1])
1157
1161
1158 @staticmethod
1162 @staticmethod
1159 def roundFloats(obj):
1163 def roundFloats(obj):
1160 if isinstance(obj, list):
1164 if isinstance(obj, list):
1161 return list(map(PlotterData.roundFloats, obj))
1165 return list(map(PlotterData.roundFloats, obj))
1162 elif isinstance(obj, float):
1166 elif isinstance(obj, float):
1163 return round(obj, 2)
1167 return round(obj, 2)
@@ -1,437 +1,437
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4
4
5 from schainpy.model.graphics.jroplot_base import Plot, plt
5 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
7 from schainpy.utils import log
7 from schainpy.utils import log
8
8
9 EARTH_RADIUS = 6.3710e3
9 EARTH_RADIUS = 6.3710e3
10
10
11
11
12 def ll2xy(lat1, lon1, lat2, lon2):
12 def ll2xy(lat1, lon1, lat2, lon2):
13
13
14 p = 0.017453292519943295
14 p = 0.017453292519943295
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
20 theta = -theta + numpy.pi/2
20 theta = -theta + numpy.pi/2
21 return r*numpy.cos(theta), r*numpy.sin(theta)
21 return r*numpy.cos(theta), r*numpy.sin(theta)
22
22
23
23
24 def km2deg(km):
24 def km2deg(km):
25 '''
25 '''
26 Convert distance in km to degrees
26 Convert distance in km to degrees
27 '''
27 '''
28
28
29 return numpy.rad2deg(km/EARTH_RADIUS)
29 return numpy.rad2deg(km/EARTH_RADIUS)
30
30
31
31
32
32
33 class SpectralMomentsPlot(SpectraPlot):
33 class SpectralMomentsPlot(SpectraPlot):
34 '''
34 '''
35 Plot for Spectral Moments
35 Plot for Spectral Moments
36 '''
36 '''
37 CODE = 'spc_moments'
37 CODE = 'spc_moments'
38 # colormap = 'jet'
38 # colormap = 'jet'
39 # plot_type = 'pcolor'
39 # plot_type = 'pcolor'
40
40
41 class DobleGaussianPlot(SpectraPlot):
41 class DobleGaussianPlot(SpectraPlot):
42 '''
42 '''
43 Plot for Double Gaussian Plot
43 Plot for Double Gaussian Plot
44 '''
44 '''
45 CODE = 'gaussian_fit'
45 CODE = 'gaussian_fit'
46 # colormap = 'jet'
46 # colormap = 'jet'
47 # plot_type = 'pcolor'
47 # plot_type = 'pcolor'
48
48
49 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
49 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
50 '''
50 '''
51 Plot SpectraCut with Double Gaussian Fit
51 Plot SpectraCut with Double Gaussian Fit
52 '''
52 '''
53 CODE = 'cut_gaussian_fit'
53 CODE = 'cut_gaussian_fit'
54
54
55
55
56 class SpectralFitObliquePlot(SpectraPlot):
56 class SpectralFitObliquePlot(SpectraPlot):
57 '''
57 '''
58 Plot for Spectral Oblique
58 Plot for Spectral Oblique
59 '''
59 '''
60 CODE = 'spc_moments'
60 CODE = 'spc_moments'
61 colormap = 'jet'
61 colormap = 'jet'
62 plot_type = 'pcolor'
62 plot_type = 'pcolor'
63
63
64
64
65 class SnrPlot(RTIPlot):
65 class SnrPlot(RTIPlot):
66 '''
66 '''
67 Plot for SNR Data
67 Plot for SNR Data
68 '''
68 '''
69
69
70 CODE = 'snr'
70 CODE = 'snr'
71 colormap = 'jet'
71 colormap = 'jet'
72
72
73 def update(self, dataOut):
73 def update(self, dataOut):
74 if len(self.channelList) == 0:
74 if len(self.channelList) == 0:
75 self.update_list(dataOut)
75 self.update_list(dataOut)
76
76
77 meta = {}
77 meta = {}
78 data = {
78 data = {
79 'snr': 10 * numpy.log10(dataOut.data_snr)
79 'snr': 10 * numpy.log10(dataOut.data_snr)
80 }
80 }
81 return data, meta
81 return data, meta
82
82
83 class DopplerPlot(RTIPlot):
83 class DopplerPlot(RTIPlot):
84 '''
84 '''
85 Plot for DOPPLER Data (1st moment)
85 Plot for DOPPLER Data (1st moment)
86 '''
86 '''
87
87
88 CODE = 'dop'
88 CODE = 'dop'
89 colormap = 'RdBu_r'
89 colormap = 'RdBu_r'
90
90
91 def update(self, dataOut):
91 def update(self, dataOut):
92 self.update_list(dataOut)
92 self.update_list(dataOut)
93 data = {
93 data = {
94 'dop': dataOut.data_dop
94 'dop': dataOut.data_dop
95 }
95 }
96
96
97 return data, {}
97 return data, {}
98
98
99 class PowerPlot(RTIPlot):
99 class PowerPlot(RTIPlot):
100 '''
100 '''
101 Plot for Power Data (0 moment)
101 Plot for Power Data (0 moment)
102 '''
102 '''
103
103
104 CODE = 'pow'
104 CODE = 'pow'
105 colormap = 'jet'
105 colormap = 'jet'
106
106
107 def update(self, dataOut):
107 def update(self, dataOut):
108 self.update_list(dataOut)
108 self.update_list(dataOut)
109 data = {
109 data = {
110 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
110 'pow': 10*numpy.log10(dataOut.data_pow)
111 }
111 }
112 try:
112 try:
113 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
113 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
114 except:
114 except:
115 pass
115 pass
116 return data, {}
116 return data, {}
117
117
118 class SpectralWidthPlot(RTIPlot):
118 class SpectralWidthPlot(RTIPlot):
119 '''
119 '''
120 Plot for Spectral Width Data (2nd moment)
120 Plot for Spectral Width Data (2nd moment)
121 '''
121 '''
122
122
123 CODE = 'width'
123 CODE = 'width'
124 colormap = 'jet'
124 colormap = 'jet'
125
125
126 def update(self, dataOut):
126 def update(self, dataOut):
127 self.update_list(dataOut)
127 self.update_list(dataOut)
128 data = {
128 data = {
129 'width': dataOut.data_width
129 'width': dataOut.data_width
130 }
130 }
131 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
131 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
132 return data, {}
132 return data, {}
133
133
134 class SkyMapPlot(Plot):
134 class SkyMapPlot(Plot):
135 '''
135 '''
136 Plot for meteors detection data
136 Plot for meteors detection data
137 '''
137 '''
138
138
139 CODE = 'param'
139 CODE = 'param'
140
140
141 def setup(self):
141 def setup(self):
142
142
143 self.ncols = 1
143 self.ncols = 1
144 self.nrows = 1
144 self.nrows = 1
145 self.width = 7.2
145 self.width = 7.2
146 self.height = 7.2
146 self.height = 7.2
147 self.nplots = 1
147 self.nplots = 1
148 self.xlabel = 'Zonal Zenith Angle (deg)'
148 self.xlabel = 'Zonal Zenith Angle (deg)'
149 self.ylabel = 'Meridional Zenith Angle (deg)'
149 self.ylabel = 'Meridional Zenith Angle (deg)'
150 self.polar = True
150 self.polar = True
151 self.ymin = -180
151 self.ymin = -180
152 self.ymax = 180
152 self.ymax = 180
153 self.colorbar = False
153 self.colorbar = False
154
154
155 def plot(self):
155 def plot(self):
156
156
157 arrayParameters = numpy.concatenate(self.data['param'])
157 arrayParameters = numpy.concatenate(self.data['param'])
158 error = arrayParameters[:, -1]
158 error = arrayParameters[:, -1]
159 indValid = numpy.where(error == 0)[0]
159 indValid = numpy.where(error == 0)[0]
160 finalMeteor = arrayParameters[indValid, :]
160 finalMeteor = arrayParameters[indValid, :]
161 finalAzimuth = finalMeteor[:, 3]
161 finalAzimuth = finalMeteor[:, 3]
162 finalZenith = finalMeteor[:, 4]
162 finalZenith = finalMeteor[:, 4]
163
163
164 x = finalAzimuth * numpy.pi / 180
164 x = finalAzimuth * numpy.pi / 180
165 y = finalZenith
165 y = finalZenith
166
166
167 ax = self.axes[0]
167 ax = self.axes[0]
168
168
169 if ax.firsttime:
169 if ax.firsttime:
170 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
170 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
171 else:
171 else:
172 ax.plot.set_data(x, y)
172 ax.plot.set_data(x, y)
173
173
174 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
174 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
175 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
175 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
176 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
176 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
177 dt2,
177 dt2,
178 len(x))
178 len(x))
179 self.titles[0] = title
179 self.titles[0] = title
180
180
181 class GenericRTIPlot(Plot):
181 class GenericRTIPlot(Plot):
182 '''
182 '''
183 Plot for data_xxxx object
183 Plot for data_xxxx object
184 '''
184 '''
185
185
186 CODE = 'param'
186 CODE = 'param'
187 colormap = 'viridis'
187 colormap = 'viridis'
188 plot_type = 'pcolorbuffer'
188 plot_type = 'pcolorbuffer'
189
189
190 def setup(self):
190 def setup(self):
191 self.xaxis = 'time'
191 self.xaxis = 'time'
192 self.ncols = 1
192 self.ncols = 1
193 self.nrows = self.data.shape('param')[0]
193 self.nrows = self.data.shape('param')[0]
194 self.nplots = self.nrows
194 self.nplots = self.nrows
195 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
195 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
196
196
197 if not self.xlabel:
197 if not self.xlabel:
198 self.xlabel = 'Time'
198 self.xlabel = 'Time'
199
199
200 self.ylabel = 'Range [km]'
200 self.ylabel = 'Range [km]'
201 if not self.titles:
201 if not self.titles:
202 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
202 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
203
203
204 def update(self, dataOut):
204 def update(self, dataOut):
205
205
206 data = {
206 data = {
207 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
207 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
208 }
208 }
209
209
210 meta = {}
210 meta = {}
211
211
212 return data, meta
212 return data, meta
213
213
214 def plot(self):
214 def plot(self):
215 # self.data.normalize_heights()
215 # self.data.normalize_heights()
216 self.x = self.data.times
216 self.x = self.data.times
217 self.y = self.data.yrange
217 self.y = self.data.yrange
218 self.z = self.data['param']
218 self.z = self.data['param']
219
219
220 self.z = numpy.ma.masked_invalid(self.z)
220 self.z = numpy.ma.masked_invalid(self.z)
221
221
222 if self.decimation is None:
222 if self.decimation is None:
223 x, y, z = self.fill_gaps(self.x, self.y, self.z)
223 x, y, z = self.fill_gaps(self.x, self.y, self.z)
224 else:
224 else:
225 x, y, z = self.fill_gaps(*self.decimate())
225 x, y, z = self.fill_gaps(*self.decimate())
226
226
227 for n, ax in enumerate(self.axes):
227 for n, ax in enumerate(self.axes):
228
228
229 self.zmax = self.zmax if self.zmax is not None else numpy.max(
229 self.zmax = self.zmax if self.zmax is not None else numpy.max(
230 self.z[n])
230 self.z[n])
231 self.zmin = self.zmin if self.zmin is not None else numpy.min(
231 self.zmin = self.zmin if self.zmin is not None else numpy.min(
232 self.z[n])
232 self.z[n])
233
233
234 if ax.firsttime:
234 if ax.firsttime:
235 if self.zlimits is not None:
235 if self.zlimits is not None:
236 self.zmin, self.zmax = self.zlimits[n]
236 self.zmin, self.zmax = self.zlimits[n]
237
237
238 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
238 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
239 vmin=self.zmin,
239 vmin=self.zmin,
240 vmax=self.zmax,
240 vmax=self.zmax,
241 cmap=self.cmaps[n]
241 cmap=self.cmaps[n]
242 )
242 )
243 else:
243 else:
244 if self.zlimits is not None:
244 if self.zlimits is not None:
245 self.zmin, self.zmax = self.zlimits[n]
245 self.zmin, self.zmax = self.zlimits[n]
246 try:
246 try:
247 ax.collections.remove(ax.collections[0])
247 ax.collections.remove(ax.collections[0])
248 except:
248 except:
249 pass
249 pass
250 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
250 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
251 vmin=self.zmin,
251 vmin=self.zmin,
252 vmax=self.zmax,
252 vmax=self.zmax,
253 cmap=self.cmaps[n]
253 cmap=self.cmaps[n]
254 )
254 )
255
255
256
256
257 class PolarMapPlot(Plot):
257 class PolarMapPlot(Plot):
258 '''
258 '''
259 Plot for weather radar
259 Plot for weather radar
260 '''
260 '''
261
261
262 CODE = 'param'
262 CODE = 'param'
263 colormap = 'seismic'
263 colormap = 'seismic'
264
264
265 def setup(self):
265 def setup(self):
266 self.ncols = 1
266 self.ncols = 1
267 self.nrows = 1
267 self.nrows = 1
268 self.width = 9
268 self.width = 9
269 self.height = 8
269 self.height = 8
270 self.mode = self.data.meta['mode']
270 self.mode = self.data.meta['mode']
271 if self.channels is not None:
271 if self.channels is not None:
272 self.nplots = len(self.channels)
272 self.nplots = len(self.channels)
273 self.nrows = len(self.channels)
273 self.nrows = len(self.channels)
274 else:
274 else:
275 self.nplots = self.data.shape(self.CODE)[0]
275 self.nplots = self.data.shape(self.CODE)[0]
276 self.nrows = self.nplots
276 self.nrows = self.nplots
277 self.channels = list(range(self.nplots))
277 self.channels = list(range(self.nplots))
278 if self.mode == 'E':
278 if self.mode == 'E':
279 self.xlabel = 'Longitude'
279 self.xlabel = 'Longitude'
280 self.ylabel = 'Latitude'
280 self.ylabel = 'Latitude'
281 else:
281 else:
282 self.xlabel = 'Range (km)'
282 self.xlabel = 'Range (km)'
283 self.ylabel = 'Height (km)'
283 self.ylabel = 'Height (km)'
284 self.bgcolor = 'white'
284 self.bgcolor = 'white'
285 self.cb_labels = self.data.meta['units']
285 self.cb_labels = self.data.meta['units']
286 self.lat = self.data.meta['latitude']
286 self.lat = self.data.meta['latitude']
287 self.lon = self.data.meta['longitude']
287 self.lon = self.data.meta['longitude']
288 self.xmin, self.xmax = float(
288 self.xmin, self.xmax = float(
289 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
289 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
290 self.ymin, self.ymax = float(
290 self.ymin, self.ymax = float(
291 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
291 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
292 # self.polar = True
292 # self.polar = True
293
293
294 def plot(self):
294 def plot(self):
295
295
296 for n, ax in enumerate(self.axes):
296 for n, ax in enumerate(self.axes):
297 data = self.data['param'][self.channels[n]]
297 data = self.data['param'][self.channels[n]]
298
298
299 zeniths = numpy.linspace(
299 zeniths = numpy.linspace(
300 0, self.data.meta['max_range'], data.shape[1])
300 0, self.data.meta['max_range'], data.shape[1])
301 if self.mode == 'E':
301 if self.mode == 'E':
302 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
302 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
303 r, theta = numpy.meshgrid(zeniths, azimuths)
303 r, theta = numpy.meshgrid(zeniths, azimuths)
304 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
304 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
305 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
305 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
306 x = km2deg(x) + self.lon
306 x = km2deg(x) + self.lon
307 y = km2deg(y) + self.lat
307 y = km2deg(y) + self.lat
308 else:
308 else:
309 azimuths = numpy.radians(self.data.yrange)
309 azimuths = numpy.radians(self.data.yrange)
310 r, theta = numpy.meshgrid(zeniths, azimuths)
310 r, theta = numpy.meshgrid(zeniths, azimuths)
311 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
311 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
312 self.y = zeniths
312 self.y = zeniths
313
313
314 if ax.firsttime:
314 if ax.firsttime:
315 if self.zlimits is not None:
315 if self.zlimits is not None:
316 self.zmin, self.zmax = self.zlimits[n]
316 self.zmin, self.zmax = self.zlimits[n]
317 ax.plt = ax.pcolormesh(# r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
317 ax.plt = ax.pcolormesh(# r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
318 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
318 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
319 vmin=self.zmin,
319 vmin=self.zmin,
320 vmax=self.zmax,
320 vmax=self.zmax,
321 cmap=self.cmaps[n])
321 cmap=self.cmaps[n])
322 else:
322 else:
323 if self.zlimits is not None:
323 if self.zlimits is not None:
324 self.zmin, self.zmax = self.zlimits[n]
324 self.zmin, self.zmax = self.zlimits[n]
325 ax.collections.remove(ax.collections[0])
325 ax.collections.remove(ax.collections[0])
326 ax.plt = ax.pcolormesh(# r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
326 ax.plt = ax.pcolormesh(# r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
327 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
327 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
328 vmin=self.zmin,
328 vmin=self.zmin,
329 vmax=self.zmax,
329 vmax=self.zmax,
330 cmap=self.cmaps[n])
330 cmap=self.cmaps[n])
331
331
332 if self.mode == 'A':
332 if self.mode == 'A':
333 continue
333 continue
334
334
335 # plot district names
335 # plot district names
336 f = open('/data/workspace/schain_scripts/distrito.csv')
336 f = open('/data/workspace/schain_scripts/distrito.csv')
337 for line in f:
337 for line in f:
338 label, lon, lat = [s.strip() for s in line.split(',') if s]
338 label, lon, lat = [s.strip() for s in line.split(',') if s]
339 lat = float(lat)
339 lat = float(lat)
340 lon = float(lon)
340 lon = float(lon)
341 # ax.plot(lon, lat, '.b', ms=2)
341 # ax.plot(lon, lat, '.b', ms=2)
342 ax.text(lon, lat, label.decode('utf8'), ha='center',
342 ax.text(lon, lat, label.decode('utf8'), ha='center',
343 va='bottom', size='8', color='black')
343 va='bottom', size='8', color='black')
344
344
345 # plot limites
345 # plot limites
346 limites = []
346 limites = []
347 tmp = []
347 tmp = []
348 for line in open('/data/workspace/schain_scripts/lima.csv'):
348 for line in open('/data/workspace/schain_scripts/lima.csv'):
349 if '#' in line:
349 if '#' in line:
350 if tmp:
350 if tmp:
351 limites.append(tmp)
351 limites.append(tmp)
352 tmp = []
352 tmp = []
353 continue
353 continue
354 values = line.strip().split(',')
354 values = line.strip().split(',')
355 tmp.append((float(values[0]), float(values[1])))
355 tmp.append((float(values[0]), float(values[1])))
356 for points in limites:
356 for points in limites:
357 ax.add_patch(
357 ax.add_patch(
358 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
358 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
359
359
360 # plot Cuencas
360 # plot Cuencas
361 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
361 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
362 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
362 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
363 values = [line.strip().split(',') for line in f]
363 values = [line.strip().split(',') for line in f]
364 points = [(float(s[0]), float(s[1])) for s in values]
364 points = [(float(s[0]), float(s[1])) for s in values]
365 ax.add_patch(Polygon(points, ec='b', fc='none'))
365 ax.add_patch(Polygon(points, ec='b', fc='none'))
366
366
367 # plot grid
367 # plot grid
368 for r in (15, 30, 45, 60):
368 for r in (15, 30, 45, 60):
369 ax.add_artist(plt.Circle((self.lon, self.lat),
369 ax.add_artist(plt.Circle((self.lon, self.lat),
370 km2deg(r), color='0.6', fill=False, lw=0.2))
370 km2deg(r), color='0.6', fill=False, lw=0.2))
371 ax.text(
371 ax.text(
372 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
372 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
373 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
373 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
374 '{}km'.format(r),
374 '{}km'.format(r),
375 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
375 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
376
376
377 if self.mode == 'E':
377 if self.mode == 'E':
378 title = 'El={}\N{DEGREE SIGN}'.format(self.data.meta['elevation'])
378 title = 'El={}\N{DEGREE SIGN}'.format(self.data.meta['elevation'])
379 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
379 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
380 else:
380 else:
381 title = 'Az={}\N{DEGREE SIGN}'.format(self.data.meta['azimuth'])
381 title = 'Az={}\N{DEGREE SIGN}'.format(self.data.meta['azimuth'])
382 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
382 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
383
383
384 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
384 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
385 self.titles = ['{} {}'.format(
385 self.titles = ['{} {}'.format(
386 self.data.parameters[x], title) for x in self.channels]
386 self.data.parameters[x], title) for x in self.channels]
387
387
388
388
389
389
390 class TxPowerPlot(Plot):
390 class TxPowerPlot(Plot):
391 '''
391 '''
392 Plot for TX Power from external file
392 Plot for TX Power from external file
393 '''
393 '''
394
394
395 CODE = 'tx_power'
395 CODE = 'tx_power'
396 plot_type = 'scatterbuffer'
396 plot_type = 'scatterbuffer'
397
397
398 def setup(self):
398 def setup(self):
399 self.xaxis = 'time'
399 self.xaxis = 'time'
400 self.ncols = 1
400 self.ncols = 1
401 self.nrows = 1
401 self.nrows = 1
402 self.nplots = 1
402 self.nplots = 1
403 self.ylabel = 'Power [kW]'
403 self.ylabel = 'Power [kW]'
404 self.xlabel = 'Time'
404 self.xlabel = 'Time'
405 self.titles = ['TX power']
405 self.titles = ['TX power']
406 self.colorbar = False
406 self.colorbar = False
407 self.plots_adjust.update({'right': 0.85 })
407 self.plots_adjust.update({'right': 0.85 })
408 #if not self.titles:
408 #if not self.titles:
409 self.titles = ['TX Power Plot']
409 self.titles = ['TX Power Plot']
410
410
411 def update(self, dataOut):
411 def update(self, dataOut):
412
412
413 data = {}
413 data = {}
414 meta = {}
414 meta = {}
415
415
416 data['tx_power'] = dataOut.txPower/1000
416 data['tx_power'] = dataOut.txPower/1000
417 meta['yrange'] = numpy.array([])
417 meta['yrange'] = numpy.array([])
418 #print(dataOut.txPower/1000)
418 #print(dataOut.txPower/1000)
419 return data, meta
419 return data, meta
420
420
421 def plot(self):
421 def plot(self):
422
422
423 x = self.data.times
423 x = self.data.times
424 xmin = self.data.min_time
424 xmin = self.data.min_time
425 xmax = xmin + self.xrange * 60 * 60
425 xmax = xmin + self.xrange * 60 * 60
426 Y = self.data['tx_power']
426 Y = self.data['tx_power']
427
427
428 if self.axes[0].firsttime:
428 if self.axes[0].firsttime:
429 if self.ymin is None: self.ymin = 0
429 if self.ymin is None: self.ymin = 0
430 if self.ymax is None: self.ymax = numpy.nanmax(Y) + 5
430 if self.ymax is None: self.ymax = numpy.nanmax(Y) + 5
431 if self.ymax == 5:
431 if self.ymax == 5:
432 self.ymax = 250
432 self.ymax = 250
433 self.ymin = 100
433 self.ymin = 100
434 self.axes[0].plot(x, Y, lw=1, label='Power')
434 self.axes[0].plot(x, Y, lw=1, label='Power')
435 plt.legend(bbox_to_anchor=(1.18, 1.0))
435 plt.legend(bbox_to_anchor=(1.18, 1.0))
436 else:
436 else:
437 self.axes[0].lines[0].set_data(x, Y) No newline at end of file
437 self.axes[0].lines[0].set_data(x, Y)
@@ -1,1935 +1,1934
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 datetime
11 import datetime
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 from itertools import combinations
14 from itertools import combinations
15 from matplotlib.ticker import LinearLocator
15 from matplotlib.ticker import LinearLocator
16
16
17 from schainpy.model.utils.BField import BField
17 from schainpy.model.utils.BField import BField
18 from scipy.interpolate import splrep
18 from scipy.interpolate import splrep
19 from scipy.interpolate import splev
19 from scipy.interpolate import splev
20
20
21 from matplotlib import __version__ as plt_version
21 from matplotlib import __version__ as plt_version
22
22
23 if plt_version >='3.3.4':
23 if plt_version >='3.3.4':
24 EXTRA_POINTS = 0
24 EXTRA_POINTS = 0
25 else:
25 else:
26 EXTRA_POINTS = 1
26 EXTRA_POINTS = 1
27 class SpectraPlot(Plot):
27 class SpectraPlot(Plot):
28 '''
28 '''
29 Plot for Spectra data
29 Plot for Spectra data
30 '''
30 '''
31
31
32 CODE = 'spc'
32 CODE = 'spc'
33 colormap = 'jet'
33 colormap = 'jet'
34 plot_type = 'pcolor'
34 plot_type = 'pcolor'
35 buffering = False
35 buffering = False
36 channelList = []
36 channelList = []
37 elevationList = []
37 elevationList = []
38 azimuthList = []
38 azimuthList = []
39
39
40 def setup(self):
40 def setup(self):
41
41
42 self.nplots = len(self.data.channels)
42 self.nplots = len(self.data.channels)
43 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
43 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
44 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
44 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
45 self.height = 3.4 * self.nrows
45 self.height = 3.4 * self.nrows
46 self.cb_label = 'dB'
46 self.cb_label = 'dB'
47 if self.showprofile:
47 if self.showprofile:
48 self.width = 5.2 * self.ncols
48 self.width = 5.2 * self.ncols
49 else:
49 else:
50 self.width = 4.2* self.ncols
50 self.width = 4.2* self.ncols
51 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.12})
51 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.12})
52 self.ylabel = 'Range [km]'
52 self.ylabel = 'Range [km]'
53
53
54 def update_list(self,dataOut):
54 def update_list(self,dataOut):
55
55
56 if len(self.channelList) == 0:
56 if len(self.channelList) == 0:
57 self.channelList = dataOut.channelList
57 self.channelList = dataOut.channelList
58 if len(self.elevationList) == 0:
58 if len(self.elevationList) == 0:
59 self.elevationList = dataOut.elevationList
59 self.elevationList = dataOut.elevationList
60 if len(self.azimuthList) == 0:
60 if len(self.azimuthList) == 0:
61 self.azimuthList = dataOut.azimuthList
61 self.azimuthList = dataOut.azimuthList
62
62
63 def update(self, dataOut):
63 def update(self, dataOut):
64
64
65 self.update_list(dataOut)
65 self.update_list(dataOut)
66 data = {}
66 data = {}
67 meta = {}
67 meta = {}
68 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
68 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
69 if dataOut.type == "Parameters":
69 if dataOut.type == "Parameters":
70 noise = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
70 noise = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
71 spc = 10*numpy.log10(dataOut.data_spc/(dataOut.nProfiles))
71 spc = 10*numpy.log10(dataOut.data_spc/(dataOut.nProfiles))
72 else:
72 else:
73 noise = 10*numpy.log10(dataOut.getNoise()/norm)
73 noise = 10*numpy.log10(dataOut.getNoise()/norm)
74
74
75 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
75 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
76 for ch in range(dataOut.nChannels):
76 for ch in range(dataOut.nChannels):
77 if hasattr(dataOut.normFactor,'ndim'):
77 if hasattr(dataOut.normFactor,'ndim'):
78 if dataOut.normFactor.ndim > 1:
78 if dataOut.normFactor.ndim > 1:
79 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
79 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
80
80
81 else:
81 else:
82 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
82 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
83 else:
83 else:
84 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
84 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
85
85
86 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
86 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
87 spc = 10*numpy.log10(z)
87 spc = 10*numpy.log10(z)
88
88
89 data['spc'] = spc
89 data['spc'] = spc
90 data['rti'] = spc.mean(axis=1)
90 data['rti'] = spc.mean(axis=1)
91 data['noise'] = noise
91 data['noise'] = noise
92 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
92 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
93 if self.CODE == 'spc_moments':
93 if self.CODE == 'spc_moments':
94 data['moments'] = dataOut.moments
94 data['moments'] = dataOut.moments
95
95
96 return data, meta
96 return data, meta
97
97
98 def plot(self):
98 def plot(self):
99
99
100 if self.xaxis == "frequency":
100 if self.xaxis == "frequency":
101 x = self.data.xrange[0]
101 x = self.data.xrange[0]
102 self.xlabel = "Frequency (kHz)"
102 self.xlabel = "Frequency (kHz)"
103 elif self.xaxis == "time":
103 elif self.xaxis == "time":
104 x = self.data.xrange[1]
104 x = self.data.xrange[1]
105 self.xlabel = "Time (ms)"
105 self.xlabel = "Time (ms)"
106 else:
106 else:
107 x = self.data.xrange[2]
107 x = self.data.xrange[2]
108 self.xlabel = "Velocity (m/s)"
108 self.xlabel = "Velocity (m/s)"
109
109
110 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
110 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
111 x = self.data.xrange[2]
111 x = self.data.xrange[2]
112 self.xlabel = "Velocity (m/s)"
112 self.xlabel = "Velocity (m/s)"
113
113
114 self.titles = []
114 self.titles = []
115
115
116 y = self.data.yrange
116 y = self.data.yrange
117 self.y = y
117 self.y = y
118
118
119 data = self.data[-1]
119 data = self.data[-1]
120 z = data['spc']
120 z = data['spc']
121
121
122 for n, ax in enumerate(self.axes):
122 for n, ax in enumerate(self.axes):
123 noise = self.data['noise'][n][0]
123 noise = self.data['noise'][n][0]
124 # noise = data['noise'][n]
124 # noise = data['noise'][n]
125
125
126 if self.CODE == 'spc_moments':
126 if self.CODE == 'spc_moments':
127 mean = data['moments'][n, 1]
127 mean = data['moments'][n, 1]
128 if self.CODE == 'gaussian_fit':
128 if self.CODE == 'gaussian_fit':
129 gau0 = data['gaussfit'][n][2,:,0]
129 gau0 = data['gaussfit'][n][2,:,0]
130 gau1 = data['gaussfit'][n][2,:,1]
130 gau1 = data['gaussfit'][n][2,:,1]
131 if ax.firsttime:
131 if ax.firsttime:
132 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
132 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
133 self.xmin = self.xmin if self.xmin else -self.xmax
133 self.xmin = self.xmin if self.xmin else -self.xmax
134 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
134 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
135 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
135 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
136 ax.plt = ax.pcolormesh(x, y, z[n].T,
136 ax.plt = ax.pcolormesh(x, y, z[n].T,
137 vmin=self.zmin,
137 vmin=self.zmin,
138 vmax=self.zmax,
138 vmax=self.zmax,
139 cmap=plt.get_cmap(self.colormap)
139 cmap=plt.get_cmap(self.colormap)
140 )
140 )
141
141
142 if self.showprofile:
142 if self.showprofile:
143 ax.plt_profile = self.pf_axes[n].plot(
143 ax.plt_profile = self.pf_axes[n].plot(
144 data['rti'][n], y)[0]
144 data['rti'][n], y)[0]
145 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
145 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
146 color="k", linestyle="dashed", lw=1)[0]
146 color="k", linestyle="dashed", lw=1)[0]
147 if self.CODE == 'spc_moments':
147 if self.CODE == 'spc_moments':
148 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
148 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
149 if self.CODE == 'gaussian_fit':
149 if self.CODE == 'gaussian_fit':
150 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
150 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
151 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
151 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
152 else:
152 else:
153 ax.plt.set_array(z[n].T.ravel())
153 ax.plt.set_array(z[n].T.ravel())
154 if self.showprofile:
154 if self.showprofile:
155 ax.plt_profile.set_data(data['rti'][n], y)
155 ax.plt_profile.set_data(data['rti'][n], y)
156 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
156 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
157 if self.CODE == 'spc_moments':
157 if self.CODE == 'spc_moments':
158 ax.plt_mean.set_data(mean, y)
158 ax.plt_mean.set_data(mean, y)
159 if self.CODE == 'gaussian_fit':
159 if self.CODE == 'gaussian_fit':
160 ax.plt_gau0.set_data(gau0, y)
160 ax.plt_gau0.set_data(gau0, y)
161 ax.plt_gau1.set_data(gau1, y)
161 ax.plt_gau1.set_data(gau1, y)
162 if len(self.azimuthList) > 0 and len(self.elevationList) > 0:
162 if len(self.azimuthList) > 0 and len(self.elevationList) > 0:
163 self.titles.append('CH {}: {:2.1f}elv {:2.1f}az {:3.2f}dB'.format(self.channelList[n], noise, self.elevationList[n], self.azimuthList[n]))
163 self.titles.append('CH {}: {:2.1f}elv {:2.1f}az {:3.2f}dB'.format(self.channelList[n], noise, self.elevationList[n], self.azimuthList[n]))
164 else:
164 else:
165 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
165 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
166
166
167 class SpectraObliquePlot(Plot):
167 class SpectraObliquePlot(Plot):
168 '''
168 '''
169 Plot for Spectra data
169 Plot for Spectra data
170 '''
170 '''
171
171
172 CODE = 'spc_oblique'
172 CODE = 'spc_oblique'
173 colormap = 'jet'
173 colormap = 'jet'
174 plot_type = 'pcolor'
174 plot_type = 'pcolor'
175
175
176 def setup(self):
176 def setup(self):
177 self.xaxis = "oblique"
177 self.xaxis = "oblique"
178 self.nplots = len(self.data.channels)
178 self.nplots = len(self.data.channels)
179 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
179 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
180 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
180 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
181 self.height = 2.6 * self.nrows
181 self.height = 2.6 * self.nrows
182 self.cb_label = 'dB'
182 self.cb_label = 'dB'
183 if self.showprofile:
183 if self.showprofile:
184 self.width = 4 * self.ncols
184 self.width = 4 * self.ncols
185 else:
185 else:
186 self.width = 3.5 * self.ncols
186 self.width = 3.5 * self.ncols
187 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
187 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
188 self.ylabel = 'Range [km]'
188 self.ylabel = 'Range [km]'
189
189
190 def update(self, dataOut):
190 def update(self, dataOut):
191
191
192 data = {}
192 data = {}
193 meta = {}
193 meta = {}
194
194
195 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
195 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
196 data['spc'] = spc
196 data['spc'] = spc
197 data['rti'] = dataOut.getPower()
197 data['rti'] = dataOut.getPower()
198 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
198 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
199 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
199 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
200
200
201 data['shift1'] = dataOut.Dop_EEJ_T1[0]
201 data['shift1'] = dataOut.Dop_EEJ_T1[0]
202 data['shift2'] = dataOut.Dop_EEJ_T2[0]
202 data['shift2'] = dataOut.Dop_EEJ_T2[0]
203 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
203 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
204 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
204 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
205 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
205 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
206
206
207 return data, meta
207 return data, meta
208
208
209 def plot(self):
209 def plot(self):
210
210
211 if self.xaxis == "frequency":
211 if self.xaxis == "frequency":
212 x = self.data.xrange[0]
212 x = self.data.xrange[0]
213 self.xlabel = "Frequency (kHz)"
213 self.xlabel = "Frequency (kHz)"
214 elif self.xaxis == "time":
214 elif self.xaxis == "time":
215 x = self.data.xrange[1]
215 x = self.data.xrange[1]
216 self.xlabel = "Time (ms)"
216 self.xlabel = "Time (ms)"
217 else:
217 else:
218 x = self.data.xrange[2]
218 x = self.data.xrange[2]
219 self.xlabel = "Velocity (m/s)"
219 self.xlabel = "Velocity (m/s)"
220
220
221 self.titles = []
221 self.titles = []
222
222
223 y = self.data.yrange
223 y = self.data.yrange
224 self.y = y
224 self.y = y
225
225
226 data = self.data[-1]
226 data = self.data[-1]
227 z = data['spc']
227 z = data['spc']
228
228
229 for n, ax in enumerate(self.axes):
229 for n, ax in enumerate(self.axes):
230 noise = self.data['noise'][n][-1]
230 noise = self.data['noise'][n][-1]
231 shift1 = data['shift1']
231 shift1 = data['shift1']
232 shift2 = data['shift2']
232 shift2 = data['shift2']
233 max_val_2 = data['max_val_2']
233 max_val_2 = data['max_val_2']
234 err1 = data['shift1_error']
234 err1 = data['shift1_error']
235 err2 = data['shift2_error']
235 err2 = data['shift2_error']
236 if ax.firsttime:
236 if ax.firsttime:
237
237
238 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
238 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
239 self.xmin = self.xmin if self.xmin else -self.xmax
239 self.xmin = self.xmin if self.xmin else -self.xmax
240 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
240 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
241 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
241 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
242 ax.plt = ax.pcolormesh(x, y, z[n].T,
242 ax.plt = ax.pcolormesh(x, y, z[n].T,
243 vmin=self.zmin,
243 vmin=self.zmin,
244 vmax=self.zmax,
244 vmax=self.zmax,
245 cmap=plt.get_cmap(self.colormap)
245 cmap=plt.get_cmap(self.colormap)
246 )
246 )
247
247
248 if self.showprofile:
248 if self.showprofile:
249 ax.plt_profile = self.pf_axes[n].plot(
249 ax.plt_profile = self.pf_axes[n].plot(
250 self.data['rti'][n][-1], y)[0]
250 self.data['rti'][n][-1], y)[0]
251 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
251 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
252 color="k", linestyle="dashed", lw=1)[0]
252 color="k", linestyle="dashed", lw=1)[0]
253
253
254 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)
254 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)
255 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)
255 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)
256 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)
256 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)
257
257
258 else:
258 else:
259 self.ploterr1.remove()
259 self.ploterr1.remove()
260 self.ploterr2.remove()
260 self.ploterr2.remove()
261 self.ploterr3.remove()
261 self.ploterr3.remove()
262 ax.plt.set_array(z[n].T.ravel())
262 ax.plt.set_array(z[n].T.ravel())
263 if self.showprofile:
263 if self.showprofile:
264 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
264 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
265 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
265 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
266 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)
266 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)
267 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)
267 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)
268 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)
268 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)
269
269
270 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
270 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
271
271
272
272
273 class CrossSpectraPlot(Plot):
273 class CrossSpectraPlot(Plot):
274
274
275 CODE = 'cspc'
275 CODE = 'cspc'
276 colormap = 'jet'
276 colormap = 'jet'
277 plot_type = 'pcolor'
277 plot_type = 'pcolor'
278 zmin_coh = None
278 zmin_coh = None
279 zmax_coh = None
279 zmax_coh = None
280 zmin_phase = None
280 zmin_phase = None
281 zmax_phase = None
281 zmax_phase = None
282 realChannels = None
282 realChannels = None
283 crossPairs = None
283 crossPairs = None
284
284
285 def setup(self):
285 def setup(self):
286
286
287 self.ncols = 4
287 self.ncols = 4
288 self.nplots = len(self.data.pairs) * 2
288 self.nplots = len(self.data.pairs) * 2
289 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
289 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
290 self.width = 3.1 * self.ncols
290 self.width = 3.1 * self.ncols
291 self.height = 2.6 * self.nrows
291 self.height = 2.6 * self.nrows
292 self.ylabel = 'Range [km]'
292 self.ylabel = 'Range [km]'
293 self.showprofile = False
293 self.showprofile = False
294 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
294 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
295
295
296 def update(self, dataOut):
296 def update(self, dataOut):
297
297
298 data = {}
298 data = {}
299 meta = {}
299 meta = {}
300
300
301 spc = dataOut.data_spc
301 spc = dataOut.data_spc
302 cspc = dataOut.data_cspc
302 cspc = dataOut.data_cspc
303 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
303 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
304 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
304 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
305 meta['pairs'] = rawPairs
305 meta['pairs'] = rawPairs
306 if self.crossPairs == None:
306 if self.crossPairs == None:
307 self.crossPairs = dataOut.pairsList
307 self.crossPairs = dataOut.pairsList
308 tmp = []
308 tmp = []
309
309
310 for n, pair in enumerate(meta['pairs']):
310 for n, pair in enumerate(meta['pairs']):
311 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
311 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
312 coh = numpy.abs(out)
312 coh = numpy.abs(out)
313 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
313 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
314 tmp.append(coh)
314 tmp.append(coh)
315 tmp.append(phase)
315 tmp.append(phase)
316
316
317 data['cspc'] = numpy.array(tmp)
317 data['cspc'] = numpy.array(tmp)
318
318
319 return data, meta
319 return data, meta
320
320
321 def plot(self):
321 def plot(self):
322
322
323 if self.xaxis == "frequency":
323 if self.xaxis == "frequency":
324 x = self.data.xrange[0]
324 x = self.data.xrange[0]
325 self.xlabel = "Frequency (kHz)"
325 self.xlabel = "Frequency (kHz)"
326 elif self.xaxis == "time":
326 elif self.xaxis == "time":
327 x = self.data.xrange[1]
327 x = self.data.xrange[1]
328 self.xlabel = "Time (ms)"
328 self.xlabel = "Time (ms)"
329 else:
329 else:
330 x = self.data.xrange[2]
330 x = self.data.xrange[2]
331 self.xlabel = "Velocity (m/s)"
331 self.xlabel = "Velocity (m/s)"
332
332
333 self.titles = []
333 self.titles = []
334
334
335 y = self.data.yrange
335 y = self.data.yrange
336 self.y = y
336 self.y = y
337
337
338 data = self.data[-1]
338 data = self.data[-1]
339 cspc = data['cspc']
339 cspc = data['cspc']
340
340
341 for n in range(len(self.data.pairs)):
341 for n in range(len(self.data.pairs)):
342 pair = self.crossPairs[n]
342 pair = self.crossPairs[n]
343 coh = cspc[n*2]
343 coh = cspc[n*2]
344 phase = cspc[n*2+1]
344 phase = cspc[n*2+1]
345 ax = self.axes[2 * n]
345 ax = self.axes[2 * n]
346 if ax.firsttime:
346 if ax.firsttime:
347 ax.plt = ax.pcolormesh(x, y, coh.T,
347 ax.plt = ax.pcolormesh(x, y, coh.T,
348 vmin=self.zmin_coh,
348 vmin=self.zmin_coh,
349 vmax=self.zmax_coh,
349 vmax=self.zmax_coh,
350 cmap=plt.get_cmap(self.colormap_coh)
350 cmap=plt.get_cmap(self.colormap_coh)
351 )
351 )
352 else:
352 else:
353 ax.plt.set_array(coh.T.ravel())
353 ax.plt.set_array(coh.T.ravel())
354 self.titles.append(
354 self.titles.append(
355 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
355 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
356
356
357 ax = self.axes[2 * n + 1]
357 ax = self.axes[2 * n + 1]
358 if ax.firsttime:
358 if ax.firsttime:
359 ax.plt = ax.pcolormesh(x, y, phase.T,
359 ax.plt = ax.pcolormesh(x, y, phase.T,
360 vmin=-180,
360 vmin=-180,
361 vmax=180,
361 vmax=180,
362 cmap=plt.get_cmap(self.colormap_phase)
362 cmap=plt.get_cmap(self.colormap_phase)
363 )
363 )
364 else:
364 else:
365 ax.plt.set_array(phase.T.ravel())
365 ax.plt.set_array(phase.T.ravel())
366 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
366 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
367
367
368
368
369 class CrossSpectra4Plot(Plot):
369 class CrossSpectra4Plot(Plot):
370
370
371 CODE = 'cspc'
371 CODE = 'cspc'
372 colormap = 'jet'
372 colormap = 'jet'
373 plot_type = 'pcolor'
373 plot_type = 'pcolor'
374 zmin_coh = None
374 zmin_coh = None
375 zmax_coh = None
375 zmax_coh = None
376 zmin_phase = None
376 zmin_phase = None
377 zmax_phase = None
377 zmax_phase = None
378
378
379 def setup(self):
379 def setup(self):
380
380
381 self.ncols = 4
381 self.ncols = 4
382 self.nrows = len(self.data.pairs)
382 self.nrows = len(self.data.pairs)
383 self.nplots = self.nrows * 4
383 self.nplots = self.nrows * 4
384 self.width = 3.1 * self.ncols
384 self.width = 3.1 * self.ncols
385 self.height = 5 * self.nrows
385 self.height = 5 * self.nrows
386 self.ylabel = 'Range [km]'
386 self.ylabel = 'Range [km]'
387 self.showprofile = False
387 self.showprofile = False
388 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
388 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
389
389
390 def plot(self):
390 def plot(self):
391
391
392 if self.xaxis == "frequency":
392 if self.xaxis == "frequency":
393 x = self.data.xrange[0]
393 x = self.data.xrange[0]
394 self.xlabel = "Frequency (kHz)"
394 self.xlabel = "Frequency (kHz)"
395 elif self.xaxis == "time":
395 elif self.xaxis == "time":
396 x = self.data.xrange[1]
396 x = self.data.xrange[1]
397 self.xlabel = "Time (ms)"
397 self.xlabel = "Time (ms)"
398 else:
398 else:
399 x = self.data.xrange[2]
399 x = self.data.xrange[2]
400 self.xlabel = "Velocity (m/s)"
400 self.xlabel = "Velocity (m/s)"
401
401
402 self.titles = []
402 self.titles = []
403
403
404
404
405 y = self.data.heights
405 y = self.data.heights
406 self.y = y
406 self.y = y
407 nspc = self.data['spc']
407 nspc = self.data['spc']
408 spc = self.data['cspc'][0]
408 spc = self.data['cspc'][0]
409 cspc = self.data['cspc'][1]
409 cspc = self.data['cspc'][1]
410
410
411 for n in range(self.nrows):
411 for n in range(self.nrows):
412 noise = self.data['noise'][:,-1]
412 noise = self.data['noise'][:,-1]
413 pair = self.data.pairs[n]
413 pair = self.data.pairs[n]
414
414
415 ax = self.axes[4 * n]
415 ax = self.axes[4 * n]
416 if ax.firsttime:
416 if ax.firsttime:
417 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
417 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
418 self.xmin = self.xmin if self.xmin else -self.xmax
418 self.xmin = self.xmin if self.xmin else -self.xmax
419 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
419 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
420 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
420 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
421 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
421 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
422 vmin=self.zmin,
422 vmin=self.zmin,
423 vmax=self.zmax,
423 vmax=self.zmax,
424 cmap=plt.get_cmap(self.colormap)
424 cmap=plt.get_cmap(self.colormap)
425 )
425 )
426 else:
426 else:
427
427
428 ax.plt.set_array(nspc[pair[0]].T.ravel())
428 ax.plt.set_array(nspc[pair[0]].T.ravel())
429 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
429 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
430
430
431 ax = self.axes[4 * n + 1]
431 ax = self.axes[4 * n + 1]
432
432
433 if ax.firsttime:
433 if ax.firsttime:
434 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
434 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
435 vmin=self.zmin,
435 vmin=self.zmin,
436 vmax=self.zmax,
436 vmax=self.zmax,
437 cmap=plt.get_cmap(self.colormap)
437 cmap=plt.get_cmap(self.colormap)
438 )
438 )
439 else:
439 else:
440
440
441 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
441 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
442 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
442 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
443
443
444 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
444 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
445 coh = numpy.abs(out)
445 coh = numpy.abs(out)
446 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
446 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
447
447
448 ax = self.axes[4 * n + 2]
448 ax = self.axes[4 * n + 2]
449 if ax.firsttime:
449 if ax.firsttime:
450 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
450 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
451 vmin=0,
451 vmin=0,
452 vmax=1,
452 vmax=1,
453 cmap=plt.get_cmap(self.colormap_coh)
453 cmap=plt.get_cmap(self.colormap_coh)
454 )
454 )
455 else:
455 else:
456 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
456 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
457 self.titles.append(
457 self.titles.append(
458 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
458 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
459
459
460 ax = self.axes[4 * n + 3]
460 ax = self.axes[4 * n + 3]
461 if ax.firsttime:
461 if ax.firsttime:
462 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
462 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
463 vmin=-180,
463 vmin=-180,
464 vmax=180,
464 vmax=180,
465 cmap=plt.get_cmap(self.colormap_phase)
465 cmap=plt.get_cmap(self.colormap_phase)
466 )
466 )
467 else:
467 else:
468 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
468 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
469 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
469 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
470
470
471
471
472 class CrossSpectra2Plot(Plot):
472 class CrossSpectra2Plot(Plot):
473
473
474 CODE = 'cspc'
474 CODE = 'cspc'
475 colormap = 'jet'
475 colormap = 'jet'
476 plot_type = 'pcolor'
476 plot_type = 'pcolor'
477 zmin_coh = None
477 zmin_coh = None
478 zmax_coh = None
478 zmax_coh = None
479 zmin_phase = None
479 zmin_phase = None
480 zmax_phase = None
480 zmax_phase = None
481
481
482 def setup(self):
482 def setup(self):
483
483
484 self.ncols = 1
484 self.ncols = 1
485 self.nrows = len(self.data.pairs)
485 self.nrows = len(self.data.pairs)
486 self.nplots = self.nrows * 1
486 self.nplots = self.nrows * 1
487 self.width = 3.1 * self.ncols
487 self.width = 3.1 * self.ncols
488 self.height = 5 * self.nrows
488 self.height = 5 * self.nrows
489 self.ylabel = 'Range [km]'
489 self.ylabel = 'Range [km]'
490 self.showprofile = False
490 self.showprofile = False
491 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
491 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
492
492
493 def plot(self):
493 def plot(self):
494
494
495 if self.xaxis == "frequency":
495 if self.xaxis == "frequency":
496 x = self.data.xrange[0]
496 x = self.data.xrange[0]
497 self.xlabel = "Frequency (kHz)"
497 self.xlabel = "Frequency (kHz)"
498 elif self.xaxis == "time":
498 elif self.xaxis == "time":
499 x = self.data.xrange[1]
499 x = self.data.xrange[1]
500 self.xlabel = "Time (ms)"
500 self.xlabel = "Time (ms)"
501 else:
501 else:
502 x = self.data.xrange[2]
502 x = self.data.xrange[2]
503 self.xlabel = "Velocity (m/s)"
503 self.xlabel = "Velocity (m/s)"
504
504
505 self.titles = []
505 self.titles = []
506
506
507
507
508 y = self.data.heights
508 y = self.data.heights
509 self.y = y
509 self.y = y
510 cspc = self.data['cspc'][1]
510 cspc = self.data['cspc'][1]
511
511
512 for n in range(self.nrows):
512 for n in range(self.nrows):
513 noise = self.data['noise'][:,-1]
513 noise = self.data['noise'][:,-1]
514 pair = self.data.pairs[n]
514 pair = self.data.pairs[n]
515 out = cspc[n]
515 out = cspc[n]
516 cross = numpy.abs(out)
516 cross = numpy.abs(out)
517 z = cross/self.data.nFactor
517 z = cross/self.data.nFactor
518 cross = 10*numpy.log10(z)
518 cross = 10*numpy.log10(z)
519
519
520 ax = self.axes[1 * n]
520 ax = self.axes[1 * n]
521 if ax.firsttime:
521 if ax.firsttime:
522 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
522 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
523 self.xmin = self.xmin if self.xmin else -self.xmax
523 self.xmin = self.xmin if self.xmin else -self.xmax
524 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
524 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
525 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
525 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
526 ax.plt = ax.pcolormesh(x, y, cross.T,
526 ax.plt = ax.pcolormesh(x, y, cross.T,
527 vmin=self.zmin,
527 vmin=self.zmin,
528 vmax=self.zmax,
528 vmax=self.zmax,
529 cmap=plt.get_cmap(self.colormap)
529 cmap=plt.get_cmap(self.colormap)
530 )
530 )
531 else:
531 else:
532 ax.plt.set_array(cross.T.ravel())
532 ax.plt.set_array(cross.T.ravel())
533 self.titles.append(
533 self.titles.append(
534 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
534 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
535
535
536
536
537 class CrossSpectra3Plot(Plot):
537 class CrossSpectra3Plot(Plot):
538
538
539 CODE = 'cspc'
539 CODE = 'cspc'
540 colormap = 'jet'
540 colormap = 'jet'
541 plot_type = 'pcolor'
541 plot_type = 'pcolor'
542 zmin_coh = None
542 zmin_coh = None
543 zmax_coh = None
543 zmax_coh = None
544 zmin_phase = None
544 zmin_phase = None
545 zmax_phase = None
545 zmax_phase = None
546
546
547 def setup(self):
547 def setup(self):
548
548
549 self.ncols = 3
549 self.ncols = 3
550 self.nrows = len(self.data.pairs)
550 self.nrows = len(self.data.pairs)
551 self.nplots = self.nrows * 3
551 self.nplots = self.nrows * 3
552 self.width = 3.1 * self.ncols
552 self.width = 3.1 * self.ncols
553 self.height = 5 * self.nrows
553 self.height = 5 * self.nrows
554 self.ylabel = 'Range [km]'
554 self.ylabel = 'Range [km]'
555 self.showprofile = False
555 self.showprofile = False
556 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
556 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
557
557
558 def plot(self):
558 def plot(self):
559
559
560 if self.xaxis == "frequency":
560 if self.xaxis == "frequency":
561 x = self.data.xrange[0]
561 x = self.data.xrange[0]
562 self.xlabel = "Frequency (kHz)"
562 self.xlabel = "Frequency (kHz)"
563 elif self.xaxis == "time":
563 elif self.xaxis == "time":
564 x = self.data.xrange[1]
564 x = self.data.xrange[1]
565 self.xlabel = "Time (ms)"
565 self.xlabel = "Time (ms)"
566 else:
566 else:
567 x = self.data.xrange[2]
567 x = self.data.xrange[2]
568 self.xlabel = "Velocity (m/s)"
568 self.xlabel = "Velocity (m/s)"
569
569
570 self.titles = []
570 self.titles = []
571
571
572
572
573 y = self.data.heights
573 y = self.data.heights
574 self.y = y
574 self.y = y
575
575
576 cspc = self.data['cspc'][1]
576 cspc = self.data['cspc'][1]
577
577
578 for n in range(self.nrows):
578 for n in range(self.nrows):
579 noise = self.data['noise'][:,-1]
579 noise = self.data['noise'][:,-1]
580 pair = self.data.pairs[n]
580 pair = self.data.pairs[n]
581 out = cspc[n]
581 out = cspc[n]
582
582
583 cross = numpy.abs(out)
583 cross = numpy.abs(out)
584 z = cross/self.data.nFactor
584 z = cross/self.data.nFactor
585 cross = 10*numpy.log10(z)
585 cross = 10*numpy.log10(z)
586
586
587 out_r= out.real/self.data.nFactor
587 out_r= out.real/self.data.nFactor
588
588
589 out_i= out.imag/self.data.nFactor
589 out_i= out.imag/self.data.nFactor
590
590
591 ax = self.axes[3 * n]
591 ax = self.axes[3 * n]
592 if ax.firsttime:
592 if ax.firsttime:
593 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
593 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
594 self.xmin = self.xmin if self.xmin else -self.xmax
594 self.xmin = self.xmin if self.xmin else -self.xmax
595 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
595 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
596 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
596 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
597 ax.plt = ax.pcolormesh(x, y, cross.T,
597 ax.plt = ax.pcolormesh(x, y, cross.T,
598 vmin=self.zmin,
598 vmin=self.zmin,
599 vmax=self.zmax,
599 vmax=self.zmax,
600 cmap=plt.get_cmap(self.colormap)
600 cmap=plt.get_cmap(self.colormap)
601 )
601 )
602 else:
602 else:
603 ax.plt.set_array(cross.T.ravel())
603 ax.plt.set_array(cross.T.ravel())
604 self.titles.append(
604 self.titles.append(
605 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
605 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
606
606
607 ax = self.axes[3 * n + 1]
607 ax = self.axes[3 * n + 1]
608 if ax.firsttime:
608 if ax.firsttime:
609 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
609 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
610 self.xmin = self.xmin if self.xmin else -self.xmax
610 self.xmin = self.xmin if self.xmin else -self.xmax
611 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
611 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
612 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
612 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
613 ax.plt = ax.pcolormesh(x, y, out_r.T,
613 ax.plt = ax.pcolormesh(x, y, out_r.T,
614 vmin=-1.e6,
614 vmin=-1.e6,
615 vmax=0,
615 vmax=0,
616 cmap=plt.get_cmap(self.colormap)
616 cmap=plt.get_cmap(self.colormap)
617 )
617 )
618 else:
618 else:
619 ax.plt.set_array(out_r.T.ravel())
619 ax.plt.set_array(out_r.T.ravel())
620 self.titles.append(
620 self.titles.append(
621 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
621 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
622
622
623 ax = self.axes[3 * n + 2]
623 ax = self.axes[3 * n + 2]
624
624
625
625
626 if ax.firsttime:
626 if ax.firsttime:
627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
628 self.xmin = self.xmin if self.xmin else -self.xmax
628 self.xmin = self.xmin if self.xmin else -self.xmax
629 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
629 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
631 ax.plt = ax.pcolormesh(x, y, out_i.T,
631 ax.plt = ax.pcolormesh(x, y, out_i.T,
632 vmin=-1.e6,
632 vmin=-1.e6,
633 vmax=1.e6,
633 vmax=1.e6,
634 cmap=plt.get_cmap(self.colormap)
634 cmap=plt.get_cmap(self.colormap)
635 )
635 )
636 else:
636 else:
637 ax.plt.set_array(out_i.T.ravel())
637 ax.plt.set_array(out_i.T.ravel())
638 self.titles.append(
638 self.titles.append(
639 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
639 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
640
640
641 class RTIPlot(Plot):
641 class RTIPlot(Plot):
642 '''
642 '''
643 Plot for RTI data
643 Plot for RTI data
644 '''
644 '''
645
645
646 CODE = 'rti'
646 CODE = 'rti'
647 colormap = 'jet'
647 colormap = 'jet'
648 plot_type = 'pcolorbuffer'
648 plot_type = 'pcolorbuffer'
649 titles = None
649 titles = None
650 channelList = []
650 channelList = []
651 elevationList = []
651 elevationList = []
652 azimuthList = []
652 azimuthList = []
653
653
654 def setup(self):
654 def setup(self):
655 self.xaxis = 'time'
655 self.xaxis = 'time'
656 self.ncols = 1
656 self.ncols = 1
657 self.nrows = len(self.data.channels)
657 self.nrows = len(self.data.channels)
658 self.nplots = len(self.data.channels)
658 self.nplots = len(self.data.channels)
659 self.ylabel = 'Range [km]'
659 self.ylabel = 'Range [km]'
660 #self.xlabel = 'Time'
660 #self.xlabel = 'Time'
661 self.cb_label = 'dB'
661 self.cb_label = 'dB'
662 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
662 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
663 self.titles = ['{} Channel {}'.format(
663 self.titles = ['{} Channel {}'.format(
664 self.CODE.upper(), x) for x in range(self.nplots)]
664 self.CODE.upper(), x) for x in range(self.nplots)]
665
665
666 def update_list(self,dataOut):
666 def update_list(self,dataOut):
667
667
668 if len(self.channelList) == 0:
668 if len(self.channelList) == 0:
669 self.channelList = dataOut.channelList
669 self.channelList = dataOut.channelList
670 if len(self.elevationList) == 0:
670 if len(self.elevationList) == 0:
671 self.elevationList = dataOut.elevationList
671 self.elevationList = dataOut.elevationList
672 if len(self.azimuthList) == 0:
672 if len(self.azimuthList) == 0:
673 self.azimuthList = dataOut.azimuthList
673 self.azimuthList = dataOut.azimuthList
674
674
675
675
676 def update(self, dataOut):
676 def update(self, dataOut):
677
677
678 if len(self.channelList) == 0:
678 if len(self.channelList) == 0:
679 self.update_list(dataOut)
679 self.update_list(dataOut)
680 data = {}
680 data = {}
681 meta = {}
681 meta = {}
682 data['rti'] = dataOut.getPower()
682 data['rti'] = dataOut.getPower()
683 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
683 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
684 noise = 10*numpy.log10(dataOut.getNoise()/norm)
684 noise = 10*numpy.log10(dataOut.getNoise()/norm)
685 data['noise'] = noise
685 data['noise'] = noise
686
686
687 return data, meta
687 return data, meta
688
688
689 def plot(self):
689 def plot(self):
690
690
691 self.x = self.data.times
691 self.x = self.data.times
692 self.y = self.data.yrange
692 self.y = self.data.yrange
693 self.z = self.data[self.CODE]
693 self.z = self.data[self.CODE]
694 self.z = numpy.array(self.z, dtype=float)
694 self.z = numpy.array(self.z, dtype=float)
695 self.z = numpy.ma.masked_invalid(self.z)
695 self.z = numpy.ma.masked_invalid(self.z)
696
696
697 try:
697 try:
698 if self.channelList != None:
698 if self.channelList != None:
699 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
699 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
700 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
700 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
701 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
701 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
702 else:
702 else:
703 self.titles = ['{} Channel {}'.format(
703 self.titles = ['{} Channel {}'.format(
704 self.CODE.upper(), x) for x in self.channelList]
704 self.CODE.upper(), x) for x in self.channelList]
705 except:
705 except:
706 if self.channelList.any() != None:
706 if self.channelList.any() != None:
707 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
707 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
708 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
708 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
709 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
709 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
710 else:
710 else:
711 self.titles = ['{} Channel {}'.format(
711 self.titles = ['{} Channel {}'.format(
712 self.CODE.upper(), x) for x in self.channelList]
712 self.CODE.upper(), x) for x in self.channelList]
713
713
714 if self.decimation is None:
714 if self.decimation is None:
715 x, y, z = self.fill_gaps(self.x, self.y, self.z)
715 x, y, z = self.fill_gaps(self.x, self.y, self.z)
716 else:
716 else:
717 x, y, z = self.fill_gaps(*self.decimate())
717 x, y, z = self.fill_gaps(*self.decimate())
718
718
719 for n, ax in enumerate(self.axes):
719 for n, ax in enumerate(self.axes):
720
720
721 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
721 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
722 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
722 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
723 data = self.data[-1]
723 data = self.data[-1]
724 if ax.firsttime:
724 if ax.firsttime:
725 ax.plt = ax.pcolormesh(x, y, z[n].T,
725 ax.plt = ax.pcolormesh(x, y, z[n].T,
726 vmin=self.zmin,
726 vmin=self.zmin,
727 vmax=self.zmax,
727 vmax=self.zmax,
728 cmap=plt.get_cmap(self.colormap)
728 cmap=plt.get_cmap(self.colormap)
729 )
729 )
730 if self.showprofile:
730 if self.showprofile:
731 ax.plot_profile = self.pf_axes[n].plot(
731 ax.plot_profile = self.pf_axes[n].plot(data[self.CODE][n], self.y)[0]
732 data[self.CODE][n], self.y)[0]
733 if "noise" in self.data:
732 if "noise" in self.data:
733
734 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
734 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
735 color="k", linestyle="dashed", lw=1)[0]
735 color="k", linestyle="dashed", lw=1)[0]
736 else:
736 else:
737 ax.collections.remove(ax.collections[0]) # error while running in 3.12
737 ax.collections.remove(ax.collections[0])
738 ax.plt = ax.pcolormesh(x, y, z[n].T,
738 ax.plt = ax.pcolormesh(x, y, z[n].T,
739 vmin=self.zmin,
739 vmin=self.zmin,
740 vmax=self.zmax,
740 vmax=self.zmax,
741 cmap=plt.get_cmap(self.colormap)
741 cmap=plt.get_cmap(self.colormap)
742 )
742 )
743 if self.showprofile:
743 if self.showprofile:
744 ax.plot_profile.set_data(data[self.CODE][n], self.y)
744 ax.plot_profile.set_data(data[self.CODE][n], self.y)
745 if "noise" in self.data:
745 if "noise" in self.data:
746 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
746 ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
747 color="k", linestyle="dashed", lw=1)[0]
748
747
749 class SpectrogramPlot(Plot):
748 class SpectrogramPlot(Plot):
750 '''
749 '''
751 Plot for Spectrogram data
750 Plot for Spectrogram data
752 '''
751 '''
753
752
754 CODE = 'Spectrogram_Profile'
753 CODE = 'Spectrogram_Profile'
755 colormap = 'binary'
754 colormap = 'binary'
756 plot_type = 'pcolorbuffer'
755 plot_type = 'pcolorbuffer'
757
756
758 def setup(self):
757 def setup(self):
759 self.xaxis = 'time'
758 self.xaxis = 'time'
760 self.ncols = 1
759 self.ncols = 1
761 self.nrows = len(self.data.channels)
760 self.nrows = len(self.data.channels)
762 self.nplots = len(self.data.channels)
761 self.nplots = len(self.data.channels)
763 self.xlabel = 'Time'
762 self.xlabel = 'Time'
764 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
763 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
765 self.titles = []
764 self.titles = []
766
765
767 self.titles = ['{} Channel {}'.format(
766 self.titles = ['{} Channel {}'.format(
768 self.CODE.upper(), x) for x in range(self.nrows)]
767 self.CODE.upper(), x) for x in range(self.nrows)]
769
768
770
769
771 def update(self, dataOut):
770 def update(self, dataOut):
772 data = {}
771 data = {}
773 meta = {}
772 meta = {}
774
773
775 maxHei = 1620#+12000
774 maxHei = 1620#+12000
776 indb = numpy.where(dataOut.heightList <= maxHei)
775 indb = numpy.where(dataOut.heightList <= maxHei)
777 hei = indb[0][-1]
776 hei = indb[0][-1]
778
777
779 factor = dataOut.nIncohInt
778 factor = dataOut.nIncohInt
780 z = dataOut.data_spc[:,:,hei] / factor
779 z = dataOut.data_spc[:,:,hei] / factor
781 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
780 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
782
781
783 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
782 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
784 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
783 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
785
784
786 data['hei'] = hei
785 data['hei'] = hei
787 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
786 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
788 data['nProfiles'] = dataOut.nProfiles
787 data['nProfiles'] = dataOut.nProfiles
789
788
790 return data, meta
789 return data, meta
791
790
792 def plot(self):
791 def plot(self):
793
792
794 self.x = self.data.times
793 self.x = self.data.times
795 self.z = self.data[self.CODE]
794 self.z = self.data[self.CODE]
796 self.y = self.data.xrange[0]
795 self.y = self.data.xrange[0]
797
796
798 hei = self.data['hei'][-1]
797 hei = self.data['hei'][-1]
799 DH = self.data['DH'][-1]
798 DH = self.data['DH'][-1]
800 nProfiles = self.data['nProfiles'][-1]
799 nProfiles = self.data['nProfiles'][-1]
801
800
802 self.ylabel = "Frequency (kHz)"
801 self.ylabel = "Frequency (kHz)"
803
802
804 self.z = numpy.ma.masked_invalid(self.z)
803 self.z = numpy.ma.masked_invalid(self.z)
805
804
806 if self.decimation is None:
805 if self.decimation is None:
807 x, y, z = self.fill_gaps(self.x, self.y, self.z)
806 x, y, z = self.fill_gaps(self.x, self.y, self.z)
808 else:
807 else:
809 x, y, z = self.fill_gaps(*self.decimate())
808 x, y, z = self.fill_gaps(*self.decimate())
810
809
811 for n, ax in enumerate(self.axes):
810 for n, ax in enumerate(self.axes):
812 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
811 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
813 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
812 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
814 data = self.data[-1]
813 data = self.data[-1]
815 if ax.firsttime:
814 if ax.firsttime:
816 ax.plt = ax.pcolormesh(x, y, z[n].T,
815 ax.plt = ax.pcolormesh(x, y, z[n].T,
817 vmin=self.zmin,
816 vmin=self.zmin,
818 vmax=self.zmax,
817 vmax=self.zmax,
819 cmap=plt.get_cmap(self.colormap)
818 cmap=plt.get_cmap(self.colormap)
820 )
819 )
821 else:
820 else:
822 # ax.collections.remove(ax.collections[0]) # error while running
821 ax.collections.remove(ax.collections[0]) # error while running
823 ax.plt = ax.pcolormesh(x, y, z[n].T,
822 ax.plt = ax.pcolormesh(x, y, z[n].T,
824 vmin=self.zmin,
823 vmin=self.zmin,
825 vmax=self.zmax,
824 vmax=self.zmax,
826 cmap=plt.get_cmap(self.colormap)
825 cmap=plt.get_cmap(self.colormap)
827 )
826 )
828
827
829
828
830
829
831 class CoherencePlot(RTIPlot):
830 class CoherencePlot(RTIPlot):
832 '''
831 '''
833 Plot for Coherence data
832 Plot for Coherence data
834 '''
833 '''
835
834
836 CODE = 'coh'
835 CODE = 'coh'
837 titles = None
836 titles = None
838
837
839 def setup(self):
838 def setup(self):
840 self.xaxis = 'time'
839 self.xaxis = 'time'
841 self.ncols = 1
840 self.ncols = 1
842 self.nrows = len(self.data.pairs)
841 self.nrows = len(self.data.pairs)
843 self.nplots = len(self.data.pairs)
842 self.nplots = len(self.data.pairs)
844 self.ylabel = 'Range [km]'
843 self.ylabel = 'Range [km]'
845 self.xlabel = 'Time'
844 self.xlabel = 'Time'
846 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
845 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
847 if self.CODE == 'coh':
846 if self.CODE == 'coh':
848 self.cb_label = ''
847 self.cb_label = ''
849 self.titles = [
848 self.titles = [
850 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
849 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
851 else:
850 else:
852 self.cb_label = 'Degrees'
851 self.cb_label = 'Degrees'
853 self.titles = [
852 self.titles = [
854 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
853 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
855
854
856 def update(self, dataOut):
855 def update(self, dataOut):
857
856
858 data = {}
857 data = {}
859 meta = {}
858 meta = {}
860 data['coh'] = dataOut.getCoherence()
859 data['coh'] = dataOut.getCoherence()
861 meta['pairs'] = dataOut.pairsList
860 meta['pairs'] = dataOut.pairsList
862
861
863 return data, meta
862 return data, meta
864
863
865 class PhasePlot(CoherencePlot):
864 class PhasePlot(CoherencePlot):
866 '''
865 '''
867 Plot for Phase map data
866 Plot for Phase map data
868 '''
867 '''
869
868
870 CODE = 'phase'
869 CODE = 'phase'
871 colormap = 'seismic'
870 colormap = 'seismic'
872
871
873 def update(self, dataOut):
872 def update(self, dataOut):
874
873
875 data = {}
874 data = {}
876 meta = {}
875 meta = {}
877 data['phase'] = dataOut.getCoherence(phase=True)
876 data['phase'] = dataOut.getCoherence(phase=True)
878 meta['pairs'] = dataOut.pairsList
877 meta['pairs'] = dataOut.pairsList
879
878
880 return data, meta
879 return data, meta
881
880
882 class NoisePlot(Plot):
881 class NoisePlot(Plot):
883 '''
882 '''
884 Plot for noise
883 Plot for noise
885 '''
884 '''
886
885
887 CODE = 'noise'
886 CODE = 'noise'
888 plot_type = 'scatterbuffer'
887 plot_type = 'scatterbuffer'
889
888
890 def setup(self):
889 def setup(self):
891 self.xaxis = 'time'
890 self.xaxis = 'time'
892 self.ncols = 1
891 self.ncols = 1
893 self.nrows = 1
892 self.nrows = 1
894 self.nplots = 1
893 self.nplots = 1
895 self.ylabel = 'Intensity [dB]'
894 self.ylabel = 'Intensity [dB]'
896 self.xlabel = 'Time'
895 self.xlabel = 'Time'
897 self.titles = ['Noise']
896 self.titles = ['Noise']
898 self.colorbar = False
897 self.colorbar = False
899 self.plots_adjust.update({'right': 0.85 })
898 self.plots_adjust.update({'right': 0.85 })
900 self.titles = ['Noise Plot']
899 self.titles = ['Noise Plot']
901
900
902 def update(self, dataOut):
901 def update(self, dataOut):
903
902
904 data = {}
903 data = {}
905 meta = {}
904 meta = {}
906 noise = 10*numpy.log10(dataOut.getNoise())
905 noise = 10*numpy.log10(dataOut.getNoise())
907 noise = noise.reshape(dataOut.nChannels, 1)
906 noise = noise.reshape(dataOut.nChannels, 1)
908 data['noise'] = noise
907 data['noise'] = noise
909 meta['yrange'] = numpy.array([])
908 meta['yrange'] = numpy.array([])
910
909
911 return data, meta
910 return data, meta
912
911
913 def plot(self):
912 def plot(self):
914
913
915 x = self.data.times
914 x = self.data.times
916 xmin = self.data.min_time
915 xmin = self.data.min_time
917 xmax = xmin + self.xrange * 60 * 60
916 xmax = xmin + self.xrange * 60 * 60
918 Y = self.data['noise']
917 Y = self.data['noise']
919
918
920 if self.axes[0].firsttime:
919 if self.axes[0].firsttime:
921 self.ymin = numpy.nanmin(Y) - 5
920 self.ymin = numpy.nanmin(Y) - 5
922 self.ymax = numpy.nanmax(Y) + 5
921 self.ymax = numpy.nanmax(Y) + 5
923 for ch in self.data.channels:
922 for ch in self.data.channels:
924 y = Y[ch]
923 y = Y[ch]
925 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
924 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
926 plt.legend(bbox_to_anchor=(1.18, 1.0))
925 plt.legend(bbox_to_anchor=(1.18, 1.0))
927 else:
926 else:
928 for ch in self.data.channels:
927 for ch in self.data.channels:
929 y = Y[ch]
928 y = Y[ch]
930 self.axes[0].lines[ch].set_data(x, y)
929 self.axes[0].lines[ch].set_data(x, y)
931
930
932 class PowerProfilePlot(Plot):
931 class PowerProfilePlot(Plot):
933
932
934 CODE = 'pow_profile'
933 CODE = 'pow_profile'
935 plot_type = 'scatter'
934 plot_type = 'scatter'
936
935
937 def setup(self):
936 def setup(self):
938
937
939 self.ncols = 1
938 self.ncols = 1
940 self.nrows = 1
939 self.nrows = 1
941 self.nplots = 1
940 self.nplots = 1
942 self.height = 4
941 self.height = 4
943 self.width = 3
942 self.width = 3
944 self.ylabel = 'Range [km]'
943 self.ylabel = 'Range [km]'
945 self.xlabel = 'Intensity [dB]'
944 self.xlabel = 'Intensity [dB]'
946 self.titles = ['Power Profile']
945 self.titles = ['Power Profile']
947 self.colorbar = False
946 self.colorbar = False
948
947
949 def update(self, dataOut):
948 def update(self, dataOut):
950
949
951 data = {}
950 data = {}
952 meta = {}
951 meta = {}
953 data[self.CODE] = dataOut.getPower()
952 data[self.CODE] = dataOut.getPower()
954
953
955 return data, meta
954 return data, meta
956
955
957 def plot(self):
956 def plot(self):
958
957
959 y = self.data.yrange
958 y = self.data.yrange
960 self.y = y
959 self.y = y
961
960
962 x = self.data[-1][self.CODE]
961 x = self.data[-1][self.CODE]
963
962
964 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
963 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
965 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
964 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
966
965
967 if self.axes[0].firsttime:
966 if self.axes[0].firsttime:
968 for ch in self.data.channels:
967 for ch in self.data.channels:
969 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
968 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
970 plt.legend()
969 plt.legend()
971 else:
970 else:
972 for ch in self.data.channels:
971 for ch in self.data.channels:
973 self.axes[0].lines[ch].set_data(x[ch], y)
972 self.axes[0].lines[ch].set_data(x[ch], y)
974
973
975
974
976 class SpectraCutPlot(Plot):
975 class SpectraCutPlot(Plot):
977
976
978 CODE = 'spc_cut'
977 CODE = 'spc_cut'
979 plot_type = 'scatter'
978 plot_type = 'scatter'
980 buffering = False
979 buffering = False
981 heights = []
980 heights = []
982 channelList = []
981 channelList = []
983 maintitle = "Spectra Cuts"
982 maintitle = "Spectra Cuts"
984 flag_setIndex = False
983 flag_setIndex = False
985
984
986 def setup(self):
985 def setup(self):
987
986
988 self.nplots = len(self.data.channels)
987 self.nplots = len(self.data.channels)
989 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
988 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
990 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
989 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
991 self.width = 4.5 * self.ncols + 2.5
990 self.width = 4.5 * self.ncols + 2.5
992 self.height = 4.8 * self.nrows
991 self.height = 4.8 * self.nrows
993 self.ylabel = 'Power [dB]'
992 self.ylabel = 'Power [dB]'
994 self.colorbar = False
993 self.colorbar = False
995 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.9, 'bottom':0.08})
994 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.9, 'bottom':0.08})
996
995
997 if len(self.selectedHeightsList) > 0:
996 if len(self.selectedHeightsList) > 0:
998 self.maintitle = "Spectra Cut"# for %d km " %(int(self.selectedHeight))
997 self.maintitle = "Spectra Cut"# for %d km " %(int(self.selectedHeight))
999
998
1000
999
1001
1000
1002 def update(self, dataOut):
1001 def update(self, dataOut):
1003 if len(self.channelList) == 0:
1002 if len(self.channelList) == 0:
1004 self.channelList = dataOut.channelList
1003 self.channelList = dataOut.channelList
1005
1004
1006 self.heights = dataOut.heightList
1005 self.heights = dataOut.heightList
1007 #print("sels: ",self.selectedHeightsList)
1006 #print("sels: ",self.selectedHeightsList)
1008 if len(self.selectedHeightsList)>0 and not self.flag_setIndex:
1007 if len(self.selectedHeightsList)>0 and not self.flag_setIndex:
1009
1008
1010 for sel_height in self.selectedHeightsList:
1009 for sel_height in self.selectedHeightsList:
1011 index_list = numpy.where(self.heights >= sel_height)
1010 index_list = numpy.where(self.heights >= sel_height)
1012 index_list = index_list[0]
1011 index_list = index_list[0]
1013 self.height_index.append(index_list[0])
1012 self.height_index.append(index_list[0])
1014 #print("sels i:"", self.height_index)
1013 #print("sels i:"", self.height_index)
1015 self.flag_setIndex = True
1014 self.flag_setIndex = True
1016 #print(self.height_index)
1015 #print(self.height_index)
1017 data = {}
1016 data = {}
1018 meta = {}
1017 meta = {}
1019
1018
1020 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter#*dataOut.nFFTPoints
1019 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter#*dataOut.nFFTPoints
1021 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1020 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1022 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1021 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1023
1022
1024
1023
1025 z = []
1024 z = []
1026 for ch in range(dataOut.nChannels):
1025 for ch in range(dataOut.nChannels):
1027 if hasattr(dataOut.normFactor,'shape'):
1026 if hasattr(dataOut.normFactor,'shape'):
1028 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1027 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1029 else:
1028 else:
1030 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1029 z.append(numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1031
1030
1032 z = numpy.asarray(z)
1031 z = numpy.asarray(z)
1033 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1032 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1034 spc = 10*numpy.log10(z)
1033 spc = 10*numpy.log10(z)
1035
1034
1036
1035
1037 data['spc'] = spc - noise
1036 data['spc'] = spc - noise
1038 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1037 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1039
1038
1040 return data, meta
1039 return data, meta
1041
1040
1042 def plot(self):
1041 def plot(self):
1043 if self.xaxis == "frequency":
1042 if self.xaxis == "frequency":
1044 x = self.data.xrange[0][0:]
1043 x = self.data.xrange[0][0:]
1045 self.xlabel = "Frequency (kHz)"
1044 self.xlabel = "Frequency (kHz)"
1046 elif self.xaxis == "time":
1045 elif self.xaxis == "time":
1047 x = self.data.xrange[1]
1046 x = self.data.xrange[1]
1048 self.xlabel = "Time (ms)"
1047 self.xlabel = "Time (ms)"
1049 else:
1048 else:
1050 x = self.data.xrange[2]
1049 x = self.data.xrange[2]
1051 self.xlabel = "Velocity (m/s)"
1050 self.xlabel = "Velocity (m/s)"
1052
1051
1053 self.titles = []
1052 self.titles = []
1054
1053
1055 y = self.data.yrange
1054 y = self.data.yrange
1056 z = self.data[-1]['spc']
1055 z = self.data[-1]['spc']
1057 #print(z.shape)
1056 #print(z.shape)
1058 if len(self.height_index) > 0:
1057 if len(self.height_index) > 0:
1059 index = self.height_index
1058 index = self.height_index
1060 else:
1059 else:
1061 index = numpy.arange(0, len(y), int((len(y))/9))
1060 index = numpy.arange(0, len(y), int((len(y))/9))
1062 #print("inde x ", index, self.axes)
1061 #print("inde x ", index, self.axes)
1063
1062
1064 for n, ax in enumerate(self.axes):
1063 for n, ax in enumerate(self.axes):
1065
1064
1066 if ax.firsttime:
1065 if ax.firsttime:
1067
1066
1068
1067
1069 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1068 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1070 self.xmin = self.xmin if self.xmin else -self.xmax
1069 self.xmin = self.xmin if self.xmin else -self.xmax
1071 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
1070 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
1072 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
1071 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
1073
1072
1074
1073
1075 ax.plt = ax.plot(x, z[n, :, index].T)
1074 ax.plt = ax.plot(x, z[n, :, index].T)
1076 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1075 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1077 self.figures[0].legend(ax.plt, labels, loc='center right', prop={'size': 8})
1076 self.figures[0].legend(ax.plt, labels, loc='center right', prop={'size': 8})
1078 ax.minorticks_on()
1077 ax.minorticks_on()
1079 ax.grid(which='major', axis='both')
1078 ax.grid(which='major', axis='both')
1080 ax.grid(which='minor', axis='x')
1079 ax.grid(which='minor', axis='x')
1081 else:
1080 else:
1082 for i, line in enumerate(ax.plt):
1081 for i, line in enumerate(ax.plt):
1083 line.set_data(x, z[n, :, index[i]])
1082 line.set_data(x, z[n, :, index[i]])
1084
1083
1085
1084
1086 self.titles.append('CH {}'.format(self.channelList[n]))
1085 self.titles.append('CH {}'.format(self.channelList[n]))
1087 plt.suptitle(self.maintitle, fontsize=10)
1086 plt.suptitle(self.maintitle, fontsize=10)
1088
1087
1089
1088
1090 class BeaconPhase(Plot):
1089 class BeaconPhase(Plot):
1091
1090
1092 __isConfig = None
1091 __isConfig = None
1093 __nsubplots = None
1092 __nsubplots = None
1094
1093
1095 PREFIX = 'beacon_phase'
1094 PREFIX = 'beacon_phase'
1096
1095
1097 def __init__(self):
1096 def __init__(self):
1098 Plot.__init__(self)
1097 Plot.__init__(self)
1099 self.timerange = 24*60*60
1098 self.timerange = 24*60*60
1100 self.isConfig = False
1099 self.isConfig = False
1101 self.__nsubplots = 1
1100 self.__nsubplots = 1
1102 self.counter_imagwr = 0
1101 self.counter_imagwr = 0
1103 self.WIDTH = 800
1102 self.WIDTH = 800
1104 self.HEIGHT = 400
1103 self.HEIGHT = 400
1105 self.WIDTHPROF = 120
1104 self.WIDTHPROF = 120
1106 self.HEIGHTPROF = 0
1105 self.HEIGHTPROF = 0
1107 self.xdata = None
1106 self.xdata = None
1108 self.ydata = None
1107 self.ydata = None
1109
1108
1110 self.PLOT_CODE = BEACON_CODE
1109 self.PLOT_CODE = BEACON_CODE
1111
1110
1112 self.FTP_WEI = None
1111 self.FTP_WEI = None
1113 self.EXP_CODE = None
1112 self.EXP_CODE = None
1114 self.SUB_EXP_CODE = None
1113 self.SUB_EXP_CODE = None
1115 self.PLOT_POS = None
1114 self.PLOT_POS = None
1116
1115
1117 self.filename_phase = None
1116 self.filename_phase = None
1118
1117
1119 self.figfile = None
1118 self.figfile = None
1120
1119
1121 self.xmin = None
1120 self.xmin = None
1122 self.xmax = None
1121 self.xmax = None
1123
1122
1124 def getSubplots(self):
1123 def getSubplots(self):
1125
1124
1126 ncol = 1
1125 ncol = 1
1127 nrow = 1
1126 nrow = 1
1128
1127
1129 return nrow, ncol
1128 return nrow, ncol
1130
1129
1131 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1130 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1132
1131
1133 self.__showprofile = showprofile
1132 self.__showprofile = showprofile
1134 self.nplots = nplots
1133 self.nplots = nplots
1135
1134
1136 ncolspan = 7
1135 ncolspan = 7
1137 colspan = 6
1136 colspan = 6
1138 self.__nsubplots = 2
1137 self.__nsubplots = 2
1139
1138
1140 self.createFigure(id = id,
1139 self.createFigure(id = id,
1141 wintitle = wintitle,
1140 wintitle = wintitle,
1142 widthplot = self.WIDTH+self.WIDTHPROF,
1141 widthplot = self.WIDTH+self.WIDTHPROF,
1143 heightplot = self.HEIGHT+self.HEIGHTPROF,
1142 heightplot = self.HEIGHT+self.HEIGHTPROF,
1144 show=show)
1143 show=show)
1145
1144
1146 nrow, ncol = self.getSubplots()
1145 nrow, ncol = self.getSubplots()
1147
1146
1148 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1147 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1149
1148
1150 def save_phase(self, filename_phase):
1149 def save_phase(self, filename_phase):
1151 f = open(filename_phase,'w+')
1150 f = open(filename_phase,'w+')
1152 f.write('\n\n')
1151 f.write('\n\n')
1153 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1152 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1154 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1153 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1155 f.close()
1154 f.close()
1156
1155
1157 def save_data(self, filename_phase, data, data_datetime):
1156 def save_data(self, filename_phase, data, data_datetime):
1158 f=open(filename_phase,'a')
1157 f=open(filename_phase,'a')
1159 timetuple_data = data_datetime.timetuple()
1158 timetuple_data = data_datetime.timetuple()
1160 day = str(timetuple_data.tm_mday)
1159 day = str(timetuple_data.tm_mday)
1161 month = str(timetuple_data.tm_mon)
1160 month = str(timetuple_data.tm_mon)
1162 year = str(timetuple_data.tm_year)
1161 year = str(timetuple_data.tm_year)
1163 hour = str(timetuple_data.tm_hour)
1162 hour = str(timetuple_data.tm_hour)
1164 minute = str(timetuple_data.tm_min)
1163 minute = str(timetuple_data.tm_min)
1165 second = str(timetuple_data.tm_sec)
1164 second = str(timetuple_data.tm_sec)
1166 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1165 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1167 f.close()
1166 f.close()
1168
1167
1169 def plot(self):
1168 def plot(self):
1170 log.warning('TODO: Not yet implemented...')
1169 log.warning('TODO: Not yet implemented...')
1171
1170
1172 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1171 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1173 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1172 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1174 timerange=None,
1173 timerange=None,
1175 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1174 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1176 server=None, folder=None, username=None, password=None,
1175 server=None, folder=None, username=None, password=None,
1177 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1176 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1178
1177
1179 if dataOut.flagNoData:
1178 if dataOut.flagNoData:
1180 return dataOut
1179 return dataOut
1181
1180
1182 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1181 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1183 return
1182 return
1184
1183
1185 if pairsList == None:
1184 if pairsList == None:
1186 pairsIndexList = dataOut.pairsIndexList[:10]
1185 pairsIndexList = dataOut.pairsIndexList[:10]
1187 else:
1186 else:
1188 pairsIndexList = []
1187 pairsIndexList = []
1189 for pair in pairsList:
1188 for pair in pairsList:
1190 if pair not in dataOut.pairsList:
1189 if pair not in dataOut.pairsList:
1191 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1190 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1192 pairsIndexList.append(dataOut.pairsList.index(pair))
1191 pairsIndexList.append(dataOut.pairsList.index(pair))
1193
1192
1194 if pairsIndexList == []:
1193 if pairsIndexList == []:
1195 return
1194 return
1196
1195
1197 # if len(pairsIndexList) > 4:
1196 # if len(pairsIndexList) > 4:
1198 # pairsIndexList = pairsIndexList[0:4]
1197 # pairsIndexList = pairsIndexList[0:4]
1199
1198
1200 hmin_index = None
1199 hmin_index = None
1201 hmax_index = None
1200 hmax_index = None
1202
1201
1203 if hmin != None and hmax != None:
1202 if hmin != None and hmax != None:
1204 indexes = numpy.arange(dataOut.nHeights)
1203 indexes = numpy.arange(dataOut.nHeights)
1205 hmin_list = indexes[dataOut.heightList >= hmin]
1204 hmin_list = indexes[dataOut.heightList >= hmin]
1206 hmax_list = indexes[dataOut.heightList <= hmax]
1205 hmax_list = indexes[dataOut.heightList <= hmax]
1207
1206
1208 if hmin_list.any():
1207 if hmin_list.any():
1209 hmin_index = hmin_list[0]
1208 hmin_index = hmin_list[0]
1210
1209
1211 if hmax_list.any():
1210 if hmax_list.any():
1212 hmax_index = hmax_list[-1]+1
1211 hmax_index = hmax_list[-1]+1
1213
1212
1214 x = dataOut.getTimeRange()
1213 x = dataOut.getTimeRange()
1215
1214
1216 thisDatetime = dataOut.datatime
1215 thisDatetime = dataOut.datatime
1217
1216
1218 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1217 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1219 xlabel = "Local Time"
1218 xlabel = "Local Time"
1220 ylabel = "Phase (degrees)"
1219 ylabel = "Phase (degrees)"
1221
1220
1222 update_figfile = False
1221 update_figfile = False
1223
1222
1224 nplots = len(pairsIndexList)
1223 nplots = len(pairsIndexList)
1225 phase_beacon = numpy.zeros(len(pairsIndexList))
1224 phase_beacon = numpy.zeros(len(pairsIndexList))
1226 for i in range(nplots):
1225 for i in range(nplots):
1227 pair = dataOut.pairsList[pairsIndexList[i]]
1226 pair = dataOut.pairsList[pairsIndexList[i]]
1228 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1227 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1229 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1228 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1230 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1229 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1231 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1230 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1232 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1231 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1233
1232
1234 if dataOut.beacon_heiIndexList:
1233 if dataOut.beacon_heiIndexList:
1235 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1234 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1236 else:
1235 else:
1237 phase_beacon[i] = numpy.average(phase)
1236 phase_beacon[i] = numpy.average(phase)
1238
1237
1239 if not self.isConfig:
1238 if not self.isConfig:
1240
1239
1241 nplots = len(pairsIndexList)
1240 nplots = len(pairsIndexList)
1242
1241
1243 self.setup(id=id,
1242 self.setup(id=id,
1244 nplots=nplots,
1243 nplots=nplots,
1245 wintitle=wintitle,
1244 wintitle=wintitle,
1246 showprofile=showprofile,
1245 showprofile=showprofile,
1247 show=show)
1246 show=show)
1248
1247
1249 if timerange != None:
1248 if timerange != None:
1250 self.timerange = timerange
1249 self.timerange = timerange
1251
1250
1252 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1251 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1253
1252
1254 if ymin == None: ymin = 0
1253 if ymin == None: ymin = 0
1255 if ymax == None: ymax = 360
1254 if ymax == None: ymax = 360
1256
1255
1257 self.FTP_WEI = ftp_wei
1256 self.FTP_WEI = ftp_wei
1258 self.EXP_CODE = exp_code
1257 self.EXP_CODE = exp_code
1259 self.SUB_EXP_CODE = sub_exp_code
1258 self.SUB_EXP_CODE = sub_exp_code
1260 self.PLOT_POS = plot_pos
1259 self.PLOT_POS = plot_pos
1261
1260
1262 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1261 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1263 self.isConfig = True
1262 self.isConfig = True
1264 self.figfile = figfile
1263 self.figfile = figfile
1265 self.xdata = numpy.array([])
1264 self.xdata = numpy.array([])
1266 self.ydata = numpy.array([])
1265 self.ydata = numpy.array([])
1267
1266
1268 update_figfile = True
1267 update_figfile = True
1269
1268
1270 #open file beacon phase
1269 #open file beacon phase
1271 path = '%s%03d' %(self.PREFIX, self.id)
1270 path = '%s%03d' %(self.PREFIX, self.id)
1272 beacon_file = os.path.join(path,'%s.txt'%self.name)
1271 beacon_file = os.path.join(path,'%s.txt'%self.name)
1273 self.filename_phase = os.path.join(figpath,beacon_file)
1272 self.filename_phase = os.path.join(figpath,beacon_file)
1274
1273
1275 self.setWinTitle(title)
1274 self.setWinTitle(title)
1276
1275
1277
1276
1278 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1277 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1279
1278
1280 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1279 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1281
1280
1282 axes = self.axesList[0]
1281 axes = self.axesList[0]
1283
1282
1284 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1283 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1285
1284
1286 if len(self.ydata)==0:
1285 if len(self.ydata)==0:
1287 self.ydata = phase_beacon.reshape(-1,1)
1286 self.ydata = phase_beacon.reshape(-1,1)
1288 else:
1287 else:
1289 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1288 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1290
1289
1291
1290
1292 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1291 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1293 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1292 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1294 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1293 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1295 XAxisAsTime=True, grid='both'
1294 XAxisAsTime=True, grid='both'
1296 )
1295 )
1297
1296
1298 self.draw()
1297 self.draw()
1299
1298
1300 if dataOut.ltctime >= self.xmax:
1299 if dataOut.ltctime >= self.xmax:
1301 self.counter_imagwr = wr_period
1300 self.counter_imagwr = wr_period
1302 self.isConfig = False
1301 self.isConfig = False
1303 update_figfile = True
1302 update_figfile = True
1304
1303
1305 self.save(figpath=figpath,
1304 self.save(figpath=figpath,
1306 figfile=figfile,
1305 figfile=figfile,
1307 save=save,
1306 save=save,
1308 ftp=ftp,
1307 ftp=ftp,
1309 wr_period=wr_period,
1308 wr_period=wr_period,
1310 thisDatetime=thisDatetime,
1309 thisDatetime=thisDatetime,
1311 update_figfile=update_figfile)
1310 update_figfile=update_figfile)
1312
1311
1313 return dataOut
1312 return dataOut
1314
1313
1315 #####################################
1314 #####################################
1316 class NoiselessSpectraPlot(Plot):
1315 class NoiselessSpectraPlot(Plot):
1317 '''
1316 '''
1318 Plot for Spectra data, subtracting
1317 Plot for Spectra data, subtracting
1319 the noise in all channels, using for
1318 the noise in all channels, using for
1320 amisr-14 data
1319 amisr-14 data
1321 '''
1320 '''
1322
1321
1323 CODE = 'noiseless_spc'
1322 CODE = 'noiseless_spc'
1324 colormap = 'jet'
1323 colormap = 'jet'
1325 plot_type = 'pcolor'
1324 plot_type = 'pcolor'
1326 buffering = False
1325 buffering = False
1327 channelList = []
1326 channelList = []
1328 last_noise = None
1327 last_noise = None
1329
1328
1330 def setup(self):
1329 def setup(self):
1331
1330
1332 self.nplots = len(self.data.channels)
1331 self.nplots = len(self.data.channels)
1333 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1332 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1334 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1333 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1335 self.height = 3.5 * self.nrows
1334 self.height = 3.5 * self.nrows
1336
1335
1337 self.cb_label = 'dB'
1336 self.cb_label = 'dB'
1338 if self.showprofile:
1337 if self.showprofile:
1339 self.width = 5.8 * self.ncols
1338 self.width = 5.8 * self.ncols
1340 else:
1339 else:
1341 self.width = 4.8* self.ncols
1340 self.width = 4.8* self.ncols
1342 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.92, 'bottom': 0.12})
1341 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.92, 'bottom': 0.12})
1343
1342
1344 self.ylabel = 'Range [km]'
1343 self.ylabel = 'Range [km]'
1345
1344
1346
1345
1347 def update_list(self,dataOut):
1346 def update_list(self,dataOut):
1348 if len(self.channelList) == 0:
1347 if len(self.channelList) == 0:
1349 self.channelList = dataOut.channelList
1348 self.channelList = dataOut.channelList
1350
1349
1351 def update(self, dataOut):
1350 def update(self, dataOut):
1352
1351
1353 self.update_list(dataOut)
1352 self.update_list(dataOut)
1354 data = {}
1353 data = {}
1355 meta = {}
1354 meta = {}
1356
1355
1357 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1356 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1358 n0 = (dataOut.getNoise()/norm)
1357 n0 = (dataOut.getNoise()/norm)
1359 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1358 noise = numpy.repeat(n0,(dataOut.nFFTPoints*dataOut.nHeights)).reshape(dataOut.nChannels,dataOut.nFFTPoints,dataOut.nHeights)
1360 noise = 10*numpy.log10(noise)
1359 noise = 10*numpy.log10(noise)
1361
1360
1362 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
1361 z = numpy.zeros((dataOut.nChannels, dataOut.nFFTPoints, dataOut.nHeights))
1363 for ch in range(dataOut.nChannels):
1362 for ch in range(dataOut.nChannels):
1364 if hasattr(dataOut.normFactor,'ndim'):
1363 if hasattr(dataOut.normFactor,'ndim'):
1365 if dataOut.normFactor.ndim > 1:
1364 if dataOut.normFactor.ndim > 1:
1366 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1365 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor[ch]))
1367 else:
1366 else:
1368 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1367 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1369 else:
1368 else:
1370 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1369 z[ch] = (numpy.divide(dataOut.data_spc[ch],dataOut.normFactor))
1371
1370
1372 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1371 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1373 spc = 10*numpy.log10(z)
1372 spc = 10*numpy.log10(z)
1374
1373
1375
1374
1376 data['spc'] = spc - noise
1375 data['spc'] = spc - noise
1377 #print(spc.shape)
1376 #print(spc.shape)
1378 data['rti'] = spc.mean(axis=1)
1377 data['rti'] = spc.mean(axis=1)
1379 data['noise'] = noise
1378 data['noise'] = noise
1380
1379
1381
1380
1382
1381
1383 # data['noise'] = noise
1382 # data['noise'] = noise
1384 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1383 meta['xrange'] = (dataOut.getFreqRange(EXTRA_POINTS)/1000., dataOut.getAcfRange(EXTRA_POINTS), dataOut.getVelRange(EXTRA_POINTS))
1385
1384
1386 return data, meta
1385 return data, meta
1387
1386
1388 def plot(self):
1387 def plot(self):
1389 if self.xaxis == "frequency":
1388 if self.xaxis == "frequency":
1390 x = self.data.xrange[0]
1389 x = self.data.xrange[0]
1391 self.xlabel = "Frequency (kHz)"
1390 self.xlabel = "Frequency (kHz)"
1392 elif self.xaxis == "time":
1391 elif self.xaxis == "time":
1393 x = self.data.xrange[1]
1392 x = self.data.xrange[1]
1394 self.xlabel = "Time (ms)"
1393 self.xlabel = "Time (ms)"
1395 else:
1394 else:
1396 x = self.data.xrange[2]
1395 x = self.data.xrange[2]
1397 self.xlabel = "Velocity (m/s)"
1396 self.xlabel = "Velocity (m/s)"
1398
1397
1399 self.titles = []
1398 self.titles = []
1400 y = self.data.yrange
1399 y = self.data.yrange
1401 self.y = y
1400 self.y = y
1402
1401
1403 data = self.data[-1]
1402 data = self.data[-1]
1404 z = data['spc']
1403 z = data['spc']
1405
1404
1406 for n, ax in enumerate(self.axes):
1405 for n, ax in enumerate(self.axes):
1407 #noise = data['noise'][n]
1406 #noise = data['noise'][n]
1408
1407
1409 if ax.firsttime:
1408 if ax.firsttime:
1410 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1409 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1411 self.xmin = self.xmin if self.xmin else -self.xmax
1410 self.xmin = self.xmin if self.xmin else -self.xmax
1412 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1411 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1413 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1412 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1414 ax.plt = ax.pcolormesh(x, y, z[n].T,
1413 ax.plt = ax.pcolormesh(x, y, z[n].T,
1415 vmin=self.zmin,
1414 vmin=self.zmin,
1416 vmax=self.zmax,
1415 vmax=self.zmax,
1417 cmap=plt.get_cmap(self.colormap)
1416 cmap=plt.get_cmap(self.colormap)
1418 )
1417 )
1419
1418
1420 if self.showprofile:
1419 if self.showprofile:
1421 ax.plt_profile = self.pf_axes[n].plot(
1420 ax.plt_profile = self.pf_axes[n].plot(
1422 data['rti'][n], y)[0]
1421 data['rti'][n], y)[0]
1423
1422
1424
1423
1425 else:
1424 else:
1426 ax.plt.set_array(z[n].T.ravel())
1425 ax.plt.set_array(z[n].T.ravel())
1427 if self.showprofile:
1426 if self.showprofile:
1428 ax.plt_profile.set_data(data['rti'][n], y)
1427 ax.plt_profile.set_data(data['rti'][n], y)
1429
1428
1430
1429
1431 self.titles.append('CH {}'.format(self.channelList[n]))
1430 self.titles.append('CH {}'.format(self.channelList[n]))
1432
1431
1433
1432
1434 class NoiselessRTIPlot(RTIPlot):
1433 class NoiselessRTIPlot(RTIPlot):
1435 '''
1434 '''
1436 Plot for RTI data
1435 Plot for RTI data
1437 '''
1436 '''
1438
1437
1439 CODE = 'noiseless_rti'
1438 CODE = 'noiseless_rti'
1440 colormap = 'jet'
1439 colormap = 'jet'
1441 plot_type = 'pcolorbuffer'
1440 plot_type = 'pcolorbuffer'
1442 titles = None
1441 titles = None
1443 channelList = []
1442 channelList = []
1444 elevationList = []
1443 elevationList = []
1445 azimuthList = []
1444 azimuthList = []
1446 last_noise = None
1445 last_noise = None
1447
1446
1448 def setup(self):
1447 def setup(self):
1449 self.xaxis = 'time'
1448 self.xaxis = 'time'
1450 self.ncols = 1
1449 self.ncols = 1
1451 #print("dataChannels ",self.data.channels)
1450 #print("dataChannels ",self.data.channels)
1452 self.nrows = len(self.data.channels)
1451 self.nrows = len(self.data.channels)
1453 self.nplots = len(self.data.channels)
1452 self.nplots = len(self.data.channels)
1454 self.ylabel = 'Range [km]'
1453 self.ylabel = 'Range [km]'
1455 #self.xlabel = 'Time'
1454 #self.xlabel = 'Time'
1456 self.cb_label = 'dB'
1455 self.cb_label = 'dB'
1457 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1456 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1458 self.titles = ['{} Channel {}'.format(
1457 self.titles = ['{} Channel {}'.format(
1459 self.CODE.upper(), x) for x in range(self.nplots)]
1458 self.CODE.upper(), x) for x in range(self.nplots)]
1460
1459
1461 def update_list(self,dataOut):
1460 def update_list(self,dataOut):
1462 if len(self.channelList) == 0:
1461 if len(self.channelList) == 0:
1463 self.channelList = dataOut.channelList
1462 self.channelList = dataOut.channelList
1464 if len(self.elevationList) == 0:
1463 if len(self.elevationList) == 0:
1465 self.elevationList = dataOut.elevationList
1464 self.elevationList = dataOut.elevationList
1466 if len(self.azimuthList) == 0:
1465 if len(self.azimuthList) == 0:
1467 self.azimuthList = dataOut.azimuthList
1466 self.azimuthList = dataOut.azimuthList
1468
1467
1469 def update(self, dataOut):
1468 def update(self, dataOut):
1470 if len(self.channelList) == 0:
1469 if len(self.channelList) == 0:
1471 self.update_list(dataOut)
1470 self.update_list(dataOut)
1472
1471
1473 data = {}
1472 data = {}
1474 meta = {}
1473 meta = {}
1475 #print(dataOut.max_nIncohInt, dataOut.nIncohInt)
1474 #print(dataOut.max_nIncohInt, dataOut.nIncohInt)
1476 #print(dataOut.windowOfFilter,dataOut.nCohInt,dataOut.nProfiles,dataOut.max_nIncohInt,dataOut.nIncohInt
1475 #print(dataOut.windowOfFilter,dataOut.nCohInt,dataOut.nProfiles,dataOut.max_nIncohInt,dataOut.nIncohInt
1477 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1476 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1478 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1477 n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1479 data['noise'] = n0
1478 data['noise'] = n0
1480 noise = numpy.repeat(n0,dataOut.nHeights).reshape(dataOut.nChannels,dataOut.nHeights)
1479 noise = numpy.repeat(n0,dataOut.nHeights).reshape(dataOut.nChannels,dataOut.nHeights)
1481 noiseless_data = dataOut.getPower() - noise
1480 noiseless_data = dataOut.getPower() - noise
1482
1481
1483 #print("power, noise:", dataOut.getPower(), n0)
1482 #print("power, noise:", dataOut.getPower(), n0)
1484 #print(noise)
1483 #print(noise)
1485 #print(noiseless_data)
1484 #print(noiseless_data)
1486
1485
1487 data['noiseless_rti'] = noiseless_data
1486 data['noiseless_rti'] = noiseless_data
1488
1487
1489 return data, meta
1488 return data, meta
1490
1489
1491 def plot(self):
1490 def plot(self):
1492 from matplotlib import pyplot as plt
1491 from matplotlib import pyplot as plt
1493 self.x = self.data.times
1492 self.x = self.data.times
1494 self.y = self.data.yrange
1493 self.y = self.data.yrange
1495 self.z = self.data['noiseless_rti']
1494 self.z = self.data['noiseless_rti']
1496 self.z = numpy.array(self.z, dtype=float)
1495 self.z = numpy.array(self.z, dtype=float)
1497 self.z = numpy.ma.masked_invalid(self.z)
1496 self.z = numpy.ma.masked_invalid(self.z)
1498
1497
1499
1498
1500 try:
1499 try:
1501 if self.channelList != None:
1500 if self.channelList != None:
1502 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1501 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1503 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1502 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1504 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1503 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1505 else:
1504 else:
1506 self.titles = ['{} Channel {}'.format(
1505 self.titles = ['{} Channel {}'.format(
1507 self.CODE.upper(), x) for x in self.channelList]
1506 self.CODE.upper(), x) for x in self.channelList]
1508 except:
1507 except:
1509 if self.channelList.any() != None:
1508 if self.channelList.any() != None:
1510 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1509 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
1511 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1510 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
1512 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1511 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
1513 else:
1512 else:
1514 self.titles = ['{} Channel {}'.format(
1513 self.titles = ['{} Channel {}'.format(
1515 self.CODE.upper(), x) for x in self.channelList]
1514 self.CODE.upper(), x) for x in self.channelList]
1516
1515
1517
1516
1518 if self.decimation is None:
1517 if self.decimation is None:
1519 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1518 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1520 else:
1519 else:
1521 x, y, z = self.fill_gaps(*self.decimate())
1520 x, y, z = self.fill_gaps(*self.decimate())
1522
1521
1523 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
1522 dummy_var = self.axes #ExtraΓ±amente esto actualiza el valor axes
1524 #print("plot shapes ", z.shape, x.shape, y.shape)
1523 #print("plot shapes ", z.shape, x.shape, y.shape)
1525 #print(self.axes)
1524 #print(self.axes)
1526 for n, ax in enumerate(self.axes):
1525 for n, ax in enumerate(self.axes):
1527
1526
1528
1527
1529 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
1528 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
1530 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
1529 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
1531 data = self.data[-1]
1530 data = self.data[-1]
1532 if ax.firsttime:
1531 if ax.firsttime:
1533 if (n+1) == len(self.channelList):
1532 if (n+1) == len(self.channelList):
1534 ax.set_xlabel('Time')
1533 ax.set_xlabel('Time')
1535 ax.plt = ax.pcolormesh(x, y, z[n].T,
1534 ax.plt = ax.pcolormesh(x, y, z[n].T,
1536 vmin=self.zmin,
1535 vmin=self.zmin,
1537 vmax=self.zmax,
1536 vmax=self.zmax,
1538 cmap=plt.get_cmap(self.colormap)
1537 cmap=plt.get_cmap(self.colormap)
1539 )
1538 )
1540 if self.showprofile:
1539 if self.showprofile:
1541 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
1540 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
1542
1541
1543 else:
1542 else:
1544 # ax.collections.remove(ax.collections[0]) # error while running
1543 ax.collections.remove(ax.collections[0]) # error while running
1545 ax.plt = ax.pcolormesh(x, y, z[n].T,
1544 ax.plt = ax.pcolormesh(x, y, z[n].T,
1546 vmin=self.zmin,
1545 vmin=self.zmin,
1547 vmax=self.zmax,
1546 vmax=self.zmax,
1548 cmap=plt.get_cmap(self.colormap)
1547 cmap=plt.get_cmap(self.colormap)
1549 )
1548 )
1550 if self.showprofile:
1549 if self.showprofile:
1551 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
1550 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
1552 # if "noise" in self.data:
1551 # if "noise" in self.data:
1553 # #ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
1552 # #ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
1554 # ax.plot_noise.set_data(data['noise'][n], self.y)
1553 # ax.plot_noise.set_data(data['noise'][n], self.y)
1555
1554
1556
1555
1557 class OutliersRTIPlot(Plot):
1556 class OutliersRTIPlot(Plot):
1558 '''
1557 '''
1559 Plot for data_xxxx object
1558 Plot for data_xxxx object
1560 '''
1559 '''
1561
1560
1562 CODE = 'outlier_rtc' # Range Time Counts
1561 CODE = 'outlier_rtc' # Range Time Counts
1563 colormap = 'cool'
1562 colormap = 'cool'
1564 plot_type = 'pcolorbuffer'
1563 plot_type = 'pcolorbuffer'
1565
1564
1566 def setup(self):
1565 def setup(self):
1567 self.xaxis = 'time'
1566 self.xaxis = 'time'
1568 self.ncols = 1
1567 self.ncols = 1
1569 self.nrows = self.data.shape('outlier_rtc')[0]
1568 self.nrows = self.data.shape('outlier_rtc')[0]
1570 self.nplots = self.nrows
1569 self.nplots = self.nrows
1571 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1570 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1572
1571
1573
1572
1574 if not self.xlabel:
1573 if not self.xlabel:
1575 self.xlabel = 'Time'
1574 self.xlabel = 'Time'
1576
1575
1577 self.ylabel = 'Height [km]'
1576 self.ylabel = 'Height [km]'
1578 if not self.titles:
1577 if not self.titles:
1579 self.titles = ['Outliers Ch:{}'.format(x) for x in range(self.nrows)]
1578 self.titles = ['Outliers Ch:{}'.format(x) for x in range(self.nrows)]
1580
1579
1581 def update(self, dataOut):
1580 def update(self, dataOut):
1582
1581
1583 data = {}
1582 data = {}
1584 data['outlier_rtc'] = dataOut.data_outlier
1583 data['outlier_rtc'] = dataOut.data_outlier
1585
1584
1586 meta = {}
1585 meta = {}
1587
1586
1588 return data, meta
1587 return data, meta
1589
1588
1590 def plot(self):
1589 def plot(self):
1591 # self.data.normalize_heights()
1590 # self.data.normalize_heights()
1592 self.x = self.data.times
1591 self.x = self.data.times
1593 self.y = self.data.yrange
1592 self.y = self.data.yrange
1594 self.z = self.data['outlier_rtc']
1593 self.z = self.data['outlier_rtc']
1595
1594
1596 #self.z = numpy.ma.masked_invalid(self.z)
1595 #self.z = numpy.ma.masked_invalid(self.z)
1597
1596
1598 if self.decimation is None:
1597 if self.decimation is None:
1599 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1598 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1600 else:
1599 else:
1601 x, y, z = self.fill_gaps(*self.decimate())
1600 x, y, z = self.fill_gaps(*self.decimate())
1602
1601
1603 for n, ax in enumerate(self.axes):
1602 for n, ax in enumerate(self.axes):
1604
1603
1605 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1604 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1606 self.z[n])
1605 self.z[n])
1607 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1606 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1608 self.z[n])
1607 self.z[n])
1609 data = self.data[-1]
1608 data = self.data[-1]
1610 if ax.firsttime:
1609 if ax.firsttime:
1611 if self.zlimits is not None:
1610 if self.zlimits is not None:
1612 self.zmin, self.zmax = self.zlimits[n]
1611 self.zmin, self.zmax = self.zlimits[n]
1613
1612
1614 ax.plt = ax.pcolormesh(x, y, z[n].T,
1613 ax.plt = ax.pcolormesh(x, y, z[n].T,
1615 vmin=self.zmin,
1614 vmin=self.zmin,
1616 vmax=self.zmax,
1615 vmax=self.zmax,
1617 cmap=self.cmaps[n]
1616 cmap=self.cmaps[n]
1618 )
1617 )
1619 if self.showprofile:
1618 if self.showprofile:
1620 ax.plot_profile = self.pf_axes[n].plot(data['outlier_rtc'][n], self.y)[0]
1619 ax.plot_profile = self.pf_axes[n].plot(data['outlier_rtc'][n], self.y)[0]
1621 self.pf_axes[n].set_xlabel('')
1620 self.pf_axes[n].set_xlabel('')
1622 else:
1621 else:
1623 if self.zlimits is not None:
1622 if self.zlimits is not None:
1624 self.zmin, self.zmax = self.zlimits[n]
1623 self.zmin, self.zmax = self.zlimits[n]
1625 # ax.collections.remove(ax.collections[0]) # error while running
1624 ax.collections.remove(ax.collections[0]) # error while running
1626 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1625 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1627 vmin=self.zmin,
1626 vmin=self.zmin,
1628 vmax=self.zmax,
1627 vmax=self.zmax,
1629 cmap=self.cmaps[n]
1628 cmap=self.cmaps[n]
1630 )
1629 )
1631 if self.showprofile:
1630 if self.showprofile:
1632 ax.plot_profile.set_data(data['outlier_rtc'][n], self.y)
1631 ax.plot_profile.set_data(data['outlier_rtc'][n], self.y)
1633 self.pf_axes[n].set_xlabel('')
1632 self.pf_axes[n].set_xlabel('')
1634
1633
1635 class NIncohIntRTIPlot(Plot):
1634 class NIncohIntRTIPlot(Plot):
1636 '''
1635 '''
1637 Plot for data_xxxx object
1636 Plot for data_xxxx object
1638 '''
1637 '''
1639
1638
1640 CODE = 'integrations_rtc' # Range Time Counts
1639 CODE = 'integrations_rtc' # Range Time Counts
1641 colormap = 'BuGn'
1640 colormap = 'BuGn'
1642 plot_type = 'pcolorbuffer'
1641 plot_type = 'pcolorbuffer'
1643
1642
1644 def setup(self):
1643 def setup(self):
1645 self.xaxis = 'time'
1644 self.xaxis = 'time'
1646 self.ncols = 1
1645 self.ncols = 1
1647 self.nrows = self.data.shape('integrations_rtc')[0]
1646 self.nrows = self.data.shape('integrations_rtc')[0]
1648 self.nplots = self.nrows
1647 self.nplots = self.nrows
1649 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1648 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1650
1649
1651
1650
1652 if not self.xlabel:
1651 if not self.xlabel:
1653 self.xlabel = 'Time'
1652 self.xlabel = 'Time'
1654
1653
1655 self.ylabel = 'Height [km]'
1654 self.ylabel = 'Height [km]'
1656 if not self.titles:
1655 if not self.titles:
1657 self.titles = ['Integration Ch:{}'.format(x) for x in range(self.nrows)]
1656 self.titles = ['Integration Ch:{}'.format(x) for x in range(self.nrows)]
1658
1657
1659 def update(self, dataOut):
1658 def update(self, dataOut):
1660
1659
1661 data = {}
1660 data = {}
1662 data['integrations_rtc'] = dataOut.nIncohInt
1661 data['integrations_rtc'] = dataOut.nIncohInt
1663
1662
1664 meta = {}
1663 meta = {}
1665
1664
1666 return data, meta
1665 return data, meta
1667
1666
1668 def plot(self):
1667 def plot(self):
1669 # self.data.normalize_heights()
1668 # self.data.normalize_heights()
1670 self.x = self.data.times
1669 self.x = self.data.times
1671 self.y = self.data.yrange
1670 self.y = self.data.yrange
1672 self.z = self.data['integrations_rtc']
1671 self.z = self.data['integrations_rtc']
1673
1672
1674 #self.z = numpy.ma.masked_invalid(self.z)
1673 #self.z = numpy.ma.masked_invalid(self.z)
1675
1674
1676 if self.decimation is None:
1675 if self.decimation is None:
1677 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1676 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1678 else:
1677 else:
1679 x, y, z = self.fill_gaps(*self.decimate())
1678 x, y, z = self.fill_gaps(*self.decimate())
1680
1679
1681 for n, ax in enumerate(self.axes):
1680 for n, ax in enumerate(self.axes):
1682
1681
1683 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1682 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1684 self.z[n])
1683 self.z[n])
1685 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1684 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1686 self.z[n])
1685 self.z[n])
1687 data = self.data[-1]
1686 data = self.data[-1]
1688 if ax.firsttime:
1687 if ax.firsttime:
1689 if self.zlimits is not None:
1688 if self.zlimits is not None:
1690 self.zmin, self.zmax = self.zlimits[n]
1689 self.zmin, self.zmax = self.zlimits[n]
1691
1690
1692 ax.plt = ax.pcolormesh(x, y, z[n].T,
1691 ax.plt = ax.pcolormesh(x, y, z[n].T,
1693 vmin=self.zmin,
1692 vmin=self.zmin,
1694 vmax=self.zmax,
1693 vmax=self.zmax,
1695 cmap=self.cmaps[n]
1694 cmap=self.cmaps[n]
1696 )
1695 )
1697 if self.showprofile:
1696 if self.showprofile:
1698 ax.plot_profile = self.pf_axes[n].plot(data['integrations_rtc'][n], self.y)[0]
1697 ax.plot_profile = self.pf_axes[n].plot(data['integrations_rtc'][n], self.y)[0]
1699 self.pf_axes[n].set_xlabel('')
1698 self.pf_axes[n].set_xlabel('')
1700 else:
1699 else:
1701 if self.zlimits is not None:
1700 if self.zlimits is not None:
1702 self.zmin, self.zmax = self.zlimits[n]
1701 self.zmin, self.zmax = self.zlimits[n]
1703 # ax.collections.remove(ax.collections[0]) # error while running
1702 ax.collections.remove(ax.collections[0]) # error while running
1704 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1703 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1705 vmin=self.zmin,
1704 vmin=self.zmin,
1706 vmax=self.zmax,
1705 vmax=self.zmax,
1707 cmap=self.cmaps[n]
1706 cmap=self.cmaps[n]
1708 )
1707 )
1709 if self.showprofile:
1708 if self.showprofile:
1710 ax.plot_profile.set_data(data['integrations_rtc'][n], self.y)
1709 ax.plot_profile.set_data(data['integrations_rtc'][n], self.y)
1711 self.pf_axes[n].set_xlabel('')
1710 self.pf_axes[n].set_xlabel('')
1712
1711
1713
1712
1714
1713
1715 class RTIMapPlot(Plot):
1714 class RTIMapPlot(Plot):
1716 '''
1715 '''
1717 Plot for RTI data
1716 Plot for RTI data
1718
1717
1719 Example:
1718 Example:
1720
1719
1721 controllerObj = Project()
1720 controllerObj = Project()
1722 controllerObj.setup(id = '11', name='eej_proc', description=desc)
1721 controllerObj.setup(id = '11', name='eej_proc', description=desc)
1723 ##.......................................................................................
1722 ##.......................................................................................
1724 ##.......................................................................................
1723 ##.......................................................................................
1725 readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', path=inPath, startDate='2023/05/24',endDate='2023/05/24',
1724 readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', path=inPath, startDate='2023/05/24',endDate='2023/05/24',
1726 startTime='12:00:00',endTime='12:45:59',walk=1,timezone='lt',margin_days=1,code = code,nCode = nCode,
1725 startTime='12:00:00',endTime='12:45:59',walk=1,timezone='lt',margin_days=1,code = code,nCode = nCode,
1727 nBaud = nBaud,nOsamp = nosamp,nChannels=nChannels,nFFT=NFFT,
1726 nBaud = nBaud,nOsamp = nosamp,nChannels=nChannels,nFFT=NFFT,
1728 syncronization=False,shiftChannels=0)
1727 syncronization=False,shiftChannels=0)
1729
1728
1730 volts_proc = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
1729 volts_proc = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
1731
1730
1732 opObj01 = volts_proc.addOperation(name='Decoder', optype='other')
1731 opObj01 = volts_proc.addOperation(name='Decoder', optype='other')
1733 opObj01.addParameter(name='code', value=code, format='floatlist')
1732 opObj01.addParameter(name='code', value=code, format='floatlist')
1734 opObj01.addParameter(name='nCode', value=1, format='int')
1733 opObj01.addParameter(name='nCode', value=1, format='int')
1735 opObj01.addParameter(name='nBaud', value=nBaud, format='int')
1734 opObj01.addParameter(name='nBaud', value=nBaud, format='int')
1736 opObj01.addParameter(name='osamp', value=nosamp, format='int')
1735 opObj01.addParameter(name='osamp', value=nosamp, format='int')
1737
1736
1738 opObj12 = volts_proc.addOperation(name='selectHeights', optype='self')
1737 opObj12 = volts_proc.addOperation(name='selectHeights', optype='self')
1739 opObj12.addParameter(name='minHei', value='90', format='float')
1738 opObj12.addParameter(name='minHei', value='90', format='float')
1740 opObj12.addParameter(name='maxHei', value='150', format='float')
1739 opObj12.addParameter(name='maxHei', value='150', format='float')
1741
1740
1742 proc_spc = controllerObj.addProcUnit(datatype='SpectraProc', inputId=volts_proc.getId())
1741 proc_spc = controllerObj.addProcUnit(datatype='SpectraProc', inputId=volts_proc.getId())
1743 proc_spc.addParameter(name='nFFTPoints', value='8', format='int')
1742 proc_spc.addParameter(name='nFFTPoints', value='8', format='int')
1744
1743
1745 opObj11 = proc_spc.addOperation(name='IncohInt', optype='other')
1744 opObj11 = proc_spc.addOperation(name='IncohInt', optype='other')
1746 opObj11.addParameter(name='n', value='1', format='int')
1745 opObj11.addParameter(name='n', value='1', format='int')
1747
1746
1748 beamMapFile = "/home/japaza/Documents/AMISR_sky_mapper/UMET_beamcodes.csv"
1747 beamMapFile = "/home/japaza/Documents/AMISR_sky_mapper/UMET_beamcodes.csv"
1749
1748
1750 opObj12 = proc_spc.addOperation(name='RTIMapPlot', optype='external')
1749 opObj12 = proc_spc.addOperation(name='RTIMapPlot', optype='external')
1751 opObj12.addParameter(name='selectedHeightsList', value='95, 100, 105, 110 ', format='int')
1750 opObj12.addParameter(name='selectedHeightsList', value='95, 100, 105, 110 ', format='int')
1752 opObj12.addParameter(name='bField', value='100', format='int')
1751 opObj12.addParameter(name='bField', value='100', format='int')
1753 opObj12.addParameter(name='filename', value=beamMapFile, format='str')
1752 opObj12.addParameter(name='filename', value=beamMapFile, format='str')
1754
1753
1755 '''
1754 '''
1756
1755
1757 CODE = 'rti_skymap'
1756 CODE = 'rti_skymap'
1758
1757
1759 plot_type = 'scatter'
1758 plot_type = 'scatter'
1760 titles = None
1759 titles = None
1761 colormap = 'jet'
1760 colormap = 'jet'
1762 channelList = []
1761 channelList = []
1763 elevationList = []
1762 elevationList = []
1764 azimuthList = []
1763 azimuthList = []
1765 last_noise = None
1764 last_noise = None
1766 flag_setIndex = False
1765 flag_setIndex = False
1767 heights = []
1766 heights = []
1768 dcosx = []
1767 dcosx = []
1769 dcosy = []
1768 dcosy = []
1770 fullDcosy = None
1769 fullDcosy = None
1771 fullDcosy = None
1770 fullDcosy = None
1772 hindex = []
1771 hindex = []
1773 mapFile = False
1772 mapFile = False
1774 ##### BField ####
1773 ##### BField ####
1775 flagBField = False
1774 flagBField = False
1776 dcosxB = []
1775 dcosxB = []
1777 dcosyB = []
1776 dcosyB = []
1778 Bmarker = ['+','*','D','x','s','>','o','^']
1777 Bmarker = ['+','*','D','x','s','>','o','^']
1779
1778
1780
1779
1781 def setup(self):
1780 def setup(self):
1782
1781
1783 self.xaxis = 'Range (Km)'
1782 self.xaxis = 'Range (Km)'
1784 if len(self.selectedHeightsList) > 0:
1783 if len(self.selectedHeightsList) > 0:
1785 self.nplots = len(self.selectedHeightsList)
1784 self.nplots = len(self.selectedHeightsList)
1786 else:
1785 else:
1787 self.nplots = 4
1786 self.nplots = 4
1788 self.ncols = int(numpy.ceil(self.nplots/2))
1787 self.ncols = int(numpy.ceil(self.nplots/2))
1789 self.nrows = int(numpy.ceil(self.nplots/self.ncols))
1788 self.nrows = int(numpy.ceil(self.nplots/self.ncols))
1790 self.ylabel = 'dcosy'
1789 self.ylabel = 'dcosy'
1791 self.xlabel = 'dcosx'
1790 self.xlabel = 'dcosx'
1792 self.colorbar = True
1791 self.colorbar = True
1793 self.width = 6 + 4.1*self.nrows
1792 self.width = 6 + 4.1*self.nrows
1794 self.height = 3 + 3.5*self.ncols
1793 self.height = 3 + 3.5*self.ncols
1795
1794
1796
1795
1797 if self.extFile!=None:
1796 if self.extFile!=None:
1798 try:
1797 try:
1799 pointings = numpy.genfromtxt(self.extFile, delimiter=',')
1798 pointings = numpy.genfromtxt(self.extFile, delimiter=',')
1800 full_azi = pointings[:,1]
1799 full_azi = pointings[:,1]
1801 full_elev = pointings[:,2]
1800 full_elev = pointings[:,2]
1802 self.fullDcosx = numpy.cos(numpy.radians(full_elev))*numpy.sin(numpy.radians(full_azi))
1801 self.fullDcosx = numpy.cos(numpy.radians(full_elev))*numpy.sin(numpy.radians(full_azi))
1803 self.fullDcosy = numpy.cos(numpy.radians(full_elev))*numpy.cos(numpy.radians(full_azi))
1802 self.fullDcosy = numpy.cos(numpy.radians(full_elev))*numpy.cos(numpy.radians(full_azi))
1804 mapFile = True
1803 mapFile = True
1805 except Exception as e:
1804 except Exception as e:
1806 self.extFile = None
1805 self.extFile = None
1807 print(e)
1806 print(e)
1808
1807
1809
1808
1810 def update_list(self,dataOut):
1809 def update_list(self,dataOut):
1811 if len(self.channelList) == 0:
1810 if len(self.channelList) == 0:
1812 self.channelList = dataOut.channelList
1811 self.channelList = dataOut.channelList
1813 if len(self.elevationList) == 0:
1812 if len(self.elevationList) == 0:
1814 self.elevationList = dataOut.elevationList
1813 self.elevationList = dataOut.elevationList
1815 if len(self.azimuthList) == 0:
1814 if len(self.azimuthList) == 0:
1816 self.azimuthList = dataOut.azimuthList
1815 self.azimuthList = dataOut.azimuthList
1817 a = numpy.radians(numpy.asarray(self.azimuthList))
1816 a = numpy.radians(numpy.asarray(self.azimuthList))
1818 e = numpy.radians(numpy.asarray(self.elevationList))
1817 e = numpy.radians(numpy.asarray(self.elevationList))
1819 self.heights = dataOut.heightList
1818 self.heights = dataOut.heightList
1820 self.dcosx = numpy.cos(e)*numpy.sin(a)
1819 self.dcosx = numpy.cos(e)*numpy.sin(a)
1821 self.dcosy = numpy.cos(e)*numpy.cos(a)
1820 self.dcosy = numpy.cos(e)*numpy.cos(a)
1822
1821
1823 if len(self.bFieldList)>0:
1822 if len(self.bFieldList)>0:
1824 datetObj = datetime.datetime.fromtimestamp(dataOut.utctime)
1823 datetObj = datetime.datetime.fromtimestamp(dataOut.utctime)
1825 doy = datetObj.timetuple().tm_yday
1824 doy = datetObj.timetuple().tm_yday
1826 year = datetObj.year
1825 year = datetObj.year
1827 # self.dcosxB, self.dcosyB
1826 # self.dcosxB, self.dcosyB
1828 ObjB = BField(year=year,doy=doy,site=2,heights=self.bFieldList)
1827 ObjB = BField(year=year,doy=doy,site=2,heights=self.bFieldList)
1829 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1828 [dcos, alpha, nlon, nlat] = ObjB.getBField()
1830
1829
1831 alpha_location = numpy.zeros((nlon,2,len(self.bFieldList)))
1830 alpha_location = numpy.zeros((nlon,2,len(self.bFieldList)))
1832 for ih in range(len(self.bFieldList)):
1831 for ih in range(len(self.bFieldList)):
1833 alpha_location[:,0,ih] = dcos[:,0,ih,0]
1832 alpha_location[:,0,ih] = dcos[:,0,ih,0]
1834 for ilon in numpy.arange(nlon):
1833 for ilon in numpy.arange(nlon):
1835 myx = (alpha[ilon,:,ih])[::-1]
1834 myx = (alpha[ilon,:,ih])[::-1]
1836 myy = (dcos[ilon,:,ih,0])[::-1]
1835 myy = (dcos[ilon,:,ih,0])[::-1]
1837 tck = splrep(myx,myy,s=0)
1836 tck = splrep(myx,myy,s=0)
1838 mydcosx = splev(ObjB.alpha_i,tck,der=0)
1837 mydcosx = splev(ObjB.alpha_i,tck,der=0)
1839
1838
1840 myx = (alpha[ilon,:,ih])[::-1]
1839 myx = (alpha[ilon,:,ih])[::-1]
1841 myy = (dcos[ilon,:,ih,1])[::-1]
1840 myy = (dcos[ilon,:,ih,1])[::-1]
1842 tck = splrep(myx,myy,s=0)
1841 tck = splrep(myx,myy,s=0)
1843 mydcosy = splev(ObjB.alpha_i,tck,der=0)
1842 mydcosy = splev(ObjB.alpha_i,tck,der=0)
1844 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
1843 alpha_location[ilon,:,ih] = numpy.array([mydcosx, mydcosy])
1845 self.dcosxB.append(alpha_location[:,0,ih])
1844 self.dcosxB.append(alpha_location[:,0,ih])
1846 self.dcosyB.append(alpha_location[:,1,ih])
1845 self.dcosyB.append(alpha_location[:,1,ih])
1847 self.flagBField = True
1846 self.flagBField = True
1848
1847
1849 if len(self.celestialList)>0:
1848 if len(self.celestialList)>0:
1850 #getBField(self.bFieldList, date)
1849 #getBField(self.bFieldList, date)
1851 #pass = kwargs.get('celestial', [])
1850 #pass = kwargs.get('celestial', [])
1852 pass
1851 pass
1853
1852
1854
1853
1855 def update(self, dataOut):
1854 def update(self, dataOut):
1856
1855
1857 if len(self.channelList) == 0:
1856 if len(self.channelList) == 0:
1858 self.update_list(dataOut)
1857 self.update_list(dataOut)
1859
1858
1860 if not self.flag_setIndex:
1859 if not self.flag_setIndex:
1861 if len(self.selectedHeightsList)>0:
1860 if len(self.selectedHeightsList)>0:
1862 for sel_height in self.selectedHeightsList:
1861 for sel_height in self.selectedHeightsList:
1863 index_list = numpy.where(self.heights >= sel_height)
1862 index_list = numpy.where(self.heights >= sel_height)
1864 index_list = index_list[0]
1863 index_list = index_list[0]
1865 self.hindex.append(index_list[0])
1864 self.hindex.append(index_list[0])
1866 self.flag_setIndex = True
1865 self.flag_setIndex = True
1867
1866
1868 data = {}
1867 data = {}
1869 meta = {}
1868 meta = {}
1870
1869
1871 data['rti_skymap'] = dataOut.getPower()
1870 data['rti_skymap'] = dataOut.getPower()
1872 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1871 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
1873 noise = 10*numpy.log10(dataOut.getNoise()/norm)
1872 noise = 10*numpy.log10(dataOut.getNoise()/norm)
1874 data['noise'] = noise
1873 data['noise'] = noise
1875
1874
1876 return data, meta
1875 return data, meta
1877
1876
1878 def plot(self):
1877 def plot(self):
1879
1878
1880 self.x = self.dcosx
1879 self.x = self.dcosx
1881 self.y = self.dcosy
1880 self.y = self.dcosy
1882 self.z = self.data[-1]['rti_skymap']
1881 self.z = self.data[-1]['rti_skymap']
1883 self.z = numpy.array(self.z, dtype=float)
1882 self.z = numpy.array(self.z, dtype=float)
1884
1883
1885 if len(self.hindex) > 0:
1884 if len(self.hindex) > 0:
1886 index = self.hindex
1885 index = self.hindex
1887 else:
1886 else:
1888 index = numpy.arange(0, len(self.heights), int((len(self.heights))/4.2))
1887 index = numpy.arange(0, len(self.heights), int((len(self.heights))/4.2))
1889
1888
1890 self.titles = ['Height {:.2f} km '.format(self.heights[i])+" " for i in index]
1889 self.titles = ['Height {:.2f} km '.format(self.heights[i])+" " for i in index]
1891 for n, ax in enumerate(self.axes):
1890 for n, ax in enumerate(self.axes):
1892
1891
1893 if ax.firsttime:
1892 if ax.firsttime:
1894
1893
1895 self.xmax = self.xmax if self.xmax else numpy.nanmax(self.x)
1894 self.xmax = self.xmax if self.xmax else numpy.nanmax(self.x)
1896 self.xmin = self.xmin if self.xmin else numpy.nanmin(self.x)
1895 self.xmin = self.xmin if self.xmin else numpy.nanmin(self.x)
1897 self.ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
1896 self.ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
1898 self.ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
1897 self.ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
1899 self.zmax = self.zmax if self.zmax else numpy.nanmax(self.z)
1898 self.zmax = self.zmax if self.zmax else numpy.nanmax(self.z)
1900 self.zmin = self.zmin if self.zmin else numpy.nanmin(self.z)
1899 self.zmin = self.zmin if self.zmin else numpy.nanmin(self.z)
1901
1900
1902 if self.extFile!=None:
1901 if self.extFile!=None:
1903 ax.scatter(self.fullDcosx, self.fullDcosy, marker="+", s=20)
1902 ax.scatter(self.fullDcosx, self.fullDcosy, marker="+", s=20)
1904
1903
1905 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1904 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1906 s=60, marker="s", vmax = self.zmax)
1905 s=60, marker="s", vmax = self.zmax)
1907
1906
1908
1907
1909 ax.minorticks_on()
1908 ax.minorticks_on()
1910 ax.grid(which='major', axis='both')
1909 ax.grid(which='major', axis='both')
1911 ax.grid(which='minor', axis='x')
1910 ax.grid(which='minor', axis='x')
1912
1911
1913 if self.flagBField :
1912 if self.flagBField :
1914
1913
1915 for ih in range(len(self.bFieldList)):
1914 for ih in range(len(self.bFieldList)):
1916 label = str(self.bFieldList[ih]) + ' km'
1915 label = str(self.bFieldList[ih]) + ' km'
1917 ax.plot(self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1916 ax.plot(self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1918 label=label, linestyle='--', ms=4.0,lw=0.5)
1917 label=label, linestyle='--', ms=4.0,lw=0.5)
1919 handles, labels = ax.get_legend_handles_labels()
1918 handles, labels = ax.get_legend_handles_labels()
1920 a = -0.05
1919 a = -0.05
1921 b = 1.15 - 1.19*(self.nrows)
1920 b = 1.15 - 1.19*(self.nrows)
1922 self.axes[0].legend(handles,labels, bbox_to_anchor=(a,b), prop={'size': (5.8+ 1.1*self.nplots)}, title='B Field βŠ₯')
1921 self.axes[0].legend(handles,labels, bbox_to_anchor=(a,b), prop={'size': (5.8+ 1.1*self.nplots)}, title='B Field βŠ₯')
1923
1922
1924 else:
1923 else:
1925
1924
1926 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1925 ax.plt = ax.scatter(self.x, self.y, c=self.z[:,index[n]], cmap = 'jet',vmin = self.zmin,
1927 s=80, marker="s", vmax = self.zmax)
1926 s=80, marker="s", vmax = self.zmax)
1928
1927
1929 if self.flagBField :
1928 if self.flagBField :
1930 for ih in range(len(self.bFieldList)):
1929 for ih in range(len(self.bFieldList)):
1931 ax.plot (self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1930 ax.plot (self.dcosxB[ih], self.dcosyB[ih], color='k', marker=self.Bmarker[ih % 8],
1932 linestyle='--', ms=4.0,lw=0.5)
1931 linestyle='--', ms=4.0,lw=0.5)
1933
1932
1934
1933
1935
1934
@@ -1,819 +1,820
1 import os
1 import os
2 import time
2 import time
3 import datetime
3 import datetime
4
4
5 import numpy
5 import numpy
6 import h5py
6 import h5py
7
7
8 import schainpy.admin
8 import schainpy.admin
9 from schainpy.model.data.jrodata import *
9 from schainpy.model.data.jrodata import *
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
11 from schainpy.model.io.jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
12 from schainpy.utils import log
12 from schainpy.utils import log
13
13
14
14
15 class HDFReader(Reader, ProcessingUnit):
15 class HDFReader(Reader, ProcessingUnit):
16 """Processing unit to read HDF5 format files
16 """Processing unit to read HDF5 format files
17
17
18 This unit reads HDF5 files created with `HDFWriter` operation contains
18 This unit reads HDF5 files created with `HDFWriter` operation contains
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
20 attributes.
20 attributes.
21 It is possible to read any HDF5 file by given the structure in the `description`
21 It is possible to read any HDF5 file by given the structure in the `description`
22 parameter, also you can add extra values to metadata with the parameter `extras`.
22 parameter, also you can add extra values to metadata with the parameter `extras`.
23
23
24 Parameters:
24 Parameters:
25 -----------
25 -----------
26 path : str
26 path : str
27 Path where files are located.
27 Path where files are located.
28 startDate : date
28 startDate : date
29 Start date of the files
29 Start date of the files
30 endDate : list
30 endDate : list
31 End date of the files
31 End date of the files
32 startTime : time
32 startTime : time
33 Start time of the files
33 Start time of the files
34 endTime : time
34 endTime : time
35 End time of the files
35 End time of the files
36 description : dict, optional
36 description : dict, optional
37 Dictionary with the description of the HDF5 file
37 Dictionary with the description of the HDF5 file
38 extras : dict, optional
38 extras : dict, optional
39 Dictionary with extra metadata to be be added to `dataOut`
39 Dictionary with extra metadata to be be added to `dataOut`
40
40
41 Attention: Be carefull, add attribute utcoffset, in the last part of reader in order to work in Local Time without time problems.
41 Attention: Be carefull, add attribute utcoffset, in the last part of reader in order to work in Local Time without time problems.
42
42
43 -----------
43 -----------
44 utcoffset='-18000'
44 utcoffset='-18000'
45
45
46
46
47 Examples
47 Examples
48 --------
48 --------
49
49
50 desc = {
50 desc = {
51 'Data': {
51 'Data': {
52 'data_output': ['u', 'v', 'w'],
52 'data_output': ['u', 'v', 'w'],
53 'utctime': 'timestamps',
53 'utctime': 'timestamps',
54 } ,
54 } ,
55 'Metadata': {
55 'Metadata': {
56 'heightList': 'heights'
56 'heightList': 'heights'
57 }
57 }
58 }
58 }
59
59
60 desc = {
60 desc = {
61 'Data': {
61 'Data': {
62 'data_output': 'winds',
62 'data_output': 'winds',
63 'utctime': 'timestamps'
63 'utctime': 'timestamps'
64 },
64 },
65 'Metadata': {
65 'Metadata': {
66 'heightList': 'heights'
66 'heightList': 'heights'
67 }
67 }
68 }
68 }
69
69
70 extras = {
70 extras = {
71 'timeZone': 300
71 'timeZone': 300
72 }
72 }
73
73
74 reader = project.addReadUnit(
74 reader = project.addReadUnit(
75 name='HDFReader',
75 name='HDFReader',
76 path='/path/to/files',
76 path='/path/to/files',
77 startDate='2019/01/01',
77 startDate='2019/01/01',
78 endDate='2019/01/31',
78 endDate='2019/01/31',
79 startTime='00:00:00',
79 startTime='00:00:00',
80 endTime='23:59:59',
80 endTime='23:59:59',
81 utcoffset='-18000'
81 utcoffset='-18000'
82 # description=json.dumps(desc),
82 # description=json.dumps(desc),
83 # extras=json.dumps(extras),
83 # extras=json.dumps(extras),
84 )
84 )
85
85
86 """
86 """
87
87
88 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
88 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
89
89
90 def __init__(self):
90 def __init__(self):
91
91
92 ProcessingUnit.__init__(self)
92 ProcessingUnit.__init__(self)
93 self.ext = ".hdf5"
93 self.ext = ".hdf5"
94 self.optchar = "D"
94 self.optchar = "D"
95 self.meta = {}
95 self.meta = {}
96 self.data = {}
96 self.data = {}
97 self.open_file = h5py.File
97 self.open_file = h5py.File
98 self.open_mode = 'r'
98 self.open_mode = 'r'
99 self.description = {}
99 self.description = {}
100 self.extras = {}
100 self.extras = {}
101 self.filefmt = "*%Y%j***"
101 self.filefmt = "*%Y%j***"
102 self.folderfmt = "*%Y%j"
102 self.folderfmt = "*%Y%j"
103 self.utcoffset = 0
103 self.utcoffset = 0
104 self.flagUpdateDataOut = False
104 self.flagUpdateDataOut = False
105 self.dataOut = Parameters()
105 self.dataOut = Parameters()
106 self.dataOut.error=False ## NOTE: Importante definir esto antes inicio
106 self.dataOut.error=False ## NOTE: Importante definir esto antes inicio
107 self.dataOut.flagNoData = True
107 self.dataOut.flagNoData = True
108
108
109 def setup(self, **kwargs):
109 def setup(self, **kwargs):
110
110
111 self.set_kwargs(**kwargs)
111 self.set_kwargs(**kwargs)
112 if not self.ext.startswith('.'):
112 if not self.ext.startswith('.'):
113 self.ext = '.{}'.format(self.ext)
113 self.ext = '.{}'.format(self.ext)
114
114
115 if self.online:
115 if self.online:
116 log.log("Searching files in online mode...", self.name)
116 log.log("Searching files in online mode...", self.name)
117
117
118 for nTries in range(self.nTries):
118 for nTries in range(self.nTries):
119 fullpath = self.searchFilesOnLine(self.path, self.startDate,
119 fullpath = self.searchFilesOnLine(self.path, self.startDate,
120 self.endDate, self.expLabel, self.ext, self.walk,
120 self.endDate, self.expLabel, self.ext, self.walk,
121 self.filefmt, self.folderfmt)
121 self.filefmt, self.folderfmt)
122 pathname, filename = os.path.split(fullpath)
122 pathname, filename = os.path.split(fullpath)
123 try:
123 try:
124 fullpath = next(fullpath)
124 fullpath = next(fullpath)
125 except:
125 except:
126 fullpath = None
126 fullpath = None
127
127
128 if fullpath:
128 if fullpath:
129 break
129 break
130
130
131 log.warning(
131 log.warning(
132 'Waiting {} sec for a valid file in {}: try {} ...'.format(
132 'Waiting {} sec for a valid file in {}: try {} ...'.format(
133 self.delay, self.path, nTries + 1),
133 self.delay, self.path, nTries + 1),
134 self.name)
134 self.name)
135 time.sleep(self.delay)
135 time.sleep(self.delay)
136
136
137 if not(fullpath):
137 if not(fullpath):
138 raise schainpy.admin.SchainError(
138 raise schainpy.admin.SchainError(
139 'There isn\'t any valid file in {}'.format(self.path))
139 'There isn\'t any valid file in {}'.format(self.path))
140
140
141 pathname, filename = os.path.split(fullpath)
141 pathname, filename = os.path.split(fullpath)
142 self.year = int(filename[1:5])
142 self.year = int(filename[1:5])
143 self.doy = int(filename[5:8])
143 self.doy = int(filename[5:8])
144 self.set = int(filename[8:11]) - 1
144 self.set = int(filename[8:11]) - 1
145 else:
145 else:
146 log.log("Searching files in {}".format(self.path), self.name)
146 log.log("Searching files in {}".format(self.path), self.name)
147 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
147 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
148 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
148 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
149
149
150 self.setNextFile()
150 self.setNextFile()
151
151
152 return
152 return
153
153
154 # def readFirstHeader(self):
154 # def readFirstHeader(self):
155 # '''Read metadata and data'''
155 # '''Read metadata and data'''
156
156
157 # self.__readMetadata()
157 # self.__readMetadata()
158 # self.__readData()
158 # self.__readData()
159 # self.__setBlockList()
159 # self.__setBlockList()
160
160
161 # if 'type' in self.meta:
161 # if 'type' in self.meta:
162 # self.dataOut = eval(self.meta['type'])()
162 # self.dataOut = eval(self.meta['type'])()
163
163
164 # for attr in self.meta:
164 # for attr in self.meta:
165 # setattr(self.dataOut, attr, self.meta[attr])
165 # setattr(self.dataOut, attr, self.meta[attr])
166
166
167 # self.blockIndex = 0
167 # self.blockIndex = 0
168
168
169 # return
169 # return
170
170
171 def readFirstHeader(self):
171 def readFirstHeader(self):
172 '''Read metadata and data'''
172 '''Read metadata and data'''
173
173
174 self.__readMetadata2()
174 self.__readMetadata2()
175 self.__readData()
175 self.__readData()
176 self.__setBlockList()
176 self.__setBlockList()
177 if 'type' in self.meta:
177 # if 'type' in self.meta:
178 self.dataOut = eval(self.meta['type'])()
178 # self.dataOut = eval(self.meta['type'])()
179
179
180 for attr in self.meta:
180 for attr in self.meta:
181 if "processingHeaderObj" in attr:
181 if "processingHeaderObj" in attr:
182 self.flagUpdateDataOut=True
182 self.flagUpdateDataOut=True
183 at = attr.split('.')
183 at = attr.split('.')
184 if len(at) > 1:
184 if len(at) > 1:
185 setattr(eval("self.dataOut."+at[0]),at[1], self.meta[attr])
185 setattr(eval("self.dataOut."+at[0]),at[1], self.meta[attr])
186 else:
186 else:
187 setattr(self.dataOut, attr, self.meta[attr])
187 setattr(self.dataOut, attr, self.meta[attr])
188 self.blockIndex = 0
188 self.blockIndex = 0
189
189
190 if self.flagUpdateDataOut:
190 if self.flagUpdateDataOut:
191 self.updateDataOut()
191 self.updateDataOut()
192
192
193 return
193 return
194
194
195 def updateDataOut(self):
195 def updateDataOut(self):
196
196
197 self.dataOut.azimuthList = self.dataOut.processingHeaderObj.azimuthList
197 self.dataOut.azimuthList = self.dataOut.processingHeaderObj.azimuthList
198 self.dataOut.elevationList = self.dataOut.processingHeaderObj.elevationList
198 self.dataOut.elevationList = self.dataOut.processingHeaderObj.elevationList
199 self.dataOut.heightList = self.dataOut.processingHeaderObj.heightList
199 self.dataOut.heightList = self.dataOut.processingHeaderObj.heightList
200 self.dataOut.ippSeconds = self.dataOut.processingHeaderObj.ipp
200 self.dataOut.ippSeconds = self.dataOut.processingHeaderObj.ipp
201 self.dataOut.elevationList = self.dataOut.processingHeaderObj.elevationList
201 self.dataOut.elevationList = self.dataOut.processingHeaderObj.elevationList
202 self.dataOut.channelList = self.dataOut.processingHeaderObj.channelList
202 self.dataOut.channelList = self.dataOut.processingHeaderObj.channelList
203 self.dataOut.nCohInt = self.dataOut.processingHeaderObj.nCohInt
203 self.dataOut.nCohInt = self.dataOut.processingHeaderObj.nCohInt
204 self.dataOut.nFFTPoints = self.dataOut.processingHeaderObj.nFFTPoints
204 self.dataOut.nFFTPoints = self.dataOut.processingHeaderObj.nFFTPoints
205 self.flagUpdateDataOut = False
205 self.flagUpdateDataOut = False
206 self.dataOut.frequency = self.dataOut.radarControllerHeaderObj.frequency
206 self.dataOut.frequency = self.dataOut.radarControllerHeaderObj.frequency
207 #self.dataOut.heightList = self.dataOut.processingHeaderObj.heightList
207 #self.dataOut.heightList = self.dataOut.processingHeaderObj.heightList
208
208
209 def __setBlockList(self):
209 def __setBlockList(self):
210 '''
210 '''
211 Selects the data within the times defined
211 Selects the data within the times defined
212
212
213 self.fp
213 self.fp
214 self.startTime
214 self.startTime
215 self.endTime
215 self.endTime
216 self.blockList
216 self.blockList
217 self.blocksPerFile
217 self.blocksPerFile
218
218
219 '''
219 '''
220
220
221 startTime = self.startTime
221 startTime = self.startTime
222 endTime = self.endTime
222 endTime = self.endTime
223 thisUtcTime = self.data['utctime'] + self.utcoffset
223 thisUtcTime = self.data['utctime'] + self.utcoffset
224 # self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
224 # self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
225 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
225 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
226 self.startFileDatetime = thisDatetime
226 self.startFileDatetime = thisDatetime
227 thisDate = thisDatetime.date()
227 thisDate = thisDatetime.date()
228 thisTime = thisDatetime.time()
228 thisTime = thisDatetime.time()
229 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
229 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
230 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
230 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
231 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
231 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
232
232
233 self.blockList = ind
233 self.blockList = ind
234 self.blocksPerFile = len(ind)
234 self.blocksPerFile = len(ind)
235 # self.blocksPerFile = len(thisUtcTime)
235 # self.blocksPerFile = len(thisUtcTime)
236 if len(ind)==0:
236 if len(ind)==0:
237 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.blockIndex,
237 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.blockIndex,
238 self.blocksPerFile,
238 self.blocksPerFile,
239 thisDatetime))
239 thisDatetime))
240 self.setNextFile()
240 self.setNextFile()
241
241
242 return
242 return
243
243
244 def __readMetadata(self):
244 def __readMetadata(self):
245 '''
245 '''
246 Reads Metadata
246 Reads Metadata
247 '''
247 '''
248
248
249 meta = {}
249 meta = {}
250
250
251 if self.description:
251 if self.description:
252 for key, value in self.description['Metadata'].items():
252 for key, value in self.description['Metadata'].items():
253 meta[key] = self.fp[value][()]
253 meta[key] = self.fp[value][()]
254 else:
254 else:
255 grp = self.fp['Metadata']
255 grp = self.fp['Metadata']
256 for name in grp:
256 for name in grp:
257 meta[name] = grp[name][()]
257 meta[name] = grp[name][()]
258
258
259 if self.extras:
259 if self.extras:
260 for key, value in self.extras.items():
260 for key, value in self.extras.items():
261 meta[key] = value
261 meta[key] = value
262 self.meta = meta
262 self.meta = meta
263
263
264 return
264 return
265
265
266 def __readMetadata2(self):
266 def __readMetadata2(self):
267 '''
267 '''
268 Reads Metadata
268 Reads Metadata
269 '''
269 '''
270 meta = {}
270 meta = {}
271
271 if self.description:
272 if self.description:
272 for key, value in self.description['Metadata'].items():
273 for key, value in self.description['Metadata'].items():
273 meta[key] = self.fp[value][()]
274 meta[key] = self.fp[value][()]
274 else:
275 else:
275 grp = self.fp['Metadata']
276 grp = self.fp['Metadata']
276 for item in grp.values():
277 for item in grp.values():
277 name = item.name
278 name = item.name
278 if isinstance(item, h5py.Dataset):
279 if isinstance(item, h5py.Dataset):
279 name = name.split("/")[-1]
280 name = name.split("/")[-1]
280 meta[name] = item[()]
281 meta[name] = item[()]
281 else:
282 else:
282 grp2 = self.fp[name]
283 grp2 = self.fp[name]
283 Obj = name.split("/")[-1]
284 Obj = name.split("/")[-1]
284
285
285 for item2 in grp2.values():
286 for item2 in grp2.values():
286 name2 = Obj+"."+item2.name.split("/")[-1]
287 name2 = Obj+"."+item2.name.split("/")[-1]
287 meta[name2] = item2[()]
288 meta[name2] = item2[()]
288
289
289 if self.extras:
290 if self.extras:
290 for key, value in self.extras.items():
291 for key, value in self.extras.items():
291 meta[key] = value
292 meta[key] = value
292 self.meta = meta
293 self.meta = meta
293
294
294 return
295 return
295
296
296 def __readData(self):
297 def __readData(self):
297
298
298 data = {}
299 data = {}
299
300
300 if self.description:
301 if self.description:
301 for key, value in self.description['Data'].items():
302 for key, value in self.description['Data'].items():
302 if isinstance(value, str):
303 if isinstance(value, str):
303 if isinstance(self.fp[value], h5py.Dataset):
304 if isinstance(self.fp[value], h5py.Dataset):
304 data[key] = self.fp[value][()]
305 data[key] = self.fp[value][()]
305 elif isinstance(self.fp[value], h5py.Group):
306 elif isinstance(self.fp[value], h5py.Group):
306 array = []
307 array = []
307 for ch in self.fp[value]:
308 for ch in self.fp[value]:
308 array.append(self.fp[value][ch][()])
309 array.append(self.fp[value][ch][()])
309 data[key] = numpy.array(array)
310 data[key] = numpy.array(array)
310 elif isinstance(value, list):
311 elif isinstance(value, list):
311 array = []
312 array = []
312 for ch in value:
313 for ch in value:
313 array.append(self.fp[ch][()])
314 array.append(self.fp[ch][()])
314 data[key] = numpy.array(array)
315 data[key] = numpy.array(array)
315 else:
316 else:
316 grp = self.fp['Data']
317 grp = self.fp['Data']
317 for name in grp:
318 for name in grp:
318 if isinstance(grp[name], h5py.Dataset):
319 if isinstance(grp[name], h5py.Dataset):
319 array = grp[name][()]
320 array = grp[name][()]
320 elif isinstance(grp[name], h5py.Group):
321 elif isinstance(grp[name], h5py.Group):
321 array = []
322 array = []
322 for ch in grp[name]:
323 for ch in grp[name]:
323 array.append(grp[name][ch][()])
324 array.append(grp[name][ch][()])
324 array = numpy.array(array)
325 array = numpy.array(array)
325 else:
326 else:
326 log.warning('Unknown type: {}'.format(name))
327 log.warning('Unknown type: {}'.format(name))
327
328
328 if name in self.description:
329 if name in self.description:
329 key = self.description[name]
330 key = self.description[name]
330 else:
331 else:
331 key = name
332 key = name
332 data[key] = array
333 data[key] = array
333
334
334 self.data = data
335 self.data = data
335 return
336 return
336
337
337 def getData(self):
338 def getData(self):
338
339
339 if not self.isDateTimeInRange(self.startFileDatetime, self.startDate, self.endDate, self.startTime, self.endTime):
340 if not self.isDateTimeInRange(self.startFileDatetime, self.startDate, self.endDate, self.startTime, self.endTime):
340 self.dataOut.flagNoData = True
341 self.dataOut.flagNoData = True
341 self.blockIndex = self.blocksPerFile
342 self.blockIndex = self.blocksPerFile
342 self.dataOut.error = True # TERMINA EL PROGRAMA
343 self.dataOut.error = True # TERMINA EL PROGRAMA
343 return
344 return
344 for attr in self.data:
345 for attr in self.data:
345
346
346 if self.data[attr].ndim == 1:
347 if self.data[attr].ndim == 1:
347 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
348 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
348 else:
349 else:
349 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
350 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
350
351
351
352
352 self.blockIndex += 1
353 self.blockIndex += 1
353
354
354 if self.blockIndex == 1:
355 if self.blockIndex == 1:
355 log.log("Block No. {}/{} -> {}".format(
356 log.log("Block No. {}/{} -> {}".format(
356 self.blockIndex,
357 self.blockIndex,
357 self.blocksPerFile,
358 self.blocksPerFile,
358 self.dataOut.datatime.ctime()), self.name)
359 self.dataOut.datatime.ctime()), self.name)
359 else:
360 else:
360 log.log("Block No. {}/{} ".format(
361 log.log("Block No. {}/{} ".format(
361 self.blockIndex,
362 self.blockIndex,
362 self.blocksPerFile),self.name)
363 self.blocksPerFile),self.name)
363
364
364 if self.blockIndex == self.blocksPerFile:
365 if self.blockIndex == self.blocksPerFile:
365 self.setNextFile()
366 self.setNextFile()
366
367
367 self.dataOut.flagNoData = False
368 self.dataOut.flagNoData = False
368
369
369 return
370 return
370
371
371 def run(self, **kwargs):
372 def run(self, **kwargs):
372
373
373 if not(self.isConfig):
374 if not(self.isConfig):
374 self.setup(**kwargs)
375 self.setup(**kwargs)
375 self.isConfig = True
376 self.isConfig = True
376
377
377 if self.blockIndex == self.blocksPerFile:
378 if self.blockIndex == self.blocksPerFile:
378 self.setNextFile()
379 self.setNextFile()
379
380
380 self.getData()
381 self.getData()
381
382
382 return
383 return
383
384
384 @MPDecorator
385 @MPDecorator
385 class HDFWriter(Operation):
386 class HDFWriter(Operation):
386 """Operation to write HDF5 files.
387 """Operation to write HDF5 files.
387
388
388 The HDF5 file contains by default two groups Data and Metadata where
389 The HDF5 file contains by default two groups Data and Metadata where
389 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
390 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
390 parameters, data attributes are normaly time dependent where the metadata
391 parameters, data attributes are normaly time dependent where the metadata
391 are not.
392 are not.
392 It is possible to customize the structure of the HDF5 file with the
393 It is possible to customize the structure of the HDF5 file with the
393 optional description parameter see the examples.
394 optional description parameter see the examples.
394
395
395 Parameters:
396 Parameters:
396 -----------
397 -----------
397 path : str
398 path : str
398 Path where files will be saved.
399 Path where files will be saved.
399 blocksPerFile : int
400 blocksPerFile : int
400 Number of blocks per file
401 Number of blocks per file
401 metadataList : list
402 metadataList : list
402 List of the dataOut attributes that will be saved as metadata
403 List of the dataOut attributes that will be saved as metadata
403 dataList : int
404 dataList : int
404 List of the dataOut attributes that will be saved as data
405 List of the dataOut attributes that will be saved as data
405 setType : bool
406 setType : bool
406 If True the name of the files corresponds to the timestamp of the data
407 If True the name of the files corresponds to the timestamp of the data
407 description : dict, optional
408 description : dict, optional
408 Dictionary with the desired description of the HDF5 file
409 Dictionary with the desired description of the HDF5 file
409
410
410 Examples
411 Examples
411 --------
412 --------
412
413
413 desc = {
414 desc = {
414 'data_output': {'winds': ['z', 'w', 'v']},
415 'data_output': {'winds': ['z', 'w', 'v']},
415 'utctime': 'timestamps',
416 'utctime': 'timestamps',
416 'heightList': 'heights'
417 'heightList': 'heights'
417 }
418 }
418 desc = {
419 desc = {
419 'data_output': ['z', 'w', 'v'],
420 'data_output': ['z', 'w', 'v'],
420 'utctime': 'timestamps',
421 'utctime': 'timestamps',
421 'heightList': 'heights'
422 'heightList': 'heights'
422 }
423 }
423 desc = {
424 desc = {
424 'Data': {
425 'Data': {
425 'data_output': 'winds',
426 'data_output': 'winds',
426 'utctime': 'timestamps'
427 'utctime': 'timestamps'
427 },
428 },
428 'Metadata': {
429 'Metadata': {
429 'heightList': 'heights'
430 'heightList': 'heights'
430 }
431 }
431 }
432 }
432
433
433 writer = proc_unit.addOperation(name='HDFWriter')
434 writer = proc_unit.addOperation(name='HDFWriter')
434 writer.addParameter(name='path', value='/path/to/file')
435 writer.addParameter(name='path', value='/path/to/file')
435 writer.addParameter(name='blocksPerFile', value='32')
436 writer.addParameter(name='blocksPerFile', value='32')
436 writer.addParameter(name='metadataList', value='heightList,timeZone')
437 writer.addParameter(name='metadataList', value='heightList,timeZone')
437 writer.addParameter(name='dataList',value='data_output,utctime')
438 writer.addParameter(name='dataList',value='data_output,utctime')
438 # writer.addParameter(name='description',value=json.dumps(desc))
439 # writer.addParameter(name='description',value=json.dumps(desc))
439
440
440 """
441 """
441
442
442 ext = ".hdf5"
443 ext = ".hdf5"
443 optchar = "D"
444 optchar = "D"
444 filename = None
445 filename = None
445 path = None
446 path = None
446 setFile = None
447 setFile = None
447 fp = None
448 fp = None
448 ds = None
449 ds = None
449 firsttime = True
450 firsttime = True
450 #Configurations
451 #Configurations
451 blocksPerFile = None
452 blocksPerFile = None
452 blockIndex = None
453 blockIndex = None
453 dataOut = None #eval ??????
454 dataOut = None #eval ??????
454 #Data Arrays
455 #Data Arrays
455 dataList = None
456 dataList = None
456 metadataList = None
457 metadataList = None
457 currentDay = None
458 currentDay = None
458 lastTime = None
459 lastTime = None
459 timeZone = "ut"
460 timeZone = "ut"
460 hourLimit = 3
461 hourLimit = 3
461 breakDays = True
462 breakDays = True
462
463
463 def __init__(self):
464 def __init__(self):
464
465
465 Operation.__init__(self)
466 Operation.__init__(self)
466 return
467 return
467
468
468 def set_kwargs(self, **kwargs):
469 def set_kwargs(self, **kwargs):
469
470
470 for key, value in kwargs.items():
471 for key, value in kwargs.items():
471 setattr(self, key, value)
472 setattr(self, key, value)
472
473
473 def set_kwargs_obj(self, obj, **kwargs):
474 def set_kwargs_obj(self, obj, **kwargs):
474
475
475 for key, value in kwargs.items():
476 for key, value in kwargs.items():
476 setattr(obj, key, value)
477 setattr(obj, key, value)
477
478
478 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None,
479 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None,
479 description={},timeZone = "ut",hourLimit = 3, breakDays=True, **kwargs):
480 description={},timeZone = "ut",hourLimit = 3, breakDays=True, **kwargs):
480 self.path = path
481 self.path = path
481 self.blocksPerFile = blocksPerFile
482 self.blocksPerFile = blocksPerFile
482 self.metadataList = metadataList
483 self.metadataList = metadataList
483 self.dataList = [s.strip() for s in dataList]
484 self.dataList = [s.strip() for s in dataList]
484 self.setType = setType
485 self.setType = setType
485 self.description = description
486 self.description = description
486 self.timeZone = timeZone
487 self.timeZone = timeZone
487 self.hourLimit = hourLimit
488 self.hourLimit = hourLimit
488 self.breakDays = breakDays
489 self.breakDays = breakDays
489 self.set_kwargs(**kwargs)
490 self.set_kwargs(**kwargs)
490
491
491 if self.metadataList is None:
492 if self.metadataList is None:
492 self.metadataList = self.dataOut.metadata_list
493 self.metadataList = self.dataOut.metadata_list
493
494
494 self.metadataList = list(set(self.metadataList))
495 self.metadataList = list(set(self.metadataList))
495
496
496 tableList = []
497 tableList = []
497 dsList = []
498 dsList = []
498
499
499 for i in range(len(self.dataList)):
500 for i in range(len(self.dataList)):
500 dsDict = {}
501 dsDict = {}
501 if hasattr(self.dataOut, self.dataList[i]):
502 if hasattr(self.dataOut, self.dataList[i]):
502 dataAux = getattr(self.dataOut, self.dataList[i])
503 dataAux = getattr(self.dataOut, self.dataList[i])
503 dsDict['variable'] = self.dataList[i]
504 dsDict['variable'] = self.dataList[i]
504 else:
505 else:
505 log.warning('Attribute {} not found in dataOut'.format(self.dataList[i]),self.name)
506 log.warning('Attribute {} not found in dataOut'.format(self.dataList[i]),self.name)
506 continue
507 continue
507
508
508 if dataAux is None:
509 if dataAux is None:
509 continue
510 continue
510 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float_)):
511 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float_)):
511 dsDict['nDim'] = 0
512 dsDict['nDim'] = 0
512 else:
513 else:
513 dsDict['nDim'] = len(dataAux.shape)
514 dsDict['nDim'] = len(dataAux.shape)
514 dsDict['shape'] = dataAux.shape
515 dsDict['shape'] = dataAux.shape
515 dsDict['dsNumber'] = dataAux.shape[0]
516 dsDict['dsNumber'] = dataAux.shape[0]
516 dsDict['dtype'] = dataAux.dtype
517 dsDict['dtype'] = dataAux.dtype
517
518
518 dsList.append(dsDict)
519 dsList.append(dsDict)
519
520
520 self.blockIndex = 0
521 self.blockIndex = 0
521 self.dsList = dsList
522 self.dsList = dsList
522 self.currentDay = self.dataOut.datatime.date()
523 self.currentDay = self.dataOut.datatime.date()
523
524
524 def timeFlag(self):
525 def timeFlag(self):
525 currentTime = self.dataOut.utctime
526 currentTime = self.dataOut.utctime
526 timeTuple = None
527 timeTuple = None
527 if self.timeZone == "lt":
528 if self.timeZone == "lt":
528 timeTuple = time.localtime(currentTime)
529 timeTuple = time.localtime(currentTime)
529 else :
530 else :
530 timeTuple = time.gmtime(currentTime)
531 timeTuple = time.gmtime(currentTime)
531 dataDay = timeTuple.tm_yday
532 dataDay = timeTuple.tm_yday
532
533
533 if self.lastTime is None:
534 if self.lastTime is None:
534 self.lastTime = currentTime
535 self.lastTime = currentTime
535 self.currentDay = dataDay
536 self.currentDay = dataDay
536 return False
537 return False
537
538
538 timeDiff = currentTime - self.lastTime
539 timeDiff = currentTime - self.lastTime
539
540
540 # Si el dia es diferente o si la diferencia entre un
541 # Si el dia es diferente o si la diferencia entre un
541 # dato y otro supera self.hourLimit
542 # dato y otro supera self.hourLimit
542 if (dataDay != self.currentDay) and self.breakDays:
543 if (dataDay != self.currentDay) and self.breakDays:
543 self.currentDay = dataDay
544 self.currentDay = dataDay
544 return True
545 return True
545 elif timeDiff > self.hourLimit*60*60:
546 elif timeDiff > self.hourLimit*60*60:
546 self.lastTime = currentTime
547 self.lastTime = currentTime
547 return True
548 return True
548 else:
549 else:
549 self.lastTime = currentTime
550 self.lastTime = currentTime
550 return False
551 return False
551
552
552 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
553 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
553 dataList=[], setType=None, description={}, **kwargs):
554 dataList=[], setType=None, description={}, **kwargs):
554
555
555 self.dataOut = dataOut
556 self.dataOut = dataOut
556 self.set_kwargs_obj(self.dataOut, **kwargs)
557 self.set_kwargs_obj(self.dataOut, **kwargs)
557 if not(self.isConfig):
558 if not(self.isConfig):
558 self.setup(path=path, blocksPerFile=blocksPerFile,
559 self.setup(path=path, blocksPerFile=blocksPerFile,
559 metadataList=metadataList, dataList=dataList,
560 metadataList=metadataList, dataList=dataList,
560 setType=setType, description=description, **kwargs)
561 setType=setType, description=description, **kwargs)
561
562
562 self.isConfig = True
563 self.isConfig = True
563 self.setNextFile()
564 self.setNextFile()
564
565
565 self.putData()
566 self.putData()
566 return
567 return
567
568
568 def setNextFile(self):
569 def setNextFile(self):
569
570
570 ext = self.ext
571 ext = self.ext
571 path = self.path
572 path = self.path
572 setFile = self.setFile
573 setFile = self.setFile
573 timeTuple = None
574 timeTuple = None
574 if self.timeZone == "lt":
575 if self.timeZone == "lt":
575 timeTuple = time.localtime(self.dataOut.utctime)
576 timeTuple = time.localtime(self.dataOut.utctime)
576 elif self.timeZone == "ut":
577 elif self.timeZone == "ut":
577 timeTuple = time.gmtime(self.dataOut.utctime)
578 timeTuple = time.gmtime(self.dataOut.utctime)
578 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
579 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
579 fullpath = os.path.join(path, subfolder)
580 fullpath = os.path.join(path, subfolder)
580
581
581 if os.path.exists(fullpath):
582 if os.path.exists(fullpath):
582 filesList = os.listdir(fullpath)
583 filesList = os.listdir(fullpath)
583 filesList = [k for k in filesList if k.startswith(self.optchar)]
584 filesList = [k for k in filesList if k.startswith(self.optchar)]
584 if len(filesList) > 0:
585 if len(filesList) > 0:
585 filesList = sorted(filesList, key=str.lower)
586 filesList = sorted(filesList, key=str.lower)
586 filen = filesList[-1]
587 filen = filesList[-1]
587 # el filename debera tener el siguiente formato
588 # el filename debera tener el siguiente formato
588 # 0 1234 567 89A BCDE (hex)
589 # 0 1234 567 89A BCDE (hex)
589 # x YYYY DDD SSS .ext
590 # x YYYY DDD SSS .ext
590 if isNumber(filen[8:11]):
591 if isNumber(filen[8:11]):
591 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
592 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
592 else:
593 else:
593 setFile = -1
594 setFile = -1
594 else:
595 else:
595 setFile = -1 #inicializo mi contador de seteo
596 setFile = -1 #inicializo mi contador de seteo
596 else:
597 else:
597 os.makedirs(fullpath)
598 os.makedirs(fullpath)
598 setFile = -1 #inicializo mi contador de seteo
599 setFile = -1 #inicializo mi contador de seteo
599
600
600 if self.setType is None:
601 if self.setType is None:
601 setFile += 1
602 setFile += 1
602 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
603 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
603 timeTuple.tm_year,
604 timeTuple.tm_year,
604 timeTuple.tm_yday,
605 timeTuple.tm_yday,
605 setFile,
606 setFile,
606 ext)
607 ext)
607 else:
608 else:
608 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
609 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
609 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
610 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
610 timeTuple.tm_year,
611 timeTuple.tm_year,
611 timeTuple.tm_yday,
612 timeTuple.tm_yday,
612 setFile,
613 setFile,
613 ext)
614 ext)
614
615
615 self.filename = os.path.join(path, subfolder, file)
616 self.filename = os.path.join(path, subfolder, file)
616
617
617
618
618
619
619 def getLabel(self, name, x=None):
620 def getLabel(self, name, x=None):
620
621
621 if x is None:
622 if x is None:
622 if 'Data' in self.description:
623 if 'Data' in self.description:
623 data = self.description['Data']
624 data = self.description['Data']
624 if 'Metadata' in self.description:
625 if 'Metadata' in self.description:
625 data.update(self.description['Metadata'])
626 data.update(self.description['Metadata'])
626 else:
627 else:
627 data = self.description
628 data = self.description
628 if name in data:
629 if name in data:
629 if isinstance(data[name], str):
630 if isinstance(data[name], str):
630 return data[name]
631 return data[name]
631 elif isinstance(data[name], list):
632 elif isinstance(data[name], list):
632 return None
633 return None
633 elif isinstance(data[name], dict):
634 elif isinstance(data[name], dict):
634 for key, value in data[name].items():
635 for key, value in data[name].items():
635 return key
636 return key
636 return name
637 return name
637 else:
638 else:
638 if 'Metadata' in self.description:
639 if 'Metadata' in self.description:
639 meta = self.description['Metadata']
640 meta = self.description['Metadata']
640 else:
641 else:
641 meta = self.description
642 meta = self.description
642 if name in meta:
643 if name in meta:
643 if isinstance(meta[name], list):
644 if isinstance(meta[name], list):
644 return meta[name][x]
645 return meta[name][x]
645 elif isinstance(meta[name], dict):
646 elif isinstance(meta[name], dict):
646 for key, value in meta[name].items():
647 for key, value in meta[name].items():
647 return value[x]
648 return value[x]
648 if 'cspc' in name:
649 if 'cspc' in name:
649 return 'pair{:02d}'.format(x)
650 return 'pair{:02d}'.format(x)
650 else:
651 else:
651 return 'channel{:02d}'.format(x)
652 return 'channel{:02d}'.format(x)
652
653
653 def writeMetadata(self, fp):
654 def writeMetadata(self, fp):
654
655
655 if self.description:
656 if self.description:
656 if 'Metadata' in self.description:
657 if 'Metadata' in self.description:
657 grp = fp.create_group('Metadata')
658 grp = fp.create_group('Metadata')
658 else:
659 else:
659 grp = fp
660 grp = fp
660 else:
661 else:
661 grp = fp.create_group('Metadata')
662 grp = fp.create_group('Metadata')
662
663
663 for i in range(len(self.metadataList)):
664 for i in range(len(self.metadataList)):
664 if not hasattr(self.dataOut, self.metadataList[i]):
665 if not hasattr(self.dataOut, self.metadataList[i]):
665 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
666 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
666 continue
667 continue
667 value = getattr(self.dataOut, self.metadataList[i])
668 value = getattr(self.dataOut, self.metadataList[i])
668 if isinstance(value, bool):
669 if isinstance(value, bool):
669 if value is True:
670 if value is True:
670 value = 1
671 value = 1
671 else:
672 else:
672 value = 0
673 value = 0
673 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
674 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
674 return
675 return
675
676
676 def writeMetadata2(self, fp):
677 def writeMetadata2(self, fp):
677
678
678 if self.description:
679 if self.description:
679 if 'Metadata' in self.description:
680 if 'Metadata' in self.description:
680 grp = fp.create_group('Metadata')
681 grp = fp.create_group('Metadata')
681 else:
682 else:
682 grp = fp
683 grp = fp
683 else:
684 else:
684 grp = fp.create_group('Metadata')
685 grp = fp.create_group('Metadata')
685
686
686 for i in range(len(self.metadataList)):
687 for i in range(len(self.metadataList)):
687
688
688 attribute = self.metadataList[i]
689 attribute = self.metadataList[i]
689 attr = attribute.split('.')
690 attr = attribute.split('.')
690 if len(attr) > 1:
691 if len(attr) > 1:
691 if not hasattr(eval("self.dataOut."+attr[0]),attr[1]):
692 if not hasattr(eval("self.dataOut."+attr[0]),attr[1]):
692 log.warning('Metadata: {}.{} not found'.format(attr[0],attr[1]), self.name)
693 log.warning('Metadata: {}.{} not found'.format(attr[0],attr[1]), self.name)
693 continue
694 continue
694 value = getattr(eval("self.dataOut."+attr[0]),attr[1])
695 value = getattr(eval("self.dataOut."+attr[0]),attr[1])
695 if isinstance(value, bool):
696 if isinstance(value, bool):
696 if value is True:
697 if value is True:
697 value = 1
698 value = 1
698 else:
699 else:
699 value = 0
700 value = 0
700 if isinstance(value,type(None)):
701 if isinstance(value,type(None)):
701 log.warning("Invalid value detected, {} is None".format(attribute), self.name)
702 log.warning("Invalid value detected, {} is None".format(attribute), self.name)
702 value = 0
703 value = 0
703 grp2 = None
704 grp2 = None
704 if not 'Metadata/'+attr[0] in fp:
705 if not 'Metadata/'+attr[0] in fp:
705 grp2 = fp.create_group('Metadata/'+attr[0])
706 grp2 = fp.create_group('Metadata/'+attr[0])
706 else:
707 else:
707 grp2 = fp['Metadata/'+attr[0]]
708 grp2 = fp['Metadata/'+attr[0]]
708 grp2.create_dataset(attr[1], data=value)
709 grp2.create_dataset(attr[1], data=value)
709
710
710 else:
711 else:
711 if not hasattr(self.dataOut, attr[0] ):
712 if not hasattr(self.dataOut, attr[0] ):
712 log.warning('Metadata: `{}` not found'.format(attribute), self.name)
713 log.warning('Metadata: `{}` not found'.format(attribute), self.name)
713 continue
714 continue
714 value = getattr(self.dataOut, attr[0])
715 value = getattr(self.dataOut, attr[0])
715 if isinstance(value, bool):
716 if isinstance(value, bool):
716 if value is True:
717 if value is True:
717 value = 1
718 value = 1
718 else:
719 else:
719 value = 0
720 value = 0
720 if isinstance(value, type(None)):
721 if isinstance(value, type(None)):
721 log.error("Value {} is None".format(attribute),self.name)
722 log.error("Value {} is None".format(attribute),self.name)
722
723
723 grp.create_dataset(self.getLabel(attribute), data=value)
724 grp.create_dataset(self.getLabel(attribute), data=value)
724
725
725 return
726 return
726
727
727 def writeData(self, fp):
728 def writeData(self, fp):
728
729
729 if self.description:
730 if self.description:
730 if 'Data' in self.description:
731 if 'Data' in self.description:
731 grp = fp.create_group('Data')
732 grp = fp.create_group('Data')
732 else:
733 else:
733 grp = fp
734 grp = fp
734 else:
735 else:
735 grp = fp.create_group('Data')
736 grp = fp.create_group('Data')
736
737
737 dtsets = []
738 dtsets = []
738 data = []
739 data = []
739
740
740 for dsInfo in self.dsList:
741 for dsInfo in self.dsList:
741 if dsInfo['nDim'] == 0:
742 if dsInfo['nDim'] == 0:
742 ds = grp.create_dataset(
743 ds = grp.create_dataset(
743 self.getLabel(dsInfo['variable']),
744 self.getLabel(dsInfo['variable']),
744 (self.blocksPerFile,),
745 (self.blocksPerFile,),
745 chunks=True,
746 chunks=True,
746 dtype=numpy.float64)
747 dtype=numpy.float64)
747 dtsets.append(ds)
748 dtsets.append(ds)
748 data.append((dsInfo['variable'], -1))
749 data.append((dsInfo['variable'], -1))
749 else:
750 else:
750 label = self.getLabel(dsInfo['variable'])
751 label = self.getLabel(dsInfo['variable'])
751 if label is not None:
752 if label is not None:
752 sgrp = grp.create_group(label)
753 sgrp = grp.create_group(label)
753 else:
754 else:
754 sgrp = grp
755 sgrp = grp
755 for i in range(dsInfo['dsNumber']):
756 for i in range(dsInfo['dsNumber']):
756 ds = sgrp.create_dataset(
757 ds = sgrp.create_dataset(
757 self.getLabel(dsInfo['variable'], i),
758 self.getLabel(dsInfo['variable'], i),
758 (self.blocksPerFile,) + dsInfo['shape'][1:],
759 (self.blocksPerFile,) + dsInfo['shape'][1:],
759 chunks=True,
760 chunks=True,
760 dtype=dsInfo['dtype'])
761 dtype=dsInfo['dtype'])
761 dtsets.append(ds)
762 dtsets.append(ds)
762 data.append((dsInfo['variable'], i))
763 data.append((dsInfo['variable'], i))
763 fp.flush()
764 fp.flush()
764
765
765 log.log('Creating file: {}'.format(fp.filename), self.name)
766 log.log('Creating file: {}'.format(fp.filename), self.name)
766
767
767 self.ds = dtsets
768 self.ds = dtsets
768 self.data = data
769 self.data = data
769 self.firsttime = True
770 self.firsttime = True
770
771
771 return
772 return
772
773
773 def putData(self):
774 def putData(self):
774
775
775 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
776 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
776 self.closeFile()
777 self.closeFile()
777 self.setNextFile()
778 self.setNextFile()
778 self.dataOut.flagNoData = False
779 self.dataOut.flagNoData = False
779 self.blockIndex = 0
780 self.blockIndex = 0
780
781
781 if self.blockIndex == 0:
782 if self.blockIndex == 0:
782 #Setting HDF5 File
783 #Setting HDF5 File
783 self.fp = h5py.File(self.filename, 'w')
784 self.fp = h5py.File(self.filename, 'w')
784 #write metadata
785 #write metadata
785 self.writeMetadata2(self.fp)
786 self.writeMetadata2(self.fp)
786 #Write data
787 #Write data
787 self.writeData(self.fp)
788 self.writeData(self.fp)
788 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
789 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
789 elif (self.blockIndex % 10 ==0):
790 elif (self.blockIndex % 10 ==0):
790 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
791 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
791 else:
792 else:
792
793
793 log.log('Block No. {}/{}'.format(self.blockIndex+1, self.blocksPerFile), self.name)
794 log.log('Block No. {}/{}'.format(self.blockIndex+1, self.blocksPerFile), self.name)
794
795
795 for i, ds in enumerate(self.ds):
796 for i, ds in enumerate(self.ds):
796 attr, ch = self.data[i]
797 attr, ch = self.data[i]
797 if ch == -1:
798 if ch == -1:
798 ds[self.blockIndex] = getattr(self.dataOut, attr)
799 ds[self.blockIndex] = getattr(self.dataOut, attr)
799 else:
800 else:
800 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
801 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
801
802
802 self.blockIndex += 1
803 self.blockIndex += 1
803
804
804 self.fp.flush()
805 self.fp.flush()
805 self.dataOut.flagNoData = True
806 self.dataOut.flagNoData = True
806
807
807 def closeFile(self):
808 def closeFile(self):
808
809
809 if self.blockIndex != self.blocksPerFile:
810 if self.blockIndex != self.blocksPerFile:
810 for ds in self.ds:
811 for ds in self.ds:
811 ds.resize(self.blockIndex, axis=0)
812 ds.resize(self.blockIndex, axis=0)
812
813
813 if self.fp:
814 if self.fp:
814 self.fp.flush()
815 self.fp.flush()
815 self.fp.close()
816 self.fp.close()
816
817
817 def close(self):
818 def close(self):
818
819
819 self.closeFile()
820 self.closeFile()
@@ -1,565 +1,576
1 """
1 """
2 Utilities for IO modules
2 Utilities for IO modules
3 @modified: Joab Apaza
3 @modified: Joab Apaza
4 @email: roj-op01@igp.gob.pe, joab.apaza32@gmail.com
4 @email: roj-op01@igp.gob.pe, joab.apaza32@gmail.com
5 """
5 """
6 ################################################################################
6 ################################################################################
7 ################################################################################
7 ################################################################################
8 import os
8 import os
9 from datetime import datetime
9 from datetime import datetime
10 import numpy
10 import numpy
11 from schainpy.model.data.jrodata import Parameters
11 from schainpy.model.data.jrodata import Parameters
12 import itertools
12 import itertools
13 import numpy
13 import numpy
14 import h5py
14 import h5py
15 import re
15 import re
16 import time
16 import time
17 from schainpy.utils import log
17 from schainpy.utils import log
18 ################################################################################
18 ################################################################################
19 ################################################################################
19 ################################################################################
20 ################################################################################
20 ################################################################################
21 def folder_in_range(folder, start_date, end_date, pattern):
21 def folder_in_range(folder, start_date, end_date, pattern):
22 """
22 """
23 Check whether folder is bettwen start_date and end_date
23 Check whether folder is bettwen start_date and end_date
24 Args:
24 Args:
25 folder (str): Folder to check
25 folder (str): Folder to check
26 start_date (date): Initial date
26 start_date (date): Initial date
27 end_date (date): Final date
27 end_date (date): Final date
28 pattern (str): Datetime format of the folder
28 pattern (str): Datetime format of the folder
29 Returns:
29 Returns:
30 bool: True for success, False otherwise
30 bool: True for success, False otherwise
31 """
31 """
32 try:
32 try:
33 dt = datetime.strptime(folder, pattern)
33 dt = datetime.strptime(folder, pattern)
34 except:
34 except:
35 raise ValueError('Folder {} does not match {} format'.format(folder, pattern))
35 raise ValueError('Folder {} does not match {} format'.format(folder, pattern))
36 return start_date <= dt.date() <= end_date
36 return start_date <= dt.date() <= end_date
37 ################################################################################
37 ################################################################################
38 ################################################################################
38 ################################################################################
39 ################################################################################
39 ################################################################################
40 def getHei_index( minHei, maxHei, heightList):
40 def getHei_index( minHei, maxHei, heightList):
41 try:
41 try:
42 if (minHei < heightList[0]):
42 if (minHei < heightList[0]):
43 minHei = heightList[0]
43 minHei = heightList[0]
44 if (maxHei > heightList[-1]):
44 if (maxHei > heightList[-1]):
45 maxHei = heightList[-1]
45 maxHei = heightList[-1]
46 minIndex = 0
46 minIndex = 0
47 maxIndex = 0
47 maxIndex = 0
48 heights = numpy.asarray(heightList)
48 heights = numpy.asarray(heightList)
49 inda = numpy.where(heights >= minHei)
49 inda = numpy.where(heights >= minHei)
50 indb = numpy.where(heights <= maxHei)
50 indb = numpy.where(heights <= maxHei)
51 try:
51 try:
52 minIndex = inda[0][0]
52 minIndex = inda[0][0]
53 except:
53 except:
54 minIndex = 0
54 minIndex = 0
55 try:
55 try:
56 maxIndex = indb[0][-1]
56 maxIndex = indb[0][-1]
57 except:
57 except:
58 maxIndex = len(heightList)
58 maxIndex = len(heightList)
59 return minIndex,maxIndex
59 return minIndex,maxIndex
60 except Exception as e:
60 except Exception as e:
61 log.error("In getHei_index: ", __name__)
61 log.error("In getHei_index: ", __name__)
62 log.error(e , __name__)
62 log.error(e , __name__)
63 ################################################################################
63 ################################################################################
64 ################################################################################
64 ################################################################################
65 ################################################################################
65 ################################################################################
66 class MergeH5(object):
66 class MergeH5(object):
67 """Processing unit to read HDF5 format files
67 """Processing unit to read HDF5 format files
68 This unit reads HDF5 files created with `HDFWriter` operation when channels area
68 This unit reads HDF5 files created with `HDFWriter` operation when channels area
69 processed by separated. Then merge all channels in a single files.
69 processed by separated. Then merge all channels in a single files.
70 "example"
70 "example"
71 nChannels = 4
71 nChannels = 4
72 pathOut = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/merged"
72 pathOut = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/merged"
73 p0 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch0"
73 p0 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch0"
74 p1 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch1"
74 p1 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch1"
75 p2 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch2"
75 p2 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch2"
76 p3 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch3"
76 p3 = "/home/soporte/Data/OutTest/clean2D/perpAndObliq/byChannels/d2022240_Ch3"
77 list = ['data_spc','data_cspc','nIncohInt','utctime']
77 list = ['data_spc','data_cspc','nIncohInt','utctime']
78 merger = MergeH5(nChannels,pathOut,list, p0, p1,p2,p3)
78 merger = MergeH5(nChannels,pathOut,list, p0, p1,p2,p3)
79 merger.run()
79 merger.run()
80 The file example_FULLmultiprocessing_merge.txt show an application for AMISR data
80 The file example_FULLmultiprocessing_merge.txt show an application for AMISR data
81 """
81 """
82 # #__attrs__ = ['paths', 'nChannels']
82 # #__attrs__ = ['paths', 'nChannels']
83 isConfig = False
83 isConfig = False
84 inPaths = None
84 inPaths = None
85 nChannels = None
85 nChannels = None
86 ch_dataIn = []
86 ch_dataIn = []
87 channelList = []
87 channelList = []
88 def __init__(self,nChannels, pOut, dataList, *args):
88 def __init__(self,nChannels, pOut, dataList, *args):
89 self.inPaths = [p for p in args]
89 self.inPaths = [p for p in args]
90 #print(self.inPaths)
90 #print(self.inPaths)
91 if len(self.inPaths) != nChannels:
91 if len(self.inPaths) != nChannels:
92 print("ERROR, number of channels different from iput paths {} != {}".format(nChannels, len(args)))
92 print("ERROR, number of channels different from iput paths {} != {}".format(nChannels, len(args)))
93 return
93 return
94 self.pathOut = pOut
94 self.pathOut = pOut
95 self.dataList = dataList
95 self.dataList = dataList
96 self.nChannels = len(self.inPaths)
96 self.nChannels = len(self.inPaths)
97 self.ch_dataIn = [Parameters() for p in args]
97 self.ch_dataIn = [Parameters() for p in args]
98 self.dataOut = Parameters()
98 self.dataOut = Parameters()
99 self.channelList = [n for n in range(nChannels)]
99 self.channelList = [n for n in range(nChannels)]
100 self.blocksPerFile = None
100 self.blocksPerFile = None
101 self.date = None
101 self.date = None
102 self.ext = ".hdf5$"
102 self.ext = ".hdf5$"
103 self.dataList = dataList
103 self.dataList = dataList
104 self.optchar = "D"
104 self.optchar = "D"
105 self.meta = {}
105 self.meta = {}
106 self.data = {}
106 self.data = {}
107 self.open_file = h5py.File
107 self.open_file = h5py.File
108 self.open_mode = 'r'
108 self.open_mode = 'r'
109 self.description = {}
109 self.description = {}
110 self.extras = {}
110 self.extras = {}
111 self.filefmt = "*%Y%j***"
111 self.filefmt = "*%Y%j***"
112 self.folderfmt = "*%Y%j"
112 self.folderfmt = "*%Y%j"
113 self.flag_spc = False
113 self.flag_spc = False
114 self.flag_pow = False
114 self.flag_pow = False
115 self.flag_snr = False
115 self.flag_snr = False
116 self.flag_nIcoh = False
116 self.flag_nIcoh = False
117 self.flagProcessingHeader = False
117 self.flagProcessingHeader = False
118 self.flagControllerHeader = False
118 self.flagControllerHeader = False
119 def setup(self):
119 def setup(self):
120 # if not self.ext.startswith('.'):
120 # if not self.ext.startswith('.'):
121 # self.ext = '.{}'.format(self.ext)
121 # self.ext = '.{}'.format(self.ext)
122 self.filenameList = self.searchFiles(self.inPaths, None)
122 self.filenameList = self.searchFiles(self.inPaths, None)
123 self.nfiles = len(self.filenameList[0])
123 self.nfiles = len(self.filenameList[0])
124 def searchFiles(self, paths, date, walk=True):
124 def searchFiles(self, paths, date, walk=True):
125 # self.paths = path
125 # self.paths = path
126 #self.date = startDate
126 #self.date = startDate
127 #self.walk = walk
127 #self.walk = walk
128 filenameList = [[] for n in range(self.nChannels)]
128 filenameList = [[] for n in range(self.nChannels)]
129 ch = 0
129 ch = 0
130 for path in paths:
130 for path in paths:
131 if os.path.exists(path):
131 if os.path.exists(path):
132 print("Searching files in {}".format(path))
132 print("Searching files in {}".format(path))
133 filenameList[ch] = self.getH5files(path, walk)
133 filenameList[ch] = self.getH5files(path, walk)
134 print("Found: ")
134 print("Found: ")
135 for f in filenameList[ch]:
135 for f in filenameList[ch]:
136 print(f)
136 print(f)
137 else:
137 else:
138 self.status = 0
138 self.status = 0
139 print('Path:%s does not exists'%path)
139 print('Path:%s does not exists'%path)
140 return 0
140 return 0
141 ch+=1
141 ch+=1
142 return filenameList
142 return filenameList
143 def getH5files(self, path, walk):
143 def getH5files(self, path, walk):
144 dirnameList = []
144 dirnameList = []
145 pat = '(\d)+.'+self.ext
145 pat = '(\d)+.'+self.ext
146 if walk:
146 if walk:
147 for root, dirs, files in os.walk(path):
147 for root, dirs, files in os.walk(path):
148 for dir in dirs:
148 for dir in dirs:
149 #print(os.path.join(root,dir))
149 #print(os.path.join(root,dir))
150 files = [re.search(pat,x) for x in os.listdir(os.path.join(root,dir))]
150 files = [re.search(pat,x) for x in os.listdir(os.path.join(root,dir))]
151 #print(files)
151 #print(files)
152 files = [x for x in files if x!=None]
152 files = [x for x in files if x!=None]
153 files = [x.string for x in files]
153 files = [x.string for x in files]
154 files = [os.path.join(root,dir,x) for x in files if x!=None]
154 files = [os.path.join(root,dir,x) for x in files if x!=None]
155 files.sort()
155 files.sort()
156 dirnameList += files
156 dirnameList += files
157 return dirnameList
157 return dirnameList
158 else:
158 else:
159 dirnameList = [re.search(pat,x) for x in os.listdir(path)]
159 dirnameList = [re.search(pat,x) for x in os.listdir(path)]
160 dirnameList = [x for x in dirnameList if x!=None]
160 dirnameList = [x for x in dirnameList if x!=None]
161 dirnameList = [x.string for x in dirnameList]
161 dirnameList = [x.string for x in dirnameList]
162 dirnameList = [x for x in dirnameList if x!=None]
162 dirnameList = [x for x in dirnameList if x!=None]
163 dirnameList.sort()
163 dirnameList.sort()
164 return dirnameList
164 return dirnameList
165 def readFile(self,fp,ch):
165 def readFile(self,fp,ch):
166 '''Read metadata and data'''
166 '''Read metadata and data'''
167 self.readMetadata(fp,ch)
167 self.readMetadata(fp,ch)
168 #print(self.metadataList)
168 # print(self.metadataList)
169 data = self.readData(fp)
169 data = self.readData(fp)
170 for attr in self.meta:
170 for attr in self.meta:
171 if "processingHeaderObj" in attr:
171 if "processingHeaderObj" in attr:
172 self.flagProcessingHeader=True
172 self.flagProcessingHeader=True
173 if "radarControllerHeaderObj" in attr:
173 if "radarControllerHeaderObj" in attr:
174 self.flagControllerHeader=True
174 self.flagControllerHeader=True
175 at = attr.split('.')
175 at = attr.split('.')
176 #print("AT ", at)
176 # print("AT ", at)
177 if len(at) > 1:
177 if len(at) > 1:
178 setattr(eval("self.ch_dataIn[ch]."+at[0]),at[1], self.meta[attr])
178 setattr(eval("self.ch_dataIn[ch]."+at[0]),at[1], self.meta[attr])
179 else:
179 else:
180 setattr(self.ch_dataIn[ch], attr, self.meta[attr])
180 setattr(self.ch_dataIn[ch], attr, self.meta[attr])
181 self.fill_dataIn(data, self.ch_dataIn[ch])
181 self.fill_dataIn(data, self.ch_dataIn[ch])
182 return
182 return
183 def readMetadata(self, fp, ch):
183 def readMetadata(self, fp, ch):
184 '''
184 '''
185 Reads Metadata
185 Reads Metadata
186 '''
186 '''
187 meta = {}
187 meta = {}
188 self.metadataList = []
188 self.metadataList = []
189 grp = fp['Metadata']
189 grp = fp['Metadata']
190 for item in grp.values():
190 for item in grp.values():
191 name = item.name
191 name = item.name
192 if isinstance(item, h5py.Dataset):
192 if isinstance(item, h5py.Dataset):
193 name = name.split("/")[-1]
193 name = name.split("/")[-1]
194 if 'List' in name:
194 if 'List' in name:
195 meta[name] = item[()].tolist()
195 meta[name] = item[()].tolist()
196 else:
196 else:
197 meta[name] = item[()]
197 meta[name] = item[()]
198 self.metadataList.append(name)
198 self.metadataList.append(name)
199 else:
199 else:
200 grp2 = fp[name]
200 grp2 = fp[name]
201 Obj = name.split("/")[-1]
201 Obj = name.split("/")[-1]
202 #print(Obj)
202 #print(Obj)
203 for item2 in grp2.values():
203 for item2 in grp2.values():
204 name2 = Obj+"."+item2.name.split("/")[-1]
204 name2 = Obj+"."+item2.name.split("/")[-1]
205 if 'List' in name2:
205 if 'List' in name2:
206 meta[name2] = item2[()].tolist()
206 meta[name2] = item2[()].tolist()
207 else:
207 else:
208 meta[name2] = item2[()]
208 meta[name2] = item2[()]
209 self.metadataList.append(name2)
209 self.metadataList.append(name2)
210 if not self.meta:
210 if not self.meta:
211 self.meta = meta.copy()
211 self.meta = meta.copy()
212 for key in list(self.meta.keys()):
212 for key in list(self.meta.keys()):
213 if "channelList" in key:
213 if "channelList" in key:
214 self.meta["channelList"] =[n for n in range(self.nChannels)]
214 self.meta["channelList"] =[n for n in range(self.nChannels)]
215 if "processingHeaderObj" in key:
215 if "processingHeaderObj" in key:
216 self.meta["processingHeaderObj.channelList"] =[n for n in range(self.nChannels)]
216 self.meta["processingHeaderObj.channelList"] =[n for n in range(self.nChannels)]
217 if "radarControllerHeaderObj" in key:
217 if "radarControllerHeaderObj" in key:
218 self.meta["radarControllerHeaderObj.channelList"] =[n for n in range(self.nChannels)]
218 self.meta["radarControllerHeaderObj.channelList"] =[n for n in range(self.nChannels)]
219 return 1
219 return 1
220 else:
220 else:
221 for k in list(self.meta.keys()):
221 for k in list(self.meta.keys()):
222 if 'List' in k and 'channel' not in k and "height" not in k and "radarControllerHeaderObj" not in k:
222 if 'List' in k and 'channel' not in k and "height" not in k and "radarControllerHeaderObj" not in k:
223 self.meta[k] += meta[k]
223 self.meta[k] += meta[k]
224 #print("Metadata: ",self.meta)
224 #print("Metadata: ",self.meta)
225 return 1
225 return 1
226 def fill_dataIn(self,data, dataIn):
226 def fill_dataIn(self,data, dataIn):
227 for attr in data:
227 for attr in data:
228 if data[attr].ndim == 1:
228 if data[attr].ndim == 1:
229 setattr(dataIn, attr, data[attr][:])
229 setattr(dataIn, attr, data[attr][:])
230 else:
230 else:
231 setattr(dataIn, attr, numpy.squeeze(data[attr][:,:]))
231 setattr(dataIn, attr, numpy.squeeze(data[attr][:,:]))
232 #print("shape in", dataIn.data_spc.shape, len(dataIn.data_spc))
232 # print("shape in", dataIn.data_spc.shape, len(dataIn.data_spc))
233 if self.flag_spc:
233 if self.flag_spc:
234 if dataIn.data_spc.ndim > 3:
234 if dataIn.data_spc.ndim > 3:
235 dataIn.data_spc = dataIn.data_spc[0]
235 dataIn.data_spc = dataIn.data_spc[0]
236 #print("shape in", dataIn.data_spc.shape)
236 #print("shape in", dataIn.data_spc.shape)
237 def getBlocksPerFile(self):
237 def getBlocksPerFile(self):
238 b = numpy.zeros(self.nChannels)
238 b = numpy.zeros(self.nChannels)
239 for i in range(self.nChannels):
239 for i in range(self.nChannels):
240 if self.flag_spc:
240 if self.flag_spc:
241 b[i] = self.ch_dataIn[i].data_spc.shape[0] #number of blocks
241 b[i] = self.ch_dataIn[i].data_spc.shape[0] #number of blocks
242 elif self.flag_pow:
242 elif self.flag_pow:
243 b[i] = self.ch_dataIn[i].data_pow.shape[0] #number of blocks
243 b[i] = self.ch_dataIn[i].data_pow.shape[0] #number of blocks
244 elif self.flag_snr:
244 elif self.flag_snr:
245 b[i] = self.ch_dataIn[i].data_snr.shape[0] #number of blocks
245 b[i] = self.ch_dataIn[i].data_snr.shape[0] #number of blocks
246 self.blocksPerFile = int(b.min())
246 self.blocksPerFile = int(b.min())
247 iresh_ch = numpy.where(b > self.blocksPerFile)[0]
247 iresh_ch = numpy.where(b > self.blocksPerFile)[0]
248 if len(iresh_ch) > 0:
248 if len(iresh_ch) > 0:
249 for ich in iresh_ch:
249 for ich in iresh_ch:
250 for i in range(len(self.dataList)):
250 for i in range(len(self.dataList)):
251 if hasattr(self.ch_dataIn[ich], self.dataList[i]):
251 if hasattr(self.ch_dataIn[ich], self.dataList[i]):
252 # print("reshaping ", self.dataList[i])
252 # print("reshaping ", self.dataList[i])
253 # print(getattr(self.ch_dataIn[ich], self.dataList[i]).shape)
253 # print(getattr(self.ch_dataIn[ich], self.dataList[i]).shape)
254 dataAux = getattr(self.ch_dataIn[ich], self.dataList[i])
254 dataAux = getattr(self.ch_dataIn[ich], self.dataList[i])
255 setattr(self.ch_dataIn[ich], self.dataList[i], None)
255 setattr(self.ch_dataIn[ich], self.dataList[i], None)
256 setattr(self.ch_dataIn[ich], self.dataList[i], dataAux[0:self.blocksPerFile])
256 setattr(self.ch_dataIn[ich], self.dataList[i], dataAux[0:self.blocksPerFile])
257 # print(getattr(self.ch_dataIn[ich], self.dataList[i]).shape)
257 # print(getattr(self.ch_dataIn[ich], self.dataList[i]).shape)
258 else:
258 else:
259 # log.error("Channels number error,iresh_ch=", iresh_ch)
259 return
260 return
260 def getLabel(self, name, x=None):
261 def getLabel(self, name, x=None):
261 if x is None:
262 if x is None:
262 if 'Data' in self.description:
263 if 'Data' in self.description:
263 data = self.description['Data']
264 data = self.description['Data']
264 if 'Metadata' in self.description:
265 if 'Metadata' in self.description:
265 data.update(self.description['Metadata'])
266 data.update(self.description['Metadata'])
266 else:
267 else:
267 data = self.description
268 data = self.description
268 if name in data:
269 if name in data:
269 if isinstance(data[name], str):
270 if isinstance(data[name], str):
270 return data[name]
271 return data[name]
271 elif isinstance(data[name], list):
272 elif isinstance(data[name], list):
272 return None
273 return None
273 elif isinstance(data[name], dict):
274 elif isinstance(data[name], dict):
274 for key, value in data[name].items():
275 for key, value in data[name].items():
275 return key
276 return key
276 return name
277 return name
277 else:
278 else:
278 if 'Metadata' in self.description:
279 if 'Metadata' in self.description:
279 meta = self.description['Metadata']
280 meta = self.description['Metadata']
280 else:
281 else:
281 meta = self.description
282 meta = self.description
282 if name in meta:
283 if name in meta:
283 if isinstance(meta[name], list):
284 if isinstance(meta[name], list):
284 return meta[name][x]
285 return meta[name][x]
285 elif isinstance(meta[name], dict):
286 elif isinstance(meta[name], dict):
286 for key, value in meta[name].items():
287 for key, value in meta[name].items():
287 return value[x]
288 return value[x]
288 if 'cspc' in name:
289 if 'cspc' in name:
289 return 'pair{:02d}'.format(x)
290 return 'pair{:02d}'.format(x)
290 else:
291 else:
291 return 'channel{:02d}'.format(x)
292 return 'channel{:02d}'.format(x)
293
292 def readData(self, fp):
294 def readData(self, fp):
293 #print("read fp: ", fp)
295 # print("read fp: ", fp)
294 data = {}
296 data = {}
295 grp = fp['Data']
297 grp = fp['Data']
296 for name in grp:
298 for name in grp:
297 if "spc" in name:
299 if "spc" in name:
298 self.flag_spc = True
300 self.flag_spc = True
299 if "pow" in name:
301 if "pow" in name:
300 self.flag_pow = True
302 self.flag_pow = True
301 if "snr" in name:
303 if "snr" in name:
302 self.flag_snr = True
304 self.flag_snr = True
303 if "nIncohInt" in name:
305 if "nIncohInt" in name:
304 self.flag_nIcoh = True
306 self.flag_nIcoh = True
305
307 # print("spc:",self.flag_spc," pow:",self.flag_pow," snr:", self.flag_snr)
306 if isinstance(grp[name], h5py.Dataset):
308 if isinstance(grp[name], h5py.Dataset):
307 array = grp[name][()]
309 array = grp[name][()]
308 elif isinstance(grp[name], h5py.Group):
310 elif isinstance(grp[name], h5py.Group):
309 array = []
311 array = []
310 for ch in grp[name]:
312 for ch in grp[name]:
311 array.append(grp[name][ch][()])
313 array.append(grp[name][ch][()])
312 array = numpy.array(array)
314 array = numpy.array(array)
313 else:
315 else:
314 print('Unknown type: {}'.format(name))
316 print('Unknown type: {}'.format(name))
315 data[name] = array
317 data[name] = array
316 return data
318 return data
319
317 def getDataOut(self):
320 def getDataOut(self):
321 # print("Getting DataOut")
318 self.dataOut = self.ch_dataIn[0].copy() #dataIn #blocks, fft, hei for metadata
322 self.dataOut = self.ch_dataIn[0].copy() #dataIn #blocks, fft, hei for metadata
319 if self.flagProcessingHeader:
323 if self.flagProcessingHeader:
320 self.dataOut.processingHeaderObj = self.ch_dataIn[0].processingHeaderObj.copy()
324 self.dataOut.processingHeaderObj = self.ch_dataIn[0].processingHeaderObj.copy()
321 self.dataOut.heightList = self.dataOut.processingHeaderObj.heightList
325 self.dataOut.heightList = self.dataOut.processingHeaderObj.heightList
322 self.dataOut.ippSeconds = self.dataOut.processingHeaderObj.ipp
326 self.dataOut.ippSeconds = self.dataOut.processingHeaderObj.ipp
323 self.dataOut.channelList = self.dataOut.processingHeaderObj.channelList
327 self.dataOut.channelList = self.dataOut.processingHeaderObj.channelList
324 self.dataOut.nCohInt = self.dataOut.processingHeaderObj.nCohInt
328 self.dataOut.nCohInt = self.dataOut.processingHeaderObj.nCohInt
325 self.dataOut.nFFTPoints = self.dataOut.processingHeaderObj.nFFTPoints
329 self.dataOut.nFFTPoints = self.dataOut.processingHeaderObj.nFFTPoints
326 if self.flagControllerHeader:
330 if self.flagControllerHeader:
327 self.dataOut.radarControllerHeaderObj = self.ch_dataIn[0].radarControllerHeaderObj.copy()
331 self.dataOut.radarControllerHeaderObj = self.ch_dataIn[0].radarControllerHeaderObj.copy()
328 self.dataOut.frequency = self.dataOut.radarControllerHeaderObj.frequency
332 self.dataOut.frequency = self.dataOut.radarControllerHeaderObj.frequency
329 #--------------------------------------------------------------------
333 #--------------------------------------------------------------------
330 #--------------------------------------------------------------------
334 #--------------------------------------------------------------------
331 if self.flag_spc:
335 if self.flag_spc:
332 if self.dataOut.data_spc.ndim < 3:
336 if self.dataOut.data_spc.ndim < 3:
333 print("shape spc in: ",self.dataOut.data_spc.shape )
337 print("shape spc in: ",self.dataOut.data_spc.shape )
334 return 0
338 return 0
335 if self.flag_pow:
339 if self.flag_pow:
336 if self.dataOut.data_pow.ndim < 2:
340 if self.dataOut.data_pow.ndim < 2:
337 print("shape pow in: ",self.dataOut.data_pow.shape )
341 print("shape pow in: ",self.dataOut.data_pow.shape )
338 return 0
342 return 0
339 if self.flag_snr:
343 if self.flag_snr:
340 if self.dataOut.data_snr.ndim < 2:
344 if self.dataOut.data_snr.ndim < 2:
341 print("shape snr in: ",self.dataOut.data_snr.shape )
345 print("shape snr in: ",self.dataOut.data_snr.shape )
342 return 0
346 return 0
343 self.dataOut.data_spc = None
347 self.dataOut.data_spc = None
344 self.dataOut.data_cspc = None
348 self.dataOut.data_cspc = None
345 self.dataOut.data_pow = None
349 self.dataOut.data_pow = None
346 self.dataOut.data_snr = None
350 self.dataOut.data_snr = None
347 self.dataOut.utctime = None
351 self.dataOut.utctime = None
348 self.dataOut.nIncohInt = None
352 self.dataOut.nIncohInt = None
349 #--------------------------------------------------------------------
353 #--------------------------------------------------------------------
350 if self.flag_spc:
354 if self.flag_spc:
351 spc = [data.data_spc for data in self.ch_dataIn]
355 spc = [data.data_spc for data in self.ch_dataIn]
352 self.dataOut.data_spc = numpy.stack(spc, axis=1) #blocks, ch, fft, hei
356 self.dataOut.data_spc = numpy.stack(spc, axis=1) #blocks, ch, fft, hei
353 #--------------------------------------------------------------------
357 #--------------------------------------------------------------------
354 if self.flag_pow:
358 if self.flag_pow:
355 pow = [data.data_pow for data in self.ch_dataIn]
359 pow = [data.data_pow for data in self.ch_dataIn]
356 self.dataOut.data_pow = numpy.stack(pow, axis=1) #blocks, ch, fft, hei
360 self.dataOut.data_pow = numpy.stack(pow, axis=1) #blocks, ch, fft, hei
357 #--------------------------------------------------------------------
361 #--------------------------------------------------------------------
358 if self.flag_snr:
362 if self.flag_snr:
359 snr = [data.data_snr for data in self.ch_dataIn]
363 snr = [data.data_snr for data in self.ch_dataIn]
360 self.dataOut.data_snr = numpy.stack(snr, axis=1) #blocks, ch, fft, hei
364 self.dataOut.data_snr = numpy.stack(snr, axis=1) #blocks, ch, fft, hei
361 #--------------------------------------------------------------------
365 #--------------------------------------------------------------------
362 time = [data.utctime for data in self.ch_dataIn]
366 time = [data.utctime for data in self.ch_dataIn]
363 time = numpy.asarray(time).mean(axis=0)
367 time = numpy.asarray(time).mean(axis=0)
364 time = numpy.squeeze(time)
368 time = numpy.squeeze(time)
365 self.dataOut.utctime = time
369 self.dataOut.utctime = time
366 #--------------------------------------------------------------------
370 #--------------------------------------------------------------------
367 if self.flag_nIcoh:
371 if self.flag_nIcoh:
368 ints = [data.nIncohInt for data in self.ch_dataIn]
372 ints = [data.nIncohInt for data in self.ch_dataIn]
369 self.dataOut.nIncohInt = numpy.stack(ints, axis=1)
373 self.dataOut.nIncohInt = numpy.stack(ints, axis=1)
370 if self.dataOut.nIncohInt.ndim > 3:
374 if self.dataOut.nIncohInt.ndim > 3:
371 aux = self.dataOut.nIncohInt
375 aux = self.dataOut.nIncohInt
372 self.dataOut.nIncohInt = None
376 self.dataOut.nIncohInt = None
373 self.dataOut.nIncohInt = aux[0]
377 self.dataOut.nIncohInt = aux[0]
374 if self.dataOut.nIncohInt.ndim < 3:
378 if self.dataOut.nIncohInt.ndim < 3:
375 nIncohInt = numpy.repeat(self.dataOut.nIncohInt, self.dataOut.nHeights).reshape(self.blocksPerFile,self.nChannels, self.dataOut.nHeights)
379 nIncohInt = numpy.repeat(self.dataOut.nIncohInt, self.dataOut.nHeights).reshape(self.blocksPerFile,self.nChannels, self.dataOut.nHeights)
376 #nIncohInt = numpy.reshape(nIncohInt, (self.blocksPerFile,self.nChannels, self.dataOut.nHeights))
380 #nIncohInt = numpy.reshape(nIncohInt, (self.blocksPerFile,self.nChannels, self.dataOut.nHeights))
377 self.dataOut.nIncohInt = None
381 self.dataOut.nIncohInt = None
378 self.dataOut.nIncohInt = nIncohInt
382 self.dataOut.nIncohInt = nIncohInt
379 if (self.dataOut.nIncohInt.shape)[0]==self.nChannels: ## ch,blocks, hei
383 if (self.dataOut.nIncohInt.shape)[0]==self.nChannels: ## ch,blocks, hei
380 self.dataOut.nIncohInt = numpy.swapaxes(self.dataOut.nIncohInt, 0, 1) ## blocks,ch, hei
384 self.dataOut.nIncohInt = numpy.swapaxes(self.dataOut.nIncohInt, 0, 1) ## blocks,ch, hei
381 else:
385 else:
382 self.dataOut.nIncohInt = self.ch_dataIn[0].nIncohInt
386 self.dataOut.nIncohInt = self.ch_dataIn[0].nIncohInt
383 #--------------------------------------------------------------------
387 #--------------------------------------------------------------------
384 #print("utcTime: ", time.shape)
388 # print("utcTime: ", time.shape)
385 #print("data_spc ",self.dataOut.data_spc.shape)
389 # print("data_spc ",self.dataOut.data_spc.shape)
386 if "data_cspc" in self.dataList:
390 if "data_cspc" in self.dataList:
387 pairsList = [pair for pair in itertools.combinations(self.channelList, 2)]
391 pairsList = [pair for pair in itertools.combinations(self.channelList, 2)]
388 #print("PairsList: ", pairsList)
392 #print("PairsList: ", pairsList)
389 self.dataOut.pairsList = pairsList
393 self.dataOut.pairsList = pairsList
390 cspc = []
394 cspc = []
391 for i, j in pairsList:
395 for i, j in pairsList:
392 cspc.append(self.ch_dataIn[i].data_spc*numpy.conjugate(self.ch_dataIn[j].data_spc)) #blocks, fft, hei
396 cspc.append(self.ch_dataIn[i].data_spc*numpy.conjugate(self.ch_dataIn[j].data_spc)) #blocks, fft, hei
393 cspc = numpy.asarray(cspc) # # pairs, blocks, fft, hei
397 cspc = numpy.asarray(cspc) # # pairs, blocks, fft, hei
394 #print("cspc: ",cspc.shape)
398 #print("cspc: ",cspc.shape)
395 self.dataOut.data_cspc = numpy.swapaxes(cspc, 0, 1) ## blocks, pairs, fft, hei
399 self.dataOut.data_cspc = numpy.swapaxes(cspc, 0, 1) ## blocks, pairs, fft, hei
396 #print("dataOut.data_cspc: ",self.dataOut.data_cspc.shape)
400 #print("dataOut.data_cspc: ",self.dataOut.data_cspc.shape)
397 #if "data_pow" in self.dataList:
401 #if "data_pow" in self.dataList:
398 return 1
402 return 1
399 # def writeMetadata(self, fp):
403 # def writeMetadata(self, fp):
400 #
404 #
401 #
405 #
402 # grp = fp.create_group('Metadata')
406 # grp = fp.create_group('Metadata')
403 #
407 #
404 # for i in range(len(self.metadataList)):
408 # for i in range(len(self.metadataList)):
405 # if not hasattr(self.dataOut, self.metadataList[i]):
409 # if not hasattr(self.dataOut, self.metadataList[i]):
406 # print('Metadata: `{}` not found'.format(self.metadataList[i]))
410 # print('Metadata: `{}` not found'.format(self.metadataList[i]))
407 # continue
411 # continue
408 # value = getattr(self.dataOut, self.metadataList[i])
412 # value = getattr(self.dataOut, self.metadataList[i])
409 # if isinstance(value, bool):
413 # if isinstance(value, bool):
410 # if value is True:
414 # if value is True:
411 # value = 1
415 # value = 1
412 # else:
416 # else:
413 # value = 0
417 # value = 0
414 # grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
418 # grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
415 # return
419 # return
416 def writeMetadata(self, fp):
420 def writeMetadata(self, fp):
417 grp = fp.create_group('Metadata')
421 grp = fp.create_group('Metadata')
418 for i in range(len(self.metadataList)):
422 for i in range(len(self.metadataList)):
419 attribute = self.metadataList[i]
423 attribute = self.metadataList[i]
420 attr = attribute.split('.')
424 attr = attribute.split('.')
421 if '' in attr:
425 if '' in attr:
422 attr.remove('')
426 attr.remove('')
423 #print(attr)
427 #print(attr)
424 if len(attr) > 1:
428 if len(attr) > 1:
425 if not hasattr(eval("self.dataOut."+attr[0]),attr[1]):
429 if not hasattr(eval("self.dataOut."+attr[0]),attr[1]):
426 print('Metadata: {}.{} not found'.format(attr[0],attr[1]))
430 print('Metadata: {}.{} not found'.format(attr[0],attr[1]))
427 continue
431 continue
428 value = getattr(eval("self.dataOut."+attr[0]),attr[1])
432 value = getattr(eval("self.dataOut."+attr[0]),attr[1])
429 if isinstance(value, bool):
433 if isinstance(value, bool):
430 if value is True:
434 if value is True:
431 value = 1
435 value = 1
432 else:
436 else:
433 value = 0
437 value = 0
434 grp2 = None
438 grp2 = None
435 if not 'Metadata/'+attr[0] in fp:
439 if not 'Metadata/'+attr[0] in fp:
436 grp2 = fp.create_group('Metadata/'+attr[0])
440 grp2 = fp.create_group('Metadata/'+attr[0])
437 else:
441 else:
438 grp2 = fp['Metadata/'+attr[0]]
442 grp2 = fp['Metadata/'+attr[0]]
439 grp2.create_dataset(attr[1], data=value)
443 grp2.create_dataset(attr[1], data=value)
440 else:
444 else:
441 if not hasattr(self.dataOut, attr[0] ):
445 if not hasattr(self.dataOut, attr[0] ):
442 print('Metadata: `{}` not found'.format(attribute))
446 print('Metadata: `{}` not found'.format(attribute))
443 continue
447 continue
444 value = getattr(self.dataOut, attr[0])
448 value = getattr(self.dataOut, attr[0])
445 if isinstance(value, bool):
449 if isinstance(value, bool):
446 if value is True:
450 if value is True:
447 value = 1
451 value = 1
448 else:
452 else:
449 value = 0
453 value = 0
450 if isinstance(value, type(None)):
454 if isinstance(value, type(None)):
451 print("------ERROR, value {} is None".format(attribute))
455 print("------ERROR, value {} is None".format(attribute))
452
456
453 grp.create_dataset(self.getLabel(attribute), data=value)
457 grp.create_dataset(self.getLabel(attribute), data=value)
454 return
458 return
459
455 def getDsList(self):
460 def getDsList(self):
461 # print("Getting DS List", self.dataList)
456 dsList =[]
462 dsList =[]
463 dataAux = None
457 for i in range(len(self.dataList)):
464 for i in range(len(self.dataList)):
458 dsDict = {}
465 dsDict = {}
459 if hasattr(self.dataOut, self.dataList[i]):
466 if hasattr(self.dataOut, self.dataList[i]):
460 dataAux = getattr(self.dataOut, self.dataList[i])
467 dataAux = getattr(self.dataOut, self.dataList[i])
461 dsDict['variable'] = self.dataList[i]
468 dsDict['variable'] = self.dataList[i]
462 else:
469 else:
463 print('Attribute {} not found in dataOut'.format(self.dataList[i]))
470 print('Attribute {} not found in dataOut'.format(self.dataList[i]))
464 continue
471 continue
465 if dataAux is None:
472 if dataAux is None:
466 continue
473 continue
467 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
474 elif isinstance(dataAux, (int, float, numpy.int_, numpy.float_)):
468 dsDict['nDim'] = 0
475 dsDict['nDim'] = 0
469 else:
476 else:
470 dsDict['nDim'] = len(dataAux.shape) -1
477 dsDict['nDim'] = len(dataAux.shape) -1
471 dsDict['shape'] = dataAux.shape
478 dsDict['shape'] = dataAux.shape
472 if len(dsDict['shape'])>=2:
479 if len(dsDict['shape'])>=2:
473 dsDict['dsNumber'] = dataAux.shape[1]
480 dsDict['dsNumber'] = dataAux.shape[1]
474 else:
481 else:
475 dsDict['dsNumber'] = 1
482 dsDict['dsNumber'] = 1
476 dsDict['dtype'] = dataAux.dtype
483 dsDict['dtype'] = dataAux.dtype
477 # if len(dataAux.shape) == 4:
484 # if len(dataAux.shape) == 4:
478 # dsDict['nDim'] = len(dataAux.shape) -1
485 # dsDict['nDim'] = len(dataAux.shape) -1
479 # dsDict['shape'] = dataAux.shape
486 # dsDict['shape'] = dataAux.shape
480 # dsDict['dsNumber'] = dataAux.shape[1]
487 # dsDict['dsNumber'] = dataAux.shape[1]
481 # dsDict['dtype'] = dataAux.dtype
488 # dsDict['dtype'] = dataAux.dtype
482 # else:
489 # else:
483 # dsDict['nDim'] = len(dataAux.shape)
490 # dsDict['nDim'] = len(dataAux.shape)
484 # dsDict['shape'] = dataAux.shape
491 # dsDict['shape'] = dataAux.shape
485 # dsDict['dsNumber'] = dataAux.shape[0]
492 # dsDict['dsNumber'] = dataAux.shape[0]
486 # dsDict['dtype'] = dataAux.dtype
493 # dsDict['dtype'] = dataAux.dtype
487 dsList.append(dsDict)
494 dsList.append(dsDict)
488 #print(dsList)
495 # print("dsList: ", dsList)
489 self.dsList = dsList
496 self.dsList = dsList
497
490 def clean_dataIn(self):
498 def clean_dataIn(self):
491 for ch in range(self.nChannels):
499 for ch in range(self.nChannels):
492 self.ch_dataIn[ch].data_spc = None
500 self.ch_dataIn[ch].data_spc = None
493 self.ch_dataIn[ch].utctime = None
501 self.ch_dataIn[ch].utctime = None
494 self.ch_dataIn[ch].nIncohInt = None
502 self.ch_dataIn[ch].nIncohInt = None
495 self.meta ={}
503 self.meta ={}
496 self.blocksPerFile = None
504 self.blocksPerFile = None
505
497 def writeData(self, outFilename):
506 def writeData(self, outFilename):
498 self.getDsList()
507 self.getDsList()
499 fp = h5py.File(outFilename, 'w')
508 fp = h5py.File(outFilename, 'w')
509 # print("--> Merged file: ",fp)
500 self.writeMetadata(fp)
510 self.writeMetadata(fp)
501 grp = fp.create_group('Data')
511 grp = fp.create_group('Data')
502 dtsets = []
512 dtsets = []
503 data = []
513 data = []
504 for dsInfo in self.dsList:
514 for dsInfo in self.dsList:
505 if dsInfo['nDim'] == 0:
515 if dsInfo['nDim'] == 0:
506 ds = grp.create_dataset(
516 ds = grp.create_dataset(
507 self.getLabel(dsInfo['variable']),(self.blocksPerFile, ),chunks=True,dtype=numpy.float64)
517 self.getLabel(dsInfo['variable']),(self.blocksPerFile, ),chunks=True,dtype=numpy.float64)
508 dtsets.append(ds)
518 dtsets.append(ds)
509 data.append((dsInfo['variable'], -1))
519 data.append((dsInfo['variable'], -1))
510 else:
520 else:
511 label = self.getLabel(dsInfo['variable'])
521 label = self.getLabel(dsInfo['variable'])
512 if label is not None:
522 if label is not None:
513 sgrp = grp.create_group(label)
523 sgrp = grp.create_group(label)
514 else:
524 else:
515 sgrp = grp
525 sgrp = grp
516 k = -1*(dsInfo['nDim'] - 1)
526 k = -1*(dsInfo['nDim'] - 1)
517 #print(k, dsInfo['shape'], dsInfo['shape'][k:])
527 # print(k, dsInfo['shape'], dsInfo['shape'][k:])
518 for i in range(dsInfo['dsNumber']):
528 for i in range(dsInfo['dsNumber']):
519 ds = sgrp.create_dataset(
529 ds = sgrp.create_dataset(
520 self.getLabel(dsInfo['variable'], i),(self.blocksPerFile, ) + dsInfo['shape'][k:],
530 self.getLabel(dsInfo['variable'], i),(self.blocksPerFile, ) + dsInfo['shape'][k:],
521 chunks=True,
531 chunks=True,
522 dtype=dsInfo['dtype'])
532 dtype=dsInfo['dtype'])
523 dtsets.append(ds)
533 dtsets.append(ds)
524 data.append((dsInfo['variable'], i))
534 data.append((dsInfo['variable'], i))
525 #print("\n",dtsets)
535 #print("\n",dtsets)
526 print('Creating merged file: {}'.format(fp.filename))
536 print('Creating merged file: {}'.format(fp.filename))
527 for i, ds in enumerate(dtsets):
537 for i, ds in enumerate(dtsets):
528 attr, ch = data[i]
538 attr, ch = data[i]
529 if ch == -1:
539 if ch == -1:
530 ds[:] = getattr(self.dataOut, attr)
540 ds[:] = getattr(self.dataOut, attr)
531 else:
541 else:
532 #print(ds, getattr(self.dataOut, attr)[ch].shape)
542 #print(ds, getattr(self.dataOut, attr)[ch].shape)
533 aux = getattr(self.dataOut, attr)# block, ch, ...
543 aux = getattr(self.dataOut, attr)# block, ch, ...
534 aux = numpy.swapaxes(aux,0,1) # ch, blocks, ...
544 aux = numpy.swapaxes(aux,0,1) # ch, blocks, ...
535 #print(ds.shape, aux.shape)
545 #print(ds.shape, aux.shape)
536 #ds[:] = getattr(self.dataOut, attr)[ch]
546 #ds[:] = getattr(self.dataOut, attr)[ch]
537 ds[:] = aux[ch]
547 ds[:] = aux[ch]
538 fp.flush()
548 fp.flush()
539 fp.close()
549 fp.close()
540 self.clean_dataIn()
550 self.clean_dataIn()
541 return
551 return
552
542 def run(self):
553 def run(self):
543 if not(self.isConfig):
554 if not(self.isConfig):
544 self.setup()
555 self.setup()
545 self.isConfig = True
556 self.isConfig = True
546 for nf in range(self.nfiles):
557 for nf in range(self.nfiles):
547 name = None
558 name = None
548 for ch in range(self.nChannels):
559 for ch in range(self.nChannels):
549 name = self.filenameList[ch][nf]
560 name = self.filenameList[ch][nf]
550 filename = os.path.join(self.inPaths[ch], name)
561 filename = os.path.join(self.inPaths[ch], name)
551 fp = h5py.File(filename, 'r')
562 fp = h5py.File(filename, 'r')
552 #print("Opening file: ",filename)
563 print("Opening file: ",filename)
553 self.readFile(fp,ch)
564 self.readFile(fp,ch)
554 fp.close()
565 fp.close()
555 if self.blocksPerFile == None:
566 if self.blocksPerFile == None:
556 self.getBlocksPerFile()
567 self.getBlocksPerFile()
557 print("blocks per file: ", self.blocksPerFile)
568 print("blocks per file: ", self.blocksPerFile)
558 if not self.getDataOut():
569 if not self.getDataOut():
559 print("Error getting DataOut invalid number of blocks")
570 print("Error getting DataOut invalid number of blocks")
560 return
571 return
561 name = name[-16:]
572 name = name[-16:]
562 #print("Final name out: ", name)
573 # print("Final name out: ", name)
563 outFile = os.path.join(self.pathOut, name)
574 outFile = os.path.join(self.pathOut, name)
564 #print("Outfile: ", outFile)
575 # print("Outfile: ", outFile)
565 self.writeData(outFile) No newline at end of file
576 self.writeData(outFile)
@@ -1,1737 +1,1738
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Spectra processing Unit and operations
5 """Spectra processing Unit and operations
6
6
7 Here you will find the processing unit `SpectraProc` and several operations
7 Here you will find the processing unit `SpectraProc` and several operations
8 to work with Spectra data type
8 to work with Spectra data type
9 """
9 """
10
10
11 import time
11 import time
12 import itertools
12 import itertools
13
13
14 import numpy
14 import numpy
15
15
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
17 from schainpy.model.data.jrodata import Spectra
17 from schainpy.model.data.jrodata import Spectra
18 from schainpy.model.data.jrodata import hildebrand_sekhon
18 from schainpy.model.data.jrodata import hildebrand_sekhon
19 from schainpy.model.data import _noise
19 from schainpy.model.data import _noise
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import matplotlib.pyplot as plt
21 import matplotlib.pyplot as plt
22 from schainpy.model.io.utilsIO import getHei_index
22 from schainpy.model.io.utilsIO import getHei_index
23 import datetime
23 import datetime
24
24
25 class SpectraProc(ProcessingUnit):
25 class SpectraProc(ProcessingUnit):
26
26
27 def __init__(self):
27 def __init__(self):
28
28
29 ProcessingUnit.__init__(self)
29 ProcessingUnit.__init__(self)
30
30
31 self.buffer = None
31 self.buffer = None
32 self.firstdatatime = None
32 self.firstdatatime = None
33 self.profIndex = 0
33 self.profIndex = 0
34 self.dataOut = Spectra()
34 self.dataOut = Spectra()
35 self.dataOut.error=False
35 self.dataOut.error=False
36 self.id_min = None
36 self.id_min = None
37 self.id_max = None
37 self.id_max = None
38 self.setupReq = False #Agregar a todas las unidades de proc
38 self.setupReq = False #Agregar a todas las unidades de proc
39 self.nsamplesFFT = 0
39 self.nsamplesFFT = 0
40
40
41 def __updateSpecFromVoltage(self):
41 def __updateSpecFromVoltage(self):
42
42
43 self.dataOut.timeZone = self.dataIn.timeZone
43 self.dataOut.timeZone = self.dataIn.timeZone
44 self.dataOut.dstFlag = self.dataIn.dstFlag
44 self.dataOut.dstFlag = self.dataIn.dstFlag
45 self.dataOut.errorCount = self.dataIn.errorCount
45 self.dataOut.errorCount = self.dataIn.errorCount
46 self.dataOut.useLocalTime = self.dataIn.useLocalTime
46 self.dataOut.useLocalTime = self.dataIn.useLocalTime
47 try:
47 try:
48 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
48 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
49 except:
49 except:
50 pass
50 pass
51 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
51 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
52 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
52 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
53 self.dataOut.ippSeconds = self.dataIn.ippSeconds
53 self.dataOut.ippSeconds = self.dataIn.ippSeconds
54 self.dataOut.ipp = self.dataIn.ipp
54 self.dataOut.ipp = self.dataIn.ipp
55 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
55 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
56 self.dataOut.channelList = self.dataIn.channelList
56 self.dataOut.channelList = self.dataIn.channelList
57 self.dataOut.heightList = self.dataIn.heightList
57 self.dataOut.heightList = self.dataIn.heightList
58 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
58 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
59 self.dataOut.nProfiles = self.dataOut.nFFTPoints
59 self.dataOut.nProfiles = self.dataOut.nFFTPoints
60 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
60 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
61 self.dataOut.utctime = self.firstdatatime
61 self.dataOut.utctime = self.firstdatatime
62 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
62 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
63 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
63 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
64 self.dataOut.flagShiftFFT = False
64 self.dataOut.flagShiftFFT = False
65 self.dataOut.nCohInt = self.dataIn.nCohInt
65 self.dataOut.nCohInt = self.dataIn.nCohInt
66 self.dataOut.nIncohInt = 1
66 self.dataOut.nIncohInt = 1
67 self.dataOut.deltaHeight = self.dataIn.deltaHeight
67 self.dataOut.deltaHeight = self.dataIn.deltaHeight
68 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
68 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
69 self.dataOut.frequency = self.dataIn.frequency
69 self.dataOut.frequency = self.dataIn.frequency
70 self.dataOut.realtime = self.dataIn.realtime
70 self.dataOut.realtime = self.dataIn.realtime
71 self.dataOut.azimuth = self.dataIn.azimuth
71 self.dataOut.azimuth = self.dataIn.azimuth
72 self.dataOut.zenith = self.dataIn.zenith
72 self.dataOut.zenith = self.dataIn.zenith
73 self.dataOut.codeList = self.dataIn.codeList
73 self.dataOut.codeList = self.dataIn.codeList
74 self.dataOut.azimuthList = self.dataIn.azimuthList
74 self.dataOut.azimuthList = self.dataIn.azimuthList
75 self.dataOut.elevationList = self.dataIn.elevationList
75 self.dataOut.elevationList = self.dataIn.elevationList
76 self.dataOut.code = self.dataIn.code
76 self.dataOut.code = self.dataIn.code
77 self.dataOut.nCode = self.dataIn.nCode
77 self.dataOut.nCode = self.dataIn.nCode
78 self.dataOut.flagProfilesByRange = self.dataIn.flagProfilesByRange
78 self.dataOut.flagProfilesByRange = self.dataIn.flagProfilesByRange
79 self.dataOut.nProfilesByRange = self.dataIn.nProfilesByRange
79 self.dataOut.nProfilesByRange = self.dataIn.nProfilesByRange
80 self.dataOut.runNextUnit = self.dataIn.runNextUnit
80 self.dataOut.runNextUnit = self.dataIn.runNextUnit
81 try:
81 try:
82 self.dataOut.step = self.dataIn.step
82 self.dataOut.step = self.dataIn.step
83 except:
83 except:
84 pass
84 pass
85
85
86 def __getFft(self):
86 def __getFft(self):
87 """
87 """
88 Convierte valores de Voltaje a Spectra
88 Convierte valores de Voltaje a Spectra
89
89
90 Affected:
90 Affected:
91 self.dataOut.data_spc
91 self.dataOut.data_spc
92 self.dataOut.data_cspc
92 self.dataOut.data_cspc
93 self.dataOut.data_dc
93 self.dataOut.data_dc
94 self.dataOut.heightList
94 self.dataOut.heightList
95 self.profIndex
95 self.profIndex
96 self.buffer
96 self.buffer
97 self.dataOut.flagNoData
97 self.dataOut.flagNoData
98 """
98 """
99 fft_volt = numpy.fft.fft(
99 fft_volt = numpy.fft.fft(
100 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
100 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
101 fft_volt = fft_volt.astype(numpy.dtype('complex'))
101 fft_volt = fft_volt.astype(numpy.dtype('complex'))
102 dc = fft_volt[:, 0, :]
102 dc = fft_volt[:, 0, :]
103
103
104 # calculo de self-spectra
104 # calculo de self-spectra
105 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
105 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
106 spc = fft_volt * numpy.conjugate(fft_volt)
106 spc = fft_volt * numpy.conjugate(fft_volt)
107 spc = spc.real
107 spc = spc.real
108
108
109 blocksize = 0
109 blocksize = 0
110 blocksize += dc.size
110 blocksize += dc.size
111 blocksize += spc.size
111 blocksize += spc.size
112
112
113 cspc = None
113 cspc = None
114 pairIndex = 0
114 pairIndex = 0
115 if self.dataOut.pairsList != None:
115 if self.dataOut.pairsList != None:
116 # calculo de cross-spectra
116 # calculo de cross-spectra
117 cspc = numpy.zeros(
117 cspc = numpy.zeros(
118 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
118 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
119 for pair in self.dataOut.pairsList:
119 for pair in self.dataOut.pairsList:
120 if pair[0] not in self.dataOut.channelList:
120 if pair[0] not in self.dataOut.channelList:
121 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
121 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
122 str(pair), str(self.dataOut.channelList)))
122 str(pair), str(self.dataOut.channelList)))
123 if pair[1] not in self.dataOut.channelList:
123 if pair[1] not in self.dataOut.channelList:
124 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
124 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
125 str(pair), str(self.dataOut.channelList)))
125 str(pair), str(self.dataOut.channelList)))
126
126
127 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
127 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
128 numpy.conjugate(fft_volt[pair[1], :, :])
128 numpy.conjugate(fft_volt[pair[1], :, :])
129 pairIndex += 1
129 pairIndex += 1
130 blocksize += cspc.size
130 blocksize += cspc.size
131
131
132 self.dataOut.data_spc = spc
132 self.dataOut.data_spc = spc
133 self.dataOut.data_cspc = cspc
133 self.dataOut.data_cspc = cspc
134 self.dataOut.data_dc = dc
134 self.dataOut.data_dc = dc
135 self.dataOut.blockSize = blocksize
135 self.dataOut.blockSize = blocksize
136 self.dataOut.flagShiftFFT = False
136 self.dataOut.flagShiftFFT = False
137
137
138 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False,
138 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False,
139 zeroPad=False, zeroPoints=0, runNextUnit=0):
139 zeroPad=False, zeroPoints=0, runNextUnit=0):
140
140 self.dataIn.runNextUnit = runNextUnit
141 self.dataIn.runNextUnit = runNextUnit
141 try:
142 try:
142 type = self.dataIn.type.decode("utf-8")
143 _type = self.dataIn.type.decode("utf-8")
143 self.dataIn.type = type
144 self.dataIn.type = _type
144 except Exception as e:
145 except Exception as e:
145 # print("spc -> ",e)
146 #print("spc -> ",self.dataIn.type, e)
146 pass
147 pass
147
148
148 if self.dataIn.type == "Spectra":
149 if self.dataIn.type == "Spectra":
149 #print("AQUI")
150 #print("AQUI")
150 try:
151 try:
151 self.dataOut.copy(self.dataIn)
152 self.dataOut.copy(self.dataIn)
152 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
153 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
153 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
154 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
154 self.dataOut.nProfiles = self.dataOut.nFFTPoints
155 self.dataOut.nProfiles = self.dataOut.nFFTPoints
155 #self.dataOut.nHeights = len(self.dataOut.heightList)
156 #self.dataOut.nHeights = len(self.dataOut.heightList)
156 except Exception as e:
157 except Exception as e:
157 print("Error dataIn ",e)
158 print("Error dataIn ",e)
158
159
159 if shift_fft:
160 if shift_fft:
160 #desplaza a la derecha en el eje 2 determinadas posiciones
161 #desplaza a la derecha en el eje 2 determinadas posiciones
161 shift = int(self.dataOut.nFFTPoints/2)
162 shift = int(self.dataOut.nFFTPoints/2)
162 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
163 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
163
164
164 if self.dataOut.data_cspc is not None:
165 if self.dataOut.data_cspc is not None:
165 #desplaza a la derecha en el eje 2 determinadas posiciones
166 #desplaza a la derecha en el eje 2 determinadas posiciones
166 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
167 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
167 if pairsList:
168 if pairsList:
168 self.__selectPairs(pairsList)
169 self.__selectPairs(pairsList)
169
170
170 elif self.dataIn.type == "Voltage":
171 elif self.dataIn.type == "Voltage":
171
172
172 self.dataOut.flagNoData = True
173 self.dataOut.flagNoData = True
173 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
174 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
174 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
175 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
175
176
176 if nFFTPoints == None:
177 if nFFTPoints == None:
177 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
178 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
178
179
179 if nProfiles == None:
180 if nProfiles == None:
180 nProfiles = nFFTPoints
181 nProfiles = nFFTPoints
181
182
182 if ippFactor == None:
183 if ippFactor == None:
183 self.dataOut.ippFactor = self.dataIn.ippFactor
184 self.dataOut.ippFactor = self.dataIn.ippFactor
184 else:
185 else:
185 self.dataOut.ippFactor = ippFactor
186 self.dataOut.ippFactor = ippFactor
186
187
187 if self.buffer is None:
188 if self.buffer is None:
188 if not zeroPad:
189 if not zeroPad:
189 self.buffer = numpy.zeros((self.dataIn.nChannels,
190 self.buffer = numpy.zeros((self.dataIn.nChannels,
190 nProfiles,
191 nProfiles,
191 self.dataIn.nHeights),
192 self.dataIn.nHeights),
192 dtype='complex')
193 dtype='complex')
193 zeroPoints = 0
194 zeroPoints = 0
194 else:
195 else:
195 self.buffer = numpy.zeros((self.dataIn.nChannels,
196 self.buffer = numpy.zeros((self.dataIn.nChannels,
196 nFFTPoints+int(zeroPoints),
197 nFFTPoints+int(zeroPoints),
197 self.dataIn.nHeights),
198 self.dataIn.nHeights),
198 dtype='complex')
199 dtype='complex')
199
200
200 self.dataOut.nFFTPoints = nFFTPoints
201 self.dataOut.nFFTPoints = nFFTPoints
201
202
202 if self.buffer is None:
203 if self.buffer is None:
203 self.buffer = numpy.zeros((self.dataIn.nChannels,
204 self.buffer = numpy.zeros((self.dataIn.nChannels,
204 nProfiles,
205 nProfiles,
205 self.dataIn.nHeights),
206 self.dataIn.nHeights),
206 dtype='complex')
207 dtype='complex')
207
208
208 if self.dataIn.flagDataAsBlock:
209 if self.dataIn.flagDataAsBlock:
209 nVoltProfiles = self.dataIn.data.shape[1]
210 nVoltProfiles = self.dataIn.data.shape[1]
210 zeroPoints = 0
211 zeroPoints = 0
211 if nVoltProfiles == nProfiles or zeroPad:
212 if nVoltProfiles == nProfiles or zeroPad:
212 self.buffer = self.dataIn.data.copy()
213 self.buffer = self.dataIn.data.copy()
213 self.profIndex = nVoltProfiles
214 self.profIndex = nVoltProfiles
214
215
215 elif nVoltProfiles < nProfiles:
216 elif nVoltProfiles < nProfiles:
216
217
217 if self.profIndex == 0:
218 if self.profIndex == 0:
218 self.id_min = 0
219 self.id_min = 0
219 self.id_max = nVoltProfiles
220 self.id_max = nVoltProfiles
220
221
221 self.buffer[:, self.id_min:self.id_max,
222 self.buffer[:, self.id_min:self.id_max,
222 :] = self.dataIn.data
223 :] = self.dataIn.data
223 self.profIndex += nVoltProfiles
224 self.profIndex += nVoltProfiles
224 self.id_min += nVoltProfiles
225 self.id_min += nVoltProfiles
225 self.id_max += nVoltProfiles
226 self.id_max += nVoltProfiles
226 elif nVoltProfiles > nProfiles:
227 elif nVoltProfiles > nProfiles:
227 self.reader.bypass = True
228 self.reader.bypass = True
228 if self.profIndex == 0:
229 if self.profIndex == 0:
229 self.id_min = 0
230 self.id_min = 0
230 self.id_max = nProfiles
231 self.id_max = nProfiles
231
232
232 self.buffer = self.dataIn.data[:, self.id_min:self.id_max,:]
233 self.buffer = self.dataIn.data[:, self.id_min:self.id_max,:]
233 self.profIndex += nProfiles
234 self.profIndex += nProfiles
234 self.id_min += nProfiles
235 self.id_min += nProfiles
235 self.id_max += nProfiles
236 self.id_max += nProfiles
236 if self.id_max == nVoltProfiles:
237 if self.id_max == nVoltProfiles:
237 self.reader.bypass = False
238 self.reader.bypass = False
238
239
239 else:
240 else:
240 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
241 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
241 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
242 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
242 self.dataOut.flagNoData = True
243 self.dataOut.flagNoData = True
243 else:
244 else:
244 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
245 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
245 self.profIndex += 1
246 self.profIndex += 1
246
247
247 if self.firstdatatime == None:
248 if self.firstdatatime == None:
248 self.firstdatatime = self.dataIn.utctime
249 self.firstdatatime = self.dataIn.utctime
249
250
250 if self.profIndex == nProfiles or (zeroPad and zeroPoints==0):
251 if self.profIndex == nProfiles or (zeroPad and zeroPoints==0):
251
252
252 self.__updateSpecFromVoltage()
253 self.__updateSpecFromVoltage()
253 if pairsList == None:
254 if pairsList == None:
254 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
255 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
255 else:
256 else:
256 self.dataOut.pairsList = pairsList
257 self.dataOut.pairsList = pairsList
257 self.__getFft()
258 self.__getFft()
258 self.dataOut.flagNoData = False
259 self.dataOut.flagNoData = False
259 self.firstdatatime = None
260 self.firstdatatime = None
260 self.nsamplesFFT = self.profIndex
261 self.nsamplesFFT = self.profIndex
261 #if not self.reader.bypass:
262 #if not self.reader.bypass:
262 self.profIndex = 0
263 self.profIndex = 0
263 #update Processing Header:
264 #update Processing Header:
264 self.dataOut.processingHeaderObj.dtype = "Spectra"
265 self.dataOut.processingHeaderObj.dtype = "Spectra"
265 self.dataOut.processingHeaderObj.nFFTPoints = self.dataOut.nFFTPoints
266 self.dataOut.processingHeaderObj.nFFTPoints = self.dataOut.nFFTPoints
266 self.dataOut.processingHeaderObj.nSamplesFFT = self.nsamplesFFT
267 self.dataOut.processingHeaderObj.nSamplesFFT = self.nsamplesFFT
267 self.dataOut.processingHeaderObj.nIncohInt = 1
268 self.dataOut.processingHeaderObj.nIncohInt = 1
268
269
269 elif self.dataIn.type == "Parameters": #when get data from h5 spc file
270 elif self.dataIn.type == "Parameters": #when get data from h5 spc file
270
271
271 self.dataOut.data_spc = self.dataIn.data_spc
272 self.dataOut.data_spc = self.dataIn.data_spc
272 self.dataOut.data_cspc = self.dataIn.data_cspc
273 self.dataOut.data_cspc = self.dataIn.data_cspc
273 self.dataOut.data_outlier = self.dataIn.data_outlier
274 self.dataOut.data_outlier = self.dataIn.data_outlier
274 self.dataOut.nProfiles = self.dataIn.nProfiles
275 self.dataOut.nProfiles = self.dataIn.nProfiles
275 self.dataOut.nIncohInt = self.dataIn.nIncohInt
276 self.dataOut.nIncohInt = self.dataIn.nIncohInt
276 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
277 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
277 self.dataOut.ippFactor = self.dataIn.ippFactor
278 self.dataOut.ippFactor = self.dataIn.ippFactor
278 self.dataOut.max_nIncohInt = self.dataIn.max_nIncohInt
279 self.dataOut.max_nIncohInt = self.dataIn.max_nIncohInt
279 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
280 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
280 self.dataOut.ProcessingHeader = self.dataIn.ProcessingHeader.copy()
281 self.dataOut.ProcessingHeader = self.dataIn.ProcessingHeader.copy()
281 self.dataOut.ippSeconds = self.dataIn.ippSeconds
282 self.dataOut.ippSeconds = self.dataIn.ippSeconds
282 self.dataOut.ipp = self.dataIn.ipp
283 self.dataOut.ipp = self.dataIn.ipp
283 #self.dataOut.abscissaList = self.dataIn.getVelRange(1)
284 #self.dataOut.abscissaList = self.dataIn.getVelRange(1)
284 #self.dataOut.spc_noise = self.dataIn.getNoise()
285 #self.dataOut.spc_noise = self.dataIn.getNoise()
285 #self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
286 #self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
286 # self.dataOut.normFactor = self.dataIn.normFactor
287 # self.dataOut.normFactor = self.dataIn.normFactor
287 if hasattr(self.dataIn, 'channelList'):
288 if hasattr(self.dataIn, 'channelList'):
288 self.dataOut.channelList = self.dataIn.channelList
289 self.dataOut.channelList = self.dataIn.channelList
289 if hasattr(self.dataIn, 'pairsList'):
290 if hasattr(self.dataIn, 'pairsList'):
290 self.dataOut.pairsList = self.dataIn.pairsList
291 self.dataOut.pairsList = self.dataIn.pairsList
291 self.dataOut.groupList = self.dataIn.pairsList
292 self.dataOut.groupList = self.dataIn.pairsList
292
293
293 self.dataOut.flagNoData = False
294 self.dataOut.flagNoData = False
294
295
295 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
296 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
296 self.dataOut.ChanDist = self.dataIn.ChanDist
297 self.dataOut.ChanDist = self.dataIn.ChanDist
297 else: self.dataOut.ChanDist = None
298 else: self.dataOut.ChanDist = None
298
299
299 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
300 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
300 # self.dataOut.VelRange = self.dataIn.VelRange
301 # self.dataOut.VelRange = self.dataIn.VelRange
301 #else: self.dataOut.VelRange = None
302 #else: self.dataOut.VelRange = None
302
303
303 else:
304 else:
304 raise ValueError("The type of input object '%s' is not valid".format(
305 raise ValueError("The type of input object '%s' is not valid".format(
305 self.dataIn.type))
306 self.dataIn.type))
306 # print("SPC done")
307 # print("SPC done")
307
308
308 def __selectPairs(self, pairsList):
309 def __selectPairs(self, pairsList):
309
310
310 if not pairsList:
311 if not pairsList:
311 return
312 return
312
313
313 pairs = []
314 pairs = []
314 pairsIndex = []
315 pairsIndex = []
315
316
316 for pair in pairsList:
317 for pair in pairsList:
317 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
318 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
318 continue
319 continue
319 pairs.append(pair)
320 pairs.append(pair)
320 pairsIndex.append(pairs.index(pair))
321 pairsIndex.append(pairs.index(pair))
321
322
322 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
323 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
323 self.dataOut.pairsList = pairs
324 self.dataOut.pairsList = pairs
324
325
325 return
326 return
326
327
327 def selectFFTs(self, minFFT, maxFFT ):
328 def selectFFTs(self, minFFT, maxFFT ):
328 """
329 """
329 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
330 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
330 minFFT<= FFT <= maxFFT
331 minFFT<= FFT <= maxFFT
331 """
332 """
332
333
333 if (minFFT > maxFFT):
334 if (minFFT > maxFFT):
334 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
335 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
335
336
336 if (minFFT < self.dataOut.getFreqRange()[0]):
337 if (minFFT < self.dataOut.getFreqRange()[0]):
337 minFFT = self.dataOut.getFreqRange()[0]
338 minFFT = self.dataOut.getFreqRange()[0]
338
339
339 if (maxFFT > self.dataOut.getFreqRange()[-1]):
340 if (maxFFT > self.dataOut.getFreqRange()[-1]):
340 maxFFT = self.dataOut.getFreqRange()[-1]
341 maxFFT = self.dataOut.getFreqRange()[-1]
341
342
342 minIndex = 0
343 minIndex = 0
343 maxIndex = 0
344 maxIndex = 0
344 FFTs = self.dataOut.getFreqRange()
345 FFTs = self.dataOut.getFreqRange()
345
346
346 inda = numpy.where(FFTs >= minFFT)
347 inda = numpy.where(FFTs >= minFFT)
347 indb = numpy.where(FFTs <= maxFFT)
348 indb = numpy.where(FFTs <= maxFFT)
348
349
349 try:
350 try:
350 minIndex = inda[0][0]
351 minIndex = inda[0][0]
351 except:
352 except:
352 minIndex = 0
353 minIndex = 0
353
354
354 try:
355 try:
355 maxIndex = indb[0][-1]
356 maxIndex = indb[0][-1]
356 except:
357 except:
357 maxIndex = len(FFTs)
358 maxIndex = len(FFTs)
358
359
359 self.selectFFTsByIndex(minIndex, maxIndex)
360 self.selectFFTsByIndex(minIndex, maxIndex)
360
361
361 return 1
362 return 1
362
363
363 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
364 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
364 newheis = numpy.where(
365 newheis = numpy.where(
365 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
366 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
366
367
367 if hei_ref != None:
368 if hei_ref != None:
368 newheis = numpy.where(self.dataOut.heightList > hei_ref)
369 newheis = numpy.where(self.dataOut.heightList > hei_ref)
369
370
370 minIndex = min(newheis[0])
371 minIndex = min(newheis[0])
371 maxIndex = max(newheis[0])
372 maxIndex = max(newheis[0])
372 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
373 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
373 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
374 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
374
375
375 # determina indices
376 # determina indices
376 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
377 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
377 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
378 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
378 avg_dB = 10 * \
379 avg_dB = 10 * \
379 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
380 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
380 beacon_dB = numpy.sort(avg_dB)[-nheis:]
381 beacon_dB = numpy.sort(avg_dB)[-nheis:]
381 beacon_heiIndexList = []
382 beacon_heiIndexList = []
382 for val in avg_dB.tolist():
383 for val in avg_dB.tolist():
383 if val >= beacon_dB[0]:
384 if val >= beacon_dB[0]:
384 beacon_heiIndexList.append(avg_dB.tolist().index(val))
385 beacon_heiIndexList.append(avg_dB.tolist().index(val))
385
386
386 data_cspc = None
387 data_cspc = None
387 if self.dataOut.data_cspc is not None:
388 if self.dataOut.data_cspc is not None:
388 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
389 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
389
390
390 data_dc = None
391 data_dc = None
391 if self.dataOut.data_dc is not None:
392 if self.dataOut.data_dc is not None:
392 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
393 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
393
394
394 self.dataOut.data_spc = data_spc
395 self.dataOut.data_spc = data_spc
395 self.dataOut.data_cspc = data_cspc
396 self.dataOut.data_cspc = data_cspc
396 self.dataOut.data_dc = data_dc
397 self.dataOut.data_dc = data_dc
397 self.dataOut.heightList = heightList
398 self.dataOut.heightList = heightList
398 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
399 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
399
400
400 return 1
401 return 1
401
402
402 def selectFFTsByIndex(self, minIndex, maxIndex):
403 def selectFFTsByIndex(self, minIndex, maxIndex):
403 """
404 """
404
405
405 """
406 """
406
407
407 if (minIndex < 0) or (minIndex > maxIndex):
408 if (minIndex < 0) or (minIndex > maxIndex):
408 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
409 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
409
410
410 if (maxIndex >= self.dataOut.nProfiles):
411 if (maxIndex >= self.dataOut.nProfiles):
411 maxIndex = self.dataOut.nProfiles-1
412 maxIndex = self.dataOut.nProfiles-1
412
413
413 #Spectra
414 #Spectra
414 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
415 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
415
416
416 data_cspc = None
417 data_cspc = None
417 if self.dataOut.data_cspc is not None:
418 if self.dataOut.data_cspc is not None:
418 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
419 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
419
420
420 data_dc = None
421 data_dc = None
421 if self.dataOut.data_dc is not None:
422 if self.dataOut.data_dc is not None:
422 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
423 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
423
424
424 self.dataOut.data_spc = data_spc
425 self.dataOut.data_spc = data_spc
425 self.dataOut.data_cspc = data_cspc
426 self.dataOut.data_cspc = data_cspc
426 self.dataOut.data_dc = data_dc
427 self.dataOut.data_dc = data_dc
427
428
428 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
429 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
429 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
430 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
430 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
431 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
431
432
432 return 1
433 return 1
433
434
434 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
435 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
435 # validacion de rango
436 # validacion de rango
436 if minHei == None:
437 if minHei == None:
437 minHei = self.dataOut.heightList[0]
438 minHei = self.dataOut.heightList[0]
438
439
439 if maxHei == None:
440 if maxHei == None:
440 maxHei = self.dataOut.heightList[-1]
441 maxHei = self.dataOut.heightList[-1]
441
442
442 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
443 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
443 print('minHei: %.2f is out of the heights range' % (minHei))
444 print('minHei: %.2f is out of the heights range' % (minHei))
444 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
445 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
445 minHei = self.dataOut.heightList[0]
446 minHei = self.dataOut.heightList[0]
446
447
447 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
448 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
448 print('maxHei: %.2f is out of the heights range' % (maxHei))
449 print('maxHei: %.2f is out of the heights range' % (maxHei))
449 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
450 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
450 maxHei = self.dataOut.heightList[-1]
451 maxHei = self.dataOut.heightList[-1]
451
452
452 # validacion de velocidades
453 # validacion de velocidades
453 velrange = self.dataOut.getVelRange(1)
454 velrange = self.dataOut.getVelRange(1)
454
455
455 if minVel == None:
456 if minVel == None:
456 minVel = velrange[0]
457 minVel = velrange[0]
457
458
458 if maxVel == None:
459 if maxVel == None:
459 maxVel = velrange[-1]
460 maxVel = velrange[-1]
460
461
461 if (minVel < velrange[0]) or (minVel > maxVel):
462 if (minVel < velrange[0]) or (minVel > maxVel):
462 print('minVel: %.2f is out of the velocity range' % (minVel))
463 print('minVel: %.2f is out of the velocity range' % (minVel))
463 print('minVel is setting to %.2f' % (velrange[0]))
464 print('minVel is setting to %.2f' % (velrange[0]))
464 minVel = velrange[0]
465 minVel = velrange[0]
465
466
466 if (maxVel > velrange[-1]) or (maxVel < minVel):
467 if (maxVel > velrange[-1]) or (maxVel < minVel):
467 print('maxVel: %.2f is out of the velocity range' % (maxVel))
468 print('maxVel: %.2f is out of the velocity range' % (maxVel))
468 print('maxVel is setting to %.2f' % (velrange[-1]))
469 print('maxVel is setting to %.2f' % (velrange[-1]))
469 maxVel = velrange[-1]
470 maxVel = velrange[-1]
470
471
471 # seleccion de indices para rango
472 # seleccion de indices para rango
472 minIndex = 0
473 minIndex = 0
473 maxIndex = 0
474 maxIndex = 0
474 heights = self.dataOut.heightList
475 heights = self.dataOut.heightList
475
476
476 inda = numpy.where(heights >= minHei)
477 inda = numpy.where(heights >= minHei)
477 indb = numpy.where(heights <= maxHei)
478 indb = numpy.where(heights <= maxHei)
478
479
479 try:
480 try:
480 minIndex = inda[0][0]
481 minIndex = inda[0][0]
481 except:
482 except:
482 minIndex = 0
483 minIndex = 0
483
484
484 try:
485 try:
485 maxIndex = indb[0][-1]
486 maxIndex = indb[0][-1]
486 except:
487 except:
487 maxIndex = len(heights)
488 maxIndex = len(heights)
488
489
489 if (minIndex < 0) or (minIndex > maxIndex):
490 if (minIndex < 0) or (minIndex > maxIndex):
490 raise ValueError("some value in (%d,%d) is not valid" % (
491 raise ValueError("some value in (%d,%d) is not valid" % (
491 minIndex, maxIndex))
492 minIndex, maxIndex))
492
493
493 if (maxIndex >= self.dataOut.nHeights):
494 if (maxIndex >= self.dataOut.nHeights):
494 maxIndex = self.dataOut.nHeights - 1
495 maxIndex = self.dataOut.nHeights - 1
495
496
496 # seleccion de indices para velocidades
497 # seleccion de indices para velocidades
497 indminvel = numpy.where(velrange >= minVel)
498 indminvel = numpy.where(velrange >= minVel)
498 indmaxvel = numpy.where(velrange <= maxVel)
499 indmaxvel = numpy.where(velrange <= maxVel)
499 try:
500 try:
500 minIndexVel = indminvel[0][0]
501 minIndexVel = indminvel[0][0]
501 except:
502 except:
502 minIndexVel = 0
503 minIndexVel = 0
503
504
504 try:
505 try:
505 maxIndexVel = indmaxvel[0][-1]
506 maxIndexVel = indmaxvel[0][-1]
506 except:
507 except:
507 maxIndexVel = len(velrange)
508 maxIndexVel = len(velrange)
508
509
509 # seleccion del espectro
510 # seleccion del espectro
510 data_spc = self.dataOut.data_spc[:,
511 data_spc = self.dataOut.data_spc[:,
511 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
512 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
512 # estimacion de ruido
513 # estimacion de ruido
513 noise = numpy.zeros(self.dataOut.nChannels)
514 noise = numpy.zeros(self.dataOut.nChannels)
514
515
515 for channel in range(self.dataOut.nChannels):
516 for channel in range(self.dataOut.nChannels):
516 daux = data_spc[channel, :, :]
517 daux = data_spc[channel, :, :]
517 sortdata = numpy.sort(daux, axis=None)
518 sortdata = numpy.sort(daux, axis=None)
518 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
519 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
519
520
520 self.dataOut.noise_estimation = noise.copy()
521 self.dataOut.noise_estimation = noise.copy()
521
522
522 return 1
523 return 1
523
524
524 class GetSNR(Operation):
525 class GetSNR(Operation):
525 '''
526 '''
526 Written by R. Flores
527 Written by R. Flores
527 '''
528 '''
528 """Operation to get SNR.
529 """Operation to get SNR.
529
530
530 Parameters:
531 Parameters:
531 -----------
532 -----------
532
533
533 Example
534 Example
534 --------
535 --------
535
536
536 op = proc_unit.addOperation(name='GetSNR', optype='other')
537 op = proc_unit.addOperation(name='GetSNR', optype='other')
537
538
538 """
539 """
539
540
540 def __init__(self, **kwargs):
541 def __init__(self, **kwargs):
541
542
542 Operation.__init__(self, **kwargs)
543 Operation.__init__(self, **kwargs)
543
544
544 def run(self,dataOut):
545 def run(self,dataOut):
545
546
546 noise = dataOut.getNoise(ymin_index=-10) #RegiΓ³n superior donde solo deberΓ­a de haber ruido
547 noise = dataOut.getNoise(ymin_index=-10) #RegiΓ³n superior donde solo deberΓ­a de haber ruido
547 dataOut.data_snr = (dataOut.data_spc.sum(axis=1)-noise[:,None]*dataOut.nFFTPoints)/(noise[:,None]*dataOut.nFFTPoints) #It works apparently
548 dataOut.data_snr = (dataOut.data_spc.sum(axis=1)-noise[:,None]*dataOut.nFFTPoints)/(noise[:,None]*dataOut.nFFTPoints) #It works apparently
548 dataOut.snl = numpy.log10(dataOut.data_snr)
549 dataOut.snl = numpy.log10(dataOut.data_snr)
549 dataOut.snl = numpy.where(dataOut.data_snr<.01, numpy.nan, dataOut.snl)
550 dataOut.snl = numpy.where(dataOut.data_snr<.01, numpy.nan, dataOut.snl)
550
551
551 return dataOut
552 return dataOut
552
553
553 class removeDC(Operation):
554 class removeDC(Operation):
554
555
555 def run(self, dataOut, mode=2):
556 def run(self, dataOut, mode=2):
556 self.dataOut = dataOut
557 self.dataOut = dataOut
557 jspectra = self.dataOut.data_spc
558 jspectra = self.dataOut.data_spc
558 jcspectra = self.dataOut.data_cspc
559 jcspectra = self.dataOut.data_cspc
559
560
560 num_chan = jspectra.shape[0]
561 num_chan = jspectra.shape[0]
561 num_hei = jspectra.shape[2]
562 num_hei = jspectra.shape[2]
562
563
563 if jcspectra is not None:
564 if jcspectra is not None:
564 jcspectraExist = True
565 jcspectraExist = True
565 num_pairs = jcspectra.shape[0]
566 num_pairs = jcspectra.shape[0]
566 else:
567 else:
567 jcspectraExist = False
568 jcspectraExist = False
568
569
569 freq_dc = int(jspectra.shape[1] / 2)
570 freq_dc = int(jspectra.shape[1] / 2)
570 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
571 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
571 ind_vel = ind_vel.astype(int)
572 ind_vel = ind_vel.astype(int)
572
573
573 if ind_vel[0] < 0:
574 if ind_vel[0] < 0:
574 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
575 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
575
576
576 if mode == 1:
577 if mode == 1:
577 jspectra[:, freq_dc, :] = (
578 jspectra[:, freq_dc, :] = (
578 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
579 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
579
580
580 if jcspectraExist:
581 if jcspectraExist:
581 jcspectra[:, freq_dc, :] = (
582 jcspectra[:, freq_dc, :] = (
582 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
583 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
583
584
584 if mode == 2:
585 if mode == 2:
585
586
586 vel = numpy.array([-2, -1, 1, 2])
587 vel = numpy.array([-2, -1, 1, 2])
587 xx = numpy.zeros([4, 4])
588 xx = numpy.zeros([4, 4])
588
589
589 for fil in range(4):
590 for fil in range(4):
590 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
591 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
591
592
592 xx_inv = numpy.linalg.inv(xx)
593 xx_inv = numpy.linalg.inv(xx)
593 xx_aux = xx_inv[0, :]
594 xx_aux = xx_inv[0, :]
594
595
595 for ich in range(num_chan):
596 for ich in range(num_chan):
596 yy = jspectra[ich, ind_vel, :]
597 yy = jspectra[ich, ind_vel, :]
597 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
598 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
598
599
599 junkid = jspectra[ich, freq_dc, :] <= 0
600 junkid = jspectra[ich, freq_dc, :] <= 0
600 cjunkid = sum(junkid)
601 cjunkid = sum(junkid)
601
602
602 if cjunkid.any():
603 if cjunkid.any():
603 jspectra[ich, freq_dc, junkid.nonzero()] = (
604 jspectra[ich, freq_dc, junkid.nonzero()] = (
604 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
605 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
605
606
606 if jcspectraExist:
607 if jcspectraExist:
607 for ip in range(num_pairs):
608 for ip in range(num_pairs):
608 yy = jcspectra[ip, ind_vel, :]
609 yy = jcspectra[ip, ind_vel, :]
609 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
610 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
610
611
611 self.dataOut.data_spc = jspectra
612 self.dataOut.data_spc = jspectra
612 self.dataOut.data_cspc = jcspectra
613 self.dataOut.data_cspc = jcspectra
613
614
614 return self.dataOut
615 return self.dataOut
615 class getNoiseB(Operation):
616 class getNoiseB(Operation):
616 """
617 """
617 Get noise from custom heights and frequency ranges,
618 Get noise from custom heights and frequency ranges,
618 offset for additional manual correction
619 offset for additional manual correction
619 J. Apaza -> developed to amisr isr spectra
620 J. Apaza -> developed to amisr isr spectra
620
621
621 """
622 """
622 __slots__ =('offset','warnings', 'isConfig', 'minIndex','maxIndex','minIndexFFT','maxIndexFFT')
623 __slots__ =('offset','warnings', 'isConfig', 'minIndex','maxIndex','minIndexFFT','maxIndexFFT')
623 def __init__(self):
624 def __init__(self):
624
625
625 Operation.__init__(self)
626 Operation.__init__(self)
626 self.isConfig = False
627 self.isConfig = False
627
628
628 def setup(self, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
629 def setup(self, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
629
630
630 self.warnings = warnings
631 self.warnings = warnings
631 if minHei == None:
632 if minHei == None:
632 minHei = self.dataOut.heightList[0]
633 minHei = self.dataOut.heightList[0]
633
634
634 if maxHei == None:
635 if maxHei == None:
635 maxHei = self.dataOut.heightList[-1]
636 maxHei = self.dataOut.heightList[-1]
636
637
637 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
638 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
638 if self.warnings:
639 if self.warnings:
639 print('minHei: %.2f is out of the heights range' % (minHei))
640 print('minHei: %.2f is out of the heights range' % (minHei))
640 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
641 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
641 minHei = self.dataOut.heightList[0]
642 minHei = self.dataOut.heightList[0]
642
643
643 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
644 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
644 if self.warnings:
645 if self.warnings:
645 print('maxHei: %.2f is out of the heights range' % (maxHei))
646 print('maxHei: %.2f is out of the heights range' % (maxHei))
646 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
647 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
647 maxHei = self.dataOut.heightList[-1]
648 maxHei = self.dataOut.heightList[-1]
648
649
649
650
650 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
651 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
651 minIndexFFT = 0
652 minIndexFFT = 0
652 maxIndexFFT = 0
653 maxIndexFFT = 0
653 # validacion de velocidades
654 # validacion de velocidades
654 indminPoint = None
655 indminPoint = None
655 indmaxPoint = None
656 indmaxPoint = None
656 if self.dataOut.type == 'Spectra':
657 if self.dataOut.type == 'Spectra':
657 if minVel == None and maxVel == None :
658 if minVel == None and maxVel == None :
658
659
659 freqrange = self.dataOut.getFreqRange(1)
660 freqrange = self.dataOut.getFreqRange(1)
660
661
661 if minFreq == None:
662 if minFreq == None:
662 minFreq = freqrange[0]
663 minFreq = freqrange[0]
663
664
664 if maxFreq == None:
665 if maxFreq == None:
665 maxFreq = freqrange[-1]
666 maxFreq = freqrange[-1]
666
667
667 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
668 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
668 if self.warnings:
669 if self.warnings:
669 print('minFreq: %.2f is out of the frequency range' % (minFreq))
670 print('minFreq: %.2f is out of the frequency range' % (minFreq))
670 print('minFreq is setting to %.2f' % (freqrange[0]))
671 print('minFreq is setting to %.2f' % (freqrange[0]))
671 minFreq = freqrange[0]
672 minFreq = freqrange[0]
672
673
673 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
674 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
674 if self.warnings:
675 if self.warnings:
675 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
676 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
676 print('maxFreq is setting to %.2f' % (freqrange[-1]))
677 print('maxFreq is setting to %.2f' % (freqrange[-1]))
677 maxFreq = freqrange[-1]
678 maxFreq = freqrange[-1]
678
679
679 indminPoint = numpy.where(freqrange >= minFreq)
680 indminPoint = numpy.where(freqrange >= minFreq)
680 indmaxPoint = numpy.where(freqrange <= maxFreq)
681 indmaxPoint = numpy.where(freqrange <= maxFreq)
681
682
682 else:
683 else:
683
684
684 velrange = self.dataOut.getVelRange(1)
685 velrange = self.dataOut.getVelRange(1)
685
686
686 if minVel == None:
687 if minVel == None:
687 minVel = velrange[0]
688 minVel = velrange[0]
688
689
689 if maxVel == None:
690 if maxVel == None:
690 maxVel = velrange[-1]
691 maxVel = velrange[-1]
691
692
692 if (minVel < velrange[0]) or (minVel > maxVel):
693 if (minVel < velrange[0]) or (minVel > maxVel):
693 if self.warnings:
694 if self.warnings:
694 print('minVel: %.2f is out of the velocity range' % (minVel))
695 print('minVel: %.2f is out of the velocity range' % (minVel))
695 print('minVel is setting to %.2f' % (velrange[0]))
696 print('minVel is setting to %.2f' % (velrange[0]))
696 minVel = velrange[0]
697 minVel = velrange[0]
697
698
698 if (maxVel > velrange[-1]) or (maxVel < minVel):
699 if (maxVel > velrange[-1]) or (maxVel < minVel):
699 if self.warnings:
700 if self.warnings:
700 print('maxVel: %.2f is out of the velocity range' % (maxVel))
701 print('maxVel: %.2f is out of the velocity range' % (maxVel))
701 print('maxVel is setting to %.2f' % (velrange[-1]))
702 print('maxVel is setting to %.2f' % (velrange[-1]))
702 maxVel = velrange[-1]
703 maxVel = velrange[-1]
703
704
704 indminPoint = numpy.where(velrange >= minVel)
705 indminPoint = numpy.where(velrange >= minVel)
705 indmaxPoint = numpy.where(velrange <= maxVel)
706 indmaxPoint = numpy.where(velrange <= maxVel)
706
707
707
708
708 # seleccion de indices para rango REEMPLAZAR FOR FUNCION EXTERNA LUEGO
709 # seleccion de indices para rango REEMPLAZAR FOR FUNCION EXTERNA LUEGO
709 # minIndex = 0
710 # minIndex = 0
710 # maxIndex = 0
711 # maxIndex = 0
711 # heights = self.dataOut.heightList
712 # heights = self.dataOut.heightList
712 # inda = numpy.where(heights >= minHei)
713 # inda = numpy.where(heights >= minHei)
713 # indb = numpy.where(heights <= maxHei)
714 # indb = numpy.where(heights <= maxHei)
714 # try:
715 # try:
715 # minIndex = inda[0][0]
716 # minIndex = inda[0][0]
716 # except:
717 # except:
717 # minIndex = 0
718 # minIndex = 0
718 # try:
719 # try:
719 # maxIndex = indb[0][-1]
720 # maxIndex = indb[0][-1]
720 # except:
721 # except:
721 # maxIndex = len(heights)
722 # maxIndex = len(heights)
722 # if (minIndex < 0) or (minIndex > maxIndex):
723 # if (minIndex < 0) or (minIndex > maxIndex):
723 # raise ValueError("some value in (%d,%d) is not valid" % (
724 # raise ValueError("some value in (%d,%d) is not valid" % (
724 # minIndex, maxIndex))
725 # minIndex, maxIndex))
725 # if (maxIndex >= self.dataOut.nHeights):
726 # if (maxIndex >= self.dataOut.nHeights):
726 # maxIndex = self.dataOut.nHeights - 1
727 # maxIndex = self.dataOut.nHeights - 1
727
728
728 minIndex, maxIndex = getHei_index(minHei,maxHei,self.dataOut.heightList)
729 minIndex, maxIndex = getHei_index(minHei,maxHei,self.dataOut.heightList)
729
730
730
731
731 #############################################################3
732 #############################################################3
732 # seleccion de indices para velocidades
733 # seleccion de indices para velocidades
733 if self.dataOut.type == 'Spectra':
734 if self.dataOut.type == 'Spectra':
734 try:
735 try:
735 minIndexFFT = indminPoint[0][0]
736 minIndexFFT = indminPoint[0][0]
736 except:
737 except:
737 minIndexFFT = 0
738 minIndexFFT = 0
738
739
739 try:
740 try:
740 maxIndexFFT = indmaxPoint[0][-1]
741 maxIndexFFT = indmaxPoint[0][-1]
741 except:
742 except:
742 maxIndexFFT = len( self.dataOut.getFreqRange(1))
743 maxIndexFFT = len( self.dataOut.getFreqRange(1))
743
744
744 self.minIndex, self.maxIndex, self.minIndexFFT, self.maxIndexFFT = minIndex, maxIndex, minIndexFFT, maxIndexFFT
745 self.minIndex, self.maxIndex, self.minIndexFFT, self.maxIndexFFT = minIndex, maxIndex, minIndexFFT, maxIndexFFT
745 self.isConfig = True
746 self.isConfig = True
746 self.offset = 1
747 self.offset = 1
747 if offset!=None:
748 if offset!=None:
748 self.offset = 10**(offset/10)
749 self.offset = 10**(offset/10)
749
750
750
751
751 def run(self, dataOut, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
752 def run(self, dataOut, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
752 self.dataOut = dataOut
753 self.dataOut = dataOut
753
754
754 if not self.isConfig:
755 if not self.isConfig:
755 self.setup(offset, minHei, maxHei,minVel, maxVel, minFreq, maxFreq, warnings)
756 self.setup(offset, minHei, maxHei,minVel, maxVel, minFreq, maxFreq, warnings)
756
757
757 self.dataOut.noise_estimation = None
758 self.dataOut.noise_estimation = None
758 noise = None
759 noise = None
759 if self.dataOut.type == 'Voltage':
760 if self.dataOut.type == 'Voltage':
760 noise = self.dataOut.getNoise(ymin_index=self.minIndex, ymax_index=self.maxIndex)
761 noise = self.dataOut.getNoise(ymin_index=self.minIndex, ymax_index=self.maxIndex)
761 elif self.dataOut.type == 'Spectra':
762 elif self.dataOut.type == 'Spectra':
762 noise = numpy.zeros( self.dataOut.nChannels)
763 noise = numpy.zeros( self.dataOut.nChannels)
763 norm = 1
764 norm = 1
764
765
765 for channel in range( self.dataOut.nChannels):
766 for channel in range( self.dataOut.nChannels):
766 if not hasattr(self.dataOut.nIncohInt,'__len__'):
767 if not hasattr(self.dataOut.nIncohInt,'__len__'):
767 norm = 1
768 norm = 1
768 else:
769 else:
769 norm = self.dataOut.max_nIncohInt[channel]/self.dataOut.nIncohInt[channel, self.minIndex:self.maxIndex]
770 norm = self.dataOut.max_nIncohInt[channel]/self.dataOut.nIncohInt[channel, self.minIndex:self.maxIndex]
770
771
771 daux = self.dataOut.data_spc[channel,self.minIndexFFT:self.maxIndexFFT, self.minIndex:self.maxIndex]
772 daux = self.dataOut.data_spc[channel,self.minIndexFFT:self.maxIndexFFT, self.minIndex:self.maxIndex]
772 daux = numpy.multiply(daux, norm)
773 daux = numpy.multiply(daux, norm)
773 sortdata = numpy.sort(daux, axis=None)
774 sortdata = numpy.sort(daux, axis=None)
774 noise[channel] = _noise.hildebrand_sekhon(sortdata, self.dataOut.max_nIncohInt[channel])/self.offset
775 noise[channel] = _noise.hildebrand_sekhon(sortdata, self.dataOut.max_nIncohInt[channel])/self.offset
775
776
776 else:
777 else:
777 noise = self.dataOut.getNoise(xmin_index=self.minIndexFFT, xmax_index=self.maxIndexFFT, ymin_index=self.minIndex, ymax_index=self.maxIndex)
778 noise = self.dataOut.getNoise(xmin_index=self.minIndexFFT, xmax_index=self.maxIndexFFT, ymin_index=self.minIndex, ymax_index=self.maxIndex)
778
779
779 self.dataOut.noise_estimation = noise.copy() # dataOut.noise
780 self.dataOut.noise_estimation = noise.copy() # dataOut.noise
780
781
781 return self.dataOut
782 return self.dataOut
782
783
783 def getNoiseByMean(self,data):
784 def getNoiseByMean(self,data):
784 #data debe estar ordenado
785 #data debe estar ordenado
785 data = numpy.mean(data,axis=1)
786 data = numpy.mean(data,axis=1)
786 sortdata = numpy.sort(data, axis=None)
787 sortdata = numpy.sort(data, axis=None)
787 pnoise = None
788 pnoise = None
788 j = 0
789 j = 0
789
790
790 mean = numpy.mean(sortdata)
791 mean = numpy.mean(sortdata)
791 min = numpy.min(sortdata)
792 min = numpy.min(sortdata)
792 delta = mean - min
793 delta = mean - min
793 indexes = numpy.where(sortdata > (mean+delta))[0] #only array of indexes
794 indexes = numpy.where(sortdata > (mean+delta))[0] #only array of indexes
794 #print(len(indexes))
795 #print(len(indexes))
795 if len(indexes)==0:
796 if len(indexes)==0:
796 pnoise = numpy.mean(sortdata)
797 pnoise = numpy.mean(sortdata)
797 else:
798 else:
798 j = indexes[0]
799 j = indexes[0]
799 pnoise = numpy.mean(sortdata[0:j])
800 pnoise = numpy.mean(sortdata[0:j])
800
801
801 return pnoise
802 return pnoise
802
803
803 def getNoiseByHS(self,data, navg):
804 def getNoiseByHS(self,data, navg):
804 #data debe estar ordenado
805 #data debe estar ordenado
805 #data = numpy.mean(data,axis=1)
806 #data = numpy.mean(data,axis=1)
806 sortdata = numpy.sort(data, axis=None)
807 sortdata = numpy.sort(data, axis=None)
807
808
808 lenOfData = len(sortdata)
809 lenOfData = len(sortdata)
809 nums_min = lenOfData*0.2
810 nums_min = lenOfData*0.2
810
811
811 if nums_min <= 5:
812 if nums_min <= 5:
812
813
813 nums_min = 5
814 nums_min = 5
814
815
815 sump = 0.
816 sump = 0.
816 sumq = 0.
817 sumq = 0.
817
818
818 j = 0
819 j = 0
819 cont = 1
820 cont = 1
820
821
821 while((cont == 1)and(j < lenOfData)):
822 while((cont == 1)and(j < lenOfData)):
822
823
823 sump += sortdata[j]
824 sump += sortdata[j]
824 sumq += sortdata[j]**2
825 sumq += sortdata[j]**2
825 #sumq -= sump**2
826 #sumq -= sump**2
826 if j > nums_min:
827 if j > nums_min:
827 rtest = float(j)/(j-1) + 1.0/navg
828 rtest = float(j)/(j-1) + 1.0/navg
828 #if ((sumq*j) > (sump**2)):
829 #if ((sumq*j) > (sump**2)):
829 if ((sumq*j) > (rtest*sump**2)):
830 if ((sumq*j) > (rtest*sump**2)):
830 j = j - 1
831 j = j - 1
831 sump = sump - sortdata[j]
832 sump = sump - sortdata[j]
832 sumq = sumq - sortdata[j]**2
833 sumq = sumq - sortdata[j]**2
833 cont = 0
834 cont = 0
834
835
835 j += 1
836 j += 1
836
837
837 lnoise = sump / j
838 lnoise = sump / j
838
839
839 return lnoise
840 return lnoise
840
841
841 class removeInterference(Operation):
842 class removeInterference(Operation):
842
843
843 def removeInterference2(self):
844 def removeInterference2(self):
844
845
845 cspc = self.dataOut.data_cspc
846 cspc = self.dataOut.data_cspc
846 spc = self.dataOut.data_spc
847 spc = self.dataOut.data_spc
847 Heights = numpy.arange(cspc.shape[2])
848 Heights = numpy.arange(cspc.shape[2])
848 realCspc = numpy.abs(cspc)
849 realCspc = numpy.abs(cspc)
849
850
850 for i in range(cspc.shape[0]):
851 for i in range(cspc.shape[0]):
851 LinePower= numpy.sum(realCspc[i], axis=0)
852 LinePower= numpy.sum(realCspc[i], axis=0)
852 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
853 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
853 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
854 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
854 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
855 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
855 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
856 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
856 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
857 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
857
858
858
859
859 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
860 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
860 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
861 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
861 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
862 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
862 cspc[i,InterferenceRange,:] = numpy.NaN
863 cspc[i,InterferenceRange,:] = numpy.NaN
863
864
864 self.dataOut.data_cspc = cspc
865 self.dataOut.data_cspc = cspc
865
866
866 def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None):
867 def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None):
867
868
868 jspectra = self.dataOut.data_spc
869 jspectra = self.dataOut.data_spc
869 jcspectra = self.dataOut.data_cspc
870 jcspectra = self.dataOut.data_cspc
870 jnoise = self.dataOut.getNoise()
871 jnoise = self.dataOut.getNoise()
871 num_incoh = self.dataOut.nIncohInt
872 num_incoh = self.dataOut.nIncohInt
872
873
873 num_channel = jspectra.shape[0]
874 num_channel = jspectra.shape[0]
874 num_prof = jspectra.shape[1]
875 num_prof = jspectra.shape[1]
875 num_hei = jspectra.shape[2]
876 num_hei = jspectra.shape[2]
876
877
877 # hei_interf
878 # hei_interf
878 if hei_interf is None:
879 if hei_interf is None:
879 count_hei = int(num_hei / 2)
880 count_hei = int(num_hei / 2)
880 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
881 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
881 hei_interf = numpy.asarray(hei_interf)[0]
882 hei_interf = numpy.asarray(hei_interf)[0]
882 # nhei_interf
883 # nhei_interf
883 if (nhei_interf == None):
884 if (nhei_interf == None):
884 nhei_interf = 5
885 nhei_interf = 5
885 if (nhei_interf < 1):
886 if (nhei_interf < 1):
886 nhei_interf = 1
887 nhei_interf = 1
887 if (nhei_interf > count_hei):
888 if (nhei_interf > count_hei):
888 nhei_interf = count_hei
889 nhei_interf = count_hei
889 if (offhei_interf == None):
890 if (offhei_interf == None):
890 offhei_interf = 0
891 offhei_interf = 0
891
892
892 ind_hei = list(range(num_hei))
893 ind_hei = list(range(num_hei))
893 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
894 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
894 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
895 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
895 mask_prof = numpy.asarray(list(range(num_prof)))
896 mask_prof = numpy.asarray(list(range(num_prof)))
896 num_mask_prof = mask_prof.size
897 num_mask_prof = mask_prof.size
897 comp_mask_prof = [0, num_prof / 2]
898 comp_mask_prof = [0, num_prof / 2]
898
899
899 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
900 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
900 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
901 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
901 jnoise = numpy.nan
902 jnoise = numpy.nan
902 noise_exist = jnoise[0] < numpy.Inf
903 noise_exist = jnoise[0] < numpy.Inf
903
904
904 # Subrutina de Remocion de la Interferencia
905 # Subrutina de Remocion de la Interferencia
905 for ich in range(num_channel):
906 for ich in range(num_channel):
906 # Se ordena los espectros segun su potencia (menor a mayor)
907 # Se ordena los espectros segun su potencia (menor a mayor)
907 power = jspectra[ich, mask_prof, :]
908 power = jspectra[ich, mask_prof, :]
908 power = power[:, hei_interf]
909 power = power[:, hei_interf]
909 power = power.sum(axis=0)
910 power = power.sum(axis=0)
910 psort = power.ravel().argsort()
911 psort = power.ravel().argsort()
911
912
912 # Se estima la interferencia promedio en los Espectros de Potencia empleando
913 # Se estima la interferencia promedio en los Espectros de Potencia empleando
913 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
914 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
914 offhei_interf, nhei_interf + offhei_interf))]]]
915 offhei_interf, nhei_interf + offhei_interf))]]]
915
916
916 if noise_exist:
917 if noise_exist:
917 # tmp_noise = jnoise[ich] / num_prof
918 # tmp_noise = jnoise[ich] / num_prof
918 tmp_noise = jnoise[ich]
919 tmp_noise = jnoise[ich]
919 junkspc_interf = junkspc_interf - tmp_noise
920 junkspc_interf = junkspc_interf - tmp_noise
920 #junkspc_interf[:,comp_mask_prof] = 0
921 #junkspc_interf[:,comp_mask_prof] = 0
921
922
922 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
923 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
923 jspc_interf = jspc_interf.transpose()
924 jspc_interf = jspc_interf.transpose()
924 # Calculando el espectro de interferencia promedio
925 # Calculando el espectro de interferencia promedio
925 noiseid = numpy.where(
926 noiseid = numpy.where(
926 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
927 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
927 noiseid = noiseid[0]
928 noiseid = noiseid[0]
928 cnoiseid = noiseid.size
929 cnoiseid = noiseid.size
929 interfid = numpy.where(
930 interfid = numpy.where(
930 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
931 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
931 interfid = interfid[0]
932 interfid = interfid[0]
932 cinterfid = interfid.size
933 cinterfid = interfid.size
933
934
934 if (cnoiseid > 0):
935 if (cnoiseid > 0):
935 jspc_interf[noiseid] = 0
936 jspc_interf[noiseid] = 0
936
937
937 # Expandiendo los perfiles a limpiar
938 # Expandiendo los perfiles a limpiar
938 if (cinterfid > 0):
939 if (cinterfid > 0):
939 new_interfid = (
940 new_interfid = (
940 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
941 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
941 new_interfid = numpy.asarray(new_interfid)
942 new_interfid = numpy.asarray(new_interfid)
942 new_interfid = {x for x in new_interfid}
943 new_interfid = {x for x in new_interfid}
943 new_interfid = numpy.array(list(new_interfid))
944 new_interfid = numpy.array(list(new_interfid))
944 new_cinterfid = new_interfid.size
945 new_cinterfid = new_interfid.size
945 else:
946 else:
946 new_cinterfid = 0
947 new_cinterfid = 0
947
948
948 for ip in range(new_cinterfid):
949 for ip in range(new_cinterfid):
949 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
950 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
950 jspc_interf[new_interfid[ip]
951 jspc_interf[new_interfid[ip]
951 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
952 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
952
953
953 jspectra[ich, :, ind_hei] = jspectra[ich, :,
954 jspectra[ich, :, ind_hei] = jspectra[ich, :,
954 ind_hei] - jspc_interf # Corregir indices
955 ind_hei] - jspc_interf # Corregir indices
955
956
956 # Removiendo la interferencia del punto de mayor interferencia
957 # Removiendo la interferencia del punto de mayor interferencia
957 ListAux = jspc_interf[mask_prof].tolist()
958 ListAux = jspc_interf[mask_prof].tolist()
958 maxid = ListAux.index(max(ListAux))
959 maxid = ListAux.index(max(ListAux))
959
960
960 if cinterfid > 0:
961 if cinterfid > 0:
961 for ip in range(cinterfid * (interf == 2) - 1):
962 for ip in range(cinterfid * (interf == 2) - 1):
962 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
963 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
963 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
964 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
964 cind = len(ind)
965 cind = len(ind)
965
966
966 if (cind > 0):
967 if (cind > 0):
967 jspectra[ich, interfid[ip], ind] = tmp_noise * \
968 jspectra[ich, interfid[ip], ind] = tmp_noise * \
968 (1 + (numpy.random.uniform(cind) - 0.5) /
969 (1 + (numpy.random.uniform(cind) - 0.5) /
969 numpy.sqrt(num_incoh))
970 numpy.sqrt(num_incoh))
970
971
971 ind = numpy.array([-2, -1, 1, 2])
972 ind = numpy.array([-2, -1, 1, 2])
972 xx = numpy.zeros([4, 4])
973 xx = numpy.zeros([4, 4])
973
974
974 for id1 in range(4):
975 for id1 in range(4):
975 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
976 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
976
977
977 xx_inv = numpy.linalg.inv(xx)
978 xx_inv = numpy.linalg.inv(xx)
978 xx = xx_inv[:, 0]
979 xx = xx_inv[:, 0]
979 ind = (ind + maxid + num_mask_prof) % num_mask_prof
980 ind = (ind + maxid + num_mask_prof) % num_mask_prof
980 yy = jspectra[ich, mask_prof[ind], :]
981 yy = jspectra[ich, mask_prof[ind], :]
981 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
982 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
982 yy.transpose(), xx)
983 yy.transpose(), xx)
983
984
984 indAux = (jspectra[ich, :, :] < tmp_noise *
985 indAux = (jspectra[ich, :, :] < tmp_noise *
985 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
986 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
986 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
987 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
987 (1 - 1 / numpy.sqrt(num_incoh))
988 (1 - 1 / numpy.sqrt(num_incoh))
988
989
989 # Remocion de Interferencia en el Cross Spectra
990 # Remocion de Interferencia en el Cross Spectra
990 if jcspectra is None:
991 if jcspectra is None:
991 return jspectra, jcspectra
992 return jspectra, jcspectra
992 num_pairs = int(jcspectra.size / (num_prof * num_hei))
993 num_pairs = int(jcspectra.size / (num_prof * num_hei))
993 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
994 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
994
995
995 for ip in range(num_pairs):
996 for ip in range(num_pairs):
996
997
997 #-------------------------------------------
998 #-------------------------------------------
998
999
999 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1000 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1000 cspower = cspower[:, hei_interf]
1001 cspower = cspower[:, hei_interf]
1001 cspower = cspower.sum(axis=0)
1002 cspower = cspower.sum(axis=0)
1002
1003
1003 cspsort = cspower.ravel().argsort()
1004 cspsort = cspower.ravel().argsort()
1004 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1005 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1005 offhei_interf, nhei_interf + offhei_interf))]]]
1006 offhei_interf, nhei_interf + offhei_interf))]]]
1006 junkcspc_interf = junkcspc_interf.transpose()
1007 junkcspc_interf = junkcspc_interf.transpose()
1007 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1008 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1008
1009
1009 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1010 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1010
1011
1011 median_real = int(numpy.median(numpy.real(
1012 median_real = int(numpy.median(numpy.real(
1012 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1013 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1013 median_imag = int(numpy.median(numpy.imag(
1014 median_imag = int(numpy.median(numpy.imag(
1014 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1015 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1015 comp_mask_prof = [int(e) for e in comp_mask_prof]
1016 comp_mask_prof = [int(e) for e in comp_mask_prof]
1016 junkcspc_interf[comp_mask_prof, :] = numpy.complex_(
1017 junkcspc_interf[comp_mask_prof, :] = numpy.complex_(
1017 median_real, median_imag)
1018 median_real, median_imag)
1018
1019
1019 for iprof in range(num_prof):
1020 for iprof in range(num_prof):
1020 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1021 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1021 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1022 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1022
1023
1023 # Removiendo la Interferencia
1024 # Removiendo la Interferencia
1024 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1025 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1025 :, ind_hei] - jcspc_interf
1026 :, ind_hei] - jcspc_interf
1026
1027
1027 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1028 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1028 maxid = ListAux.index(max(ListAux))
1029 maxid = ListAux.index(max(ListAux))
1029
1030
1030 ind = numpy.array([-2, -1, 1, 2])
1031 ind = numpy.array([-2, -1, 1, 2])
1031 xx = numpy.zeros([4, 4])
1032 xx = numpy.zeros([4, 4])
1032
1033
1033 for id1 in range(4):
1034 for id1 in range(4):
1034 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1035 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1035
1036
1036 xx_inv = numpy.linalg.inv(xx)
1037 xx_inv = numpy.linalg.inv(xx)
1037 xx = xx_inv[:, 0]
1038 xx = xx_inv[:, 0]
1038
1039
1039 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1040 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1040 yy = jcspectra[ip, mask_prof[ind], :]
1041 yy = jcspectra[ip, mask_prof[ind], :]
1041 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1042 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1042
1043
1043 # Guardar Resultados
1044 # Guardar Resultados
1044 self.dataOut.data_spc = jspectra
1045 self.dataOut.data_spc = jspectra
1045 self.dataOut.data_cspc = jcspectra
1046 self.dataOut.data_cspc = jcspectra
1046
1047
1047 return 1
1048 return 1
1048
1049
1049
1050
1050 def run(self, dataOut, interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None, mode=1):
1051 def run(self, dataOut, interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None, mode=1):
1051
1052
1052 self.dataOut = dataOut
1053 self.dataOut = dataOut
1053
1054
1054 if mode == 1:
1055 if mode == 1:
1055 self.removeInterference(interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None)
1056 self.removeInterference(interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None)
1056 elif mode == 2:
1057 elif mode == 2:
1057 self.removeInterference2()
1058 self.removeInterference2()
1058
1059
1059 return self.dataOut
1060 return self.dataOut
1060
1061
1061
1062
1062 class deflip(Operation):
1063 class deflip(Operation):
1063
1064
1064 def run(self, dataOut):
1065 def run(self, dataOut):
1065 # arreglo 1: (num_chan, num_profiles, num_heights)
1066 # arreglo 1: (num_chan, num_profiles, num_heights)
1066 self.dataOut = dataOut
1067 self.dataOut = dataOut
1067
1068
1068 # JULIA-oblicua, indice 2
1069 # JULIA-oblicua, indice 2
1069 # arreglo 2: (num_profiles, num_heights)
1070 # arreglo 2: (num_profiles, num_heights)
1070 jspectra = self.dataOut.data_spc[2]
1071 jspectra = self.dataOut.data_spc[2]
1071 jspectra_tmp=numpy.zeros(jspectra.shape)
1072 jspectra_tmp=numpy.zeros(jspectra.shape)
1072 num_profiles=jspectra.shape[0]
1073 num_profiles=jspectra.shape[0]
1073 freq_dc = int(num_profiles / 2)
1074 freq_dc = int(num_profiles / 2)
1074 # Flip con for
1075 # Flip con for
1075 for j in range(num_profiles):
1076 for j in range(num_profiles):
1076 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1077 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1077 # Intercambio perfil de DC con perfil inmediato anterior
1078 # Intercambio perfil de DC con perfil inmediato anterior
1078 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1079 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1079 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1080 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1080 # canal modificado es re-escrito en el arreglo de canales
1081 # canal modificado es re-escrito en el arreglo de canales
1081 self.dataOut.data_spc[2] = jspectra_tmp
1082 self.dataOut.data_spc[2] = jspectra_tmp
1082
1083
1083 return self.dataOut
1084 return self.dataOut
1084
1085
1085
1086
1086 class IncohInt(Operation):
1087 class IncohInt(Operation):
1087
1088
1088 __profIndex = 0
1089 __profIndex = 0
1089 __withOverapping = False
1090 __withOverapping = False
1090
1091
1091 __byTime = False
1092 __byTime = False
1092 __initime = None
1093 __initime = None
1093 __lastdatatime = None
1094 __lastdatatime = None
1094 __integrationtime = None
1095 __integrationtime = None
1095
1096
1096 __buffer_spc = None
1097 __buffer_spc = None
1097 __buffer_cspc = None
1098 __buffer_cspc = None
1098 __buffer_dc = None
1099 __buffer_dc = None
1099
1100
1100 __dataReady = False
1101 __dataReady = False
1101
1102
1102 __timeInterval = None
1103 __timeInterval = None
1103 incohInt = 0
1104 incohInt = 0
1104 nOutliers = 0
1105 nOutliers = 0
1105 n = None
1106 n = None
1106
1107
1107 _flagProfilesByRange = False
1108 _flagProfilesByRange = False
1108 _nProfilesByRange = 0
1109 _nProfilesByRange = 0
1109 def __init__(self):
1110 def __init__(self):
1110
1111
1111 Operation.__init__(self)
1112 Operation.__init__(self)
1112
1113
1113 def setup(self, n=None, timeInterval=None, overlapping=False):
1114 def setup(self, n=None, timeInterval=None, overlapping=False):
1114 """
1115 """
1115 Set the parameters of the integration class.
1116 Set the parameters of the integration class.
1116
1117
1117 Inputs:
1118 Inputs:
1118
1119
1119 n : Number of coherent integrations
1120 n : Number of coherent integrations
1120 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1121 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1121 overlapping :
1122 overlapping :
1122
1123
1123 """
1124 """
1124
1125
1125 self.__initime = None
1126 self.__initime = None
1126 self.__lastdatatime = 0
1127 self.__lastdatatime = 0
1127
1128
1128 self.__buffer_spc = 0
1129 self.__buffer_spc = 0
1129 self.__buffer_cspc = 0
1130 self.__buffer_cspc = 0
1130 self.__buffer_dc = 0
1131 self.__buffer_dc = 0
1131
1132
1132 self.__profIndex = 0
1133 self.__profIndex = 0
1133 self.__dataReady = False
1134 self.__dataReady = False
1134 self.__byTime = False
1135 self.__byTime = False
1135 self.incohInt = 0
1136 self.incohInt = 0
1136 self.nOutliers = 0
1137 self.nOutliers = 0
1137 if n is None and timeInterval is None:
1138 if n is None and timeInterval is None:
1138 raise ValueError("n or timeInterval should be specified ...")
1139 raise ValueError("n or timeInterval should be specified ...")
1139
1140
1140 if n is not None:
1141 if n is not None:
1141 self.n = int(n)
1142 self.n = int(n)
1142 else:
1143 else:
1143
1144
1144 self.__integrationtime = int(timeInterval)
1145 self.__integrationtime = int(timeInterval)
1145 self.n = None
1146 self.n = None
1146 self.__byTime = True
1147 self.__byTime = True
1147
1148
1148
1149
1149
1150
1150 def putData(self, data_spc, data_cspc, data_dc):
1151 def putData(self, data_spc, data_cspc, data_dc):
1151 """
1152 """
1152 Add a profile to the __buffer_spc and increase in one the __profileIndex
1153 Add a profile to the __buffer_spc and increase in one the __profileIndex
1153
1154
1154 """
1155 """
1155 if data_spc.all() == numpy.nan :
1156 if data_spc.all() == numpy.nan :
1156 print("nan ")
1157 print("nan ")
1157 return
1158 return
1158 self.__buffer_spc += data_spc
1159 self.__buffer_spc += data_spc
1159
1160
1160 if data_cspc is None:
1161 if data_cspc is None:
1161 self.__buffer_cspc = None
1162 self.__buffer_cspc = None
1162 else:
1163 else:
1163 self.__buffer_cspc += data_cspc
1164 self.__buffer_cspc += data_cspc
1164
1165
1165 if data_dc is None:
1166 if data_dc is None:
1166 self.__buffer_dc = None
1167 self.__buffer_dc = None
1167 else:
1168 else:
1168 self.__buffer_dc += data_dc
1169 self.__buffer_dc += data_dc
1169
1170
1170 self.__profIndex += 1
1171 self.__profIndex += 1
1171
1172
1172 return
1173 return
1173
1174
1174 def pushData(self):
1175 def pushData(self):
1175 """
1176 """
1176 Return the sum of the last profiles and the profiles used in the sum.
1177 Return the sum of the last profiles and the profiles used in the sum.
1177
1178
1178 Affected:
1179 Affected:
1179
1180
1180 self.__profileIndex
1181 self.__profileIndex
1181
1182
1182 """
1183 """
1183
1184
1184 data_spc = self.__buffer_spc
1185 data_spc = self.__buffer_spc
1185 data_cspc = self.__buffer_cspc
1186 data_cspc = self.__buffer_cspc
1186 data_dc = self.__buffer_dc
1187 data_dc = self.__buffer_dc
1187 n = self.__profIndex
1188 n = self.__profIndex
1188
1189
1189 self.__buffer_spc = 0
1190 self.__buffer_spc = 0
1190 self.__buffer_cspc = 0
1191 self.__buffer_cspc = 0
1191 self.__buffer_dc = 0
1192 self.__buffer_dc = 0
1192
1193
1193
1194
1194 return data_spc, data_cspc, data_dc, n
1195 return data_spc, data_cspc, data_dc, n
1195
1196
1196 def byProfiles(self, *args):
1197 def byProfiles(self, *args):
1197
1198
1198 self.__dataReady = False
1199 self.__dataReady = False
1199 avgdata_spc = None
1200 avgdata_spc = None
1200 avgdata_cspc = None
1201 avgdata_cspc = None
1201 avgdata_dc = None
1202 avgdata_dc = None
1202
1203
1203 self.putData(*args)
1204 self.putData(*args)
1204
1205
1205 if self.__profIndex == self.n:
1206 if self.__profIndex == self.n:
1206
1207
1207 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1208 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1208 self.n = n
1209 self.n = n
1209 self.__dataReady = True
1210 self.__dataReady = True
1210
1211
1211 return avgdata_spc, avgdata_cspc, avgdata_dc
1212 return avgdata_spc, avgdata_cspc, avgdata_dc
1212
1213
1213 def byTime(self, datatime, *args):
1214 def byTime(self, datatime, *args):
1214
1215
1215 self.__dataReady = False
1216 self.__dataReady = False
1216 avgdata_spc = None
1217 avgdata_spc = None
1217 avgdata_cspc = None
1218 avgdata_cspc = None
1218 avgdata_dc = None
1219 avgdata_dc = None
1219
1220
1220 self.putData(*args)
1221 self.putData(*args)
1221
1222
1222 if (datatime - self.__initime) >= self.__integrationtime:
1223 if (datatime - self.__initime) >= self.__integrationtime:
1223 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1224 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1224 self.n = n
1225 self.n = n
1225 self.__dataReady = True
1226 self.__dataReady = True
1226
1227
1227 return avgdata_spc, avgdata_cspc, avgdata_dc
1228 return avgdata_spc, avgdata_cspc, avgdata_dc
1228
1229
1229 def integrate(self, datatime, *args):
1230 def integrate(self, datatime, *args):
1230
1231
1231 if self.__profIndex == 0:
1232 if self.__profIndex == 0:
1232 self.__initime = datatime
1233 self.__initime = datatime
1233
1234
1234 if self.__byTime:
1235 if self.__byTime:
1235 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1236 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1236 datatime, *args)
1237 datatime, *args)
1237 else:
1238 else:
1238 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1239 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1239
1240
1240 if not self.__dataReady:
1241 if not self.__dataReady:
1241 return None, None, None, None
1242 return None, None, None, None
1242
1243
1243 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1244 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1244
1245
1245 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1246 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1246 if n == 1:
1247 if n == 1:
1247 return dataOut
1248 return dataOut
1248
1249
1249 if dataOut.flagNoData == True:
1250 if dataOut.flagNoData == True:
1250 return dataOut
1251 return dataOut
1251
1252
1252 if dataOut.flagProfilesByRange == True:
1253 if dataOut.flagProfilesByRange == True:
1253 self._flagProfilesByRange = True
1254 self._flagProfilesByRange = True
1254
1255
1255 dataOut.flagNoData = True
1256 dataOut.flagNoData = True
1256 dataOut.processingHeaderObj.timeIncohInt = timeInterval
1257 dataOut.processingHeaderObj.timeIncohInt = timeInterval
1257 if not self.isConfig:
1258 if not self.isConfig:
1258 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1259 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1259 self.setup(n, timeInterval, overlapping)
1260 self.setup(n, timeInterval, overlapping)
1260 self.isConfig = True
1261 self.isConfig = True
1261
1262
1262
1263
1263 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1264 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1264 dataOut.data_spc,
1265 dataOut.data_spc,
1265 dataOut.data_cspc,
1266 dataOut.data_cspc,
1266 dataOut.data_dc)
1267 dataOut.data_dc)
1267
1268
1268 self.incohInt += dataOut.nIncohInt
1269 self.incohInt += dataOut.nIncohInt
1269
1270
1270
1271
1271 if isinstance(dataOut.data_outlier,numpy.ndarray) or isinstance(dataOut.data_outlier,int) or isinstance(dataOut.data_outlier, float):
1272 if isinstance(dataOut.data_outlier,numpy.ndarray) or isinstance(dataOut.data_outlier,int) or isinstance(dataOut.data_outlier, float):
1272 self.nOutliers += dataOut.data_outlier
1273 self.nOutliers += dataOut.data_outlier
1273
1274
1274 if self._flagProfilesByRange:
1275 if self._flagProfilesByRange:
1275 dataOut.flagProfilesByRange = True
1276 dataOut.flagProfilesByRange = True
1276 self._nProfilesByRange += dataOut.nProfilesByRange
1277 self._nProfilesByRange += dataOut.nProfilesByRange
1277
1278
1278 if self.__dataReady:
1279 if self.__dataReady:
1279 #print("prof: ",dataOut.max_nIncohInt,self.__profIndex)
1280 #print("prof: ",dataOut.max_nIncohInt,self.__profIndex)
1280 dataOut.data_spc = avgdata_spc
1281 dataOut.data_spc = avgdata_spc
1281 dataOut.data_cspc = avgdata_cspc
1282 dataOut.data_cspc = avgdata_cspc
1282 dataOut.data_dc = avgdata_dc
1283 dataOut.data_dc = avgdata_dc
1283 dataOut.nIncohInt = self.incohInt
1284 dataOut.nIncohInt = self.incohInt
1284 dataOut.data_outlier = self.nOutliers
1285 dataOut.data_outlier = self.nOutliers
1285 dataOut.utctime = avgdatatime
1286 dataOut.utctime = avgdatatime
1286 dataOut.flagNoData = False
1287 dataOut.flagNoData = False
1287 self.incohInt = 0
1288 self.incohInt = 0
1288 self.nOutliers = 0
1289 self.nOutliers = 0
1289 self.__profIndex = 0
1290 self.__profIndex = 0
1290 dataOut.nProfilesByRange = self._nProfilesByRange
1291 dataOut.nProfilesByRange = self._nProfilesByRange
1291 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1292 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1292 self._flagProfilesByRange = False
1293 self._flagProfilesByRange = False
1293 # print("IncohInt Done")
1294 # print("IncohInt Done")
1294 return dataOut
1295 return dataOut
1295
1296
1296
1297
1297 class IntegrationFaradaySpectra(Operation):
1298 class IntegrationFaradaySpectra(Operation):
1298
1299
1299 __profIndex = 0
1300 __profIndex = 0
1300 __withOverapping = False
1301 __withOverapping = False
1301
1302
1302 __byTime = False
1303 __byTime = False
1303 __initime = None
1304 __initime = None
1304 __lastdatatime = None
1305 __lastdatatime = None
1305 __integrationtime = None
1306 __integrationtime = None
1306
1307
1307 __buffer_spc = None
1308 __buffer_spc = None
1308 __buffer_cspc = None
1309 __buffer_cspc = None
1309 __buffer_dc = None
1310 __buffer_dc = None
1310
1311
1311 __dataReady = False
1312 __dataReady = False
1312
1313
1313 __timeInterval = None
1314 __timeInterval = None
1314 n_ints = None #matriz de numero de integracions (CH,HEI)
1315 n_ints = None #matriz de numero de integracions (CH,HEI)
1315 n = None
1316 n = None
1316 minHei_ind = None
1317 minHei_ind = None
1317 maxHei_ind = None
1318 maxHei_ind = None
1318 navg = 1.0
1319 navg = 1.0
1319 factor = 0.0
1320 factor = 0.0
1320 dataoutliers = None # (CHANNELS, HEIGHTS)
1321 dataoutliers = None # (CHANNELS, HEIGHTS)
1321
1322
1322 _flagProfilesByRange = False
1323 _flagProfilesByRange = False
1323 _nProfilesByRange = 0
1324 _nProfilesByRange = 0
1324
1325
1325 def __init__(self):
1326 def __init__(self):
1326
1327
1327 Operation.__init__(self)
1328 Operation.__init__(self)
1328
1329
1329 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None, minHei=None, maxHei=None, avg=1,factor=0.75):
1330 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None, minHei=None, maxHei=None, avg=1,factor=0.75):
1330 """
1331 """
1331 Set the parameters of the integration class.
1332 Set the parameters of the integration class.
1332
1333
1333 Inputs:
1334 Inputs:
1334
1335
1335 n : Number of coherent integrations
1336 n : Number of coherent integrations
1336 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1337 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1337 overlapping :
1338 overlapping :
1338
1339
1339 """
1340 """
1340
1341
1341 self.__initime = None
1342 self.__initime = None
1342 self.__lastdatatime = 0
1343 self.__lastdatatime = 0
1343
1344
1344 self.__buffer_spc = []
1345 self.__buffer_spc = []
1345 self.__buffer_cspc = []
1346 self.__buffer_cspc = []
1346 self.__buffer_dc = 0
1347 self.__buffer_dc = 0
1347
1348
1348 self.__profIndex = 0
1349 self.__profIndex = 0
1349 self.__dataReady = False
1350 self.__dataReady = False
1350 self.__byTime = False
1351 self.__byTime = False
1351
1352
1352 self.factor = factor
1353 self.factor = factor
1353 self.navg = avg
1354 self.navg = avg
1354 #self.ByLags = dataOut.ByLags ###REDEFINIR
1355 #self.ByLags = dataOut.ByLags ###REDEFINIR
1355 self.ByLags = False
1356 self.ByLags = False
1356 self.maxProfilesInt = 0
1357 self.maxProfilesInt = 0
1357 self.__nChannels = dataOut.nChannels
1358 self.__nChannels = dataOut.nChannels
1358 if DPL != None:
1359 if DPL != None:
1359 self.DPL=DPL
1360 self.DPL=DPL
1360 else:
1361 else:
1361 #self.DPL=dataOut.DPL ###REDEFINIR
1362 #self.DPL=dataOut.DPL ###REDEFINIR
1362 self.DPL=0
1363 self.DPL=0
1363
1364
1364 if n is None and timeInterval is None:
1365 if n is None and timeInterval is None:
1365 raise ValueError("n or timeInterval should be specified ...")
1366 raise ValueError("n or timeInterval should be specified ...")
1366
1367
1367 if n is not None:
1368 if n is not None:
1368 self.n = int(n)
1369 self.n = int(n)
1369 else:
1370 else:
1370 self.__integrationtime = int(timeInterval)
1371 self.__integrationtime = int(timeInterval)
1371 self.n = None
1372 self.n = None
1372 self.__byTime = True
1373 self.__byTime = True
1373
1374
1374
1375
1375 if minHei == None:
1376 if minHei == None:
1376 minHei = self.dataOut.heightList[0]
1377 minHei = self.dataOut.heightList[0]
1377
1378
1378 if maxHei == None:
1379 if maxHei == None:
1379 maxHei = self.dataOut.heightList[-1]
1380 maxHei = self.dataOut.heightList[-1]
1380
1381
1381 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
1382 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
1382 print('minHei: %.2f is out of the heights range' % (minHei))
1383 print('minHei: %.2f is out of the heights range' % (minHei))
1383 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
1384 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
1384 minHei = self.dataOut.heightList[0]
1385 minHei = self.dataOut.heightList[0]
1385
1386
1386 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
1387 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
1387 print('maxHei: %.2f is out of the heights range' % (maxHei))
1388 print('maxHei: %.2f is out of the heights range' % (maxHei))
1388 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
1389 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
1389 maxHei = self.dataOut.heightList[-1]
1390 maxHei = self.dataOut.heightList[-1]
1390
1391
1391 ind_list1 = numpy.where(self.dataOut.heightList >= minHei)
1392 ind_list1 = numpy.where(self.dataOut.heightList >= minHei)
1392 ind_list2 = numpy.where(self.dataOut.heightList <= maxHei)
1393 ind_list2 = numpy.where(self.dataOut.heightList <= maxHei)
1393 self.minHei_ind = ind_list1[0][0]
1394 self.minHei_ind = ind_list1[0][0]
1394 self.maxHei_ind = ind_list2[0][-1]
1395 self.maxHei_ind = ind_list2[0][-1]
1395
1396
1396 def putData(self, data_spc, data_cspc, data_dc):
1397 def putData(self, data_spc, data_cspc, data_dc):
1397 """
1398 """
1398 Add a profile to the __buffer_spc and increase in one the __profileIndex
1399 Add a profile to the __buffer_spc and increase in one the __profileIndex
1399
1400
1400 """
1401 """
1401
1402
1402 self.__buffer_spc.append(data_spc)
1403 self.__buffer_spc.append(data_spc)
1403
1404
1404 if self.__nChannels < 2:
1405 if self.__nChannels < 2:
1405 self.__buffer_cspc = None
1406 self.__buffer_cspc = None
1406 else:
1407 else:
1407 self.__buffer_cspc.append(data_cspc)
1408 self.__buffer_cspc.append(data_cspc)
1408
1409
1409 if data_dc is None:
1410 if data_dc is None:
1410 self.__buffer_dc = None
1411 self.__buffer_dc = None
1411 else:
1412 else:
1412 self.__buffer_dc += data_dc
1413 self.__buffer_dc += data_dc
1413
1414
1414 self.__profIndex += 1
1415 self.__profIndex += 1
1415
1416
1416 return
1417 return
1417
1418
1418 def hildebrand_sekhon_Integration(self,sortdata,navg, factor):
1419 def hildebrand_sekhon_Integration(self,sortdata,navg, factor):
1419 #data debe estar ordenado
1420 #data debe estar ordenado
1420 #sortdata = numpy.sort(data, axis=None)
1421 #sortdata = numpy.sort(data, axis=None)
1421 #sortID=data.argsort()
1422 #sortID=data.argsort()
1422 lenOfData = len(sortdata)
1423 lenOfData = len(sortdata)
1423 nums_min = lenOfData*factor
1424 nums_min = lenOfData*factor
1424 if nums_min <= 5:
1425 if nums_min <= 5:
1425 nums_min = 5
1426 nums_min = 5
1426 sump = 0.
1427 sump = 0.
1427 sumq = 0.
1428 sumq = 0.
1428 j = 0
1429 j = 0
1429 cont = 1
1430 cont = 1
1430 while((cont == 1)and(j < lenOfData)):
1431 while((cont == 1)and(j < lenOfData)):
1431 sump += sortdata[j]
1432 sump += sortdata[j]
1432 sumq += sortdata[j]**2
1433 sumq += sortdata[j]**2
1433 if j > nums_min:
1434 if j > nums_min:
1434 rtest = float(j)/(j-1) + 1.0/navg
1435 rtest = float(j)/(j-1) + 1.0/navg
1435 if ((sumq*j) > (rtest*sump**2)):
1436 if ((sumq*j) > (rtest*sump**2)):
1436 j = j - 1
1437 j = j - 1
1437 sump = sump - sortdata[j]
1438 sump = sump - sortdata[j]
1438 sumq = sumq - sortdata[j]**2
1439 sumq = sumq - sortdata[j]**2
1439 cont = 0
1440 cont = 0
1440 j += 1
1441 j += 1
1441 #lnoise = sump / j
1442 #lnoise = sump / j
1442 #print("H S done")
1443 #print("H S done")
1443 #return j,sortID
1444 #return j,sortID
1444 return j
1445 return j
1445
1446
1446
1447
1447 def pushData(self):
1448 def pushData(self):
1448 """
1449 """
1449 Return the sum of the last profiles and the profiles used in the sum.
1450 Return the sum of the last profiles and the profiles used in the sum.
1450
1451
1451 Affected:
1452 Affected:
1452
1453
1453 self.__profileIndex
1454 self.__profileIndex
1454
1455
1455 """
1456 """
1456 bufferH=None
1457 bufferH=None
1457 buffer=None
1458 buffer=None
1458 buffer1=None
1459 buffer1=None
1459 buffer_cspc=None
1460 buffer_cspc=None
1460 #print("aes: ", self.__buffer_cspc)
1461 #print("aes: ", self.__buffer_cspc)
1461 self.__buffer_spc=numpy.array(self.__buffer_spc)
1462 self.__buffer_spc=numpy.array(self.__buffer_spc)
1462 if self.__nChannels > 1 :
1463 if self.__nChannels > 1 :
1463 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1464 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1464
1465
1465 #print("FREQ_DC",self.__buffer_spc.shape,self.__buffer_cspc.shape)
1466 #print("FREQ_DC",self.__buffer_spc.shape,self.__buffer_cspc.shape)
1466
1467
1467 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1468 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1468 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1469 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1469
1470
1470 self.dataOutliers = numpy.zeros((self.nChannels,self.nHeights)) # --> almacen de outliers
1471 self.dataOutliers = numpy.zeros((self.nChannels,self.nHeights)) # --> almacen de outliers
1471
1472
1472 for k in range(self.minHei_ind,self.maxHei_ind):
1473 for k in range(self.minHei_ind,self.maxHei_ind):
1473 if self.__nChannels > 1:
1474 if self.__nChannels > 1:
1474 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1475 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1475
1476
1476 outliers_IDs_cspc=[]
1477 outliers_IDs_cspc=[]
1477 cspc_outliers_exist=False
1478 cspc_outliers_exist=False
1478 for i in range(self.nChannels):#dataOut.nChannels):
1479 for i in range(self.nChannels):#dataOut.nChannels):
1479
1480
1480 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1481 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1481 indexes=[]
1482 indexes=[]
1482 #sortIDs=[]
1483 #sortIDs=[]
1483 outliers_IDs=[]
1484 outliers_IDs=[]
1484
1485
1485 for j in range(self.nProfiles): #frecuencias en el tiempo
1486 for j in range(self.nProfiles): #frecuencias en el tiempo
1486 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1487 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1487 # continue
1488 # continue
1488 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1489 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1489 # continue
1490 # continue
1490 buffer=buffer1[:,j]
1491 buffer=buffer1[:,j]
1491 sortdata = numpy.sort(buffer, axis=None)
1492 sortdata = numpy.sort(buffer, axis=None)
1492
1493
1493 sortID=buffer.argsort()
1494 sortID=buffer.argsort()
1494 index = _noise.hildebrand_sekhon2(sortdata,self.navg)
1495 index = _noise.hildebrand_sekhon2(sortdata,self.navg)
1495
1496
1496 #index,sortID=self.hildebrand_sekhon_Integration(buffer,1,self.factor)
1497 #index,sortID=self.hildebrand_sekhon_Integration(buffer,1,self.factor)
1497
1498
1498 # fig,ax = plt.subplots()
1499 # fig,ax = plt.subplots()
1499 # ax.set_title(str(k)+" "+str(j))
1500 # ax.set_title(str(k)+" "+str(j))
1500 # x=range(len(sortdata))
1501 # x=range(len(sortdata))
1501 # ax.scatter(x,sortdata)
1502 # ax.scatter(x,sortdata)
1502 # ax.axvline(index)
1503 # ax.axvline(index)
1503 # plt.show()
1504 # plt.show()
1504
1505
1505 indexes.append(index)
1506 indexes.append(index)
1506 #sortIDs.append(sortID)
1507 #sortIDs.append(sortID)
1507 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1508 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1508
1509
1509 #print("Outliers: ",outliers_IDs)
1510 #print("Outliers: ",outliers_IDs)
1510 outliers_IDs=numpy.array(outliers_IDs)
1511 outliers_IDs=numpy.array(outliers_IDs)
1511 outliers_IDs=outliers_IDs.ravel()
1512 outliers_IDs=outliers_IDs.ravel()
1512 outliers_IDs=numpy.unique(outliers_IDs)
1513 outliers_IDs=numpy.unique(outliers_IDs)
1513 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1514 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1514 indexes=numpy.array(indexes)
1515 indexes=numpy.array(indexes)
1515 indexmin=numpy.min(indexes)
1516 indexmin=numpy.min(indexes)
1516
1517
1517
1518
1518 #print(indexmin,buffer1.shape[0], k)
1519 #print(indexmin,buffer1.shape[0], k)
1519
1520
1520 # fig,ax = plt.subplots()
1521 # fig,ax = plt.subplots()
1521 # ax.plot(sortdata)
1522 # ax.plot(sortdata)
1522 # ax2 = ax.twinx()
1523 # ax2 = ax.twinx()
1523 # x=range(len(indexes))
1524 # x=range(len(indexes))
1524 # #plt.scatter(x,indexes)
1525 # #plt.scatter(x,indexes)
1525 # ax2.scatter(x,indexes)
1526 # ax2.scatter(x,indexes)
1526 # plt.show()
1527 # plt.show()
1527
1528
1528 if indexmin != buffer1.shape[0]:
1529 if indexmin != buffer1.shape[0]:
1529 if self.__nChannels > 1:
1530 if self.__nChannels > 1:
1530 cspc_outliers_exist= True
1531 cspc_outliers_exist= True
1531
1532
1532 lt=outliers_IDs
1533 lt=outliers_IDs
1533 #avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1534 #avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1534
1535
1535 for p in list(outliers_IDs):
1536 for p in list(outliers_IDs):
1536 #buffer1[p,:]=avg
1537 #buffer1[p,:]=avg
1537 buffer1[p,:] = numpy.NaN
1538 buffer1[p,:] = numpy.NaN
1538
1539
1539 self.dataOutliers[i,k] = len(outliers_IDs)
1540 self.dataOutliers[i,k] = len(outliers_IDs)
1540
1541
1541
1542
1542 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1543 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1543
1544
1544
1545
1545 if self.__nChannels > 1:
1546 if self.__nChannels > 1:
1546 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1547 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1547
1548
1548
1549
1549 if self.__nChannels > 1:
1550 if self.__nChannels > 1:
1550 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1551 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1551 if cspc_outliers_exist:
1552 if cspc_outliers_exist:
1552
1553
1553 lt=outliers_IDs_cspc
1554 lt=outliers_IDs_cspc
1554
1555
1555 #avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1556 #avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1556 for p in list(outliers_IDs_cspc):
1557 for p in list(outliers_IDs_cspc):
1557 #buffer_cspc[p,:]=avg
1558 #buffer_cspc[p,:]=avg
1558 buffer_cspc[p,:] = numpy.NaN
1559 buffer_cspc[p,:] = numpy.NaN
1559
1560
1560 if self.__nChannels > 1:
1561 if self.__nChannels > 1:
1561 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1562 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1562
1563
1563
1564
1564
1565
1565
1566
1566 nOutliers = len(outliers_IDs)
1567 nOutliers = len(outliers_IDs)
1567 #print("Outliers n: ",self.dataOutliers,nOutliers)
1568 #print("Outliers n: ",self.dataOutliers,nOutliers)
1568 buffer=None
1569 buffer=None
1569 bufferH=None
1570 bufferH=None
1570 buffer1=None
1571 buffer1=None
1571 buffer_cspc=None
1572 buffer_cspc=None
1572
1573
1573
1574
1574 buffer=None
1575 buffer=None
1575
1576
1576 #data_spc = numpy.sum(self.__buffer_spc,axis=0)
1577 #data_spc = numpy.sum(self.__buffer_spc,axis=0)
1577 data_spc = numpy.nansum(self.__buffer_spc,axis=0)
1578 data_spc = numpy.nansum(self.__buffer_spc,axis=0)
1578 if self.__nChannels > 1:
1579 if self.__nChannels > 1:
1579 #data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1580 #data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1580 data_cspc = numpy.nansum(self.__buffer_cspc,axis=0)
1581 data_cspc = numpy.nansum(self.__buffer_cspc,axis=0)
1581 else:
1582 else:
1582 data_cspc = None
1583 data_cspc = None
1583 data_dc = self.__buffer_dc
1584 data_dc = self.__buffer_dc
1584 #(CH, HEIGH)
1585 #(CH, HEIGH)
1585 self.maxProfilesInt = self.__profIndex - 1
1586 self.maxProfilesInt = self.__profIndex - 1
1586 n = self.__profIndex - self.dataOutliers # n becomes a matrix
1587 n = self.__profIndex - self.dataOutliers # n becomes a matrix
1587
1588
1588 self.__buffer_spc = []
1589 self.__buffer_spc = []
1589 self.__buffer_cspc = []
1590 self.__buffer_cspc = []
1590 self.__buffer_dc = 0
1591 self.__buffer_dc = 0
1591 self.__profIndex = 0
1592 self.__profIndex = 0
1592 #print("cleaned ",data_cspc)
1593 #print("cleaned ",data_cspc)
1593 return data_spc, data_cspc, data_dc, n
1594 return data_spc, data_cspc, data_dc, n
1594
1595
1595 def byProfiles(self, *args):
1596 def byProfiles(self, *args):
1596
1597
1597 self.__dataReady = False
1598 self.__dataReady = False
1598 avgdata_spc = None
1599 avgdata_spc = None
1599 avgdata_cspc = None
1600 avgdata_cspc = None
1600 avgdata_dc = None
1601 avgdata_dc = None
1601
1602
1602 self.putData(*args)
1603 self.putData(*args)
1603
1604
1604 if self.__profIndex >= self.n:
1605 if self.__profIndex >= self.n:
1605
1606
1606 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1607 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1607 self.n_ints = n
1608 self.n_ints = n
1608 self.__dataReady = True
1609 self.__dataReady = True
1609
1610
1610 return avgdata_spc, avgdata_cspc, avgdata_dc
1611 return avgdata_spc, avgdata_cspc, avgdata_dc
1611
1612
1612 def byTime(self, datatime, *args):
1613 def byTime(self, datatime, *args):
1613
1614
1614 self.__dataReady = False
1615 self.__dataReady = False
1615 avgdata_spc = None
1616 avgdata_spc = None
1616 avgdata_cspc = None
1617 avgdata_cspc = None
1617 avgdata_dc = None
1618 avgdata_dc = None
1618
1619
1619 self.putData(*args)
1620 self.putData(*args)
1620
1621
1621 if (datatime - self.__initime) >= self.__integrationtime:
1622 if (datatime - self.__initime) >= self.__integrationtime:
1622 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1623 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1623 self.n_ints = n
1624 self.n_ints = n
1624 self.__dataReady = True
1625 self.__dataReady = True
1625
1626
1626 return avgdata_spc, avgdata_cspc, avgdata_dc
1627 return avgdata_spc, avgdata_cspc, avgdata_dc
1627
1628
1628 def integrate(self, datatime, *args):
1629 def integrate(self, datatime, *args):
1629
1630
1630 if self.__profIndex == 0:
1631 if self.__profIndex == 0:
1631 self.__initime = datatime
1632 self.__initime = datatime
1632
1633
1633 if self.__byTime:
1634 if self.__byTime:
1634 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1635 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1635 datatime, *args)
1636 datatime, *args)
1636 else:
1637 else:
1637 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1638 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1638
1639
1639 if not self.__dataReady:
1640 if not self.__dataReady:
1640 return None, None, None, None
1641 return None, None, None, None
1641
1642
1642 #print("integrate", avgdata_cspc)
1643 #print("integrate", avgdata_cspc)
1643 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1644 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1644
1645
1645 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False, minHei=None, maxHei=None, avg=1, factor=0.75):
1646 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False, minHei=None, maxHei=None, avg=1, factor=0.75):
1646 self.dataOut = dataOut
1647 self.dataOut = dataOut
1647 if n == 1:
1648 if n == 1:
1648 return self.dataOut
1649 return self.dataOut
1649 self.dataOut.processingHeaderObj.timeIncohInt = timeInterval
1650 self.dataOut.processingHeaderObj.timeIncohInt = timeInterval
1650
1651
1651 if dataOut.flagProfilesByRange:
1652 if dataOut.flagProfilesByRange:
1652 self._flagProfilesByRange = True
1653 self._flagProfilesByRange = True
1653
1654
1654 if self.dataOut.nChannels == 1:
1655 if self.dataOut.nChannels == 1:
1655 self.dataOut.data_cspc = None #si es un solo canal no vale la pena acumular DATOS
1656 self.dataOut.data_cspc = None #si es un solo canal no vale la pena acumular DATOS
1656 #print("IN spc:", self.dataOut.data_spc.shape, self.dataOut.data_cspc)
1657 #print("IN spc:", self.dataOut.data_spc.shape, self.dataOut.data_cspc)
1657 if not self.isConfig:
1658 if not self.isConfig:
1658 self.setup(self.dataOut, n, timeInterval, overlapping,DPL ,minHei, maxHei, avg, factor)
1659 self.setup(self.dataOut, n, timeInterval, overlapping,DPL ,minHei, maxHei, avg, factor)
1659 self.isConfig = True
1660 self.isConfig = True
1660
1661
1661 if not self.ByLags:
1662 if not self.ByLags:
1662 self.nProfiles=self.dataOut.nProfiles
1663 self.nProfiles=self.dataOut.nProfiles
1663 self.nChannels=self.dataOut.nChannels
1664 self.nChannels=self.dataOut.nChannels
1664 self.nHeights=self.dataOut.nHeights
1665 self.nHeights=self.dataOut.nHeights
1665 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1666 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1666 self.dataOut.data_spc,
1667 self.dataOut.data_spc,
1667 self.dataOut.data_cspc,
1668 self.dataOut.data_cspc,
1668 self.dataOut.data_dc)
1669 self.dataOut.data_dc)
1669 else:
1670 else:
1670 self.nProfiles=self.dataOut.nProfiles
1671 self.nProfiles=self.dataOut.nProfiles
1671 self.nChannels=self.dataOut.nChannels
1672 self.nChannels=self.dataOut.nChannels
1672 self.nHeights=self.dataOut.nHeights
1673 self.nHeights=self.dataOut.nHeights
1673 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1674 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1674 self.dataOut.dataLag_spc,
1675 self.dataOut.dataLag_spc,
1675 self.dataOut.dataLag_cspc,
1676 self.dataOut.dataLag_cspc,
1676 self.dataOut.dataLag_dc)
1677 self.dataOut.dataLag_dc)
1677 self.dataOut.flagNoData = True
1678 self.dataOut.flagNoData = True
1678
1679
1679 if self._flagProfilesByRange:
1680 if self._flagProfilesByRange:
1680 dataOut.flagProfilesByRange = True
1681 dataOut.flagProfilesByRange = True
1681 self._nProfilesByRange += dataOut.nProfilesByRange
1682 self._nProfilesByRange += dataOut.nProfilesByRange
1682
1683
1683 if self.__dataReady:
1684 if self.__dataReady:
1684
1685
1685 if not self.ByLags:
1686 if not self.ByLags:
1686 if self.nChannels == 1:
1687 if self.nChannels == 1:
1687 #print("f int", avgdata_spc.shape)
1688 #print("f int", avgdata_spc.shape)
1688 self.dataOut.data_spc = avgdata_spc
1689 self.dataOut.data_spc = avgdata_spc
1689 self.dataOut.data_cspc = None
1690 self.dataOut.data_cspc = None
1690 else:
1691 else:
1691 self.dataOut.data_spc = numpy.squeeze(avgdata_spc)
1692 self.dataOut.data_spc = numpy.squeeze(avgdata_spc)
1692 self.dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1693 self.dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1693 self.dataOut.data_dc = avgdata_dc
1694 self.dataOut.data_dc = avgdata_dc
1694 self.dataOut.data_outlier = self.dataOutliers
1695 self.dataOut.data_outlier = self.dataOutliers
1695
1696
1696
1697
1697 else:
1698 else:
1698 self.dataOut.dataLag_spc = avgdata_spc
1699 self.dataOut.dataLag_spc = avgdata_spc
1699 self.dataOut.dataLag_cspc = avgdata_cspc
1700 self.dataOut.dataLag_cspc = avgdata_cspc
1700 self.dataOut.dataLag_dc = avgdata_dc
1701 self.dataOut.dataLag_dc = avgdata_dc
1701
1702
1702 self.dataOut.data_spc=self.dataOut.dataLag_spc[:,:,:,self.dataOut.LagPlot]
1703 self.dataOut.data_spc=self.dataOut.dataLag_spc[:,:,:,self.dataOut.LagPlot]
1703 self.dataOut.data_cspc=self.dataOut.dataLag_cspc[:,:,:,self.dataOut.LagPlot]
1704 self.dataOut.data_cspc=self.dataOut.dataLag_cspc[:,:,:,self.dataOut.LagPlot]
1704 self.dataOut.data_dc=self.dataOut.dataLag_dc[:,:,self.dataOut.LagPlot]
1705 self.dataOut.data_dc=self.dataOut.dataLag_dc[:,:,self.dataOut.LagPlot]
1705
1706
1706 self.dataOut.nIncohInt *= self.n_ints
1707 self.dataOut.nIncohInt *= self.n_ints
1707
1708
1708 self.dataOut.utctime = avgdatatime
1709 self.dataOut.utctime = avgdatatime
1709 self.dataOut.flagNoData = False
1710 self.dataOut.flagNoData = False
1710
1711
1711 dataOut.nProfilesByRange = self._nProfilesByRange
1712 dataOut.nProfilesByRange = self._nProfilesByRange
1712 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1713 self._nProfilesByRange = numpy.zeros((1,len(dataOut.heightList)))
1713 self._flagProfilesByRange = False
1714 self._flagProfilesByRange = False
1714
1715
1715 return self.dataOut
1716 return self.dataOut
1716
1717
1717 class dopplerFlip(Operation):
1718 class dopplerFlip(Operation):
1718
1719
1719 def run(self, dataOut, chann = None):
1720 def run(self, dataOut, chann = None):
1720 # arreglo 1: (num_chan, num_profiles, num_heights)
1721 # arreglo 1: (num_chan, num_profiles, num_heights)
1721 self.dataOut = dataOut
1722 self.dataOut = dataOut
1722 # JULIA-oblicua, indice 2
1723 # JULIA-oblicua, indice 2
1723 # arreglo 2: (num_profiles, num_heights)
1724 # arreglo 2: (num_profiles, num_heights)
1724 jspectra = self.dataOut.data_spc[chann]
1725 jspectra = self.dataOut.data_spc[chann]
1725 jspectra_tmp = numpy.zeros(jspectra.shape)
1726 jspectra_tmp = numpy.zeros(jspectra.shape)
1726 num_profiles = jspectra.shape[0]
1727 num_profiles = jspectra.shape[0]
1727 freq_dc = int(num_profiles / 2)
1728 freq_dc = int(num_profiles / 2)
1728 # Flip con for
1729 # Flip con for
1729 for j in range(num_profiles):
1730 for j in range(num_profiles):
1730 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1731 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1731 # Intercambio perfil de DC con perfil inmediato anterior
1732 # Intercambio perfil de DC con perfil inmediato anterior
1732 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1733 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1733 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1734 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1734 # canal modificado es re-escrito en el arreglo de canales
1735 # canal modificado es re-escrito en el arreglo de canales
1735 self.dataOut.data_spc[chann] = jspectra_tmp
1736 self.dataOut.data_spc[chann] = jspectra_tmp
1736
1737
1737 return self.dataOut No newline at end of file
1738 return self.dataOut
General Comments 0
You need to be logged in to leave comments. Login now